有些计算器,只能进行单步计算,就是说只能输入数字和加减乘除四则运算符号,而不能有括号的出现。可编程计算器就是指能输入括号、数字和四则运算符号,并对所输入的四则运算表达式进行分析,得最终计算出结果的计算器。

不多说下面用编译原理里面讲过的SLR文法来实现。

其实还有一种比较简单的方法——用栈来实现,可以看这里:http://blog.csdn.net/he_qiao_2010/article/details/8710495。

 可编程计算器的SLR文法实现(表达式求值)

0.        在计算机科学中,文法是编译原理的基础,是描述一门程序设计语言和实现其编译器的方法。它可以使语言中的每个句子都能用严格定义的规则来构造。说白了类似于语文里面遣词造句的一种规则。比如一个句子的一般形式就是主、谓、宾,即:句子——>主谓宾。那么要构造一个句子,就只需要主语、谓语、宾语按照这个顺序排列就够了。在我们想设计的这个可编程计算器中数字就是0-9这十个数字,即:num——>[0-9]+。(这里+表示某个集合中的元素可以重复出现多次,但至少出现一次)这个实际上是正则表达式,也是文法的一类。

1.        在讲什么是SLR之前先说一下LR在编译技术里面的概念。LR(k)是指一种高效的、自下而上的针对于上下文无关的文法分析技术,其中L是指从左向右扫描输入,R是指构造最右推导的逆,而k是指决定分析动作时向前找的符号的个数。而SLR是LR方法中最简单的一种。(由于四则运算式比较简单,SLR已经足以描述所有的表达式)

2.        下面给出一个比较直观的例子,看一个文法如何分析一个四则运算表达式。

3.        首先给出这个文法:

(1)       E_ -> E
(2)       E -> E+T | E-T | T
(3)       T -> T*F | T/F | F
(4)       F -> ( E ) | id

也就等价于:

(1)       E_ -> E

(2)       E -> E+T

(3)       E -> E-T

(4)       E -> T

(5)       T -> T*F

(6)       T -> T/F

(7)       T -> F

(8)       F -> ( E )

(9)       F ->   id

用以上文法构建SLR分析表:

标识符

+

-

*

/

(

)

$

id

E

T

F

acc

0

1

2

3

4

5

6

7

0

1

2

17

实际上整个构造过程要通过转换图来实现,而且画图过程比较繁琐,下面是通过转换图得到的便于程序实现的转移表。

#defineSTAT         16
#defineACTION        8
#defineTURN            3/************转移表(动作部分)***************/
int    MOVETABLE[STAT][ACTION] = {{ 0, 0, 0, 0, 4, 0, 0,5},  /*0*/{ 6, 7, 0, 0, 0,-1,17, 0},     /*1*/{-4,-4,10,11, 0,-4,-4, 0},   /*2*/{-7,-7,-7,-7, 0,-7,-7, 0},     /*3*/{ 0, 0, 0, 0, 4, 0, 0, 5},/*4*/{-9,-9,-9,-9, 0,-9,-9, 0},/*5*/{ 0, 0, 0, 0, 4, 0, 0, 5},       /*6*/{ 0, 0, 0, 0, 4, 0, 0, 5},       /*7*/{-2,-2,10,11, 0,-2,-2, 0},   /*8*/{-3,-3,10,11, 0,-3,-3, 0},/*9*/{ 0, 0, 0, 0, 4, 0, 0, 5},/*10*/{ 0, 0, 0, 0, 4, 0, 0, 5},       /*11*/{-5,-5,-5,-5, 0,-5,-5, 0},     /*12*/{-6,-6,-6,-6, 0,-6,-6, 0},     /*13*/{ 6, 7, 0, 0, 0,15, 0, 0},/*14*/{-8,-8,-8,-8, 0,-8,-8, 0}/*15*/};/************转移表(转移部分)***************/
int    TURNTABLE[STAT][TURN] = {{ 1, 2, 3 }, /*0*/{ 0, 0, 0 }, /*1*/{ 0, 0, 0 }, /*2*/{ 0, 0, 0 }, /*3*/{14, 2, 3 }, /*4*/{ 0, 0, 0 }, /*5*/{ 0, 8, 3 }, /*6*/{ 0, 9, 3 }, /*7*/{ 0, 0, 0 }, /*8*/{ 0, 0, 0 }, /*9*/{ 0, 0, 12}, /*10*/{ 0, 0, 13},         /*11*/{ 0, 0, 0 }, /*12*/{ 0, 0, 0 }, /*13*/{ 0, 0, 0 }, /*14*/{ 0, 0, 0 } /*15*/};

负数表示按照第几个文法表达式进行规约。一些细节看源码。

实际上它的主要思想就是把整个表达式塞进栈里面,然后通过查表来决定是压栈还是出栈。整个过程,就是弹栈然后计算,又把计算结果压栈,再弹栈。。。等等。

而什么时候该出栈什么时候该入栈,由文法产生的转移表决定,这就也许是文法的神奇之处吧。我是感觉编译原理比较难学,一个First集和Follow集就纠结了半天。

好吧,下面看看程序的实现结果,下面有几张简单的截图(用MFC实现),如此界面,请大家不喜勿喷。。。^_^

生成词法单元(二元组)

分析表达式合法性,如果合法计算出结果

如果输入不合法的表达式

显示错误信息:

源码下载地址:http://www.pudn.com/downloads493/sourcecode/windows/other/detail2055486.html

2015-03-21更新源码的下载地址:

百度网盘:http://pan.baidu.com/s/1jG69m5o

利用SLR实现可编程计算器(表达式求值)相关推荐

  1. c语言编程实现表达式求值,c语言实现表达式求值的方法

    c语言实现表达式求值的方法 发布时间:2020-06-22 16:45:46 来源:亿速云 阅读:82 作者:Leah 这期内容当中小编将会给大家带来有关c语言实现表达式求值的方法,以专业的角度为大家 ...

  2. 计算器软件----表达式求值

    学完栈写了一个计算器小程序, 基本功能如下: 1.支持基本的+ - * / % 运算 2.支持sin.cos.tan.ln.log.乘方(^).开方(sqrt).指数(exp) 求值 3.支持括号及括 ...

  3. 算术表达式求值的程序设计与实现_数据结构课程设计

    以下内容可且仅可供参考,如有错误欢迎指正. 部分思路借鉴算术表达式求值(C语言栈)_夜何其的博客-CSDN博客_c语言利用栈求解算术表达式侵删致歉 <算术表达式求值的程序设计与实现>题目要 ...

  4. 如何利用计算机求函数解析式,数据结构表达式求值(计算器)实验报告(共10篇).doc...

    数据结构表达式求值(计算器)实验报告(共10篇) 数据结构表达式求值(计算器)实验报告(共10篇) 数据结构课程设计_实验报告(一)表达式求值(计算器) 数据结构课程设计 实验报告 起止时间:2015 ...

  5. 字符串算术表达式求值-简单计算器实现(栈)-数据结构和算法(Java)

    1 字符串算术表达式分类 字符串算术表达式分为前缀表达式.中缀表达式和后缀表达式.其中前缀表达式又称波兰表达式,后缀表达式基于前缀表达式,又称逆波兰表达式.下面给出百度百科关于几种表达式的定义: 前缀 ...

  6. 编程实现算术表达式求值_用魔法打败魔法:C++模板元编程实现的scheme元循环求值器...

    本文使用 Zhihu On VSCode 创作并发布 [TOC] 前言 寒假时沉迷C++模板元编程,写了个简单的Scheme元循环求值器.可以用类似Scheme的语法写出这样的C++模板代码: _&l ...

  7. 简单计算器(浙大复试题)表达式求值

    读入一个只包含 +.-.*./ 的非负整数计算表达式,计算该表达式的值. 输入 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔.没有非法表达式.当 ...

  8. [计蒜客 15504 百度的科学计算器(简单)]表达式求值

    [计蒜客 15504 百度的科学计算器(简单)]表达式求值 分类: Math 表达式求值 1. 题目链接 [计蒜客 15504 百度的科学计算器(简单)] 2. 题意描述 求一个只带加减的实数表达式. ...

  9. iOS仿写计算器中缀转后缀 表达式求值

    github地址 iOS计算器 准备工作 由于OC没有自带的栈文件,只能链表模拟栈 typedef struct {char data[50];int top; }Stack;//符号栈 //之前把D ...

最新文章

  1. 笔记:Linux下C编程实现每隔一秒向文件中写入当前时间
  2. asp.net 备份和恢复SQL SERVER 数据库
  3. Unity3D_(游戏)贪吃蛇
  4. 算法-----两数之和 II - 输入有序数组
  5. 算法提高 c++_ch04_02_修正版
  6. Swagger2接口注释参数使用数组
  7. 写在WinHEC开幕之际:沿着Windows我们一路走来
  8. win7安装证书时无响应的解决办法
  9. 年会抽奖程序,开箱即用
  10. Apollo课程学习2——高精地图HD Map
  11. 人脸美化随笔1——研究方向总结
  12. 阿里云服务器导出方案
  13. Docker常见错误
  14. python的查找list的元素
  15. ios适配暗黑模式-图片、颜色
  16. TeamViewer远程服务器管理工具使用哪些端口
  17. 4.10 使用照片滤镜命令修改图像色温和色调 [原创Ps教程]
  18. Swift - 使用EventKit操作提醒事项(2、新增、修改、删除提醒)
  19. Java高效开发框架Nutz:是SSH的轮子?还是新神器?
  20. EasyUI之树形菜单选项卡前端应用

热门文章

  1. java 实现macd算法_java尝试编写macd,试验顶背离底背离
  2. 1705. 吃苹果的最大数目(贪心、优先队列(堆)、哈希表),总之先吃快烂的苹果
  3. PHP汉字转拼音笔记.txt
  4. 通过预先数据标注让AI算法更加精确
  5. 扒一扒那些叫欧拉的定理们(六)——九点圆定理的证明
  6. python爬虫抓图_Python 爬虫网页抓图保存
  7. 钳形万用表使用方法,如何测量电压、电流、电阻?
  8. html中stroke函数,HTML中stroke是什么意思?
  9. 201208197PM-Error on Unable to obtain lock on *.lok . Server may already be running
  10. 前后台系统和RTOS系统的区别