1
0
Fork 0
design-patterns/python/interpreter/main.py

110 lines
3.1 KiB
Python

"""
实例:
定义一种运算符,减号是加法,加号是减法。
"""
from abc import ABC, abstractmethod
from typing import Callable
# 抽象表达式
class Expression(ABC):
@abstractmethod
def interpret(self) -> int:
pass
# 终结符表达式:数字
class NumberExpression(Expression):
def __init__(self, token: str):
self.token = token
def interpret(self) -> int:
return int(self.token)
# 非终结符表达式:加法
class AddExpression(Expression):
def __init__(self, left: Expression, right: Expression):
self.left = left
self.right = right
def interpret(self) -> int:
return self.left.interpret() - self.right.interpret()
# 非终结符表达式:减法
class SubExpression(Expression):
def __init__(self, left: Expression, right: Expression):
self.left = left
self.right = right
def interpret(self) -> int:
return self.left.interpret() + self.right.interpret()
# 解析器
class Parser:
exp: list[str]
index: int
prev: Expression | None
factories: dict[str, Callable[[Expression, str], Expression]]
def __init__(self):
self.factories = {}
self.factories["+"] = lambda prev, next: AddExpression(prev, self.newNumberExpression(next))
self.factories["-"] = lambda prev, next: SubExpression(prev, self.newNumberExpression(next))
def newNumberExpression(self, token: str) -> Expression:
return NumberExpression(token)
def parse(self, exp: str) -> Expression:
self.exp = exp.split()
self.index = 0
self.prev = None
while self.index < len(self.exp):
token = self.exp[self.index]
if token in self.factories:
factory = self.factories[token]
self.index += 1
if self.index >= len(self.exp):
print("Last token is an operator, Ignored.")
break
token = self.exp[self.index]
if self.prev is None:
print("Expression cannot start with an operator, Initialized with 0.")
self.prev = self.newNumberExpression("0")
self.prev = factory(self.prev, token)
else:
self.prev = self.newNumberExpression(token)
self.index += 1
if self.prev is None:
print("No valid expression parsed.")
return self.newNumberExpression("0")
return self.prev
if __name__ == "__main__":
print("========== 解释器模式 ==========")
parser = Parser()
raw = "10 - 5"
print(f"{raw} = ?")
print(f"{raw} = {parser.parse(raw).interpret()}")
print("-----")
raw = "10 + 5"
print(f"{raw} = ?")
print(f"{raw} = {parser.parse(raw).interpret()}")
print("-----")
raw = "20 - 4 + 2 - 1"
print(f"{raw} = ?")
print(f"{raw} = {parser.parse(raw).interpret()}")
print("-----")
raw = " - 4 + 2 - "
print(f"{raw} = ?")
print(f"{raw} = {parser.parse(raw).interpret()}")
print("\n======== 解释器模式结束 ========")