C++实践之路-----计算器(1)

来源:互联网 发布:淘宝微商代理能挣钱吗? 编辑:程序博客网 时间:2024/05/22 14:13

计算器的设计

1.需求说明

         计算器主要功能是根据用户的输入,进行适当的计算。里面需要有内置函数、变量记录功能。

2.功能、对象

         根据需要,我们可以大致抽象出一些对象来:

解析器:负责解析式子,目标是将输入的字符串转换成一个算术树,逆波兰序

符号表:记录出现过的符号(符号包括:变量名、内置函数、内置常量)

扫描器:从左往右的扫描缓冲器并将它们转换成记号

存储器:存储着变量的值

函数表:存储着一些内置函数

3.设计

         采用自顶向下设计的设计方法,下面是顶层的结构:

{

         函数表:FunctionaTable

         存储表:Store

         While(true)

                  1.读取用户输入

                  2.创建扫描器Scanner

                  3.创建解析器Parser

                  4.获得值Eval

}

4.逐步完善

现在开始逐渐完善上面的函数

4.1 扫描器

扫描器功能分析:

扫描器需要有什么功能呢?扫描器需要对用户的输入进行解析,根据输入给出记号,具体怎么处理记号不归扫描器的管。

我们以一个简单的式子来说明,扫描器需要有的功能:

B=3+4/5-7*4+a-c

上面这个式子里有加减乘除、还有变量,所以扫描器应该要能识别不同的运算符,然后提供提取数字、变量的功能。

         抽象出来其提供的接口有

{

         Token()返回记号

         Accept()解析下一个记号

         Number()返回数字

         GetSymbolName()返回变量名

}

4.2 符号表

         符号表是负责记录了所有出现的符号,包括变量名、函数名、内置变量。

符号表的功能:

1、添加符号  ---------------返回符号的标识符

2、查找符号   --------------返回标识符

3、获得符号   --------------根据标识符得到符号

         根据上面的要求,我们可能的实现是什么呢?

我们对符号应该有唯一的id标识,,然后 字符串 – id 这个可以用hash表实现,但是 id 到 字符串怎么可以快速实现呢?我们可以记录下这种关系,即id – 字符串的关系即可,我们可以通过下面的结构表示:

哈希表【HTabl】 ----------   提供    字符串 ----- Ids

字符串表[StringBuffer]---------提供    偏移-----------字符串

偏移记录表----------------------提供-------id----------------偏移

 

偏移记录表  通过 id 来 得到在StringBuffer表中的偏移

由上图我们可以大致了解数据结构了:

符号表中有几个重要的对象

Hash表:记录了   string  ------    id    对应关系

字符串表:记录了   不同的identifier

偏移表  :记录了    id    --------   偏移 对应关系

 

 

4.3 解析器

功能

Eval()

{

         1.递归解析式子

         2.计算值

}

         首先介绍一些基本概念:

1、表达式 expression

a.是一个后面有加号或者减号的项,加号或者减号后面又是另一个表达式

b.如果表达式不含有任何减号或者加号,它等于此项

c.表达式也可以为一个项加一个等于号,再加上一个表达式

// expression is Term + experssion

// or Term - expression

// or Term = expression

// or just Term

2、项 term

a.被另一个项乘或者除的因子

b.如果一个项不包含任何乘或者除运算符,它等于此因子

// term is Factor * Term

// or Factor / Term

// or just Factor

3、因子 factor

a.一个数组

b.一个对应于某变量的标识符

c.后面带有一个因子的减号

d.小括号中的整个表达式

 

根据上面的说明,我们就可以设计出解析器了,根据上面的规则

提供几个函数

{

    void   Parse();

    Node * Expr();

    Node * Term();

    Node * Factor();

}

根据上面的需求我们可以就可以开始具体实现了。


原创粉丝点击