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