1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <soulng/cppcode/Expression.hpp>
  7 [cpp]#include <soulng/util/TextUtils.hpp>
  8 [cpp]#include <sng2html/sng2html/ParserDeclaratorParser.hpp>
  9 [cpp]#include <sng2html/sng2html/ParserDeclarationParser.hpp>
 10 [cpp]#include <sng2html/sng2html/ParserLiteralParser.hpp>
 11 [cpp]#include <sng2html/sng2html/ParserIdentifierParser.hpp>
 12 [cpp]#include <sng2html/sng2html/ParserFileLexer.hpp>
 13 [cpp]#include <sng2html/sng2html/ParserFileTokens.hpp>
 14 
 15 using namespace soulng::lexer;
 16 using namespace ParserFileTokens;
 17 
 18 parser ParserExpressionParser
 19 {
 20     uselexer ParserFileLexer;
 21 
 22     using ParserDeclaratorParser.TypeId;
 23     using ParserDeclaratorParser.TypeSpecifierSeq;
 24     using ParserDeclaratorParser.PtrOperator;
 25     using ParserDeclarationParser.SimpleTypeSpecifier;
 26     using ParserDeclarationParser.TypeName;
 27     using ParserLiteralParser.CppLiteral;
 28     using ParserIdentifierParser.QualifiedCppId;
 29 
 30     CppExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
 31         ::= (AssignmentExpression:left{ expr.reset(left); } (COMMA AssignmentExpression:right{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), soulng::cppcode::Operator::comma, right)); })*)
 32         {
 33             return expr.release();
 34         }
 35         ;
 36 
 37     ConstantExpression : soulng::cppcode::CppObject*
 38         ::= CppExpression:expr{ return expr; }
 39         ;
 40 
 41     AssignmentExpression : soulng::cppcode::CppObject*
 42         ::= LogicalOrExpression:left AssignmentOp:op AssignmentExpression:right!{ return new soulng::cppcode::BinaryOpExpr(left, op, right); }
 43         |   ConditionalExpression:conditionalExpr{ return conditionalExpr; }
 44         |   ThrowExpression:throwExpr{ return throwExpr; }
 45         ;
 46 
 47     AssignmentOp : soulng::cppcode::Operator
 48         ::= ASSIGN{ return soulng::cppcode::Operator::assign; }
 49         |   MULASSIGN{ return soulng::cppcode::Operator::mulAssign; }
 50         |   DIVASSIGN{ return soulng::cppcode::Operator::divAssign; }
 51         |   REMASSIGN{ return soulng::cppcode::Operator::remAssign; }
 52         |   PLUSASSIGN{ return soulng::cppcode::Operator::plusAssign; }
 53         |   MINUSASSIGN{ return soulng::cppcode::Operator::minusAssign; }
 54         |   SHIFTLEFTASSIGN{ return soulng::cppcode::Operator::shiftLeftAssign; }
 55         |   SHIFTRIGHTASSIGN{ return soulng::cppcode::Operator::shiftRightAssign; }
 56         |   ANDASSIGN{ return soulng::cppcode::Operator::andAssign; }
 57         |   XORASSIGN{ return soulng::cppcode::Operator::xorAssign; }
 58         |   ORASSIGN{ return soulng::cppcode::Operator::orAssign; }
 59         ;
 60 
 61     ConditionalExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
 62         ::=
 63         (
 64             LogicalOrExpression:left{ expr.reset(left); }
 65             (QUEST CppExpression:ifExpr! COLON AssignmentExpression:thenExpr!{ expr.reset(new soulng::cppcode::ConditionalExpr(expr.release(), ifExpr, thenExpr)); })?
 66         )
 67         {
 68             return expr.release();
 69         }
 70         ;
 71 
 72     ThrowExpression() : soulng::cppcode::CppObject*
 73         ::= (THROW AssignmentExpression:exception?){ return new soulng::cppcode::ThrowExpr(exception); }
 74         ;
 75 
 76     LogicalOrExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
 77         ::=
 78         (   LogicalAndExpression:left{ expr.reset(left); }
 79             (DISJUNCTION LogicalAndExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), soulng::cppcode::Operator::or_, right)); })*
 80         )
 81         {
 82             return expr.release();
 83         }
 84         ;
 85 
 86     LogicalAndExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
 87         ::=
 88         (   InclusiveOrExpression:left{ expr.reset(left); }
 89             (AMPAMP InclusiveOrExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), soulng::cppcode::Operator::and_, right)); })*
 90         )
 91         {
 92             return expr.release();
 93         }
 94         ;
 95 
 96     InclusiveOrExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
 97         ::=
 98         (   ExclusiveOrExpression:left{ expr.reset(left); }
 99             (BITOR ExclusiveOrExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), soulng::cppcode::Operator::bitor_, right)); })*
100         )
101         {
102             return expr.release();
103         }
104         ;
105 
106     ExclusiveOrExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
107         ::=
108         (   AndExpression:left{ expr.reset(left); }
109             (BITXOR AndExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), soulng::cppcode::Operator::bitxor, right)); })*
110         )
111         {
112             return expr.release();
113         }
114         ;
115 
116     AndExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
117         ::=
118         (
119             EqualityExpression:left{ expr.reset(left); }
120             (AMP EqualityExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), soulng::cppcode::Operator::bitand_, right)); })*
121         )
122         {
123             return expr.release();
124         }
125         ;
126 
127     EqualityExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
128         ::=
129         (
130             RelationalExpression:left{ expr.reset(left); }
131             (EqOp:op RelationalExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), op, right)); })*
132         )
133         {
134             return expr.release();
135         }
136         ;
137 
138     EqOp : soulng::cppcode::Operator
139         ::= EQ{ return soulng::cppcode::Operator::eq; }
140         |   NEQ{ return soulng::cppcode::Operator::notEq; }
141         ;
142 
143     RelationalExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
144         ::=
145         (
146             ShiftExpression:left{ expr.reset(left); }
147             (RelOp:op ShiftExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), op, right)); })*
148         )
149         {
150             return expr.release();
151         }
152         ;
153 
154     RelOp : soulng::cppcode::Operator
155         ::= LANGLE{ return soulng::cppcode::Operator::less; }
156         |   RANGLE{ return soulng::cppcode::Operator::greater; }
157         |   LEQ{ return soulng::cppcode::Operator::lessOrEq; }
158         |   GEQ{ return soulng::cppcode::Operator::greaterOrEq; }
159         ;
160 
161     ShiftExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
162         ::=
163         (
164             AdditiveExpression:left{ expr.reset(left); }
165             (ShiftOp:op AdditiveExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), op, right)); })*
166         )
167         {
168             return expr.release();
169         }
170         ;
171 
172     ShiftOp : soulng::cppcode::Operator
173         ::= SHIFTLEFT{ return soulng::cppcode::Operator::shiftLeft; }
174         |   SHIFTRIGHT{ return soulng::cppcode::Operator::shiftRight; }
175         ;
176 
177     AdditiveExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
178         ::=
179         (
180             MultiplicativeExpression:left{ expr.reset(left); }
181             (AddOp:op MultiplicativeExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), op, right)); })*
182         )
183         {
184             return expr.release();
185         }
186         ;
187 
188     AddOp : soulng::cppcode::Operator
189         ::= PLUS{ return soulng::cppcode::Operator::plus; }
190         |   MINUS{ return soulng::cppcode::Operator::minus; }
191         ;
192 
193     MultiplicativeExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
194         ::=
195         (
196             PmExpression:left{ expr.reset(left); }
197             (MulOp:op PmExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), op, right)); })*
198         )
199         {
200             return expr.release();
201         }
202         ;
203 
204     MulOp : soulng::cppcode::Operator
205         ::= STAR{ return soulng::cppcode::Operator::mul; }
206         |   DIV{ return soulng::cppcode::Operator::div; }
207         |   REM{ return soulng::cppcode::Operator::rem; }
208         ;
209 
210     PmExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
211         ::=
212         (
213             CastExpression:left{ expr.reset(left); } (PmOp:op CastExpression:right!{ expr.reset(new soulng::cppcode::BinaryOpExpr(expr.release(), op, right)); })*
214         )
215         {
216             return expr.release();
217         }
218         ;
219 
220     PmOp : soulng::cppcode::Operator
221         ::= DOTSTAR{ return soulng::cppcode::Operator::dotStar; }
222         |   ARROWSTAR{ return soulng::cppcode::Operator::arrowStar; }
223         ;
224 
225     CastExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
226         ::=
227         (
228             LPAREN TypeId:typeId RPAREN CastExpression:castExpr{ expr.reset(new soulng::cppcode::CastExpr(typeId, castExpr)); }
229         |   UnaryExpression:unaryExpr{ expr.reset(unaryExpr); }
230         )
231         {
232             return expr.release();
233         }
234         ;
235 
236     UnaryExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
237         ::=
238         (   PostfixExpression:postfixExpr{ expr.reset(postfixExpr); }
239         |   PostCastExpression:postCastExpr{ expr.reset(postCastExpr); }
240         |   PLUSPLUS UnaryExpression:u1!{ expr.reset(new soulng::cppcode::PreIncrementExpr(u1)); }
241         |   MINUSMINUS UnaryExpression:u2!{ expr.reset(new soulng::cppcode::PreDecrementExpr(u2)); }
242         |   UnaryOperator:op CastExpression:castExpr!{ expr.reset(new soulng::cppcode::UnaryOpExpr(op, castExpr)); }
243         |   SIZEOF LPAREN TypeId:typeId! RPAREN!{ expr.reset(new soulng::cppcode::SizeOfExpr(typeId, true)); }
244         |   SIZEOF UnaryExpression:u3!{ expr.reset(new soulng::cppcode::SizeOfExpr(u3, false)); }
245         |   NewExpression:newExpr{ expr.reset(newExpr); }
246         |   DeleteExpression:deleteExpr{ expr.reset(deleteExpr); }
247         )
248         {
249             return expr.release();
250         }
251         ;
252 
253     UnaryOperator : soulng::cppcode::Operator
254         ::= STAR{ return soulng::cppcode::Operator::deref; }
255         |   AMP{ return soulng::cppcode::Operator::addrOf; }
256         |   PLUS{ return soulng::cppcode::Operator::plus; }
257         |   MINUS{ return soulng::cppcode::Operator::minus; }
258         |   EXCLAMATION{ return soulng::cppcode::Operator::not_; }
259         |   CPL{ return soulng::cppcode::Operator::cpl; }
260         ;
261 
262     PostfixExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
263         ::=
264         (   PrimaryExpression:primaryExpr{ expr.reset(primaryExpr); }
265             (   LBRACKET CppExpression:index RBRACKET!{ expr.reset(new soulng::cppcode::IndexExpr(expr.release(), index)); }
266             |   LPAREN{ expr.reset(new soulng::cppcode::InvokeExpr(expr.release())); } ExpressionList(expr.get()):exprList? RPAREN!
267             |   DOT IdExpression:dotMember!{ expr.reset(new soulng::cppcode::MemberAccessExpr(expr.release(), dotMember)); }
268             |   ARROW IdExpression:arrowMember!{ expr.reset(new soulng::cppcode::PtrMemberAccessExpr(expr.release(), arrowMember)); }
269             |   PLUSPLUS{ expr.reset(new soulng::cppcode::PostIncrementExpr(expr.release())); }
270             |   MINUSMINUS{ expr.reset(new soulng::cppcode::PostDecrementExpr(expr.release())); }
271             )*
272         |   TypeSpecifierOrTypeName:type{ expr.reset(new soulng::cppcode::InvokeExpr(expr.release())); } LPAREN ExpressionList(expr.get()):typeExprList? RPAREN
273         )
274         {
275             return expr.release();
276         }
277         ;
278 
279     PostCastExpression(var std::u32string castStr) : soulng::cppcode::CppObject*
280         ::=
281         (
282             (   DYNAMICCAST{ castStr = U"dynamic_cast"; }
283             |   STATICCAST{ castStr = U"static_cast"; }
284             |   REINTERPRETCAST{ castStr = U"reinterpret_cast"; }
285             |   CONSTCAST{ castStr = U"const_cast"; }
286             )
287             LANGLE! TypeId:typeId! RANGLE! LPAREN! CppExpression:expr! RPAREN!{ return new soulng::cppcode::PostCastExpr(castStr, typeId, expr); }
288         |   TYPEID LPAREN! CppExpression:typeIdExpr! RPAREN!{ return new soulng::cppcode::TypeIdExpr(typeIdExpr); }
289         )
290         ;
291 
292     ExpressionList(soulng::cppcode::CppObject* owner)
293         ::= AssignmentExpression:expr{ owner->AddExpr(expr); } % COMMA
294         ;
295 
296     PrimaryExpression(var std::unique_ptr expr) : soulng::cppcode::CppObject*
297         ::= CppLiteral:literal{ return literal; }
298         |   THIS{ return new soulng::cppcode::ThisAccess(); }
299         |   LPAREN CppExpression:pexpr RPAREN{ return new soulng::cppcode::ParenExpr(pexpr); }
300         |   IdExpression:idExpr{ return idExpr; }
301         ;
302 
303     IdExpression(var Span s) : soulng::cppcode::IdExpr*
304         ::= (QualifiedCppId:id1{ s = span; } COLONCOLON OperatorFunctionId:ofId1{ s.end = span.end; }){ return new soulng::cppcode::IdExpr(lexer.GetMatch(s)); }
305         |   (empty{ s = span; } (COLONCOLON)? OperatorFunctionId:ofid2{ s.end = span.end; }){ return new soulng::cppcode::IdExpr(lexer.GetMatch(s)); }
306         |   QualifiedCppId:id2{ return new soulng::cppcode::IdExpr(id2); }
307         ;
308 
309     TypeSpecifierOrTypeName : soulng::cppcode::CppObject*
310         ::= SimpleTypeSpecifier:simpleTypeSpecifier{ return simpleTypeSpecifier; }
311         |   TypeName:typeName{ return typeName; }
312         ;
313 
314     NewExpression(var bool global, var std::unique_ptr newExpr) : soulng::cppcode::CppObject*
315         ::=
316         (   (COLONCOLON{ global = true; })?
317             NEW{ newExpr.reset(new soulng::cppcode::NewExpr(global)); }
318             empty{ newExpr->BeginAddPlacement(); } NewPlacement(newExpr.get()):placement? empty{ newExpr->EndAddPlacement(); }
319             (NewTypeId:newTypeId{ newExpr->SetParens(false); newExpr->SetTypeId(newTypeId); } | LPAREN TypeId:ti RPAREN{ newExpr->SetParens(true); newExpr->SetTypeId(ti); })
320             empty{ newExpr->BeginAddInitializer(); } NewInitializer(newExpr.get()):initializer? empty{ newExpr->EndAddInitializer(); }
321         )
322         {
323             return newExpr.release();
324         }
325         ;
326 
327     NewPlacement(soulng::cppcode::CppObject* owner)
328         ::= LPAREN ExpressionList(owner):exprList RPAREN
329         ;
330 
331     NewTypeId(var std::unique_ptr ti) : soulng::cppcode::TypeId*
332         ::= empty{ ti.reset(new soulng::cppcode::TypeId()); }
333             (
334                 (TypeSpecifierSeq(ti.get()):typeSpecifierSeq | TypeName:typeName{ ti->Add(typeName); })
335                 (NewDeclarator:newDeclarator{ ti->Declarator() = newDeclarator; })?
336             )
337             {
338                 return ti.release();
339             }
340         ;
341 
342     NewDeclarator(var Span s) : std::u32string
343         ::= empty{ s = span; }
344         (   PtrOperator:ptrOperator{ s.end = span.end; } (NewDeclarator:newDeclarator{ s.end = span.end; })?
345         |   DirectNewDeclarator:directNewDeclarator{ s.end = span.end; }
346         )
347         {
348             return soulng::util::Trim(lexer.GetMatch(s));
349         }
350         ;
351 
352     NewInitializer(soulng::cppcode::CppObject* owner)
353         ::= LPAREN ExpressionList(owner):initializer? RPAREN
354         ;
355 
356     DirectNewDeclarator
357         ::= LBRACKET CppExpression:expr RBRACKET (LBRACKET ConstantExpression:constantExpr RBRACKET)*
358         ;
359 
360     DeleteExpression(var bool global, var bool array) : soulng::cppcode::CppObject*
361         ::= ((COLONCOLON{ global = true; })? DELETE (LBRACKET RBRACKET{ array = true; })? CastExpression:ptr)
362         {
363             return new soulng::cppcode::DeleteExpr(global, array, ptr);
364         }
365         ;
366 
367     OperatorFunctionId(var Span s) : std::u32string
368         ::= OPERATOR{ s = span; } Operator:oprtr{ s.end = span.end; return lexer.GetMatch(s); }
369         ;
370 
371     Operator
372         ::= LBRACKET RBRACKET
373         |   LPAREN RPAREN
374         |   ARROWSTAR
375         |   ARROW
376         |   COMMA
377         |   MINUSMINUS
378         |   PLUSPLUS
379         |   DISJUNCTION
380         |   AMPAMP
381         |   LEQ
382         |   GEQ
383         |   NEQ
384         |   EQ
385         |   SHIFTLEFTASSIGN
386         |   SHIFTRIGHTASSIGN
387         |   SHIFTLEFT
388         |   SHIFTRIGHT
389         |   ORASSIGN
390         |   ANDASSIGN
391         |   XORASSIGN
392         |   REMASSIGN
393         |   DIVASSIGN
394         |   MULASSIGN
395         |   MINUSASSIGN
396         |   PLUSASSIGN
397         |   LANGLE
398         |   RANGLE
399         |   ASSIGN
400         |   EXCLAMATION
401         |   CPL
402         |   BITOR
403         |   AMP
404         |   BITXOR
405         |   REM
406         |   DIV
407         |   STAR
408         |   MINUS
409         |   PLUS
410         |   NEW LBRACKET RBRACKET
411         |   DELETE LBRACKET RBRACKET
412         |   NEW
413         |   DELETE
414         ;
415 
416     ruleinfo
417     {
418         (CppExpression, "C++ expression"), (ConstantExpression, "constant C++ expression"), (AssignmentExpression, "assignment expression"), (AssignmentOp, "assignment operator"),
419         (ConditionalExpression, "conditional expression"), (ThrowExpression, "throw expression"), (LogicalOrExpression, "logical OR-expression"), (LogicalAndExpression, "logical AND-expression"),
420         (InclusiveOrExpression, "inclusive OR-expression"), (ExclusiveOrExpression, "exclusive OR-expression"), (AndExpression, "AND-expression"), (EqualityExpression, "equality expression"),
421         (EqOp, "equality operator"), (RelationalExpression, "relational expression"), (RelOp, "relational operator"), (ShiftExpression, "shift expression"), (ShiftOp, "shift operator"),
422         (AdditiveExpression, "additive expression"), (AddOp, "additive operator"), (MultiplicativeExpression, "multiplicative expression"), (MulOp, "multiplicative operator"),
423         (PmExpression, "pointer-to-member expression"), (PmOp, "pointer-to-member operator"), (CastExpression, "cast-expression"), (UnaryExpression, "unary expression"),
424         (UnaryOperator, "unary operator"), (PostfixExpression, "postfix expression"), (PostCastExpression, "postfix cast-expression"), (ExpressionList, "expression list"),
425         (PrimaryExpression, "primary expression"), (IdExpression, "ID-expression"), (TypeSpecifierOrTypeName, "type specifier or type name"), (NewExpression, "new-expression"),
426         (NewPlacement, "new placement"), (NewTypeId, "new type identifier"), (NewDeclarator, "new declarator"), (NewInitializer, "new initializer"), (DirectNewDeclarator, "direct new declarator"),
427         (DeleteExpression, "delete expression"), (OperatorFunctionId, "operator function identifier"), (Operator, "operator")
428     }
429 }