add error message to zig side of tokenizing/parsing

master
Travis 2020-10-29 11:04:50 -05:00
parent 960b5b518f
commit d7f9128b5d
4 changed files with 27 additions and 3 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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 "" {

View File

@ -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,
});