Source code for titan_pylib.algorithm.parser
[docs]
1class Parser:
2 """Parser
3
4 Examples:
5 expression: < 四則演算の式 > ::= < 乗算除算の式 > (+ or -) < 乗算除算の式 > (+ or -) ...
6 term : < 乗算除算の式 > ::= < 括弧か数 > (* or /) < 括弧か数 > (* or /) ...
7 term2 など
8
9 factor : < 括弧か数 > ::= '(' < 四則演算の式 > ')' or < 数 >
10 number : < 数 > ::= ...
11 """
12
13 def __init__(self, s: str) -> None:
14 self.s: str = s
15 self.n: int = len(s)
16 self.ptr: int = 0
17
[docs]
18 def parse(self) -> int:
19 return self.expression()
20
[docs]
21 def expression(self) -> int:
22 """四則演算の式をパースして、その評価結果を返す。"""
23 ret = self.term()
24 while self.ptr < self.n:
25 if self.get_char() == "+":
26 self.consume("+")
27 ret += self.term()
28 elif self.get_char() == "-":
29 self.consume("-")
30 ret -= self.term()
31 else:
32 break
33 return ret
34
[docs]
35 def term(self) -> int:
36 """乗算除算の式をパースして、その評価結果を返す。"""
37 ret = self.factor()
38 while self.ptr < self.n:
39 if self.get_char() == "*":
40 self.consume("*")
41 ret *= self.factor()
42 elif self.get_char() == "/":
43 self.consume("/")
44 ret = ret // self.factor() # 切り捨て
45 else:
46 break
47 return ret
48
[docs]
49 def factor(self) -> int:
50 """括弧か数をパースして、その評価結果を返す。"""
51 if self.ptr >= self.n:
52 return 0
53 if self.get_char() == "(":
54 self.consume("(")
55 ret = self.expression()
56 self.consume(")")
57 return ret
58 else:
59 return self.number()
60
[docs]
61 def number(self) -> int:
62 """数字の列をパースして、その数を返す。"""
63 ret = 0
64 while self.ptr < self.n and self.get_char().isdigit():
65 ret *= 10
66 ret += int(self.get_char())
67 self.ptr += 1
68 return ret
69
[docs]
70 def consume(self, expected: str) -> None:
71 """begin が expected を指していたら begin を一つ進める。"""
72 assert (
73 self.s[self.ptr] == expected
74 ), f"Expected: {expected} but got {self.s[self.ptr]}, s={self.s}"
75 self.ptr += 1
76
[docs]
77 def get_char(self) -> str:
78 return self.s[self.ptr]
79
80
81# import sys
82# from lark import Lark
83# from lark import Transformer
84# from functools import reduce
85
86
87# class CalcTransformer(Transformer):
88# def expr(self, tree):
89# return reduce(lambda x, y: x + y, tree)
90
91# def term(self, tree):
92# return reduce(lambda x, y: x * y, tree)
93
94# def factor(self, tree):
95# return tree[0]
96
97# def number(self, tree):
98# return int(tree[0])
99
100
101# G = """
102# expr : term [ "+" expr ]
103# term : factor [ "*" term ]
104# factor : number | "(" expr ")"
105# number : /[0-9]+/
106# """
107
108# text = "(1+5)*3+2"
109# parser = Lark(G, start="expr")
110# tree = parser.parse(text)
111# print(tree)
112# result = CalcTransformer().transform(tree)
113# print(result)