parser

ソースコード

from titan_pylib.algorithm.parser import Parser

view on github

展開済みコード

  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)

仕様

class Parser(s: str)[source]

Bases: object

Examples

expression: < 四則演算の式 > ::= < 乗算除算の式 > (+ or -) < 乗算除算の式 > (+ or -) … term : < 乗算除算の式 > ::= < 括弧か数 > (* or /) < 括弧か数 > (* or /) … term2 など

factor : < 括弧か数 > ::= ‘(’ < 四則演算の式 > ‘)’ or < 数 > number : < 数 > ::= …

consume(expected: str) None[source]

begin が expected を指していたら begin を一つ進める。

expression() int[source]

四則演算の式をパースして、その評価結果を返す。

factor() int[source]

括弧か数をパースして、その評価結果を返す。

get_char() str[source]
number() int[source]

数字の列をパースして、その数を返す。

parse() int[source]
term() int[source]

乗算除算の式をパースして、その評価結果を返す。