文法驱动计算器的实现

 

原文见: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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值