• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rieske / trans / 28460339749

30 Jun 2026 04:35PM UTC coverage: 90.401% (-0.1%) from 90.53%
28460339749

Pull #44

github

rieske
Simplify struct field codegen to FieldAddress only

Drop FieldLoad/FieldStore; materialize the field address then reuse
Dereference for reads and LvalueAssign for writes. Keep a single
baseIsPointer flag on FieldAddress for dot vs arrow.
Pull Request #44: Implement C structs with member access

236 of 282 new or added lines in 12 files covered. (83.69%)

7 existing lines in 2 files now uncovered.

5349 of 5917 relevant lines covered (90.4%)

235740.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.24
/src/ast/ContextualSyntaxNodeBuilder.cpp
1
#include "ContextualSyntaxNodeBuilder.h"
2
#include "MemberAccess.h"
3

4
#include <algorithm>
5
#include <sstream>
6

7
#include "ArithmeticExpression.h"
8
#include "ArrayAccess.h"
9
#include "ArrayDeclarator.h"
10
#include "AssignmentExpression.h"
11
#include "BitwiseExpression.h"
12
#include "Block.h"
13
#include "ComparisonExpression.h"
14
#include "ConstantExpression.h"
15
#include "ExpressionList.h"
16
#include "ForLoopHeader.h"
17
#include "FunctionCall.h"
18
#include "FunctionDefinition.h"
19
#include "Identifier.h"
20
#include "IdentifierExpression.h"
21
#include "IfElseStatement.h"
22
#include "IfStatement.h"
23
#include "JumpStatement.h"
24
#include "LogicalAndExpression.h"
25
#include "LogicalOrExpression.h"
26
#include "LoopStatement.h"
27
#include "Operator.h"
28
#include "PostfixExpression.h"
29
#include "PrefixExpression.h"
30
#include "ReturnStatement.h"
31
#include "VoidReturnStatement.h"
32
#include "ShiftExpression.h"
33
#include "TypeCast.h"
34
#include "UnaryExpression.h"
35
#include "WhileLoopHeader.h"
36

37
#include "ast/StringLiteralExpression.h"
38
#include "types/Type.h"
39

40
namespace ast {
41

42
void doNothing(AbstractSyntaxTreeBuilderContext&) {
70,380 ✔
43
}
70,380 ✔
44

45
void shortType(AbstractSyntaxTreeBuilderContext& context) {
×
46
    throw std::runtime_error { "short type is not implemented yet" };
×
47
}
48

49
void integerType(AbstractSyntaxTreeBuilderContext& context) {
1,104 ✔
50
    context.pushTypeSpecifier( { type::signedInteger(), context.popTerminal().value });
1,104 ✔
51
}
1,104 ✔
52

53
void longType(AbstractSyntaxTreeBuilderContext& context) {
×
54
    throw std::runtime_error { "long type is not implemented yet" };
×
55
}
56

57
void characterType(AbstractSyntaxTreeBuilderContext& context) {
6 ✔
58
    context.pushTypeSpecifier( { type::signedCharacter(), context.popTerminal().value });
6 ✔
59
}
6 ✔
60

61
void voidType(AbstractSyntaxTreeBuilderContext& context) {
38 ✔
62
    context.pushTypeSpecifier( { type::voidType(), context.popTerminal().value });
38 ✔
63
}
38 ✔
64

65
void floatType(AbstractSyntaxTreeBuilderContext& context) {
×
66
    context.pushTypeSpecifier( { type::floating(), context.popTerminal().value });
×
67
}
×
68

69
void doubleType(AbstractSyntaxTreeBuilderContext& context) {
×
70
    throw std::runtime_error { "double type is not implemented yet" };
×
71
}
72

73
void signedType(AbstractSyntaxTreeBuilderContext& context) {
×
74
    throw std::runtime_error { "signed type is not implemented yet" };
×
75
}
76

77
void unsignedType(AbstractSyntaxTreeBuilderContext& context) {
×
78
    throw std::runtime_error { "unsigned type is not implemented yet" };
×
79
}
80

81
void typedefName(AbstractSyntaxTreeBuilderContext& context) {
×
82
    throw std::runtime_error { "typedefName type is not implemented yet" };
×
83
}
84

85
void structOrUnionType(AbstractSyntaxTreeBuilderContext& context) {
14 ✔
86
    // type_spec -> struct_or_union_spec: TypeSpecifier already pushed.
87
}
14 ✔
88

89
void enumType(AbstractSyntaxTreeBuilderContext& context) {
×
90
    throw std::runtime_error { "enumType type is not implemented yet" };
×
91
}
92

93
void constQualifier(AbstractSyntaxTreeBuilderContext& context) {
×
94
    context.pushTypeQualifier(type::Qualifier::CONST);
×
95
}
×
96

97
void volatileQualifier(AbstractSyntaxTreeBuilderContext& context) {
×
98
    context.pushTypeQualifier(type::Qualifier::VOLATILE);
×
99
}
×
100

101
void typeQualifierList(AbstractSyntaxTreeBuilderContext& context) {
×
102
    context.newTypeQualifierList(context.popTypeQualifier());
×
103
}
×
104

105
void addTypeQualifierToList(AbstractSyntaxTreeBuilderContext& context) {
×
106
    context.addToTypeQualifierList(context.popTypeQualifier());
×
107
}
×
108

109
void parenthesizedExpression(AbstractSyntaxTreeBuilderContext& context) {
52 ✔
110
    context.popTerminal();
52 ✔
111
    context.popTerminal();
52 ✔
112
}
52 ✔
113

114
void declarationTypeSpecifier(AbstractSyntaxTreeBuilderContext& context) {
1,150 ✔
115
    context.pushDeclarationSpecifiers( { context.popTypeSpecifier() });
1,150 ✔
116
}
1,150 ✔
117

118
void addDeclarationTypeSpecifier(AbstractSyntaxTreeBuilderContext& context) {
×
119
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
×
120
    auto typeSpecifier = context.popTypeSpecifier();
×
121
    context.pushDeclarationSpecifiers( { typeSpecifier, declarationSpecifiers });
×
122
}
×
123

124
void declarationStorageClassSpecifier(AbstractSyntaxTreeBuilderContext& context) {
×
125
    context.pushDeclarationSpecifiers( { context.popStorageSpecifier() });
×
126
}
×
127

128
void addDeclarationStorageClassSpecifier(AbstractSyntaxTreeBuilderContext& context) {
×
129
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
×
130
    auto storageSpecifier = context.popStorageSpecifier();
×
131
    context.pushDeclarationSpecifiers( { storageSpecifier, declarationSpecifiers });
×
132
}
×
133

134
void declarationTypeQualifier(AbstractSyntaxTreeBuilderContext& context) {
×
135
    context.pushDeclarationSpecifiers( { context.popTypeQualifier() });
×
136
}
×
137

138
void addDeclarationTypeQualifier(AbstractSyntaxTreeBuilderContext& context) {
×
139
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
×
140
    auto typeQualifier = context.popTypeQualifier();
×
141
    context.pushDeclarationSpecifiers( { typeQualifier, declarationSpecifiers });
×
142
}
×
143

144
void identifierDeclarator(AbstractSyntaxTreeBuilderContext& context) {
1,276 ✔
145
    context.pushDirectDeclarator(std::make_unique<Identifier>(context.popTerminal()));
1,276 ✔
146
}
1,276 ✔
147

148
void arrayDeclarator(AbstractSyntaxTreeBuilderContext& context) {
×
149
    context.popTerminal();
×
150
    context.popTerminal();
×
151
    context.pushDirectDeclarator(std::make_unique<ArrayDeclarator>(context.popDirectDeclarator(), context.popExpression()));
×
152
}
×
153

154
void abstractArrayDeclarator(AbstractSyntaxTreeBuilderContext& context) {
×
155
    context.popTerminal();
×
156
    context.popTerminal();
×
157
    //context.pushDeclarator(std::make_unique<ArrayDeclarator>(context.popDirectDeclarator()));
158
    throw std::runtime_error { "abstract array declarator is not implemented yet" };
×
159
}
160

161
void functionDeclarator(AbstractSyntaxTreeBuilderContext& context) {
70 ✔
162
    context.popTerminal();
70 ✔
163
    context.popTerminal();
70 ✔
164
    auto arguments = context.popArgumentsDeclaration().first;
70 ✔
165
    // `(void)` is an empty parameter list, not a single void parameter.
166
    if (arguments.size() == 1 && arguments.front().isVoid()) {
70 ✔
167
        arguments.clear();
2 ✔
168
    }
169
    context.pushDirectDeclarator(std::make_unique<FunctionDeclarator>(context.popDirectDeclarator(), std::move(arguments)));
70 ✔
170
}
70 ✔
171

172
void noargFunctionDeclarator(AbstractSyntaxTreeBuilderContext& context) {
406 ✔
173
    context.popTerminal();
406 ✔
174
    context.popTerminal();
406 ✔
175
    context.pushDirectDeclarator(std::make_unique<FunctionDeclarator>(context.popDirectDeclarator()));
406 ✔
176
}
406 ✔
177

178
void pointerToDeclarator(AbstractSyntaxTreeBuilderContext& context) {
68 ✔
179
    context.pushDeclarator(std::make_unique<Declarator>(context.popDirectDeclarator(), context.popPointers()));
68 ✔
180
}
68 ✔
181

182
void declarator(AbstractSyntaxTreeBuilderContext& context) {
1,208 ✔
183
    context.pushDeclarator(std::make_unique<Declarator>(context.popDirectDeclarator()));
1,208 ✔
184
}
1,208 ✔
185

186
void parameterDeclaration(AbstractSyntaxTreeBuilderContext& context) {
168 ✔
187
    context.pushFormalArgument(FormalArgument { context.popDeclarationSpecifiers(), context.popDeclarator() });
168 ✔
188
}
168 ✔
189

190
void abstractParameterDeclaration(AbstractSyntaxTreeBuilderContext& context) {
×
191
    throw std::runtime_error { "abstractParameterDeclaration is not implemented yet" };
×
192
    //context.pushFormalArgument(std::make_unique<FormalArgument>(context.popDeclarationSpecifiers(), context.popAbstractDeclarator()));
193
}
194

195
void parameterBaseTypeDeclaration(AbstractSyntaxTreeBuilderContext& context) {
2 ✔
196
    context.pushFormalArgument(FormalArgument { context.popDeclarationSpecifiers() });
2 ✔
197
}
2 ✔
198

199
void formalArguments(AbstractSyntaxTreeBuilderContext& context) {
70 ✔
200
    FormalArguments formalArguments;
70 ✔
201
    formalArguments.push_back(context.popFormalArgument());
70 ✔
202
    context.pushFormalArguments(std::move(formalArguments));
70 ✔
203
}
70 ✔
204

205
void addFormalArgument(AbstractSyntaxTreeBuilderContext& context) {
100 ✔
206
    context.popTerminal();
100 ✔
207
    auto formalArguments = context.popFormalArguments();
100 ✔
208
    formalArguments.push_back(context.popFormalArgument());
100 ✔
209
    context.pushFormalArguments(std::move(formalArguments));
100 ✔
210
}
100 ✔
211

212
void formalArgumentsDeclaration(AbstractSyntaxTreeBuilderContext& context) {
70 ✔
213
    context.pushArgumentsDeclaration(std::make_pair(context.popFormalArguments(), false));
70 ✔
214
}
70 ✔
215

216
void formalArgumentsWithVararg(AbstractSyntaxTreeBuilderContext& context) {
×
217
    context.popTerminal();
×
218
    context.popTerminal();
×
219
    //context.pushArgumentsDeclaration(std::make_pair(context.popFormalArguments(), true));
220
    throw std::runtime_error { "formalArgumentsWithVararg is not implemented yet" };
×
221
}
222

223
void integerConstant(AbstractSyntaxTreeBuilderContext& context) {
1,246 ✔
224
    auto constant = context.popTerminal();
1,246 ✔
225
    context.pushConstant( { constant.value, type::signedInteger(), constant.context });
1,246 ✔
226
}
1,246 ✔
227

228
void characterConstant(AbstractSyntaxTreeBuilderContext& context) {
14 ✔
229
    auto constant = context.popTerminal();
14 ✔
230
    context.pushConstant( { constant.value, type::signedCharacter(), constant.context });
14 ✔
231
}
14 ✔
232

233
void floatConstant(AbstractSyntaxTreeBuilderContext& context) {
×
234
    auto constant = context.popTerminal();
×
235
    throw std::runtime_error { "floating constants not implemented yet" };
×
236
    // context.pushConstant( { constant.value, type::floating(), constant.context });
237
}
×
238

239
void enumerationConstant(AbstractSyntaxTreeBuilderContext& context) {
×
240
    auto constant = context.popTerminal();
×
241
    throw std::runtime_error { "enumerationConstant is not implemented yet" };
×
242
}
×
243

244
void identifierExpression(AbstractSyntaxTreeBuilderContext& context) {
2,706 ✔
245
    auto identifier = context.popTerminal();
2,706 ✔
246
    context.pushExpression(std::make_unique<IdentifierExpression>(identifier.value, identifier.context));
2,706 ✔
247
}
2,706 ✔
248

249
void constantExpression(AbstractSyntaxTreeBuilderContext& context) {
1,260 ✔
250
    context.pushExpression(std::make_unique<ConstantExpression>(context.popConstant()));
1,260 ✔
251
}
1,260 ✔
252

253
void stringLiteralExpression(AbstractSyntaxTreeBuilderContext& context) {
802 ✔
254
    auto literal = context.popTerminal();
802 ✔
255
    context.pushExpression(std::make_unique<StringLiteralExpression>(literal.value, literal.context));
802 ✔
256
}
802 ✔
257

258
void arrayAccess(AbstractSyntaxTreeBuilderContext& context) {
×
259
    context.popTerminal(); // ]
×
260
    context.popTerminal(); // [
×
261
    auto subscriptExpression = context.popExpression();
×
262
    auto postfixExpression = context.popExpression();
×
263
    context.pushExpression(std::make_unique<ArrayAccess>(std::move(postfixExpression), std::move(subscriptExpression)));
×
264
}
×
265

266
void functionCall(AbstractSyntaxTreeBuilderContext& context) {
888 ✔
267
    context.popTerminal(); // )
888 ✔
268
    context.popTerminal(); // (
888 ✔
269
    context.pushExpression(std::make_unique<FunctionCall>(context.popExpression(), context.popActualArgumentsList()));
888 ✔
270
}
888 ✔
271

272
void noargFunctionCall(AbstractSyntaxTreeBuilderContext& context) {
24 ✔
273
    context.popTerminal(); // )
24 ✔
274
    context.popTerminal(); // (
24 ✔
275
    context.pushExpression(std::make_unique<FunctionCall>(context.popExpression()));
24 ✔
276
}
24 ✔
277

278
void directMemberAccess(AbstractSyntaxTreeBuilderContext& context) {
20 ✔
279
    auto member = context.popTerminal();
20 ✔
280
    context.popTerminal();
20 ✔
281
    auto base = context.popExpression();
20 ✔
282
    context.pushExpression(std::make_unique<MemberAccess>(std::move(base), member.value, false, member.context));
20 ✔
283
}
20 ✔
284

285
void pointeeMemberAccess(AbstractSyntaxTreeBuilderContext& context) {
4 ✔
286
    auto member = context.popTerminal();
4 ✔
287
    context.popTerminal();
4 ✔
288
    auto base = context.popExpression();
4 ✔
289
    context.pushExpression(std::make_unique<MemberAccess>(std::move(base), member.value, true, member.context));
4 ✔
290
}
4 ✔
291

292
void postfixIncrementDecrement(AbstractSyntaxTreeBuilderContext& context) {
24 ✔
293
    context.pushExpression(std::make_unique<PostfixExpression>(context.popExpression(), std::make_unique<Operator>(context.popTerminal().type)));
24 ✔
294
}
24 ✔
295

296
void prefixIncrementDecrement(AbstractSyntaxTreeBuilderContext& context) {
28 ✔
297
    context.pushExpression(std::make_unique<PrefixExpression>(std::make_unique<Operator>(context.popTerminal().value), context.popExpression()));
28 ✔
298
}
28 ✔
299

300
void unaryExpression(AbstractSyntaxTreeBuilderContext& context) {
538 ✔
301
    context.pushExpression(std::make_unique<UnaryExpression>(std::make_unique<Operator>(context.popTerminal().value), context.popExpression()));
538 ✔
302
}
538 ✔
303

304
void sizeofExpression(AbstractSyntaxTreeBuilderContext& context) {
×
305
    throw std::runtime_error { "sizeofExpression is not implemented yet" };
×
306
}
307

308
void sizeofTypeExpression(AbstractSyntaxTreeBuilderContext& context) {
×
309
    throw std::runtime_error { "sizeofTypeExpression is not implemented yet" };
×
310
}
311

312
void typeCast(AbstractSyntaxTreeBuilderContext& context) {
×
313
    context.popTerminal(); // )
×
314
    //context.pushExpression(std::make_unique<TypeCast>(context.popTypeName(), context.popExpression()));
315
    context.popTerminal(); // (
×
316
    throw std::runtime_error { "typeCast is not implemented yet" };
×
317
}
318

319
void arithmeticExpression(AbstractSyntaxTreeBuilderContext& context) {
114 ✔
320
    auto rightHandSide = context.popExpression();
114 ✔
321
    auto leftHandSide = context.popExpression();
114 ✔
322
    auto arithmeticOperator = std::make_unique<Operator>(context.popTerminal().value);
114 ✔
323
    context.pushExpression(std::make_unique<ArithmeticExpression>(std::move(leftHandSide), std::move(arithmeticOperator), std::move(rightHandSide)));
114 ✔
324
}
114 ✔
325

326
void shiftExpression(AbstractSyntaxTreeBuilderContext& context) {
20 ✔
327
    auto additionExpression = context.popExpression();
20 ✔
328
    auto shiftExpression = context.popExpression();
20 ✔
329
    auto shiftOperator = std::make_unique<Operator>(context.popTerminal().value);
20 ✔
330
    context.pushExpression(std::make_unique<ShiftExpression>(std::move(shiftExpression), std::move(shiftOperator), std::move(additionExpression)));
20 ✔
331
}
20 ✔
332

333
void relationalExpression(AbstractSyntaxTreeBuilderContext& context) {
180 ✔
334
    auto rightHandSide = context.popExpression();
180 ✔
335
    auto leftHandSide = context.popExpression();
180 ✔
336
    auto comparisonOperator = std::make_unique<Operator>(context.popTerminal().value);
180 ✔
337
    context.pushExpression(std::make_unique<ComparisonExpression>(std::move(leftHandSide), std::move(comparisonOperator), std::move(rightHandSide)));
180 ✔
338
}
180 ✔
339

340
void bitwiseExpression(AbstractSyntaxTreeBuilderContext& context) {
16 ✔
341
    auto rightHandSide = context.popExpression();
16 ✔
342
    auto leftHandSide = context.popExpression();
16 ✔
343
    auto bitwiseOperator = std::make_unique<Operator>(context.popTerminal().value);
16 ✔
344
    context.pushExpression(std::make_unique<BitwiseExpression>(std::move(leftHandSide), std::move(bitwiseOperator), std::move(rightHandSide)));
16 ✔
345
}
16 ✔
346

347
void logicalAndExpression(AbstractSyntaxTreeBuilderContext& context) {
12 ✔
348
    context.popTerminal();
12 ✔
349
    auto rightHandSide = context.popExpression();
12 ✔
350
    auto leftHandSide = context.popExpression();
12 ✔
351
    context.pushExpression(std::make_unique<LogicalAndExpression>(std::move(leftHandSide), std::move(rightHandSide)));
12 ✔
352
}
12 ✔
353

354
void logicalOrExpression(AbstractSyntaxTreeBuilderContext& context) {
12 ✔
355
    context.popTerminal();
12 ✔
356
    auto rightHandSide = context.popExpression();
12 ✔
357
    auto leftHandSide = context.popExpression();
12 ✔
358
    context.pushExpression(std::make_unique<LogicalOrExpression>(std::move(leftHandSide), std::move(rightHandSide)));
12 ✔
359
}
12 ✔
360

361
void conditionalExpression(AbstractSyntaxTreeBuilderContext& context) {
×
362
    throw std::runtime_error { "conditionalExpression is not implemented yet" };
×
363
}
364

365
void assignmentExpression(AbstractSyntaxTreeBuilderContext& context) {
472 ✔
366
    auto rightHandSide = context.popExpression();
472 ✔
367
    auto leftHandSide = context.popExpression();
472 ✔
368
    auto assignmentOperator = std::make_unique<Operator>(context.popTerminal().value);
472 ✔
369
    context.pushExpression(
472 ✔
370
            std::make_unique<AssignmentExpression>(std::move(leftHandSide), std::move(assignmentOperator), std::move(rightHandSide)));
944 ✔
371
}
472 ✔
372

373
void initializer(AbstractSyntaxTreeBuilderContext& context) {
×
374
    throw std::runtime_error { "initializer is not implemented yet" };
×
375
}
376

377
void initializedDeclarator(AbstractSyntaxTreeBuilderContext& context) {
554 ✔
378
    auto declarator = context.popDeclarator();
554 ✔
379
    context.pushInitializedDeclarator(std::make_unique<InitializedDeclarator>(std::move(declarator)));
554 ✔
380
}
554 ✔
381

382
void initializedDeclaratorWithInitializer(AbstractSyntaxTreeBuilderContext& context) {
66 ✔
383
    auto declarator = context.popDeclarator();
66 ✔
384
    auto initializerExpression = context.popExpression();
66 ✔
385
    context.pushInitializedDeclarator(std::make_unique<InitializedDeclarator>(std::move(declarator), std::move(initializerExpression)));
66 ✔
386
}
66 ✔
387

388
void initializedDeclaratorList(AbstractSyntaxTreeBuilderContext& context) {
498 ✔
389
    std::vector<std::unique_ptr<InitializedDeclarator>> declarators;
498 ✔
390
    declarators.push_back(context.popInitializedDeclarator());
498 ✔
391
    context.pushInitializedDeclarators(std::move(declarators));
498 ✔
392
}
498 ✔
393

394
void addToInitializedDeclaratorList(AbstractSyntaxTreeBuilderContext& context) {
122 ✔
395
    context.popTerminal();
122 ✔
396
    auto initializedDeclarators = context.popInitializedDeclarators();
122 ✔
397
    initializedDeclarators.push_back(context.popInitializedDeclarator());
122 ✔
398
    context.pushInitializedDeclarators(std::move(initializedDeclarators));
122 ✔
399
}
122 ✔
400

401
void initializedDeclaration(AbstractSyntaxTreeBuilderContext& context) {
498 ✔
402
    context.popTerminal();
498 ✔
403
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
498 ✔
404
    auto initializedDeclarators = context.popInitializedDeclarators();
498 ✔
405
    context.pushDeclaration(std::make_unique<Declaration>(declarationSpecifiers, std::move(initializedDeclarators)));
498 ✔
406
}
498 ✔
407

408
void declaration(AbstractSyntaxTreeBuilderContext& context) {
6 ✔
409
    context.popTerminal();
6 ✔
410
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
6 ✔
411
    context.pushDeclaration(std::make_unique<Declaration>(declarationSpecifiers));
6 ✔
412
}
6 ✔
413

414
void declarationList(AbstractSyntaxTreeBuilderContext& context) {
280 ✔
415
    std::vector<std::unique_ptr<Declaration>> declarations;
280 ✔
416
    declarations.push_back(context.popDeclaration());
280 ✔
417
    context.pushDeclarationList(std::move(declarations));
280 ✔
418
}
280 ✔
419

420
void addDeclarationToList(AbstractSyntaxTreeBuilderContext& context) {
102 ✔
421
    auto declarations = context.popDeclarationList();
102 ✔
422
    declarations.push_back(context.popDeclaration());
102 ✔
423
    context.pushDeclarationList(std::move(declarations));
102 ✔
424
}
102 ✔
425

426
void expressionList(AbstractSyntaxTreeBuilderContext& context) {
2 ✔
427
    context.popTerminal();
2 ✔
428
    auto rightHandSide = context.popExpression();
2 ✔
429
    auto leftHandSide = context.popExpression();
2 ✔
430
    context.pushExpression(std::make_unique<ExpressionList>(std::move(leftHandSide), std::move(rightHandSide)));
2 ✔
431
}
2 ✔
432

433
void pointer(AbstractSyntaxTreeBuilderContext& context) {
68 ✔
434
    context.popTerminal();
68 ✔
435
    context.newPointer(Pointer { });
68 ✔
436
}
68 ✔
437

438
void pointerToPointer(AbstractSyntaxTreeBuilderContext& context) {
×
439
    context.popTerminal();
×
440
    context.pointerToPointer(Pointer { });
×
441
}
×
442

443
void qualifiedPointer(AbstractSyntaxTreeBuilderContext& context) {
×
444
    context.popTerminal();
×
445
    context.newPointer(context.popTypeQualifierList());
×
446
}
×
447

448
void qualifiedPointerToPointer(AbstractSyntaxTreeBuilderContext& context) {
×
449
    context.popTerminal();
×
450
    context.pointerToPointer( { context.popTypeQualifierList() });
×
451
}
×
452

453
void ifStatement(AbstractSyntaxTreeBuilderContext& context) {
20 ✔
454
    context.popTerminal();
20 ✔
455
    context.popTerminal();
20 ✔
456
    context.popTerminal();
20 ✔
457
    context.pushStatement(std::make_unique<IfStatement>(context.popExpression(), context.popStatement()));
20 ✔
458
}
20 ✔
459

460
void ifElseStatement(AbstractSyntaxTreeBuilderContext& context) {
16 ✔
461
    context.popTerminal();
16 ✔
462
    context.popTerminal();
16 ✔
463
    context.popTerminal();
16 ✔
464
    context.popTerminal();
16 ✔
465
    auto falsyStatement = context.popStatement();
16 ✔
466
    auto truthyStatement = context.popStatement();
16 ✔
467
    context.pushStatement(std::make_unique<IfElseStatement>(context.popExpression(), std::move(truthyStatement), std::move(falsyStatement)));
16 ✔
468
}
16 ✔
469

470
void whileLoopStatement(AbstractSyntaxTreeBuilderContext& context) {
20 ✔
471
    context.popTerminal();
20 ✔
472
    context.popTerminal();
20 ✔
473
    context.popTerminal();
20 ✔
474
    auto loopHeader = std::make_unique<WhileLoopHeader>(context.popExpression());
20 ✔
475
    auto body = context.popStatement();
20 ✔
476
    context.pushStatement(std::make_unique<LoopStatement>(std::move(loopHeader), std::move(body)));
20 ✔
477
}
20 ✔
478

479
void statementList(AbstractSyntaxTreeBuilderContext& context) {
574 ✔
480
    context.newStatementList(context.popStatement());
574 ✔
481
}
574 ✔
482

483
void addToStatementList(AbstractSyntaxTreeBuilderContext& context) {
1,314 ✔
484
    context.addToStatementList(context.popStatement());
1,314 ✔
485
}
1,314 ✔
486

487
void returnExpressionStatement(AbstractSyntaxTreeBuilderContext& context) {
456 ✔
488
    context.popTerminal();
456 ✔
489
    context.popTerminal();
456 ✔
490
    context.pushStatement(std::make_unique<ReturnStatement>(context.popExpression()));
456 ✔
491
}
456 ✔
492

493
void returnVoidStatement(AbstractSyntaxTreeBuilderContext& context) {
22 ✔
494
    context.popTerminal();
22 ✔
495
    context.popTerminal();
22 ✔
496
    context.pushStatement(std::make_unique<VoidReturnStatement>());
22 ✔
497
}
22 ✔
498

499
void createActualArgumentsList(AbstractSyntaxTreeBuilderContext& context) {
888 ✔
500
    context.newActualArgumentsList(context.popExpression());
888 ✔
501
}
888 ✔
502

503
void addToActualArgumentsList(AbstractSyntaxTreeBuilderContext& context) {
1,094 ✔
504
    context.popTerminal();
1,094 ✔
505
    context.addToActualArgumentsList(context.popExpression());
1,094 ✔
506
}
1,094 ✔
507

508
void declarationCompound(AbstractSyntaxTreeBuilderContext& context) {
×
509
    context.popTerminal();
×
510
    context.popTerminal();
×
511
    context.pushStatement(std::make_unique<Block>(context.popDeclarationList(), std::vector<std::unique_ptr<AbstractSyntaxTreeNode>> { }));
×
512
}
×
513

514
void statementCompound(AbstractSyntaxTreeBuilderContext& context) {
294 ✔
515
    context.popTerminal();
294 ✔
516
    context.popTerminal();
294 ✔
517
    context.pushStatement(std::make_unique<Block>(std::vector<std::unique_ptr<Declaration>> { }, context.popStatementList()));
294 ✔
518
}
294 ✔
519

520
void fullCompound(AbstractSyntaxTreeBuilderContext& context) {
280 ✔
521
    context.popTerminal();
280 ✔
522
    context.popTerminal();
280 ✔
523
    auto declarations = context.popDeclarationList();
280 ✔
524
    auto statements = context.popStatementList();
280 ✔
525
    context.pushStatement(std::make_unique<Block>(std::move(declarations), std::move(statements)));
280 ✔
526
}
280 ✔
527

528
void emptyCompound(AbstractSyntaxTreeBuilderContext& context) {
12 ✔
529
    context.popTerminal();
12 ✔
530
    context.popTerminal();
12 ✔
531
    context.pushStatement(std::make_unique<Block>(
12 ✔
532
                std::vector<std::unique_ptr<Declaration>> { },
12 ✔
533
                std::vector<std::unique_ptr<AbstractSyntaxTreeNode>>{}));
12 ✔
534
}
12 ✔
535

536
void expressionStatement(AbstractSyntaxTreeBuilderContext& context) {
1,314 ✔
537
    context.popTerminal();
1,314 ✔
538
    context.pushStatement(context.popExpression());
1,314 ✔
539
}
1,314 ✔
540

541
void emptyStatement(AbstractSyntaxTreeBuilderContext& context) {
×
542
    context.popTerminal();
×
543
}
×
544

545
void functionDefinition(AbstractSyntaxTreeBuilderContext& context) {
474 ✔
546
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
474 ✔
547
    auto declarator = context.popDeclarator();
474 ✔
548
    auto statement = context.popStatement();
474 ✔
549
    context.pushStatement(std::make_unique<FunctionDefinition>(std::move(declarationSpecifiers), std::move(declarator), std::move(statement)));
474 ✔
550
}
474 ✔
551

552
void defaultReturnTypeFunctionDefinition(AbstractSyntaxTreeBuilderContext& context) {
×
553
    DeclarationSpecifiers defaultReturnTypeSpecifiers { TypeSpecifier { type::signedInteger(), "int" } };
×
554
    context.pushStatement(std::make_unique<FunctionDefinition>(defaultReturnTypeSpecifiers, context.popDeclarator(), context.popStatement()));
×
555
}
×
556

557
void externalFunctionDefinition(AbstractSyntaxTreeBuilderContext& context) {
474 ✔
558
    context.pushExternalDeclaration(context.popStatement());
474 ✔
559
}
474 ✔
560

561
void externalDeclaration(AbstractSyntaxTreeBuilderContext& context) {
122 ✔
562
    context.pushExternalDeclaration(context.popDeclaration());
122 ✔
563
}
122 ✔
564

565
void translationUnit(AbstractSyntaxTreeBuilderContext& context) {
382 ✔
566
    context.addToTranslationUnit(context.popExternalDeclaration());
382 ✔
567
}
382 ✔
568

569
void addToTranslationUnit(AbstractSyntaxTreeBuilderContext& context) {
214 ✔
570
    context.addToTranslationUnit(context.popExternalDeclaration());
214 ✔
571
}
214 ✔
572

573
ContextualSyntaxNodeBuilder::ContextualSyntaxNodeBuilder(const parser::Grammar& grammar) {
384 ✔
574
    this->grammar = &grammar;
384 ✔
575

576
    int s_type_specifier = grammar.symbolId("<type_spec>");
384 ✔
577
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("short") }] = shortType;
1,536 ✔
578
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("int") }] = integerType;
1,536 ✔
579
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("long") }] = longType;
1,536 ✔
580
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("char") }] = characterType;
1,536 ✔
581
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("void") }] = voidType;
1,536 ✔
582
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("float") }] = floatType;
1,536 ✔
583
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("double") }] = doubleType;
1,536 ✔
584
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("signed") }] = signedType;
1,536 ✔
585
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("unsigned") }] = unsignedType;
1,536 ✔
586
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("typedef_name") }] = typedefName;
1,536 ✔
587
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("<struct_or_union_spec>") }] = structOrUnionType;
1,536 ✔
588
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("<enum_spec>") }] = enumType;
1,920 ✔
589

590
    int s_type_qualifier = grammar.symbolId("<type_qualifier>");
384 ✔
591
    nodeCreatorRegistry[s_type_qualifier][{ grammar.symbolId("const") }] = constQualifier;
1,536 ✔
592
    nodeCreatorRegistry[s_type_qualifier][{ grammar.symbolId("volatile") }] = volatileQualifier;
1,920 ✔
593

594
    int s_decl_specs = grammar.symbolId("<decl_specs>");
384 ✔
595
    nodeCreatorRegistry[s_decl_specs][{ s_type_specifier }] = declarationTypeSpecifier;
768 ✔
596
    nodeCreatorRegistry[s_decl_specs][{ s_type_specifier, s_decl_specs }] = addDeclarationTypeSpecifier;
768 ✔
597
    nodeCreatorRegistry[s_decl_specs][{ grammar.symbolId("<storage_class_spec>") }] = declarationStorageClassSpecifier;
1,536 ✔
598
    nodeCreatorRegistry[s_decl_specs][{ grammar.symbolId("<storage_class_spec>"), s_decl_specs }] = addDeclarationStorageClassSpecifier;
1,536 ✔
599
    nodeCreatorRegistry[s_decl_specs][{ s_type_qualifier }] = declarationTypeQualifier;
768 ✔
600
    nodeCreatorRegistry[s_decl_specs][{ s_type_qualifier, s_decl_specs }] = addDeclarationTypeQualifier;
1,152 ✔
601

602
    int s_direct_declarator = grammar.symbolId("<direct_declarator>");
768 ✔
603
    int s_declarator = grammar.symbolId("<declarator>");
768 ✔
604
    int s_param_type_list = grammar.symbolId("<param_type_list>");
768 ✔
605
    int s_identifier = grammar.symbolId("id");
768 ✔
606
    int s_open_paren = grammar.symbolId("(");
768 ✔
607
    int s_close_paren = grammar.symbolId(")");
768 ✔
608
    int s_open_bracket = grammar.symbolId("[");
768 ✔
609
    int s_close_bracket = grammar.symbolId("]");
384 ✔
610

611
    nodeCreatorRegistry[s_direct_declarator][{ s_identifier }] = identifierDeclarator;
768 ✔
612
    nodeCreatorRegistry[s_direct_declarator][{ s_open_paren, s_declarator, s_close_paren }] = parenthesizedExpression;
768 ✔
613
    nodeCreatorRegistry[s_direct_declarator][{ s_direct_declarator, s_open_bracket, grammar.symbolId("<const_exp>"), s_close_bracket }] = arrayDeclarator;
1,536 ✔
614
    nodeCreatorRegistry[s_direct_declarator][{ s_direct_declarator, s_open_bracket, s_close_bracket }] = abstractArrayDeclarator;
768 ✔
615
    nodeCreatorRegistry[s_direct_declarator][{ s_direct_declarator, s_open_paren, s_param_type_list, s_close_paren }] = functionDeclarator;
768 ✔
616
    nodeCreatorRegistry[s_direct_declarator][{ s_direct_declarator, s_open_paren, s_close_paren }] = noargFunctionDeclarator;
1,152 ✔
617

618
    int s_pointer = grammar.symbolId("<pointer>" );
384 ✔
619
    nodeCreatorRegistry[s_declarator][{ s_pointer, s_direct_declarator }] = pointerToDeclarator;
768 ✔
620
    nodeCreatorRegistry[s_declarator][{ s_direct_declarator }] = declarator;
1,152 ✔
621

622
    int s_param_decl = grammar.symbolId("<param_decl>");
384 ✔
623
    nodeCreatorRegistry[s_param_decl][{ s_decl_specs, s_declarator }] = parameterDeclaration;
768 ✔
624
    nodeCreatorRegistry[s_param_decl][{ s_decl_specs, grammar.symbolId("<abstract_declarator>") }] = abstractParameterDeclaration;
1,536 ✔
625
    nodeCreatorRegistry[s_param_decl][{ s_decl_specs }] = parameterBaseTypeDeclaration;
1,152 ✔
626

627
    int s_param_list = grammar.symbolId("<param_list>");
768 ✔
628
    int s_comma = grammar.symbolId(",");
384 ✔
629
    nodeCreatorRegistry[s_param_list][{ s_param_decl }] = formalArguments;
768 ✔
630
    nodeCreatorRegistry[s_param_list][{ s_param_list, s_comma, s_param_decl }] = addFormalArgument;
768 ✔
631

632
    nodeCreatorRegistry[s_param_type_list][{ s_param_list }] = formalArgumentsDeclaration;
768 ✔
633
    nodeCreatorRegistry[s_param_type_list][{ s_param_list, s_comma, grammar.symbolId("...") }] = formalArgumentsWithVararg;
1,920 ✔
634

635
    int s_constant = grammar.symbolId("<const>");
384 ✔
636
    nodeCreatorRegistry[s_constant][{ grammar.symbolId("int_const") }] = integerConstant;
1,536 ✔
637
    nodeCreatorRegistry[s_constant][{ grammar.symbolId("char_const") }] = characterConstant;
1,536 ✔
638
    nodeCreatorRegistry[s_constant][{ grammar.symbolId("float_const") }] = floatConstant;
1,536 ✔
639
    nodeCreatorRegistry[s_constant][{ grammar.symbolId("enumeration_const") }] = enumerationConstant;
1,920 ✔
640

641
    int s_exp = grammar.symbolId("<exp>");
768 ✔
642
    int s_primary_exp = grammar.symbolId("<primary_exp>");
384 ✔
643
    nodeCreatorRegistry[s_primary_exp][{ s_identifier }] = identifierExpression;
768 ✔
644
    nodeCreatorRegistry[s_primary_exp][{ s_constant }] = constantExpression;
768 ✔
645
    nodeCreatorRegistry[s_primary_exp][{ grammar.symbolId("string") }] = stringLiteralExpression;
1,536 ✔
646
    nodeCreatorRegistry[s_primary_exp][{ s_open_paren, s_exp, s_close_paren }] = parenthesizedExpression;
1,152 ✔
647

648
    int s_argument_exp_list = grammar.symbolId("<argument_exp_list>");
768 ✔
649
    int s_postfix_exp = grammar.symbolId("<postfix_exp>");
384 ✔
650
    nodeCreatorRegistry[s_postfix_exp][{ s_primary_exp }] = doNothing;
768 ✔
651
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, s_open_bracket, s_exp, s_close_bracket }] = arrayAccess;
768 ✔
652
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, s_open_paren, s_argument_exp_list, s_close_paren }] = functionCall;
768 ✔
653
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, s_open_paren, s_close_paren }] = noargFunctionCall;
768 ✔
654
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, grammar.symbolId("."), s_identifier }] = directMemberAccess;
1,536 ✔
655
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, grammar.symbolId("->"), s_identifier }] = pointeeMemberAccess;
1,536 ✔
656
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, grammar.symbolId("++") }] = postfixIncrementDecrement;
1,536 ✔
657
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, grammar.symbolId("--") }] = postfixIncrementDecrement;
1,920 ✔
658

659
    int s_cast_exp = grammar.symbolId("<cast_exp>");
768 ✔
660
    int s_unary_exp = grammar.symbolId("<unary_exp>");
768 ✔
661
    int s_unary_operator = grammar.symbolId("<unary_operator>");
384 ✔
662
    nodeCreatorRegistry[s_unary_exp][{ s_postfix_exp }] = doNothing;
768 ✔
663
    nodeCreatorRegistry[s_unary_exp][{ grammar.symbolId("++"), s_unary_exp }] = prefixIncrementDecrement;
1,536 ✔
664
    nodeCreatorRegistry[s_unary_exp][{ grammar.symbolId("--"), s_unary_exp }] = prefixIncrementDecrement;
1,536 ✔
665
    nodeCreatorRegistry[s_unary_exp][{ s_unary_operator, s_cast_exp }] = unaryExpression;
768 ✔
666
    nodeCreatorRegistry[s_unary_exp][{ grammar.symbolId("sizeof"), s_unary_exp }] = sizeofExpression;
1,536 ✔
667
    nodeCreatorRegistry[s_unary_exp][{ grammar.symbolId("sizeof"), s_open_paren, grammar.symbolId("<type_name>"), s_close_paren }] = sizeofTypeExpression;
2,304 ✔
668

669
    nodeCreatorRegistry[s_cast_exp][{ s_unary_exp }] = doNothing;
768 ✔
670
    nodeCreatorRegistry[s_cast_exp][{ s_open_paren, grammar.symbolId("<type_name>"), s_close_paren, s_cast_exp }] = typeCast;
1,920 ✔
671

672
    int s_mult_exp = grammar.symbolId("<mult_exp>");
384 ✔
673
    nodeCreatorRegistry[s_mult_exp][{ s_cast_exp }] = doNothing;
768 ✔
674
    nodeCreatorRegistry[s_mult_exp][{ s_mult_exp, grammar.symbolId("*"), s_cast_exp }] = arithmeticExpression;
1,536 ✔
675
    nodeCreatorRegistry[s_mult_exp][{ s_mult_exp, grammar.symbolId("/"), s_cast_exp }] = arithmeticExpression;
1,536 ✔
676
    nodeCreatorRegistry[s_mult_exp][{ s_mult_exp, grammar.symbolId("%"), s_cast_exp }] = arithmeticExpression;
1,920 ✔
677

678
    int s_additive_exp = grammar.symbolId("<additive_exp>");
384 ✔
679
    nodeCreatorRegistry[s_additive_exp][{ s_mult_exp }] = doNothing;
768 ✔
680
    nodeCreatorRegistry[s_additive_exp][{ s_additive_exp, grammar.symbolId("+"), s_mult_exp }] = arithmeticExpression;
1,536 ✔
681
    nodeCreatorRegistry[s_additive_exp][{ s_additive_exp, grammar.symbolId("-"), s_mult_exp }] = arithmeticExpression;
1,920 ✔
682

683
    int s_shift_exp = grammar.symbolId("<shift_expression>");
384 ✔
684
    nodeCreatorRegistry[s_shift_exp][{ s_additive_exp }] = doNothing;
768 ✔
685
    nodeCreatorRegistry[s_shift_exp][{ s_shift_exp, grammar.symbolId("<<"), s_additive_exp }] = shiftExpression;
1,536 ✔
686
    nodeCreatorRegistry[s_shift_exp][{ s_shift_exp, grammar.symbolId(">>"), s_additive_exp }] = shiftExpression;
1,920 ✔
687

688
    int s_relational_exp = grammar.symbolId("<relational_exp>");
384 ✔
689
    nodeCreatorRegistry[s_relational_exp][{ s_shift_exp }] = doNothing;
768 ✔
690
    nodeCreatorRegistry[s_relational_exp][{ s_relational_exp, grammar.symbolId("<"), s_shift_exp }] = relationalExpression;
1,536 ✔
691
    nodeCreatorRegistry[s_relational_exp][{ s_relational_exp, grammar.symbolId(">"), s_shift_exp }] = relationalExpression;
1,536 ✔
692
    nodeCreatorRegistry[s_relational_exp][{ s_relational_exp, grammar.symbolId("<="), s_shift_exp }] = relationalExpression;
1,536 ✔
693
    nodeCreatorRegistry[s_relational_exp][{ s_relational_exp, grammar.symbolId(">="), s_shift_exp }] = relationalExpression;
1,920 ✔
694

695
    int s_equality_exp = grammar.symbolId("<equality_exp>");
384 ✔
696
    nodeCreatorRegistry[s_equality_exp][{ s_relational_exp }] = doNothing;
768 ✔
697
    nodeCreatorRegistry[s_equality_exp][{ s_equality_exp, grammar.symbolId("=="), s_relational_exp }] = relationalExpression;
1,536 ✔
698
    nodeCreatorRegistry[s_equality_exp][{ s_equality_exp, grammar.symbolId("!="), s_relational_exp }] = relationalExpression;
1,920 ✔
699

700
    int s_and_exp = grammar.symbolId("<and_exp>");
384 ✔
701
    nodeCreatorRegistry[s_and_exp][{ s_equality_exp }] = doNothing;
768 ✔
702
    nodeCreatorRegistry[s_and_exp][{ s_and_exp, grammar.symbolId("&"), s_equality_exp }] = bitwiseExpression;
1,920 ✔
703

704
    int s_exclusive_or_exp = grammar.symbolId("<exclusive_or_exp>");
384 ✔
705
    nodeCreatorRegistry[s_exclusive_or_exp][{ s_and_exp }] = doNothing;
768 ✔
706
    nodeCreatorRegistry[s_exclusive_or_exp][{ s_exclusive_or_exp, grammar.symbolId("^"), s_and_exp }] = bitwiseExpression;
1,920 ✔
707

708
    int s_inclusive_or_exp = grammar.symbolId("<inclusive_or_exp>");
384 ✔
709
    nodeCreatorRegistry[s_inclusive_or_exp][{ s_exclusive_or_exp }] = doNothing;
768 ✔
710
    nodeCreatorRegistry[s_inclusive_or_exp][{ s_inclusive_or_exp, grammar.symbolId("|"), s_exclusive_or_exp }] = bitwiseExpression;
1,920 ✔
711

712
    int s_logical_and_exp = grammar.symbolId("<logical_and_exp>");
384 ✔
713
    nodeCreatorRegistry[s_logical_and_exp][{ s_inclusive_or_exp }] = doNothing;
768 ✔
714
    nodeCreatorRegistry[s_logical_and_exp][{ s_logical_and_exp, grammar.symbolId("&&"), s_inclusive_or_exp }] = logicalAndExpression;
1,920 ✔
715

716
    int s_logical_or_exp = grammar.symbolId("<logical_or_exp>");
384 ✔
717
    nodeCreatorRegistry[s_logical_or_exp][{ s_logical_and_exp }] = doNothing;
768 ✔
718
    nodeCreatorRegistry[s_logical_or_exp][{ s_logical_or_exp, grammar.symbolId("||"), s_logical_and_exp }] = logicalOrExpression;
1,920 ✔
719

720
    int s_conditional_exp = grammar.symbolId("<conditional_exp>");
384 ✔
721
    nodeCreatorRegistry[s_conditional_exp][{ s_logical_or_exp }] = doNothing;
768 ✔
722
    nodeCreatorRegistry[s_conditional_exp][{ s_logical_or_exp, grammar.symbolId("?"), s_exp, grammar.symbolId(":"), s_conditional_exp }] = conditionalExpression;
2,688 ✔
723

724
    int s_assignment = grammar.symbolId("<assignment_exp>");
768 ✔
725
    int s_assignment_operator = grammar.symbolId("<assignment_operator>");
384 ✔
726
    nodeCreatorRegistry[s_assignment][{ s_conditional_exp }] = doNothing;
768 ✔
727
    nodeCreatorRegistry[s_assignment][{ s_unary_exp, s_assignment_operator, s_assignment }] = assignmentExpression;
1,152 ✔
728

729
    int s_initializer = grammar.symbolId("<initializer>");
768 ✔
730
    int s_open_brace = grammar.symbolId("{");
768 ✔
731
    int s_close_brace = grammar.symbolId("}");
384 ✔
732
    nodeCreatorRegistry[s_initializer][{ s_assignment }] = doNothing;
768 ✔
733
    nodeCreatorRegistry[s_initializer][{ s_open_brace, grammar.symbolId("<initializer_list>"), s_close_brace }] = initializer;
1,920 ✔
734

735
    int s_init_declarator = grammar.symbolId("<init_declarator>");
384 ✔
736
    nodeCreatorRegistry[s_init_declarator][{ s_declarator }] = initializedDeclarator;
768 ✔
737
    nodeCreatorRegistry[s_init_declarator][{ s_declarator, grammar.symbolId("="), s_initializer }] = initializedDeclaratorWithInitializer;
1,920 ✔
738

739
    int s_init_declarator_list = grammar.symbolId("<init_declarator_list>");
384 ✔
740
    nodeCreatorRegistry[s_init_declarator_list][{ s_init_declarator }] = initializedDeclaratorList;
768 ✔
741
    nodeCreatorRegistry[s_init_declarator_list][{ s_init_declarator_list, s_comma, s_init_declarator }] = addToInitializedDeclaratorList;
1,152 ✔
742

743
    int s_decl = grammar.symbolId("<decl>");
768 ✔
744
    int s_semicolon = grammar.symbolId(";");
384 ✔
745
    nodeCreatorRegistry[s_decl][{ s_decl_specs, s_init_declarator_list, s_semicolon }] = initializedDeclaration;
768 ✔
746
    nodeCreatorRegistry[s_decl][{ s_decl_specs, s_semicolon }] = declaration;
1,152 ✔
747

748
    int s_decl_list = grammar.symbolId("<decl_list>");
384 ✔
749
    nodeCreatorRegistry[s_decl_list][{ s_decl }] = declarationList;
768 ✔
750
    nodeCreatorRegistry[s_decl_list][{ s_decl_list, s_decl }] = addDeclarationToList;
768 ✔
751

752
    nodeCreatorRegistry[s_exp][{ s_assignment }] = doNothing;
768 ✔
753
    nodeCreatorRegistry[s_exp][{ s_exp, s_comma, s_assignment }] = expressionList;
1,152 ✔
754

755
    int s_type_qualifier_list = grammar.symbolId("<type_qualifier_list>");
384 ✔
756
    nodeCreatorRegistry[s_type_qualifier_list][{ s_type_qualifier }] = typeQualifierList;
768 ✔
757
    nodeCreatorRegistry[s_type_qualifier_list][{ s_type_qualifier_list, s_type_qualifier }] = addTypeQualifierToList;
768 ✔
758

759
    nodeCreatorRegistry[s_pointer][{ grammar.symbolId("*"), s_type_qualifier_list }] = qualifiedPointer;
1,536 ✔
760
    nodeCreatorRegistry[s_pointer][{ grammar.symbolId("*") }] = pointer;
1,536 ✔
761
    nodeCreatorRegistry[s_pointer][{ grammar.symbolId("*"), s_type_qualifier_list, s_pointer }] = qualifiedPointerToPointer;
1,536 ✔
762
    nodeCreatorRegistry[s_pointer][{ grammar.symbolId("*"), s_pointer }] = pointerToPointer;
1,536 ✔
763

764
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("&") }] = doNothing;
1,536 ✔
765
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("*") }] = doNothing;
1,536 ✔
766
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("+") }] = doNothing;
1,536 ✔
767
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("-") }] = doNothing;
1,536 ✔
768
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("~") }] = doNothing;
1,536 ✔
769
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("!") }] = doNothing;
1,536 ✔
770

771
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("=") }] = doNothing;
1,536 ✔
772
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("*=") }] = doNothing;
1,536 ✔
773
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("/=") }] = doNothing;
1,536 ✔
774
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("%=") }] = doNothing;
1,536 ✔
775
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("+=") }] = doNothing;
1,536 ✔
776
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("-=") }] = doNothing;
1,536 ✔
777
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("<<=") }] = doNothing;
1,536 ✔
778
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId(">>=") }] = doNothing;
1,536 ✔
779
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("&=") }] = doNothing;
1,536 ✔
780
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("^=") }] = doNothing;
1,536 ✔
781
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("|=") }] = doNothing;
1,920 ✔
782

783
    int s_exp_stat = grammar.symbolId("<exp_stat>");
384 ✔
784
    nodeCreatorRegistry[s_exp_stat][{ s_exp, s_semicolon }] = expressionStatement;
768 ✔
785
    nodeCreatorRegistry[s_exp_stat][{ s_semicolon }] = emptyStatement;
1,152 ✔
786

787
    int s_matched = grammar.symbolId("<matched>");
768 ✔
788
    int s_unmatched = grammar.symbolId("<unmatched>");
768 ✔
789
    int s_stat = grammar.symbolId("<stat>");
768 ✔
790
    int s_compound_stat = grammar.symbolId("<compound_stat>");
768 ✔
791
    int s_jump_stat = grammar.symbolId("<jump_stat>");
768 ✔
792
    int s_if = grammar.symbolId("if");
384 ✔
793
    nodeCreatorRegistry[s_matched][{s_if, s_open_paren, s_exp, s_close_paren, s_matched, grammar.symbolId("else"), s_matched }] = ifElseStatement;
1,536 ✔
794
    nodeCreatorRegistry[s_unmatched][{s_if, s_open_paren, s_exp, s_close_paren, s_stat }] = ifStatement;
768 ✔
795
    //nodeCreatorRegistry[s_matched][{ grammar.symbolId("switch"), s_open_paren, s_exp, s_close_paren, s_matched }] = switchStatement;
796
    //nodeCreatorRegistry[s_matched][{ grammar.symbolId("<labeled_stat_matched>") }] = labeledStatement; // ??
797
    nodeCreatorRegistry[s_matched][{ s_exp_stat }] = doNothing;
768 ✔
798
    nodeCreatorRegistry[s_matched][{ s_compound_stat }] = doNothing;
768 ✔
799
    nodeCreatorRegistry[s_matched][{ s_jump_stat }] = doNothing;
768 ✔
800

801
    nodeCreatorRegistry[s_stat][{ s_matched }] = doNothing;
768 ✔
802
    nodeCreatorRegistry[s_stat][{ s_unmatched }] = doNothing;
1,152 ✔
803

804
    int s_stat_list = grammar.symbolId("<stat_list>");
384 ✔
805
    nodeCreatorRegistry[s_stat_list][{ s_stat }] = statementList;
768 ✔
806
    nodeCreatorRegistry[s_stat_list][{ s_stat_list, s_stat }] = addToStatementList;
1,152 ✔
807

808
    int s_return = grammar.symbolId("return");
384 ✔
809
    //nodeCreatorRegistry[s_jump][{ grammar.symbolId("goto"), s_identifier, s_semicolon }] = gotoStatement;
810
    //nodeCreatorRegistry[s_jump][{ grammar.symbolId("continue"), s_semicolon }] = continueStatement;
811
    //nodeCreatorRegistry[s_jump][{ grammar.symbolId("break"), s_semicolon }] = breakStatement;
812
    nodeCreatorRegistry[s_jump_stat][{ s_return, s_exp, s_semicolon }] = returnExpressionStatement;
768 ✔
813
    nodeCreatorRegistry[s_jump_stat][{ s_return, s_semicolon }] = returnVoidStatement;
1,152 ✔
814

815

816
    int s_struct_or_union = grammar.symbolId("<struct_or_union>");
768 ✔
817
    int s_struct_or_union_spec = grammar.symbolId("<struct_or_union_spec>");
768 ✔
818
    int s_struct_decl_list = grammar.symbolId("<struct_decl_list>");
768 ✔
819
    int s_struct_decl = grammar.symbolId("<struct_decl>");
768 ✔
820
    int s_struct_declarator_list = grammar.symbolId("<struct_declarator_list>");
768 ✔
821
    int s_struct_declarator = grammar.symbolId("<struct_declarator>");
768 ✔
822
    int s_spec_qualifier_list = grammar.symbolId("<spec_qualifier_list>");
384 ✔
823

824
    nodeCreatorRegistry[s_struct_or_union][{ grammar.symbolId("struct") }] = [](AbstractSyntaxTreeBuilderContext& context) { context.popTerminal(); };
1,550 ✔
825
    nodeCreatorRegistry[s_struct_or_union][{ grammar.symbolId("union") }] = [](AbstractSyntaxTreeBuilderContext& context) {
1,920 ✔
NEW
826
        context.popTerminal();
×
NEW
827
        throw std::runtime_error { "union is not implemented" };
×
828
    };
384 ✔
829

830
    nodeCreatorRegistry[s_struct_or_union_spec][{ s_struct_or_union, s_identifier, grammar.symbolId("{"), s_struct_decl_list, grammar.symbolId("}") }] =
2,688 ✔
NEW
831
        [](AbstractSyntaxTreeBuilderContext& context) {
×
832
            context.popTerminal();
6 ✔
833
            context.popTerminal();
6 ✔
834
            auto tag = context.popTerminal();
6 ✔
835
            auto members = context.popStructMemberList();
6 ✔
836
            auto structType = type::structure(std::move(members));
6 ✔
837
            context.defineStructTag(tag.value, structType);
6 ✔
838
            context.pushTypeSpecifier(TypeSpecifier { structType, tag.value });
6 ✔
839
        };
390 ✔
840
    nodeCreatorRegistry[s_struct_or_union_spec][{ s_struct_or_union, grammar.symbolId("{"), s_struct_decl_list, grammar.symbolId("}") }] =
2,688 ✔
NEW
841
        [](AbstractSyntaxTreeBuilderContext& context) {
×
NEW
842
            context.popTerminal();
×
NEW
843
            context.popTerminal();
×
NEW
844
            auto members = context.popStructMemberList();
×
NEW
845
            context.pushTypeSpecifier(TypeSpecifier { type::structure(std::move(members)), "" });
×
846
        };
384 ✔
847
    nodeCreatorRegistry[s_struct_or_union_spec][{ s_struct_or_union, s_identifier }] =
1,152 ✔
NEW
848
        [](AbstractSyntaxTreeBuilderContext& context) {
×
849
            auto tag = context.popTerminal();
8 ✔
850
            auto found = context.lookupStructTag(tag.value);
8 ✔
851
            if (!found) {
8 ✔
NEW
852
                throw std::runtime_error { "unknown struct type: " + tag.value };
×
853
            }
854
            context.pushTypeSpecifier(TypeSpecifier { *found, tag.value });
8 ✔
855
        };
392 ✔
856

857
    nodeCreatorRegistry[s_spec_qualifier_list][{ s_type_specifier }] = doNothing;
768 ✔
858
    nodeCreatorRegistry[s_spec_qualifier_list][{ s_type_specifier, s_spec_qualifier_list }] = doNothing;
768 ✔
859
    nodeCreatorRegistry[s_spec_qualifier_list][{ s_type_qualifier }] = [](AbstractSyntaxTreeBuilderContext& context) { context.popTypeQualifier(); };
768 ✔
860
    nodeCreatorRegistry[s_spec_qualifier_list][{ s_type_qualifier, s_spec_qualifier_list }] = [](AbstractSyntaxTreeBuilderContext& context) { context.popTypeQualifier(); };
768 ✔
861

862
    nodeCreatorRegistry[s_struct_declarator][{ s_declarator }] = [](AbstractSyntaxTreeBuilderContext& context) {
1,152 ✔
863
        auto declarator = context.popDeclarator();
12 ✔
864
        context.addStructDeclaratorName(declarator->getName());
12 ✔
865
    };
396 ✔
866
    nodeCreatorRegistry[s_struct_declarator_list][{ s_struct_declarator }] = doNothing;
768 ✔
867
    nodeCreatorRegistry[s_struct_declarator_list][{ s_struct_declarator_list, s_comma, s_struct_declarator }] =
1,152 ✔
868
        [](AbstractSyntaxTreeBuilderContext& context) { context.popTerminal(); };
384 ✔
869

870
    nodeCreatorRegistry[s_struct_decl][{ s_spec_qualifier_list, s_struct_declarator_list, s_semicolon }] =
1,152 ✔
NEW
871
        [](AbstractSyntaxTreeBuilderContext& context) {
×
872
            context.popTerminal();
12 ✔
873
            auto names = context.popStructDeclaratorNameList();
12 ✔
874
            auto typeSpec = context.popTypeSpecifier();
12 ✔
875
            auto fieldType = typeSpec.getType();
12 ✔
876
            for (const auto& name : names) {
24 ✔
877
                context.addStructMember(name, fieldType);
12 ✔
878
            }
879
        };
396 ✔
880
    nodeCreatorRegistry[s_struct_decl_list][{ s_struct_decl }] = doNothing;
768 ✔
881
    nodeCreatorRegistry[s_struct_decl_list][{ s_struct_decl_list, s_struct_decl }] = doNothing;
768 ✔
882

883

884
    nodeCreatorRegistry[s_argument_exp_list][{ s_assignment }] = createActualArgumentsList;
768 ✔
885
    nodeCreatorRegistry[s_argument_exp_list][{ s_argument_exp_list, s_comma, s_assignment }] = addToActualArgumentsList;
768 ✔
886

887
    nodeCreatorRegistry[s_compound_stat][{ s_open_brace, s_decl_list, s_stat_list, s_close_brace}] = fullCompound;
768 ✔
888
    nodeCreatorRegistry[s_compound_stat][{ s_open_brace, s_stat_list, s_close_brace}] = statementCompound;
768 ✔
889
    nodeCreatorRegistry[s_compound_stat][{ s_open_brace, s_decl_list, s_close_brace}] = declarationCompound;
768 ✔
890
    nodeCreatorRegistry[s_compound_stat][{ s_open_brace, s_close_brace}] = emptyCompound;
1,152 ✔
891

892
    int s_function_definition = grammar.symbolId("<function_definition>");
384 ✔
893
    nodeCreatorRegistry[s_function_definition][{ s_decl_specs, s_declarator, s_compound_stat }] = functionDefinition;
768 ✔
894
    nodeCreatorRegistry[s_function_definition][{ s_declarator, s_compound_stat }] = defaultReturnTypeFunctionDefinition;
1,152 ✔
895

896
    int s_external_decl = grammar.symbolId("<external_decl>");
384 ✔
897
    nodeCreatorRegistry[s_external_decl][{ s_function_definition }] = externalFunctionDefinition;
768 ✔
898
    nodeCreatorRegistry[s_external_decl][{ s_decl }] = externalDeclaration;
1,152 ✔
899

900
    int s_translation_unit = grammar.symbolId("<translation_unit>");
384 ✔
901
    nodeCreatorRegistry[s_translation_unit][{ s_external_decl }] = translationUnit;
768 ✔
902
    nodeCreatorRegistry[s_translation_unit][{ s_translation_unit, s_external_decl }] = addToTranslationUnit;
1,152 ✔
903

904
    int s_iteration_stat_matched = grammar.symbolId("<iteration_stat_matched>");
768 ✔
905
    int s_iteration_stat_unmatched = grammar.symbolId("<iteration_stat_unmatched>");
384 ✔
906
    nodeCreatorRegistry[s_matched][{ s_iteration_stat_matched }] = doNothing;
768 ✔
907
    nodeCreatorRegistry[s_unmatched][{ s_iteration_stat_unmatched }] = doNothing;
1,152 ✔
908

909
    int s_while = grammar.symbolId("while");
768 ✔
910
    int s_for = grammar.symbolId("for");
384 ✔
911
    nodeCreatorRegistry[s_iteration_stat_matched][{ s_while, s_open_paren, s_exp, s_close_paren, s_matched }] = whileLoopStatement;
768 ✔
912
    nodeCreatorRegistry[s_iteration_stat_unmatched][{ s_while, s_open_paren, s_exp, s_close_paren, s_unmatched }] = whileLoopStatement;
768 ✔
913

914
    auto forLoop = [](bool hasInit, bool hasClause, bool hasIncrement) {
3,072 ✔
915
        return [=](AbstractSyntaxTreeBuilderContext& context) {
30 ✔
916
            for (int i = 0; i < 5; ++i) {
180 ✔
917
                context.popTerminal();  // for ( ; ; ) punctuation
150 ✔
918
            }
919
            auto increment = hasIncrement ? context.popExpression() : nullptr;
30 ✔
920
            auto clause = hasClause ? context.popExpression() : nullptr;
30 ✔
921
            auto initialization = hasInit ? context.popExpression() : nullptr;
30 ✔
922
            auto loopHeader = std::make_unique<ForLoopHeader>(std::move(initialization), std::move(clause), std::move(increment));
30 ✔
923
            auto body = context.popStatement();
30 ✔
924
            context.pushStatement(std::make_unique<LoopStatement>(std::move(loopHeader), std::move(body)));
30 ✔
925
        };
3,102 ✔
926
    };
927
    auto registerFor = [&](const std::vector<int>& prod, std::function<void(AbstractSyntaxTreeBuilderContext&)> creator) {
3,072 ✔
928
        nodeCreatorRegistry[s_iteration_stat_matched][prod] = creator;
3,072 ✔
929
        auto unmatchedProd = prod;
3,072 ✔
930
        unmatchedProd.back() = s_unmatched;
3,072 ✔
931
        nodeCreatorRegistry[s_iteration_stat_unmatched][unmatchedProd] = creator;
3,072 ✔
932
    };
3,072 ✔
933
    registerFor({ s_for, s_open_paren, s_exp, s_semicolon, s_exp, s_semicolon, s_exp, s_close_paren, s_matched }, forLoop(true,  true,  true));
1,152 ✔
934
    registerFor({ s_for, s_open_paren, s_exp, s_semicolon, s_exp, s_semicolon, s_close_paren, s_matched }, forLoop(true,  true,  false));
1,152 ✔
935
    registerFor({ s_for, s_open_paren, s_exp, s_semicolon, s_semicolon, s_exp, s_close_paren, s_matched }, forLoop(true,  false, true));
1,152 ✔
936
    registerFor({ s_for, s_open_paren, s_exp, s_semicolon, s_semicolon, s_close_paren, s_matched }, forLoop(true,  false, false));
1,152 ✔
937
    registerFor({ s_for, s_open_paren, s_semicolon, s_exp, s_semicolon, s_exp, s_close_paren, s_matched }, forLoop(false, true,  true));
1,152 ✔
938
    registerFor({ s_for, s_open_paren, s_semicolon, s_exp, s_semicolon, s_close_paren, s_matched }, forLoop(false, true,  false));
1,152 ✔
939
    registerFor({ s_for, s_open_paren, s_semicolon, s_semicolon, s_exp, s_close_paren, s_matched }, forLoop(false, false, true));
1,152 ✔
940
    registerFor({ s_for, s_open_paren, s_semicolon, s_semicolon, s_close_paren, s_matched }, forLoop(false, false, false));
1,152 ✔
941
}
384 ✔
942

943
ContextualSyntaxNodeBuilder::~ContextualSyntaxNodeBuilder() = default;
384 ✔
944

945
void ContextualSyntaxNodeBuilder::updateContext(const parser::Production& production, AbstractSyntaxTreeBuilderContext& context) const {
94,810 ✔
946
    try {
947
        nodeCreatorRegistry.at(production.getDefiningSymbol()).at(production.producedSequence())(context);
94,810 ✔
UNCOV
948
    } catch (std::out_of_range& exception) {
×
UNCOV
949
        noCreatorDefined(production);
×
950
    }
×
951
}
94,810 ✔
952

UNCOV
953
void ContextualSyntaxNodeBuilder::noCreatorDefined(const parser::Production& production) const {
×
954
    throw std::runtime_error { "no AST creator defined for production `" + grammar->str(production) + "`" };
×
955
}
956

957
void ContextualSyntaxNodeBuilder::loopJumpStatement(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
958
    context.pushStatement(std::make_unique<JumpStatement>(context.popTerminal()));
×
UNCOV
959
    context.popTerminal();
×
UNCOV
960
}
×
961

962
} /* namespace ast */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc