reuse parser
This commit is contained in:
parent
3eb8983028
commit
67b91df174
|
|
@ -54,18 +54,18 @@ fn prefix_atom(parser: *Parser, _: u32, tok: Token) Error!*const Expr {
|
||||||
return try parser.make_expr(.{ .atom = tok });
|
return try parser.make_expr(.{ .atom = tok });
|
||||||
}
|
}
|
||||||
fn prefix_paren(parser: *Parser, _: u32, _: Token) Error!*const Expr {
|
fn prefix_paren(parser: *Parser, _: u32, _: Token) Error!*const Expr {
|
||||||
const expr = try parser.parse(0);
|
const expr = try parser.parse_expr(0);
|
||||||
if (parser.tokenizer.next().kind != op_kind(")")) {
|
if (parser.tokenizer.next().kind != op_kind(")")) {
|
||||||
return Error.SyntaxError;
|
return Error.SyntaxError;
|
||||||
}
|
}
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
fn prefix_unop(parser: *Parser, precedence: u32, tok: Token) Error!*const Expr {
|
fn prefix_unop(parser: *Parser, precedence: u32, tok: Token) Error!*const Expr {
|
||||||
const expr = try parser.parse(precedence);
|
const expr = try parser.parse_expr(precedence);
|
||||||
return try parser.make_expr(.{ .unop = .{ .expr = expr, .op = tok } });
|
return try parser.make_expr(.{ .unop = .{ .expr = expr, .op = tok } });
|
||||||
}
|
}
|
||||||
fn infix_binop(parser: *Parser, precedence: u32, lhs: *const Expr, tok: Token) Error!*const Expr {
|
fn infix_binop(parser: *Parser, precedence: u32, lhs: *const Expr, tok: Token) Error!*const Expr {
|
||||||
const rhs = try parser.parse(precedence);
|
const rhs = try parser.parse_expr(precedence);
|
||||||
return try parser.make_expr(.{ .binop = .{ .lhs = lhs, .rhs = rhs, .op = tok } });
|
return try parser.make_expr(.{ .binop = .{ .lhs = lhs, .rhs = rhs, .op = tok } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,7 +73,11 @@ pub const Parser = struct {
|
||||||
tokenizer: token.Tokenizer,
|
tokenizer: token.Tokenizer,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
ops: std.AutoHashMap(TokenKind, Operator),
|
ops: std.AutoHashMap(TokenKind, Operator),
|
||||||
pub fn parse(self: *Parser, precedence: u32) Error!*const Expr {
|
pub fn parse(self: *Parser, src: []const u8) Error!*const Expr {
|
||||||
|
self.tokenizer = token.Tokenizer.init(src, self.ops);
|
||||||
|
return self.parse_expr(0);
|
||||||
|
}
|
||||||
|
fn parse_expr(self: *Parser, precedence: u32) Error!*const Expr {
|
||||||
const tok = self.tokenizer.next();
|
const tok = self.tokenizer.next();
|
||||||
const prefix = self.ops.get(tok.kind) orelse return Error.InvalidOp;
|
const prefix = self.ops.get(tok.kind) orelse return Error.InvalidOp;
|
||||||
var left = try prefix.parse_prefix(self, prefix.precedence, tok);
|
var left = try prefix.parse_prefix(self, prefix.precedence, tok);
|
||||||
|
|
@ -99,13 +103,14 @@ pub const Parser = struct {
|
||||||
const op_p = try self.ops.getOrPutValue(op_kind(op), .{ .precedence = precedence });
|
const op_p = try self.ops.getOrPutValue(op_kind(op), .{ .precedence = precedence });
|
||||||
op_p.value_ptr.parse_infix = infix_binop;
|
op_p.value_ptr.parse_infix = infix_binop;
|
||||||
}
|
}
|
||||||
pub fn init(src: []const u8, allocator: std.mem.Allocator) !Parser {
|
pub fn init(allocator: std.mem.Allocator) !Parser {
|
||||||
const ops = std.AutoHashMap(TokenKind, Operator).init(allocator);
|
const ops = std.AutoHashMap(TokenKind, Operator).init(allocator);
|
||||||
var p = Parser{ .tokenizer = token.Tokenizer.init(src, ops), .allocator = allocator, .ops = ops };
|
var p = Parser{ .tokenizer = undefined, .allocator = allocator, .ops = ops };
|
||||||
|
|
||||||
try p.ops.put(TokenKind.name, .{ .parse_prefix = prefix_atom });
|
try p.ops.put(TokenKind.name, .{ .parse_prefix = prefix_atom });
|
||||||
try p.ops.put(TokenKind.number, .{ .parse_prefix = prefix_atom });
|
try p.ops.put(TokenKind.number, .{ .parse_prefix = prefix_atom });
|
||||||
try p.ops.put(op_kind("("), .{ .parse_prefix = prefix_paren });
|
try p.ops.put(op_kind("("), .{ .parse_prefix = prefix_paren });
|
||||||
|
try p.ops.put(op_kind(")"), .{});
|
||||||
try p.register_unop("+", 4);
|
try p.register_unop("+", 4);
|
||||||
try p.register_unop("-", 4);
|
try p.register_unop("-", 4);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ pub fn main() !void {
|
||||||
const content = try file.readToEndAlloc(allocator, std.math.maxInt(usize));
|
const content = try file.readToEndAlloc(allocator, std.math.maxInt(usize));
|
||||||
defer allocator.free(content);
|
defer allocator.free(content);
|
||||||
|
|
||||||
var p = try lib.parse.Parser.init(content, allocator);
|
var p = try lib.parse.Parser.init(allocator);
|
||||||
defer p.free();
|
defer p.free();
|
||||||
std.debug.print("{}\n", .{(try p.parse(0)).eval(content)});
|
std.debug.print("{}\n", .{(try p.parse(content)).eval(content)});
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue