%{ #include extern yylineno; %} %token PROGRAM_T INTEGER_T REAL_T OF_T VAR_T ARRAY_T %token PROCEDURE_T FUNCTION_T BEGIN_T END_T ELSE_T THEN_T DO_T %token READ_T WRITE_T IF_T WHILE_T %token ASSIGN_OP DOTDOT NOT_T %token ID NUM REAL_NUM %left REL_OP %left AND_T OR_T %left NOT_T %left '+' '-' %left '*' '/' MOD_T %% program : PROGRAM_T ID '(' id_list ')' ';' declarations subprograms compound_stmt '.' ; id_list : id_list ',' ID | ID ; declarations : declarations VAR_T id_list ':' type ';' | {/* empty */} ; type : standard_type | ARRAY_T '[' NUM DOTDOT NUM ']' OF_T standard_type ; standard_type : INTEGER_T | REAL_T ; subprograms : subprograms subprogram ';' | {/* empty */} ; subprogram : subprogram_head declarations compound_stmt ; subprogram_head : FUNCTION_T ID arguments ':' standard_type ';' | PROCEDURE_T ID arguments ';' ; arguments : '(' param_list ')' | {/* empty */} ; param_list : param_list ';' id_list ':' type | id_list ':' type ; compound_stmt : BEGIN_T opt_stmts END_T ; opt_stmts : stmt_list | {/* empty */} ; stmt_list : stmt | stmt_list ';' stmt ; stmt : ID ASSIGN_OP expression | ID '[' expression ']' ASSIGN_OP expression | procedure_stmt | compound_stmt | IF_T expression THEN_T stmt ELSE_T stmt | WHILE_T expression DO_T stmt | READ_T '(' variable_list ')' | WRITE_T '(' expression_list ')' ; variable_list : variable_list ',' variable | variable ; variable : ID | ID '[' expression ']' ; procedure_stmt : ID | ID '(' expression_list ')' ; expression_list : expression_list ',' expression | expression ; expression : expression REL_OP expression | expression '+' expression | expression '-' expression | expression '*' expression | expression '/' expression | expression MOD_T expression | expression AND_T expression | expression OR_T expression | NOT_T expression | '-' expression | ID | ID '[' expression ']' | ID '(' expression_list ')' | NUM | REAL_NUM | '(' expression ')' ; %% yyerror() { printf("Syntax error line %d\n",yylineno); }