给定一个字符串如:2/(3+4))*(3-1)+6-8 ,用程序解析出来,输出最终的值。这是个AST 语法解析问题,最直观的是建立一颗语法树,然后遍历语法树来获得最终的效果。如下图,建立这么一个语法树,然后广度优先搜索,进行操作就能得到最终的结果。

但是,其实我们有更方便的方法去做,不用建立语法树,而是利用栈,给每个操作符号定义优先级,就可以实现这个功能。一共的操作符号有:

(  )  +  -  *  /

只有这四种,定义其优先等级分别为:

( : -1

) : 0

+ : 1

- : 1

* : 2

/ : 2

解析表达式字符串,从左到右把它的字符加入到栈,如果遇到第二个操作符开始,其优先级小于前面的操作符的优先级,则先合并前面的操作符号的操作项,不断得重复此过程直到栈中只有一个符号。

我的程序定义了两个栈,一个栈是存操作符的,一个栈是存数值的。挺多处理的细节不文字表示了,看下面的代码(python实现)

class NodeOpt:"""操作符节点"""def __init__(self, ch, precedence):self.ch = chself.precedence = precedenceclass AST:"""加减乘除任意组合的语法解析器"""# 操作符栈_operatorStack = []# 值栈_exprStack = []# 具体操作符节点left_range = NodeOpt(ch='(', precedence=-1)right_range = NodeOpt(ch=')', precedence=0)add = NodeOpt(ch='+', precedence=1)sub = NodeOpt(ch='-', precedence=1)mul = NodeOpt(ch='*', precedence=2)div = NodeOpt(ch='/', precedence=2)__opts = [add, sub, mul, div, left_range, right_range]def getOptNode(self, ch):"""根据符号获取节点"""for ops in self.__opts:if ops.ch == ch:return opsdef isValue(self, ch):"""判断是否为数值"""if self.isOperator(ch):return Falsereturn Truedef isOperator(self, ch):"""判断是否为操作符"""for ops in self.__opts:if ops.ch == ch:return Truereturn Falsedef operator(self, e1, e2, operator):"""执行操作"""opt = operator.che1 = float(e1)e2 = float(e2)if opt is '+':return e1 + e2elif opt is '-':return e1 - e2elif opt is '*':return e1 * e2elif opt is '/':return e1 / e2else:return Nonedef ifGo(self):if len(self._exprStack) >= 2 and len(self._operatorStack) >= 1:return Trueelse:return Falsedef parse(self, input):""":param input: 字符数组"""for ch in input:if ch is '(':ch = self.getOptNode(ch)self._operatorStack.append(ch)elif self.isValue(ch):self._exprStack.append(ch)elif self.isOperator(ch):ch = self.getOptNode(ch)while self.ifGo() and ch.precedence <= self._operatorStack[-1].precedence:e2 = self._exprStack.pop()e1 = self._exprStack.pop()operator = self._operatorStack.pop()self._exprStack.append(self.operator(e1, e2, operator))self._operatorStack.append(ch)if ch.ch is ')':while self._operatorStack[-1].ch != '(':self._operatorStack.pop()self._operatorStack.pop()else:return Exceptionwhile self.ifGo():e2 = self._exprStack.pop()e1 = self._exprStack.pop()operator = self._operatorStack.pop()self._exprStack.append(self.operator(e1, e2, operator))return self._exprStack.pop()if __name__ == '__main__':ast = AST()myopt = "2/(3+((2-5)+1))*(3-1)+6-8"optlist = []i = 0while i < len(myopt):optlist.append(myopt[i])i += 1result = ast.parse(optlist)print(result) 

转载于:https://www.cnblogs.com/aijianiula/p/9961331.html

实现加减乘除任意组合的语法解析相关推荐

  1. 用 C 语言开发一门编程语言 — 语法解析器

    目录 文章目录 目录 前文列表 编程语言的本质 词法分析 语法分析 使用 MPC 解析器组合库 安装 快速入门 实现波兰表达式的语法解析 波兰表达式 正则表达式 代码实现 前文列表 <用 C 语 ...

  2. Hive之 Hql语法解析

    Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的SQL查 ...

  3. 多层科目任意组合汇总报表的性能优化 (上)

    一 问题背景 我们先来看一张资产负债表: 这是一个典型的中国式复杂报表格式,其复杂并不在于布局,而在于其中"期末余额"的每个单元格都是一个需要独立计算的指标,互相之间几乎没有关系, ...

  4. c语言结构体语法分析,C语言结构体struct的语法解析

    本节内容需要结合视频讲解才能更容易理解,视频播放地址如下: 用java开发编译器 本节,我们着重研究结构体定义,也就是struct 这种变量定义,C语言编译器是如何解析的,本节我们要解析的结构体定义如 ...

  5. C语言结构体struct的语法解析

    本节内容需要结合视频讲解才能更容易理解,视频播放地址如下: 用java开发编译器 本节,我们着重研究结构体定义,也就是struct 这种变量定义,C语言编译器是如何解析的,本节我们要解析的结构体定义如 ...

  6. 正则表达式常用语法解析

    正则表达式常用语法解析 什么是正则表达式 正则表达式之元字符 匹配位置的元字符 ^.$./b 匹配字符的元字符 ..\w.\W.\s.\S.\d.\D 正则表达式之文字匹配 字符类 字符转义 反义 正 ...

  7. Boost学习之语法解析器--Spirit

    Boost.Spirit能使我们轻松地编写出一个简单脚本的语法解析器,它巧妙利用了元编程并重载了大量的C++操作符使得我们能够在C++里直接使用类似EBNF的语法构造出一个完整的语法解析器(同时也把C ...

  8. pg/og内核原理-词法语法解析(更新中)

    目录 概念与含义 流程概览 词法语法代码 parsenode.h kwlist.h scan.l gram.y bison的使用 查看状态机 解决规约冲突 plpgsql的词法与语法 概念与含义 一条 ...

  9. 内核级python:编译器的词法和语法解析基本原理

    python在收到代码内容后,首先要启动两个流程,分别为词法解析和语法解析.看过我编译原理课程的同学对这两个流程应该不陌生.词法解析其实就是把代码里面不同的元素分别归类,例如234,1.35,1e3等 ...

最新文章

  1. 【TCP/IP详解 卷一:协议】第十二章 广播和多播
  2. gis属性表怎么导成excel_第022篇:ArcGIS中将属性表直接导出为Excel的方法
  3. 虚拟机删除后服务器内存,卸载虚拟机后仍占内存
  4. JavaScript 中 JSON.parse()和JSON.stringify()
  5. java map转string_【库学科技】32道常见的Java基础面试题
  6. ffmpeg 丢帧 灰屏_音视频常见问题分析和解决:HLS切片丢帧引起的视频卡顿问题排查...
  7. 逻辑回归(LR) 算法模型简介
  8. c#rs232与三菱通讯_三菱各系统的RS232通讯接口汇总
  9. linux centos 权限审核 polkitd进程 简介
  10. 清北学堂noip2018集训D4
  11. a4纸在html的像素,打印常识:A4纸张在显示器上应该要多少像素?
  12. CSP 201609-3 炉石传说
  13. FairMOT训练测试自定义数据集
  14. 码神-day8-java
  15. Java常用设计模式(三)
  16. 再听 ,抖音视频背景制作---小龙老师
  17. linux命令配置网卡IP (全)
  18. 电子面单接口申请对接(返回电子面单模板)
  19. 20190917练习题总结——选择题
  20. 运维系统常用健康度模型浅析

热门文章

  1. 解决电脑网络正常但是打不开网页
  2. php大华视频监控接入,大华摄像头实时视频接入Demo
  3. 【Win10】电脑麦克风录音:设备调测
  4. 2019TFE计算机科学排名,2019TFE Times 硕士专业排名
  5. PacBio相关知识
  6. 7款漂亮的纯css字体样式
  7. 争议不断的AI绘画,靠什么成为了顶流?
  8. OpenCV显示MNIST中的手写图片
  9. 从零开始写Python爬虫 --- 1.5 爬虫实践: 笔趣阁小说批量下载
  10. [转载]Malcolm的新书:Outliers