%{ #include #include #include #include "lex.h" #include "symbol.c" #define YYSTYPE char const * int yylex (void); void yyerror (char const *); list_entry_t* entry; int errorcount; typedef struct id_type id_type_t; struct id_type { void *type; /* The type of this variable, as per Hw2 */ unsigned int dimension; /* Vector dimension */ unsigned int size; /* Size along the last dimension */ id_type_t *subsize; /* Type of the previous dimensions */ }; id_type_t* tmptype; id_type_t* type_init(void* type); void type_add_dim(id_type_t* type, int size); //yylval variables int int_var; int float_var; int true_var; int false_var; %} %token ID %token BASIC %token BOOL %token NUM %token REAL %token IF %token ELSE %token WHILE %token DO %token BREAK %token LE %token LT %token GE %token GT %token EQUALTO %token NOTEQUAL %token OPENPAREN %token CLOSEPAREN %token OPENBRACKET %token CLOSEBRACKET %token OPENBRACE %token CLOSEBRACE %token AND %token OR %token SEMI %token PLUS %token MINUS %token MULTI %token DIV %token NOT %token EQUALS %% prgrm: block {printf("program->block\n");} ; block: OPENBRACE decls stmts CLOSEBRACE {printf("block->{ decls stmts }\n");} ; decls: /*empty*/ {printf("decls->empty\n");} | decls decl {printf("decls->decls decl\n");} ; decl: type ID SEMI {printf("decl->type id\n"); entry=(list_entry_t*)$2; tmptype=(id_type_t*)$1; entry->value=tmptype;} ; type: type OPENBRACKET NUM CLOSEBRACKET {printf("type->type [ num ]\n"); tmptype=(id_type_t*)$1; type_add_dim(tmptype,*((int*)$3)); $$=(void*)tmptype;} | BASIC {printf("type->basic\n"); $$=(void*)type_init((void *)$1);} ; stmts: /*empty*/ {printf("stmts->empty\n");} | stmts stmt {printf("stmts->stmts stmt\n");} ; stmt: loc EQUALS bool SEMI {printf("stmt->loc = bool ;\n");} | IF OPENPAREN bool CLOSEPAREN stmt {printf("stmt->if ( bool ) stmt\n");} | IF OPENPAREN bool CLOSEPAREN stmt ELSE stmt {printf("stmt->if ( bool ) stmt else stmt\n");} | WHILE OPENPAREN bool CLOSEPAREN stmt {printf("stmt->while ( bool ) stmt\n");} | DO stmt WHILE OPENPAREN bool CLOSEPAREN SEMI {printf("stmt->do stmt while ( bool ) ;\n");} | BREAK SEMI {printf("stmt->break;\n");} | block {printf("stmt->block;\n");} | error SEMI {errorcount++; printf("**Syntax error. Total errors: %i**\n",errorcount);} //If an error is encountered, skip to after next semicolon. ; loc: loc OPENBRACKET bool CLOSEBRACKET {printf("loc->loc ( bool )\n");} | ID {printf("loc->id;\n");} ; bool: bool OR join {printf("bool->bool || join\n");} | join {printf("bool->join\n");} ; join: join AND equality {printf("join->join && equality\n");} | equality {printf("join->equality\n");} ; equality: equality EQUALTO rel {printf("equality->equality == rel\n");} | equality NOTEQUAL rel {printf("equality->equality != rel\n");} | rel {printf("equality->rel\n");} ; rel: expr LT expr {printf("rel->expr <= expr\n");} | expr LE expr {printf("rel->expr < expr\n");} | expr GE expr {printf("rel->expr >= expr\n");} | expr GT expr {printf("rel->expr > expr\n");} | expr {printf("rel->expr\n");} ; expr: expr PLUS term {printf("expr-> expr + term;\n");} | expr MINUS term {printf("expr-> expr - term\n");} | term {printf("expr-> term\n");} ; term: term MULTI unary {printf("term-> term * unary\n");} | term DIV unary {printf("term-> term / unary\n");} | unary {printf("term-> unary\n");} ; unary: NOT unary {printf("unary-> ! unary\n");} | MINUS unary {printf("unary-> - unary\n");} | factor {printf("unary-> factor\n");} ; factor: OPENPAREN bool CLOSEPAREN {printf("factor-> ( bool )\n");} | loc {printf("factor-> loc\n");} | NUM {printf("factor-> NUM\n");} | REAL {printf("factor-> REAL\n");} | BOOL {printf("factor-> BOOL\n");} ; %% #include "lex.yy.c" char* typeToString(id_type_t* type){ char* typename=calloc(8,sizeof(char)); char* out=calloc(400,sizeof(char)); strcpy(out,"NULL"); if(type==NULL) return out; if(type->type==((void*)&float_var)) typename="float"; else if(type->type==((void*)&int_var)) typename="int"; else if(type->type==NULL) typename="NULL"; else typename="unknown"; sprintf(out,"{type=%s, dimension=%u, size=%u, subsize=%s}",typename,type->dimension,type->size,typeToString(type->subsize)); //printf("typeToString outputs: %s\n",out); return out; } void type_add_dim(id_type_t* type, int size){ while(type->subsize!=NULL){ type->dimension++; type=type->subsize; } type->dimension++; type->size=size; type->subsize=type_init(type->type); } id_type_t *type_init(void* type){ //Create the id_type id_type_t* newType; //Allocate memory newType = (id_type_t *) malloc(sizeof(id_type_t)); if (newType == NULL) { exit(EXIT_FAILURE); } newType->type=type; newType->dimension=0; newType->size=0; newType->subsize=NULL; //Return the new type return newType; } //Print out symbol table int print_table(){ list_entry_t* entry=head->list; while(entry!=NULL) { if(entry->value==NULL) printf("\t[%s] => NULL\n",(char*)entry->key); else printf("\t[%s] => %s\n",(char*)entry->key,typeToString((id_type_t*)entry->value)); //add code here to print value entry=entry->next; } } int main(int argc, char* argv[]){ head=list_init(cmp_string); yyin=fopen( argv[1], "r" ); if(yyin==NULL) exit(EXIT_FAILURE); errorcount=0; int parse = yyparse(); printf("\n\nParsing Result: \n\tParser Returns: %i\n\tErrors Found: %i\n",parse,errorcount); printf("\nSymbol Table:\n"); print_table(); printf("\n\nProgram End\n"); return 0; }