%start prog %token IDENT %token STRINGLIT %token INTLIT %token INTEGER STRING %token IF WHILE RETURN PRINT %token EQ NEQ LT GT LEQ GEQ %left PLUS MINUS %left MULT DIV %right UMINUS %token OPENPAR CLOSEPAR %token SEMICOLON COMA %token OPENCURLY CLOSECURLY %token ERROR %% prog: /* Nothing */ | prog def ; def: vardef | fundef ; vardef: type IDENT SEMICOLON ; fundef: type IDENT OPENPAR params CLOSEPAR body ; type: STRING | INTEGER ; params: /* empty */ | paramlist ; paramlist: param | paramlist COMA param ; param: type IDENT ; body: OPENCURLY vardefs stmts CLOSECURLY ; vardefs: /* empty */ | vardefs vardef ; stmts: /* empty */ | stmts stmt ; stmt: while_stmt | if_stmt | ret_stmt | print_stmt | assign | funcall_stmt ; while_stmt: WHILE OPENPAR boolexpr CLOSEPAR body } ; if_stmt: IF OPENPAR boolexpr CLOSEPAR body ; ret_stmt: RETURN expr SEMICOLON ; print_stmt: PRINT expr SEMICOLON ; assign: IDENT EQ expr SEMICOLON ; funcall_stmt: funcall SEMICOLON } ; boolexpr: expr EQ expr | expr NEQ expr | expr LT expr | expr GT expr | expr LEQ expr | expr GEQ expr ; expr: funcall | INTLIT | IDENT | STRINGLIT | OPENPAR expr CLOSEPAR | expr PLUS expr | expr MINUS expr | expr MULT expr | expr DIV expr | MINUS expr %prec UMINUS ; funcall: IDENT OPENPAR args CLOSEPAR ; args: /* empty */ | arglist ; arglist: expr |expr COMA arglist ; %%