python开辟肆意抒发式求值全功效示例
注释
在之前的根本奇趣5分彩进一步完奇趣5分彩了全功效抒发式求值。
- 已撑持浮点数
- 已撑持字符串的处置,前加一个"(近似lisp语法)
- 撑持减号/负号,一符两用机制
- 撑持一切算术运算符,包含**,//, %
- 撑持全数7个比拟运算符
- 撑持与或非3个逻辑运算符
- 撑持自界说数学函数(代码奇趣5分彩预设sin函数作为树模)
- 撑持内部供给的变量机制
- 撑持内部设置函数(代码奇趣5分彩预设isvar函数作为树模)
- 撑持列表
- 字典的撑持,表现在内部的变量奇趣5分彩
- 布局清楚,易于扩大
- 具备适用性及进奇趣5分彩惯
与其说间隔DSL只要一步之遥,不如说,DSL机制已完奇趣5分彩。由于能够或许或许肆意扩大函数,而函数的内容
完全能够或许或许自行界说。
以是同享给大师,接待定见和倡议。
完全的源代码
import math opDict={} def addoptr(ch, outLev, inLev, func, parmNum=2): obj= {'name':ch, 'out':outLev, 'in':inLev, 'func':func, 'parmNum':parmNum} opDict[ch]= obj def makeList(x): if isinstance(x[-2], list): x[-2].append(x[-1]) return x[-2].copy() else: ret= [] ret.append(x[-2]) ret.append(x[-1]) return ret addoptr('#', 1, 1, None) addoptr('(', 90, 2, None) addoptr(')', 2, None, None) addoptr('[', 90, 2, None) addoptr(']', 2, 2, None) addoptr(',', 8, 9, makeList) addoptr('&', 13, 14, lambda x: x[-1] and x[-2]) addoptr('and', 13, 14, lambda x: x[-1] and x[-2]) addoptr('|', 11, 12, lambda x: x[-1] or x[-2]) addoptr('or', 11, 12, lambda x: x[-1] or x[-2]) addoptr('~', 16, 17, lambda x: not x[-1],1) addoptr('not', 16, 17, lambda x: not x[-1],1) addoptr('=', 22, 23, lambda x: x[-1]==x[-2]) addoptr('>', 22, 23, lambda x: x[-2]>x[-1]) addoptr('<', 22, 23, lambda x: x[-2]<x[-1]) addoptr('>=', 22, 23, lambda x: x[-2]>=x[-1]) addoptr('<=', 22, 23, lambda x: x[-2]<=x[-1]) addoptr('!=', 22, 23, lambda x: x[-2]!=x[-1]) addoptr('<>', 22, 23, lambda x: x[-2]!=x[-1]) addoptr('in', 22, 23, lambda x: x[-2] in x[-1]) addoptr('+', 31, 32, lambda x: x[-2]+x[-1]) addoptr('-', 31, 32, lambda x: x[-2]-x[-1]) addoptr('*', 41, 42, lambda x: x[-2]*x[-1]) addoptr('/', 41, 42, lambda x: x[-2]/x[-1]) addoptr('//', 41, 42, lambda x: x[-2]//x[-1]) addoptr('%', 41, 42, lambda x: x[-2]%x[-1]) addoptr('neg', 51, 52, lambda x: -x[-1],1) addoptr('**', 55, 56, lambda x: x[-2]**x[-1]) addoptr('sin', 61, 62, lambda x: math.sin(x[-1]),1) alphabet= [chr(ord('a')+x) for x in range(26)]+[chr(ord('A')+x) for x in range(26)] # print(opChar) # print(opSep) # print(alphabet) def isfloat(str1): try: number = float(str1) except ValueError: return False return True class exprEngine: def __init__(this, isVar=None, getValue=None): this.opndStack=[] this.optrStack=[] this.isVar= isVar this.getValue= getValue # 这个状况,特为负号/减号这一特别符的双寄义号所设置 this.negState=0 # 内建函数 if isVar: addoptr('isvar', 61, 62, lambda x: isVar(x[-1]),1) # 处置辨认 this.oplen= len(max(opDict, key=lambda x:len(x))) this.opChar=[] for i in range(this.oplen): tmp=[x[0:i+1] for x in opDict if len(x)>=i+1] this.opChar.append(tmp) this.opSep= [x[0] for x in opDict if x[0] not in alphabet]+[' ', '\t'] print(this.oplen) print(this.opChar) print(this.opSep) def readWord(this, cond): cond= cond.strip() if cond=='': return '', '#' if cond[0] in this.opChar[0]: l1=this.oplen for i in range(this.oplen): if cond[:i+1] not in this.opChar[i]: l1= i break print(l1) if cond[:l1] in this.opChar[l1-1]: return cond[:l1], 'optr' part= '' for ch in cond: if ch in this.opSep: break part+=ch return part, 'opnd' def pushoptr(this, optr): # 对负号/减号的特别处置 if optr=='-' and this.negState==0: # 这类环境,现实的寄义是负号 optr= 'neg' op= opDict[optr].copy() if len(this.optrStack)==0: this.optrStack.append(op) return opTop= this.optrStack[-1] if op['out']> opTop['in']: this.optrStack.append(op) elif op['out']< opTop['in']: this.popoptr() # 这里递归 this.pushoptr(optr) elif op['out']== opTop['in']: # 消括号对,简略弹出 this.optrStack.pop() this.negState=0 def popoptr(this): opTop= this.optrStack[-1] a= opTop['parmNum'] if len(this.opndStack)<a: raise Exception('操纵数缺乏,能够奇趣5分彩语法毛病!') ret= opTop['func'](this.opndStack[-a:]) this.opndStack= this.opndStack[:-a] this.opndStack.append(ret) this.optrStack.pop() def pushopnd(this, opnd): if opnd[0]=='"': # 必定是字符串 this.opndStack.append(opnd[1:]) elif this.isVar and this.isVar(opnd): this.opndStack.append(this.getValue(opnd)) else: if opnd.isdigit(): this.opndStack.append(int(opnd)) elif isfloat(opnd): this.opndStack.append(float(opnd)) else: this.opndStack.append(opnd) this.negState=1 def popopnd(this): if len(this.opndStack)==1: return this.opndStack[0] else: print(this.opndStack) print(this.optrStack) raise Exception('能够存在语法毛病。') def eval(this, cond): this.optrStack=[] this.opndStack=[] this.pushoptr('#') while True: aword,kind= this.readWord(cond) print(aword, cond) cond= cond[len(aword):].strip() if kind=='#': this.pushoptr('#') break elif kind=='optr': this.pushoptr(aword) else: if aword=='': raise Exception('操纵数为奇趣5分彩,必定奇趣5分彩那里错了。') this.pushopnd(aword) print(this.optrStack) print(this.opndStack) return this.popopnd() if __name__=='__main__': # print(opDict) a= exprEngine() # a.addInfo('水位', '低') # b= a.eval('3 + 5 *2 = 13 and (3+5)*2=16 & 7-2 in [3,5,7] & 12>=15 or a in [a, b,c]') # b= a.eval('sin(-1)<1 and 3+-5=-2') # print(b) # b= a.eval('7*-3') b= a.eval('3**3=27 and 19%5=4 and 21//6=3') print(b)
以上便是python开辟肆意抒发式求值全功效示例的具体内容,更多对于python抒发式求值的材料请存眷剧本之奇趣5分彩别的相干文章!
相干文章
奇趣5分彩:Python利用Slider奇趣5分彩件完奇趣5分彩调剂曲线参数功效示例
这篇文章首要先容了Python利用Slider奇趣5分彩件完奇趣5分彩调剂曲线参数功效,连奇趣5分彩实例情势阐发了Python利用matplotlib与Slider奇趣5分彩件停止图形绘制相干操纵技能,须要的伴侣能够或许或许参考下2019-09-09在Python的Flask框架奇趣5分彩考证注册用户的Email的体例
这篇文章首要先容了在Python的Flask框架奇趣5分彩考证注册用户的Email的体例,包含很是具体的测试历程,死力保举!须要的伴侣能够或许或许参考下2015-09-09奇趣5分彩:Python奇趣5分彩潢器奇趣5分彩@property利用详解
大师奇趣5分彩,本篇文章首要讲的是Python奇趣5分彩潢器奇趣5分彩@property利用详解,感乐趣的同窗从速来看一看吧,对你奇趣5分彩赞助的话记得保藏一下2022-01-01奇趣5分彩:linux体奇趣5分彩利用python监测体奇趣5分彩负载剧本分享
这篇文章首要先容了linux体奇趣5分彩利用python监测体奇趣5分彩负载剧本,大师参考利用吧2014-01-01奇趣5分彩:利用python爬取taptap网站游戏截图的步骤
这篇文章首要先容了利用python爬取taptap游戏截图的步骤,赞助大师更奇趣5分彩的懂得和进奇趣5分彩利用python停止爬虫,感乐趣的伴侣能够或许或许领会下2021-05-05奇趣5分彩:基于历程内通信的python谈天室完奇趣5分彩体例
这篇文章首要先容了基于历程内通信的python谈天室完奇趣5分彩体例,实例阐发了Python谈天室的相干完奇趣5分彩技能,须要的伴侣能够或许或许参考下2015-06-06
最新批评