文法驱动计算器的实现

原创 2011年01月19日 19:20:00

 

原文见:http://liaoweiqiang.info/index.php/2011/01/19/calculator/

1、设计思路

这里只考虑了+-*/()和数字这些符号,实现的是简单的计算器,重点介绍实现思路,更复杂的计算机运算规则可以在这个基础上扩充。

计算器的主要难点在于优先及的处理,目前已经有的主要是使用堆栈的办法,比如:《基于堆栈的计算器实现算法》,另外的就有这种使用文法分析的方法。

本着动手练脑的实践精神,主要介绍后者。使用文法实现优先级相对来说较容易,利用产生式即可达到,满足优先级低的表达式推导出优先级高的即可。

比如下面的方法里面,加减法(addExpr)推导出乘除法(mulExpr),乘除法(mulExpr)推出 括号运算符号(simpleExpr )。

文法验证部分使用到了http://pegjs.majda.cz/online

start=addExpr

addExpr=a:mulExpr ‘+’ b:addExpr {return a+b;}//推导表达式第一部分不能是自己,避免文化的递归。

/a:mulExpr ‘-’ b:addExpr {return a-b;}

/a:mulExpr {return a;}//mulExpr=>simpleExp,使用mulExpr最高推导项。

mulExpr=a:simpleExpr’*'b:mulExpr {return a*b}

/a:simpleExpr’/'b:mulExpr {return a/b}

/a:simpleExpr {return a}//直接推导出simpleExpr的项,在文法里面只出现一次。

simpleExpr=”(“a:addExpr”)” {return a;}

/integer

integer “integer”

= digits:[0-9]+ { return parseInt(digits.join(“”), 10); }


注意方法设计规则:

  1. 文法不能出现递归,推导结果表达式如果由多部分组成,第一部分不能为推导值。
  2. 如果a=>b,那么aR=bR。如果推导结果可能的值,也能由推导结果表达式推出,那么该推导项使用最高推导项。
  3. 文法应尽量简洁,相同的推导只出现一次。

2、实现DEMO

见:http://liaoweiqiang.info/wp-content/uploads/2011/01/calculator.html

3、实现代码

见:https://www.google.com/notebook/public/06776177474416402618/BDQjwDAoQy5Xm3Nkl

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

基于文法分析的简单计算器实现

《Programming: Principles and Practice Using C++》读书笔记(二) 程序设计的过程: 分析 设计-实现-测试 得到程序原型 再设计-再实现-再测试 几个轮...

上一个计算器有bug,还是用语法制导的方法计算表达式,这个没有bug,用的是LL(1)表达式文法,以=号结束

pointer计数指针 pointer.h #ifndef _pointer_h #define _pointer_h template class pointer { pu...

编译原理LL(1)文法实现

  • 2012-12-27 19:37
  • 258KB
  • 下载

编译原理(九) LR(0)文法分析法(算法描述和C++代码实现)

概念梳理 最左推导:每一步替换最左边的非终结符  最右推导:每一步替换最右边的非终结符,最右推导称为规范推导  短语:令G是一个文法,S是文法的开始符号,假定αβδ是文法G的一个句型,如果有...

c实现消除文法左递归

  • 2010-01-08 21:25
  • 140KB
  • 下载

LL(1)文法的实现代码(可报错处理)

先定义一个分析表 public class Table { private String[][] table = { { "", "", "", "", "", "" }, { ...

编译原理LL1文法实现

内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)