1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  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 }