\r
prog: (decl)+ EOF;\r
\r
-decl: varDecl\r
+decl: varDecl ';'\r
| funcDecl\r
| structDecl\r
+ | namespaceDecl\r
;\r
\r
+namespaceDecl: 'namespace' typeName '{' decl* '}';\r
+\r
varDecl: 'var' var;\r
var: varName (':' type) ('=' expr)?;\r
varInit: varName (':' type) ('=' expr);\r
\r
-type: typeName (typeModifier)*;\r
-typeModifier: '*' | '[' NUMBER? ']';\r
+type: namespaceSpecifier* typeName genericInstantiation? (typeModifier)*;\r
+typeModifier: '*' | ('[' (INT_LIT)? ']');\r
\r
+namespaceSpecifier: typeName '::';\r
\r
funcDecl: 'func' func;\r
-func: funcName '(' parameter ')' (':' type) body;\r
+func: funcName genericDecl? '(' parameter ')' (':' type) (body | ';');\r
parameter: (var (',' var)*)?;\r
\r
body: '{' stmt* '}';\r
\r
\r
-structDecl: 'struct' structName '{' structMember* '}';\r
-structMember: structVar | structMethod;\r
-structVar: var;\r
+structDecl: 'struct' structName genericDecl? '{' structMember* '}';\r
+structMember: privateDecl? structVar | structMethod;\r
+structVar: var ';';\r
structMethod: func;\r
+privateDecl: 'private';\r
\r
+genericDecl: '<' typeName (',' typeName)* '>';\r
+genericInstantiation: '<' type (',' type)* '>';\r
\r
-stmt: varDecl\r
+stmt: varDecl ';'\r
| ifStmt\r
| switchStmt\r
| forStmt\r
| whileStmt\r
- | assignStmt\r
- | returnStmt\r
- | expr;\r
+ | assignStmt ';'\r
+ | returnStmt ';'\r
+ | expr ';';\r
\r
-ifStmt: 'if' expr body ('else' 'if' expr body)* ('else' body)?;\r
+ifStmt: 'if' expr body elseIfStmt* elseStmt?;\r
+elseIfStmt: 'else' 'if' expr body;\r
+elseStmt: 'else' body;\r
\r
-switchStmt: 'switch' identifierExpr switchBody;\r
-switchBody: '{' ('case' expr body)* '}';\r
+switchStmt: 'switch' expr switchBody;\r
+switchBody: '{' switchCase* '}';\r
+switchCase: 'case' expr body;\r
\r
-forStmt: 'for' (varInit | assignStmt) ',' expr ',' expr body;\r
+forStmt: 'for' varInit ',' expr ',' expr body;\r
\r
whileStmt: 'while' expr body;\r
\r
-assignStmt: identifierExpr '=' expr;\r
+assignStmt: expr '=' expr;\r
\r
returnStmt: 'return' expr;\r
\r
-expr: funcExpr\r
- | litExpr\r
- | identifierExpr\r
- | parenExpr\r
- | accessExpr\r
- | opExpr;\r
-\r
-/* op */\r
-nonOpExpr: funcExpr\r
- | litExpr\r
- | identifierExpr\r
- | parenExpr\r
- | accessExpr;\r
-\r
-/* lit access op */\r
-nonAccessExpr: funcExpr\r
- | identifierExpr\r
- | parenExpr;\r
-\r
-funcExpr: funcName '(' (expr (',' expr)*)? ')';\r
-\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
-identifierExpr: varName;\r
-\r
-litExpr: INT_LIT | DECIMAL_LIT | STRING_LIT | BOOL_LIT;\r
+expr: namespaceSpecifier* funcName genericInstantiation? '(' (expr (',' expr)*)? ')' #funcExpr\r
+ | expr '.' funcName genericInstantiation? '(' (expr (',' expr)*)? ')' #methodExpr\r
+ | literal #litExpr\r
+ | '(' expr ')' #parenExpr\r
+ | expr (dot | arrow) varName #dotExpr\r
+ | prefix_op expr #prefixOpExpr\r
+ | expr postfix_op #postfixOpExpr\r
+ | expr binary_op expr #binaryOpExpr\r
+ | expr '?' expr ':' expr #ternaryOpExpr\r
+ | expr '[' expr ']' #bracketExpr\r
+ | namespaceSpecifier* varName #identifierExpr\r
+ ;\r
\r
-accessExpr: nonAccessExpr ((('.' | '->') identifierExpr) | ('[' expr ']'))+;\r
+dot: '.';\r
+arrow: '->';\r
\r
-parenExpr: '(' expr ')';\r
+literal: INT_LIT | DECIMAL_LIT | StringLit | BOOL_LIT;\r
\r
funcName: NAME;\r
varName: NAME;\r
structName: NAME;\r
\r
\r
-POSTFIX_OP:\r
+postfix_op:\r
'++' | '--';\r
-PREFIX_OP:\r
- [+!~&*-] | POSTFIX_OP;\r
-BINARY_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
+StringLit: '"' CharSeq '"';\r
+\r
+fragment CharSeq: Char+;\r
+fragment Char: ~["\\\r\n]\r
+ | '\\' ['"?abfnrtv\\]\r
+ | '\\\n'\r
+ | '\\\r\n'\r
+ ;\r
\r
NAME: ([a-z] | [A-Z] | [0-9])+;\r
WS: [ \t\r\n]+ -> skip;\r
NEWLINE: [\r\n]+;\r
-NUMBER: [0-9]+;\r
+COMMENT: '//' .*? '\n' -> skip;\r