-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.zig
More file actions
73 lines (62 loc) · 2.15 KB
/
Copy pathparser.zig
File metadata and controls
73 lines (62 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
const std = @import("std");
const writer = std.io.getStdOut().writer();
const eql = std.meta.eql;
const expect = std.testing.expect;
const scanner = @import("./scanner.zig");
const TokenTag = scanner.TokenTag;
const ParserError = error{
UnexpectedEOF,
UnknownToken,
};
pub const Parser = struct {
tokens: []const TokenTag,
pos: usize,
pub fn init(tokens: []const TokenTag) Parser {
return Parser{
.tokens = tokens,
.pos = 0,
};
}
fn eat(self: *Parser, tokenTag: TokenTag) ParserError!TokenTag {
const currentToken: TokenTag = self.tokens[self.pos];
if (@as(@typeInfo(TokenTag).Union.tag_type.?, tokenTag) != currentToken) {
return ParserError.UnknownToken;
}
self.pos += 1;
return currentToken;
}
pub fn parse(self: *Parser) !f64 {
return self.parseExpression(0);
}
fn parseExpression(self: *Parser, precedence: u8) ParserError!f64 {
var left = try self.prefix();
while (precedence < try self.infixPrecedence(self.tokens[self.pos])) {
left = try self.infix(&left, self.tokens[self.pos]);
}
return left;
}
fn prefix(self: *Parser) ParserError!f64 {
const numberToken = try self.eat(TokenTag{ .NUM = 0 });
return numberToken.NUM;
}
fn infix(self: *Parser, left: *f64, tokenTag: TokenTag) ParserError!f64 {
var token = try self.eat(tokenTag);
var newPrecedence = try self.infixPrecedence(tokenTag);
return switch (token) {
.ADD => left.* + try self.parseExpression(newPrecedence),
.MINUS => left.* - try self.parseExpression(newPrecedence),
.MULTIPLY => left.* * try self.parseExpression(newPrecedence),
.DIVISION => @divExact(left.*, try self.parseExpression(newPrecedence)),
else => 0,
};
}
fn infixPrecedence(self: *Parser, opToken: TokenTag) ParserError!u8 {
_ = self;
return switch (opToken) {
.EOF => 0,
.ADD, .MINUS => 2,
.MULTIPLY, .DIVISION => 3,
else => ParserError.UnknownToken,
};
}
};