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