%start prog %token IDENT %token STRINGLIT %token INTLIT %token INTEGER STRING %token IF WHILE RETURN PRINT ELSE %token EQ NEQ LT GT LEQ GEQ %left PLUS MINUS %left MULT DIV %right UMINUS %token OPENPAR CLOSEPAR %token SEMICOLON COMMA %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 COMMA 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 | IF OPENPAR boolexpr CLOSEPAR body ELSE 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 COMMA arglist ; %%