authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-04 10:26:01-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-04 10:26:44-07:00
log785a6c1aa9a7979a962db9d741a53897c423cb92
treeba871a0dedbb34ae2957c712b400c15f5809b33e
parent96556ce8b885c9c56e24f26a65b6234eb8b102be

std: remove dead and rotting C parsing code


3 files changed, 0 insertions(+), 2117 deletions(-)

lib/std/c.zig-2
......@@ -10,8 +10,6 @@ const page_size = std.mem.page_size;
1010pub const tokenizer = @import("c/tokenizer.zig");
1111pub const Token = tokenizer.Token;
1212pub const Tokenizer = tokenizer.Tokenizer;
13pub const parse = @import("c/parse.zig").parse;
14pub const ast = @import("c/ast.zig");
1513pub const builtins = @import("c/builtins.zig");
1614
1715test {
lib/std/c/ast.zig deleted-681
......@@ -1,681 +0,0 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2021 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6const std = @import("std");
7const ArrayList = std.ArrayList;
8const Token = std.c.Token;
9const Source = std.c.tokenizer.Source;
10
11pub const TokenIndex = usize;
12
13pub const Tree = struct {
14 tokens: []Token,
15 sources: []Source,
16 root_node: *Node.Root,
17 arena_state: std.heap.ArenaAllocator.State,
18 gpa: *mem.Allocator,
19 msgs: []Msg,
20
21 pub fn deinit(self: *Tree) void {
22 self.arena_state.promote(self.gpa).deinit();
23 }
24
25 pub fn tokenSlice(tree: *Tree, token: TokenIndex) []const u8 {
26 return tree.tokens.at(token).slice();
27 }
28
29 pub fn tokenEql(tree: *Tree, a: TokenIndex, b: TokenIndex) bool {
30 const atok = tree.tokens.at(a);
31 const btok = tree.tokens.at(b);
32 return atok.eql(btok.*);
33 }
34};
35
36pub const Msg = struct {
37 kind: enum {
38 Error,
39 Warning,
40 Note,
41 },
42 inner: Error,
43};
44
45pub const Error = union(enum) {
46 InvalidToken: SingleTokenError("invalid token '{}'"),
47 ExpectedToken: ExpectedToken,
48 ExpectedExpr: SingleTokenError("expected expression, found '{}'"),
49 ExpectedTypeName: SingleTokenError("expected type name, found '{}'"),
50 ExpectedFnBody: SingleTokenError("expected function body, found '{}'"),
51 ExpectedDeclarator: SingleTokenError("expected declarator, found '{}'"),
52 ExpectedInitializer: SingleTokenError("expected initializer, found '{}'"),
53 ExpectedEnumField: SingleTokenError("expected enum field, found '{}'"),
54 ExpectedType: SingleTokenError("expected enum field, found '{}'"),
55 InvalidTypeSpecifier: InvalidTypeSpecifier,
56 InvalidStorageClass: SingleTokenError("invalid storage class, found '{}'"),
57 InvalidDeclarator: SimpleError("invalid declarator"),
58 DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"),
59 DuplicateSpecifier: SingleTokenError("duplicate declaration specifier '{}'"),
60 MustUseKwToRefer: MustUseKwToRefer,
61 FnSpecOnNonFn: SingleTokenError("function specifier '{}' on non function"),
62 NothingDeclared: SimpleError("declaration doesn't declare anything"),
63 QualifierIgnored: SingleTokenError("qualifier '{}' ignored"),
64
65 pub fn render(self: *const Error, tree: *Tree, stream: anytype) !void {
66 switch (self.*) {
67 .InvalidToken => |*x| return x.render(tree, stream),
68 .ExpectedToken => |*x| return x.render(tree, stream),
69 .ExpectedExpr => |*x| return x.render(tree, stream),
70 .ExpectedTypeName => |*x| return x.render(tree, stream),
71 .ExpectedDeclarator => |*x| return x.render(tree, stream),
72 .ExpectedFnBody => |*x| return x.render(tree, stream),
73 .ExpectedInitializer => |*x| return x.render(tree, stream),
74 .ExpectedEnumField => |*x| return x.render(tree, stream),
75 .ExpectedType => |*x| return x.render(tree, stream),
76 .InvalidTypeSpecifier => |*x| return x.render(tree, stream),
77 .InvalidStorageClass => |*x| return x.render(tree, stream),
78 .InvalidDeclarator => |*x| return x.render(tree, stream),
79 .DuplicateQualifier => |*x| return x.render(tree, stream),
80 .DuplicateSpecifier => |*x| return x.render(tree, stream),
81 .MustUseKwToRefer => |*x| return x.render(tree, stream),
82 .FnSpecOnNonFn => |*x| return x.render(tree, stream),
83 .NothingDeclared => |*x| return x.render(tree, stream),
84 .QualifierIgnored => |*x| return x.render(tree, stream),
85 }
86 }
87
88 pub fn loc(self: *const Error) TokenIndex {
89 switch (self.*) {
90 .InvalidToken => |x| return x.token,
91 .ExpectedToken => |x| return x.token,
92 .ExpectedExpr => |x| return x.token,
93 .ExpectedTypeName => |x| return x.token,
94 .ExpectedDeclarator => |x| return x.token,
95 .ExpectedFnBody => |x| return x.token,
96 .ExpectedInitializer => |x| return x.token,
97 .ExpectedEnumField => |x| return x.token,
98 .ExpectedType => |*x| return x.token,
99 .InvalidTypeSpecifier => |x| return x.token,
100 .InvalidStorageClass => |x| return x.token,
101 .InvalidDeclarator => |x| return x.token,
102 .DuplicateQualifier => |x| return x.token,
103 .DuplicateSpecifier => |x| return x.token,
104 .MustUseKwToRefer => |*x| return x.name,
105 .FnSpecOnNonFn => |*x| return x.name,
106 .NothingDeclared => |*x| return x.name,
107 .QualifierIgnored => |*x| return x.name,
108 }
109 }
110
111 pub const ExpectedToken = struct {
112 token: TokenIndex,
113 expected_id: std.meta.Tag(Token.Id),
114
115 pub fn render(self: *const ExpectedToken, tree: *Tree, stream: anytype) !void {
116 const found_token = tree.tokens.at(self.token);
117 if (found_token.id == .Invalid) {
118 return stream.print("expected '{s}', found invalid bytes", .{self.expected_id.symbol()});
119 } else {
120 const token_name = found_token.id.symbol();
121 return stream.print("expected '{s}', found '{s}'", .{ self.expected_id.symbol(), token_name });
122 }
123 }
124 };
125
126 pub const InvalidTypeSpecifier = struct {
127 token: TokenIndex,
128 type_spec: *Node.TypeSpec,
129
130 pub fn render(self: *const ExpectedToken, tree: *Tree, stream: anytype) !void {
131 try stream.write("invalid type specifier '");
132 try type_spec.spec.print(tree, stream);
133 const token_name = tree.tokens.at(self.token).id.symbol();
134 return stream.print("{s}'", .{token_name});
135 }
136 };
137
138 pub const MustUseKwToRefer = struct {
139 kw: TokenIndex,
140 name: TokenIndex,
141
142 pub fn render(self: *const ExpectedToken, tree: *Tree, stream: anytype) !void {
143 return stream.print("must use '{s}' tag to refer to type '{s}'", .{ tree.slice(kw), tree.slice(name) });
144 }
145 };
146
147 fn SingleTokenError(comptime msg: []const u8) type {
148 return struct {
149 token: TokenIndex,
150
151 pub fn render(self: *const @This(), tree: *Tree, stream: anytype) !void {
152 const actual_token = tree.tokens.at(self.token);
153 return stream.print(msg, .{actual_token.id.symbol()});
154 }
155 };
156 }
157
158 fn SimpleError(comptime msg: []const u8) type {
159 return struct {
160 const ThisError = @This();
161
162 token: TokenIndex,
163
164 pub fn render(self: *const ThisError, tokens: *Tree.TokenList, stream: anytype) !void {
165 return stream.write(msg);
166 }
167 };
168 }
169};
170
171pub const Type = struct {
172 pub const TypeList = ArrayList(*Type);
173
174 @"const": bool = false,
175 atomic: bool = false,
176 @"volatile": bool = false,
177 restrict: bool = false,
178
179 id: union(enum) {
180 Int: struct {
181 id: Id,
182 is_signed: bool,
183
184 pub const Id = enum {
185 Char,
186 Short,
187 Int,
188 Long,
189 LongLong,
190 };
191 },
192 Float: struct {
193 id: Id,
194
195 pub const Id = enum {
196 Float,
197 Double,
198 LongDouble,
199 };
200 },
201 Pointer: *Type,
202 Function: struct {
203 return_type: *Type,
204 param_types: TypeList,
205 },
206 Typedef: *Type,
207 Record: *Node.RecordType,
208 Enum: *Node.EnumType,
209
210 /// Special case for macro parameters that can be any type.
211 /// Only present if `retain_macros == true`.
212 Macro,
213 },
214};
215
216pub const Node = struct {
217 id: Id,
218
219 pub const Id = enum {
220 Root,
221 EnumField,
222 RecordField,
223 RecordDeclarator,
224 JumpStmt,
225 ExprStmt,
226 LabeledStmt,
227 CompoundStmt,
228 IfStmt,
229 SwitchStmt,
230 WhileStmt,
231 DoStmt,
232 ForStmt,
233 StaticAssert,
234 Declarator,
235 Pointer,
236 FnDecl,
237 Typedef,
238 VarDecl,
239 };
240
241 pub const Root = struct {
242 base: Node = Node{ .id = .Root },
243 decls: DeclList,
244 eof: TokenIndex,
245
246 pub const DeclList = ArrayList(*Node);
247 };
248
249 pub const DeclSpec = struct {
250 storage_class: union(enum) {
251 Auto: TokenIndex,
252 Extern: TokenIndex,
253 Register: TokenIndex,
254 Static: TokenIndex,
255 Typedef: TokenIndex,
256 None,
257 } = .None,
258 thread_local: ?TokenIndex = null,
259 type_spec: TypeSpec = TypeSpec{},
260 fn_spec: union(enum) {
261 Inline: TokenIndex,
262 Noreturn: TokenIndex,
263 None,
264 } = .None,
265 align_spec: ?struct {
266 alignas: TokenIndex,
267 expr: *Node,
268 rparen: TokenIndex,
269 } = null,
270 };
271
272 pub const TypeSpec = struct {
273 qual: TypeQual = TypeQual{},
274 spec: union(enum) {
275 /// error or default to int
276 None,
277 Void: TokenIndex,
278 Char: struct {
279 sign: ?TokenIndex = null,
280 char: TokenIndex,
281 },
282 Short: struct {
283 sign: ?TokenIndex = null,
284 short: TokenIndex = null,
285 int: ?TokenIndex = null,
286 },
287 Int: struct {
288 sign: ?TokenIndex = null,
289 int: ?TokenIndex = null,
290 },
291 Long: struct {
292 sign: ?TokenIndex = null,
293 long: TokenIndex,
294 longlong: ?TokenIndex = null,
295 int: ?TokenIndex = null,
296 },
297 Float: struct {
298 float: TokenIndex,
299 complex: ?TokenIndex = null,
300 },
301 Double: struct {
302 long: ?TokenIndex = null,
303 double: ?TokenIndex,
304 complex: ?TokenIndex = null,
305 },
306 Bool: TokenIndex,
307 Atomic: struct {
308 atomic: TokenIndex,
309 typename: *Node,
310 rparen: TokenIndex,
311 },
312 Enum: *EnumType,
313 Record: *RecordType,
314 Typedef: struct {
315 sym: TokenIndex,
316 sym_type: *Type,
317 },
318
319 pub fn print(self: *@This(), self: *const @This(), tree: *Tree, stream: anytype) !void {
320 switch (self.spec) {
321 .None => unreachable,
322 .Void => |index| try stream.write(tree.slice(index)),
323 .Char => |char| {
324 if (char.sign) |s| {
325 try stream.write(tree.slice(s));
326 try stream.writeByte(' ');
327 }
328 try stream.write(tree.slice(char.char));
329 },
330 .Short => |short| {
331 if (short.sign) |s| {
332 try stream.write(tree.slice(s));
333 try stream.writeByte(' ');
334 }
335 try stream.write(tree.slice(short.short));
336 if (short.int) |i| {
337 try stream.writeByte(' ');
338 try stream.write(tree.slice(i));
339 }
340 },
341 .Int => |int| {
342 if (int.sign) |s| {
343 try stream.write(tree.slice(s));
344 try stream.writeByte(' ');
345 }
346 if (int.int) |i| {
347 try stream.writeByte(' ');
348 try stream.write(tree.slice(i));
349 }
350 },
351 .Long => |long| {
352 if (long.sign) |s| {
353 try stream.write(tree.slice(s));
354 try stream.writeByte(' ');
355 }
356 try stream.write(tree.slice(long.long));
357 if (long.longlong) |l| {
358 try stream.writeByte(' ');
359 try stream.write(tree.slice(l));
360 }
361 if (long.int) |i| {
362 try stream.writeByte(' ');
363 try stream.write(tree.slice(i));
364 }
365 },
366 .Float => |float| {
367 try stream.write(tree.slice(float.float));
368 if (float.complex) |c| {
369 try stream.writeByte(' ');
370 try stream.write(tree.slice(c));
371 }
372 },
373 .Double => |double| {
374 if (double.long) |l| {
375 try stream.write(tree.slice(l));
376 try stream.writeByte(' ');
377 }
378 try stream.write(tree.slice(double.double));
379 if (double.complex) |c| {
380 try stream.writeByte(' ');
381 try stream.write(tree.slice(c));
382 }
383 },
384 .Bool => |index| try stream.write(tree.slice(index)),
385 .Typedef => |typedef| try stream.write(tree.slice(typedef.sym)),
386 else => try stream.print("TODO print {}", self.spec),
387 }
388 }
389 } = .None,
390 };
391
392 pub const EnumType = struct {
393 tok: TokenIndex,
394 name: ?TokenIndex,
395 body: ?struct {
396 lbrace: TokenIndex,
397
398 /// always EnumField
399 fields: FieldList,
400 rbrace: TokenIndex,
401 },
402
403 pub const FieldList = Root.DeclList;
404 };
405
406 pub const EnumField = struct {
407 base: Node = Node{ .id = .EnumField },
408 name: TokenIndex,
409 value: ?*Node,
410 };
411
412 pub const RecordType = struct {
413 tok: TokenIndex,
414 kind: enum {
415 Struct,
416 Union,
417 },
418 name: ?TokenIndex,
419 body: ?struct {
420 lbrace: TokenIndex,
421
422 /// RecordField or StaticAssert
423 fields: FieldList,
424 rbrace: TokenIndex,
425 },
426
427 pub const FieldList = Root.DeclList;
428 };
429
430 pub const RecordField = struct {
431 base: Node = Node{ .id = .RecordField },
432 type_spec: TypeSpec,
433 declarators: DeclaratorList,
434 semicolon: TokenIndex,
435
436 pub const DeclaratorList = Root.DeclList;
437 };
438
439 pub const RecordDeclarator = struct {
440 base: Node = Node{ .id = .RecordDeclarator },
441 declarator: ?*Declarator,
442 bit_field_expr: ?*Expr,
443 };
444
445 pub const TypeQual = struct {
446 @"const": ?TokenIndex = null,
447 atomic: ?TokenIndex = null,
448 @"volatile": ?TokenIndex = null,
449 restrict: ?TokenIndex = null,
450 };
451
452 pub const JumpStmt = struct {
453 base: Node = Node{ .id = .JumpStmt },
454 ltoken: TokenIndex,
455 kind: union(enum) {
456 Break,
457 Continue,
458 Return: ?*Node,
459 Goto: TokenIndex,
460 },
461 semicolon: TokenIndex,
462 };
463
464 pub const ExprStmt = struct {
465 base: Node = Node{ .id = .ExprStmt },
466 expr: ?*Expr,
467 semicolon: TokenIndex,
468 };
469
470 pub const LabeledStmt = struct {
471 base: Node = Node{ .id = .LabeledStmt },
472 kind: union(enum) {
473 Label: TokenIndex,
474 Case: TokenIndex,
475 Default: TokenIndex,
476 },
477 stmt: *Node,
478 };
479
480 pub const CompoundStmt = struct {
481 base: Node = Node{ .id = .CompoundStmt },
482 lbrace: TokenIndex,
483 statements: StmtList,
484 rbrace: TokenIndex,
485
486 pub const StmtList = Root.DeclList;
487 };
488
489 pub const IfStmt = struct {
490 base: Node = Node{ .id = .IfStmt },
491 @"if": TokenIndex,
492 cond: *Node,
493 body: *Node,
494 @"else": ?struct {
495 tok: TokenIndex,
496 body: *Node,
497 },
498 };
499
500 pub const SwitchStmt = struct {
501 base: Node = Node{ .id = .SwitchStmt },
502 @"switch": TokenIndex,
503 expr: *Expr,
504 rparen: TokenIndex,
505 stmt: *Node,
506 };
507
508 pub const WhileStmt = struct {
509 base: Node = Node{ .id = .WhileStmt },
510 @"while": TokenIndex,
511 cond: *Expr,
512 rparen: TokenIndex,
513 body: *Node,
514 };
515
516 pub const DoStmt = struct {
517 base: Node = Node{ .id = .DoStmt },
518 do: TokenIndex,
519 body: *Node,
520 @"while": TokenIndex,
521 cond: *Expr,
522 semicolon: TokenIndex,
523 };
524
525 pub const ForStmt = struct {
526 base: Node = Node{ .id = .ForStmt },
527 @"for": TokenIndex,
528 init: ?*Node,
529 cond: ?*Expr,
530 semicolon: TokenIndex,
531 incr: ?*Expr,
532 rparen: TokenIndex,
533 body: *Node,
534 };
535
536 pub const StaticAssert = struct {
537 base: Node = Node{ .id = .StaticAssert },
538 assert: TokenIndex,
539 expr: *Node,
540 semicolon: TokenIndex,
541 };
542
543 pub const Declarator = struct {
544 base: Node = Node{ .id = .Declarator },
545 pointer: ?*Pointer,
546 prefix: union(enum) {
547 None,
548 Identifer: TokenIndex,
549 Complex: struct {
550 lparen: TokenIndex,
551 inner: *Node,
552 rparen: TokenIndex,
553 },
554 },
555 suffix: union(enum) {
556 None,
557 Fn: struct {
558 lparen: TokenIndex,
559 params: Params,
560 rparen: TokenIndex,
561 },
562 Array: Arrays,
563 },
564
565 pub const Arrays = ArrayList(*Array);
566 pub const Params = ArrayList(*Param);
567 };
568
569 pub const Array = struct {
570 lbracket: TokenIndex,
571 inner: union(enum) {
572 Inferred,
573 Unspecified: TokenIndex,
574 Variable: struct {
575 asterisk: ?TokenIndex,
576 static: ?TokenIndex,
577 qual: TypeQual,
578 expr: *Expr,
579 },
580 },
581 rbracket: TokenIndex,
582 };
583
584 pub const Pointer = struct {
585 base: Node = Node{ .id = .Pointer },
586 asterisk: TokenIndex,
587 qual: TypeQual,
588 pointer: ?*Pointer,
589 };
590
591 pub const Param = struct {
592 kind: union(enum) {
593 Variable,
594 Old: TokenIndex,
595 Normal: struct {
596 decl_spec: *DeclSpec,
597 declarator: *Node,
598 },
599 },
600 };
601
602 pub const FnDecl = struct {
603 base: Node = Node{ .id = .FnDecl },
604 decl_spec: DeclSpec,
605 declarator: *Declarator,
606 old_decls: OldDeclList,
607 body: ?*CompoundStmt,
608
609 pub const OldDeclList = ArrayList(*Node);
610 };
611
612 pub const Typedef = struct {
613 base: Node = Node{ .id = .Typedef },
614 decl_spec: DeclSpec,
615 declarators: DeclaratorList,
616 semicolon: TokenIndex,
617
618 pub const DeclaratorList = Root.DeclList;
619 };
620
621 pub const VarDecl = struct {
622 base: Node = Node{ .id = .VarDecl },
623 decl_spec: DeclSpec,
624 initializers: Initializers,
625 semicolon: TokenIndex,
626
627 pub const Initializers = Root.DeclList;
628 };
629
630 pub const Initialized = struct {
631 base: Node = Node{ .id = Initialized },
632 declarator: *Declarator,
633 eq: TokenIndex,
634 init: Initializer,
635 };
636
637 pub const Initializer = union(enum) {
638 list: struct {
639 initializers: List,
640 rbrace: TokenIndex,
641 },
642 expr: *Expr,
643
644 pub const List = ArrayList(*Initializer);
645 };
646
647 pub const Macro = struct {
648 base: Node = Node{ .id = Macro },
649 kind: union(enum) {
650 Undef: []const u8,
651 Fn: struct {
652 params: []const []const u8,
653 expr: *Expr,
654 },
655 Expr: *Expr,
656 },
657 };
658};
659
660pub const Expr = struct {
661 id: Id,
662 ty: *Type,
663 value: union(enum) {
664 None,
665 },
666
667 pub const Id = enum {
668 Infix,
669 Literal,
670 };
671
672 pub const Infix = struct {
673 base: Expr = Expr{ .id = .Infix },
674 lhs: *Expr,
675 op_token: TokenIndex,
676 op: Op,
677 rhs: *Expr,
678
679 pub const Op = enum {};
680 };
681};
lib/std/c/parse.zig deleted-1434
......@@ -1,1434 +0,0 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2021 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6const std = @import("std");
7const mem = std.mem;
8const assert = std.debug.assert;
9const Allocator = std.mem.Allocator;
10const ast = std.c.ast;
11const Node = ast.Node;
12const Type = ast.Type;
13const Tree = ast.Tree;
14const TokenIndex = ast.TokenIndex;
15const Token = std.c.Token;
16const TokenIterator = ast.Tree.TokenList.Iterator;
17
18pub const Error = error{ParseError} || Allocator.Error;
19
20pub const Options = struct {
21 // /// Keep simple macros unexpanded and add the definitions to the ast
22 // retain_macros: bool = false,
23 /// Warning or error
24 warn_as_err: union(enum) {
25 /// All warnings are warnings
26 None,
27
28 /// Some warnings are errors
29 Some: []std.meta.Tag(ast.Error),
30
31 /// All warnings are errors
32 All,
33 } = .All,
34};
35
36/// Result should be freed with tree.deinit() when there are
37/// no more references to any of the tokens or nodes.
38pub fn parse(allocator: *Allocator, source: []const u8, options: Options) !*Tree {
39 const tree = blk: {
40 // This block looks unnecessary, but is a "foot-shield" to prevent the SegmentedLists
41 // from being initialized with a pointer to this `arena`, which is created on
42 // the stack. Following code should instead refer to `&tree.arena_allocator`, a
43 // pointer to data which lives safely on the heap and will outlive `parse`.
44 var arena = std.heap.ArenaAllocator.init(allocator);
45 errdefer arena.deinit();
46 const tree = try arena.allocator.create(ast.Tree);
47 tree.* = .{
48 .root_node = undefined,
49 .arena_allocator = arena,
50 .tokens = undefined,
51 .sources = undefined,
52 };
53 break :blk tree;
54 };
55 errdefer tree.deinit();
56 const arena = &tree.arena_allocator.allocator;
57
58 tree.tokens = ast.Tree.TokenList.init(arena);
59 tree.sources = ast.Tree.SourceList.init(arena);
60
61 var tokenizer = std.zig.Tokenizer.init(source);
62 while (true) {
63 const tree_token = try tree.tokens.addOne();
64 tree_token.* = tokenizer.next();
65 if (tree_token.id == .Eof) break;
66 }
67 // TODO preprocess here
68 var it = tree.tokens.iterator(0);
69
70 while (true) {
71 const tok = it.peek().?.id;
72 switch (id) {
73 .LineComment,
74 .MultiLineComment,
75 => {
76 _ = it.next();
77 },
78 else => break,
79 }
80 }
81
82 var parse_arena = std.heap.ArenaAllocator.init(allocator);
83 defer parse_arena.deinit();
84
85 var parser = Parser{
86 .scopes = Parser.SymbolList.init(allocator),
87 .arena = &parse_arena.allocator,
88 .it = &it,
89 .tree = tree,
90 .options = options,
91 };
92 defer parser.symbols.deinit();
93
94 tree.root_node = try parser.root();
95 return tree;
96}
97
98const Parser = struct {
99 arena: *Allocator,
100 it: *TokenIterator,
101 tree: *Tree,
102
103 arena: *Allocator,
104 scopes: ScopeList,
105 options: Options,
106
107 const ScopeList = std.SegmentedLists(Scope);
108 const SymbolList = std.SegmentedLists(Symbol);
109
110 const Scope = struct {
111 kind: ScopeKind,
112 syms: SymbolList,
113 };
114
115 const Symbol = struct {
116 name: []const u8,
117 ty: *Type,
118 };
119
120 const ScopeKind = enum {
121 Block,
122 Loop,
123 Root,
124 Switch,
125 };
126
127 fn pushScope(parser: *Parser, kind: ScopeKind) !void {
128 const new = try parser.scopes.addOne();
129 new.* = .{
130 .kind = kind,
131 .syms = SymbolList.init(parser.arena),
132 };
133 }
134
135 fn popScope(parser: *Parser, len: usize) void {
136 _ = parser.scopes.pop();
137 }
138
139 fn getSymbol(parser: *Parser, tok: TokenIndex) ?*Symbol {
140 const name = parser.tree.tokenSlice(tok);
141 var scope_it = parser.scopes.iterator(parser.scopes.len);
142 while (scope_it.prev()) |scope| {
143 var sym_it = scope.syms.iterator(scope.syms.len);
144 while (sym_it.prev()) |sym| {
145 if (mem.eql(u8, sym.name, name)) {
146 return sym;
147 }
148 }
149 }
150 return null;
151 }
152
153 fn declareSymbol(parser: *Parser, type_spec: Node.TypeSpec, dr: *Node.Declarator) Error!void {
154 return; // TODO
155 }
156
157 /// Root <- ExternalDeclaration* eof
158 fn root(parser: *Parser) Allocator.Error!*Node.Root {
159 try parser.pushScope(.Root);
160 defer parser.popScope();
161 const node = try parser.arena.create(Node.Root);
162 node.* = .{
163 .decls = Node.Root.DeclList.init(parser.arena),
164 .eof = undefined,
165 };
166 while (parser.externalDeclarations() catch |e| switch (e) {
167 error.OutOfMemory => return error.OutOfMemory,
168 error.ParseError => return node,
169 }) |decl| {
170 try node.decls.push(decl);
171 }
172 node.eof = parser.eatToken(.Eof) orelse return node;
173 return node;
174 }
175
176 /// ExternalDeclaration
177 /// <- DeclSpec Declarator OldStyleDecl* CompoundStmt
178 /// / Declaration
179 /// OldStyleDecl <- DeclSpec Declarator (COMMA Declarator)* SEMICOLON
180 fn externalDeclarations(parser: *Parser) !?*Node {
181 return parser.declarationExtra(false);
182 }
183
184 /// Declaration
185 /// <- DeclSpec DeclInit SEMICOLON
186 /// / StaticAssert
187 /// DeclInit <- Declarator (EQUAL Initializer)? (COMMA Declarator (EQUAL Initializer)?)*
188 fn declaration(parser: *Parser) !?*Node {
189 return parser.declarationExtra(true);
190 }
191
192 fn declarationExtra(parser: *Parser, local: bool) !?*Node {
193 if (try parser.staticAssert()) |decl| return decl;
194 const begin = parser.it.index + 1;
195 var ds = Node.DeclSpec{};
196 const got_ds = try parser.declSpec(&ds);
197 if (local and !got_ds) {
198 // not a declaration
199 return null;
200 }
201 switch (ds.storage_class) {
202 .Auto, .Register => |tok| return parser.err(.{
203 .InvalidStorageClass = .{ .token = tok },
204 }),
205 .Typedef => {
206 const node = try parser.arena.create(Node.Typedef);
207 node.* = .{
208 .decl_spec = ds,
209 .declarators = Node.Typedef.DeclaratorList.init(parser.arena),
210 .semicolon = undefined,
211 };
212 while (true) {
213 const dr = @fieldParentPtr(Node.Declarator, "base", (try parser.declarator(.Must)) orelse return parser.err(.{
214 .ExpectedDeclarator = .{ .token = parser.it.index },
215 }));
216 try parser.declareSymbol(ds.type_spec, dr);
217 try node.declarators.push(&dr.base);
218 if (parser.eatToken(.Comma)) |_| {} else break;
219 }
220 return &node.base;
221 },
222 else => {},
223 }
224 var first_dr = try parser.declarator(.Must);
225 if (first_dr != null and declaratorIsFunction(first_dr.?)) {
226 // TODO typedeffed fn proto-only
227 const dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?);
228 try parser.declareSymbol(ds.type_spec, dr);
229 var old_decls = Node.FnDecl.OldDeclList.init(parser.arena);
230 const body = if (parser.eatToken(.Semicolon)) |_|
231 null
232 else blk: {
233 if (local) {
234 // TODO nested function warning
235 }
236 // TODO first_dr.is_old
237 // while (true) {
238 // var old_ds = Node.DeclSpec{};
239 // if (!(try parser.declSpec(&old_ds))) {
240 // // not old decl
241 // break;
242 // }
243 // var old_dr = (try parser.declarator(.Must));
244 // // if (old_dr == null)
245 // // try parser.err(.{
246 // // .NoParamName = .{ .token = parser.it.index },
247 // // });
248 // // try old_decls.push(decl);
249 // }
250 const body_node = (try parser.compoundStmt()) orelse return parser.err(.{
251 .ExpectedFnBody = .{ .token = parser.it.index },
252 });
253 break :blk @fieldParentPtr(Node.CompoundStmt, "base", body_node);
254 };
255
256 const node = try parser.arena.create(Node.FnDecl);
257 node.* = .{
258 .decl_spec = ds,
259 .declarator = dr,
260 .old_decls = old_decls,
261 .body = body,
262 };
263 return &node.base;
264 } else {
265 switch (ds.fn_spec) {
266 .Inline, .Noreturn => |tok| return parser.err(.{
267 .FnSpecOnNonFn = .{ .token = tok },
268 }),
269 else => {},
270 }
271 // TODO threadlocal without static or extern on local variable
272 const node = try parser.arena.create(Node.VarDecl);
273 node.* = .{
274 .decl_spec = ds,
275 .initializers = Node.VarDecl.Initializers.init(parser.arena),
276 .semicolon = undefined,
277 };
278 if (first_dr == null) {
279 node.semicolon = try parser.expectToken(.Semicolon);
280 const ok = switch (ds.type_spec.spec) {
281 .Enum => |e| e.name != null,
282 .Record => |r| r.name != null,
283 else => false,
284 };
285 const q = ds.type_spec.qual;
286 if (!ok)
287 try parser.warn(.{
288 .NothingDeclared = .{ .token = begin },
289 })
290 else if (q.@"const" orelse q.atomic orelse q.@"volatile" orelse q.restrict) |tok|
291 try parser.warn(.{
292 .QualifierIgnored = .{ .token = tok },
293 });
294 return &node.base;
295 }
296 var dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?);
297 while (true) {
298 try parser.declareSymbol(ds.type_spec, dr);
299 if (parser.eatToken(.Equal)) |tok| {
300 try node.initializers.push((try parser.initializer(dr)) orelse return parser.err(.{
301 .ExpectedInitializer = .{ .token = parser.it.index },
302 }));
303 } else try node.initializers.push(&dr.base);
304 if (parser.eatToken(.Comma) != null) break;
305 dr = @fieldParentPtr(Node.Declarator, "base", (try parser.declarator(.Must)) orelse return parser.err(.{
306 .ExpectedDeclarator = .{ .token = parser.it.index },
307 }));
308 }
309 node.semicolon = try parser.expectToken(.Semicolon);
310 return &node.base;
311 }
312 }
313
314 fn declaratorIsFunction(node: *Node) bool {
315 if (node.id != .Declarator) return false;
316 assert(node.id == .Declarator);
317 const dr = @fieldParentPtr(Node.Declarator, "base", node);
318 if (dr.suffix != .Fn) return false;
319 switch (dr.prefix) {
320 .None, .Identifer => return true,
321 .Complex => |inner| {
322 var inner_node = inner.inner;
323 while (true) {
324 if (inner_node.id != .Declarator) return false;
325 assert(inner_node.id == .Declarator);
326 const inner_dr = @fieldParentPtr(Node.Declarator, "base", inner_node);
327 if (inner_dr.pointer != null) return false;
328 switch (inner_dr.prefix) {
329 .None, .Identifer => return true,
330 .Complex => |c| inner_node = c.inner,
331 }
332 }
333 },
334 }
335 }
336
337 /// StaticAssert <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
338 fn staticAssert(parser: *Parser) !?*Node {
339 const tok = parser.eatToken(.Keyword_static_assert) orelse return null;
340 _ = try parser.expectToken(.LParen);
341 const const_expr = (try parser.constExpr()) orelse parser.err(.{
342 .ExpectedExpr = .{ .token = parser.it.index },
343 });
344 _ = try parser.expectToken(.Comma);
345 const str = try parser.expectToken(.StringLiteral);
346 _ = try parser.expectToken(.RParen);
347 const node = try parser.arena.create(Node.StaticAssert);
348 node.* = .{
349 .assert = tok,
350 .expr = const_expr,
351 .semicolon = try parser.expectToken(.Semicolon),
352 };
353 return &node.base;
354 }
355
356 /// DeclSpec <- (StorageClassSpec / TypeSpec / FnSpec / AlignSpec)*
357 /// returns true if any tokens were consumed
358 fn declSpec(parser: *Parser, ds: *Node.DeclSpec) !bool {
359 var got = false;
360 while ((try parser.storageClassSpec(ds)) or (try parser.typeSpec(&ds.type_spec)) or (try parser.fnSpec(ds)) or (try parser.alignSpec(ds))) {
361 got = true;
362 }
363 return got;
364 }
365
366 /// StorageClassSpec
367 /// <- Keyword_typedef / Keyword_extern / Keyword_static / Keyword_thread_local / Keyword_auto / Keyword_register
368 fn storageClassSpec(parser: *Parser, ds: *Node.DeclSpec) !bool {
369 blk: {
370 if (parser.eatToken(.Keyword_typedef)) |tok| {
371 if (ds.storage_class != .None or ds.thread_local != null)
372 break :blk;
373 ds.storage_class = .{ .Typedef = tok };
374 } else if (parser.eatToken(.Keyword_extern)) |tok| {
375 if (ds.storage_class != .None)
376 break :blk;
377 ds.storage_class = .{ .Extern = tok };
378 } else if (parser.eatToken(.Keyword_static)) |tok| {
379 if (ds.storage_class != .None)
380 break :blk;
381 ds.storage_class = .{ .Static = tok };
382 } else if (parser.eatToken(.Keyword_thread_local)) |tok| {
383 switch (ds.storage_class) {
384 .None, .Extern, .Static => {},
385 else => break :blk,
386 }
387 ds.thread_local = tok;
388 } else if (parser.eatToken(.Keyword_auto)) |tok| {
389 if (ds.storage_class != .None or ds.thread_local != null)
390 break :blk;
391 ds.storage_class = .{ .Auto = tok };
392 } else if (parser.eatToken(.Keyword_register)) |tok| {
393 if (ds.storage_class != .None or ds.thread_local != null)
394 break :blk;
395 ds.storage_class = .{ .Register = tok };
396 } else return false;
397 return true;
398 }
399 try parser.warn(.{
400 .DuplicateSpecifier = .{ .token = parser.it.index },
401 });
402 return true;
403 }
404
405 /// TypeSpec
406 /// <- Keyword_void / Keyword_char / Keyword_short / Keyword_int / Keyword_long / Keyword_float / Keyword_double
407 /// / Keyword_signed / Keyword_unsigned / Keyword_bool / Keyword_complex / Keyword_imaginary /
408 /// / Keyword_atomic LPAREN TypeName RPAREN
409 /// / EnumSpec
410 /// / RecordSpec
411 /// / IDENTIFIER // typedef name
412 /// / TypeQual
413 fn typeSpec(parser: *Parser, type_spec: *Node.TypeSpec) !bool {
414 blk: {
415 if (parser.eatToken(.Keyword_void)) |tok| {
416 if (type_spec.spec != .None)
417 break :blk;
418 type_spec.spec = .{ .Void = tok };
419 } else if (parser.eatToken(.Keyword_char)) |tok| {
420 switch (type_spec.spec) {
421 .None => {
422 type_spec.spec = .{
423 .Char = .{
424 .char = tok,
425 },
426 };
427 },
428 .Int => |int| {
429 if (int.int != null)
430 break :blk;
431 type_spec.spec = .{
432 .Char = .{
433 .char = tok,
434 .sign = int.sign,
435 },
436 };
437 },
438 else => break :blk,
439 }
440 } else if (parser.eatToken(.Keyword_short)) |tok| {
441 switch (type_spec.spec) {
442 .None => {
443 type_spec.spec = .{
444 .Short = .{
445 .short = tok,
446 },
447 };
448 },
449 .Int => |int| {
450 if (int.int != null)
451 break :blk;
452 type_spec.spec = .{
453 .Short = .{
454 .short = tok,
455 .sign = int.sign,
456 },
457 };
458 },
459 else => break :blk,
460 }
461 } else if (parser.eatToken(.Keyword_long)) |tok| {
462 switch (type_spec.spec) {
463 .None => {
464 type_spec.spec = .{
465 .Long = .{
466 .long = tok,
467 },
468 };
469 },
470 .Int => |int| {
471 type_spec.spec = .{
472 .Long = .{
473 .long = tok,
474 .sign = int.sign,
475 .int = int.int,
476 },
477 };
478 },
479 .Long => |*long| {
480 if (long.longlong != null)
481 break :blk;
482 long.longlong = tok;
483 },
484 .Double => |*double| {
485 if (double.long != null)
486 break :blk;
487 double.long = tok;
488 },
489 else => break :blk,
490 }
491 } else if (parser.eatToken(.Keyword_int)) |tok| {
492 switch (type_spec.spec) {
493 .None => {
494 type_spec.spec = .{
495 .Int = .{
496 .int = tok,
497 },
498 };
499 },
500 .Short => |*short| {
501 if (short.int != null)
502 break :blk;
503 short.int = tok;
504 },
505 .Int => |*int| {
506 if (int.int != null)
507 break :blk;
508 int.int = tok;
509 },
510 .Long => |*long| {
511 if (long.int != null)
512 break :blk;
513 long.int = tok;
514 },
515 else => break :blk,
516 }
517 } else if (parser.eatToken(.Keyword_signed) orelse parser.eatToken(.Keyword_unsigned)) |tok| {
518 switch (type_spec.spec) {
519 .None => {
520 type_spec.spec = .{
521 .Int = .{
522 .sign = tok,
523 },
524 };
525 },
526 .Char => |*char| {
527 if (char.sign != null)
528 break :blk;
529 char.sign = tok;
530 },
531 .Short => |*short| {
532 if (short.sign != null)
533 break :blk;
534 short.sign = tok;
535 },
536 .Int => |*int| {
537 if (int.sign != null)
538 break :blk;
539 int.sign = tok;
540 },
541 .Long => |*long| {
542 if (long.sign != null)
543 break :blk;
544 long.sign = tok;
545 },
546 else => break :blk,
547 }
548 } else if (parser.eatToken(.Keyword_float)) |tok| {
549 if (type_spec.spec != .None)
550 break :blk;
551 type_spec.spec = .{
552 .Float = .{
553 .float = tok,
554 },
555 };
556 } else if (parser.eatToken(.Keyword_double)) |tok| {
557 if (type_spec.spec != .None)
558 break :blk;
559 type_spec.spec = .{
560 .Double = .{
561 .double = tok,
562 },
563 };
564 } else if (parser.eatToken(.Keyword_complex)) |tok| {
565 switch (type_spec.spec) {
566 .None => {
567 type_spec.spec = .{
568 .Double = .{
569 .complex = tok,
570 .double = null,
571 },
572 };
573 },
574 .Float => |*float| {
575 if (float.complex != null)
576 break :blk;
577 float.complex = tok;
578 },
579 .Double => |*double| {
580 if (double.complex != null)
581 break :blk;
582 double.complex = tok;
583 },
584 else => break :blk,
585 }
586 } else if (parser.eatToken(.Keyword_bool)) |tok| {
587 if (type_spec.spec != .None)
588 break :blk;
589 type_spec.spec = .{ .Bool = tok };
590 } else if (parser.eatToken(.Keyword_atomic)) |tok| {
591 // might be _Atomic qualifier
592 if (parser.eatToken(.LParen)) |_| {
593 if (type_spec.spec != .None)
594 break :blk;
595 const name = (try parser.typeName()) orelse return parser.err(.{
596 .ExpectedTypeName = .{ .token = parser.it.index },
597 });
598 type_spec.spec.Atomic = .{
599 .atomic = tok,
600 .typename = name,
601 .rparen = try parser.expectToken(.RParen),
602 };
603 } else {
604 parser.putBackToken(tok);
605 }
606 } else if (parser.eatToken(.Keyword_enum)) |tok| {
607 if (type_spec.spec != .None)
608 break :blk;
609 type_spec.spec.Enum = try parser.enumSpec(tok);
610 } else if (parser.eatToken(.Keyword_union) orelse parser.eatToken(.Keyword_struct)) |tok| {
611 if (type_spec.spec != .None)
612 break :blk;
613 type_spec.spec.Record = try parser.recordSpec(tok);
614 } else if (parser.eatToken(.Identifier)) |tok| {
615 const ty = parser.getSymbol(tok) orelse {
616 parser.putBackToken(tok);
617 return false;
618 };
619 switch (ty.id) {
620 .Enum => |e| blk: {
621 if (e.name) |some|
622 if (!parser.tree.tokenEql(some, tok))
623 break :blk;
624 return parser.err(.{
625 .MustUseKwToRefer = .{ .kw = e.tok, .name = tok },
626 });
627 },
628 .Record => |r| blk: {
629 if (r.name) |some|
630 if (!parser.tree.tokenEql(some, tok))
631 break :blk;
632 return parser.err(.{
633 .MustUseKwToRefer = .{
634 .kw = r.tok,
635 .name = tok,
636 },
637 });
638 },
639 .Typedef => {
640 type_spec.spec = .{
641 .Typedef = .{
642 .sym = tok,
643 .sym_type = ty,
644 },
645 };
646 return true;
647 },
648 else => {},
649 }
650 parser.putBackToken(tok);
651 return false;
652 }
653 return parser.typeQual(&type_spec.qual);
654 }
655 return parser.err(.{
656 .InvalidTypeSpecifier = .{
657 .token = parser.it.index,
658 .type_spec = type_spec,
659 },
660 });
661 }
662
663 /// TypeQual <- Keyword_const / Keyword_restrict / Keyword_volatile / Keyword_atomic
664 fn typeQual(parser: *Parser, qual: *Node.TypeQual) !bool {
665 blk: {
666 if (parser.eatToken(.Keyword_const)) |tok| {
667 if (qual.@"const" != null)
668 break :blk;
669 qual.@"const" = tok;
670 } else if (parser.eatToken(.Keyword_restrict)) |tok| {
671 if (qual.atomic != null)
672 break :blk;
673 qual.atomic = tok;
674 } else if (parser.eatToken(.Keyword_volatile)) |tok| {
675 if (qual.@"volatile" != null)
676 break :blk;
677 qual.@"volatile" = tok;
678 } else if (parser.eatToken(.Keyword_atomic)) |tok| {
679 if (qual.atomic != null)
680 break :blk;
681 qual.atomic = tok;
682 } else return false;
683 return true;
684 }
685 try parser.warn(.{
686 .DuplicateQualifier = .{ .token = parser.it.index },
687 });
688 return true;
689 }
690
691 /// FnSpec <- Keyword_inline / Keyword_noreturn
692 fn fnSpec(parser: *Parser, ds: *Node.DeclSpec) !bool {
693 blk: {
694 if (parser.eatToken(.Keyword_inline)) |tok| {
695 if (ds.fn_spec != .None)
696 break :blk;
697 ds.fn_spec = .{ .Inline = tok };
698 } else if (parser.eatToken(.Keyword_noreturn)) |tok| {
699 if (ds.fn_spec != .None)
700 break :blk;
701 ds.fn_spec = .{ .Noreturn = tok };
702 } else return false;
703 return true;
704 }
705 try parser.warn(.{
706 .DuplicateSpecifier = .{ .token = parser.it.index },
707 });
708 return true;
709 }
710
711 /// AlignSpec <- Keyword_alignas LPAREN (TypeName / ConstExpr) RPAREN
712 fn alignSpec(parser: *Parser, ds: *Node.DeclSpec) !bool {
713 if (parser.eatToken(.Keyword_alignas)) |tok| {
714 _ = try parser.expectToken(.LParen);
715 const node = (try parser.typeName()) orelse (try parser.constExpr()) orelse parser.err(.{
716 .ExpectedExpr = .{ .token = parser.it.index },
717 });
718 if (ds.align_spec != null) {
719 try parser.warn(.{
720 .DuplicateSpecifier = .{ .token = parser.it.index },
721 });
722 }
723 ds.align_spec = .{
724 .alignas = tok,
725 .expr = node,
726 .rparen = try parser.expectToken(.RParen),
727 };
728 return true;
729 }
730 return false;
731 }
732
733 /// EnumSpec <- Keyword_enum IDENTIFIER? (LBRACE EnumField RBRACE)?
734 fn enumSpec(parser: *Parser, tok: TokenIndex) !*Node.EnumType {
735 const node = try parser.arena.create(Node.EnumType);
736 const name = parser.eatToken(.Identifier);
737 node.* = .{
738 .tok = tok,
739 .name = name,
740 .body = null,
741 };
742 const ty = try parser.arena.create(Type);
743 ty.* = .{
744 .id = .{
745 .Enum = node,
746 },
747 };
748 if (name) |some|
749 try parser.symbols.append(.{
750 .name = parser.tree.tokenSlice(some),
751 .ty = ty,
752 });
753 if (parser.eatToken(.LBrace)) |lbrace| {
754 var fields = Node.EnumType.FieldList.init(parser.arena);
755 try fields.push((try parser.enumField()) orelse return parser.err(.{
756 .ExpectedEnumField = .{ .token = parser.it.index },
757 }));
758 while (parser.eatToken(.Comma)) |_| {
759 try fields.push((try parser.enumField()) orelse break);
760 }
761 node.body = .{
762 .lbrace = lbrace,
763 .fields = fields,
764 .rbrace = try parser.expectToken(.RBrace),
765 };
766 }
767 return node;
768 }
769
770 /// EnumField <- IDENTIFIER (EQUAL ConstExpr)? (COMMA EnumField) COMMA?
771 fn enumField(parser: *Parser) !?*Node {
772 const name = parser.eatToken(.Identifier) orelse return null;
773 const node = try parser.arena.create(Node.EnumField);
774 node.* = .{
775 .name = name,
776 .value = null,
777 };
778 if (parser.eatToken(.Equal)) |eq| {
779 node.value = (try parser.constExpr()) orelse parser.err(.{
780 .ExpectedExpr = .{ .token = parser.it.index },
781 });
782 }
783 return &node.base;
784 }
785
786 /// RecordSpec <- (Keyword_struct / Keyword_union) IDENTIFIER? (LBRACE RecordField+ RBRACE)?
787 fn recordSpec(parser: *Parser, tok: TokenIndex) !*Node.RecordType {
788 const node = try parser.arena.create(Node.RecordType);
789 const name = parser.eatToken(.Identifier);
790 const is_struct = parser.tree.tokenSlice(tok)[0] == 's';
791 node.* = .{
792 .tok = tok,
793 .kind = if (is_struct) .Struct else .Union,
794 .name = name,
795 .body = null,
796 };
797 const ty = try parser.arena.create(Type);
798 ty.* = .{
799 .id = .{
800 .Record = node,
801 },
802 };
803 if (name) |some|
804 try parser.symbols.append(.{
805 .name = parser.tree.tokenSlice(some),
806 .ty = ty,
807 });
808 if (parser.eatToken(.LBrace)) |lbrace| {
809 try parser.pushScope(.Block);
810 defer parser.popScope();
811 var fields = Node.RecordType.FieldList.init(parser.arena);
812 while (true) {
813 if (parser.eatToken(.RBrace)) |rbrace| {
814 node.body = .{
815 .lbrace = lbrace,
816 .fields = fields,
817 .rbrace = rbrace,
818 };
819 break;
820 }
821 try fields.push(try parser.recordField());
822 }
823 }
824 return node;
825 }
826
827 /// RecordField
828 /// <- TypeSpec* (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON
829 /// \ StaticAssert
830 fn recordField(parser: *Parser) Error!*Node {
831 if (try parser.staticAssert()) |decl| return decl;
832 var got = false;
833 var type_spec = Node.TypeSpec{};
834 while (try parser.typeSpec(&type_spec)) got = true;
835 if (!got)
836 return parser.err(.{
837 .ExpectedType = .{ .token = parser.it.index },
838 });
839 const node = try parser.arena.create(Node.RecordField);
840 node.* = .{
841 .type_spec = type_spec,
842 .declarators = Node.RecordField.DeclaratorList.init(parser.arena),
843 .semicolon = undefined,
844 };
845 while (true) {
846 const rdr = try parser.recordDeclarator();
847 try parser.declareSymbol(type_spec, rdr.declarator);
848 try node.declarators.push(&rdr.base);
849 if (parser.eatToken(.Comma)) |_| {} else break;
850 }
851
852 node.semicolon = try parser.expectToken(.Semicolon);
853 return &node.base;
854 }
855
856 /// TypeName <- TypeSpec* AbstractDeclarator?
857 fn typeName(parser: *Parser) Error!?*Node {
858 @panic("TODO");
859 }
860
861 /// RecordDeclarator <- Declarator? (COLON ConstExpr)?
862 fn recordDeclarator(parser: *Parser) Error!*Node.RecordDeclarator {
863 @panic("TODO");
864 }
865
866 /// Pointer <- ASTERISK TypeQual* Pointer?
867 fn pointer(parser: *Parser) Error!?*Node.Pointer {
868 const asterisk = parser.eatToken(.Asterisk) orelse return null;
869 const node = try parser.arena.create(Node.Pointer);
870 node.* = .{
871 .asterisk = asterisk,
872 .qual = .{},
873 .pointer = null,
874 };
875 while (try parser.typeQual(&node.qual)) {}
876 node.pointer = try parser.pointer();
877 return node;
878 }
879
880 const Named = enum {
881 Must,
882 Allowed,
883 Forbidden,
884 };
885
886 /// Declarator <- Pointer? DeclaratorSuffix
887 /// DeclaratorPrefix
888 /// <- IDENTIFIER // if named != .Forbidden
889 /// / LPAREN Declarator RPAREN
890 /// / (none) // if named != .Must
891 /// DeclaratorSuffix
892 /// <- DeclaratorPrefix (LBRACKET ArrayDeclarator? RBRACKET)*
893 /// / DeclaratorPrefix LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
894 fn declarator(parser: *Parser, named: Named) Error!?*Node {
895 const ptr = try parser.pointer();
896 var node: *Node.Declarator = undefined;
897 var inner_fn = false;
898
899 // TODO sizof(int (int))
900 // prefix
901 if (parser.eatToken(.LParen)) |lparen| {
902 const inner = (try parser.declarator(named)) orelse return parser.err(.{
903 .ExpectedDeclarator = .{ .token = lparen + 1 },
904 });
905 inner_fn = declaratorIsFunction(inner);
906 node = try parser.arena.create(Node.Declarator);
907 node.* = .{
908 .pointer = ptr,
909 .prefix = .{
910 .Complex = .{
911 .lparen = lparen,
912 .inner = inner,
913 .rparen = try parser.expectToken(.RParen),
914 },
915 },
916 .suffix = .None,
917 };
918 } else if (named != .Forbidden) {
919 if (parser.eatToken(.Identifier)) |tok| {
920 node = try parser.arena.create(Node.Declarator);
921 node.* = .{
922 .pointer = ptr,
923 .prefix = .{ .Identifer = tok },
924 .suffix = .None,
925 };
926 } else if (named == .Must) {
927 return parser.err(.{
928 .ExpectedToken = .{ .token = parser.it.index, .expected_id = .Identifier },
929 });
930 } else {
931 if (ptr) |some|
932 return &some.base;
933 return null;
934 }
935 } else {
936 node = try parser.arena.create(Node.Declarator);
937 node.* = .{
938 .pointer = ptr,
939 .prefix = .None,
940 .suffix = .None,
941 };
942 }
943 // suffix
944 if (parser.eatToken(.LParen)) |lparen| {
945 if (inner_fn)
946 return parser.err(.{
947 .InvalidDeclarator = .{ .token = lparen },
948 });
949 node.suffix = .{
950 .Fn = .{
951 .lparen = lparen,
952 .params = Node.Declarator.Params.init(parser.arena),
953 .rparen = undefined,
954 },
955 };
956 try parser.paramDecl(node);
957 node.suffix.Fn.rparen = try parser.expectToken(.RParen);
958 } else if (parser.eatToken(.LBracket)) |tok| {
959 if (inner_fn)
960 return parser.err(.{
961 .InvalidDeclarator = .{ .token = tok },
962 });
963 node.suffix = .{ .Array = Node.Declarator.Arrays.init(parser.arena) };
964 var lbrace = tok;
965 while (true) {
966 try node.suffix.Array.push(try parser.arrayDeclarator(lbrace));
967 if (parser.eatToken(.LBracket)) |t| lbrace = t else break;
968 }
969 }
970 if (parser.eatToken(.LParen) orelse parser.eatToken(.LBracket)) |tok|
971 return parser.err(.{
972 .InvalidDeclarator = .{ .token = tok },
973 });
974 return &node.base;
975 }
976
977 /// ArrayDeclarator
978 /// <- ASTERISK
979 /// / Keyword_static TypeQual* AssignmentExpr
980 /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr)
981 /// / TypeQual+ AssignmentExpr?
982 /// / AssignmentExpr
983 fn arrayDeclarator(parser: *Parser, lbracket: TokenIndex) !*Node.Array {
984 const arr = try parser.arena.create(Node.Array);
985 arr.* = .{
986 .lbracket = lbracket,
987 .inner = .Inferred,
988 .rbracket = undefined,
989 };
990 if (parser.eatToken(.Asterisk)) |tok| {
991 arr.inner = .{ .Unspecified = tok };
992 } else {
993 // TODO
994 }
995 arr.rbracket = try parser.expectToken(.RBracket);
996 return arr;
997 }
998
999 /// Params <- ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?
1000 /// ParamDecl <- DeclSpec (Declarator / AbstractDeclarator)
1001 fn paramDecl(parser: *Parser, dr: *Node.Declarator) !void {
1002 var old_style = false;
1003 while (true) {
1004 var ds = Node.DeclSpec{};
1005 if (try parser.declSpec(&ds)) {
1006 //TODO
1007 // TODO try parser.declareSymbol(ds.type_spec, dr);
1008 } else if (parser.eatToken(.Identifier)) |tok| {
1009 old_style = true;
1010 } else if (parser.eatToken(.Ellipsis)) |tok| {
1011 // TODO
1012 }
1013 }
1014 }
1015
1016 /// Expr <- AssignmentExpr (COMMA Expr)*
1017 fn expr(parser: *Parser) Error!?*Expr {
1018 @panic("TODO");
1019 }
1020
1021 /// AssignmentExpr
1022 /// <- ConditionalExpr // TODO recursive?
1023 /// / UnaryExpr (EQUAL / ASTERISKEQUAL / SLASHEQUAL / PERCENTEQUAL / PLUSEQUAL / MINUSEQUA /
1024 /// / ANGLEBRACKETANGLEBRACKETLEFTEQUAL / ANGLEBRACKETANGLEBRACKETRIGHTEQUAL /
1025 /// / AMPERSANDEQUAL / CARETEQUAL / PIPEEQUAL) AssignmentExpr
1026 fn assignmentExpr(parser: *Parser) !?*Expr {
1027 @panic("TODO");
1028 }
1029
1030 /// ConstExpr <- ConditionalExpr
1031 fn constExpr(parser: *Parser) Error!?*Expr {
1032 const start = parser.it.index;
1033 const expression = try parser.conditionalExpr();
1034 if (expression != null and expression.?.value == .None)
1035 return parser.err(.{
1036 .ConsExpr = start,
1037 });
1038 return expression;
1039 }
1040
1041 /// ConditionalExpr <- LogicalOrExpr (QUESTIONMARK Expr COLON ConditionalExpr)?
1042 fn conditionalExpr(parser: *Parser) Error!?*Expr {
1043 @panic("TODO");
1044 }
1045
1046 /// LogicalOrExpr <- LogicalAndExpr (PIPEPIPE LogicalOrExpr)*
1047 fn logicalOrExpr(parser: *Parser) !*Node {
1048 const lhs = (try parser.logicalAndExpr()) orelse return null;
1049 }
1050
1051 /// LogicalAndExpr <- BinOrExpr (AMPERSANDAMPERSAND LogicalAndExpr)*
1052 fn logicalAndExpr(parser: *Parser) !*Node {
1053 @panic("TODO");
1054 }
1055
1056 /// BinOrExpr <- BinXorExpr (PIPE BinOrExpr)*
1057 fn binOrExpr(parser: *Parser) !*Node {
1058 @panic("TODO");
1059 }
1060
1061 /// BinXorExpr <- BinAndExpr (CARET BinXorExpr)*
1062 fn binXorExpr(parser: *Parser) !*Node {
1063 @panic("TODO");
1064 }
1065
1066 /// BinAndExpr <- EqualityExpr (AMPERSAND BinAndExpr)*
1067 fn binAndExpr(parser: *Parser) !*Node {
1068 @panic("TODO");
1069 }
1070
1071 /// EqualityExpr <- ComparisionExpr ((EQUALEQUAL / BANGEQUAL) EqualityExpr)*
1072 fn equalityExpr(parser: *Parser) !*Node {
1073 @panic("TODO");
1074 }
1075
1076 /// ComparisionExpr <- ShiftExpr (ANGLEBRACKETLEFT / ANGLEBRACKETLEFTEQUAL /ANGLEBRACKETRIGHT / ANGLEBRACKETRIGHTEQUAL) ComparisionExpr)*
1077 fn comparisionExpr(parser: *Parser) !*Node {
1078 @panic("TODO");
1079 }
1080
1081 /// ShiftExpr <- AdditiveExpr (ANGLEBRACKETANGLEBRACKETLEFT / ANGLEBRACKETANGLEBRACKETRIGHT) ShiftExpr)*
1082 fn shiftExpr(parser: *Parser) !*Node {
1083 @panic("TODO");
1084 }
1085
1086 /// AdditiveExpr <- MultiplicativeExpr (PLUS / MINUS) AdditiveExpr)*
1087 fn additiveExpr(parser: *Parser) !*Node {
1088 @panic("TODO");
1089 }
1090
1091 /// MultiplicativeExpr <- UnaryExpr (ASTERISK / SLASH / PERCENT) MultiplicativeExpr)*
1092 fn multiplicativeExpr(parser: *Parser) !*Node {
1093 @panic("TODO");
1094 }
1095
1096 /// UnaryExpr
1097 /// <- LPAREN TypeName RPAREN UnaryExpr
1098 /// / Keyword_sizeof LAPERN TypeName RPAREN
1099 /// / Keyword_sizeof UnaryExpr
1100 /// / Keyword_alignof LAPERN TypeName RPAREN
1101 /// / (AMPERSAND / ASTERISK / PLUS / PLUSPLUS / MINUS / MINUSMINUS / TILDE / BANG) UnaryExpr
1102 /// / PrimaryExpr PostFixExpr*
1103 fn unaryExpr(parser: *Parser) !*Node {
1104 @panic("TODO");
1105 }
1106
1107 /// PrimaryExpr
1108 /// <- IDENTIFIER
1109 /// / INTEGERLITERAL / FLOATLITERAL / STRINGLITERAL / CHARLITERAL
1110 /// / LPAREN Expr RPAREN
1111 /// / Keyword_generic LPAREN AssignmentExpr (COMMA Generic)+ RPAREN
1112 fn primaryExpr(parser: *Parser) !*Node {
1113 @panic("TODO");
1114 }
1115
1116 /// Generic
1117 /// <- TypeName COLON AssignmentExpr
1118 /// / Keyword_default COLON AssignmentExpr
1119 fn generic(parser: *Parser) !*Node {
1120 @panic("TODO");
1121 }
1122
1123 /// PostFixExpr
1124 /// <- LPAREN TypeName RPAREN LBRACE Initializers RBRACE
1125 /// / LBRACKET Expr RBRACKET
1126 /// / LPAREN (AssignmentExpr (COMMA AssignmentExpr)*)? RPAREN
1127 /// / (PERIOD / ARROW) IDENTIFIER
1128 /// / (PLUSPLUS / MINUSMINUS)
1129 fn postFixExpr(parser: *Parser) !*Node {
1130 @panic("TODO");
1131 }
1132
1133 /// Initializers <- ((Designator+ EQUAL)? Initializer COMMA)* (Designator+ EQUAL)? Initializer COMMA?
1134 fn initializers(parser: *Parser) !*Node {
1135 @panic("TODO");
1136 }
1137
1138 /// Initializer
1139 /// <- LBRACE Initializers RBRACE
1140 /// / AssignmentExpr
1141 fn initializer(parser: *Parser, dr: *Node.Declarator) Error!?*Node {
1142 @panic("TODO");
1143 }
1144
1145 /// Designator
1146 /// <- LBRACKET ConstExpr RBRACKET
1147 /// / PERIOD IDENTIFIER
1148 fn designator(parser: *Parser) !*Node {
1149 @panic("TODO");
1150 }
1151
1152 /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE
1153 fn compoundStmt(parser: *Parser) Error!?*Node {
1154 const lbrace = parser.eatToken(.LBrace) orelse return null;
1155 try parser.pushScope(.Block);
1156 defer parser.popScope();
1157 const body_node = try parser.arena.create(Node.CompoundStmt);
1158 body_node.* = .{
1159 .lbrace = lbrace,
1160 .statements = Node.CompoundStmt.StmtList.init(parser.arena),
1161 .rbrace = undefined,
1162 };
1163 while (true) {
1164 if (parser.eatToken(.RBRACE)) |rbrace| {
1165 body_node.rbrace = rbrace;
1166 break;
1167 }
1168 try body_node.statements.push((try parser.declaration()) orelse (try parser.stmt()));
1169 }
1170 return &body_node.base;
1171 }
1172
1173 /// Stmt
1174 /// <- CompoundStmt
1175 /// / Keyword_if LPAREN Expr RPAREN Stmt (Keyword_ELSE Stmt)?
1176 /// / Keyword_switch LPAREN Expr RPAREN Stmt
1177 /// / Keyword_while LPAREN Expr RPAREN Stmt
1178 /// / Keyword_do statement Keyword_while LPAREN Expr RPAREN SEMICOLON
1179 /// / Keyword_for LPAREN (Declaration / ExprStmt) ExprStmt Expr? RPAREN Stmt
1180 /// / Keyword_default COLON Stmt
1181 /// / Keyword_case ConstExpr COLON Stmt
1182 /// / Keyword_goto IDENTIFIER SEMICOLON
1183 /// / Keyword_continue SEMICOLON
1184 /// / Keyword_break SEMICOLON
1185 /// / Keyword_return Expr? SEMICOLON
1186 /// / IDENTIFIER COLON Stmt
1187 /// / ExprStmt
1188 fn stmt(parser: *Parser) Error!*Node {
1189 if (try parser.compoundStmt()) |node| return node;
1190 if (parser.eatToken(.Keyword_if)) |tok| {
1191 const node = try parser.arena.create(Node.IfStmt);
1192 _ = try parser.expectToken(.LParen);
1193 node.* = .{
1194 .@"if" = tok,
1195 .cond = (try parser.expr()) orelse return parser.err(.{
1196 .ExpectedExpr = .{ .token = parser.it.index },
1197 }),
1198 .body = undefined,
1199 .@"else" = null,
1200 };
1201 _ = try parser.expectToken(.RParen);
1202 node.body = try parser.stmt();
1203 if (parser.eatToken(.Keyword_else)) |else_tok| {
1204 node.@"else" = .{
1205 .tok = else_tok,
1206 .body = try parser.stmt(),
1207 };
1208 }
1209 return &node.base;
1210 }
1211 if (parser.eatToken(.Keyword_while)) |tok| {
1212 try parser.pushScope(.Loop);
1213 defer parser.popScope();
1214 _ = try parser.expectToken(.LParen);
1215 const cond = (try parser.expr()) orelse return parser.err(.{
1216 .ExpectedExpr = .{ .token = parser.it.index },
1217 });
1218 const rparen = try parser.expectToken(.RParen);
1219 const node = try parser.arena.create(Node.WhileStmt);
1220 node.* = .{
1221 .@"while" = tok,
1222 .cond = cond,
1223 .rparen = rparen,
1224 .body = try parser.stmt(),
1225 .semicolon = try parser.expectToken(.Semicolon),
1226 };
1227 return &node.base;
1228 }
1229 if (parser.eatToken(.Keyword_do)) |tok| {
1230 try parser.pushScope(.Loop);
1231 defer parser.popScope();
1232 const body = try parser.stmt();
1233 _ = try parser.expectToken(.LParen);
1234 const cond = (try parser.expr()) orelse return parser.err(.{
1235 .ExpectedExpr = .{ .token = parser.it.index },
1236 });
1237 _ = try parser.expectToken(.RParen);
1238 const node = try parser.arena.create(Node.DoStmt);
1239 node.* = .{
1240 .do = tok,
1241 .body = body,
1242 .cond = cond,
1243 .@"while" = @"while",
1244 .semicolon = try parser.expectToken(.Semicolon),
1245 };
1246 return &node.base;
1247 }
1248 if (parser.eatToken(.Keyword_for)) |tok| {
1249 try parser.pushScope(.Loop);
1250 defer parser.popScope();
1251 _ = try parser.expectToken(.LParen);
1252 const init = if (try parser.declaration()) |decl| blk: {
1253 // TODO disallow storage class other than auto and register
1254 break :blk decl;
1255 } else try parser.exprStmt();
1256 const cond = try parser.expr();
1257 const semicolon = try parser.expectToken(.Semicolon);
1258 const incr = try parser.expr();
1259 const rparen = try parser.expectToken(.RParen);
1260 const node = try parser.arena.create(Node.ForStmt);
1261 node.* = .{
1262 .@"for" = tok,
1263 .init = init,
1264 .cond = cond,
1265 .semicolon = semicolon,
1266 .incr = incr,
1267 .rparen = rparen,
1268 .body = try parser.stmt(),
1269 };
1270 return &node.base;
1271 }
1272 if (parser.eatToken(.Keyword_switch)) |tok| {
1273 try parser.pushScope(.Switch);
1274 defer parser.popScope();
1275 _ = try parser.expectToken(.LParen);
1276 const switch_expr = try parser.exprStmt();
1277 const rparen = try parser.expectToken(.RParen);
1278 const node = try parser.arena.create(Node.SwitchStmt);
1279 node.* = .{
1280 .@"switch" = tok,
1281 .expr = switch_expr,
1282 .rparen = rparen,
1283 .body = try parser.stmt(),
1284 };
1285 return &node.base;
1286 }
1287 if (parser.eatToken(.Keyword_default)) |tok| {
1288 _ = try parser.expectToken(.Colon);
1289 const node = try parser.arena.create(Node.LabeledStmt);
1290 node.* = .{
1291 .kind = .{ .Default = tok },
1292 .stmt = try parser.stmt(),
1293 };
1294 return &node.base;
1295 }
1296 if (parser.eatToken(.Keyword_case)) |tok| {
1297 _ = try parser.expectToken(.Colon);
1298 const node = try parser.arena.create(Node.LabeledStmt);
1299 node.* = .{
1300 .kind = .{ .Case = tok },
1301 .stmt = try parser.stmt(),
1302 };
1303 return &node.base;
1304 }
1305 if (parser.eatToken(.Keyword_goto)) |tok| {
1306 const node = try parser.arena.create(Node.JumpStmt);
1307 node.* = .{
1308 .ltoken = tok,
1309 .kind = .{ .Goto = tok },
1310 .semicolon = try parser.expectToken(.Semicolon),
1311 };
1312 return &node.base;
1313 }
1314 if (parser.eatToken(.Keyword_continue)) |tok| {
1315 const node = try parser.arena.create(Node.JumpStmt);
1316 node.* = .{
1317 .ltoken = tok,
1318 .kind = .Continue,
1319 .semicolon = try parser.expectToken(.Semicolon),
1320 };
1321 return &node.base;
1322 }
1323 if (parser.eatToken(.Keyword_break)) |tok| {
1324 const node = try parser.arena.create(Node.JumpStmt);
1325 node.* = .{
1326 .ltoken = tok,
1327 .kind = .Break,
1328 .semicolon = try parser.expectToken(.Semicolon),
1329 };
1330 return &node.base;
1331 }
1332 if (parser.eatToken(.Keyword_return)) |tok| {
1333 const node = try parser.arena.create(Node.JumpStmt);
1334 node.* = .{
1335 .ltoken = tok,
1336 .kind = .{ .Return = try parser.expr() },
1337 .semicolon = try parser.expectToken(.Semicolon),
1338 };
1339 return &node.base;
1340 }
1341 if (parser.eatToken(.Identifier)) |tok| {
1342 if (parser.eatToken(.Colon)) |_| {
1343 const node = try parser.arena.create(Node.LabeledStmt);
1344 node.* = .{
1345 .kind = .{ .Label = tok },
1346 .stmt = try parser.stmt(),
1347 };
1348 return &node.base;
1349 }
1350 parser.putBackToken(tok);
1351 }
1352 return parser.exprStmt();
1353 }
1354
1355 /// ExprStmt <- Expr? SEMICOLON
1356 fn exprStmt(parser: *Parser) !*Node {
1357 const node = try parser.arena.create(Node.ExprStmt);
1358 node.* = .{
1359 .expr = try parser.expr(),
1360 .semicolon = try parser.expectToken(.Semicolon),
1361 };
1362 return &node.base;
1363 }
1364
1365 fn eatToken(parser: *Parser, id: std.meta.Tag(Token.Id)) ?TokenIndex {
1366 while (true) {
1367 switch ((parser.it.next() orelse return null).id) {
1368 .LineComment, .MultiLineComment, .Nl => continue,
1369 else => |next_id| if (next_id == id) {
1370 return parser.it.index;
1371 } else {
1372 _ = parser.it.prev();
1373 return null;
1374 },
1375 }
1376 }
1377 }
1378
1379 fn expectToken(parser: *Parser, id: std.meta.Tag(Token.Id)) Error!TokenIndex {
1380 while (true) {
1381 switch ((parser.it.next() orelse return error.ParseError).id) {
1382 .LineComment, .MultiLineComment, .Nl => continue,
1383 else => |next_id| if (next_id != id) {
1384 return parser.err(.{
1385 .ExpectedToken = .{ .token = parser.it.index, .expected_id = id },
1386 });
1387 } else {
1388 return parser.it.index;
1389 },
1390 }
1391 }
1392 }
1393
1394 fn putBackToken(parser: *Parser, putting_back: TokenIndex) void {
1395 while (true) {
1396 const prev_tok = parser.it.next() orelse return;
1397 switch (prev_tok.id) {
1398 .LineComment, .MultiLineComment, .Nl => continue,
1399 else => {
1400 assert(parser.it.list.at(putting_back) == prev_tok);
1401 return;
1402 },
1403 }
1404 }
1405 }
1406
1407 fn err(parser: *Parser, msg: ast.Error) Error {
1408 try parser.tree.msgs.push(.{
1409 .kind = .Error,
1410 .inner = msg,
1411 });
1412 return error.ParseError;
1413 }
1414
1415 fn warn(parser: *Parser, msg: ast.Error) Error!void {
1416 const is_warning = switch (parser.options.warn_as_err) {
1417 .None => true,
1418 .Some => |list| for (list) |item| (if (item == msg) break false) else true,
1419 .All => false,
1420 };
1421 try parser.tree.msgs.push(.{
1422 .kind = if (is_warning) .Warning else .Error,
1423 .inner = msg,
1424 });
1425 if (!is_warning) return error.ParseError;
1426 }
1427
1428 fn note(parser: *Parser, msg: ast.Error) Error!void {
1429 try parser.tree.msgs.push(.{
1430 .kind = .Note,
1431 .inner = msg,
1432 });
1433 }
1434};