实现解释器模式示例,添加抽象表达式、终结符表达式及解析器类,增强代码可读性
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
"""
|
||||
实例:
|
||||
定义一种运算符,减号是加法,加号是减法。
|
||||
"""
|
||||
|
||||
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======== 解释器模式结束 ========")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user