资讯专栏INFORMATION COLUMN

python开发任意表达式具体例子

89542767 / 209人阅读


  小编写这篇文章的主要目的,就是给大家介绍一下关于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']&gt;opTop['in']:
  this.optrStack.append(op)
  elif op['out']&lt;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)&lt;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&gt;=15 or a in[a,b,c]')
  #b=a.eval('sin(-1)&lt;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.ucloud.cn/yun/127801.html

相关文章

  • python爬虫抓取纯静态网站及其资源

    摘要:下面跟大家详细分享一下写爬虫抓取静态网站的全过程。而我们上面说的元字符都代表一定的规则和占据一定的字符。 遇到的需求 前段时间需要快速做个静态展示页面,要求是响应式和较美观。由于时间较短,自己动手写的话也有点麻烦,所以就打算上网找现成的。 中途找到了几个页面发现不错,然后就开始思考怎么把页面给下载下来。 由于之前还没有了解过爬虫,自然也就没有想到可以用爬虫来抓取网页内容。所以我采取的办...

    daydream 评论0 收藏0
  • Python正则达式r'(.*)are(.*?).*'具体是什么意思呢?

      小编写这篇文章的一个主要目的,主要是给大家去做一个解答,解答的内容是关于python正则表达式的内容,主要是会涉及到r'(.*)are(.*?).*'这些相关的知识性内容,它也是比较的晦涩难懂的,下面给大家具体解释下。  在学习Python3的正则表达式的时候遇到一个例子  #!/usr/bin/python3   importre   line="Catsaresm...

    89542767 评论0 收藏0
  • Python基础教程:-正则达式基本语法以及re模块

    摘要:正则表达式关闭或可选标志。如果所含正则表达式,以表示,在当前位置成功匹配时成功,否则失败。否则指的是八进制字符码的表达式。 正则表达式是个很牛逼的东西,不管是在javascript,还是在Python web开发(http://www.maiziedu.com/course/python-px...)中,我们都会遇到正则表达式,虽然javascript和Python的正则表达式区别不大...

    y1chuan 评论0 收藏0
  • Python3中六种标准数据类型的简单说明和理解

    摘要:作者心叶时间中的变量不需要声明。中有六个标准的数据类型数字字符串列表元组集合字典。字符串格式化我叫今年岁心叶我叫心叶今年岁如上所示,字符串支持格式化,当然,出来上面用到的和以外,还有一些别的,具体看文档是不是感觉有点语言的味道。 作者:心叶时间:2018-04-21 09:28 Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。 Python3...

    Cheng_Gang 评论0 收藏0
  • Python3中六种标准数据类型的简单说明和理解

    摘要:作者心叶时间中的变量不需要声明。中有六个标准的数据类型数字字符串列表元组集合字典。字符串格式化我叫今年岁心叶我叫心叶今年岁如上所示,字符串支持格式化,当然,出来上面用到的和以外,还有一些别的,具体看文档是不是感觉有点语言的味道。 作者:心叶时间:2018-04-21 09:28 Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。 Python3...

    rockswang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<