110 lines
3.1 KiB
Python
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======== 解释器模式结束 ========")
|
|
|
|
|