使用AntlrWorks编写了以下Expr.g语法文件,考虑到便与后期遍历树构造节点方便,添加了一些虚Token,例如BINARY。
语法文件内容如下:
1
grammar Expr;
2
3 options {
4 output = AST;
5 ASTLabelType = CommonTree;
6 // language=CSharp;
7 }
8
9 tokens {
10 CALL;
11 INDEX;
12 BINARY;
13 UNARY;
14 CONST;
15 VAR;
16 FIELD;
17 }
18
19 expr
20 : logicalOrExpr
21 ;
22
23 logicalOrExpr
24 : (logicalAndExpr -> logicalAndExpr) (OR b = logicalAndExpr -> ^ (BINARY OR $logicalOrExpr $b)) *
25 ;
26
27 logicalAndExpr
28 : (equalityExpr -> equalityExpr) (AND b = equalityExpr -> ^ (BINARY AND $logicalAndExpr $b)) *
29 ;
30
31 equalityExpr
32 : (relationalExpr -> relationalExpr) ((a = EQUALS | a = NOTEQUALS) b = relationalExpr -> ^ (BINARY $a $equalityExpr $b)) *
33 ;
34
35 relationalExpr
36 : (additiveExpr -> additiveExpr) ((a = LT | a = LTEQ | a = GT | a = GTEQ) b = additiveExpr -> ^ (BINARY $a $relationalExpr $b)) ?
37 ;
38
39 additiveExpr
40 : (multiplyExpr -> multiplyExpr) ((a = PLUS | a = MINUS) b = multiplyExpr -> ^ (BINARY $a $additiveExpr $b)) *
41 ;
42
43 multiplyExpr
44 : (powExpr -> powExpr) ((a = MUL | a = DIV | a = MOD) b = powExpr ->^ (BINARY $a $multiplyExpr $b)) *
45 ;
46
47 powExpr
48 : (unaryExpr -> unaryExpr) (POWER b = unaryExpr -> ^ (BINARY POWER $powExpr $b)) ?
49 ;
50
51 unaryExpr
52 : (a = PLUS | a = MINUS | a = NOT) unaryExpr -> ^ (UNARY $a unaryExpr)
53 | memberExpr
54 ;
55
56 memberExpr
57 : basicExpr ^ (memberAccessExpr | indexerExpr) *
58 ;
59
60 basicExpr
61 : constant | varExpr | methodExpr | parenExpr;
62
63 parenExpr
64 : LPAREN expr RPAREN -> expr
65 ;
66
67 constant
68 : (a = INTEGER_LITERAL | a = DECIMAL_LITERAL | a = DATETIME_LITERAL | a = STRING_LITERAL | a = BOOL_LITERAL) -> ^ (CONST $a)
69 ;
70
71 memberAccessExpr
72 : ' . ' ! memberFunctionExpr
73 ;
74
75 memberFunctionExpr
76 : fieldPropertyExpr -> ^ (FIELD fieldPropertyExpr) | methodExpr
77 ;
78
79 fieldPropertyExpr
80 : IDENTIFIER
81 ;
82
83 varExpr
84 : IDENTIFIER -> ^ (VAR IDENTIFIER)
85 ;
86 methodExpr
87 : IDENTIFIER LPAREN (argument (COMMA argument) * ) ? RPAREN -> ^ (CALL IDENTIFIER argument * )
88 ;
89
90 indexerExpr
91 : LBRACKET argument (COMMA argument) * RBRACKET -> ^ (INDEX argument + )
92 ;
93
94 argument
95 : expr
96 ;
97
98
99 AND
100 : ' and '
101 ;
102
103 OR
104 : ' or '
105 ;
106
107 NOT
108 : ' not '
109 ;
110
111 COMMA
112 : ' , '
113 ;
114
115 PLUS
116 : ' + '
117 ;
118
119 MINUS
120 : ' - '
121 ;
122
123 MUL
124 : ' * '
125 ;
126
127 DIV
128 : ' / '
129 ;
130
131 MOD
132 : ' % '
133 ;
134
135 POWER
136 : ' ^ '
137 ;
138
139 EQUALS : ' = ' ;
140
141 NOTEQUALS
142 : ' != ' | ' <> ' ;
143
144 LT : ' < ' ;
145 LTEQ : ' <= ' ;
146 GT : ' > ' ;
147 GTEQ : ' >= ' ;
148
149 LPAREN
150 : ' ( '
151 ;
152
153 RPAREN : ' ) '
154 ;
155
156 LBRACKET
157 : ' [ '
158 ;
159
160 RBRACKET
161 : ' ] '
162 ;
163
164 DATETIME_LITERAL
165 : ' \ '' STRING_LITERAL ' \ ''
166 ;
167
168 STRING_LITERAL
169 : ' " ' ( ~ ' " ' ) * ' " '
170 ;
171
172 BOOL_LITERAL
173 : ' true ' | ' True ' | ' false ' | ' False '
174 ;
175
176 IDENTIFIER
177 : LETTER (LETTER | Digit) *
178 ;
179
180 fragment
181 LETTER
182 : ' A ' .. ' Z ' | ' a ' .. ' z ' | ' _ '
183 ;
184
185 DECIMAL_LITERAL
186 : (INTEGER_LITERAL) ? ' . ' Digit * Exponent ?
187 ;
188
189 fragment
190 Exponent
191 : ( ' e ' | ' E ' ) INTEGER_LITERAL
192 ;
193
194 INTEGER_LITERAL
195 : Digit +
196 ;
197
198 fragment
199 Digit
200 : ' 0 ' .. ' 9 '
201 ;
202
203
204
205 /* Ignore white spaces */
206 WS
207 : ( ' ' | ' \r ' | ' \t ' | ' \u000C ' | ' \n ' ) {$channel = HIDDEN;}
208 ;
209
2
3 options {
4 output = AST;
5 ASTLabelType = CommonTree;
6 // language=CSharp;
7 }
8
9 tokens {
10 CALL;
11 INDEX;
12 BINARY;
13 UNARY;
14 CONST;
15 VAR;
16 FIELD;
17 }
18
19 expr
20 : logicalOrExpr
21 ;
22
23 logicalOrExpr
24 : (logicalAndExpr -> logicalAndExpr) (OR b = logicalAndExpr -> ^ (BINARY OR $logicalOrExpr $b)) *
25 ;
26
27 logicalAndExpr
28 : (equalityExpr -> equalityExpr) (AND b = equalityExpr -> ^ (BINARY AND $logicalAndExpr $b)) *
29 ;
30
31 equalityExpr
32 : (relationalExpr -> relationalExpr) ((a = EQUALS | a = NOTEQUALS) b = relationalExpr -> ^ (BINARY $a $equalityExpr $b)) *
33 ;
34
35 relationalExpr
36 : (additiveExpr -> additiveExpr) ((a = LT | a = LTEQ | a = GT | a = GTEQ) b = additiveExpr -> ^ (BINARY $a $relationalExpr $b)) ?
37 ;
38
39 additiveExpr
40 : (multiplyExpr -> multiplyExpr) ((a = PLUS | a = MINUS) b = multiplyExpr -> ^ (BINARY $a $additiveExpr $b)) *
41 ;
42
43 multiplyExpr
44 : (powExpr -> powExpr) ((a = MUL | a = DIV | a = MOD) b = powExpr ->^ (BINARY $a $multiplyExpr $b)) *
45 ;
46
47 powExpr
48 : (unaryExpr -> unaryExpr) (POWER b = unaryExpr -> ^ (BINARY POWER $powExpr $b)) ?
49 ;
50
51 unaryExpr
52 : (a = PLUS | a = MINUS | a = NOT) unaryExpr -> ^ (UNARY $a unaryExpr)
53 | memberExpr
54 ;
55
56 memberExpr
57 : basicExpr ^ (memberAccessExpr | indexerExpr) *
58 ;
59
60 basicExpr
61 : constant | varExpr | methodExpr | parenExpr;
62
63 parenExpr
64 : LPAREN expr RPAREN -> expr
65 ;
66
67 constant
68 : (a = INTEGER_LITERAL | a = DECIMAL_LITERAL | a = DATETIME_LITERAL | a = STRING_LITERAL | a = BOOL_LITERAL) -> ^ (CONST $a)
69 ;
70
71 memberAccessExpr
72 : ' . ' ! memberFunctionExpr
73 ;
74
75 memberFunctionExpr
76 : fieldPropertyExpr -> ^ (FIELD fieldPropertyExpr) | methodExpr
77 ;
78
79 fieldPropertyExpr
80 : IDENTIFIER
81 ;
82
83 varExpr
84 : IDENTIFIER -> ^ (VAR IDENTIFIER)
85 ;
86 methodExpr
87 : IDENTIFIER LPAREN (argument (COMMA argument) * ) ? RPAREN -> ^ (CALL IDENTIFIER argument * )
88 ;
89
90 indexerExpr
91 : LBRACKET argument (COMMA argument) * RBRACKET -> ^ (INDEX argument + )
92 ;
93
94 argument
95 : expr
96 ;
97
98
99 AND
100 : ' and '
101 ;
102
103 OR
104 : ' or '
105 ;
106
107 NOT
108 : ' not '
109 ;
110
111 COMMA
112 : ' , '
113 ;
114
115 PLUS
116 : ' + '
117 ;
118
119 MINUS
120 : ' - '
121 ;
122
123 MUL
124 : ' * '
125 ;
126
127 DIV
128 : ' / '
129 ;
130
131 MOD
132 : ' % '
133 ;
134
135 POWER
136 : ' ^ '
137 ;
138
139 EQUALS : ' = ' ;
140
141 NOTEQUALS
142 : ' != ' | ' <> ' ;
143
144 LT : ' < ' ;
145 LTEQ : ' <= ' ;
146 GT : ' > ' ;
147 GTEQ : ' >= ' ;
148
149 LPAREN
150 : ' ( '
151 ;
152
153 RPAREN : ' ) '
154 ;
155
156 LBRACKET
157 : ' [ '
158 ;
159
160 RBRACKET
161 : ' ] '
162 ;
163
164 DATETIME_LITERAL
165 : ' \ '' STRING_LITERAL ' \ ''
166 ;
167
168 STRING_LITERAL
169 : ' " ' ( ~ ' " ' ) * ' " '
170 ;
171
172 BOOL_LITERAL
173 : ' true ' | ' True ' | ' false ' | ' False '
174 ;
175
176 IDENTIFIER
177 : LETTER (LETTER | Digit) *
178 ;
179
180 fragment
181 LETTER
182 : ' A ' .. ' Z ' | ' a ' .. ' z ' | ' _ '
183 ;
184
185 DECIMAL_LITERAL
186 : (INTEGER_LITERAL) ? ' . ' Digit * Exponent ?
187 ;
188
189 fragment
190 Exponent
191 : ( ' e ' | ' E ' ) INTEGER_LITERAL
192 ;
193
194 INTEGER_LITERAL
195 : Digit +
196 ;
197
198 fragment
199 Digit
200 : ' 0 ' .. ' 9 '
201 ;
202
203
204
205 /* Ignore white spaces */
206 WS
207 : ( ' ' | ' \r ' | ' \t ' | ' \u000C ' | ' \n ' ) {$channel = HIDDEN;}
208 ;
209
在AntlrWorks调试以下语句:2-3+IIF(true=false, ds.b[1].id+bb, pp())
解析后的AST为:
![AST.jpg](https://i-blog.csdnimg.cn/blog_migrate/251035d17ffb617d9c19e34e76a4bfd5.jpeg)