1
2
3
4
5
6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
7 [hpp]#include <sngcm/ast/Statement.hpp>
8 [hpp]#include <sngcm/cmparser/ParsingContext.hpp>
9 [cpp]#include <sngcm/cmparser/Expression.hpp>
10 [cpp]#include <sngcm/cmparser/TypeExpr.hpp>
11 [cpp]#include <sngcm/cmparser/Identifier.hpp>
12 [cpp]#include <sngcm/cmlexer/CmajorLexer.hpp>
13 [cpp]#include <sngcm/cmlexer/CmajorTokens.hpp>
14
15 using namespace sngcm::ast;
16 using namespace CmajorTokens;
17
18 parser api(SNGCM_PARSER_API) StatementParser
19 {
20 uselexer CmajorLexer;
21
22 using ExpressionParser.Expression;
23 using ExpressionParser.ArgumentList;
24 using TypeExprParser.TypeExpr;
25 using IdentifierParser.Identifier;
26
27 Statement(boost::uuids::uuid* moduleId, ParsingContext* ctx) : StatementNode*
28 ::= LabeledStatement(moduleId, ctx):labeledStatement{ return labeledStatement; }
29 | ControlStatement(moduleId, ctx):controlStatement{ return controlStatement; }
30 | ExpressionStatement(moduleId, ctx):expressionStatement{ return expressionStatement; }
31 | AssignmentStatement(moduleId, ctx):assignmentStatement{ return assignmentStatement; }
32 | ConstructionStatement(moduleId, ctx):constructionStatement{ return constructionStatement; }
33 | DeleteStatement(moduleId, ctx):deleteStatement{ return deleteStatement; }
34 | DestroyStatement(moduleId, ctx):destroyStatement{ return destroyStatement; }
35 | EmptyStatement(moduleId, ctx):emptyStatement{ return emptyStatement; }
36 | ThrowStatement(moduleId, ctx):throwStatement{ return throwStatement; }
37 | TryStatement(moduleId, ctx):tryStatement{ return tryStatement; }
38 | AssertStatement(moduleId, ctx):assertStatement{ return assertStatement; }
39 | ConditionalCompilationStatement(moduleId, ctx):condCompStatement{ return condCompStatement; }
40 ;
41
42 Label(boost::uuids::uuid* moduleId, var Span s, var std::u32string label) : LabelNode*
43 ::= (ID{ s = span; label = lexer.GetMatch(span); } COLON{ s.end = span.end; }){ return new LabelNode(s, *moduleId, label); }
44 ;
45
46 LabeledStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr stmt) : StatementNode*
47 ::= Label(moduleId):lbl Statement(moduleId, ctx):s{ stmt.reset(new LabeledStatementNode(span, *moduleId, s)); stmt->SetLabelNode(lbl); return stmt.release(); }
48 ;
49
50 ControlStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx) : StatementNode*
51 ::= CompoundStatement(moduleId, ctx):compoundStatement{ return compoundStatement; }
52 | ReturnStatement(moduleId, ctx):returnStatement{ return returnStatement; }
53 | IfStatement(moduleId, ctx):ifStatement{ return ifStatement; }
54 | WhileStatement(moduleId, ctx):whileStatement{ return whileStatement; }
55 | DoStatement(moduleId, ctx):doStatement{ return doStatement; }
56 | RangeForStatement(moduleId, ctx):rangeForStatement{ return rangeForStatement; }
57 | ForStatement(moduleId, ctx):forStatement{ return forStatement; }
58 | BreakStatement(moduleId, ctx):breakStatement{ return breakStatement; }
59 | ContinueStatement(moduleId, ctx):continueStatement{ return continueStatement; }
60 | GotoStatement(moduleId, ctx):gotoStatement{ return gotoStatement; }
61 | SwitchStatement(moduleId, ctx):switchStatement{ return switchStatement; }
62 | GotoCaseStatement(moduleId, ctx):gotoCaseStatement{ return gotoCaseStatement; }
63 | GotoDefaultStatement(moduleId, ctx):gotoDefaultStatement{ return gotoDefaultStatement; }
64 ;
65
66 CompoundStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr compoundStatement) : CompoundStatementNode*
67 ::= LBRACE{ compoundStatement.reset(new CompoundStatementNode(span, *moduleId)); compoundStatement->SetBeginBraceSpan(span); }
68 (Statement(moduleId, ctx):stmt{ compoundStatement->AddStatement(stmt); })* RBRACE!
69 {
70 compoundStatement->SetEndBraceSpan(span);
71 compoundStatement->SetSpanEnd(span.end);
72 return compoundStatement.release();
73 }
74 ;
75
76 ReturnStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
77 ::= RETURN{ s = span; } Expression(moduleId, ctx):expr? SEMICOLON!{ s.end = span.end; return new ReturnStatementNode(s, *moduleId, expr); }
78 ;
79
80 IfStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var Span leftParenSpan, var Span rightParenSpan, var Span elseSpan, var std::unique_ptr condNode) : IfStatementNode*
81 ::=
82 ( IF{ s = span; } LPAREN{ leftParenSpan = span; } Expression(moduleId, ctx):cond{ condNode.reset(cond); s.end = condNode->GetSpan().end; }
83 RPAREN{ rightParenSpan = span; s.end = span.end; }
84 Statement(moduleId, ctx):thenS (ELSE{ elseSpan = span; } Statement(moduleId, ctx):elseS)?
85 )
86 {
87 IfStatementNode* value = new IfStatementNode(s, *moduleId, condNode.release(), thenS, elseS);
88 value->SetLeftParenSpan(leftParenSpan);
89 value->SetRightParenSpan(rightParenSpan);
90 value->SetElseSpan(elseSpan);
91 return value;
92 }
93 ;
94
95 WhileStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var Span leftParenSpan, var Span rightParenSpan) : WhileStatementNode*
96 ::= (WHILE{ s = span; } LPAREN!{ leftParenSpan = span; } Expression(moduleId, ctx):cond! RPAREN!{ rightParenSpan = span; } Statement(moduleId, ctx):stmt!{ s.end = span.end; })
97 {
98 WhileStatementNode* value = new WhileStatementNode(s, *moduleId, cond, stmt);
99 value->SetLeftParenSpan(leftParenSpan);
100 value->SetRightParenSpan(rightParenSpan);
101 return value;
102 }
103 ;
104
105 DoStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var Span whileSpan, var Span leftParenSpan, var Span rightParenSpan) : DoStatementNode*
106 ::= (DO{ s = span; } Statement(moduleId, ctx):stmt! WHILE!{ whileSpan = span; } LPAREN!{ leftParenSpan = span; } Expression(moduleId, ctx):cond! RPAREN!{ rightParenSpan = span; } SEMICOLON!{ s.end = span.end; })
107 {
108 DoStatementNode* value = new DoStatementNode(s, *moduleId, stmt, cond);
109 value->SetWhileSpan(whileSpan);
110 value->SetLeftParenSpan(leftParenSpan);
111 value->SetRightParenSpan(rightParenSpan);
112 return value;
113 }
114 ;
115
116 ForStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var Span leftParenSpan, var Span rightParenSpan) : ForStatementNode*
117 ::=
118 (
119 FOR{ s = span; } LPAREN{ leftParenSpan = span; } ForInitStatement(moduleId, ctx):init! Expression(moduleId, ctx):cond? SEMICOLON! ForLoopStatementExpr(moduleId, ctx):loop! RPAREN!{ rightParenSpan = span; }
120 Statement(moduleId, ctx):stmt!{ s.end = span.end; }
121 )
122 {
123 ForStatementNode* value = new ForStatementNode(s, *moduleId, init, cond, loop, stmt);
124 value->SetLeftParenSpan(leftParenSpan);
125 value->SetRightParenSpan(rightParenSpan);
126 return value;
127 }
128 ;
129
130 ForInitStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx) : StatementNode*
131 ::= AssignmentStatement(moduleId, ctx):assignmentStatement{ return assignmentStatement; }
132 | ConstructionStatement(moduleId, ctx):constructionStatement{ return constructionStatement; }
133 | EmptyStatement(moduleId, ctx):emptyStatement{ return emptyStatement; }
134 ;
135
136 ForLoopStatementExpr(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr exprNode) : StatementNode*
137 ::= AssignmentStatementExpr(moduleId, ctx):assignmentStatementExpr
138 {
139 return assignmentStatementExpr;
140 }
141 | Expression(moduleId, ctx):expr
142 {
143 exprNode.reset(expr);
144 Span s = exprNode->GetSpan();
145 ExpressionStatementNode* expressionStatementNode = new ExpressionStatementNode(s, *moduleId, exprNode.release());
146 return expressionStatementNode;
147 }
148 | empty
149 {
150 EmptyStatementNode* emptyStatementNode = new EmptyStatementNode(span, *moduleId);
151 return emptyStatementNode;
152 }
153 ;
154
155 RangeForStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var Span leftParenSpan, var Span rightParenSpan, var Span colonSpan) : RangeForStatementNode*
156 ::=
157 (
158 FOR{ s = span; } LPAREN{ leftParenSpan = span; } TypeExpr(moduleId, ctx):type Identifier(moduleId):id COLON{ colonSpan = span; } Expression(moduleId, ctx):container! RPAREN!{ rightParenSpan = span; }
159 Statement(moduleId, ctx):action{ s.end = span.end; }
160 )
161 {
162 RangeForStatementNode* value = new RangeForStatementNode(s, *moduleId, type, id, container, action);
163 value->SetLeftParenSpan(leftParenSpan);
164 value->SetRightParenSpan(rightParenSpan);
165 value->SetColonSpan(colonSpan);
166 return value;
167 }
168 ;
169
170 BreakStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
171 ::= BREAK{ s = span; } SEMICOLON!{ s.end = span.end; return new BreakStatementNode(s, *moduleId); }
172 ;
173
174 ContinueStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
175 ::= CONTINUE{ s = span; } SEMICOLON!{ s.end = span.end; return new ContinueStatementNode(s, *moduleId); }
176 ;
177
178 GotoStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::u32string label, var Span s) : StatementNode*
179 ::= GOTO{ s = span; } ID{ label = lexer.GetMatch(span); } SEMICOLON!{ s.end = span.end; return new GotoStatementNode(s, *moduleId, label); }
180 ;
181
182 SwitchStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr switchStatement,
183 var Span leftParenSpan, var Span rightParenSpan, var Span beginBraceSpan, var Span endBraceSpan) : SwitchStatementNode*
184 ::= (SWITCH LPAREN!{ leftParenSpan = span; } Expression(moduleId, ctx):cond! RPAREN!)
185 {
186 rightParenSpan = span;
187 switchStatement.reset(new SwitchStatementNode(span, *moduleId, cond));
188 switchStatement->SetLeftParenSpan(leftParenSpan);
189 switchStatement->SetRightParenSpan(rightParenSpan);
190 }
191 LBRACE!{ beginBraceSpan = span; }
192 ( CaseStatement(moduleId, ctx):caseStatement{ switchStatement->AddCase(caseStatement); }
193 | DefaultStatement(moduleId, ctx):defaultStatement{ switchStatement->SetDefault(defaultStatement); }
194 )*
195 RBRACE!{ endBraceSpan = span; switchStatement->SetBeginBraceSpan(beginBraceSpan); switchStatement->SetEndBraceSpan(endBraceSpan); return switchStatement.release(); }
196 ;
197
198 CaseStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr caseS, var Span s, var Span caseSpan) : CaseStatementNode*
199 ::= empty{ caseS.reset(new CaseStatementNode(span, *moduleId)); s = span; }
200 (((CASE{ caseSpan = span; } Expression(moduleId, ctx):caseExpr{ caseS->AddCaseSpan(caseSpan); caseS->AddCaseExpr(caseExpr); } COLON!)+){ s.end = span.end; caseS->SetSpan(s); }
201 (Statement(moduleId, ctx):stmt{ caseS->AddStatement(stmt); })*
202 )
203 {
204 return caseS.release();
205 }
206 ;
207
208 DefaultStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr defaultS, var Span s) : DefaultStatementNode*
209 ::= (DEFAULT{ s = span; } COLON!{ s.end = span.end; defaultS.reset(new DefaultStatementNode(s, *moduleId)); }
210 (Statement(moduleId, ctx):stmt{ defaultS->AddStatement(stmt); })*
211 )
212 {
213 return defaultS.release();
214 }
215 ;
216
217 GotoCaseStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
218 ::= GOTO{ s = span; } CASE Expression(moduleId, ctx):caseExpr SEMICOLON!{ s.end = span.end; return new GotoCaseStatementNode(s, *moduleId, caseExpr); }
219 ;
220
221 GotoDefaultStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
222 ::= GOTO{ s = span; } DEFAULT SEMICOLON!{ s.end = span.end; return new GotoDefaultStatementNode(s, *moduleId); }
223 ;
224
225 AssignmentStatementExpr(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr target, var Span s) : StatementNode*
226 ::= empty{ ctx->PushParsingLvalue(true); }
227 Expression(moduleId, ctx):tgt{ target.reset(tgt); s = target->GetSpan(); ctx->PopParsingLvalue(); } / { ctx->PopParsingLvalue(); } ASSIGN Expression(moduleId, ctx):source
228 {
229 s.end = span.end; return new AssignmentStatementNode(s, *moduleId, target.release(), source);
230 }
231 ;
232
233 AssignmentStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr statement) : StatementNode*
234 ::= AssignmentStatementExpr(moduleId, ctx):stmt SEMICOLON{ statement.reset(stmt); statement->SetSpanEnd(span.end); return statement.release(); }
235 ;
236
237 ConstructionStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr constructionStatement) : ConstructionStatementNode*
238 ::= (TypeExpr(moduleId, ctx):type Identifier(moduleId):id!){ constructionStatement.reset(new ConstructionStatementNode(span, *moduleId, type, id)); }
239 ( ASSIGN Expression(moduleId, ctx):value!{ constructionStatement->AddArgument(value); constructionStatement->SetAssignment(); }
240 | LPAREN ArgumentList(moduleId, ctx, constructionStatement.get()):argumentList RPAREN!
241 | empty{ constructionStatement->SetEmpty(); }
242 )
243 SEMICOLON!{ constructionStatement->SetSpanEnd(span.end); return constructionStatement.release(); }
244 ;
245
246 DeleteStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
247 ::= DELETE{ s = span; } Expression(moduleId, ctx):ptr! SEMICOLON!{ s.end = span.end; return new DeleteStatementNode(s, *moduleId, ptr); }
248 ;
249
250 DestroyStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
251 ::= DESTROY{ s = span; } Expression(moduleId, ctx):ptr! SEMICOLON!{ s.end = span.end; return new DestroyStatementNode(s, *moduleId, ptr); }
252 ;
253
254 ExpressionStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr exprNode, var Span s) : StatementNode*
255 ::= empty{ ctx->PushParsingExpressionStatement(true); }
256 (Expression(moduleId, ctx):expr{ exprNode.reset(expr); s = span; } SEMICOLON{ s.end = span.end; })
257 {
258 ctx->PopParsingExpressionStatement();
259 exprNode->SetSpan(s);
260 return new ExpressionStatementNode(s, *moduleId, exprNode.release());
261 }
262 /
263 {
264 ctx->PopParsingExpressionStatement();
265 }
266 ;
267
268 EmptyStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx) : StatementNode*
269 ::= SEMICOLON{ return new EmptyStatementNode(span, *moduleId); }
270 ;
271
272 ThrowStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
273 ::= THROW{ s = span; } Expression(moduleId, ctx):exception? SEMICOLON!{ s.end = span.end; return new ThrowStatementNode(s, *moduleId, exception); }
274 ;
275
276 TryStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr tryStatement) : TryStatementNode*
277 ::=
278 ( (TRY CompoundStatement(moduleId, ctx):tryBlock){ tryStatement.reset(new TryStatementNode(span, *moduleId, tryBlock)); }
279 (Catch(moduleId, ctx):ctch{ tryStatement->AddCatch(ctch); })+
280 )
281 {
282 return tryStatement.release();
283 }
284 ;
285
286 Catch(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s, var Span leftParenSpan, var Span rightParenSpan) : CatchNode*
287 ::= CATCH{ s = span; } LPAREN!{ leftParenSpan = span; } TypeExpr(moduleId, ctx):catchType! Identifier(moduleId):catchId? RPAREN!{ rightParenSpan = span; }
288 CompoundStatement(moduleId, ctx):catchBlock
289 {
290 s.end = span.end;
291 CatchNode* value = new CatchNode(s, *moduleId, catchType, catchId, catchBlock);
292 value->SetLeftParenSpan(leftParenSpan);
293 value->SetRightParenSpan(rightParenSpan);
294 return value;
295 }
296 ;
297
298 AssertStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var Span s) : StatementNode*
299 ::= HASH{ s = span; } ASSERT Expression(moduleId, ctx):expr! SEMICOLON!{ s.end = span.end; return new AssertStatementNode(s, *moduleId, expr); }
300 ;
301
302 ConditionalCompilationStatement(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr condCompStmt,
303 var Span s, var Span keywordSpan, var Span leftParenSpan, var Span rightParenSpan) : ConditionalCompilationStatementNode*
304 ::= HASH{ s = span; keywordSpan = span; }
305 IF{ keywordSpan.end = span.end; } LPAREN!{ leftParenSpan = span; }
306 ConditionalCompilationExpression(moduleId):ifExpr{ s.end = span.end; condCompStmt.reset(new ConditionalCompilationStatementNode(s, *moduleId, ifExpr)); condCompStmt->IfPart()->SetKeywordSpan(keywordSpan); }
307 RPAREN!{ rightParenSpan = span; condCompStmt->IfPart()->SetLeftParenSpan(leftParenSpan); condCompStmt->IfPart()->SetRightParenSpan(rightParenSpan); }
308 (Statement(moduleId, ctx):ifS{ condCompStmt->AddIfStatement(ifS); })*
309 (
310 HASH{ keywordSpan = span; } ELIF{ keywordSpan.end = span.end; }
311 LPAREN!{ leftParenSpan = span; } ConditionalCompilationExpression(moduleId):elifExpr{ condCompStmt->AddElifExpr(span, *moduleId, elifExpr); } RPAREN!
312 {
313 rightParenSpan = span;
314 condCompStmt->SetElifLeftParenSpan(leftParenSpan);
315 condCompStmt->SetElifRightParenSpan(rightParenSpan);
316 condCompStmt->SetElifKeywordSpan(keywordSpan);
317 }
318 (Statement(moduleId, ctx):elifS{ condCompStmt->AddElifStatement(elifS); })*
319 )*
320 (
321 HASH{ keywordSpan = span; } ELSE (Statement(moduleId, ctx):elseS{ condCompStmt->AddElseStatement(span, *moduleId, elseS); })* empty{ condCompStmt->ElsePart()->SetKeywordSpan(keywordSpan); }
322 )?
323 HASH{ keywordSpan = span; } ENDIF!{ keywordSpan.end = span.end; condCompStmt->SetEndIfSpan(keywordSpan); return condCompStmt.release(); }
324 ;
325
326 ConditionalCompilationExpression(boost::uuids::uuid* moduleId) : ConditionalCompilationExpressionNode*
327 ::= ConditionalCompilationDisjunction(moduleId):disjunction{ return disjunction; }
328 ;
329
330 ConditionalCompilationDisjunction(boost::uuids::uuid* moduleId, var Span s, var std::unique_ptr condCompExpr) : ConditionalCompilationExpressionNode*
331 ::=
332 (
333 ConditionalCompilationConjunction(moduleId):left{ s = span; condCompExpr.reset(left); }
334 (DISJUNCTION ConditionalCompilationConjunction(moduleId):right{ s.end = span.end; condCompExpr.reset(new ConditionalCompilationDisjunctionNode(s, *moduleId, condCompExpr.release(), right)); })*
335 )
336 {
337 return condCompExpr.release();
338 }
339 ;
340
341 ConditionalCompilationConjunction(boost::uuids::uuid* moduleId, var Span s, var std::unique_ptr condCompExpr) : ConditionalCompilationExpressionNode*
342 ::=
343 (
344 ConditionalCompilationPrefix(moduleId):left{ s = span; condCompExpr.reset(left); }
345 (AMPAMP ConditionalCompilationPrefix(moduleId):right{ s.end = span.end; condCompExpr.reset(new ConditionalCompilationConjunctionNode(s, *moduleId, condCompExpr.release(), right)); })*
346 )
347 {
348 return condCompExpr.release();
349 }
350 ;
351
352 ConditionalCompilationPrefix(boost::uuids::uuid* moduleId, var Span s, var std::unique_ptr condCompExpr) : ConditionalCompilationExpressionNode*
353 ::=
354 ( EXCLAMATION{ s = span; } ConditionalCompilationPrefix(moduleId):prefix{ s.end = span.end; condCompExpr.reset(new ConditionalCompilationNotNode(s, *moduleId, prefix)); }
355 | ConditionalCompilationPrimary(moduleId):primary!{ condCompExpr.reset(primary); }
356 )
357 {
358 return condCompExpr.release();
359 }
360 ;
361
362 ConditionalCompilationPrimary(boost::uuids::uuid* moduleId, var std::u32string symbol) : ConditionalCompilationExpressionNode*
363 ::= ID{ symbol = lexer.GetMatch(span); return new ConditionalCompilationPrimaryNode(span, *moduleId, symbol); }
364 | LPAREN ConditionalCompilationExpression(moduleId):expr RPAREN!{ return new ParenthesizedConditionalCompilationExpressionNode(span, *moduleId, expr); }
365 ;
366
367 ruleinfo
368 {
369 (Statement, "statement"), (Label, "label"), (LabeledStatement, "labeled statement"), (ControlStatement, "control statement"), (CompoundStatement, "compound statement"),
370 (ReturnStatement, "return statement"), (IfStatement, "if statement"), (WhileStatement, "while statement"), (DoStatement, "do statement"),
371 (ForStatement, "for statement"), (ForInitStatement, "for initialization statement"), (ForLoopStatementExpr, "for loop expression"),
372 (RangeForStatement, "range for statement"), (BreakStatement, "break statement"), (ContinueStatement, "continue statement"), (GotoStatement, "goto statement"),
373 (SwitchStatement, "switch statement"), (CaseStatement, "case statement"), (DefaultStatement, "default statement"), (GotoCaseStatement, "goto case statement"),
374 (GotoDefaultStatement, "goto default statement"), (AssignmentStatementExpr, "assignment expression"), (AssignmentStatement, "assignment statement"),
375 (ConstructionStatement, "construction statement"), (DeleteStatement, "delete statement"), (DestroyStatement, "destroy statement"), (ExpressionStatement, "expression statement"),
376 (EmptyStatement, "empty statement"), (ThrowStatement, "throw statement"), (TryStatement, "try statement"), (Catch, "catch statement"), (AssertStatement, "assert statement"),
377 (ConditionalCompilationStatement, "conditional compilation statement"), (ConditionalCompilationExpression, "conditional compilation expression"),
378 (ConditionalCompilationDisjunction, "conditional compilation disjunction"), (ConditionalCompilationConjunction, "conditional compilation conjunction"),
379 (ConditionalCompilationPrefix, "conditional compilation prefix expression"), (ConditionalCompilationPrimary, "conditional compilation primary expression")
380 }
381 }