Improve parser error handling
This commit is contained in:
parent
7236c0b43a
commit
cb5d7c7798
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const token = @import("token.zig");
|
||||||
|
|
||||||
pub var hasError: bool = false;
|
pub var hasError: bool = false;
|
||||||
|
|
||||||
|
@ -6,7 +7,20 @@ pub fn err(line: u64, message: []const u8) void {
|
||||||
report(line, "", message);
|
report(line, "", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn report(line: u64, where: []u8, message: []const u8) void {
|
pub fn errToken(tok: token.Token, message: []const u8) void {
|
||||||
|
if (tok.token_type == token.TokenType.EOF) {
|
||||||
|
report(tok.line, " at end", message);
|
||||||
|
} else {
|
||||||
|
var buffer = [_]u8{0} ** 100;
|
||||||
|
const where = std.fmt.bufPrint(&buffer, " at '{s}'", .{tok.lexeme}) catch {
|
||||||
|
std.debug.print("Format error: buffer empty", .{});
|
||||||
|
std.process.exit(1);
|
||||||
|
};
|
||||||
|
report(tok.line, where, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn report(line: u64, where: []const u8, message: []const u8) void {
|
||||||
std.debug.print("[line {}] Error{s}: {s}\n", .{ line, where, message });
|
std.debug.print("[line {}] Error{s}: {s}\n", .{ line, where, message });
|
||||||
hasError = true;
|
hasError = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,10 @@ fn run(allocator: std.mem.Allocator, bytes: []u8) !void {
|
||||||
.allocator = alloc,
|
.allocator = alloc,
|
||||||
};
|
};
|
||||||
|
|
||||||
const expression = try parse.expression();
|
const expression = parse.parse();
|
||||||
// std.debug.print("AST: {}", .{expression.*});
|
if (err.hasError) {
|
||||||
expr.AstPrint(expression.*);
|
return;
|
||||||
|
}
|
||||||
|
expr.AstPrint(expression);
|
||||||
std.debug.print("\n", .{});
|
std.debug.print("\n", .{});
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,12 @@ const Token = token_zig.Token;
|
||||||
|
|
||||||
const errors_zig = @import("error.zig");
|
const errors_zig = @import("error.zig");
|
||||||
const err = errors_zig.err;
|
const err = errors_zig.err;
|
||||||
|
const errToken = errors_zig.errToken;
|
||||||
|
|
||||||
|
const ParseError = error{
|
||||||
|
UnmatchedParen,
|
||||||
|
UnexpectedToken,
|
||||||
|
};
|
||||||
|
|
||||||
pub const Parser = struct {
|
pub const Parser = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
@ -20,11 +26,20 @@ pub const Parser = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
current: u64 = 0,
|
current: u64 = 0,
|
||||||
|
|
||||||
pub fn expression(self: *Self) !*Expr {
|
pub fn parse(self: *Self) Expr {
|
||||||
|
var expr = self.expression() catch blk: {
|
||||||
|
break :blk &Expr{ .literal = LiteralExpr{
|
||||||
|
.nil = false,
|
||||||
|
} };
|
||||||
|
};
|
||||||
|
return expr.*;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expression(self: *Self) !*Expr {
|
||||||
return self.equality();
|
return self.equality();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn equality(self: *Self) !*Expr {
|
fn equality(self: *Self) !*Expr {
|
||||||
var expr = try self.comparison();
|
var expr = try self.comparison();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -128,7 +143,7 @@ pub const Parser = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn primary(self: *Self) error{OutOfMemory}!*Expr {
|
fn primary(self: *Self) error{ OutOfMemory, UnmatchedParen, UnexpectedToken }!*Expr {
|
||||||
var expr = try self.allocator.create(Expr);
|
var expr = try self.allocator.create(Expr);
|
||||||
const token = self.advance();
|
const token = self.advance();
|
||||||
switch (token.token_type) {
|
switch (token.token_type) {
|
||||||
|
@ -143,12 +158,13 @@ pub const Parser = struct {
|
||||||
};
|
};
|
||||||
var next_token = self.advance();
|
var next_token = self.advance();
|
||||||
if (next_token.token_type != TokenType.RIGHT_PAREN) {
|
if (next_token.token_type != TokenType.RIGHT_PAREN) {
|
||||||
err(next_token.line, "Unclosed left paren.");
|
errToken(next_token, "Unclosed left paren.");
|
||||||
|
return ParseError.UnmatchedParen;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
err(token.line, "Unexpected primary token type.");
|
errToken(token, "Unexpected token.");
|
||||||
expr.* = Expr{ .literal = LiteralExpr{ .nil = false } };
|
return ParseError.UnexpectedToken;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return expr;
|
return expr;
|
||||||
|
|
Loading…
Reference in New Issue