1
2
3
4
5
6 [hpp]#include <sngcpp/parser/ParserApi.hpp>
7 [hpp]#include <sngcpp/ast/Statement.hpp>
8 [hpp]#include <sngcpp/parser/ParsingContext.hpp>
9 [cpp]#include <sngcpp/parser/Declaration.hpp>
10 [cpp]#include <sngcpp/parser/Declarator.hpp>
11 [cpp]#include <sngcpp/parser/Expression.hpp>
12 [cpp]#include <sngcpp/parser/Identifier.hpp>
13 [cpp]#include <sngcpp/parser/TypeExpr.hpp>
14 [cpp]#include <sngcpp/lexer/CppLexer.hpp>
15 [cpp]#include <sngcpp/lexer/CppTokens.hpp>
16
17 using namespace CppTokens;
18 using namespace soulng::lexer;
19
20 parser api(SNGCPP_PARSER_API) StatementParser
21 {
22 uselexer CppLexer;
23
24 using ExpressionParser.ConstantExpression;
25 using ExpressionParser.Expression;
26 using DeclarationParser.BlockDeclaration;
27 using DeclarationParser.SimpleDeclaration;
28 using DeclaratorParser.BracedInitializerList;
29 using DeclaratorParser.Declarator;
30 using DeclaratorParser.InitializerClause;
31 using IdentifierParser.Identifier;
32 using TypeExprParser.TypeExpr;
33
34 Statement(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
35 ::= LabeledStatement(ctx):labeledStatement{ return labeledStatement; }
36 | ExpressionStatement(ctx):expressionStatement{ return expressionStatement; }
37 | CompoundStatement(ctx):compoundStatement{ return compoundStatement; }
38 | SelectionStatement(ctx):selectionStatement{ return selectionStatement; }
39 | IterationStatement(ctx):iterationStatement{ return iterationStatement; }
40 | JumpStatement(ctx):jumpStatement{ return jumpStatement; }
41 | DeclarationStatement(ctx):declarationStatement{ return declarationStatement; }
42 | TryStatement(ctx):tryStatement{ return tryStatement; }
43 ;
44
45 LabeledStatement(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
46 ::= Identifier:id{ s = span; } COLON Statement(ctx):ls{ s.end = span.end; return new sngcpp::ast::LabeledStatementNode(s, id, ls); }
47 | CASE{ s = span; } ConstantExpression(ctx):caseExpr! COLON! Statement(ctx):cs!{ s.end = span.end; return new sngcpp::ast::CaseStatementNode(s, caseExpr, cs); }
48 | DEFAULT{ s = span; } COLON! Statement(ctx):ds!{ s.end = span.end; return new sngcpp::ast::DefaultStatementNode(s, ds); }
49 ;
50
51 ExpressionStatement(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
52 ::= empty{ s = span; } Expression(ctx):expr? SEMICOLON{ s.end = span.end; return new sngcpp::ast::ExpressionStatementNode(s, expr); }
53 ;
54
55 CompoundStatement(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr node) : sngcpp::ast::CompoundStatementNode*
56 ::= LBRACE{ node.reset(new sngcpp::ast::CompoundStatementNode(span)); } (Statement(ctx):stmt{ node->AddStatement(span, stmt); })* RBRACE!{ node->SetEndBraceSpan(span); return node.release(); }
57 ;
58
59 SelectionStatement(sngcpp::cppparser::ParsingContext* ctx, var Span s, var Span elseSpan) : sngcpp::ast::Node*
60 ::= (IF{ s = span; } LPAREN! Condition(ctx):cond1! RPAREN! Statement(ctx):thenS!{ s.end = span.end; } (ELSE{ elseSpan = span; } Statement(ctx):elseS!{ s.end = span.end; })?)
61 {
62 return new sngcpp::ast::IfStatementNode(s, cond1, thenS, elseS, elseSpan);
63 }
64 | (SWITCH{ s = span; } LPAREN! Condition(ctx):cond2! RPAREN! Statement(ctx):stmt!{ s.end = span.end; })
65 {
66 return new sngcpp::ast::SwitchStatementNode(s, cond2, stmt);
67 }
68 ;
69
70 IterationStatement(sngcpp::cppparser::ParsingContext* ctx, var Span s, var Span whileSpan) : sngcpp::ast::Node*
71 ::= WHILE{ s = span; } LPAREN! Condition(ctx):cond1! RPAREN! Statement(ctx):stmt1!
72 {
73 s.end = span.end;
74 return new sngcpp::ast::WhileStatementNode(s, cond1, stmt1);
75 }
76 | DO{ s = span; } Statement(ctx):stmt2 WHILE!{ whileSpan = span; } LPAREN! Expression(ctx):cond2! RPAREN! SEMICOLON!
77 {
78 s.end = span.end;
79 return new sngcpp::ast::DoStatementNode(s, stmt2, cond2, whileSpan);
80 }
81 | FOR{ s = span; } LPAREN ForRangeDeclaration(ctx):forRange COLON ForRangeInitializer(ctx):forRangeInit! RPAREN! Statement(ctx):stmt3!
82 {
83 s.end = span.end;
84 return new sngcpp::ast::RangeForStatementNode(s, forRange, forRangeInit, stmt3);
85 }
86 | FOR{ s = span; } LPAREN ForInitStatement(ctx):forInit Condition(ctx):cond4? SEMICOLON Expression(ctx):loopExpr? RPAREN! Statement(ctx):stmt4!
87 {
88 s.end = span.end;
89 return new sngcpp::ast::ForStatementNode(s, forInit, cond4, loopExpr, stmt4);
90 }
91 ;
92
93 JumpStatement(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
94 ::= BREAK{ s = span; } SEMICOLON!{ s.end = span.end; return new sngcpp::ast::BreakStatementNode(s); }
95 | CONTINUE{ s = span; } SEMICOLON!{ s.end = span.end; return new sngcpp::ast::ContinueStatementNode(s); }
96 | RETURN{ s = span; } Expression(ctx):expr? SEMICOLON!{ s.end = span.end; return new sngcpp::ast::ReturnStatementNode(s, expr); }
97 | RETURN{ s = span; } BracedInitializerList(ctx):bi SEMICOLON!{ s.end = span.end; return new sngcpp::ast::ReturnStatementNode(s, bi); }
98 | GOTO{ s = span; } Identifier:target! SEMICOLON!{ s.end = span.end; return new sngcpp::ast::GotoStatementNode(s, target); }
99 ;
100
101 DeclarationStatement(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
102 ::= BlockDeclaration(ctx):declaration{ return new sngcpp::ast::DeclarationStatementNode(span, declaration); }
103 ;
104
105 TryStatement(sngcpp::cppparser::ParsingContext* ctx, var std::unique_ptr node, var Span s) : sngcpp::ast::Node*
106 ::= TRY{ s = span; } CompoundStatement(ctx):tryBlock!{ s.end = span.end; node.reset(new sngcpp::ast::TryStatementNode(s, tryBlock)); } HandlerSequence(ctx, node.get()):handlerSequence!
107 {
108 return node.release();
109 }
110 ;
111
112 HandlerSequence(sngcpp::cppparser::ParsingContext* ctx, sngcpp::ast::TryStatementNode* tryStatementNode)
113 ::= (Handler(ctx):handler{ tryStatementNode->AddHandler(span, handler); })+
114 ;
115
116 Handler(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
117 ::= CATCH{ s = span; } LPAREN! ExceptionDeclaration(ctx):exceptionDeclaration! RPAREN! CompoundStatement(ctx):catchBlock!
118 {
119 s.end = span.end;
120 return new sngcpp::ast::HandlerNode(s, exceptionDeclaration, catchBlock);
121 }
122 ;
123
124 Condition(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
125 ::= TypeExpr(ctx):typeExpr{ s = span; } Declarator(ctx):declarator
126 ( ASSIGN InitializerClause(ctx):ic
127 {
128 s.end = span.end;
129 return new sngcpp::ast::SimpleDeclarationNode(s, sngcpp::ast::Specifier::none, typeExpr, new sngcpp::ast::InitDeclaratorNode(s, declarator, new sngcpp::ast::AssignmentInitializerNode(s, ic)));
130 }
131 | BracedInitializerList(ctx):bi
132 {
133 s.end = span.end;
134 return new sngcpp::ast::SimpleDeclarationNode(s, sngcpp::ast::Specifier::none, typeExpr, new sngcpp::ast::InitDeclaratorNode(s, declarator, bi));
135 }
136 )
137 | Expression(ctx):expr{ return expr; }
138 ;
139
140 ForRangeDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
141 ::= TypeExpr(ctx):typeExpr{ s = span; } Declarator(ctx):declarator{ s.end = span.end; return new sngcpp::ast::SimpleDeclarationNode(s, sngcpp::ast::Specifier::none, typeExpr, declarator); }
142 ;
143
144 ForRangeInitializer(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
145 ::= Expression(ctx):expr{ return expr;}
146 | BracedInitializerList(ctx):bi{ return bi; }
147 ;
148
149 ForInitStatement(sngcpp::cppparser::ParsingContext* ctx) : sngcpp::ast::Node*
150 ::= ExpressionStatement(ctx):expressionStatement{ return expressionStatement; }
151 | SimpleDeclaration(ctx):simpleDeclaration{ return simpleDeclaration; }
152 ;
153
154 ExceptionDeclaration(sngcpp::cppparser::ParsingContext* ctx, var Span s) : sngcpp::ast::Node*
155 ::= (TypeExpr(ctx):typeExpr{ s = span; } (Declarator(ctx):declarator{ s.end = span.end; })?){ return new sngcpp::ast::SimpleDeclarationNode(s, sngcpp::ast::Specifier::none, typeExpr, declarator); }
156 | ELLIPSES{ return new sngcpp::ast::CatchAllNode(span); }
157 ;
158 }