continue parsing on invalid and token

This commit is contained in:
Vexu 2020-05-13 17:36:06 +03:00
parent be392777b7
commit cefc04348e
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
3 changed files with 22 additions and 15 deletions

View File

@ -166,6 +166,7 @@ pub const Error = union(enum) {
ExpectedSuffixOp: ExpectedSuffixOp,
DeclBetweenFields: DeclBetweenFields,
MissingComma: MissingComma,
InvalidAnd: InvalidAnd,
pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
switch (self.*) {
@ -215,6 +216,7 @@ pub const Error = union(enum) {
.ExpectedSuffixOp => |*x| return x.render(tokens, stream),
.DeclBetweenFields => |*x| return x.render(tokens, stream),
.MissingComma => |*x| return x.render(tokens, stream),
.InvalidAnd => |*x| return x.render(tokens, stream),
}
}
@ -266,6 +268,7 @@ pub const Error = union(enum) {
.ExpectedSuffixOp => |x| return x.token,
.DeclBetweenFields => |x| return x.token,
.MissingComma => |x| return x.token,
.InvalidAnd => |x| return x.token,
}
}
@ -312,6 +315,7 @@ pub const Error = union(enum) {
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
pub const MissingComma = SimpleError("Expected comma between items");
pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
pub const ExpectedCall = struct {
node: *Node,
@ -339,9 +343,6 @@ pub const Error = union(enum) {
pub fn render(self: *const ExpectedToken, tokens: *Tree.TokenList, stream: var) !void {
const found_token = tokens.at(self.token);
switch (found_token.id) {
.Invalid_ampersands => {
return stream.print("`&&` is invalid. Note that `and` is boolean AND.", .{});
},
.Invalid => {
return stream.print("expected '{}', found invalid bytes", .{self.expected_id.symbol()});
},

View File

@ -2824,21 +2824,16 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
while (try nodeParseFn(arena, it, tree)) |node| {
try list.push(node);
const token = nextToken(it);
switch (token.ptr.id) {
.Comma => {},
switch (it.peek().?.id) {
.Comma => _ = nextToken(it),
// all possible delimiters
.Colon, .RParen, .RBrace, .RBracket => {
putBackToken(it, token.index);
break;
},
.Colon, .RParen, .RBrace, .RBracket => break,
else => {
// this is likely just a missing comma,
// continue parsing this list and give an error
try tree.errors.push(.{
.MissingComma = .{ .token = token.index },
.MissingComma = .{ .token = it.index },
});
putBackToken(it, token.index);
},
}
}
@ -2850,7 +2845,17 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
fn SimpleBinOpParseFn(comptime token: Token.Id, comptime op: Node.InfixOp.Op) NodeParseFn {
return struct {
pub fn parse(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*Node {
const op_token = eatToken(it, token) orelse return null;
const op_token = if (token == .Keyword_and) switch (it.peek().?.id) {
.Keyword_and => nextToken(it).index,
.Invalid_ampersands => blk: {
try tree.errors.push(.{
.InvalidAnd = .{ .token = it.index },
});
break :blk nextToken(it).index;
},
else => return null,
} else eatToken(it, token) orelse return null;
const node = try arena.create(Node.InfixOp);
node.* = .{
.op_token = op_token,

View File

@ -21,14 +21,15 @@ test "zig fmt: fault tolerant parsing" {
\\ 2 => {}
\\ 3 => {}
\\ else => {
\\ inline;
\\ foo && bar +;
\\ }
\\ }
\\}
, &[_]Error{
.MissingComma,
.MissingComma,
.ExpectedInlinable,
.InvalidAnd,
.InvalidToken,
});
}