仿查询分析器的C#计算器——1.初步分析

计算器是很多编程初学者都做过的,从最简单的控制台程序开始,输入值,输入运算符,再输入值,得到一个结果。带界面的基本上是模仿Windows操作系统的计算器,通过按钮输入值和运算符,然后给出运算结果。能不能直接输入表达式,或者能够对好几个表达式进行计算,或者选择表达式中的一部分进行计算,如果输入错误能不能指出表达式中的错误位置?这样的要求类似于MS SQL的查询分析器,本系列文章将介绍如何实现这样一个计算器。(这些内容已经涉及到编译原理,但本人并非计算机专业毕业,只是稍微看了一下编译原理的资料,专业词汇比如有限状态机之类就不提了,咱也不是很pro,呵呵。)

首先给出一个表达式5*3+12/4,我们拿到这个表达式之后会得到如下分析:

1.乘法的优先级高后面的加法,先算乘法,乘号两边的数分别是53,执行乘法5*3=15

2.加法的优先级没有后面的除法优先级高,先算除法,除号两边的数是124,执行除法12/4=3

3.乘除法做完之后再做加法,这时候加法并不需要知道两边到底怎么计算的,只需要知道两边计算后的值就可以了,乘法的值是15,除法的值是3,执行加法15+3=18

 

在这个表达式后面再加一个步骤:5*3+12/4-8,这时候只不过多了一步操作

4.做完加法后做减法,减号也不需要知道两边怎么计算的,向两边请求值,得到加法的值是18,另一边是一个数字8,不需要计算就直接给它,执行减法18-8=10

 

再稍微改变一下:5*3+12/4-8/2,计算过程就是

4.做完加法准备做减法,但后面的除法优先级高,先做除法,除号两边的数是82,执行除法得到4

5.然后执行减法,减法左边是执行加法后的值18,右边是执行除法后的值4,执行减法18-4=14

 

到此会发现,其实可以把每一个操作符理解成一个数值存储单元,并且该单元可以根据它两边的数值进行一定的计算得到自身的值。它只关心两边的值,而不需要关心值是通过什么算法得来的。这样就有了二叉树的味道,一个结点下面可以有两个子结点。因此,不管表达式多复杂,最终都只有一个结果,这个结果就是最后一个操作符对它两边的值进行计算得到的,而最后一个操作符就可以理解成根节点。下面,就把表达式按照树的形状分解:

语法树分析1

 

这里减法就是根节点,它向下请求值并进行计算。它的下级也是采用同样的方法向下请求值,请求到值后就执行自身的计算,把计算结果存储在自己的存储单元里,然后让上一级调用自身的值。最后由根节点计算其下级的值得到整个表达式的值。最终计算完的树结构如下:

语法树分析2 

 

我在实际编程中就是采用这种方法对表达式进行分析和计算的,如图:

计算器语法树分析

 

输入界面(选择部分表达式计算)

计算器输入界面

 

至于如何将表达式分析成树形结构,以及如何调用下级节点求值,在以后的文章中详细介绍。

 

代码下载:https://files.cnblogs.com/conexpress/ConExpress_MyCalculator.rar

(本程序还有一些细节上的bug,有兴趣的朋友可以完善一下。)

posted @ 2009-03-04 15:37  Alex Leo  阅读(5222)  评论(16编辑  收藏  举报