]> gitweb.ps.run Git - toc/blob - Toc.g4
generic grammar
[toc] / Toc.g4
1 grammar Toc;\r
2 \r
3 prog: (decl)+ EOF;\r
4 \r
5 decl: varDecl ';'\r
6     | funcDecl\r
7     | structDecl\r
8     ;\r
9 \r
10 varDecl:  'var' var;\r
11 var:  varName (':' type) ('=' expr)?;\r
12 varInit:  varName (':' type) ('=' expr);\r
13 \r
14 type: typeName (typeModifier)*;\r
15 typeModifier: '*' | ('[' (INT_LIT)? ']');\r
16 \r
17 \r
18 funcDecl: 'func' func;\r
19 func: funcName genericDecl? '(' parameter ')' (':' type) body;\r
20 parameter: (var (',' var)*)?;\r
21 \r
22 body: '{' stmt* '}';\r
23 \r
24 \r
25 structDecl: 'struct' structName genericDecl? '{' structMember* '}';\r
26 structMember: structVar | structMethod;\r
27 structVar: var ';';\r
28 structMethod: func;\r
29 \r
30 genericDecl: '<' typeName (',' typeName)* '>';\r
31 \r
32 stmt: varDecl ';'\r
33     | ifStmt\r
34     | switchStmt\r
35     | forStmt\r
36     | whileStmt\r
37     | assignStmt ';'\r
38     | returnStmt ';'\r
39     | expr ';';\r
40 \r
41 ifStmt: 'if' expr body elseIfStmt* elseStmt?;\r
42 elseIfStmt: 'else' 'if' expr body;\r
43 elseStmt: 'else' body;\r
44 \r
45 switchStmt: 'switch' identifierExpr switchBody;\r
46 switchBody: '{' switchCase* '}';\r
47 switchCase: 'case' expr body;\r
48 \r
49 forStmt: 'for' (varInit | assignStmt) ',' expr ',' expr body;\r
50 \r
51 whileStmt: 'while' expr body;\r
52 \r
53 assignStmt: identifierExpr '=' expr;\r
54 \r
55 returnStmt: 'return' expr;\r
56 \r
57 expr: funcExpr\r
58     | litExpr\r
59     | identifierExpr\r
60     | parenExpr\r
61     | accessExpr\r
62     | opExpr;\r
63 \r
64 /* op */\r
65 nonOpExpr: funcExpr\r
66          | litExpr\r
67          | identifierExpr\r
68          | parenExpr\r
69          | accessExpr;\r
70 \r
71 /* lit access op */\r
72 nonAccessExpr: funcExpr\r
73              | identifierExpr\r
74              | parenExpr;\r
75 \r
76 funcExpr: funcName '(' (expr (',' expr)*)? ')';\r
77 \r
78 opExpr: binaryOp | prefixOp | postfixOp | ternaryOp;\r
79 binaryOp: nonOpExpr binary_op nonOpExpr (binary_op nonOpExpr)*;\r
80 prefixOp: prefix_op nonOpExpr;\r
81 postfixOp: nonOpExpr postfix_op;\r
82 ternaryOp: nonOpExpr '?' expr ':' expr;\r
83 \r
84 identifierExpr: varName;\r
85 \r
86 litExpr: INT_LIT | DECIMAL_LIT | STRING_LIT | BOOL_LIT;\r
87 \r
88 accessExpr: nonAccessExpr (accessSubExpr)+;\r
89 accessSubExpr: accessMember | accessBrackets;\r
90 accessMember: ('.' | '->') identifierExpr;\r
91 accessBrackets: '[' expr ']';\r
92 \r
93 parenExpr: '(' expr ')';\r
94 \r
95 funcName: NAME;\r
96 varName: NAME;\r
97 typeName: NAME;\r
98 structName: NAME;\r
99 \r
100 \r
101 postfix_op:\r
102     '++' | '--';\r
103 prefix_op:\r
104     '+' | '-' | '!' | '~' | '&' | '*' | postfix_op;\r
105 binary_op:\r
106     '+' | '-' | '*' | '/' | '%' | '&' | '<' | '|' | '^' | '>' |\r
107     '==' | '!=' | '<=' | '>=' | '<'  | '>' |\r
108     '<<' | '>>' | '||' | '&&' | '&=' | '|=' | '^=' |\r
109     '<<=' | '>>=' | '+=' | '-=' | '*=' | '/=' | '%=';\r
110 \r
111 INT_LIT: ('+' | '-')? [0-9]+;\r
112 DECIMAL_LIT: ('+' | '-')* [0-9]+ '.' [0-9]+;\r
113 STRING_LIT: '"' [^"]* '"';\r
114 BOOL_LIT: 'true' | 'false';\r
115 \r
116 NAME: ([a-z] | [A-Z] | [0-9])+;\r
117 WS: [ \t\r\n]+ -> skip;\r
118 NEWLINE: [\r\n]+;\r