mirror of
https://github.com/ziglang/zig.git
synced 2025-12-17 03:33:06 +00:00
continue parsing after missing commas and invalid statements
This commit is contained in:
parent
91358f3092
commit
be392777b7
@ -165,6 +165,7 @@ pub const Error = union(enum) {
|
|||||||
ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
|
ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
|
||||||
ExpectedSuffixOp: ExpectedSuffixOp,
|
ExpectedSuffixOp: ExpectedSuffixOp,
|
||||||
DeclBetweenFields: DeclBetweenFields,
|
DeclBetweenFields: DeclBetweenFields,
|
||||||
|
MissingComma: MissingComma,
|
||||||
|
|
||||||
pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
|
pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
@ -213,6 +214,7 @@ pub const Error = union(enum) {
|
|||||||
.ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
|
.ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
|
||||||
.ExpectedSuffixOp => |*x| return x.render(tokens, stream),
|
.ExpectedSuffixOp => |*x| return x.render(tokens, stream),
|
||||||
.DeclBetweenFields => |*x| return x.render(tokens, stream),
|
.DeclBetweenFields => |*x| return x.render(tokens, stream),
|
||||||
|
.MissingComma => |*x| return x.render(tokens, stream),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +265,7 @@ pub const Error = union(enum) {
|
|||||||
.ExpectedDerefOrUnwrap => |x| return x.token,
|
.ExpectedDerefOrUnwrap => |x| return x.token,
|
||||||
.ExpectedSuffixOp => |x| return x.token,
|
.ExpectedSuffixOp => |x| return x.token,
|
||||||
.DeclBetweenFields => |x| return x.token,
|
.DeclBetweenFields => |x| return x.token,
|
||||||
|
.MissingComma => |x| return x.token,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,6 +311,7 @@ pub const Error = union(enum) {
|
|||||||
pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
|
pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
|
||||||
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
|
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
|
||||||
pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
|
pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
|
||||||
|
pub const MissingComma = SimpleError("Expected comma between items");
|
||||||
|
|
||||||
pub const ExpectedCall = struct {
|
pub const ExpectedCall = struct {
|
||||||
node: *Node,
|
node: *Node,
|
||||||
|
|||||||
@ -1083,7 +1083,14 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
|||||||
|
|
||||||
var statements = Node.Block.StatementList.init(arena);
|
var statements = Node.Block.StatementList.init(arena);
|
||||||
while (true) {
|
while (true) {
|
||||||
const statement = (try parseStatement(arena, it, tree)) orelse break;
|
const statement = (parseStatement(arena, it, tree) catch |err| switch (err) {
|
||||||
|
error.OutOfMemory => return error.OutOfMemory,
|
||||||
|
error.ParseError => {
|
||||||
|
// try to skip to the next statement
|
||||||
|
findToken(it, .Semicolon);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
}) orelse break;
|
||||||
try statements.push(statement);
|
try statements.push(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2816,7 +2823,24 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
|
|||||||
var list = L.init(arena);
|
var list = L.init(arena);
|
||||||
while (try nodeParseFn(arena, it, tree)) |node| {
|
while (try nodeParseFn(arena, it, tree)) |node| {
|
||||||
try list.push(node);
|
try list.push(node);
|
||||||
if (eatToken(it, .Comma) == null) break;
|
|
||||||
|
const token = nextToken(it);
|
||||||
|
switch (token.ptr.id) {
|
||||||
|
.Comma => {},
|
||||||
|
// all possible delimiters
|
||||||
|
.Colon, .RParen, .RBrace, .RBracket => {
|
||||||
|
putBackToken(it, token.index);
|
||||||
|
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 },
|
||||||
|
});
|
||||||
|
putBackToken(it, token.index);
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,30 @@ test "zig fmt: fault tolerant parsing" {
|
|||||||
.ExpectedInlinable,
|
.ExpectedInlinable,
|
||||||
.ExpectedInlinable,
|
.ExpectedInlinable,
|
||||||
});
|
});
|
||||||
|
try testError(
|
||||||
|
\\test "" {
|
||||||
|
\\ foo + +;
|
||||||
|
\\ inline;
|
||||||
|
\\}
|
||||||
|
, &[_]Error{
|
||||||
|
.InvalidToken,
|
||||||
|
.ExpectedInlinable,
|
||||||
|
});
|
||||||
|
try testError(
|
||||||
|
\\test "" {
|
||||||
|
\\ switch (foo) {
|
||||||
|
\\ 2 => {}
|
||||||
|
\\ 3 => {}
|
||||||
|
\\ else => {
|
||||||
|
\\ inline;
|
||||||
|
\\ }
|
||||||
|
\\ }
|
||||||
|
\\}
|
||||||
|
, &[_]Error{
|
||||||
|
.MissingComma,
|
||||||
|
.MissingComma,
|
||||||
|
.ExpectedInlinable,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "zig fmt: top-level fields" {
|
test "zig fmt: top-level fields" {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user