program: structs stmts ; stmts: ( stmt )+ ; structs: ( "struct" ID maybe_typarms "{" ( field )+ "}" )* ; stmt: "var" ID "=" expr ";" | "print" expr ";" | "{" stmts "}" | expr "=" expr ";" | "skip" ";" | "fun" ID maybe_typarms "(" params ")" ":" type stmt | "if" "(" expr ")" stmt ( "else" stmt )? | "while" "(" expr ")" stmt ; field: ID ":" type ";" ; param: ID ":" type ; params: ( param ( "," param )* )? ; type: "int" | "string" | "(" types ")" "->" type | ID ( "[" types "]" )? ; types: ( type ( "," type )* )? ; exprs: ( expr ( "," expr )* )? ; maybe_typarms: ( "[" ID ( "," ID )* "]" )? ; expr: cmp_expr; cmp_expr: add_expr ( CMP add_expr )? ; add_expr: mult_expr (PLUS mult_expr)* ; mult_expr: call_expr (MULT call_expr)* ; call_expr: base_expr ( "(" exprs ")" | "." ID )* | ( "new" | "null" ) ID ( "[" types "]" )? ; base_expr: ID ( "[" types "]" )? | INT | STRING | "is_null" "(" expr ")" | "(" expr ")" ; ID : LETTER ( LETTER | DIGIT )* ; INT : ( DIGIT )+ ; LETTER : ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ; DIGIT : ( '0' .. '9' ) ; STRING : '"' (~ '"')* '"' ; PLUS : ( '+' | '-' ); MULT : ( '*' | '/' | '%' ); CMP : '<' | '>' | "<=" | ">=" | "!=" | "=="; COMMENT : "//" (~ '\n')* '\n' | '#' (~ '\n')* '\n' ; WHITESPACE: (' ' | '\r' | '\n' | '\t') ; // vim: ft=antlr