authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-05 13:24:10+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-05 20:25:51+02:00
log46f292982d6035c7d57ae8d637c770a121c40e37
tree8f103c5572630359d0a4fe119a86b58422a54fe6
parent25f7f66b8fb882a9b0abcad1baed851fabc464de
signaturelock-open Commit is signed but in an unrecognized format.

std-c parser DeclSpec


4 files changed, 232 insertions(+), 109 deletions(-)

lib/std/c.zig+1-1
......@@ -2,7 +2,7 @@ const builtin = @import("builtin");
22const std = @import("std");
33const page_size = std.mem.page_size;
44
5const tokenizer = @import("c/tokenizer.zig");
5pub const tokenizer = @import("c/tokenizer.zig");
66pub const Token = tokenizer.Token;
77pub const Tokenizer = tokenizer.Tokenizer;
88pub const parse = @import("c/parse.zig").parse;
lib/std/c/ast.zig+38-8
......@@ -1,4 +1,4 @@
1const std = @import("std.zig");
1const std = @import("std");
22const SegmentedList = std.SegmentedList;
33const Token = std.c.Token;
44const Source = std.c.tokenizer.Source;
......@@ -11,6 +11,7 @@ pub const Tree = struct {
1111 root_node: *Node.Root,
1212 arena_allocator: std.heap.ArenaAllocator,
1313 errors: ErrorList,
14 warnings: ?ErrorList,
1415
1516 pub const SourceList = SegmentedList(Source, 4);
1617 pub const TokenList = Source.TokenList;
......@@ -30,8 +31,10 @@ pub const Error = union(enum) {
3031 ExpectedToken: ExpectedToken,
3132 ExpectedExpr: SingleTokenError("expected expression, found '{}'"),
3233 ExpectedStmt: SingleTokenError("expected statement, found '{}'"),
34 ExpectedTypeName: SingleTokenError("expected type name, found '{}'"),
3335 InvalidTypeSpecifier: InvalidTypeSpecifier,
3436 DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"),
37 DuplicateSpecifier: SingleTokenError("duplicate declaration specifier '{}'"),
3538
3639 pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
3740 switch (self.*) {
......@@ -39,8 +42,10 @@ pub const Error = union(enum) {
3942 .ExpectedToken => |*x| return x.render(tokens, stream),
4043 .ExpectedExpr => |*x| return x.render(tokens, stream),
4144 .ExpectedStmt => |*x| return x.render(tokens, stream),
45 .ExpectedTypeName => |*x| return x.render(tokens, stream),
4246 .InvalidTypeSpecifier => |*x| return x.render(tokens, stream),
4347 .DuplicateQualifier => |*x| return x.render(tokens, stream),
48 .DuplicateSpecifier => |*x| return x.render(tokens, stream),
4449 }
4550 }
4651
......@@ -50,8 +55,10 @@ pub const Error = union(enum) {
5055 .ExpectedToken => |x| return x.token,
5156 .ExpectedExpr => |x| return x.token,
5257 .ExpectedStmt => |x| return x.token,
58 .ExpectedTypeName => |x| return x.token,
5359 .InvalidTypeSpecifier => |x| return x.token,
5460 .DuplicateQualifier => |x| return x.token,
61 .DuplicateSpecifier => |x| return x.token,
5562 }
5663 }
5764
......@@ -72,11 +79,11 @@ pub const Error = union(enum) {
7279
7380 pub const InvalidTypeSpecifier = struct {
7481 token: TokenIndex,
75 type: *Node.Type,
82 type_spec: *Node.TypeSpec,
7683
7784 pub fn render(self: *const ExpectedToken, tokens: *Tree.TokenList, stream: var) !void {
7885 try stream.write("invalid type specifier '");
79 try type.specifier.print(tokens, stream);
86 try type_spec.spec.print(tokens, stream);
8087 const token_name = tokens.at(self.token).id.symbol();
8188 return stream.print("{}'", .{ token_name });
8289 }
......@@ -114,9 +121,32 @@ pub const Node = struct {
114121 pub const DeclList = SegmentedList(*Node, 4);
115122 };
116123
117 pub const Type = struct {
118 qualifiers: Qualifiers,
119 specifier: union(enum) {
124 pub const DeclSpec = struct {
125 storage_class: union(enum) {
126 Auto: TokenIndex,
127 Extern: TokenIndex,
128 Register: TokenIndex,
129 Static: TokenIndex,
130 Typedef: TokenIndex,
131 None,
132 } = .None,
133 thread_local: ?TokenIndex = null,
134 type_spec: TypeSpec = TypeSpec{},
135 fn_spec: union(enum) {
136 Inline: TokenIndex,
137 Noreturn: TokenIndex,
138 None,
139 } = .None,
140 align_spec: ?struct {
141 alignas: TokenIndex,
142 expr: *Node,
143 rparen: TokenIndex,
144 } = null,
145 };
146
147 pub const TypeSpec = struct {
148 qual: TypeQual = TypeQual{},
149 spec: union(enum) {
120150 /// error or default to int
121151 None,
122152 Void: TokenIndex,
......@@ -167,10 +197,10 @@ pub const Node = struct {
167197 else => @panic("TODO print type specifier"),
168198 }
169199 }
170 },
200 } = .None,
171201 };
172202
173 pub const Qualifiers = struct {
203 pub const TypeQual = struct {
174204 @"const": ?TokenIndex = null,
175205 atomic: ?TokenIndex = null,
176206 @"volatile": ?TokenIndex = null,
lib/std/c/parse.zig+187-98
......@@ -1,7 +1,8 @@
1const std = @import("../std.zig");
1const std = @import("std");
22const assert = std.debug.assert;
33const Allocator = std.mem.Allocator;
44const ast = std.c.ast;
5const Node = ast.Node;
56const Tree = ast.Tree;
67const TokenIndex = ast.TokenIndex;
78const Token = std.c.Token;
......@@ -69,6 +70,12 @@ const Parser = struct {
6970 arena: *Allocator,
7071 it: *TokenIterator,
7172 tree: *Tree,
73 typedefs: std.StringHashMap(void),
74
75 fn isTypedef(parser: *Parser, tok: TokenIndex) bool {
76 const token = parser.it.list.at(tok);
77 return parser.typedefs.contains(token.slice());
78 }
7279
7380 /// Root <- ExternalDeclaration* eof
7481 fn root(parser: *Parser) Allocator.Error!*Node {
......@@ -93,48 +100,89 @@ const Parser = struct {
93100 }
94101
95102 /// ExternalDeclaration
96 /// <- Declaration
97 /// / DeclarationSpecifiers Declarator Declaration* CompoundStmt
103 /// <- DeclSpec Declarator Declaration* CompoundStmt
104 /// / DeclSpec (Declarator (EQUAL Initializer)?)* SEMICOLON
105 /// / StaticAssert
98106 fn externalDeclarations(parser: *Parser) !?*Node {
99107 if (try Declaration(parser)) |decl| {}
100108 return null;
101109 }
102110
103111 /// Declaration
104 /// <- DeclarationSpecifiers (Declarator (EQUAL Initializer)?)* SEMICOLON
105 /// \ StaticAssertDeclaration
112 /// <- DeclSpec (Declarator (EQUAL Initializer)?)* SEMICOLON
113 /// / StaticAssert
106114 fn declaration(parser: *Parser) !?*Node {}
107115
108 /// StaticAssertDeclaration <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
109 fn staticAssertDeclaration(parser: *Parser) !?*Node {}
116 /// StaticAssert <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
117 fn StaticAssert(parser: *Parser) !?*Node {}
110118
111 /// DeclarationSpecifiers
112 /// <- (Keyword_typedef / Keyword_extern / Keyword_static / Keyword_thread_local / Keyword_auto / Keyword_register
113 /// / Type
114 /// / Keyword_inline / Keyword_noreturn
115 /// / Keyword_alignas LPAREN (TypeName / ConstExpr) RPAREN)*
116 fn declarationSpecifiers(parser: *Parser) !*Node {}
119 /// DeclSpec <- (StorageClassSpec / TypeSpec / FnSpec / AlignSpec)*
120 fn declSpec(parser: *Parser) !*Node.DeclSpec {
121 const ds = try parser.arena.create(Node.DeclSpec);
122 ds.* = .{};
123 while ((try parser.storageClassSpec(ds)) or (try parser.typeSpec(&ds.type_spec)) or (try parser.fnSpec(ds)) or (try parser.alignSpec(ds))) {}
124 return ds;
125 }
117126
118 /// Type
127 /// StorageClassSpec
128 /// <- Keyword_typedef / Keyword_extern / Keyword_static / Keyword_thread_local / Keyword_auto / Keyword_register
129 fn storageClassSpec(parser: *Parser, ds: *Node.DeclSpec) !bool {
130 blk: {
131 if (parser.eatToken(.Keyword_typedef)) |tok| {
132 if (ds.storage_class != .None or ds.thread_local != null)
133 break :blk;
134 ds.storage_class = .{ .Typedef = tok };
135 } else if (parser.eatToken(.Keyword_extern)) |tok| {
136 if (ds.storage_class != .None)
137 break :blk;
138 ds.storage_class = .{ .Extern = tok };
139 } else if (parser.eatToken(.Keyword_static)) |tok| {
140 if (ds.storage_class != .None)
141 break :blk;
142 ds.storage_class = .{ .Static = tok };
143 } else if (parser.eatToken(.Keyword_thread_local)) |tok| {
144 switch (ds.storage_class) {
145 .None, .Extern, .Static => {},
146 else => break :blk,
147 }
148 ds.thread_local = tok;
149 } else if (parser.eatToken(.Keyword_auto)) |tok| {
150 if (ds.storage_class != .None or ds.thread_local != null)
151 break :blk;
152 ds.storage_class = .{ .Auto = tok };
153 } else if (parser.eatToken(.Keyword_register)) |tok| {
154 if (ds.storage_class != .None or ds.thread_local != null)
155 break :blk;
156 ds.storage_class = .{ .Register = tok };
157 } else return false;
158 return true;
159 }
160 try parser.warning(.{
161 .DuplicateSpecifier = .{ .token = parser.it.index },
162 });
163 return true;
164 }
165
166 /// TypeSpec
119167 /// <- Keyword_void / Keyword_char / Keyword_short / Keyword_int / Keyword_long / Keyword_float / Keyword_double
120168 /// / Keyword_signed / Keyword_unsigned / Keyword_bool / Keyword_complex / Keyword_imaginary /
121169 /// / Keyword_atomic LPAREN TypeName RPAREN
122170 /// / EnumSpecifier
123171 /// / RecordSpecifier
124172 /// / IDENTIFIER // typedef name
125 /// / TypeQualifier
126 fn type(parser: *Parser, type: *Node.Type) !bool {
127 while (try parser.typeQualifier(type.qualifiers)) {}
173 /// / TypeQual
174 fn typeSpec(parser: *Parser, type_spec: *Node.TypeSpec) !bool {
175 while (try parser.typeQual(&type_spec.qual)) {}
128176 blk: {
129177 if (parser.eatToken(.Keyword_void)) |tok| {
130 if (type.specifier != .None)
178 if (type_spec.spec != .None)
131179 break :blk;
132 type.specifier = .{ .Void = tok };
180 type_spec.spec = .{ .Void = tok };
133181 return true;
134182 } else if (parser.eatToken(.Keyword_char)) |tok| {
135 switch (type.specifier) {
183 switch (type_spec.spec) {
136184 .None => {
137 type.specifier = .{
185 type_spec.spec = .{
138186 .Char = .{
139187 .char = tok,
140188 },
......@@ -143,7 +191,7 @@ const Parser = struct {
143191 .Int => |int| {
144192 if (int.int != null)
145193 break :blk;
146 type.specifier = .{
194 type_spec.spec = .{
147195 .Char = .{
148196 .char = tok,
149197 .sign = int.sign,
......@@ -154,9 +202,9 @@ const Parser = struct {
154202 }
155203 return true;
156204 } else if (parser.eatToken(.Keyword_short)) |tok| {
157 switch (type.specifier) {
205 switch (type_spec.spec) {
158206 .None => {
159 type.specifier = .{
207 type_spec.spec = .{
160208 .Short = .{
161209 .short = tok,
162210 },
......@@ -165,7 +213,7 @@ const Parser = struct {
165213 .Int => |int| {
166214 if (int.int != null)
167215 break :blk;
168 type.specifier = .{
216 type_spec.spec = .{
169217 .Short = .{
170218 .short = tok,
171219 .sign = int.sign,
......@@ -176,16 +224,16 @@ const Parser = struct {
176224 }
177225 return true;
178226 } else if (parser.eatToken(.Keyword_long)) |tok| {
179 switch (type.specifier) {
227 switch (type_spec.spec) {
180228 .None => {
181 type.specifier = .{
229 type_spec.spec = .{
182230 .Long = .{
183231 .long = tok,
184232 },
185233 };
186234 },
187235 .Int => |int| {
188 type.specifier = .{
236 type_spec.spec = .{
189237 .Long = .{
190238 .long = tok,
191239 .sign = int.sign,
......@@ -207,9 +255,9 @@ const Parser = struct {
207255 }
208256 return true;
209257 } else if (parser.eatToken(.Keyword_int)) |tok| {
210 switch (type.specifier) {
258 switch (type_spec.spec) {
211259 .None => {
212 type.specifier = .{
260 type_spec.spec = .{
213261 .Int = .{
214262 .int = tok,
215263 },
......@@ -234,9 +282,9 @@ const Parser = struct {
234282 }
235283 return true;
236284 } else if (parser.eatToken(.Keyword_signed) orelse parser.eatToken(.Keyword_unsigned)) |tok| {
237 switch (type.specifier) {
285 switch (type_spec.spec) {
238286 .None => {
239 type.specifier = .{
287 type_spec.spec = .{
240288 .Int = .{
241289 .sign = tok,
242290 },
......@@ -266,30 +314,30 @@ const Parser = struct {
266314 }
267315 return true;
268316 } else if (parser.eatToken(.Keyword_float)) |tok| {
269 if (type.specifier != .None)
317 if (type_spec.spec != .None)
270318 break :blk;
271 type.specifier = .{
319 type_spec.spec = .{
272320 .Float = .{
273321 .float = tok,
274322 },
275323 };
276324 return true;
277 } else if (parser.eatToken(.Keyword_double)) |tok| {
278 if (type.specifier != .None)
325 } else if (parser.eatToken(.Keyword_double)) |tok| {
326 if (type_spec.spec != .None)
279327 break :blk;
280 type.specifier = .{
328 type_spec.spec = .{
281329 .Double = .{
282330 .double = tok,
283331 },
284332 };
285333 return true;
286 } else if (parser.eatToken(.Keyword_complex)) |tok| {
287 switch (type.specifier) {
334 } else if (parser.eatToken(.Keyword_complex)) |tok| {
335 switch (type_spec.spec) {
288336 .None => {
289 type.specifier = .{
337 type_spec.spec = .{
290338 .Double = .{
291339 .complex = tok,
292 .double = null
340 .double = null,
293341 },
294342 };
295343 },
......@@ -306,40 +354,41 @@ const Parser = struct {
306354 else => break :blk,
307355 }
308356 return true;
309 } if (parser.eatToken(.Keyword_bool)) |tok| {
310 if (type.specifier != .None)
357 }
358 if (parser.eatToken(.Keyword_bool)) |tok| {
359 if (type_spec.spec != .None)
311360 break :blk;
312 type.specifier = .{ .Bool = tok };
361 type_spec.spec = .{ .Bool = tok };
313362 return true;
314363 } else if (parser.eatToken(.Keyword_atomic)) |tok| {
315 if (type.specifier != .None)
364 if (type_spec.spec != .None)
316365 break :blk;
317366 _ = try parser.expectToken(.LParen);
318367 const name = try parser.expect(typeName, .{
319 .ExpectedTypeName = .{ .tok = it.index },
368 .ExpectedTypeName = .{ .token = parser.it.index },
320369 });
321 type.specifier.Atomic = .{
370 type_spec.spec.Atomic = .{
322371 .atomic = tok,
323372 .typename = name,
324373 .rparen = try parser.expectToken(.RParen),
325374 };
326375 return true;
327376 } else if (parser.eatToken(.Keyword_enum)) |tok| {
328 if (type.specifier != .None)
377 if (type_spec.spec != .None)
329378 break :blk;
330379 @panic("TODO enum type");
331380 // return true;
332381 } else if (parser.eatToken(.Keyword_union) orelse parser.eatToken(.Keyword_struct)) |tok| {
333 if (type.specifier != .None)
382 if (type_spec.spec != .None)
334383 break :blk;
335384 @panic("TODO record type");
336385 // return true;
337386 } else if (parser.eatToken(.Identifier)) |tok| {
338 if (!parser.typedefs.contains(tok)) {
387 if (!parser.isTypedef(tok)) {
339388 parser.putBackToken(tok);
340389 return false;
341390 }
342 type.specifier = .{
391 type_spec.spec = .{
343392 .Typedef = tok,
344393 };
345394 return true;
......@@ -348,44 +397,81 @@ const Parser = struct {
348397 try parser.tree.errors.push(.{
349398 .InvalidTypeSpecifier = .{
350399 .token = parser.it.index,
351 .type = type,
400 .type_spec = type_spec,
352401 },
353402 });
354403 return error.ParseError;
355404 }
356405
357 /// TypeQualifier <- Keyword_const / Keyword_restrict / Keyword_volatile / Keyword_atomic
358 fn typeQualifier(parser: *Parser, qualifiers: *Node.Qualifiers) !bool {
359 if (parser.eatToken(.Keyword_const)) |tok| {
360 if (qualifiers.@"const" != null)
361 return parser.warning(.{
362 .DuplicateQualifier = .{ .token = tok },
363 });
364 qualifiers.@"const" = tok;
365 } else if (parser.eatToken(.Keyword_restrict)) |tok| {
366 if (qualifiers.atomic != null)
367 return parser.warning(.{
368 .DuplicateQualifier = .{ .token = tok },
369 });
370 qualifiers.atomic = tok;
371 } else if (parser.eatToken(.Keyword_volatile)) |tok| {
372 if (qualifiers.@"volatile" != null)
373 return parser.warning(.{
374 .DuplicateQualifier = .{ .token = tok },
375 });
376 qualifiers.@"volatile" = tok;
377 } else if (parser.eatToken(.Keyword_atomic)) |tok| {
378 if (qualifiers.atomic != null)
379 return parser.warning(.{
380 .DuplicateQualifier = .{ .token = tok },
381 });
382 qualifiers.atomic = tok;
383 } else return false;
406 /// TypeQual <- Keyword_const / Keyword_restrict / Keyword_volatile / Keyword_atomic
407 fn typeQual(parser: *Parser, qual: *Node.TypeQual) !bool {
408 blk: {
409 if (parser.eatToken(.Keyword_const)) |tok| {
410 if (qual.@"const" != null)
411 break :blk;
412 qual.@"const" = tok;
413 } else if (parser.eatToken(.Keyword_restrict)) |tok| {
414 if (qual.atomic != null)
415 break :blk;
416 qual.atomic = tok;
417 } else if (parser.eatToken(.Keyword_volatile)) |tok| {
418 if (qual.@"volatile" != null)
419 break :blk;
420 qual.@"volatile" = tok;
421 } else if (parser.eatToken(.Keyword_atomic)) |tok| {
422 if (qual.atomic != null)
423 break :blk;
424 qual.atomic = tok;
425 } else return false;
426 return true;
427 }
428 try parser.warning(.{
429 .DuplicateQualifier = .{ .token = parser.it.index },
430 });
431 return true;
432 }
433
434 /// FnSpec <- Keyword_inline / Keyword_noreturn
435 fn fnSpec(parser: *Parser, ds: *Node.DeclSpec) !bool {
436 blk: {
437 if (parser.eatToken(.Keyword_inline)) |tok| {
438 if (ds.fn_spec != .None)
439 break :blk;
440 ds.fn_spec = .{ .Inline = tok };
441 } else if (parser.eatToken(.Keyword_noreturn)) |tok| {
442 if (ds.fn_spec != .None)
443 break :blk;
444 ds.fn_spec = .{ .Noreturn = tok };
445 } else return false;
446 return true;
447 }
448 try parser.warning(.{
449 .DuplicateSpecifier = .{ .token = parser.it.index },
450 });
384451 return true;
385452 }
386453
387 /// FunctionSpecifier <- Keyword_inline / Keyword_noreturn
388 fn functionSpecifier(parser: *Parser) !*Node {}
454 /// AlignSpec <- Keyword_alignas LPAREN (TypeName / ConstExpr) RPAREN
455 fn alignSpec(parser: *Parser, ds: *Node.DeclSpec) !bool {
456 if (parser.eatToken(.Keyword_alignas)) |tok| {
457 _ = try parser.expectToken(.LParen);
458 const node = (try parser.typeName()) orelse (try parser.expect(conditionalExpr, .{
459 .ExpectedExpr = .{ .token = parser.it.index },
460 }));
461 if (ds.align_spec != null) {
462 try parser.warning(.{
463 .DuplicateSpecifier = .{ .token = parser.it.index },
464 });
465 }
466 ds.align_spec = .{
467 .alignas = tok,
468 .expr = node,
469 .rparen = try parser.expectToken(.RParen),
470 };
471 return true;
472 }
473 return false;
474 }
389475
390476 /// EnumSpecifier <- Keyword_enum IDENTIFIER? (LBRACE EnumField RBRACE)?
391477 fn enumSpecifier(parser: *Parser) !*Node {}
......@@ -397,13 +483,13 @@ const Parser = struct {
397483 fn recordSpecifier(parser: *Parser) !*Node {}
398484
399485 /// RecordField
400 /// <- Type* (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON
401 /// \ StaticAssertDeclaration
486 /// <- TypeSpec* (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON
487 /// \ StaticAssert
402488 fn recordField(parser: *Parser) !*Node {}
403489
404490 /// TypeName
405 /// <- Type* AbstractDeclarator?
406 fn typeName(parser: *Parser) !*Node {}
491 /// <- TypeSpec* AbstractDeclarator?
492 fn typeName(parser: *Parser) !*Node {
407493
408494 /// RecordDeclarator <- Declarator? (COLON ConstExpr)?
409495 fn recordDeclarator(parser: *Parser) !*Node {}
......@@ -411,7 +497,7 @@ const Parser = struct {
411497 /// Declarator <- Pointer? DirectDeclarator
412498 fn declarator(parser: *Parser) !*Node {}
413499
414 /// Pointer <- ASTERISK TypeQualifier* Pointer?
500 /// Pointer <- ASTERISK TypeQual* Pointer?
415501 fn pointer(parser: *Parser) !*Node {}
416502
417503 /// DirectDeclarator
......@@ -422,13 +508,13 @@ const Parser = struct {
422508 fn directDeclarator(parser: *Parser) !*Node {}
423509
424510 /// BracketDeclarator
425 /// <- Keyword_static TypeQualifier* AssignmentExpr
426 /// / TypeQualifier+ (ASTERISK / Keyword_static AssignmentExpr)
427 /// / TypeQualifier+ AssignmentExpr?
511 /// <- Keyword_static TypeQual* AssignmentExpr
512 /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr)
513 /// / TypeQual+ AssignmentExpr?
428514 /// / AssignmentExpr
429515 fn bracketDeclarator(parser: *Parser) !*Node {}
430516
431 /// ParamDecl <- DeclarationSpecifiers (Declarator / AbstractDeclarator)
517 /// ParamDecl <- DeclSpec (Declarator / AbstractDeclarator)
432518 fn paramDecl(parser: *Parser) !*Node {}
433519
434520 /// AbstractDeclarator <- Pointer? DirectAbstractDeclarator?
......@@ -647,25 +733,25 @@ const Parser = struct {
647733 return &node.base;
648734 }
649735
650 fn eatToken(parser: *Parser, id: Token.Id) ?TokenIndex {
736 fn eatToken(parser: *Parser, id: @TagType(Token.Id)) ?TokenIndex {
651737 while (true) {
652738 const next_tok = parser.it.next() orelse return null;
653739 if (next_tok.id != .LineComment and next_tok.id != .MultiLineComment) {
654740 if (next_tok.id == id) {
655741 return parser.it.index;
656742 }
657 parser.it.prev();
743 _ = parser.it.prev();
658744 return null;
659745 }
660746 }
661747 }
662748
663 fn expectToken(parser: *Parser, id: Token.Id) Error!TokenIndex {
749 fn expectToken(parser: *Parser, id: @TagType(Token.Id)) Error!TokenIndex {
664750 while (true) {
665751 const next_tok = parser.it.next() orelse return error.ParseError;
666752 if (next_tok.id != .LineComment and next_tok.id != .MultiLineComment) {
667753 if (next_tok.id != id) {
668 try tree.errors.push(.{
754 try parser.tree.errors.push(.{
669755 .ExpectedToken = .{ .token = parser.it.index, .expected_id = id },
670756 });
671757 return error.ParseError;
......@@ -678,7 +764,7 @@ const Parser = struct {
678764 fn putBackToken(parser: *Parser, putting_back: TokenIndex) void {
679765 while (true) {
680766 const prev_tok = parser.it.prev() orelse return;
681 if (next_tok.id == .LineComment or next_tok.id == .MultiLineComment) continue;
767 if (prev_tok.id == .LineComment or prev_tok.id == .MultiLineComment) continue;
682768 assert(parser.it.list.at(putting_back) == prev_tok);
683769 return;
684770 }
......@@ -689,14 +775,17 @@ const Parser = struct {
689775 parseFn: fn (*Parser) Error!?*Node,
690776 err: ast.Error, // if parsing fails
691777 ) Error!*Node {
692 return (try parseFn(arena, it, tree)) orelse {
778 return (try parseFn(parser)) orelse {
693779 try parser.tree.errors.push(err);
694780 return error.ParseError;
695781 };
696782 }
697783
698 fn warning(parser: *Parser, err: ast.Error) Error {
699 // if (parser.warnaserror)
784 fn warning(parser: *Parser, err: ast.Error) Error!void {
785 if (parser.tree.warnings) |*w| {
786 try w.push(err);
787 return;
788 }
700789 try parser.tree.errors.push(err);
701790 return error.ParseError;
702791 }
lib/std/c/tokenizer.zig+6-2
......@@ -135,8 +135,8 @@ pub const Token = struct {
135135 Keyword_error,
136136 Keyword_pragma,
137137
138 pub fn symbol(tok: Token) []const u8 {
139 return switch (tok.id) {
138 pub fn symbol(id: @TagType(Id)) []const u8 {
139 return switch (id) {
140140 .Invalid => "Invalid",
141141 .Eof => "Eof",
142142 .Nl => "NewLine",
......@@ -347,6 +347,10 @@ pub const Token = struct {
347347 return null;
348348 }
349349
350 pub fn slice(tok: Token) []const u8 {
351 return tok.source.buffer[tok.start..tok.end];
352 }
353
350354 pub const NumSuffix = enum {
351355 None,
352356 F,