小编写这篇文章的主要目的,就是给大家介绍一下关于python开发实例,有一些全功能的具体实例,那么,具体内容小编就给大家讲解下。
正文
在之前的基础上进一步实现了全功能表达式求值。
已支持浮点数
已支持字符串的处理,前加一个"(类似lisp语法)
支持减号/负号,一符两用机制
支持所有算术运算符,包括**,//,%
支持全部7个比较运算符
支持与或非3个逻辑运算符
支持自定义数学函数(代码中预设sin函数作为示范)
支持外部提供的变量机制
支持外部设置函数(代码中预设isvar函数作为示范)
支持列表
字典的支持,体现在外部的变量中
结构清晰,易于扩展
具有实用性及学习性
与其说距离DSL只有一步之遥,不如说,DSL机制已经实现。因为可以任意扩展函数,而函数的内容
完全可以自行定义。
完整的源代码
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('操作数不足,可能有语法错误!') 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('操作数为空,肯定有哪里错了。') 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)
具体代码就给大家介绍到这里了,希望可以给各位读者带来一定的帮助。
原创文章,作者:网友投稿,如若转载,请注明出处:https://www.cloudads.cn/archives/3958.html