1
2
3
4
5
6 [hpp]#include <sngcpp/parser/ParserApi.hpp>
7 [hpp]#include <sngcpp/ast/Expression.hpp>
8 [hpp]#include <sngcpp/parser/ParsingContext.hpp>
9 [cpp]#include <sngcpp/parser/Declarator.hpp>
10 [cpp]#include <sngcpp/parser/Function.hpp>
11 [cpp]#include <sngcpp/parser/Identifier.hpp>
12 [cpp]#include <sngcpp/parser/Literal.hpp>
13 [cpp]#include <sngcpp/parser/SimpleType.hpp>
14 [cpp]#include <sngcpp/parser/Statement.hpp>
15 [cpp]#include <sngcpp/parser/Template.hpp>
16 [cpp]#include <sngcpp/parser/TypeExpr.hpp>
17 [cpp]#include <sngcpp/lexer/CppLexer.hpp>
18 [cpp]#include <sngcpp/lexer/CppTokens.hpp>
19
20 using namespace CppTokens;
21 using namespace soulng::lexer;
22
23 parser api(SNGCPP_PARSER_API) ExpressionParser
24 {
25 uselexer CppLexer;
26 main;
27
28 using TypeExprParser.TypeExpr;
29 using DeclaratorParser.InitializerList;
30 using DeclaratorParser.InitializerClause;
31 using DeclaratorParser.BracedInitializerList;
32 using FunctionParser.ParameterList;
33 using LiteralParser.Literal;
34 using SimpleTypeParser.SimpleTypeSpecifier;
35 using IdentifierParser.Identifier;
36 using IdentifierParser.NestedNameSpecifier;
37 using StatementParser.CompoundStatement;
38 using TemplateParser.TemplateId;
39
40 Expression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
41 ::=
42 ( AssignmentExpression(ctx):left{ expr.reset(left); s = span; }
43 (COMMA AssignmentExpression(ctx):right{ s.end = span.end; expr.reset(new sngcpp::ast::CommaExpressionNode(s, expr.release(), right)); })*
44 )
45 {
46 return expr.release();
47 }
48 ;
49
50 ConstantExpression(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
51 ::= ConditionalExpression(ctx):expr{ return expr; }
52 ;
53
54 AssignmentExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
55 ::= empty{ ctx->BeginParsingLvalue(); }
56 ( LogicalOrExpression(ctx):logicalOrExpression{ s = span; ctx->EndParsingLvalue(); expr.reset(logicalOrExpression); } / { ctx->EndParsingLvalue(); }
57 AssignmentOperator:op
58 InitializerClause(ctx):initializerClause{ s.end = span.end; expr.reset(new sngcpp::ast::AssignmentExpressionNode(s, expr.release(), op, initializerClause)); }
59 | ConditionalExpression(ctx):conditionalExpression{ expr.reset(conditionalExpression); }
60 | ThrowExpression(ctx):throwExpression{ expr.reset(throwExpression); }
61 )
62 {
63 return expr.release();
64 }
65 ;
66
67 AssignmentOperator : sngcpp::ast::Operator
68 ::= ASSIGN{ return sngcpp::ast::Operator::assign; }
69 | MULASSIGN{ return sngcpp::ast::Operator::mulAssign; }
70 | DIVASSIGN{ return sngcpp::ast::Operator::divAssign; }
71 | REMASSIGN{ return sngcpp::ast::Operator::remAssign; }
72 | ADDASSIGN{ return sngcpp::ast::Operator::addAssign; }
73 | SUBASSIGN{ return sngcpp::ast::Operator::subAssign; }
74 | SHIFTRIGHTASSIGN{ return sngcpp::ast::Operator::shiftRightAssign; }
75 | SHIFTLEFTASSIGN{ return sngcpp::ast::Operator::shiftLeftAssign; }
76 | ANDASSIGN{ return sngcpp::ast::Operator::andAssign; }
77 | XORASSIGN{ return sngcpp::ast::Operator::xorAssign; }
78 | ORASSIGN{ return sngcpp::ast::Operator::orAssign; }
79 ;
80
81 ConditionalExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
82 ::=
83 ( LogicalOrExpression(ctx):logicalOrExpression{ expr.reset(logicalOrExpression); s = span; }
84 (QUEST Expression(ctx):thenExpr COLON AssignmentExpression(ctx):elseExpr{ s.end = span.end; expr.reset(new sngcpp::ast::ConditionalExpressionNode(s, expr.release(), thenExpr, elseExpr)); })?
85 )
86 {
87 return expr.release();
88 }
89 ;
90
91 ThrowExpression(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
92 ::= (THROW{ s = span; } (AssignmentExpression(ctx):exception{ s.end = span.end; })?)
93 {
94 return new sngcpp::ast::ThrowExpressionNode(s, exception);
95 }
96 ;
97
98 LogicalOrExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
99 ::=
100 ( LogicalAndExpression(ctx):left{ expr.reset(left); s = span; }
101 (
102 OROR LogicalAndExpression(ctx):right
103 {
104 if (ctx->ParsingTemplateIdOrLvalueAndNotArguments()) pass = false; else
105 {
106 s.end = span.end;
107 expr.reset(new sngcpp::ast::LogicalOrExpressionNode(s, expr.release(), right));
108 }
109 }
110 )*
111 )
112 {
113 return expr.release();
114 }
115 ;
116
117 LogicalAndExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
118 ::=
119 ( InclusiveOrExpression(ctx):left{ expr.reset(left); s = span; }
120 (
121 AMPAMP InclusiveOrExpression(ctx):right
122 {
123 if (ctx->ParsingTemplateIdOrLvalueAndNotArguments()) pass = false; else
124 {
125 s.end = span.end;
126 expr.reset(new sngcpp::ast::LogicalAndExpressionNode(s, expr.release(), right));
127 }
128 }
129 )*
130 )
131 {
132 return expr.release();
133 }
134 ;
135
136 InclusiveOrExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
137 ::=
138 ( ExclusiveOrExpression(ctx):left{ expr.reset(left); s = span; }
139 (
140 OR ExclusiveOrExpression(ctx):right
141 {
142 if (ctx->ParsingLvalueAndNotArguments()) pass = false; else
143 {
144 s.end = span.end;
145 expr.reset(new sngcpp::ast::InclusiveOrExpressionNode(s, expr.release(), right));
146 }
147 }
148 )*
149 )
150 {
151 return expr.release();
152 }
153 ;
154
155 ExclusiveOrExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
156 ::=
157 ( AndExpression(ctx):left{ expr.reset(left); s = span; }
158 (
159 XOR AndExpression(ctx):right
160 {
161 if (ctx->ParsingLvalueAndNotArguments()) pass = false; else
162 {
163 s.end = span.end;
164 expr.reset(new sngcpp::ast::ExclusiveOrExpressionNode(s, expr.release(), right));
165 }
166 }
167 )*
168 )
169 {
170 return expr.release();
171 }
172 ;
173
174 AndExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
175 ::=
176 ( EqualityExpression(ctx):left{ expr.reset(left); s = span; }
177 (
178 AMP EqualityExpression(ctx):right
179 {
180 if (ctx->ParsingLvalueAndNotArguments()) pass = false; else
181 {
182 s.end = span.end;
183 expr.reset(new sngcpp::ast::AndExpressionNode(s, expr.release(), right));
184 }
185 }
186 )*
187 )
188 {
189 return expr.release();
190 }
191 ;
192
193 EqualityExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
194 ::=
195 ( RelationalExpression(ctx):left{ expr.reset(left); s = span; }
196 (
197 EqualityOperator:op RelationalExpression(ctx):right
198 {
199 if (ctx->ParsingLvalueAndNotArguments()) pass = false; else
200 {
201 s.end = span.end;
202 expr.reset(new sngcpp::ast::EqualityExpressionNode(s, expr.release(), right, op));
203 }
204 }
205 )*
206 )
207 {
208 return expr.release();
209 }
210 ;
211
212 EqualityOperator : sngcpp::ast::Operator
213 ::= EQ{ return sngcpp::ast::Operator::equal; }
214 | NEQ{ return sngcpp::ast::Operator::notEqual; }
215 ;
216
217 RelationalExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
218 ::=
219 ( ShiftExpression(ctx):left{ expr.reset(left); s = span; }
220 (
221 RelationalOperator:op ShiftExpression(ctx):right
222 {
223 if (ctx->ParsingTemplateIdOrLvalueAndNotArguments()) pass = false; else
224 {
225 s.end = span.end;
226 expr.reset(new sngcpp::ast::RelationalExpressionNode(s, expr.release(), right, op));
227 }
228 }
229 )*
230 )
231 {
232 return expr.release();
233 }
234 ;
235
236 RelationalOperator : sngcpp::ast::Operator
237 ::= LEQ{ return sngcpp::ast::Operator::lessOrEqual; }
238 | GEQ{ return sngcpp::ast::Operator::greaterOrEqual; }
239 | LANGLE{ return sngcpp::ast::Operator::less; }
240 | RANGLE{ return sngcpp::ast::Operator::greater; }
241 ;
242
243 ShiftExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
244 ::=
245 ( AdditiveExpression(ctx):left{ expr.reset(left); s = span; }
246 (
247 ShiftOperator:op AdditiveExpression(ctx):right
248 {
249 if (ctx->ParsingTemplateIdOrLvalueAndNotArguments()) pass = false; else
250 {
251 s.end = span.end;
252 expr.reset(new sngcpp::ast::ShiftExpressionNode(s, expr.release(), right, op));
253 }
254 }
255 )*
256 )
257 {
258 return expr.release();
259 }
260 ;
261
262 ShiftOperator : sngcpp::ast::Operator
263 ::= SHIFTLEFT{ return sngcpp::ast::Operator::shiftLeft; }
264 | SHIFTRIGHT{ return sngcpp::ast::Operator::shiftRight; }
265 ;
266
267 AdditiveExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
268 ::=
269 ( MultiplicativeExpression(ctx):left{ expr.reset(left); s = span; }
270 (
271 AdditiveOperator:op MultiplicativeExpression(ctx):right
272 {
273 if (ctx->ParsingLvalueAndNotArguments()) pass = false; else
274 {
275 s.end = span.end;
276 expr.reset(new sngcpp::ast::AdditiveExpressionNode(s, expr.release(), right, op));
277 }
278 }
279 )*
280 )
281 {
282 return expr.release();
283 }
284 ;
285
286 AdditiveOperator : sngcpp::ast::Operator
287 ::= PLUS{ return sngcpp::ast::Operator::add; }
288 | MINUS{ return sngcpp::ast::Operator::sub; }
289 ;
290
291 MultiplicativeExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
292 ::=
293 ( PMExpression(ctx):left{ expr.reset(left); s = span; }
294 (
295 MultiplicativeOperator:op PMExpression(ctx):right
296 {
297 if (ctx->ParsingLvalueAndNotArguments()) pass = false; else
298 {
299 s.end = span.end;
300 expr.reset(new sngcpp::ast::MultiplicativeExpressionNode(s, expr.release(), right, op));
301 }
302 }
303 )*
304 )
305 {
306 return expr.release();
307 }
308 ;
309
310 MultiplicativeOperator : sngcpp::ast::Operator
311 ::= STAR{ return sngcpp::ast::Operator::mul; }
312 | DIV{ return sngcpp::ast::Operator::div; }
313 | MOD{ return sngcpp::ast::Operator::rem; }
314 ;
315
316 PMExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
317 ::=
318 ( CastExpression(ctx):left{ expr.reset(left); s = span; }
319 (
320 PMOperator:op CastExpression(ctx):right
321 {
322 s.end = span.end;
323 expr.reset(new sngcpp::ast::PMExpressionNode(s, expr.release(), right, op));
324 }
325 )*
326 )
327 {
328 return expr.release();
329 }
330 ;
331
332 PMOperator : sngcpp::ast::Operator
333 ::= DOTSTAR{ return sngcpp::ast::Operator::dotStar; }
334 | ARROWSTAR{ return sngcpp::ast::Operator::arrowStar; }
335 ;
336
337 CastExpression(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
338 ::= LPAREN{ s = span; } TypeExpr(ctx):typeExpr RPAREN CastExpression(ctx):castExpr{ s.end = span.end; return new sngcpp::ast::CastExpressionNode(s, typeExpr, castExpr); }
339 | UnaryExpression(ctx):unaryExpression{ return unaryExpression; }
340 ;
341
342 UnaryExpression(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
343 ::= PLUSPLUS{ s = span; } CastExpression(ctx):c1{ s.end = span.end; return new sngcpp::ast::UnaryExpressionNode(s, sngcpp::ast::Operator::inc, c1); }
344 | MINUSMINUS{ s = span; } CastExpression(ctx):c2{ s.end = span.end; return new sngcpp::ast::UnaryExpressionNode(s, sngcpp::ast::Operator::dec, c2); }
345 | UnaryOperator:op{ s = span; } CastExpression(ctx):c3{ s.end = span.end; return new sngcpp::ast::UnaryExpressionNode(s, op, c3); }
346 | SIZEOF{ s = span; } UnaryExpression(ctx):u4{ s.end = span.end; return new sngcpp::ast::UnaryExpressionNode(s, sngcpp::ast::Operator::sizeOf, u4); }
347 | ALIGNOF{ s = span; } LPAREN TypeExpr(ctx):t5 RPAREN{ s.end = span.end; return new sngcpp::ast::UnaryExpressionNode(s, sngcpp::ast::Operator::alignOf, t5); }
348 | NewExpression(ctx):newExpr{ return newExpr; }
349 | DeleteExpression(ctx):deleteExpr{ return deleteExpr; }
350 | PostfixExpression(ctx):postfixExpr{ return postfixExpr; }
351 ;
352
353 UnaryOperator : sngcpp::ast::Operator
354 ::= STAR{ return sngcpp::ast::Operator::deref; }
355 | AMP{ return sngcpp::ast::Operator::addrOf; }
356 | PLUS{ return sngcpp::ast::Operator::unaryPlus; }
357 | MINUS{ return sngcpp::ast::Operator::unaryMinus; }
358 | EXCLAMATION{ return sngcpp::ast::Operator::not_; }
359 | TILDE{ return sngcpp::ast::Operator::complement; }
360 ;
361
362 NewExpression(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
363 ::= (NEW{ s = span; } NewPlacement(ctx):placement? TypeExpr(ctx):typeExpr{ s.end = span.end; } (NewInitializer(ctx):initializer{ s.end = span.end; })?)
364 {
365 return new sngcpp::ast::NewExpressionNode(s, placement, typeExpr, initializer);
366 }
367 ;
368
369 NewPlacement(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
370 ::= LPAREN ExpressionList(ctx):exprList RPAREN{ return exprList; }
371 ;
372
373 NewInitializer(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
374 ::= LPAREN ArgumentList(ctx):args RPAREN{ return args; }
375 ;
376
377 ExpressionList(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
378 ::= InitializerList(ctx):initializerList{ return initializerList; }
379 ;
380
381 ArgumentList(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
382 ::= ExpressionList(ctx):exprList{ return exprList; }
383 | empty{ return nullptr; }
384 ;
385
386 DeleteExpression(sngcpp::cppparser::ParsingContext* ctx, var bool array, var Span s) : sngcpp::ast::Node*
387 ::= DELETE{ s = span; } (LBRACKET RBRACKET{ array = true; })? CastExpression(ctx):castExpr{ s.end = span.end; return new sngcpp::ast::DeleteExpressionNode(s, array, castExpr); }
388 ;
389
390 PostfixExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
391 ::=
392 ( PrimaryExpression(ctx):primaryExpr{ expr.reset(primaryExpr); s = span; }
393 ( LBRACKET{ ctx->BeginParsingArguments(); }
394 (Expression(ctx):index
395 RBRACKET){ s.end = span.end; ctx->EndParsingArguments(); expr.reset(new sngcpp::ast::SubscriptExpressionNode(s, expr.release(), index)); } / { ctx->EndParsingArguments(); }
396 | LPAREN{ ctx->BeginParsingArguments(); }
397 (ArgumentList(ctx):args
398 RPAREN){ s.end = span.end; ctx->EndParsingArguments(); expr.reset(new sngcpp::ast::InvokeExpressionNode(s, expr.release(), args)); } / { ctx->EndParsingArguments(); }
399 | DOT IdExpression(ctx):id1{ s.end = span.end; expr.reset(new sngcpp::ast::DotNode(s, expr.release(), id1)); }
400 | ARROW IdExpression(ctx):id2{ s.end = span.end; expr.reset(new sngcpp::ast::ArrowNode(s, expr.release(), id2)); }
401 | PLUSPLUS{ s.end = span.end; expr.reset(new sngcpp::ast::PostfixIncNode(s, expr.release())); }
402 | MINUSMINUS{ s.end = span.end; expr.reset(new sngcpp::ast::PostfixDecNode(s, expr.release())); }
403 )*
404 )
405 {
406 return expr.release();
407 }
408 ;
409
410 PrimaryExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr expr, var Span s) : sngcpp::ast::Node*
411 ::=
412 ( Literal:literal{ expr.reset(literal); }
413 | THIS{ expr.reset(new sngcpp::ast::ThisNode(span)); }
414 | LPAREN{ s = span; } Expression(ctx):e RPAREN{ s.end = span.end; expr.reset(new sngcpp::ast::ParenthesizedExprNode(s, e)); }
415 | CppCastExpression(ctx):cppCastExpr{ expr.reset(cppCastExpr); }
416 | TypeIdExpression(ctx):typeIdExpr{ expr.reset(typeIdExpr); }
417 | SimpleTypeSpecifier:s1{ s = span; } LPAREN ArgumentList(ctx):args1 RPAREN
418 {
419 s.end = span.end;
420 expr.reset(new sngcpp::ast::InvokeExpressionNode(s, new sngcpp::ast::SimpleTypeNode(s, std::vector(1, s1)), args1));
421 }
422 | SimpleTypeSpecifier:s2{ s = span; } BracedInitializerList(ctx):bracedInitializerList1
423 {
424 s.end = span.end;
425 expr.reset(new sngcpp::ast::InvokeExpressionNode(s, new sngcpp::ast::SimpleTypeNode(s, std::vector(1, s2)), bracedInitializerList1));
426 }
427 | TypeExpr(ctx):t1{ s = span; } LPAREN ArgumentList(ctx):args2 RPAREN
428 {
429 s.end = span.end;
430 expr.reset(new sngcpp::ast::InvokeExpressionNode(s, t1, args2));
431 }
432 | TypeExpr(ctx):t2{ s = span; } BracedInitializerList(ctx):bracedInitializerList2
433 {
434 s.end = span.end;
435 expr.reset(new sngcpp::ast::InvokeExpressionNode(s, t2, bracedInitializerList2));
436 }
437 | IdExpression(ctx):idExpr{ expr.reset(idExpr); }
438 | LambdaExpression(ctx):lambdaExpr{ return lambdaExpr; }
439 )
440 {
441 return expr.release();
442 }
443 ;
444
445 CppCastExpression(sngcpp::cppparser::ParsingContext* ctx, var sngcpp::ast::Operator op, var Span s) : sngcpp::ast::Node*
446 ::=
447 ( ( DYNAMIC_CAST{ s = span; op = sngcpp::ast::Operator::dynamicCast; }
448 | STATIC_CAST{ s = span; op = sngcpp::ast::Operator::staticCast; }
449 | REINTERPRET_CAST{ s = span; op = sngcpp::ast::Operator::reinterpretCast; }
450 | CONST_CAST{ s = span; op = sngcpp::ast::Operator::constCast; }
451 )
452 LANGLE TypeExpr(ctx):typeExpr RANGLE LPAREN ExpressionList(ctx):exprList RPAREN{ s.end = span.end; }
453 )
454 {
455 return new sngcpp::ast::CppCastExpressionNode(s, typeExpr, exprList, op);
456 }
457 ;
458
459 TypeIdExpression(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
460 ::= TYPEID{ s = span; } LPAREN TypeExpr(ctx):typeExpr RPAREN{ s.end = span.end; return new sngcpp::ast::TypeIdExpressionNode(s, typeExpr); }
461 | TYPEID{ s = span; } LPAREN Expression(ctx):expr RPAREN{ s.end = span.end; return new sngcpp::ast::TypeIdExpressionNode(s, expr); }
462 ;
463
464 IdExpression(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
465 ::= QualifiedId(ctx):qualifiedId{ return qualifiedId; }
466 | UnqualifiedId(ctx):unqualifiedId{ return unqualifiedId; }
467 ;
468
469 UnqualifiedId(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
470 ::= TemplateId(ctx):templateId{ return templateId; }
471 | Identifier:id1{ return new sngcpp::ast::IdentifierNode(span, id1); }
472 | OperatorFunctionId:operatorFunctionId{ return operatorFunctionId; }
473 | ConversionFunctionId(ctx):conversionFunctionId{ return conversionFunctionId; }
474 | TILDE{ s = span; } Identifier:id2{ s.end = span.end; return new sngcpp::ast::DtorIdNode(s, id2); }
475 ;
476
477 QualifiedId(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
478 ::= COLONCOLON{ s = span; } TemplateId(ctx):templateId{ s.end = span.end; return new sngcpp::ast::NestedIdNode(s, nullptr, templateId); }
479 | COLONCOLON{ s = span; } NestedNameSpecifier(ctx):ns1 UnqualifiedId(ctx):uid1{ s.end = span.end; return new sngcpp::ast::NestedIdNode(s, new sngcpp::ast::NestedIdNode(s, nullptr, ns1), uid1); }
480 | COLONCOLON{ s = span; } Identifier:id1{ s.end = span.end; return new sngcpp::ast::NestedIdNode(s, nullptr, new sngcpp::ast::IdentifierNode(s, id1)); }
481 | COLONCOLON{ s = span; } OperatorFunctionId:operatorFunctionId{ s.end = span.end; return new sngcpp::ast::NestedIdNode(s, nullptr, operatorFunctionId); }
482 | NestedNameSpecifier(ctx):ns2{ s = span; } UnqualifiedId(ctx):uid2{ s.end = span.end; return new sngcpp::ast::NestedIdNode(s, ns2, uid2); }
483 ;
484
485 OperatorFunctionId(var Span s) : sngcpp::ast::Node*
486 ::= OPERATOR{ s = span; } Operator:op{ s.end = span.end; return new sngcpp::ast::OperatorFunctionIdNode(s, op); }
487 ;
488
489 Operator : sngcpp::ast::Operator
490 ::= NEW LBRACKET RBRACKET{ return sngcpp::ast::Operator::newArray; }
491 | DELETE LBRACKET RBRACKET{ return sngcpp::ast::Operator::deleteArray; }
492 | NEW{ return sngcpp::ast::Operator::new_; }
493 | DELETE{ return sngcpp::ast::Operator::delete_; }
494 | AssignmentOperator:assignmentOp{ return assignmentOp; }
495 | PLUSPLUS{ return sngcpp::ast::Operator::inc; }
496 | MINUSMINUS{ return sngcpp::ast::Operator::dec; }
497 | SHIFTLEFT{ return sngcpp::ast::Operator::shiftLeft; }
498 | SHIFTRIGHT{ return sngcpp::ast::Operator::shiftRight; }
499 | AMPAMP{ return sngcpp::ast::Operator::logicalAnd; }
500 | OROR{ return sngcpp::ast::Operator::logicalOr; }
501 | EQ{ return sngcpp::ast::Operator::equal; }
502 | NEQ{ return sngcpp::ast::Operator::notEqual; }
503 | LEQ{ return sngcpp::ast::Operator::lessOrEqual; }
504 | GEQ{ return sngcpp::ast::Operator::greaterOrEqual; }
505 | LANGLE{ return sngcpp::ast::Operator::less; }
506 | RANGLE{ return sngcpp::ast::Operator::greater; }
507 | DOTSTAR{ return sngcpp::ast::Operator::dotStar; }
508 | ARROWSTAR{ return sngcpp::ast::Operator::arrowStar; }
509 | ARROW{ return sngcpp::ast::Operator::arrow; }
510 | LPAREN RPAREN{ return sngcpp::ast::Operator::apply; }
511 | LBRACKET RBRACKET{ return sngcpp::ast::Operator::subscript; }
512 | PLUS{ return sngcpp::ast::Operator::add; }
513 | MINUS{ return sngcpp::ast::Operator::sub; }
514 | STAR{ return sngcpp::ast::Operator::mul; }
515 | DIV{ return sngcpp::ast::Operator::div; }
516 | MOD{ return sngcpp::ast::Operator::rem; }
517 | XOR{ return sngcpp::ast::Operator::xor_; }
518 | AMP{ return sngcpp::ast::Operator::and_; }
519 | OR{ return sngcpp::ast::Operator::or_; }
520 | TILDE{ return sngcpp::ast::Operator::complement; }
521 | EXCLAMATION{ return sngcpp::ast::Operator::not_; }
522 | COMMA{ return sngcpp::ast::Operator::comma; }
523 ;
524
525 ConversionFunctionId(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
526 ::= OPERATOR{ s = span; } TypeExpr(ctx):typeExpr{ s.end = span.end; return new sngcpp::ast::ConversionFunctionIdNode(s, typeExpr); }
527 ;
528
529 LambdaExpression(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr node) : sngcpp::ast::Node*
530 ::= LBRACKET{ node.reset(new sngcpp::ast::LambdaExpressionNode(span)); } LambdaCaptures(node.get()):captures RBRACKET! (ParameterList(ctx):params{ node->SetParameters(params); })?
531 CompoundStatement(ctx):body!{ node->SetBody(body); return node.release(); }
532 ;
533
534 LambdaCaptures(sngcpp::ast::LambdaExpressionNode* lambdaExpression)
535 ::= (CaptureDefault:captureDefault{ lambdaExpression->AddCapture(captureDefault); })? Captures(lambdaExpression):captures?
536 ;
537
538 CaptureDefault : sngcpp::ast::Node*
539 ::= ASSIGN{ return new sngcpp::ast::AssignCaptureNode(span); }
540 | AMP{ return new sngcpp::ast::RefCaptureNode(span); }
541 ;
542
543 Captures(sngcpp::ast::LambdaExpressionNode* lambdaExpression)
544 ::= Capture:left{ lambdaExpression->AddCapture(left); } (COMMA Capture:right{ lambdaExpression->AddCapture(right); })*
545 ;
546
547 Capture : sngcpp::ast::Node*
548 ::= Identifier:id{ return new sngcpp::ast::IdentifierCaptureNode(span, new sngcpp::ast::IdentifierNode(span, id)); }
549 | THIS{ return new sngcpp::ast::ThisCaptureNode(span); }
550 ;
551 }