返回顶部
首页 > 资讯 > 后端开发 > Python >python开发任意表达式求值全功能示例
  • 341
分享到

python开发任意表达式求值全功能示例

2024-04-02 19:04:59 341人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录正文完整的源代码正文 在之前的基础上进一步实现了全功能表达式求值。 已支持浮点数已支持字符串的处理,前加一个"(类似lisp语法)支持减号/负号,一符两用机制支持所有算

正文

在之前的基础上进一步实现了全功能表达式求值。

  • 已支持浮点数
  • 已支持字符串的处理,前加一个"(类似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)

以上就是python开发任意表达式求值全功能示例的详细内容,更多关于python表达式求值的资料请关注编程网其它相关文章!

--结束END--

本文标题: python开发任意表达式求值全功能示例

本文链接: https://lsjlt.com/news/119285.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • python开发任意表达式求值全功能示例
    目录正文完整的源代码正文 在之前的基础上进一步实现了全功能表达式求值。 已支持浮点数已支持字符串的处理,前加一个"(类似lisp语法)支持减号/负号,一符两用机制支持所有算...
    99+
    2024-04-02
  • python如何开发任意表达式的求值全功能
    本篇内容介绍了“python如何开发任意表达式的求值全功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!完整的源代码import ...
    99+
    2023-07-02
  • python四则运算表达式求值示例详解
    目录四则运算表达式求值思路说明算法步骤代码四则运算表达式求值 思路说明 使用双栈来实现——存放数值的栈 nums 与存放运算符的栈&nbs...
    99+
    2024-04-02
  • mysql中正则表达式搜索功能的示例分析
    这篇文章主要介绍mysql中正则表达式搜索功能的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体如下:我们知道正则表达式是描述搜索模式的特殊字符串。 它是一个强大的工具,为...
    99+
    2024-04-02
  • JavaScript数据结构中栈应用之表达式求值的示例分析
    这篇文章给大家分享的是有关JavaScript数据结构中栈应用之表达式求值的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体如下:下面来谈一个比较经典的表达式求值问题,...
    99+
    2024-04-02
  • Android开发中正则表达式工具类RegexUtil的示例分析
    小编给大家分享一下Android开发中正则表达式工具类RegexUtil的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体如下:public ...
    99+
    2023-05-30
    android
  • 如何利用Redis和Python开发分布式任务队列功能
    如何利用Redis和Python开发分布式任务队列功能简介:随着互联网应用的发展,对于实时性和并发处理能力的需求越来越高,分布式任务队列成为解决并发任务处理的重要工具。本文将详细介绍如何利用Redis和Python开发分布式任务队列功能,并...
    99+
    2023-10-22
    Python redis 分布式任务队列
  • python使用正则表达式匹配字符串开头并打印示例
    本文实例讲述了python使用正则表达式匹配字符串开头并打印的方法。分享给大家供大家参考,具体如下: import re s="name=z1hangshan username=fff url=www....
    99+
    2022-06-04
    示例 字符串 开头
  • Java使用正则表达式截取重复出现的XML字符串功能示例
    本文实例讲述了Java使用正则表达式截取重复出现的XML字符串功能。分享给大家供大家参考,具体如下:public static void main(String[] args) throws DocumentException { S...
    99+
    2023-05-31
    java 正则表达式 xml
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作