authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-06 14:41:53+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-06 20:06:17+02:00
log3ed6d7d24589aa295409880239833fdc8d6be9d6
treedbc34e02bcde7e5f4cc2ba668d41ff7382629b03
parentd5d52af26ec3d3e6a171564112978a7d8c96aba4
signature Commit is signed but in an unrecognized format.

std-c parser declarator


2 files changed, 153 insertions(+), 37 deletions(-)

lib/std/c/ast.zig+37-16
...@@ -41,6 +41,7 @@ pub const Error = union(enum) {...@@ -41,6 +41,7 @@ pub const Error = union(enum) {
41 ExpectedStmt: SingleTokenError("expected statement, found '{}'"),41 ExpectedStmt: SingleTokenError("expected statement, found '{}'"),
42 ExpectedTypeName: SingleTokenError("expected type name, found '{}'"),42 ExpectedTypeName: SingleTokenError("expected type name, found '{}'"),
43 ExpectedFnBody: SingleTokenError("expected function body, found '{}'"),43 ExpectedFnBody: SingleTokenError("expected function body, found '{}'"),
44 ExpectedDeclarator: SingleTokenError("expected declarator, found '{}'"),
44 ExpectedInitializer: SingleTokenError("expected initializer, found '{}'"),45 ExpectedInitializer: SingleTokenError("expected initializer, found '{}'"),
45 InvalidTypeSpecifier: InvalidTypeSpecifier,46 InvalidTypeSpecifier: InvalidTypeSpecifier,
46 DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"),47 DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"),
...@@ -55,6 +56,7 @@ pub const Error = union(enum) {...@@ -55,6 +56,7 @@ pub const Error = union(enum) {
55 .ExpectedTypeName => |*x| return x.render(tokens, stream),56 .ExpectedTypeName => |*x| return x.render(tokens, stream),
56 .ExpectedDeclarator => |*x| return x.render(tokens, stream),57 .ExpectedDeclarator => |*x| return x.render(tokens, stream),
57 .ExpectedFnBody => |*x| return x.render(tokens, stream),58 .ExpectedFnBody => |*x| return x.render(tokens, stream),
59 .ExpectedInitializer => |*x| return x.render(tokens, stream),
58 .InvalidTypeSpecifier => |*x| return x.render(tokens, stream),60 .InvalidTypeSpecifier => |*x| return x.render(tokens, stream),
59 .DuplicateQualifier => |*x| return x.render(tokens, stream),61 .DuplicateQualifier => |*x| return x.render(tokens, stream),
60 .DuplicateSpecifier => |*x| return x.render(tokens, stream),62 .DuplicateSpecifier => |*x| return x.render(tokens, stream),
...@@ -70,6 +72,7 @@ pub const Error = union(enum) {...@@ -70,6 +72,7 @@ pub const Error = union(enum) {
70 .ExpectedTypeName => |x| return x.token,72 .ExpectedTypeName => |x| return x.token,
71 .ExpectedDeclarator => |x| return x.token,73 .ExpectedDeclarator => |x| return x.token,
72 .ExpectedFnBody => |x| return x.token,74 .ExpectedFnBody => |x| return x.token,
75 .ExpectedInitializer => |x| return x.token,
73 .InvalidTypeSpecifier => |x| return x.token,76 .InvalidTypeSpecifier => |x| return x.token,
74 .DuplicateQualifier => |x| return x.token,77 .DuplicateQualifier => |x| return x.token,
75 .DuplicateSpecifier => |x| return x.token,78 .DuplicateSpecifier => |x| return x.token,
...@@ -277,30 +280,48 @@ pub const Node = struct {...@@ -277,30 +280,48 @@ pub const Node = struct {
277 };280 };
278281
279 pub const Declarator = struct {282 pub const Declarator = struct {
283 base: Node = Node{ .id = .Declarator },
280 pointer: *Pointer,284 pointer: *Pointer,
281 identifier: ?TokenIndex,285 prefix: union(enum) {
282 kind: union(enum) {286 None,
283 Simple,287 Identifer: TokenIndex,
284 Complex: struct {288 Complex: struct {
285 lparen: TokenIndex,289 lparen: TokenIndex,
286 inner: *Declarator,290 inner: *Node,
287 rparen: TokenIndex,291 rparen: TokenIndex,
288 },292 },
289 Fn: ParamList,293 },
290 Array: ArrayList,294 suffix: union(enum) {
295 None,
296 Fn: struct {
297 lparen: TokenIndex,
298 params: Params,
299 rparen: TokenIndex,
300 },
301 Array: Arrays,
291 },302 },
292303
293 pub const ArrayList = std.SegmentedList(*Array, 2);304 pub const Arrays = std.SegmentedList(*Array, 2);
294 pub const ParamList = std.SegmentedList(*Param, 4);305 pub const Params = std.SegmentedList(*Param, 4);
295 };306 };
296307
297 pub const Array = union(enum) {308 pub const Array = struct {
298 Unspecified,309 rbracket: TokenIndex,
299 Variable: TokenIndex,310 inner: union(enum) {
300 Known: *Expr,311 Inferred,
312 Unspecified: TokenIndex,
313 Variable: struct {
314 asterisk: ?TokenIndex,
315 static: ?TokenIndex,
316 qual: TypeQual,
317 expr: *Expr,
318 },
319 },
320 rbracket: TokenIndex,
301 };321 };
302322
303 pub const Pointer = struct {323 pub const Pointer = struct {
324 base: Node = Node{ .id = .Pointer },
304 asterisk: TokenIndex,325 asterisk: TokenIndex,
305 qual: TypeQual,326 qual: TypeQual,
306 pointer: ?*Pointer,327 pointer: ?*Pointer,
...@@ -312,7 +333,7 @@ pub const Node = struct {...@@ -312,7 +333,7 @@ pub const Node = struct {
312 Old: TokenIndex,333 Old: TokenIndex,
313 Normal: struct {334 Normal: struct {
314 decl_spec: *DeclSpec,335 decl_spec: *DeclSpec,
315 declarator: *Declarator,336 declarator: *Node,
316 },337 },
317 },338 },
318 };339 };
...@@ -320,7 +341,7 @@ pub const Node = struct {...@@ -320,7 +341,7 @@ pub const Node = struct {
320 pub const Fn = struct {341 pub const Fn = struct {
321 base: Node = Node{ .id = .Fn },342 base: Node = Node{ .id = .Fn },
322 decl_spec: DeclSpec,343 decl_spec: DeclSpec,
323 declarator: *Declarator,344 declarator: *Node,
324 old_decls: OldDeclList,345 old_decls: OldDeclList,
325 body: ?*CompoundStmt,346 body: ?*CompoundStmt,
326347
...@@ -332,7 +353,7 @@ pub const Node = struct {...@@ -332,7 +353,7 @@ pub const Node = struct {
332 decl_spec: DeclSpec,353 decl_spec: DeclSpec,
333 declarators: DeclaratorList,354 declarators: DeclaratorList,
334355
335 pub const DeclaratorList = std.SegmentedList(*Declarator, 2);356 pub const DeclaratorList = Root.DeclList;
336 };357 };
337358
338 pub const Var = struct {359 pub const Var = struct {
...@@ -344,7 +365,7 @@ pub const Node = struct {...@@ -344,7 +365,7 @@ pub const Node = struct {
344 };365 };
345366
346 pub const Initialized = struct {367 pub const Initialized = struct {
347 declarator: *Declarator,368 declarator: *Node,
348 eq: TokenIndex,369 eq: TokenIndex,
349 init: Initializer,370 init: Initializer,
350 };371 };
lib/std/c/parse.zig+116-21
...@@ -589,7 +589,7 @@ const Parser = struct {...@@ -589,7 +589,7 @@ const Parser = struct {
589 fn recordDeclarator(parser: *Parser) !*Node {}589 fn recordDeclarator(parser: *Parser) !*Node {}
590590
591 /// Pointer <- ASTERISK TypeQual* Pointer?591 /// Pointer <- ASTERISK TypeQual* Pointer?
592 fn pointer(parser: *Parser) !?*Node.Pointer {592 fn pointer(parser: *Parser) Error!?*Node {
593 const asterisk = parser.eatToken(.Asterisk) orelse return null;593 const asterisk = parser.eatToken(.Asterisk) orelse return null;
594 const node = try parser.arena.create(Node.Pointer);594 const node = try parser.arena.create(Node.Pointer);
595 node.* = .{595 node.* = .{
...@@ -599,34 +599,129 @@ const Parser = struct {...@@ -599,34 +599,129 @@ const Parser = struct {
599 };599 };
600 while (try parser.typeQual(&node.qual)) {}600 while (try parser.typeQual(&node.qual)) {}
601 node.pointer = try parser.pointer();601 node.pointer = try parser.pointer();
602 return node;602 return &node.base;
603 }603 }
604 /// DirectDeclarator604
605 /// <- IDENTIFIER605 const Named = enum {
606 Must,
607 Allowed,
608 Forbidden,
609 };
610
611 /// Declarator <- Pointer? DeclaratorSuffix
612 /// DeclaratorPrefix
613 /// <- IDENTIFIER // if named != .Forbidden
606 /// / LPAREN Declarator RPAREN614 /// / LPAREN Declarator RPAREN
607 /// / DirectDeclarator LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET615 /// / (none) // if named != .Must
608 /// / DirectDeclarator LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN616 /// DeclaratorSuffix
609 fn directDeclarator(parser: *Parser) !*Node {}617 /// <. DeclaratorPrefix (LBRACKET ArrayDeclarator? RBRACKET)*
618 /// / DeclaratorPrefix LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
619 fn declarator(parser: *Parser, named: Named) Error!?*Node {
620 const ptr = try parser.pointer();
621 var node: *Node.Declarator = undefined;
622 // prefix
623 if (parser.eatToken(.LParen)) |lparen| {
624 const inner = (try parser.declarator(named)) orelse return parser.err(.{
625 .ExpectedDeclarator = .{ .token = lparen + 1 },
626 });
627 node = try parser.arena.create(Node.Declarator);
628 node.* = .{
629 .pointer = ptr,
630 .prefix = .{
631 .Comples = .{
632 .lparen = lparen,
633 .inner = inner,
634 .rparen = try parser.expectToken(.RParen),
635 },
636 },
637 .suffix = .None,
638 };
639 } else if (named != .Forbidden) {
640 if (parser.eatToken(.Identifier)) |tok| {
641 node = try parser.arena.create(Node.Declarator);
642 node.* = .{
643 .pointer = ptr,
644 .prefix = .{ .Simple = tok },
645 .suffix = .None,
646 };
647 } else if (named == .Must) {
648 return parser.err(.{
649 .ExpectedToken = .{ .token = parser.it.index, .expected_id = .Identifier },
650 });
651 } else {
652 return ptr;
653 }
654 } else {
655 node = try parser.arena.create(Node.Declarator);
656 node.* = .{
657 .pointer = ptr,
658 .prefix = .None,
659 .suffix = .None,
660 };
661 }
662 // suffix
663 if (parser.eatToken(.LParen)) |lparen| {
664 node.suffix = .{
665 .Fn = .{
666 .lparen = lparen,
667 .params = .Node.Declarator.Params.init(parser.arena),
668 .rparen = undefined,
669 },
670 };
671 try parser.ParamDecl(node);
672 node.suffix.Fn.rparen = try parser.expectToken(.RParen);
673 } else {
674 while (parser.arrayDeclarator()) |arr| {
675 if (node.suffix == .None)
676 node.suffix = .{ .Array = .Node.Declarator.Arrays.init(parser.arena) };
677 try node.suffix.Array.push(arr);
678 }
679 }
680 if (parser.eatToken(.LParen) orelse parser.eatToken(.LBracket)) |tok|
681 return parser.err(.{
682 .InvalidDeclarator = .{ .token = tok },
683 });
684 return node;
685 }
610686
611 /// BracketDeclarator687 /// ArrayDeclarator
612 /// <- Keyword_static TypeQual* AssignmentExpr688 /// <- ASTERISK
689 /// / Keyword_static TypeQual* AssignmentExpr
613 /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr)690 /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr)
614 /// / TypeQual+ AssignmentExpr?691 /// / TypeQual+ AssignmentExpr?
615 /// / AssignmentExpr692 /// / AssignmentExpr
616 fn bracketDeclarator(parser: *Parser) !*Node {}693 fn arrayDeclarator(parser: *Parser, dr: *Node.Declarator) !?*Node.Array {
694 const lbracket = parser.eatToken(.LBracket) orelse return null;
695 const arr = try parser.arena.create(Node.Array);
696 arr.* = .{
697 .lbracket = lbarcket,
698 .inner = .Inferred,
699 .rbracket = undefined,
700 };
701 if (parser.eatToken(.Asterisk)) |tok| {
702 arr.inner = .{ .Unspecified = tok };
703 } else {
704 // TODO
705 }
706 arr.rbracket = try parser.expectToken(.RBracket);
707 return arr;
708 }
617709
710 /// Params <- ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?
618 /// ParamDecl <- DeclSpec (Declarator / AbstractDeclarator)711 /// ParamDecl <- DeclSpec (Declarator / AbstractDeclarator)
619 fn paramDecl(parser: *Parser) !*Node {}712 fn paramDecl(parser: *Parser, dr: *Node.Declarator) !void {
620713 var old_style = false;
621 /// AbstractDeclarator <- Pointer? DirectAbstractDeclarator?714 while (true) {
622 fn abstractDeclarator(parser: *Parser) !*Node {}715 var ds = Node.DeclSpec;
623716 if (try parser.declSpec(&ds)) {
624 /// DirectAbstractDeclarator717 //TODO
625 /// <- IDENTIFIER718 } else if (parser.eatToken(.Identifier)) {
626 /// / LPAREN DirectAbstractDeclarator RPAREN719 old_style = true;
627 /// / DirectAbstractDeclarator? LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET720 } else if (parser.eatToken(.Ellipsis)) {
628 /// / DirectAbstractDeclarator? LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN721 // TODO
629 fn directAbstractDeclarator(parser: *Parser) !*Node {}722 }
723 }
724 }
630725
631 /// Expr <- AssignmentExpr (COMMA Expr)*726 /// Expr <- AssignmentExpr (COMMA Expr)*
632 fn expr(parser: *Parser) !*Node {}727 fn expr(parser: *Parser) !*Node {}