大家在参考本节时,请先阅读以下博文,进行预热:

http://blog.csdn.net/tyler_download/article/details/50708807

本节代码下载地址:

http://pan.baidu.com/s/1sjWiwPn

代码的理解和运行是吃透编译原理的关键,如果我们看的是爱情动作片,自然选择无码的好,但如果看得是计算机课程,则必须有码,无码的计算机理论都是耍流氓。

当前,java所实现的简易编译器目的是将一条或一组含有加号和乘号的算术表达式编译成类似汇编语言的伪码,因此必须给算术表达式设立一组语法规则,那么程序才能对输入的表达式进行分析。我们把一组带有分号的算术表达式称为statements, 例如:

1+2*3+4;

2+3*4+5;

3+4*5+6;

这三个表达式的集合称为statements.同时将一组表达式中的某一条带有分号的表达式称为expression, 这样statements 就是由一个或多个expression组成的:

因此statements的语法规则可以写成:

statements -> expression; | expression; statements

大家看到该语法定义跟我在上一篇文章中举的例子有所不同:

1.    在-> 右边有两组解析规则,他们用符号 | 分割开。

2.    -> 左边的被解析的对象居然在右边的解析规则中出现,形成了一种循环,也就是用自己来解释自己,这种情况在编译原理中称为左循环LR (Left recursive).

这里,大家可能会发现语法定义的一些问题:

1.    右边有两组解析规则,用右边替换左边时,到底选取哪一组?

2.    左边的符号(statements) 出现在右边的规则中,替换的话就会出现死循环:

statements(buffer) {

expression(buffer);

statements(buffer); //此处将导致循环调用

}

这些问题,在后面我们再加以解决,暂且先继续给出余下的语法规则:

Expression ->expression + term | term;

term -> term* factor | factor

factor ->NUMBER | (expression)

看到这,大家会不会有点恼火,为什么这组语法规则能够用来解析一组算术表达式? 你是根据什么办法给出这组规则的?我以前在读编译原理的相关书籍时也会有这些郁闷和困惑,都不知道作者是怎么想到的,书中解释有含糊不清,直到现在我才明白,在学习的早期,有些地方你必须先囫囵吞枣,带着疑惑看到后面,你自然就会明白,所以大家在此先无需理解我是怎么给出这组语法定义的,先记着,然后把代码跑一边,看看结果,有个感性认识,在后续文章中,我会慢慢解释,如何根据要编译的文本,给出相应的语法规则。

现在我们来解决前面提到的两个问题, ->右边有两组替换规则,在语法解析的时候,如何决定选取哪一组?在编译原理的实现技巧中,有一种方法叫look ahead, 举个例子,对规则:

statements ->expression; | expression; statements

替换时用“| “ 左边的 expression; 还是右边的expression; statements呢,办法是当我们在程序中,读到第一个分号”;” 时,再继续读入下一个符号,如果继续读入符号时,返回的是输入的结束标志(EOI) 那么我们就使用“|” 左边的规则来替换,如果继续读入的符号不是结束标志,那意味着分号后边还有需要解析的信息,那就使用“|” 右边的替换规则,这种技巧在语法解析中就叫look ahead.

如何解决语法规则中出现循环调用呢?我们需要对语法规则做一些更改,更改原理在以后的文章中再做进一步的解释,请大家再囫囵吞枣一次,我知道吃东西不消化会对胃不好,黄天在上,这里是最后一次这样,请大家原谅,修改后的语法规则如下:

1. statements -> ‘空‘ | expression; statements

2. expression-> term expression'

3. expression'-> +term expression' | ‘空‘

4. term -> factor  term'

5. term' -> * factor  term' | ‘空‘

6. factor -> number | (expression)

这组修改后的语法规则比修改前更加难以理解,但能确保,这组规则不会出现修改前那样导致解析死循环。语法规则中的’空’ 表示结束,什么都不做。例如如果我们输入一个空字符串””给语法解析器,那么规则1中就以”空”来解析输入的空字符串,其结果就是程序什么都不做,直接返回,在程序中”空” 相当于return语句。

我们用表达式:1 + 2 ; 看看语法规则形成的解析树是怎样的:

在下面给出的视频中,我将对代码实现进行详细的讲解,同时通过运行代码,让大家体会到执行的效果,以帮助大家对语法解析的原理和实现有深一步的认识,大家把代码下下来,对着视频中的步骤运行一次,便可得知一个语法解析器的“五脏六腑"是如何组合运行的。由于视频中会出现代码解析,如果画面分辨率过低,可能无法看清代码,请大家在观看视频时将分辨率设置成高清或1080P。

由于csdn无法插入视频,我将视频地址给出如下:

http://v.youku.com/v_show/id_XMTQ4MTI2NzgyMA==.html?firsttime=0&from=y1.4-2

转载于:https://www.cnblogs.com/csguo/p/7614809.html

用java实现编译器-算术表达式及其语法解析器的实现相关推荐

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

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

  2. CSS大会 | 打破常“规”:挖掘语法解析器规则漏洞

    2019年7月30-31日,第五届互联网安全领袖峰会(CSS 2019)在北京开幕.作为前沿技术安全研究团队代表,Tencent Blade Team两位高级安全研究员受邀登台,探讨如何挖掘语法解析器 ...

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

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

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

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

  5. sqlparser mysql_SQL语法解析器JSQLParser | IT瘾

    相关 [sql 语法 解析器] 推荐: SQL 语法解释器jsqlparser. 是用java 开发的解析器, 可以生成java类层次结构.. 可以完美解析 表的 增删查改等操作.. 展开它的源码你会 ...

  6. mysql ddl 语法解析工具_sharding-sphere之语法解析器

    语法解析器,根据不同类型的语句有不同的语法解析器去解析成成SQLStatement,SQL解析器的类图我用脑图画出来如下: SQLParser.png 可以看到,不同的sql有不同的处理解析器去解析, ...

  7. NET Core中使用Irony实现自己的查询语言语法解析器

    在之前<在ASP.NET Core中使用Apworks快速开发数据服务>一文的评论部分,.NET大神张善友为我提了个建议,可以使用Compile As a Service的Roslyn为语 ...

  8. 使用ANTLR做一个简单的Python SQL语法解析器 - 推酷

    使用ANTLR做一个简单的Python SQL语法解析器 - 推酷 使用ANTLR做一个简单的Python SQL语法解析器 - 推酷 posted on 2016-11-14 13:11 lexus ...

  9. Python语法解析器PLY——lex and yacc in Python - 娄振林专栏 - 博客频道 - CSDN.NET

    Python语法解析器PLY--lex and yacc in Python - 娄振林专栏 - 博客频道 - CSDN.NET Python语法解析器PLY--lex and yacc in Pyt ...

  10. java定义语法解析器,java开发工具intellij idea使用教程:定义语法和解析器.pdf

    java开发工具intellij idea使用教程:定义语法和解析器.pdf 还剩 3页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: 慧都 科技 -- ...

最新文章

  1. 网络空间安全:社会工程学之信息追踪——学习笔记 利用搜索引擎追踪!
  2. 【转】基于easyui开发Web版Activiti流程定制器详解(一)——目录结构
  3. php无法添加数据库,无法添加数据到数据库
  4. telnet IP不通/sybase central工具无法连接到数据库
  5. 重返商用计算市场,紫光计算机要做数字化转型生意
  6. Raki的读paper小记:Named Entity Recognition as Dependency Parsing
  7. mPush实战笔记1服务器环境
  8. 手机浏览器设置为纯净百度主页 去除百度首页推送
  9. 桌面麒麟系统添加字体
  10. appcan mysql_AppCan的图片、文件操作、上传、下载操作 From Ken
  11. PDF怎么转换成Word文档呢?不妨试试这两种方法!
  12. 第五届安洵杯网络挑战赛WP
  13. 本本CPU控制让游戏3D效果最佳境界
  14. Huge And Integer
  15. matlab 比较两个函数,Matlab同时拟合两个函数 - 数学 - 小木虫 - 学术 科研 互动社区...
  16. 现在做什么能挣钱?想要在互联网赚钱,一定要懂这些!
  17. 【mysql】mysql查询结果添加固定值
  18. 【涨粉10万】CSDN年度总结——再见2021
  19. 数据库连接池是什么?
  20. 创建表空间(Oracle)

热门文章

  1. CentOS 6.9之LVM创建,扩容
  2. linux基础命令总结-1
  3. Mysql DBA 20天速成教程
  4. Android View的生命周期详解
  5. 阿里的dubbo 到底是用来干嘛的?
  6. react-native 自定义view向js暴露接口方法
  7. 求求你们了,别再写满屏的 if/ else 了!
  8. 循序渐进,一文详解微服务架构!
  9. 金九银十招聘季,程序员跳槽BAT最新面经
  10. Android上SQLite的性能优化问题