add error message to zig side of tokenizing/parsing
parent
960b5b518f
commit
d7f9128b5d
|
@ -171,6 +171,7 @@ pub const Error = union(enum) {
|
|||
ExpectedBlockOrField: ExpectedBlockOrField,
|
||||
DeclBetweenFields: DeclBetweenFields,
|
||||
InvalidAnd: InvalidAnd,
|
||||
AsteriskAfterPointerDereference: AsteriskAfterPointerDereference,
|
||||
|
||||
pub fn render(self: *const Error, tokens: []const Token.Id, stream: anytype) !void {
|
||||
switch (self.*) {
|
||||
|
@ -222,6 +223,7 @@ pub const Error = union(enum) {
|
|||
.ExpectedBlockOrField => |*x| return x.render(tokens, stream),
|
||||
.DeclBetweenFields => |*x| return x.render(tokens, stream),
|
||||
.InvalidAnd => |*x| return x.render(tokens, stream),
|
||||
.AsteriskAfterPointerDereference => |*x| return x.render(tokens, stream),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,6 +277,7 @@ pub const Error = union(enum) {
|
|||
.ExpectedBlockOrField => |x| return x.token,
|
||||
.DeclBetweenFields => |x| return x.token,
|
||||
.InvalidAnd => |x| return x.token,
|
||||
.AsteriskAfterPointerDereference => |x| return x.token,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,6 +326,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 InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
|
||||
pub const AsteriskAfterPointerDereference = SimpleError("`.*` can't be followed by `*`. Are you missing a space?");
|
||||
|
||||
pub const ExpectedCall = struct {
|
||||
node: *Node,
|
||||
|
|
|
@ -2701,6 +2701,13 @@ const Parser = struct {
|
|||
return &node.base;
|
||||
}
|
||||
|
||||
if (p.token_ids[p.tok_i] == .Invalid_periodasterisks) {
|
||||
try p.errors.append(p.gpa, .{
|
||||
.AsteriskAfterPointerDereference = .{ .token = p.tok_i },
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
if (p.eatToken(.Period)) |period| {
|
||||
if (try p.parseIdentifier()) |identifier| {
|
||||
const node = try p.arena.allocator.create(Node.SimpleInfixOp);
|
||||
|
|
|
@ -219,6 +219,17 @@ test "recovery: invalid global error set access" {
|
|||
});
|
||||
}
|
||||
|
||||
test "recovery: invalid asterisk after pointer dereference" {
|
||||
try testError(
|
||||
\\test "" {
|
||||
\\ var sequence = "repeat".*** 10;
|
||||
\\}
|
||||
, &[_]Error{
|
||||
.AsteriskAfterPointerDereference,
|
||||
.ExpectedToken,
|
||||
});
|
||||
}
|
||||
|
||||
test "recovery: missing semicolon after if, for, while stmt" {
|
||||
try testError(
|
||||
\\test "" {
|
||||
|
|
|
@ -78,6 +78,7 @@ pub const Token = struct {
|
|||
pub const Id = enum {
|
||||
Invalid,
|
||||
Invalid_ampersands,
|
||||
Invalid_periodasterisks,
|
||||
Identifier,
|
||||
StringLiteral,
|
||||
MultilineStringLiteralLine,
|
||||
|
@ -201,6 +202,7 @@ pub const Token = struct {
|
|||
return switch (id) {
|
||||
.Invalid => "Invalid",
|
||||
.Invalid_ampersands => "&&",
|
||||
.Invalid_periodasterisks => ".**",
|
||||
.Identifier => "Identifier",
|
||||
.StringLiteral => "StringLiteral",
|
||||
.MultilineStringLiteralLine => "MultilineStringLiteralLine",
|
||||
|
@ -1002,13 +1004,13 @@ pub const Tokenizer = struct {
|
|||
|
||||
.period_asterisk => switch (c) {
|
||||
'*' => {
|
||||
result.id = .Invalid;
|
||||
result.id = .Invalid_periodasterisks;
|
||||
break;
|
||||
},
|
||||
else => {
|
||||
result.id = .PeriodAsterisk;
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
.slash => switch (c) {
|
||||
|
@ -1794,7 +1796,7 @@ test "correctly parse pointer dereference followed by asterisk" {
|
|||
|
||||
testTokenize("\"b\".*** 10", &[_]Token.Id{
|
||||
.StringLiteral,
|
||||
.Invalid,
|
||||
.Invalid_periodasterisks,
|
||||
.AsteriskAsterisk,
|
||||
.IntegerLiteral,
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue