authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-14 11:19:50+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-14 11:19:50+03:00
log89f2923a8aad5119b1506c3b8e08464e132c228e
tree4c493eeb1af93701fa57a541d1bac56a1d145e02
parentac319b27348f60e37f3f1b478fee00202280715f
signature Commit is signed but in an unrecognized format.

recover from missing semicolon


2 files changed, 30 insertions(+), 3 deletions(-)

lib/std/zig/parse.zig+13-3
......@@ -667,7 +667,12 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
667667 if (try parseLabeledStatement(arena, it, tree)) |node| return node;
668668 if (try parseSwitchExpr(arena, it, tree)) |node| return node;
669669 if (try parseAssignExpr(arena, it, tree)) |node| {
670 _ = try expectToken(it, tree, .Semicolon);
670 _ = eatToken(it, .Semicolon) orelse {
671 try tree.errors.push(.{
672 .ExpectedToken = .{ .token = it.index, .expected_id = .Semicolon },
673 });
674 // pretend we saw a semicolon and continue parsing
675 };
671676 return node;
672677 }
673678
......@@ -911,7 +916,12 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
911916fn parseBlockExprStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
912917 if (try parseBlockExpr(arena, it, tree)) |node| return node;
913918 if (try parseAssignExpr(arena, it, tree)) |node| {
914 _ = try expectToken(it, tree, .Semicolon);
919 _ = eatToken(it, .Semicolon) orelse {
920 try tree.errors.push(.{
921 .ExpectedToken = .{ .token = it.index, .expected_id = .Semicolon },
922 });
923 // pretend we saw a semicolon and continue parsing
924 };
915925 return node;
916926 }
917927 return null;
......@@ -3072,7 +3082,7 @@ fn parseDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.D
30723082}
30733083
30743084/// Eat a single-line doc comment on the same line as another node
3075fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, after_token: TokenIndex) Allocator.Error!?*Node.DocComment {
3085fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, after_token: TokenIndex) !?*Node.DocComment {
30763086 const comment_token = eatToken(it, .DocComment) orelse return null;
30773087 if (tree.tokensOnSameLine(after_token, comment_token)) {
30783088 const node = try arena.create(Node.DocComment);
lib/std/zig/parser_test.zig+17
......@@ -102,6 +102,23 @@ test "recovery: invalid extern/inline" {
102102 });
103103}
104104
105test "recovery: missing semicolon" {
106 try testError(
107 \\test "" {
108 \\ comptime a && b
109 \\ c && d
110 \\ @foo
111 \\}
112 , &[_]Error{
113 .InvalidAnd,
114 .ExpectedToken,
115 .InvalidAnd,
116 .ExpectedToken,
117 .ExpectedParamList,
118 .ExpectedToken,
119 });
120}
121
105122test "zig fmt: top-level fields" {
106123 try testCanonical(
107124 \\a: did_you_know,