1
2
3
4
5
6 using Cm.Ast;
7 using ParserFileTokens;
8
9 parser ExpressionParser
10 {
11 uselexer ParserFileLexer;
12
13 using LiteralParser.Literal;
14 using BasicTypeParser.BasicType;
15 using TemplateParser.TemplateId;
16 using TypeExprParser.TypeExpr;
17 using IdentifierParser.Identifier;
18
19 Expression(ParsingContext* ctx) : Node*
20 ::= Equivalence(ctx):equivalence{ return equivalence; }
21 ;
22
23 Equivalence(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
24 ::=
25 ( Implication(ctx):left{ s = span; expr.Reset(left); }
26 ( EQUIVALENCE{ if (!ctx->parsingConcept || ctx->parsingTemplateId) pass = false; }
27 Implication(ctx):right!{ s.end = span.end; expr.Reset(new EquivalenceNode(s, ctx->ModuleId(), expr.Release(), right)); }
28 )*
29 )
30 {
31 return expr.Release();
32 }
33 ;
34
35 Implication(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
36 ::=
37 ( Disjunction(ctx):left{ s = span; expr.Reset(left); }
38 ( IMPLICATION{ if (!ctx->parsingConcept || ctx->parsingTemplateId) pass = false; }
39 Implication(ctx):right!{ s.end = span.end; expr.Reset(new ImplicationNode(s, ctx->ModuleId(), expr.Release(), right)); }
40 )?
41 )
42 {
43 return expr.Release();
44 }
45 ;
46
47 Disjunction(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
48 ::=
49 ( Conjunction(ctx):left{ s = span; expr.Reset(left); }
50 ( DISJUNCTION{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; }
51 Conjunction(ctx):right!{ s.end = span.end; expr.Reset(new DisjunctionNode(s, ctx->ModuleId(), expr.Release(), right)); }
52 )*
53 )
54 {
55 return expr.Release();
56 }
57 ;
58
59 Conjunction(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
60 ::=
61 ( BitOr(ctx):left{ s = span; expr.Reset(left); }
62 ( AMPAMP{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; }
63 BitOr(ctx):right!{ s.end = span.end; expr.Reset(new ConjunctionNode(s, ctx->ModuleId(), expr.Release(), right)); }
64 )*
65 )
66 {
67 return expr.Release();
68 }
69 ;
70
71 BitOr(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
72 ::=
73 ( BitXor(ctx):left{ s = span; expr.Reset(left); }
74 ( BITOR{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; }
75 BitXor(ctx):right!{ s.end = span.end; expr.Reset(new BitOrNode(s, ctx->ModuleId(), expr.Release(), right)); }
76 )*
77 )
78 {
79 return expr.Release();
80 }
81 ;
82
83 BitXor(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
84 ::=
85 ( BitAnd(ctx):left{ s = span; expr.Reset(left); }
86 ( BITXOR{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; }
87 BitAnd(ctx):right!{ s.end = span.end; expr.Reset(new BitXorNode(s, ctx->ModuleId(), expr.Release(), right)); }
88 )*
89 )
90 {
91 return expr.Release();
92 }
93 ;
94
95 BitAnd(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
96 ::=
97 ( Equality(ctx):left{ s = span; expr.Reset(left); }
98 ( AMP{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; }
99 Equality(ctx):right!{ s.end = span.end; expr.Reset(new BitAndNode(s, ctx->ModuleId(), expr.Release(), right)); }
100 )*
101 )
102 {
103 return expr.Release();
104 }
105 ;
106
107 Equality(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s, var Operator op) : Node*
108 ::=
109 ( Relational(ctx):left{ s = span; expr.Reset(left); }
110 (
111 ( EQ{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else op = Operator.eq; }
112 | NEQ{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else op = Operator.neq; }
113 )
114 Relational(ctx):right!
115 {
116 switch (op)
117 {
118 case Operator.eq: s.end = span.end; expr.Reset(new EqualNode(s, ctx->ModuleId(), expr.Release(), right)); break;
119 case Operator.neq: s.end = span.end; expr.Reset(new NotEqualNode(s, ctx->ModuleId(), expr.Release(), right)); break;
120 }
121 }
122 )*
123 )
124 {
125 return expr.Release();
126 }
127 ;
128
129 Relational(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s, var Operator op) : Node*
130 ::=
131 ( Shift(ctx):left{ s = span; expr.Reset(left); }
132 (
133 ( LEQ{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { op = Operator.lessOrEq; ctx->PushParsingIsOrAs(false); } }
134 | GEQ{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { op = Operator.greaterOrEq; ctx->PushParsingIsOrAs(false); } }
135 | LANGLE{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { op = Operator.less; ctx->PushParsingIsOrAs(false); } }
136 | RANGLE{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { op = Operator.greater; ctx->PushParsingIsOrAs(false); } }
137 | IS{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { op = Operator.is_; ctx->PushParsingIsOrAs(true); } }
138 TypeExpr(ctx):isType
139 | AS{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { op = Operator.as_; ctx->PushParsingIsOrAs(true); } }
140 TypeExpr(ctx):asType
141 )
142 (Shift(ctx):right | empty{ if (!ctx->parsingIsOrAs) pass = false; })
143 {
144 ctx->PopParsingIsOrAs();
145 switch (op)
146 {
147 case Operator.lessOrEq: s.end = span.end; expr.Reset(new LessOrEqualNode(s, ctx->ModuleId(), expr.Release(), right)); break;
148 case Operator.greaterOrEq: s.end = span.end; expr.Reset(new GreaterOrEqualNode(s, ctx->ModuleId(), expr.Release(), right)); break;
149 case Operator.less: s.end = span.end; expr.Reset(new LessNode(s, ctx->ModuleId(), expr.Release(), right)); break;
150 case Operator.greater: s.end = span.end; expr.Reset(new GreaterNode(s, ctx->ModuleId(), expr.Release(), right)); break;
151 case Operator.is_: s.end = span.end; expr.Reset(new IsNode(s, ctx->ModuleId(), expr.Release(), isType)); break;
152 case Operator.as_: s.end = span.end; expr.Reset(new AsNode(s, ctx->ModuleId(), expr.Release(), asType)); break;
153 }
154 }
155 )*
156 )
157 {
158 return expr.Release();
159 }
160 ;
161
162 Shift(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s, var Operator op) : Node*
163 ::=
164 ( Additive(ctx):left{ s = span; expr.Reset(left); }
165 (
166 ( SHIFTLEFT{ if (ctx->parsingLvalue) pass = false; else op = Operator.shiftLeft; }
167 | SHIFTRIGHT{ if (ctx->parsingLvalue) pass = false; else op = Operator.shiftRight; }
168 )
169 empty{ ctx->BeginParsingArguments(); } Additive(ctx):right!
170 {
171 switch (op)
172 {
173 case Operator.shiftLeft: s.end = span.end; expr.Reset(new ShiftLeftNode(s, ctx->ModuleId(), expr.Release(), right)); break;
174 case Operator.shiftRight: s.end = span.end; expr.Reset(new ShiftRightNode(s, ctx->ModuleId(), expr.Release(), right)); break;
175 }
176 ctx->EndParsingArguments();
177 }
178 /
179 {
180 ctx->EndParsingArguments();
181 }
182 )*
183 )
184 {
185 return expr.Release();
186 }
187 ;
188
189 Additive(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s, var Operator op) : Node*
190 ::=
191 ( Multiplicative(ctx):left{ s = span; expr.Reset(left); }
192 (
193 ( PLUS{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else op = Operator.plus; }
194 | MINUS{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else op = Operator.minus; }
195 )
196 Multiplicative(ctx):right!
197 {
198 switch (op)
199 {
200 case Operator.plus: s.end = span.end; expr.Reset(new AddNode(s, ctx->ModuleId(), expr.Release(), right)); break;
201 case Operator.minus: s.end = span.end; expr.Reset(new SubNode(s, ctx->ModuleId(), expr.Release(), right)); break;
202 }
203 }
204 )*
205 )
206 {
207 return expr.Release();
208 }
209 ;
210
211 Multiplicative(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s, var Operator op) : Node*
212 ::=
213 ( Prefix(ctx):left{ s = span; expr.Reset(left); }
214 (
215 ( STAR{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else op = Operator.mul; }
216 | DIV{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else op = Operator.div; }
217 | REM{ if (ctx->parsingLvalue || ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else op = Operator.rem; }
218 )
219 Prefix(ctx):right!
220 {
221 switch (op)
222 {
223 case Operator.mul: s.end = span.end; expr.Reset(new MulNode(s, ctx->ModuleId(), expr.Release(), right)); break;
224 case Operator.div: s.end = span.end; expr.Reset(new DivNode(s, ctx->ModuleId(), expr.Release(), right)); break;
225 case Operator.rem: s.end = span.end; expr.Reset(new RemNode(s, ctx->ModuleId(), expr.Release(), right)); break;
226 }
227 }
228 )*
229 )
230 {
231 return expr.Release();
232 }
233 ;
234
235 Prefix(ParsingContext* ctx, var UniquePtr<Node> prefix, var Span s, var Operator op) : Node*
236 ::=
237 ( ( PLUSPLUS{ s = span; op = Operator.plusplus; }
238 | MINUSMINUS{ s = span; op = Operator.minusminus; }
239 | PLUS{ if (ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { s = span; op = Operator.plus; } }
240 | MINUS{ if (ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { s = span; op = Operator.minus; } }
241 | EXCLAMATION{ if (ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { s = span; op = Operator.not_; } }
242 | CPL{ if (ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { s = span; op = Operator.complement; } }
243 | STAR{ if (ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { s = span; op = Operator.deref; } }
244 | AMP{ if (ctx->parsingExpressionStatement && !ctx->parsingArguments) pass = false; else { s = span; op = Operator.addrOf; } }
245 )
246 Prefix(ctx):p
247 {
248 prefix.Reset(p);
249 s.end = span.end;
250 switch (op)
251 {
252 case Operator.plusplus: return new PrefixIncrementNode(s, ctx->ModuleId(), prefix.Release());
253 case Operator.minusminus: return new PrefixDecrementNode(s, ctx->ModuleId(), prefix.Release());
254 case Operator.plus: return new UnaryPlusNode(s, ctx->ModuleId(), prefix.Release());
255 case Operator.minus: return new UnaryMinusNode(s, ctx->ModuleId(), prefix.Release());
256 case Operator.not_: return new NotNode(s, ctx->ModuleId(), prefix.Release());
257 case Operator.complement: return new ComplementNode(s, ctx->ModuleId(), prefix.Release());
258 case Operator.deref: return new DerefNode(s, ctx->ModuleId(), prefix.Release());
259 case Operator.addrOf: return new AddrOfNode(s, ctx->ModuleId(), prefix.Release());
260 }
261 }
262 | Postfix(ctx):postfix{ return postfix; }
263 )
264 ;
265
266 Postfix(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
267 ::=
268 ( Primary(ctx):primary{ s = span; expr.Reset(primary); }
269 ( PLUSPLUS{ s.end = span.end; expr.Reset(new PostfixIncrementNode(s, ctx->ModuleId(), expr.Release())); }
270 | MINUSMINUS{ s.end = span.end; expr.Reset(new PostfixDecrementNode(s, ctx->ModuleId(), expr.Release())); }
271 | DOT Identifier(ctx):dotMember{ s.end = span.end; expr.Reset(new DotNode(s, ctx->ModuleId(), expr.Release(), dotMember)); }
272 | ARROW Identifier(ctx):arrowMember{ s.end = span.end; expr.Reset(new ArrowNode(s, ctx->ModuleId(), expr.Release(), arrowMember)); }
273 | LBRACKET{ ctx->PushParsingLvalue(false); ctx->PushParsingExpressionStatement(false); }
274 Expression(ctx):index{ ctx->PopParsingExpressionStatement(); ctx->PopParsingLvalue(); }
275 RBRACKET!{ s.end = span.end; expr.Reset(new IndexingNode(s, ctx->ModuleId(), expr.Release(), index)); }
276 | LPAREN{ expr.Reset(new InvokeNode(s, ctx->ModuleId(), expr.Release())); } ArgumentList(ctx, expr.Get()):args RPAREN!{ expr->SetSpanEnd(span.end); }
277 )*
278 )
279 {
280 return expr.Release();
281 }
282 ;
283
284 Primary(ParsingContext* ctx, var Span s) : Node*
285 ::= (LPAREN{ s = span; } Expression(ctx):expr RPAREN{ s.end = span.end; }){ return new ParenthesizedExpressionNode(s, ctx->ModuleId(), expr); }
286 | Literal(ctx):literal{ return literal; }
287 | BasicType(ctx):basicType{ return basicType; }
288 | TemplateId(ctx):templateId{ return templateId; }
289 | Identifier(ctx):id{ return id; }
290 | THIS{ return new ThisNode(span, ctx->ModuleId()); }
291 | BASE{ return new BaseNode(span, ctx->ModuleId()); }
292 | SizeOfExpr(ctx):sizeOf{ return sizeOf; }
293 | TypeNameExpr(ctx):typeName{ return typeName; }
294 | TypeIdExpr(ctx):typeId{ return typeId; }
295 | CastExpr(ctx):castExpr{ return castExpr; }
296 | ConstructExpr(ctx):constructExpr{ return constructExpr; }
297 | NewExpr(ctx):newExpr{ return newExpr; }
298 ;
299
300 SizeOfExpr(ParsingContext* ctx, var Span s) : Node*
301 ::= (SIZEOF{ s = span; } LPAREN! Expression(ctx):expr! RPAREN!){ s.end = span.end; return new SizeOfNode(s, ctx->ModuleId(), expr); }
302 ;
303
304 TypeNameExpr(ParsingContext* ctx, var Span s) : Node*
305 ::= (TYPENAME{ s = span; } LPAREN! Expression(ctx):expr! RPAREN!){ s.end = span.end; return new TypeNameNode(s, ctx->ModuleId(), expr); }
306 ;
307
308 TypeIdExpr(ParsingContext* ctx, var Span s) : Node*
309 ::= (TYPEID{ s = span; } LPAREN! Expression(ctx):expr! RPAREN!){ s.end = span.end; return new TypeIdNode(s, ctx->ModuleId(), expr); }
310 ;
311
312 CastExpr(ParsingContext* ctx, var Span s) : Node*
313 ::= (CAST{ s = span; } LANGLE! TypeExpr(ctx):typeExpr! RANGLE! LPAREN! Expression(ctx):expr! RPAREN!){ s.end = span.end; return new CastNode(s, ctx->ModuleId(), typeExpr, expr); }
314 ;
315
316 ConstructExpr(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
317 ::= (CONSTRUCT{ s = span; } LANGLE! TypeExpr(ctx):typeExpr! RANGLE!){ expr.Reset(new ConstructNode(s, ctx->ModuleId(), typeExpr)); } LPAREN! ExpressionList(ctx, expr.Get()):exprList! RPAREN!
318 {
319 expr->SetSpanEnd(span.end);
320 return expr.Release();
321 }
322 ;
323
324 NewExpr(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
325 ::= (NEW{ s = span; } TypeExpr(ctx):typeExpr!{ s.end = span.end; expr.Reset(new NewNode(s, ctx->ModuleId(), typeExpr)); } (LPAREN ArgumentList(ctx, expr.Get()):argList RPAREN{ expr->SetSpanEnd(span.end); })?)
326 {
327 return expr.Release();
328 }
329 ;
330
331 ArgumentList(ParsingContext* ctx, Node* node)
332 ::= (ExpressionList(ctx, node):exprList?)
333 ;
334
335 ExpressionList(ParsingContext* ctx, Node* node)
336 ::= empty{ ctx->BeginParsingArguments(); }
337 ( (Expression(ctx):arg{ node->AddArgument(arg); }) % COMMA){ ctx->EndParsingArguments(); } / { ctx->EndParsingArguments(); }
338 ;
339
340 InvokeExpr(ParsingContext* ctx, var UniquePtr<Node> expr, var Span s) : Node*
341 ::= ((TemplateId(ctx):templateId{ s = span; expr.Reset(templateId); } | Identifier(ctx):id{ s = span; expr.Reset(id); })
342 ( DOT Identifier(ctx):dotMemberId!{ s.end = span.end; expr.Reset(new DotNode(s, ctx->ModuleId(), expr.Release(), dotMemberId)); } )*
343 LPAREN{ expr.Reset(new InvokeNode(s, ctx->ModuleId(), expr.Release())); } ArgumentList(ctx, expr.Get()):argList RPAREN!{ expr->SetSpanEnd(span.end); })
344 {
345 return expr.Release();
346 }
347 ;
348
349 ruleinfo
350 {
351 (Expression, "expression"), (Equivalence, "equivalence expression"), (Implication, "implication expression"), (Disjunction, "disjunctive expression"),
352 (Conjunction, "conjunctive expression"), (BitOr, "bitwise or expression "),
353 (BitXor, "bitwise exclusive or expression"), (BitAnd, "bitwise and expression"), (Equality, "equality expression"), (Relational, "relational expression"),
354 (Shift, "shift expression"), (Additive, "additive expression"), (Multiplicative, "multiplicative expression"),
355 (Prefix, "prefix expression"), (Postfix, "postfix expression"), (Primary, "primary expression"), (SizeOfExpr, "sizeof expression"), (TypeNameExpr, "typename expression"),
356 (TypeIdExpr, "typeid expression"), (CastExpr, "cast expression"), (ConstructExpr, "construct expression"), (NewExpr, "new expression"),
357 (ArgumentList, "argument list"), (ExpressionList, "expression list"), (InvokeExpr, "invoke expression")
358 }
359 }