解释器模式 python 表达式计算

GoF定义:
定义语言的文法 ,并且建立一个解释器来解释该语言中的句子.

在GOF的书中指出:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。而且当文法简单、效率不是关键问题的时候效果最好。 

更多相关资料:http://www.cnblogs.com/cbf4life/archive/2009/12/17/1626125.html

import sys
class priority:#定义符号优先级
    symbol = '#+-*/%()'
    def getisp(self,a):#栈内优先权
        if '#'.find(a)!=-1: return 0
        if '('.find(a)!=-1: return 1
        if '-+'.find(a)!=-1: return 3
        if '*/%'.find(a)!=-1: return 5
        if ')'.find(a)!=-1: return 6
    def geticp(self,a): #栈外优先权
        if '#'.find(a)!=-1: return 0
        if '('.find(a)!=-1: return 6
        if '-+'.find(a)!=-1: return 2
        if '*/%'.find(a)!=-1: return 4
        if ')'.find(a)!=-1: return 1

class Expression:#抽象类
    def interpreter():
        pass

class VarExpression(Expression):#数字,终结表达式
    def __init__(self,_key):
        self.key=_key
    def interpreter(self):
        return self.key

class SymbolExpression(Expression):#运算类基类
    def __init__(self,_left,_right):
        self.left = _left
        self.right = _right

class SubExpression(SymbolExpression):#减
    def __init__(self,_left,_right):
        self.parent=SymbolExpression(_left,_right)
    def interpreter(self):
        return self.parent.left.interpreter()-self.parent.right.interpreter()

class AddExpression(SymbolExpression):#加
    def __init__(self,_left,_right):
        self.parent=SymbolExpression(_left,_right)
    def interpreter(self):
        return self.parent.left.interpreter()+self.parent.right.interpreter()

class MulExpression(SymbolExpression):#乘
    def __init__(self,_left,_right):
        self.parent=SymbolExpression(_left,_right)
    def interpreter(self):
        return self.parent.left.interpreter()*self.parent.right.interpreter()

class DivExpression(SymbolExpression):#除
    def __init__(self,_left,_right):
        self.parent=SymbolExpression(_left,_right)
    def interpreter(self):
        return self.parent.left.interpreter()/self.parent.right.interpreter()

class ModExpression(SymbolExpression):#取余
    def __init__(self,_left,_right):
        self.parent=SymbolExpression(_left,_right)
    def interpreter(self):
        return self.parent.left.interpreter()%self.parent.right.interpreter()

class Calculator:
    exp=''
    order=[]
    def __init__(self,_exp):
        _exp = _exp.replace(' ','')
        self.exp=_exp
        _exp=_exp+'#'
        i=0
        f=0
        p=1
        tmp = 0
        stack='#'
        order=[]
        pty = priority()
        while len(stack)>0:
            if pty.symbol.find(_exp[i])!=-1:
                if f>0:order = order+[tmp]
                f = 0
                p=1
                tmp = 0
                ch = _exp[i]
                ch1 = stack[-1]
                #print (ch1,' ',pty.getisp(ch1),' ',pty.geticp(ch))
                if pty.getisp(ch1)<pty.geticp(ch):
                    stack=stack+ch
                    i=i+1
                elif pty.getisp(ch1)>pty.geticp(ch):
                    order = order+[stack[-1]]
                    stack = stack[0:-1]
                else :
                    if stack[-1]=='(': i=i+1
                    stack = stack[0:-1]
            else :
                if f==0: f = 1
                if _exp[i]=='.':
                    f = 2
                elif f==1:
                    tmp = tmp*10 +int(_exp[i])-int('0')
                else:
                    p = p*0.1
                    tmp = tmp+(int(_exp[i])-int('0'))*p
                i=i+1
        print (order) #order 为后缀表达式
        self.order=order
        stack=[]
        for i in order:#创建递归树
            if pty.symbol.find(str(i))!=-1:
                right = stack[-1] # 把栈中连个元素取出
                left = stack[-2]
                stack = stack[0:-2]
                if '+'.find(str(i))!=-1:
                    stack = stack+[AddExpression(left,right)]
                elif '-'.find(str(i))!=-1:
                    stack = stack+[SubExpression(left,right)]
                elif '*'.find(str(i))!=-1:
                    stack = stack+[MulExpression(left,right)]
                elif '/'.find(str(i))!=-1:
                    stack = stack+[DivExpression(left,right)]
                elif '%'.find(str(i))!=-1:
                    stack = stack+[ModExpression(left,right)]
            else :
                stack=stack+[VarExpression(i)]
        self.expression = stack[0]
    
    def run(self):#计算递归树
        return self.expression.interpreter()
def Client():
    a=input("请输入正确表达式:eg:1*(2+3):\n")
    cal = Calculator(a)
    print (a,"=",cal.run())

Client()


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解释器模式是一种设计模式,它允许我们定义一种语言,并且可以使用该语言来解释和执行特定的任务。该模式适用于需要实现复杂语言处理的场景,例如编译器、解析器、计算器等。 实现解释器模式需要以下几个元素: - 抽象表达式(Abstract Expression):定义解释器的接口,通常包括一个解释方法(interpret),该方法的参数通常为一个上下文(Context)对象。 - 终结符表达式(Terminal Expression):表示语言中的基本单元,例如变量、常量等。 - 非终结符表达式(Nonterminal Expression):表示语言中的复合结构,通常由多个终结符表达式组成。 - 上下文(Context):保存解释器解释时所需的状态和信息。 下面是一个简单的例子,假设我们需要计算一个简单的四则运算表达式: ```python # 定义抽象表达式 class Expression: def interpret(self, context): pass # 定义终结符表达式 class Number(Expression): def __init__(self, number): self.number = number def interpret(self, context): return int(self.number) # 定义非终结符表达式 class Plus(Expression): def __init__(self, left, right): self.left = left self.right = right def interpret(self, context): return self.left.interpret(context) + self.right.interpret(context) # 定义上下文 class Context: def __init__(self, text): self.text = text def next(self): if len(self.text) > 0: return self.text.pop(0) else: return None ``` 在上面的代码中,我们定义了一个抽象表达式类 `Expression`,包含一个 `interpret` 方法;终结符表达式 `Number`,表示一个数字;非终结符表达式 `Plus`,表示加法运算;以及上下文类 `Context`,保存语言的状态和信息。 接下来,我们可以使用这些类来解释一个四则运算表达式: ```python # 创建表达式 expr1 = Plus(Number(3), Number(4)) expr2 = Plus(Number(2), expr1) # 创建上下文 context = Context(list(str(expr2.interpret(None)))) # 输出结果 print(expr2.interpret(context)) # 9 ``` 在上面的代码中,我们首先创建了一个四则运算表达式 `2 + 3 + 4`,然后使用上下文类 `Context` 将其转换为一个字符列表 `[2, +, 3, +, 4]`,最后通过调用 `interpret` 方法计算表达式的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值