authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-04 21:26:43+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-05 20:25:51+02:00
loga20c0b31de2b6d8de568707429754a6d39d3346d
tree7f3f9960e8fa3cc05970bcfcb26c0ab8e1f39d55
parent73a53fa263dd514940715b98e64e96764af91d46
signature Commit is signed but in an unrecognized format.

std-c parser and ast organization


2 files changed, 382 insertions(+), 234 deletions(-)

lib/std/c/ast.zig+41-7
......@@ -54,13 +54,47 @@ pub const Error = union(enum) {
5454 }
5555};
5656
57pub const Root = struct {
58 decls: DeclList,
59 eof_token: TokenIndex,
57pub const Node = struct {
58 id: Id,
6059
61 pub const DeclList = SegmentedList(*Decl, 4);
62};
60 pub const Id = enum {
61 Root,
62 JumpStmt,
63 ExprStmt,
64 Label,
65 };
66
67 pub const Root = struct {
68 base: Node,
69 decls: DeclList,
70 eof: TokenIndex,
6371
64pub const Decl = struct {
72 pub const DeclList = SegmentedList(*Node, 4);
73 };
6574
66};
\ No newline at end of file
75 pub const JumpStmt = struct {
76 base: Node = Node{ .id = .JumpStmt},
77 ltoken: TokenIndex,
78 kind: Kind,
79 semicolon: TokenIndex,
80
81 pub const Kind = union(enum) {
82 Break,
83 Continue,
84 Return: ?*Node,
85 Goto: TokenIndex,
86 };
87 };
88
89 pub const ExprStmt = struct {
90 base: Node = Node{ .id = .ExprStmt},
91 expr: ?*Node,
92 semicolon: TokenIndex,
93 };
94
95 pub const Label = struct {
96 base: Node = Node{ .id = .Label},
97 identifier: TokenIndex,
98 colon: TokenIndex,
99 };
100};
lib/std/c/parse.zig+341-227
......@@ -55,242 +55,356 @@ pub fn parse(allocator: *Allocator, source: []const u8) !*Tree {
5555 }
5656 }
5757
58 tree.root_node = try parseRoot(arena, &it, tree);
58 var parser = Parser{
59 .arena = arena,
60 .it = &it,
61 .tree = tree,
62 };
63
64 tree.root_node = try parser.root();
5965 return tree;
6066}
6167
62/// Root <- ExternalDeclaration* eof
63fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!*Node {
64 const node = try arena.create(ast.Root);
65 node.* = .{
66 .decls = ast.Node.DeclList.init(arena),
67 .eof_token = undefined,
68 };
69 while (parseExternalDeclarations(arena, it, tree) catch |err| switch (err) {
70 error.OutOfMemory => return error.OutOfMemory,
71 error.ParseError => return node,
72 }) |decl| {
73 try node.decls.push(decl);
74 }
75 node.eof_token = eatToken(it, .Eof) orelse {
76 try tree.errors.push(.{
77 .ExpectedDecl = .{ .token = it.index },
78 });
68const Parser = struct {
69 arena: *Allocator,
70 it: *TokenIterator,
71 tree: *Tree,
72
73 /// Root <- ExternalDeclaration* eof
74 fn root(parser: *Parser) Allocator.Error!*Node {
75 const node = try arena.create(ast.Root);
76 node.* = .{
77 .decls = ast.Node.DeclList.init(arena),
78 .eof = undefined,
79 };
80 while (parser.externalDeclarations() catch |err| switch (err) {
81 error.OutOfMemory => return error.OutOfMemory,
82 error.ParseError => return node,
83 }) |decl| {
84 try node.decls.push(decl);
85 }
86 node.eof = eatToken(it, .Eof) orelse {
87 try tree.errors.push(.{
88 .ExpectedDecl = .{ .token = it.index },
89 });
90 return node;
91 };
7992 return node;
80 };
81 return node;
82}
93 }
8394
84/// ExternalDeclaration
85/// <- Declaration
86/// / DeclarationSpecifiers Declarator Declaration* CompoundStmt
87fn parseExternalDeclarations(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
88 if (try parseDeclaration(arena, it, tree)) |decl| {}
89 return null;
90}
95 /// ExternalDeclaration
96 /// <- Declaration
97 /// / DeclarationSpecifiers Declarator Declaration* CompoundStmt
98 fn externalDeclarations(parser: *Parser) !?*Node {
99 if (try Declaration(parser)) |decl| {}
100 return null;
101 }
102
103 /// Declaration
104 /// <- DeclarationSpecifiers (Declarator (EQUAL Initializer)?)* SEMICOLON
105 /// \ StaticAssertDeclaration
106 fn declaration(parser: *Parser) !?*Node {}
107
108 /// StaticAssertDeclaration <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
109 fn staticAssertDeclaration(parser: *Parser) !?*Node {}
110
111 /// DeclarationSpecifiers
112 /// <- StorageClassSpecifier DeclarationSpecifiers?
113 /// / TypeSpecifier DeclarationSpecifiers?
114 /// / TypeQualifier DeclarationSpecifiers?
115 /// / FunctionSpecifier DeclarationSpecifiers?
116 /// / AlignmentSpecifier DeclarationSpecifiers?
117 fn declarationSpecifiers(parser: *Parser) !*Node {}
118
119 /// StorageClassSpecifier
120 /// <- Keyword_typedef / Keyword_extern / Keyword_static / Keyword_thread_local / Keyword_auto / Keyword_register
121 fn storageClassSpecifier(parser: *Parser) !*Node {}
122
123 /// TypeSpecifier
124 /// <- Keyword_void / Keyword_char / Keyword_short / Keyword_int / Keyword_long / Keyword_float / Keyword_double
125 /// / Keyword_signed / Keyword_unsigned / Keyword_bool / Keyword_complex / Keyword_imaginary /
126 /// / Keyword_atomic LPAREN TypeName RPAREN
127 /// / EnumSpecifier
128 /// / RecordSpecifier
129 /// / IDENTIFIER // typedef name
130 fn typeSpecifier(parser: *Parser) !*Node {}
131
132 /// TypeQualifier <- Keyword_const / Keyword_restrict / Keyword_volatile / Keyword_atomic
133 fn typeQualifier(parser: *Parser) !*Node {}
134
135 /// FunctionSpecifier <- Keyword_inline / Keyword_noreturn
136 fn functionSpecifier(parser: *Parser) !*Node {}
91137
92/// Declaration
93/// <- DeclarationSpecifiers (Declarator (EQUAL Initializer)?)* SEMICOLON
94/// \ StaticAssertDeclaration
95fn parseDeclaration(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {}
96
97/// StaticAssertDeclaration <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
98fn parseStaticAssertDeclaration(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {}
99
100/// DeclarationSpecifiers
101/// <- StorageClassSpecifier DeclarationSpecifiers?
102/// / TypeSpecifier DeclarationSpecifiers?
103/// / TypeQualifier DeclarationSpecifiers?
104/// / FunctionSpecifier DeclarationSpecifiers?
105/// / AlignmentSpecifier DeclarationSpecifiers?
106fn parseDeclarationSpecifiers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
107
108/// StorageClassSpecifier
109/// <- Keyword_typedef / Keyword_extern / Keyword_static / Keyword_thread_local / Keyword_auto / Keyword_register
110fn parseStorageClassSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
111
112/// TypeSpecifier
113/// <- Keyword_void / Keyword_char / Keyword_short / Keyword_int / Keyword_long / Keyword_float / Keyword_double
114/// / Keyword_signed / Keyword_unsigned / Keyword_bool / Keyword_complex / Keyword_imaginary /
115/// / Keyword_atomic LPAREN TypeName RPAREN
116/// / EnumSpecifier
117/// / RecordSpecifier
118/// / IDENTIFIER // typedef name
119fn parseTypeSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
138 /// AlignmentSpecifier <- Keyword_alignas LPAREN (TypeName / ConstExpr) RPAREN
139 fn alignmentSpecifier(parser: *Parser) !*Node {}
120140
121/// TypeQualifier <- Keyword_const / Keyword_restrict / Keyword_volatile / Keyword_atomic
122fn parseTypeQualifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
141 /// EnumSpecifier <- Keyword_enum IDENTIFIER? (LBRACE EnumField RBRACE)?
142 fn enumSpecifier(parser: *Parser) !*Node {}
123143
124/// FunctionSpecifier <- Keyword_inline / Keyword_noreturn
125fn parseFunctionSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
144 /// EnumField <- IDENTIFIER (EQUAL ConstExpr)? (COMMA EnumField) COMMA?
145 fn enumField(parser: *Parser) !*Node {}
126146
127/// AlignmentSpecifier <- Keyword_alignas LPAREN (TypeName / ConstExpr) RPAREN
128fn parseAlignmentSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
147 /// RecordSpecifier <- (Keyword_struct / Keyword_union) IDENTIFIER? (LBRACE RecordField+ RBRACE)?
148 fn recordSpecifier(parser: *Parser) !*Node {}
149
150 /// RecordField
151 /// <- SpecifierQualifer (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON
152 /// \ StaticAssertDeclaration
153 fn recordField(parser: *Parser) !*Node {}
154
155 /// TypeName
156 /// <- SpecifierQualifer AbstractDeclarator?
157 fn typeName(parser: *Parser) !*Node {}
158
159 /// SpecifierQualifer
160 /// <- TypeSpecifier SpecifierQualifer?
161 /// / TypeQualifier SpecifierQualifer?
162 fn specifierQualifer(parser: *Parser) !*Node {}
163
164 /// RecordDeclarator <- Declarator? (COLON ConstExpr)?
165 fn recordDeclarator(parser: *Parser) !*Node {}
166
167 /// Declarator <- Pointer? DirectDeclarator
168 fn declarator(parser: *Parser) !*Node {}
169
170 /// Pointer <- ASTERISK TypeQualifier* Pointer?
171 fn pointer(parser: *Parser) !*Node {}
172
173 /// DirectDeclarator
174 /// <- IDENTIFIER
175 /// / LPAREN Declarator RPAREN
176 /// / DirectDeclarator LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET
177 /// / DirectDeclarator LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
178 fn directDeclarator(parser: *Parser) !*Node {}
179
180 /// BracketDeclarator
181 /// <- Keyword_static TypeQualifier* AssignmentExpr
182 /// / TypeQualifier+ (ASTERISK / Keyword_static AssignmentExpr)
183 /// / TypeQualifier+ AssignmentExpr?
184 /// / AssignmentExpr
185 fn bracketDeclarator(parser: *Parser) !*Node {}
186
187 /// ParamDecl <- DeclarationSpecifiers (Declarator / AbstractDeclarator)
188 fn paramDecl(parser: *Parser) !*Node {}
189
190 /// AbstractDeclarator <- Pointer? DirectAbstractDeclarator?
191 fn abstractDeclarator(parser: *Parser) !*Node {}
192
193 /// DirectAbstractDeclarator
194 /// <- IDENTIFIER
195 /// / LPAREN DirectAbstractDeclarator RPAREN
196 /// / DirectAbstractDeclarator? LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET
197 /// / DirectAbstractDeclarator? LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
198 fn directAbstractDeclarator(parser: *Parser) !*Node {}
199
200 /// Expr <- AssignmentExpr (COMMA Expr)*
201 fn expr(parser: *Parser) !*Node {}
202
203 /// AssignmentExpr
204 /// <- ConditionalExpr // TODO recursive?
205 /// / UnaryExpr (EQUAL / ASTERISKEQUAL / SLASHEQUAL / PERCENTEQUAL / PLUSEQUAL / MINUSEQUA /
206 /// / ANGLEBRACKETANGLEBRACKETLEFTEQUAL / ANGLEBRACKETANGLEBRACKETRIGHTEQUAL /
207 /// / AMPERSANDEQUAL / CARETEQUAL / PIPEEQUAL) AssignmentExpr
208 fn assignmentExpr(parser: *Parser) !*Node {}
209
210 /// ConstExpr <- ConditionalExpr
211 /// ConditionalExpr <- LogicalOrExpr (QUESTIONMARK Expr COLON ConditionalExpr)?
212 fn conditionalExpr(parser: *Parser) !*Node {}
213
214 /// LogicalOrExpr <- LogicalAndExpr (PIPEPIPE LogicalOrExpr)*
215 fn logicalOrExpr(parser: *Parser) !*Node {}
216
217 /// LogicalAndExpr <- BinOrExpr (AMPERSANDAMPERSAND LogicalAndExpr)*
218 fn logicalAndExpr(parser: *Parser) !*Node {}
219
220 /// BinOrExpr <- BinXorExpr (PIPE BinOrExpr)*
221 fn binOrExpr(parser: *Parser) !*Node {}
222
223 /// BinXorExpr <- BinAndExpr (CARET BinXorExpr)*
224 fn binXorExpr(parser: *Parser) !*Node {}
225
226 /// BinAndExpr <- EqualityExpr (AMPERSAND BinAndExpr)*
227 fn binAndExpr(parser: *Parser) !*Node {}
228
229 /// EqualityExpr <- ComparisionExpr ((EQUALEQUAL / BANGEQUAL) EqualityExpr)*
230 fn equalityExpr(parser: *Parser) !*Node {}
231
232 /// ComparisionExpr <- ShiftExpr (ANGLEBRACKETLEFT / ANGLEBRACKETLEFTEQUAL /ANGLEBRACKETRIGHT / ANGLEBRACKETRIGHTEQUAL) ComparisionExpr)*
233 fn comparisionExpr(parser: *Parser) !*Node {}
234
235 /// ShiftExpr <- AdditiveExpr (ANGLEBRACKETANGLEBRACKETLEFT / ANGLEBRACKETANGLEBRACKETRIGHT) ShiftExpr)*
236 fn shiftExpr(parser: *Parser) !*Node {}
237
238 /// AdditiveExpr <- MultiplicativeExpr (PLUS / MINUS) AdditiveExpr)*
239 fn additiveExpr(parser: *Parser) !*Node {}
240
241 /// MultiplicativeExpr <- UnaryExpr (ASTERISK / SLASH / PERCENT) MultiplicativeExpr)*
242 fn multiplicativeExpr(parser: *Parser) !*Node {}
243
244 /// UnaryExpr
245 /// <- LPAREN TypeName RPAREN UnaryExpr
246 /// / Keyword_sizeof LAPERN TypeName RPAREN
247 /// / Keyword_sizeof UnaryExpr
248 /// / Keyword_alignof LAPERN TypeName RPAREN
249 /// / (AMPERSAND / ASTERISK / PLUS / PLUSPLUS / MINUS / MINUSMINUS / TILDE / BANG) UnaryExpr
250 /// / PrimaryExpr PostFixExpr*
251 fn unaryExpr(parser: *Parser) !*Node {}
252
253 /// PrimaryExpr
254 /// <- IDENTIFIER
255 /// / INTEGERLITERAL / FLITERAL / STRINGLITERAL / CHARLITERAL
256 /// / LPAREN Expr RPAREN
257 /// / Keyword_generic LPAREN AssignmentExpr (COMMA Generic)+ RPAREN
258 fn primaryExpr(parser: *Parser) !*Node {}
259
260 /// Generic
261 /// <- TypeName COLON AssignmentExpr
262 /// / Keyword_default COLON AssignmentExpr
263 fn generic(parser: *Parser) !*Node {}
264
265 /// PostFixExpr
266 /// <- LPAREN TypeName RPAREN LBRACE Initializers RBRACE
267 /// / LBRACKET Expr RBRACKET
268 /// / LPAREN (AssignmentExpr (COMMA AssignmentExpr)*)? RPAREN
269 /// / (PERIOD / ARROW) IDENTIFIER
270 /// / (PLUSPLUS / MINUSMINUS)
271 fn postFixExpr(parser: *Parser) !*Node {}
272
273 /// Initializers <- ((Designator+ EQUAL)? Initializer COMMA)* (Designator+ EQUAL)? Initializer COMMA?
274 fn initializers(parser: *Parser) !*Node {}
275
276 /// Initializer
277 /// <- LBRACE Initializers RBRACE
278 /// / AssignmentExpr
279 fn initializer(parser: *Parser) !*Node {}
280
281 /// Designator
282 /// <- LBRACKET Initializers RBRACKET
283 /// / PERIOD IDENTIFIER
284 fn designator(parser: *Parser) !*Node {}
285
286 /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE
287 fn compoundStmt(parser: *Parser) !?*Node {}
288
289 /// Stmt
290 /// <- CompoundStmt
291 /// / Keyword_if LPAREN Expr RPAREN Stmt (Keyword_ELSE Stmt)?
292 /// / Keyword_switch LPAREN Expr RPAREN Stmt
293 /// / Keyword_while LPAREN Expr RPAREN Stmt
294 /// / Keyword_do statement Keyword_while LPAREN Expr RPAREN SEMICOLON
295 /// / Keyword_for LPAREN (Declaration / ExprStmt) ExprStmt Expr? RPAREN Stmt
296 /// / Keyword_default COLON Stmt
297 /// / Keyword_case ConstExpr COLON Stmt
298 /// / Keyword_goto IDENTIFIER SEMICOLON
299 /// / Keyword_continue SEMICOLON
300 /// / Keyword_break SEMICOLON
301 /// / Keyword_return Expr? SEMICOLON
302 /// / IDENTIFIER COLON Stmt
303 /// / ExprStmt
304 fn stmt(parser: *Parser) !?*Node {
305 if (parser.compoundStmt()) |node| return node;
306 // if (parser.eatToken(.Keyword_if)) |tok| {}
307 // if (parser.eatToken(.Keyword_switch)) |tok| {}
308 // if (parser.eatToken(.Keyword_while)) |tok| {}
309 // if (parser.eatToken(.Keyword_do)) |tok| {}
310 // if (parser.eatToken(.Keyword_for)) |tok| {}
311 // if (parser.eatToken(.Keyword_default)) |tok| {}
312 // if (parser.eatToken(.Keyword_case)) |tok| {}
313 if (parser.eatToken(.Keyword_goto)) |tok| {
314 const node = try parser.arena.create(Node.JumpStmt);
315 node.* = .{
316 .ltoken = tok,
317 .kind = .Goto,
318 .semicolon = parser.expectToken(.Semicolon),
319 };
320 return &node.base;
321 }
322 if (parser.eatToken(.Keyword_continue)) |tok| {
323 const node = try parser.arena.create(Node.JumpStmt);
324 node.* = .{
325 .ltoken = tok,
326 .kind = .Continue,
327 .semicolon = parser.expectToken(.Semicolon),
328 };
329 return &node.base;
330 }
331 if (parser.eatToken(.Keyword_break)) |tok| {
332 const node = try parser.arena.create(Node.JumpStmt);
333 node.* = .{
334 .ltoken = tok,
335 .kind = .Break,
336 .semicolon = parser.expectToken(.Semicolon),
337 };
338 return &node.base;
339 }
340 if (parser.eatToken(.Keyword_return)) |tok| {
341 const node = try parser.arena.create(Node.JumpStmt);
342 node.* = .{
343 .ltoken = tok,
344 .kind = .{ .Return = try parser.expr() },
345 .semicolon = parser.expectToken(.Semicolon),
346 };
347 return &node.base;
348 }
349 if (parser.eatToken(.Identifier)) |tok| {
350 if (parser.eatToken(.Colon)) |col| {
351 const node = try parser.arena.create(Node.Label);
352 node.* = .{
353 .identifier = tok,
354 .semicolon = parser.expectToken(.Colon),
355 };
356 return &node.base;
357 }
358 putBackToken(tok);
359 }
360 if (parser.exprStmt()) |node| return node;
361 return null;
362 }
129363
130/// EnumSpecifier <- Keyword_enum IDENTIFIER? (LBRACE EnumField RBRACE)?
131fn parseEnumSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
364 /// ExprStmt <- Expr? SEMICOLON
365 fn exprStmt(parser: *Parser) !*Node {
366 const node = try parser.arena.create(Node.ExprStmt);
367 node.* = .{
368 .expr = try parser.expr(),
369 .semicolon = parser.expectToken(.Semicolon),
370 };
371 return &node.base;
372 }
132373
133/// EnumField <- IDENTIFIER (EQUAL ConstExpr)? (COMMA EnumField) COMMA?
134fn parseEnumField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
374 fn eatToken(parser: *Parser, id: Token.Id) ?TokenIndex {
375 while (true) {
376 const next_tok = parser.it.next() orelse return null;
377 if (next_tok.id != .LineComment and next_tok.id != .MultiLineComment) {
378 if (next_tok.id == id) {
379 return parser.it.index;
380 }
381 parser.it.prev();
382 return null;
383 }
384 }
385 }
135386
136/// RecordSpecifier <- (Keyword_struct / Keyword_union) IDENTIFIER? (LBRACE RecordField+ RBRACE)?
137fn parseRecordSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
138
139/// RecordField
140/// <- SpecifierQualifer (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON
141/// \ StaticAssertDeclaration
142fn parseRecordField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
143
144/// TypeName
145/// <- SpecifierQualifer AbstractDeclarator?
146fn parseTypeName(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
147
148/// SpecifierQualifer
149/// <- TypeSpecifier SpecifierQualifer?
150/// / TypeQualifier SpecifierQualifer?
151fn parseSpecifierQualifer(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
152
153/// RecordDeclarator <- Declarator? (COLON ConstExpr)?
154fn parseRecordDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
155
156/// Declarator <- Pointer? DirectDeclarator
157fn parseDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
158
159/// Pointer <- ASTERISK TypeQualifier* Pointer?
160fn parsePointer(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
161
162/// DirectDeclarator
163/// <- IDENTIFIER
164/// / LPAREN Declarator RPAREN
165/// / DirectDeclarator LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET
166/// / DirectDeclarator LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
167fn parseDirectDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
168
169/// BracketDeclarator
170/// <- Keyword_static TypeQualifier* AssignmentExpr
171/// / TypeQualifier+ (ASTERISK / Keyword_static AssignmentExpr)
172/// / TypeQualifier+ AssignmentExpr?
173/// / AssignmentExpr
174fn parseBracketDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
175
176/// ParamDecl <- DeclarationSpecifiers (Declarator / AbstractDeclarator)
177fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
178
179/// AbstractDeclarator <- Pointer? DirectAbstractDeclarator?
180fn parseAbstractDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
181
182/// DirectAbstractDeclarator
183/// <- IDENTIFIER
184/// / LPAREN DirectAbstractDeclarator RPAREN
185/// / DirectAbstractDeclarator? LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET
186/// / DirectAbstractDeclarator? LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
187fn parseDirectAbstractDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
188
189/// Expr <- AssignmentExpr (COMMA Expr)*
190fn parseExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
191
192/// AssignmentExpr
193/// <- ConditionalExpr
194/// / UnaryExpr (EQUAL / ASTERISKEQUAL / SLASHEQUAL / PERCENTEQUAL / PLUSEQUAL / MINUSEQUA /
195/// / ANGLEBRACKETANGLEBRACKETLEFTEQUAL / ANGLEBRACKETANGLEBRACKETRIGHTEQUAL /
196/// / AMPERSANDEQUAL / CARETEQUAL / PIPEEQUAL) AssignmentExpr
197fn parseAssignmentExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
198
199/// ConstExpr <- ConditionalExpr
200/// ConditionalExpr <- LogicalOrExpr (QUESTIONMARK Expr COLON ConditionalExpr)?
201fn parseConditionalExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
202
203/// LogicalOrExpr <- LogicalAndExpr (PIPEPIPE LogicalOrExpr)*
204fn parseLogicalOrExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
205
206/// LogicalAndExpr <- BinOrExpr (AMPERSANDAMPERSAND LogicalAndExpr)*
207fn parseLogicalAndExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
208
209/// BinOrExpr <- BinXorExpr (PIPE BinOrExpr)*
210fn parseBinOrExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
211
212/// BinXorExpr <- BinAndExpr (CARET BinXorExpr)*
213fn parseBinXorExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
214
215/// BinAndExpr <- EqualityExpr (AMPERSAND BinAndExpr)*
216fn parseBinAndExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
217
218/// EqualityExpr <- ComparisionExpr ((EQUALEQUAL / BANGEQUAL) EqualityExpr)*
219fn parseEqualityExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
220
221/// ComparisionExpr <- ShiftExpr (ANGLEBRACKETLEFT / ANGLEBRACKETLEFTEQUAL /ANGLEBRACKETRIGHT / ANGLEBRACKETRIGHTEQUAL) ComparisionExpr)*
222fn parseComparisionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
223
224/// ShiftExpr <- AdditiveExpr (ANGLEBRACKETANGLEBRACKETLEFT / ANGLEBRACKETANGLEBRACKETRIGHT) ShiftExpr)*
225fn parseShiftExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
226
227/// AdditiveExpr <- MultiplicativeExpr (PLUS / MINUS) AdditiveExpr)*
228fn parseAdditiveExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
229
230/// MultiplicativeExpr <- UnaryExpr (ASTERISK / SLASH / PERCENT) MultiplicativeExpr)*
231fn parseMultiplicativeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
232
233/// UnaryExpr
234/// <- LPAREN TypeName RPAREN UnaryExpr
235/// / Keyword_sizeof LAPERN TypeName RPAREN
236/// / Keyword_sizeof UnaryExpr
237/// / Keyword_alignof LAPERN TypeName RPAREN
238/// / (AMPERSAND / ASTERISK / PLUS / PLUSPLUS / MINUS / MINUSMINUS / TILDE / BANG) UnaryExpr
239/// / PrimaryExpr PostFixExpr*
240fn parseUnaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
241
242/// PrimaryExpr
243/// <- IDENTIFIER
244/// / INTEGERLITERAL / FLITERAL / STRINGLITERAL / CHARLITERAL
245/// / LPAREN Expr RPAREN
246/// / Keyword_generic LPAREN AssignmentExpr (COMMA Generic)+ RPAREN
247fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
248
249/// Generic
250/// <- TypeName COLON AssignmentExpr
251/// / Keyword_default COLON AssignmentExpr
252fn parseGeneric(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
253
254/// PostFixExpr
255/// <- LPAREN TypeName RPAREN LBRACE Initializers RBRACE
256/// / LBRACKET Expr RBRACKET
257/// / LPAREN (AssignmentExpr (COMMA AssignmentExpr)*)? RPAREN
258/// / (PERIOD / ARROW) IDENTIFIER
259/// / (PLUSPLUS / MINUSMINUS)
260fn parsePostFixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
261
262/// Initializers <- ((Designator+ EQUAL)? Initializer COMMA)* (Designator+ EQUAL)? Initializer COMMA?
263fn parseInitializers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
264
265/// Initializer
266/// <- LBRACE Initializers RBRACE
267/// / AssignmentExpr
268fn parseInitializer(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
269
270/// Designator
271/// <- LBRACKET Initializers RBRACKET
272/// / PERIOD IDENTIFIER
273fn parseDesignator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
274
275/// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE
276fn parseCompoundStmt(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
277
278/// Stmt
279/// <- CompoundStmt
280/// / Keyword_if LPAREN Expr RPAREN Stmt (Keyword_ELSE Stmt)?
281/// / Keyword_switch LPAREN Expr RPAREN Stmt
282/// / Keyword_while LPAREN Expr RPAREN Stmt
283/// / Keyword_do statement Keyword_while LPAREN Expr RPAREN SEMICOLON
284/// / Keyword_for LPAREN (Declaration / ExprStmt) ExprStmt Expr? RPAREN Stmt
285/// / Keyword_default COLON Stmt
286/// / Keyword_case ConstExpr COLON Stmt
287/// / Keyword_goto IDENTIFIER SEMICOLON
288/// / Keyword_continue SEMICOLON
289/// / Keyword_break SEMICOLON
290/// / Keyword_return Expr? SEMICOLON
291/// / IDENTIFIER COLON Stmt
292/// / ExprStmt
293fn parseStmt(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
294
295/// ExprStmt <- Expr? SEMICOLON
296fn parseExprStmt(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
387 fn expectToken(parser: *Parser, id: Token.Id) Error!TokenIndex {
388 while (true) {
389 const next_tok = parser.it.next() orelse return error.ParseError;
390 if (next_tok.id != .LineComment and next_tok.id != .MultiLineComment) {
391 if (next_tok.id != id) {
392 try tree.errors.push(.{
393 .ExpectedToken = .{ .token = parser.it.index, .expected_id = id },
394 });
395 return error.ParseError;
396 }
397 return parser.it.index;
398 }
399 }
400 }
401
402 fn putBackToken(it: *TokenIterator, putting_back: TokenIndex) void {
403 while (true) {
404 const prev_tok = it.prev() orelse return;
405 if (next_tok.id == .LineComment or next_tok.id == .MultiLineComment) continue;
406 assert(it.list.at(putting_back) == prev_tok);
407 return;
408 }
409 }
410};