| author | |
| committer | |
| log | be392777b763028a02866342b12915a1e69ebdf1 |
| tree | 4282ef39d369811480bf2d74e9fef6a434d9f68c |
| parent | 91358f3092fb2004bb46572d44a0e377ed400565 |
| signature | Commit is signed but in an unrecognized format. |
3 files changed, 54 insertions(+), 2 deletions(-)
lib/std/zig/ast.zig+4| ... | ... | @@ -165,6 +165,7 @@ pub const Error = union(enum) { |
| 165 | 165 | ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap, |
| 166 | 166 | ExpectedSuffixOp: ExpectedSuffixOp, |
| 167 | 167 | DeclBetweenFields: DeclBetweenFields, |
| 168 | MissingComma: MissingComma, | |
| 168 | 169 | |
| 169 | 170 | pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void { |
| 170 | 171 | switch (self.*) { |
| ... | ... | @@ -213,6 +214,7 @@ pub const Error = union(enum) { |
| 213 | 214 | .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream), |
| 214 | 215 | .ExpectedSuffixOp => |*x| return x.render(tokens, stream), |
| 215 | 216 | .DeclBetweenFields => |*x| return x.render(tokens, stream), |
| 217 | .MissingComma => |*x| return x.render(tokens, stream), | |
| 216 | 218 | } |
| 217 | 219 | } |
| 218 | 220 | |
| ... | ... | @@ -263,6 +265,7 @@ pub const Error = union(enum) { |
| 263 | 265 | .ExpectedDerefOrUnwrap => |x| return x.token, |
| 264 | 266 | .ExpectedSuffixOp => |x| return x.token, |
| 265 | 267 | .DeclBetweenFields => |x| return x.token, |
| 268 | .MissingComma => |x| return x.token, | |
| 266 | 269 | } |
| 267 | 270 | } |
| 268 | 271 | |
| ... | ... | @@ -308,6 +311,7 @@ pub const Error = union(enum) { |
| 308 | 311 | pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier"); |
| 309 | 312 | pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier"); |
| 310 | 313 | pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields"); |
| 314 | pub const MissingComma = SimpleError("Expected comma between items"); | |
| 311 | 315 | |
| 312 | 316 | pub const ExpectedCall = struct { |
| 313 | 317 | node: *Node, |
lib/std/zig/parse.zig+26-2| ... | ... | @@ -1083,7 +1083,14 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1083 | 1083 | |
| 1084 | 1084 | var statements = Node.Block.StatementList.init(arena); |
| 1085 | 1085 | while (true) { |
| 1086 | const statement = (try parseStatement(arena, it, tree)) orelse break; | |
| 1086 | const statement = (parseStatement(arena, it, tree) catch |err| switch (err) { | |
| 1087 | error.OutOfMemory => return error.OutOfMemory, | |
| 1088 | error.ParseError => { | |
| 1089 | // try to skip to the next statement | |
| 1090 | findToken(it, .Semicolon); | |
| 1091 | continue; | |
| 1092 | }, | |
| 1093 | }) orelse break; | |
| 1087 | 1094 | try statements.push(statement); |
| 1088 | 1095 | } |
| 1089 | 1096 | |
| ... | ... | @@ -2816,7 +2823,24 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) { |
| 2816 | 2823 | var list = L.init(arena); |
| 2817 | 2824 | while (try nodeParseFn(arena, it, tree)) |node| { |
| 2818 | 2825 | try list.push(node); |
| 2819 | if (eatToken(it, .Comma) == null) break; | |
| 2826 | ||
| 2827 | const token = nextToken(it); | |
| 2828 | switch (token.ptr.id) { | |
| 2829 | .Comma => {}, | |
| 2830 | // all possible delimiters | |
| 2831 | .Colon, .RParen, .RBrace, .RBracket => { | |
| 2832 | putBackToken(it, token.index); | |
| 2833 | break; | |
| 2834 | }, | |
| 2835 | else => { | |
| 2836 | // this is likely just a missing comma, | |
| 2837 | // continue parsing this list and give an error | |
| 2838 | try tree.errors.push(.{ | |
| 2839 | .MissingComma = .{ .token = token.index }, | |
| 2840 | }); | |
| 2841 | putBackToken(it, token.index); | |
| 2842 | }, | |
| 2843 | } | |
| 2820 | 2844 | } |
| 2821 | 2845 | return list; |
| 2822 | 2846 | } |
lib/std/zig/parser_test.zig+24| ... | ... | @@ -6,6 +6,30 @@ test "zig fmt: fault tolerant parsing" { |
| 6 | 6 | .ExpectedInlinable, |
| 7 | 7 | .ExpectedInlinable, |
| 8 | 8 | }); |
| 9 | try testError( | |
| 10 | \\test "" { | |
| 11 | \\ foo + +; | |
| 12 | \\ inline; | |
| 13 | \\} | |
| 14 | , &[_]Error{ | |
| 15 | .InvalidToken, | |
| 16 | .ExpectedInlinable, | |
| 17 | }); | |
| 18 | try testError( | |
| 19 | \\test "" { | |
| 20 | \\ switch (foo) { | |
| 21 | \\ 2 => {} | |
| 22 | \\ 3 => {} | |
| 23 | \\ else => { | |
| 24 | \\ inline; | |
| 25 | \\ } | |
| 26 | \\ } | |
| 27 | \\} | |
| 28 | , &[_]Error{ | |
| 29 | .MissingComma, | |
| 30 | .MissingComma, | |
| 31 | .ExpectedInlinable, | |
| 32 | }); | |
| 9 | 33 | } |
| 10 | 34 | |
| 11 | 35 | test "zig fmt: top-level fields" { |