%{ #include extern lineno; %} %union { int i; char s[100]; } %token TOKTRUE %token TOKVAR %token TOKOF %token TOKNOT %token TOKOR %token TOKAND %token TOKFUNCTION %token TOKPROCEDURE %token TOKBOOL %token TOKINT %token TOKCHAR %token TOKARRAY %token TOKDO %token TOKWHILE %token TOKELSE %token TOKTHEN %token TOKIF %token TOKEND %token TOKBEGIN %token TOKMOD %token TOKFALSE %token IDENTIFIER %token PLUS %token MINUS %token MULTIPLY %token DIVIDE %token LES %token LEQ %token EQ %token GT %token GE %token NEQ %token COMMA %token SEMI %token OPENPAR %token CLOSEPAR %token COLON %token ASSIGNOP %token STRING %token INTCONST %token LB %token RB %left LES LEQ EQ GT GE NEQ %left TOKOR MINUS PLUS %left TOKAND MULTIPLY DIVIDE TOKMOD %left TOKNOT UMINUS %% program: TOKPROCEDURE IDENTIFIER declaration compound_stmt |TOKPROCEDURE error {our_error(1);} declaration compound_stmt ; procedure: TOKPROCEDURE IDENTIFIER formal_par_list declaration compound_stmt | TOKPROCEDURE error formal_par_list {our_error(2);} declaration compound_stmt ; forward_procedure: TOKPROCEDURE IDENTIFIER formal_par_list SEMI | TOKPROCEDURE error SEMI {our_error(3);} ; function: fun_declare declaration compound_stmt ; forward_function: fun_declare SEMI ; fun_declare: TOKFUNCTION IDENTIFIER formal_par_list COLON simple_type | TOKFUNCTION error {our_error(4);} formal_par_list COLON simple_type | TOKFUNCTION IDENTIFIER formal_par_list error {our_error(5);}simple_type ; declaration: |declaration procedure |declaration function |declaration forward_procedure |declaration forward_function |declaration var_decl ; assgmnt_stmt: leftexpr ASSIGNOP r_expr |leftexpr error r_expr{our_error(11);} ; actual_par_list: | r_expr | actual_par_list COMMA r_expr | actual_par_list error r_expr {our_error(21);} ; compound_stmt: TOKBEGIN TOKEND | TOKBEGIN stmt_block TOKEND | TOKBEGIN stmt_block error {our_error(6);} ; stmt_block: stmt |stmt SEMI stmt |stmt SEMI {our_error(0);} ; stmt: compound_stmt |assgmnt_stmt |if_stmt |while_stmt |IDENTIFIER OPENPAR actual_par_list CLOSEPAR |IDENTIFIER OPENPAR CLOSEPAR | error SEMI {yyerror(27);} ; if_stmt: TOKIF boolexpr TOKTHEN stmt TOKELSE stmt |TOKIF boolexpr error TOKELSE {our_error(8);} |TOKIF boolexpr TOKTHEN stmt |TOKIF boolexpr error stmt {our_error(9);} ; while_stmt: TOKWHILE boolexpr TOKDO stmt |TOKWHILE boolexpr error stmt {our_error(10);} ; binary_op: TOKAND |TOKOR |MULTIPLY |MINUS |PLUS |DIVIDE |TOKMOD ; rel_op: LES | LEQ | GT | GE | EQ | NEQ ; type: simple_type | array_declare ; simple_type: TOKCHAR | TOKINT | TOKBOOL | error {our_error(25);} ; array_declare: TOKARRAY LB INTCONST RB TOKOF simple_type |TOKARRAY error INTCONST {our_error(14);} RB TOKOF simple_type |TOKARRAY LB INTCONST error TOKOF {our_error(14);} simple_type |TOKARRAY error INTCONST {our_error(14);} TOKOF simple_type |TOKARRAY LB INTCONST RB error simple_type {our_error(12);} |TOKARRAY error INTCONST error simple_type {our_error(13);} |TOKARRAY LB error RB {our_error(15);} TOKOF simple_type |TOKARRAY error RB {our_error(13);} TOKOF simple_type |TOKARRAY error TOKOF {our_error(13);} simple_type |TOKARRAY error simple_type {our_error(13);} ; constant: INTCONST | STRING | TOKTRUE | TOKFALSE ; var_decl: IDENTIFIER COLON type SEMI |IDENTIFIER var_list COLON type SEMI |IDENTIFIER COLON type {our_error(20);} |IDENTIFIER var_list COLON type {our_error(20);} |IDENTIFIER var_list type {our_error(21);} ; var_list: COMMA IDENTIFIER |var_list COMMA IDENTIFIER |IDENTIFIER {our_error(21);} ; leftexpr: IDENTIFIER |IDENTIFIER LB r_expr RB |IDENTIFIER LB r_expr {our_error(23);} |IDENTIFIER r_expr RB {our_error(23);} ; r_expr: constant | r_expr binary_op r_expr | IDENTIFIER | IDENTIFIER LB r_expr RB | TOKNOT r_expr | MINUS r_expr %prec UMINUS | OPENPAR r_expr CLOSEPAR | OPENPAR r_expr SEMI {our_error(16);} | IDENTIFIER OPENPAR actual_par_list CLOSEPAR | IDENTIFIER LB r_expr {our_error(17);} | IDENTIFIER OPENPAR actual_par_list error SEMI{our_error(16);} ; boolexpr: r_expr rel_op r_expr ; formal_par_list: OPENPAR CLOSEPAR |OPENPAR formal_rec CLOSEPAR |OPENPAR formal_rec error{our_error(18);} ; formal_rec: var_decl | TOKVAR var_decl | formal_rec TOKVAR var_decl | formal_rec var_decl ; %% int yyerror() { printf(""); } int our_error (int our_errno) { static int ourerrline=0; if (ourerrline !=lineno) { printf("line %4i: SYNTAX ERROR ::",lineno); switch (our_errno){ case 0: printf(" Semicolon expected\n",yylval);break; case 1: printf(" Error in declaration \n");break; case 2: printf(" Not a procedure name \n");break; case 3: printf(" Wrong procedure declaration\n");break; case 4: printf(" Not a function name\n");break; case 5: printf(" Colon expected at function declaration\n");break; case 6: printf(" Unbalanced BEGIN-END\n");break; case 7: printf(" Fatal: Expected at least one block BEGIN-END\n");break; case 8: printf(" Missing THEN from if-then-else\n");break; case 9: printf(" Missing THEN from if-then\n");break; case 10: printf(" WHILE without DO\n");break; case 11: printf(" Wrong assignment command\n");break; case 12: printf(" \"of\" Expected at array declaration\n");break; case 13: printf(" Wrong array declaration\n");break; case 14: printf(" Missing brackets at array declaration\n");break; case 15: printf(" Expected integer constant at array index\n");break; case 16: printf(" Unbalanced parenthesis\n");break; case 17: printf(" Missing brackets at array parameter\n");break; case 18: printf(" Unbalanced parenthesis at subroutine\n");break; case 19: printf(" Invalid parameter list\n");break; case 20: printf(" Missing semi at var_decl\n");break; case 21: printf(" Missing COMMA at variable list\n");break; case 22: printf(" Missing COLON at var decl\n");break; case 23: printf(" Missing brackets at array expression\n");break; case 24: printf(" Invalid type\n");break; case 25: printf(" Missing type at declaration\n");break; case 26: printf(" Constant expected\n");break; case 27: printf(" Error in statement\n");break; } ourerrline=lineno; } } main() { yyparse(); }