\r
prog: (decl)+ EOF;\r
\r
-decl: varDecl\r
+decl: varDecl ';'\r
| funcDecl\r
| structDecl\r
;\r
\r
varDecl: 'var' var;\r
var: varName (':' type) ('=' expr)?;\r
+varInit: varName (':' type) ('=' expr);\r
\r
-type: typeName;\r
+type: typeName (typeModifier)*;\r
+typeModifier: '*' | ('[' (INT_LIT)? ']');\r
\r
\r
funcDecl: 'func' func;\r
func: funcName '(' parameter ')' (':' type) body;\r
-parameter: (firstParameter (additionalParameter)*)?;\r
-firstParameter: var;\r
-additionalParameter: ',' var;\r
+parameter: (var (',' var)*)?;\r
\r
body: '{' stmt* '}';\r
\r
\r
structDecl: 'struct' structName '{' structMember* '}';\r
structMember: structVar | structMethod;\r
-structVar: var;\r
+structVar: var ';';\r
structMethod: func;\r
\r
\r
-stmt: (varDecl\r
- | conditional\r
- | loop\r
- | assignment\r
- | returnStmt\r
- | expr) ;\r
+stmt: varDecl ';'\r
+ | ifStmt\r
+ | switchStmt\r
+ | forStmt\r
+ | whileStmt\r
+ | assignStmt ';'\r
+ | returnStmt ';'\r
+ | expr ';';\r
\r
-conditional: ifCond;\r
-ifCond: 'if' expr body;\r
+ifStmt: 'if' expr body elseIfStmt* elseStmt?;\r
+elseIfStmt: 'else' 'if' expr body;\r
+elseStmt: 'else' body;\r
\r
-loop: whileLoop;\r
-whileLoop: 'while' expr body;\r
+switchStmt: 'switch' identifierExpr switchBody;\r
+switchBody: '{' switchCase* '}';\r
+switchCase: 'case' expr body;\r
\r
-assignment: identifier '=' expr;\r
+forStmt: 'for' (varInit | assignStmt) ',' expr ',' expr body;\r
+\r
+whileStmt: 'while' expr body;\r
+\r
+assignStmt: identifierExpr '=' expr;\r
\r
returnStmt: 'return' expr;\r
\r
-expr: funcCall\r
- | literal\r
- | identifier\r
- | subscript\r
- | memberAccess\r
+expr: funcExpr\r
+ | litExpr\r
+ | identifierExpr\r
| parenExpr\r
- | operatorExpr;\r
-\r
-nonOpExpr: funcCall\r
- | literal\r
- | identifier\r
- | subscript\r
- | memberAccess\r
- | parenExpr;\r
+ | accessExpr\r
+ | opExpr;\r
\r
-nonSubscriptExpr: funcCall\r
- | identifier\r
- | memberAccess\r
- | parenExpr;\r
+/* op */\r
+nonOpExpr: funcExpr\r
+ | litExpr\r
+ | identifierExpr\r
+ | parenExpr\r
+ | accessExpr;\r
\r
-funcCall: funcName '(' (expr (',' expr)*)? ')';\r
+/* lit access op */\r
+nonAccessExpr: funcExpr\r
+ | identifierExpr\r
+ | parenExpr;\r
\r
-operatorExpr: binaryOperator;\r
-binaryOperator: nonOpExpr BINARY_OPERATOR nonOpExpr (BINARY_OPERATOR nonOpExpr)*;\r
+funcExpr: funcName '(' (expr (',' expr)*)? ')';\r
\r
-identifier: varName;\r
+opExpr: binaryOp | prefixOp | postfixOp | ternaryOp;\r
+binaryOp: nonOpExpr binary_op nonOpExpr (binary_op nonOpExpr)*;\r
+prefixOp: prefix_op nonOpExpr;\r
+postfixOp: nonOpExpr postfix_op;\r
+ternaryOp: nonOpExpr '?' expr ':' expr;\r
\r
-literal: INTLIT;\r
+identifierExpr: varName;\r
\r
-subscript: nonSubscriptExpr '[' expr ']';\r
+litExpr: INT_LIT | DECIMAL_LIT | STRING_LIT | BOOL_LIT;\r
\r
-memberAccess: identifier '.' identifier;\r
+accessExpr: nonAccessExpr (accessSubExpr)+;\r
+accessSubExpr: accessMember | accessBrackets;\r
+accessMember: ('.' | '->') identifierExpr;\r
+accessBrackets: '[' expr ']';\r
\r
parenExpr: '(' expr ')';\r
\r
structName: NAME;\r
\r
\r
-BINARY_OPERATOR:\r
- '+' | '-' | '*' | '/'\r
- | '==' | '!='\r
- | '<' | '>';\r
-INTLIT: ('+' | '-')? [0-9]+;\r
+postfix_op:\r
+ '++' | '--';\r
+prefix_op:\r
+ '+' | '-' | '!' | '~' | '&' | '*' | postfix_op;\r
+binary_op:\r
+ '+' | '-' | '*' | '/' | '%' | '&' | '<' | '|' | '^' | '>' |\r
+ '==' | '!=' | '<=' | '>=' | '<' | '>' |\r
+ '<<' | '>>' | '||' | '&&' | '&=' | '|=' | '^=' |\r
+ '<<=' | '>>=' | '+=' | '-=' | '*=' | '/=' | '%=';\r
+\r
+INT_LIT: ('+' | '-')? [0-9]+;\r
+DECIMAL_LIT: ('+' | '-')* [0-9]+ '.' [0-9]+;\r
+STRING_LIT: '"' [^"]* '"';\r
+BOOL_LIT: 'true' | 'false';\r
+\r
NAME: ([a-z] | [A-Z] | [0-9])+;\r
WS: [ \t\r\n]+ -> skip;\r
NEWLINE: [\r\n]+;\r