Edward Venator EECS 337 HW3 Assignment A syntactical analyzer created using bison and the C programming language. --------------------------------------------- Intro This program is a lexical and syntactical analyzer designed to parse the code found on the bottom of page 986 of the text. The lexical analyzer runs through a file of code, specified by a command line argument, and performs lexical analysis, adding symbols to a symbol table, implemented as a linked list. The syntactical analyzer adds type information for each symbol in the symbol table and prints out the rules being used as it constructs a parse tree. In addition, the syntactical analyzer implements rudimentary error handling, as described in assumptions.txt. --------------------------------------------- Lexemes The Lexical Analyzer recognizes the following lexemes: * Whitespace - perform no action * Comment - perform no action. Recognizes singal line (//Comment) and block (/*Comment*/) style comments * if - yylval=NULL; prints "if"; returns IF token * else - yylval=NULL; prints "else"; returns ELSE token * while - yylval=NULL; prints "while"; returns WHILE token * do - yylval=NULL; prints "do"; returns DO token * break - yylval=NULL; prints "break"; returns BREAK token * basic - yylval=pointer to int_var or float_var as appropriate; prints "basic"; returns BASIC token * true - yylval=pointer to true_var; prints "true"; returns BOOL token * false - yylval=pointer to false_var; prints "false"; returns BOOL token * id - yylval=pointer to entry in symbol table; prints "id"; returns ID token * num - yylval=void * pointer to integer; prints "num"; returns NUM token * real - yylval=void * pointer to float; prints "real"; returns REAL token * <= - yylval=NULL; prints "<="; returns LE token * < - yylval=NULL; prints "<"; returns LT token * >= - yylval=NULL; prints ">="; returns GE token * > - yylval=NULL; prints ">"; returns GT token * == - yylval=NULL; prints "=="; returns EQUALTO token * != - yylval=NULL; prints "!="; returns NOTEQUAL token * { - yylval=NULL; prints "{"; returns OPENBRACKET token * } - yylval=NULL; prints "}"; returns CLOSEBRACKET token * ( - yylval=NULL; prints "("; returns OPENPAREN token * ) - yylval=NULL; prints ")"; returns CLOSEPAREN token * && - yylval=NULL; prints "&&"; returns AND token * || - yylval=NULL; prints "||"; returns OR token * ; - yylval=NULL; prints ";"; returns SEMI token * + - yylval=NULL; prints "+"; returns PLUS * - - yylval=NULL; prints "-"; returns MINUS token * * - yylval=NULL; prints "*"; returns MULTI token * / - yylval=NULL; prints "/"; returns DIV token * ! - yylval=NULL; prints "!"; returns NOT token * = - yylval=NULL; prints "="; returns EQUALS token --------------------------------------------- The Symbol Table The symbol table, contained in symbol.c, is implemented as a linked list with the following functions: list_head_t *list_init(int (*cmp)(const void *, const void *)) *allocates memory for a list head, returns a pointer to the list head list_entry_t* listinsert(list_head_t *head, void *key, void *value) *adds a list entry key=>value to list with head head, returns a pointer to this entry list_entry_t *list_search_entry(list_head_t *head, void *key) *searches list with head head for an entry with key key and returns a pointer to the first entry found void *list_search(list_head_t *head, void *key) *searches list with head head for an entry with key key and returns a pointer to the value of this entry *not used in this assignment --------------------------------------------- Grammar Rules prgrm->block block->'{' decls stmts '}' decls->/*empty*/ | decls decl decl->type ID ';' Add a type designation to the symbol table. type->type [ NUM ] Add a dimension to the type designation for the id. | BASIC stmts->/*empty*/ | stmts stmt stmt->loc = bool ';' | "if" '(' bool ')' stmt | "if" '(' bool ')' stmt "else" stmt | "while" '(' bool ')' stmt | "do" stmt "while" '(' bool ')' ';' | "break" ';' | block | error ";" If an error is encountered, increment error counter and skip to after next semicolon. loc->loc '[' bool ']' | ID bool->bool "||" join | join join->join "&&" equality | equality equality->equality "==" rel | equality "!=" rel | rel rel-> expr '<' expr | expr "<=" expr | expr ">=" expr | expr '>' expr | expr expr-> expr '+' term | expr '-' term | term term-> term '*' unary | term '/' unary | unary unary->'!' unary | '-' unary | factor factor->'(' bool ')' | loc | NUM | REAL | BOOL --------------------------------------------- lex.h A header file for lex.yy.c (generated by flex from lex.l). Contains definitions for all auxiliary functions in lex.l. --------------------------------------------- lex.l This is the lex file containing the lexical analyzer. It contains no main method. To compile: flex lex.l Compiling this file creates lex.yy.c, which is dependent on lex.h. --------------------------------------------- yacc.y This is the yacc file containing the parser. It contains a main method which opens the file with a name passed by command line argument, then runs yyparse() on this file, and prints every rule it executes. At the end of execution, it prints the symbol table, including type entries. To Compile: bison yacc.y Compiling this file creates yacc.tab.c, which is dependent on lex.c. This file does not need to be editted and can be compiled immediately after creation. To Compile: gcc yac.tab.c -o yacc -ll -ly --------------------------------------------- Running yacc To run yacc, open a command line shell, cd to the appropriate directory then enter the command: ./yacc where is the file you wish yacc to analyze. The file "test" in my project contains the code I have tested yacc with. It is copied from the bottom of page 986. To run lex on test, enter the command: ./yacc test