1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <soulng/cppcode/Statement.hpp>
  7 [cpp]#include <sng2html/sng2html/LexerDeclarationParser.hpp>
  8 [cpp]#include <sng2html/sng2html/LexerDeclaratorParser.hpp>
  9 [cpp]#include <sng2html/sng2html/LexerExpressionParser.hpp>
 10 [cpp]#include <sng2html/sng2html/LexerFileLexer.hpp>
 11 [cpp]#include <sng2html/sng2html/LexerFileTokens.hpp>
 12 
 13 using namespace soulng::lexer;
 14 using namespace LexerFileTokens;
 15 
 16 parser LexerStatementParser
 17 {
 18     uselexer LexerFileLexer;
 19 
 20     using LexerDeclarationParser.SimpleDeclaration;
 21     using LexerDeclarationParser.BlockDeclaration;
 22     using LexerDeclarationParser.TypeId;
 23     using LexerDeclaratorParser.TypeSpecifierSeq;
 24     using LexerDeclaratorParser.Declarator;
 25     using LexerDeclaratorParser.AbstractDeclarator;
 26     using LexerExpressionParser.CppExpression;
 27     using LexerExpressionParser.ConstantExpression;
 28     using LexerExpressionParser.AssignmentExpression;
 29 
 30     Statement : soulng::cppcode::Statement*
 31         ::= LabeledStatement:labeledStatement{ return labeledStatement; }
 32         |   EmptyStatement:emptyStatement{ return emptyStatement; }
 33         |   CompoundStatement:compoundStatement{ return compoundStatement; }
 34         |   SelectionStatement:selectionStatement{ return selectionStatement; }
 35         |   IterationStatement:iterationStatement{ return iterationStatement; }
 36         |   JumpStatement:jumpStatement{ return jumpStatement; }
 37         |   DeclarationStatement:declarationStatement{ return declarationStatement; }
 38         |   TryStatement:tryStatement{ return tryStatement; }
 39         |   ExpressionStatement:expressionStatement{ return expressionStatement; }
 40         ;
 41 
 42     LabeledStatement(var std::u32string label) : soulng::cppcode::Statement*
 43         ::= ID{ label = lexer.GetMatch(span); } COLON Statement:stmt1!{ return new soulng::cppcode::LabeledStatement(label, stmt1); }
 44         |   CASE ConstantExpression:caseExpr! COLON! Statement:stmt2!{ return new soulng::cppcode::CaseStatement(caseExpr, stmt2); }
 45         |   DEFAULT COLON! Statement:stmt3!{ return new soulng::cppcode::DefaultStatement(stmt3); }
 46         ;
 47 
 48     EmptyStatement : soulng::cppcode::Statement*
 49         ::= SEMICOLON{ return new soulng::cppcode::EmptyStatement(); }
 50         ;
 51 
 52     CompoundStatement(var std::unique_ptr compoundStatement) : soulng::cppcode::CompoundStatement*
 53         ::= LBRACE{ compoundStatement.reset(new soulng::cppcode::CompoundStatement()); }
 54             (Statement:stmt{ compoundStatement->Add(stmt); })*
 55             RBRACE!
 56         {
 57             return compoundStatement.release();
 58         }
 59         ;
 60 
 61     SelectionStatement : soulng::cppcode::Statement*
 62         ::= IfStatement:ifStatement{ return ifStatement; }
 63         |   SwitchStatement:switchStatement{ return switchStatement; }
 64         ;
 65 
 66     IfStatement : soulng::cppcode::Statement*
 67         ::= (IF LPAREN! Condition:cond! RPAREN! Statement:thenS! (ELSE Statement:elseS)?)
 68         {
 69             return new soulng::cppcode::IfStatement(cond, thenS, elseS);
 70         }
 71         ;
 72 
 73     SwitchStatement : soulng::cppcode::Statement*
 74         ::= SWITCH LPAREN! Condition:cond! RPAREN! Statement:stmt!
 75         {
 76             return new soulng::cppcode::SwitchStatement(cond, stmt);
 77         }
 78         ;
 79 
 80     IterationStatement : soulng::cppcode::Statement*
 81         ::= WhileStatement:whileStatement{ return whileStatement; }
 82         |   DoStatement:doStatement{ return doStatement; }
 83         |   RangeForStatement:rangeForStatement{ return rangeForStatement; }
 84         |   ForStatement:forStatement{ return forStatement; }
 85         ;
 86 
 87     WhileStatement : soulng::cppcode::Statement*
 88         ::= WHILE LPAREN! Condition:cond! RPAREN! Statement:stmt!
 89         {
 90             return new soulng::cppcode::WhileStatement(cond, stmt);
 91         }
 92         ;
 93 
 94     DoStatement : soulng::cppcode::Statement*
 95         ::= DO Statement:stmt! WHILE! LPAREN! CppExpression:cond! RPAREN! SEMICOLON!
 96         {
 97             return new soulng::cppcode::DoStatement(stmt, cond);
 98         }
 99         ;
100 
101     RangeForStatement : soulng::cppcode::Statement*
102         ::= FOR LPAREN ForRangeDeclaration:forRangeDeclaration COLON CppExpression:container! RPAREN! Statement:stmt!
103         {
104             return new soulng::cppcode::RangeForStatement(forRangeDeclaration, container, stmt);
105         }
106         ;
107 
108     ForRangeDeclaration(var std::unique_ptr forRangeDeclaration) : soulng::cppcode::ForRangeDeclaration*
109         ::=
110         (
111             empty{ forRangeDeclaration.reset(new soulng::cppcode::ForRangeDeclaration()); }
112             TypeSpecifierSeq(forRangeDeclaration->GetTypeId()):typeSpecifierSeq Declarator:declarator{ forRangeDeclaration->SetDeclarator(declarator); }
113         )
114         {
115             return forRangeDeclaration.release();
116         }
117         ;
118 
119     ForStatement : soulng::cppcode::Statement*
120         ::= FOR LPAREN ForInitStatement:forInitStatement Condition:cond? SEMICOLON CppExpression:loopExpr? RPAREN! Statement:stmt!
121         {
122             return new soulng::cppcode::ForStatement(forInitStatement, cond, loopExpr, stmt);
123         }
124         ;
125 
126     ForInitStatement : soulng::cppcode::CppObject*
127         ::= EmptyStatement:emptyStatement{ return emptyStatement; }
128         |   ExpressionStatement:expressionStatement{ return expressionStatement; }
129         |   SimpleDeclaration:simpleDeclaration{ return simpleDeclaration; }
130         ;
131 
132     JumpStatement : soulng::cppcode::Statement*
133         ::= BreakStatement:breakStatement{ return breakStatement; }
134         |   ContinueStatement:continueStatement{ return continueStatement; }
135         |   ReturnStatement:returnStatement{ return returnStatement; }
136         |   GotoStatement:gotoStatement{ return gotoStatement; }
137         ;
138 
139     BreakStatement : soulng::cppcode::Statement*
140         ::= (BREAK SEMICOLON!){ return new soulng::cppcode::BreakStatement(); }
141         ;
142 
143     ContinueStatement : soulng::cppcode::Statement*
144         ::= (CONTINUE SEMICOLON!){ return new soulng::cppcode::ContinueStatement(); }
145         ;
146 
147     ReturnStatement : soulng::cppcode::Statement*
148         ::= (RETURN CppExpression:returnValue? SEMICOLON!){ return new soulng::cppcode::ReturnStatement(returnValue); }
149         ;
150 
151     GotoStatement(var std::u32string target) : soulng::cppcode::Statement*
152         ::= (GOTO ID!{ target = lexer.GetMatch(span); } SEMICOLON!){ return new soulng::cppcode::GotoStatement(target); }
153         ;
154 
155     DeclarationStatement : soulng::cppcode::Statement*
156         ::= BlockDeclaration:declaration{ return new soulng::cppcode::DeclarationStatement(declaration); }
157         ;
158 
159     Condition : soulng::cppcode::CppObject*
160         ::= TypeId:typeId Declarator:declarator ASSIGN AssignmentExpression:assignmentExpr{ return new soulng::cppcode::ConditionWithDeclarator(typeId, declarator, assignmentExpr); }
161         |   CppExpression:expr{ return expr; }
162         ;
163 
164     TryStatement(var std::unique_ptr tryStatement) : soulng::cppcode::Statement*
165         ::=
166         (   TRY CompoundStatement:tryBlock{ tryStatement.reset(new soulng::cppcode::TryStatement(tryBlock)); }
167             HandlerSeq(tryStatement.get()):handlerSeq!
168         )
169         {
170             return tryStatement.release();
171         }
172         ;
173 
174     HandlerSeq(soulng::cppcode::TryStatement* tryStatement)
175         ::= Handler:handler!{ tryStatement->Add(handler); } HandlerSeq(tryStatement):handlerSeq?
176         ;
177 
178     Handler : soulng::cppcode::Handler*
179         ::= CATCH LPAREN! ExceptionDeclaration:exceptionDeclaration! RPAREN! CompoundStatement:catchBlock!
180         {
181             return new soulng::cppcode::Handler(exceptionDeclaration, catchBlock);
182         }
183         ;
184 
185     ExceptionDeclaration(var std::unique_ptr exceptionDeclaration) : soulng::cppcode::ExceptionDeclaration*
186         ::= empty{ exceptionDeclaration.reset(new soulng::cppcode::ExceptionDeclaration()); }
187         (   TypeSpecifierSeq(exceptionDeclaration->GetTypeId()):typeSpecifierSeq
188             (   Declarator:declarator{ exceptionDeclaration->GetTypeId()->Declarator() = declarator; }
189             |   AbstractDeclarator:abstractDeclarator{ exceptionDeclaration->GetTypeId()->Declarator() = abstractDeclarator; }
190             )?
191         |   ELLIPSIS{ exceptionDeclaration->CatchAll() = true; }
192         )
193         {
194             return exceptionDeclaration.release();
195         }
196         ;
197 
198     ExpressionStatement : soulng::cppcode::Statement*
199         ::= (CppExpression:expr SEMICOLON!){ return new soulng::cppcode::ExpressionStatement(expr); }
200         ;
201 
202     ruleinfo
203     {
204         (Statement, "C++ statement"), (LabeledStatement, "labeled statement"), (EmptyStatement, "empty statement"), (CompoundStatement, "compound statement"),
205         (SelectionStatement, "selection statement"), (IfStatement, "if-statement"), (SwitchStatement, "switch-statement"), (IterationStatement, "iteration statement"),
206         (WhileStatement, "while-statement"), (DoStatement, "do-statement"), (RangeForStatement, "range-based for-statement"), (ForRangeDeclaration, "for-range declaration"),
207         (ForStatement, "for-statement"), (ForInitStatement, "for initialization statement"), (JumpStatement, "jump statement"), (BreakStatement, "break-statement"),
208         (ContinueStatement, "continue-statement"), (ReturnStatement, "return-statement"), (GotoStatement, "goto-statement"), (DeclarationStatement, "declaration statement"),
209         (Condition, "condition"), (TryStatement, "try-statement"), (HandlerSeq, "handler sequence"), (Handler, "handler"), (ExceptionDeclaration, "exception declaration"),
210         (ExpressionStatement, "expression statement")
211     }
212 }