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

rieske / trans / 29858613021

21 Jul 2026 06:45PM UTC coverage: 90.602% (-0.1%) from 90.735%
29858613021

Pull #52

github

rieske
Fuzz test and fix issues
Pull Request #52: Fuzz test and fix issues

54 of 72 new or added lines in 7 files covered. (75.0%)

100 existing lines in 4 files now uncovered.

5312 of 5863 relevant lines covered (90.6%)

365676.6 hits per line

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

80.03
/src/ast/ContextualSyntaxNodeBuilder.cpp
1
#include "ContextualSyntaxNodeBuilder.h"
2

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

6
#include "ArithmeticExpression.h"
7
#include "ArrayAccess.h"
8
#include "ArrayDeclarator.h"
9
#include "AssignmentExpression.h"
10
#include "BitwiseExpression.h"
11
#include "Block.h"
12
#include "ComparisonExpression.h"
13
#include "ConstantExpression.h"
14
#include "ExpressionList.h"
15
#include "ForLoopHeader.h"
16
#include "FunctionCall.h"
17
#include "FunctionDefinition.h"
18
#include "Identifier.h"
19
#include "IdentifierExpression.h"
20
#include "IfElseStatement.h"
21
#include "IfStatement.h"
22
#include "JumpStatement.h"
23
#include "LogicalAndExpression.h"
24
#include "LogicalOrExpression.h"
25
#include "LoopStatement.h"
26
#include "Operator.h"
27
#include "ParenthesizedDeclarator.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&) {
72,736✔
43
}
72,736✔
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,152✔
50
    context.pushTypeSpecifier( { type::signedInteger(), context.popTerminal().value });
1,152✔
51
}
1,152✔
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) {
×
86
    throw std::runtime_error { "structOrUnionType type is not implemented yet" };
×
87
}
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) {
54✔
110
    context.popTerminal();
54✔
111
    context.popTerminal();
54✔
112
}
54✔
113

114
void parenthesizedDeclarator(AbstractSyntaxTreeBuilderContext& context) {
8✔
115
    context.popTerminal();
8✔
116
    context.popTerminal();
8✔
117
    context.pushDirectDeclarator(std::make_unique<ParenthesizedDeclarator>(context.popDeclarator()));
8✔
118
}
8✔
119

120
void declarationTypeSpecifier(AbstractSyntaxTreeBuilderContext& context) {
1,196✔
121
    context.pushDeclarationSpecifiers( { context.popTypeSpecifier() });
1,196✔
122
}
1,196✔
123

124
void addDeclarationTypeSpecifier(AbstractSyntaxTreeBuilderContext& context) {
×
125
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
×
126
    auto typeSpecifier = context.popTypeSpecifier();
×
127
    context.pushDeclarationSpecifiers( { typeSpecifier, declarationSpecifiers });
×
128
}
×
129

130
void declarationStorageClassSpecifier(AbstractSyntaxTreeBuilderContext& context) {
×
131
    context.pushDeclarationSpecifiers( { context.popStorageSpecifier() });
×
132
}
×
133

134
void addDeclarationStorageClassSpecifier(AbstractSyntaxTreeBuilderContext& context) {
×
135
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
×
136
    auto storageSpecifier = context.popStorageSpecifier();
×
137
    context.pushDeclarationSpecifiers( { storageSpecifier, declarationSpecifiers });
×
138
}
×
139

140
void declarationTypeQualifier(AbstractSyntaxTreeBuilderContext& context) {
×
141
    context.pushDeclarationSpecifiers( { context.popTypeQualifier() });
×
142
}
×
143

144
void addDeclarationTypeQualifier(AbstractSyntaxTreeBuilderContext& context) {
×
145
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
×
146
    auto typeQualifier = context.popTypeQualifier();
×
147
    context.pushDeclarationSpecifiers( { typeQualifier, declarationSpecifiers });
×
148
}
×
149

150
void identifierDeclarator(AbstractSyntaxTreeBuilderContext& context) {
1,310✔
151
    context.pushDirectDeclarator(std::make_unique<Identifier>(context.popTerminal()));
1,310✔
152
}
1,310✔
153

154
void arrayDeclarator(AbstractSyntaxTreeBuilderContext& context) {
×
155
    context.popTerminal();
×
156
    context.popTerminal();
×
157
    context.pushDirectDeclarator(std::make_unique<ArrayDeclarator>(context.popDirectDeclarator(), context.popExpression()));
×
158
}
×
159

160
void abstractArrayDeclarator(AbstractSyntaxTreeBuilderContext& context) {
×
161
    context.popTerminal();
×
162
    context.popTerminal();
×
163
    //context.pushDeclarator(std::make_unique<ArrayDeclarator>(context.popDirectDeclarator()));
164
    throw std::runtime_error { "abstract array declarator is not implemented yet" };
×
165
}
166

167
void functionDeclarator(AbstractSyntaxTreeBuilderContext& context) {
74✔
168
    context.popTerminal();
74✔
169
    context.popTerminal();
74✔
170
    auto arguments = context.popArgumentsDeclaration().first;
74✔
171
    // `(void)` is an empty parameter list, not a single void parameter.
172
    if (arguments.size() == 1 && arguments.front().isVoid()) {
74✔
173
        arguments.clear();
2✔
174
    }
175
    context.pushDirectDeclarator(std::make_unique<FunctionDeclarator>(context.popDirectDeclarator(), std::move(arguments)));
74✔
176
}
74✔
177

178
void noargFunctionDeclarator(AbstractSyntaxTreeBuilderContext& context) {
432✔
179
    context.popTerminal();
432✔
180
    context.popTerminal();
432✔
181
    context.pushDirectDeclarator(std::make_unique<FunctionDeclarator>(context.popDirectDeclarator()));
432✔
182
}
432✔
183

184
void pointerToDeclarator(AbstractSyntaxTreeBuilderContext& context) {
68✔
185
    context.pushDeclarator(std::make_unique<Declarator>(context.popDirectDeclarator(), context.popPointers()));
68✔
186
}
68✔
187

188
void declarator(AbstractSyntaxTreeBuilderContext& context) {
1,250✔
189
    context.pushDeclarator(std::make_unique<Declarator>(context.popDirectDeclarator()));
1,250✔
190
}
1,250✔
191

192
void parameterDeclaration(AbstractSyntaxTreeBuilderContext& context) {
168✔
193
    context.pushFormalArgument(FormalArgument { context.popDeclarationSpecifiers(), context.popDeclarator() });
168✔
194
}
168✔
195

196
void abstractParameterDeclaration(AbstractSyntaxTreeBuilderContext& context) {
×
197
    throw std::runtime_error { "abstractParameterDeclaration is not implemented yet" };
×
198
    //context.pushFormalArgument(std::make_unique<FormalArgument>(context.popDeclarationSpecifiers(), context.popAbstractDeclarator()));
199
}
200

201
void parameterBaseTypeDeclaration(AbstractSyntaxTreeBuilderContext& context) {
8✔
202
    context.pushFormalArgument(FormalArgument { context.popDeclarationSpecifiers() });
8✔
203
}
8✔
204

205
void formalArguments(AbstractSyntaxTreeBuilderContext& context) {
74✔
206
    FormalArguments formalArguments;
74✔
207
    formalArguments.push_back(context.popFormalArgument());
74✔
208
    context.pushFormalArguments(std::move(formalArguments));
74✔
209
}
74✔
210

211
void addFormalArgument(AbstractSyntaxTreeBuilderContext& context) {
102✔
212
    context.popTerminal();
102✔
213
    auto formalArguments = context.popFormalArguments();
102✔
214
    formalArguments.push_back(context.popFormalArgument());
102✔
215
    context.pushFormalArguments(std::move(formalArguments));
102✔
216
}
102✔
217

218
void formalArgumentsDeclaration(AbstractSyntaxTreeBuilderContext& context) {
74✔
219
    context.pushArgumentsDeclaration(std::make_pair(context.popFormalArguments(), false));
74✔
220
}
74✔
221

UNCOV
222
void formalArgumentsWithVararg(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
223
    context.popTerminal();
×
UNCOV
224
    context.popTerminal();
×
225
    //context.pushArgumentsDeclaration(std::make_pair(context.popFormalArguments(), true));
UNCOV
226
    throw std::runtime_error { "formalArgumentsWithVararg is not implemented yet" };
×
227
}
228

229
void integerConstant(AbstractSyntaxTreeBuilderContext& context) {
1,318✔
230
    auto constant = context.popTerminal();
1,318✔
231
    context.pushConstant( { constant.value, type::signedInteger(), constant.context });
1,318✔
232
}
1,318✔
233

234
void characterConstant(AbstractSyntaxTreeBuilderContext& context) {
14✔
235
    auto constant = context.popTerminal();
14✔
236
    context.pushConstant( { constant.value, type::signedCharacter(), constant.context });
14✔
237
}
14✔
238

UNCOV
239
void floatConstant(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
240
    auto constant = context.popTerminal();
×
UNCOV
241
    throw std::runtime_error { "floating constants not implemented yet" };
×
242
    // context.pushConstant( { constant.value, type::floating(), constant.context });
UNCOV
243
}
×
244

UNCOV
245
void enumerationConstant(AbstractSyntaxTreeBuilderContext& context) {
×
246
    auto constant = context.popTerminal();
×
247
    throw std::runtime_error { "enumerationConstant is not implemented yet" };
×
248
}
×
249

250
void identifierExpression(AbstractSyntaxTreeBuilderContext& context) {
2,770✔
251
    auto identifier = context.popTerminal();
2,770✔
252
    context.pushExpression(std::make_unique<IdentifierExpression>(identifier.value, identifier.context));
2,770✔
253
}
2,770✔
254

255
void constantExpression(AbstractSyntaxTreeBuilderContext& context) {
1,332✔
256
    context.pushExpression(std::make_unique<ConstantExpression>(context.popConstant()));
1,332✔
257
}
1,332✔
258

259
void stringLiteralExpression(AbstractSyntaxTreeBuilderContext& context) {
824✔
260
    auto literal = context.popTerminal();
824✔
261
    context.pushExpression(std::make_unique<StringLiteralExpression>(literal.value, literal.context));
824✔
262
}
824✔
263

UNCOV
264
void arrayAccess(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
265
    context.popTerminal(); // ]
×
UNCOV
266
    context.popTerminal(); // [
×
UNCOV
267
    auto subscriptExpression = context.popExpression();
×
UNCOV
268
    auto postfixExpression = context.popExpression();
×
UNCOV
269
    context.pushExpression(std::make_unique<ArrayAccess>(std::move(postfixExpression), std::move(subscriptExpression)));
×
UNCOV
270
}
×
271

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

278
void noargFunctionCall(AbstractSyntaxTreeBuilderContext& context) {
24✔
279
    context.popTerminal(); // )
24✔
280
    context.popTerminal(); // (
24✔
281
    context.pushExpression(std::make_unique<FunctionCall>(context.popExpression()));
24✔
282
}
24✔
283

UNCOV
284
void directMemberAccess(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
285
    throw std::runtime_error { "directMemberAccess is not implemented yet" };
×
286
}
287

UNCOV
288
void pointeeMemberAccess(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
289
    throw std::runtime_error { "pointeeMemberAccess is not implemented yet" };
×
290
}
291

292
void postfixIncrementDecrement(AbstractSyntaxTreeBuilderContext& context) {
26✔
293
    context.pushExpression(std::make_unique<PostfixExpression>(context.popExpression(), std::make_unique<Operator>(context.popTerminal().type)));
26✔
294
}
26✔
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) {
544✔
301
    context.pushExpression(std::make_unique<UnaryExpression>(std::make_unique<Operator>(context.popTerminal().value), context.popExpression()));
544✔
302
}
544✔
303

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

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

312
void typeCast(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
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) {
118✔
320
    auto rightHandSide = context.popExpression();
118✔
321
    auto leftHandSide = context.popExpression();
118✔
322
    auto arithmeticOperator = std::make_unique<Operator>(context.popTerminal().value);
118✔
323
    context.pushExpression(std::make_unique<ArithmeticExpression>(std::move(leftHandSide), std::move(arithmeticOperator), std::move(rightHandSide)));
118✔
324
}
118✔
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) {
186✔
334
    auto rightHandSide = context.popExpression();
186✔
335
    auto leftHandSide = context.popExpression();
186✔
336
    auto comparisonOperator = std::make_unique<Operator>(context.popTerminal().value);
186✔
337
    context.pushExpression(std::make_unique<ComparisonExpression>(std::move(leftHandSide), std::move(comparisonOperator), std::move(rightHandSide)));
186✔
338
}
186✔
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

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

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

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

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

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

388
void initializedDeclaratorList(AbstractSyntaxTreeBuilderContext& context) {
514✔
389
    std::vector<std::unique_ptr<InitializedDeclarator>> declarators;
514✔
390
    declarators.push_back(context.popInitializedDeclarator());
514✔
391
    context.pushInitializedDeclarators(std::move(declarators));
514✔
392
}
514✔
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) {
514✔
402
    context.popTerminal();
514✔
403
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
514✔
404
    auto initializedDeclarators = context.popInitializedDeclarators();
514✔
405
    context.pushDeclaration(std::make_unique<Declaration>(declarationSpecifiers, std::move(initializedDeclarators)));
514✔
406
}
514✔
407

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

414
void declarationList(AbstractSyntaxTreeBuilderContext& context) {
298✔
415
    std::vector<std::unique_ptr<Declaration>> declarations;
298✔
416
    declarations.push_back(context.popDeclaration());
298✔
417
    context.pushDeclarationList(std::move(declarations));
298✔
418
}
298✔
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

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

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

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

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

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

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

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

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

487
void returnExpressionStatement(AbstractSyntaxTreeBuilderContext& context) {
488✔
488
    context.popTerminal();
488✔
489
    context.popTerminal();
488✔
490
    context.pushStatement(std::make_unique<ReturnStatement>(context.popExpression()));
488✔
491
}
488✔
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) {
916✔
500
    context.newActualArgumentsList(context.popExpression());
916✔
501
}
916✔
502

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

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

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

520
void fullCompound(AbstractSyntaxTreeBuilderContext& context) {
298✔
521
    context.popTerminal();
298✔
522
    context.popTerminal();
298✔
523
    auto declarations = context.popDeclarationList();
298✔
524
    auto statements = context.popStatementList();
298✔
525
    context.pushStatement(std::make_unique<Block>(std::move(declarations), std::move(statements)));
298✔
526
}
298✔
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,350✔
537
    context.popTerminal();
1,350✔
538
    context.pushStatement(context.popExpression());
1,350✔
539
}
1,350✔
540

541
void emptyStatement(AbstractSyntaxTreeBuilderContext& context) {
8✔
542
    context.popTerminal();
8✔
543
    // Null statement `;` still occupies a statement slot so parents (if/while/for/stat_list)
544
    // can pop a body without under-flowing the AST statement stack.
545
    context.pushStatement(std::make_unique<Block>(
8✔
546
            std::vector<std::unique_ptr<Declaration>> { },
8✔
547
            std::vector<std::unique_ptr<AbstractSyntaxTreeNode>> { }));
8✔
548
}
8✔
549

550
void functionDefinition(AbstractSyntaxTreeBuilderContext& context) {
504✔
551
    auto declarationSpecifiers = context.popDeclarationSpecifiers();
504✔
552
    auto declarator = context.popDeclarator();
504✔
553
    auto statement = context.popStatement();
504✔
554
    context.pushStatement(std::make_unique<FunctionDefinition>(std::move(declarationSpecifiers), std::move(declarator), std::move(statement)));
504✔
555
}
504✔
556

UNCOV
557
void defaultReturnTypeFunctionDefinition(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
558
    DeclarationSpecifiers defaultReturnTypeSpecifiers { TypeSpecifier { type::signedInteger(), "int" } };
×
UNCOV
559
    context.pushStatement(std::make_unique<FunctionDefinition>(defaultReturnTypeSpecifiers, context.popDeclarator(), context.popStatement()));
×
UNCOV
560
}
×
561

562
void externalFunctionDefinition(AbstractSyntaxTreeBuilderContext& context) {
504✔
563
    context.pushExternalDeclaration(context.popStatement());
504✔
564
}
504✔
565

566
void externalDeclaration(AbstractSyntaxTreeBuilderContext& context) {
114✔
567
    context.pushExternalDeclaration(context.popDeclaration());
114✔
568
}
114✔
569

570
void translationUnit(AbstractSyntaxTreeBuilderContext& context) {
408✔
571
    context.addToTranslationUnit(context.popExternalDeclaration());
408✔
572
}
408✔
573

574
void addToTranslationUnit(AbstractSyntaxTreeBuilderContext& context) {
210✔
575
    context.addToTranslationUnit(context.popExternalDeclaration());
210✔
576
}
210✔
577

578
ContextualSyntaxNodeBuilder::ContextualSyntaxNodeBuilder(const parser::Grammar& grammar) {
410✔
579
    this->grammar = &grammar;
410✔
580

581
    int s_type_specifier = grammar.symbolId("<type_spec>");
410✔
582
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("short") }] = shortType;
1,640✔
583
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("int") }] = integerType;
1,640✔
584
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("long") }] = longType;
1,640✔
585
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("char") }] = characterType;
1,640✔
586
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("void") }] = voidType;
1,640✔
587
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("float") }] = floatType;
1,640✔
588
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("double") }] = doubleType;
1,640✔
589
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("signed") }] = signedType;
1,640✔
590
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("unsigned") }] = unsignedType;
1,640✔
591
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("typedef_name") }] = typedefName;
1,640✔
592
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("<struct_or_union_spec>") }] = structOrUnionType;
1,640✔
593
    nodeCreatorRegistry[s_type_specifier][{ grammar.symbolId("<enum_spec>") }] = enumType;
2,050✔
594

595
    int s_type_qualifier = grammar.symbolId("<type_qualifier>");
410✔
596
    nodeCreatorRegistry[s_type_qualifier][{ grammar.symbolId("const") }] = constQualifier;
1,640✔
597
    nodeCreatorRegistry[s_type_qualifier][{ grammar.symbolId("volatile") }] = volatileQualifier;
2,050✔
598

599
    int s_decl_specs = grammar.symbolId("<decl_specs>");
410✔
600
    nodeCreatorRegistry[s_decl_specs][{ s_type_specifier }] = declarationTypeSpecifier;
820✔
601
    nodeCreatorRegistry[s_decl_specs][{ s_type_specifier, s_decl_specs }] = addDeclarationTypeSpecifier;
820✔
602
    nodeCreatorRegistry[s_decl_specs][{ grammar.symbolId("<storage_class_spec>") }] = declarationStorageClassSpecifier;
1,640✔
603
    nodeCreatorRegistry[s_decl_specs][{ grammar.symbolId("<storage_class_spec>"), s_decl_specs }] = addDeclarationStorageClassSpecifier;
1,640✔
604
    nodeCreatorRegistry[s_decl_specs][{ s_type_qualifier }] = declarationTypeQualifier;
820✔
605
    nodeCreatorRegistry[s_decl_specs][{ s_type_qualifier, s_decl_specs }] = addDeclarationTypeQualifier;
1,230✔
606

607
    int s_direct_declarator = grammar.symbolId("<direct_declarator>");
820✔
608
    int s_declarator = grammar.symbolId("<declarator>");
820✔
609
    int s_param_type_list = grammar.symbolId("<param_type_list>");
820✔
610
    int s_identifier = grammar.symbolId("id");
820✔
611
    int s_open_paren = grammar.symbolId("(");
820✔
612
    int s_close_paren = grammar.symbolId(")");
820✔
613
    int s_open_bracket = grammar.symbolId("[");
820✔
614
    int s_close_bracket = grammar.symbolId("]");
410✔
615

616
    nodeCreatorRegistry[s_direct_declarator][{ s_identifier }] = identifierDeclarator;
820✔
617
    nodeCreatorRegistry[s_direct_declarator][{ s_open_paren, s_declarator, s_close_paren }] = parenthesizedDeclarator;
820✔
618
    nodeCreatorRegistry[s_direct_declarator][{ s_direct_declarator, s_open_bracket, grammar.symbolId("<const_exp>"), s_close_bracket }] = arrayDeclarator;
1,640✔
619
    nodeCreatorRegistry[s_direct_declarator][{ s_direct_declarator, s_open_bracket, s_close_bracket }] = abstractArrayDeclarator;
820✔
620
    nodeCreatorRegistry[s_direct_declarator][{ s_direct_declarator, s_open_paren, s_param_type_list, s_close_paren }] = functionDeclarator;
820✔
621
    nodeCreatorRegistry[s_direct_declarator][{ s_direct_declarator, s_open_paren, s_close_paren }] = noargFunctionDeclarator;
1,230✔
622

623
    int s_pointer = grammar.symbolId("<pointer>" );
410✔
624
    nodeCreatorRegistry[s_declarator][{ s_pointer, s_direct_declarator }] = pointerToDeclarator;
820✔
625
    nodeCreatorRegistry[s_declarator][{ s_direct_declarator }] = declarator;
1,230✔
626

627
    int s_param_decl = grammar.symbolId("<param_decl>");
410✔
628
    nodeCreatorRegistry[s_param_decl][{ s_decl_specs, s_declarator }] = parameterDeclaration;
820✔
629
    nodeCreatorRegistry[s_param_decl][{ s_decl_specs, grammar.symbolId("<abstract_declarator>") }] = abstractParameterDeclaration;
1,640✔
630
    nodeCreatorRegistry[s_param_decl][{ s_decl_specs }] = parameterBaseTypeDeclaration;
1,230✔
631

632
    int s_param_list = grammar.symbolId("<param_list>");
820✔
633
    int s_comma = grammar.symbolId(",");
410✔
634
    nodeCreatorRegistry[s_param_list][{ s_param_decl }] = formalArguments;
820✔
635
    nodeCreatorRegistry[s_param_list][{ s_param_list, s_comma, s_param_decl }] = addFormalArgument;
820✔
636

637
    nodeCreatorRegistry[s_param_type_list][{ s_param_list }] = formalArgumentsDeclaration;
820✔
638
    nodeCreatorRegistry[s_param_type_list][{ s_param_list, s_comma, grammar.symbolId("...") }] = formalArgumentsWithVararg;
2,050✔
639

640
    int s_constant = grammar.symbolId("<const>");
410✔
641
    nodeCreatorRegistry[s_constant][{ grammar.symbolId("int_const") }] = integerConstant;
1,640✔
642
    nodeCreatorRegistry[s_constant][{ grammar.symbolId("char_const") }] = characterConstant;
1,640✔
643
    nodeCreatorRegistry[s_constant][{ grammar.symbolId("float_const") }] = floatConstant;
1,640✔
644
    nodeCreatorRegistry[s_constant][{ grammar.symbolId("enumeration_const") }] = enumerationConstant;
2,050✔
645

646
    int s_exp = grammar.symbolId("<exp>");
820✔
647
    int s_primary_exp = grammar.symbolId("<primary_exp>");
410✔
648
    nodeCreatorRegistry[s_primary_exp][{ s_identifier }] = identifierExpression;
820✔
649
    nodeCreatorRegistry[s_primary_exp][{ s_constant }] = constantExpression;
820✔
650
    nodeCreatorRegistry[s_primary_exp][{ grammar.symbolId("string") }] = stringLiteralExpression;
1,640✔
651
    nodeCreatorRegistry[s_primary_exp][{ s_open_paren, s_exp, s_close_paren }] = parenthesizedExpression;
1,230✔
652

653
    int s_argument_exp_list = grammar.symbolId("<argument_exp_list>");
820✔
654
    int s_postfix_exp = grammar.symbolId("<postfix_exp>");
410✔
655
    nodeCreatorRegistry[s_postfix_exp][{ s_primary_exp }] = doNothing;
820✔
656
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, s_open_bracket, s_exp, s_close_bracket }] = arrayAccess;
820✔
657
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, s_open_paren, s_argument_exp_list, s_close_paren }] = functionCall;
820✔
658
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, s_open_paren, s_close_paren }] = noargFunctionCall;
820✔
659
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, grammar.symbolId(".") }] = directMemberAccess;
1,640✔
660
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, grammar.symbolId("->") }] = pointeeMemberAccess;
1,640✔
661
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, grammar.symbolId("++") }] = postfixIncrementDecrement;
1,640✔
662
    nodeCreatorRegistry[s_postfix_exp][{ s_postfix_exp, grammar.symbolId("--") }] = postfixIncrementDecrement;
2,050✔
663

664
    int s_cast_exp = grammar.symbolId("<cast_exp>");
820✔
665
    int s_unary_exp = grammar.symbolId("<unary_exp>");
820✔
666
    int s_unary_operator = grammar.symbolId("<unary_operator>");
410✔
667
    nodeCreatorRegistry[s_unary_exp][{ s_postfix_exp }] = doNothing;
820✔
668
    nodeCreatorRegistry[s_unary_exp][{ grammar.symbolId("++"), s_unary_exp }] = prefixIncrementDecrement;
1,640✔
669
    nodeCreatorRegistry[s_unary_exp][{ grammar.symbolId("--"), s_unary_exp }] = prefixIncrementDecrement;
1,640✔
670
    nodeCreatorRegistry[s_unary_exp][{ s_unary_operator, s_cast_exp }] = unaryExpression;
820✔
671
    nodeCreatorRegistry[s_unary_exp][{ grammar.symbolId("sizeof"), s_unary_exp }] = sizeofExpression;
1,640✔
672
    nodeCreatorRegistry[s_unary_exp][{ grammar.symbolId("sizeof"), s_open_paren, grammar.symbolId("<type_name>"), s_close_paren }] = sizeofTypeExpression;
2,460✔
673

674
    nodeCreatorRegistry[s_cast_exp][{ s_unary_exp }] = doNothing;
820✔
675
    nodeCreatorRegistry[s_cast_exp][{ s_open_paren, grammar.symbolId("<type_name>"), s_close_paren, s_cast_exp }] = typeCast;
2,050✔
676

677
    int s_mult_exp = grammar.symbolId("<mult_exp>");
410✔
678
    nodeCreatorRegistry[s_mult_exp][{ s_cast_exp }] = doNothing;
820✔
679
    nodeCreatorRegistry[s_mult_exp][{ s_mult_exp, grammar.symbolId("*"), s_cast_exp }] = arithmeticExpression;
1,640✔
680
    nodeCreatorRegistry[s_mult_exp][{ s_mult_exp, grammar.symbolId("/"), s_cast_exp }] = arithmeticExpression;
1,640✔
681
    nodeCreatorRegistry[s_mult_exp][{ s_mult_exp, grammar.symbolId("%"), s_cast_exp }] = arithmeticExpression;
2,050✔
682

683
    int s_additive_exp = grammar.symbolId("<additive_exp>");
410✔
684
    nodeCreatorRegistry[s_additive_exp][{ s_mult_exp }] = doNothing;
820✔
685
    nodeCreatorRegistry[s_additive_exp][{ s_additive_exp, grammar.symbolId("+"), s_mult_exp }] = arithmeticExpression;
1,640✔
686
    nodeCreatorRegistry[s_additive_exp][{ s_additive_exp, grammar.symbolId("-"), s_mult_exp }] = arithmeticExpression;
2,050✔
687

688
    int s_shift_exp = grammar.symbolId("<shift_expression>");
410✔
689
    nodeCreatorRegistry[s_shift_exp][{ s_additive_exp }] = doNothing;
820✔
690
    nodeCreatorRegistry[s_shift_exp][{ s_shift_exp, grammar.symbolId("<<"), s_additive_exp }] = shiftExpression;
1,640✔
691
    nodeCreatorRegistry[s_shift_exp][{ s_shift_exp, grammar.symbolId(">>"), s_additive_exp }] = shiftExpression;
2,050✔
692

693
    int s_relational_exp = grammar.symbolId("<relational_exp>");
410✔
694
    nodeCreatorRegistry[s_relational_exp][{ s_shift_exp }] = doNothing;
820✔
695
    nodeCreatorRegistry[s_relational_exp][{ s_relational_exp, grammar.symbolId("<"), s_shift_exp }] = relationalExpression;
1,640✔
696
    nodeCreatorRegistry[s_relational_exp][{ s_relational_exp, grammar.symbolId(">"), s_shift_exp }] = relationalExpression;
1,640✔
697
    nodeCreatorRegistry[s_relational_exp][{ s_relational_exp, grammar.symbolId("<="), s_shift_exp }] = relationalExpression;
1,640✔
698
    nodeCreatorRegistry[s_relational_exp][{ s_relational_exp, grammar.symbolId(">="), s_shift_exp }] = relationalExpression;
2,050✔
699

700
    int s_equality_exp = grammar.symbolId("<equality_exp>");
410✔
701
    nodeCreatorRegistry[s_equality_exp][{ s_relational_exp }] = doNothing;
820✔
702
    nodeCreatorRegistry[s_equality_exp][{ s_equality_exp, grammar.symbolId("=="), s_relational_exp }] = relationalExpression;
1,640✔
703
    nodeCreatorRegistry[s_equality_exp][{ s_equality_exp, grammar.symbolId("!="), s_relational_exp }] = relationalExpression;
2,050✔
704

705
    int s_and_exp = grammar.symbolId("<and_exp>");
410✔
706
    nodeCreatorRegistry[s_and_exp][{ s_equality_exp }] = doNothing;
820✔
707
    nodeCreatorRegistry[s_and_exp][{ s_and_exp, grammar.symbolId("&"), s_equality_exp }] = bitwiseExpression;
2,050✔
708

709
    int s_exclusive_or_exp = grammar.symbolId("<exclusive_or_exp>");
410✔
710
    nodeCreatorRegistry[s_exclusive_or_exp][{ s_and_exp }] = doNothing;
820✔
711
    nodeCreatorRegistry[s_exclusive_or_exp][{ s_exclusive_or_exp, grammar.symbolId("^"), s_and_exp }] = bitwiseExpression;
2,050✔
712

713
    int s_inclusive_or_exp = grammar.symbolId("<inclusive_or_exp>");
410✔
714
    nodeCreatorRegistry[s_inclusive_or_exp][{ s_exclusive_or_exp }] = doNothing;
820✔
715
    nodeCreatorRegistry[s_inclusive_or_exp][{ s_inclusive_or_exp, grammar.symbolId("|"), s_exclusive_or_exp }] = bitwiseExpression;
2,050✔
716

717
    int s_logical_and_exp = grammar.symbolId("<logical_and_exp>");
410✔
718
    nodeCreatorRegistry[s_logical_and_exp][{ s_inclusive_or_exp }] = doNothing;
820✔
719
    nodeCreatorRegistry[s_logical_and_exp][{ s_logical_and_exp, grammar.symbolId("&&"), s_inclusive_or_exp }] = logicalAndExpression;
2,050✔
720

721
    int s_logical_or_exp = grammar.symbolId("<logical_or_exp>");
410✔
722
    nodeCreatorRegistry[s_logical_or_exp][{ s_logical_and_exp }] = doNothing;
820✔
723
    nodeCreatorRegistry[s_logical_or_exp][{ s_logical_or_exp, grammar.symbolId("||"), s_logical_and_exp }] = logicalOrExpression;
2,050✔
724

725
    int s_conditional_exp = grammar.symbolId("<conditional_exp>");
410✔
726
    nodeCreatorRegistry[s_conditional_exp][{ s_logical_or_exp }] = doNothing;
820✔
727
    nodeCreatorRegistry[s_conditional_exp][{ s_logical_or_exp, grammar.symbolId("?"), s_exp, grammar.symbolId(":"), s_conditional_exp }] = conditionalExpression;
2,870✔
728

729
    int s_assignment = grammar.symbolId("<assignment_exp>");
820✔
730
    int s_assignment_operator = grammar.symbolId("<assignment_operator>");
410✔
731
    nodeCreatorRegistry[s_assignment][{ s_conditional_exp }] = doNothing;
820✔
732
    nodeCreatorRegistry[s_assignment][{ s_unary_exp, s_assignment_operator, s_assignment }] = assignmentExpression;
1,230✔
733

734
    int s_initializer = grammar.symbolId("<initializer>");
820✔
735
    int s_open_brace = grammar.symbolId("{");
820✔
736
    int s_close_brace = grammar.symbolId("}");
410✔
737
    nodeCreatorRegistry[s_initializer][{ s_assignment }] = doNothing;
820✔
738
    nodeCreatorRegistry[s_initializer][{ s_open_brace, grammar.symbolId("<initializer_list>"), s_close_brace }] = initializer;
2,050✔
739

740
    int s_init_declarator = grammar.symbolId("<init_declarator>");
410✔
741
    nodeCreatorRegistry[s_init_declarator][{ s_declarator }] = initializedDeclarator;
820✔
742
    nodeCreatorRegistry[s_init_declarator][{ s_declarator, grammar.symbolId("="), s_initializer }] = initializedDeclaratorWithInitializer;
2,050✔
743

744
    int s_init_declarator_list = grammar.symbolId("<init_declarator_list>");
410✔
745
    nodeCreatorRegistry[s_init_declarator_list][{ s_init_declarator }] = initializedDeclaratorList;
820✔
746
    nodeCreatorRegistry[s_init_declarator_list][{ s_init_declarator_list, s_comma, s_init_declarator }] = addToInitializedDeclaratorList;
1,230✔
747

748
    int s_decl = grammar.symbolId("<decl>");
820✔
749
    int s_semicolon = grammar.symbolId(";");
410✔
750
    nodeCreatorRegistry[s_decl][{ s_decl_specs, s_init_declarator_list, s_semicolon }] = initializedDeclaration;
820✔
751
    nodeCreatorRegistry[s_decl][{ s_decl_specs, s_semicolon }] = declaration;
1,230✔
752

753
    int s_decl_list = grammar.symbolId("<decl_list>");
410✔
754
    nodeCreatorRegistry[s_decl_list][{ s_decl }] = declarationList;
820✔
755
    nodeCreatorRegistry[s_decl_list][{ s_decl_list, s_decl }] = addDeclarationToList;
820✔
756

757
    nodeCreatorRegistry[s_exp][{ s_assignment }] = doNothing;
820✔
758
    nodeCreatorRegistry[s_exp][{ s_exp, s_comma, s_assignment }] = expressionList;
1,230✔
759

760
    int s_type_qualifier_list = grammar.symbolId("<type_qualifier_list>");
410✔
761
    nodeCreatorRegistry[s_type_qualifier_list][{ s_type_qualifier }] = typeQualifierList;
820✔
762
    nodeCreatorRegistry[s_type_qualifier_list][{ s_type_qualifier_list, s_type_qualifier }] = addTypeQualifierToList;
820✔
763

764
    nodeCreatorRegistry[s_pointer][{ grammar.symbolId("*"), s_type_qualifier_list }] = qualifiedPointer;
1,640✔
765
    nodeCreatorRegistry[s_pointer][{ grammar.symbolId("*") }] = pointer;
1,640✔
766
    nodeCreatorRegistry[s_pointer][{ grammar.symbolId("*"), s_type_qualifier_list, s_pointer }] = qualifiedPointerToPointer;
1,640✔
767
    nodeCreatorRegistry[s_pointer][{ grammar.symbolId("*"), s_pointer }] = pointerToPointer;
1,640✔
768

769
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("&") }] = doNothing;
1,640✔
770
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("*") }] = doNothing;
1,640✔
771
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("+") }] = doNothing;
1,640✔
772
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("-") }] = doNothing;
1,640✔
773
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("~") }] = doNothing;
1,640✔
774
    nodeCreatorRegistry[s_unary_operator][{ grammar.symbolId("!") }] = doNothing;
1,640✔
775

776
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("=") }] = doNothing;
1,640✔
777
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("*=") }] = doNothing;
1,640✔
778
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("/=") }] = doNothing;
1,640✔
779
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("%=") }] = doNothing;
1,640✔
780
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("+=") }] = doNothing;
1,640✔
781
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("-=") }] = doNothing;
1,640✔
782
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("<<=") }] = doNothing;
1,640✔
783
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId(">>=") }] = doNothing;
1,640✔
784
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("&=") }] = doNothing;
1,640✔
785
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("^=") }] = doNothing;
1,640✔
786
    nodeCreatorRegistry[s_assignment_operator][{ grammar.symbolId("|=") }] = doNothing;
2,050✔
787

788
    int s_exp_stat = grammar.symbolId("<exp_stat>");
410✔
789
    nodeCreatorRegistry[s_exp_stat][{ s_exp, s_semicolon }] = expressionStatement;
820✔
790
    nodeCreatorRegistry[s_exp_stat][{ s_semicolon }] = emptyStatement;
1,230✔
791

792
    int s_matched = grammar.symbolId("<matched>");
820✔
793
    int s_unmatched = grammar.symbolId("<unmatched>");
820✔
794
    int s_stat = grammar.symbolId("<stat>");
820✔
795
    int s_compound_stat = grammar.symbolId("<compound_stat>");
820✔
796
    int s_jump_stat = grammar.symbolId("<jump_stat>");
820✔
797
    int s_if = grammar.symbolId("if");
410✔
798
    nodeCreatorRegistry[s_matched][{s_if, s_open_paren, s_exp, s_close_paren, s_matched, grammar.symbolId("else"), s_matched }] = ifElseStatement;
1,640✔
799
    nodeCreatorRegistry[s_unmatched][{s_if, s_open_paren, s_exp, s_close_paren, s_stat }] = ifStatement;
820✔
800
    //nodeCreatorRegistry[s_matched][{ grammar.symbolId("switch"), s_open_paren, s_exp, s_close_paren, s_matched }] = switchStatement;
801
    //nodeCreatorRegistry[s_matched][{ grammar.symbolId("<labeled_stat_matched>") }] = labeledStatement; // ??
802
    nodeCreatorRegistry[s_matched][{ s_exp_stat }] = doNothing;
820✔
803
    nodeCreatorRegistry[s_matched][{ s_compound_stat }] = doNothing;
820✔
804
    nodeCreatorRegistry[s_matched][{ s_jump_stat }] = doNothing;
820✔
805

806
    nodeCreatorRegistry[s_stat][{ s_matched }] = doNothing;
820✔
807
    nodeCreatorRegistry[s_stat][{ s_unmatched }] = doNothing;
1,230✔
808

809
    int s_stat_list = grammar.symbolId("<stat_list>");
410✔
810
    nodeCreatorRegistry[s_stat_list][{ s_stat }] = statementList;
820✔
811
    nodeCreatorRegistry[s_stat_list][{ s_stat_list, s_stat }] = addToStatementList;
1,230✔
812

813
    int s_return = grammar.symbolId("return");
410✔
814
    //nodeCreatorRegistry[s_jump][{ grammar.symbolId("goto"), s_identifier, s_semicolon }] = gotoStatement;
815
    //nodeCreatorRegistry[s_jump][{ grammar.symbolId("continue"), s_semicolon }] = continueStatement;
816
    //nodeCreatorRegistry[s_jump][{ grammar.symbolId("break"), s_semicolon }] = breakStatement;
817
    nodeCreatorRegistry[s_jump_stat][{ s_return, s_exp, s_semicolon }] = returnExpressionStatement;
820✔
818
    nodeCreatorRegistry[s_jump_stat][{ s_return, s_semicolon }] = returnVoidStatement;
820✔
819

820
    nodeCreatorRegistry[s_argument_exp_list][{ s_assignment }] = createActualArgumentsList;
820✔
821
    nodeCreatorRegistry[s_argument_exp_list][{ s_argument_exp_list, s_comma, s_assignment }] = addToActualArgumentsList;
820✔
822

823
    nodeCreatorRegistry[s_compound_stat][{ s_open_brace, s_decl_list, s_stat_list, s_close_brace}] = fullCompound;
820✔
824
    nodeCreatorRegistry[s_compound_stat][{ s_open_brace, s_stat_list, s_close_brace}] = statementCompound;
820✔
825
    nodeCreatorRegistry[s_compound_stat][{ s_open_brace, s_decl_list, s_close_brace}] = declarationCompound;
820✔
826
    nodeCreatorRegistry[s_compound_stat][{ s_open_brace, s_close_brace}] = emptyCompound;
1,230✔
827

828
    int s_function_definition = grammar.symbolId("<function_definition>");
410✔
829
    nodeCreatorRegistry[s_function_definition][{ s_decl_specs, s_declarator, s_compound_stat }] = functionDefinition;
820✔
830
    nodeCreatorRegistry[s_function_definition][{ s_declarator, s_compound_stat }] = defaultReturnTypeFunctionDefinition;
1,230✔
831

832
    int s_external_decl = grammar.symbolId("<external_decl>");
410✔
833
    nodeCreatorRegistry[s_external_decl][{ s_function_definition }] = externalFunctionDefinition;
820✔
834
    nodeCreatorRegistry[s_external_decl][{ s_decl }] = externalDeclaration;
1,230✔
835

836
    int s_translation_unit = grammar.symbolId("<translation_unit>");
410✔
837
    nodeCreatorRegistry[s_translation_unit][{ s_external_decl }] = translationUnit;
820✔
838
    nodeCreatorRegistry[s_translation_unit][{ s_translation_unit, s_external_decl }] = addToTranslationUnit;
1,230✔
839

840
    int s_iteration_stat_matched = grammar.symbolId("<iteration_stat_matched>");
820✔
841
    int s_iteration_stat_unmatched = grammar.symbolId("<iteration_stat_unmatched>");
410✔
842
    nodeCreatorRegistry[s_matched][{ s_iteration_stat_matched }] = doNothing;
820✔
843
    nodeCreatorRegistry[s_unmatched][{ s_iteration_stat_unmatched }] = doNothing;
1,230✔
844

845
    int s_while = grammar.symbolId("while");
820✔
846
    int s_for = grammar.symbolId("for");
410✔
847
    nodeCreatorRegistry[s_iteration_stat_matched][{ s_while, s_open_paren, s_exp, s_close_paren, s_matched }] = whileLoopStatement;
820✔
848
    nodeCreatorRegistry[s_iteration_stat_unmatched][{ s_while, s_open_paren, s_exp, s_close_paren, s_unmatched }] = whileLoopStatement;
820✔
849

850
    auto forLoop = [](bool hasInit, bool hasClause, bool hasIncrement) {
3,280✔
851
        return [=](AbstractSyntaxTreeBuilderContext& context) {
36✔
852
            for (int i = 0; i < 5; ++i) {
216✔
853
                context.popTerminal();  // for ( ; ; ) punctuation
180✔
854
            }
855
            auto increment = hasIncrement ? context.popExpression() : nullptr;
36✔
856
            auto clause = hasClause ? context.popExpression() : nullptr;
36✔
857
            auto initialization = hasInit ? context.popExpression() : nullptr;
36✔
858
            auto loopHeader = std::make_unique<ForLoopHeader>(std::move(initialization), std::move(clause), std::move(increment));
36✔
859
            auto body = context.popStatement();
36✔
860
            context.pushStatement(std::make_unique<LoopStatement>(std::move(loopHeader), std::move(body)));
36✔
861
        };
3,316✔
862
    };
863
    auto registerFor = [&](const std::vector<int>& prod, std::function<void(AbstractSyntaxTreeBuilderContext&)> creator) {
3,280✔
864
        nodeCreatorRegistry[s_iteration_stat_matched][prod] = creator;
3,280✔
865
        auto unmatchedProd = prod;
3,280✔
866
        unmatchedProd.back() = s_unmatched;
3,280✔
867
        nodeCreatorRegistry[s_iteration_stat_unmatched][unmatchedProd] = creator;
3,280✔
868
    };
3,280✔
869
    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,230✔
870
    registerFor({ s_for, s_open_paren, s_exp, s_semicolon, s_exp, s_semicolon, s_close_paren, s_matched }, forLoop(true,  true,  false));
1,230✔
871
    registerFor({ s_for, s_open_paren, s_exp, s_semicolon, s_semicolon, s_exp, s_close_paren, s_matched }, forLoop(true,  false, true));
1,230✔
872
    registerFor({ s_for, s_open_paren, s_exp, s_semicolon, s_semicolon, s_close_paren, s_matched }, forLoop(true,  false, false));
1,230✔
873
    registerFor({ s_for, s_open_paren, s_semicolon, s_exp, s_semicolon, s_exp, s_close_paren, s_matched }, forLoop(false, true,  true));
1,230✔
874
    registerFor({ s_for, s_open_paren, s_semicolon, s_exp, s_semicolon, s_close_paren, s_matched }, forLoop(false, true,  false));
1,230✔
875
    registerFor({ s_for, s_open_paren, s_semicolon, s_semicolon, s_exp, s_close_paren, s_matched }, forLoop(false, false, true));
1,230✔
876
    registerFor({ s_for, s_open_paren, s_semicolon, s_semicolon, s_close_paren, s_matched }, forLoop(false, false, false));
1,230✔
877
}
410✔
878

879
ContextualSyntaxNodeBuilder::~ContextualSyntaxNodeBuilder() = default;
410✔
880

881
void ContextualSyntaxNodeBuilder::updateContext(const parser::Production& production, AbstractSyntaxTreeBuilderContext& context) const {
97,988✔
882
    try {
883
        nodeCreatorRegistry.at(production.getDefiningSymbol()).at(production.producedSequence())(context);
97,988✔
UNCOV
884
    } catch (std::out_of_range& exception) {
×
UNCOV
885
        noCreatorDefined(production);
×
UNCOV
886
    }
×
887
}
97,988✔
888

UNCOV
889
void ContextualSyntaxNodeBuilder::noCreatorDefined(const parser::Production& production) const {
×
UNCOV
890
    throw std::runtime_error { "no AST creator defined for production `" + grammar->str(production) + "`" };
×
891
}
892

UNCOV
893
void ContextualSyntaxNodeBuilder::loopJumpStatement(AbstractSyntaxTreeBuilderContext& context) {
×
UNCOV
894
    context.pushStatement(std::make_unique<JumpStatement>(context.popTerminal()));
×
895
    context.popTerminal();
×
896
}
×
897

898
} /* 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