递归下降分析法实现强化计算器

article/2025/10/15 3:05:01

一. 实验概述

1.使用bison 和 flex 实现扩展版计算器

       该计算器支持实型的两种表达,分别是小数和科学计数法.

       该计算器支持 加, 减, 乘 除 四种运算 和括号()运算符.

       该计算器支持整形,实型混合运算

2.通过递归下降分析法自行编写的语法分析和使用flex进行的词法分析的计算器.

       支持整数,实数

       支持加减乘除和括号

       支持混合运算.

二. 测试和结果

如图所示,编写test.txt测试内容,其中有加减乘除混合运算,连除,指数e表达式等

调用calculator_self 分析执行,与手算结果均一致,且没有bug.

三. 总体架构

1.flex+bison的软件总体架构:

2.flex+手动语法分析的架构:

四. 详细设计

1.在calculator.l 文件中实现对实数和减,除的词法支持:

       eee可识别科学计数法的e或E符号;

       point 用于识别 点 .

       plus_minu 用于识别 科学计数法中的正负号

       reald 用于识别 实性数字,设计思想为:先识别一个数字,再接一个点,再接一堆数字,再接一个e或E的克林闭包,

增加对reald的操作:

调用库函数识别realnumber, 并返回REALDIGIT;

white_line返回’\n’便于我们后续分析.

2.在calculator.y中增加强化计算器的语法支持.

在union中添加对double类型的支持.

修改Factor,增加一项对REALDIGIT的支持.

修改Line 文法使之支持对换行符的识别.

3.在expr.c中增加对两种类型的加减乘除的支持.

例如:

在加法中,先判断是否又实数,如果是在判断哪个是实数,然后加减乘除,如果不是就直接加两个src.val.

减乘除的方法类似,就是把运算法号一改变就可.详情见源码expr.c .

4. 在main.c中调用设计的内容.

在main.c中引用lex和yacc的头文件,然后判断文件是否为空,不是就调用yyparse();

二. 自己设计的语法分析部分:

1.自己设计的calculator_myyacc.c

总体设计如图所示,根据文法使用递归下降分析法逐级分析.

myprint()的功能是打印结构体中的值.

yyparse() 是主函数,文法开始调用Input();

Input()是输入函数, 先判断下一个token是否在input的First集里面,不是就直接报错,如果是,则根据情况调用line();如果是文件末尾就返回.

line()是line文法分析函数.同理也是先判断是否正在First集合里,然后调用expr()分析,如果遇到\n 则tonken取下一个,继续调用line(),直到最后到EOF.

expr()函数支持对expr文法的支持.这里要返回具体的运算结果了,因此先malloc所需结构体的内存.

然后判断token是否在First集里面,如果是则调用term()分析,将结果赋给src1,然后term()中最终会交还数据并且token会指向没有识别的下一个token,这里不需要再next_token(),直接判断token是否是’+’, 或 ‘-‘, 如果是则继续调用term,并把结果赋给src2,然后调用expr中的加减算法,最后使用完了free掉src2.以此类推,直到expr中遇到该文法无法处理的符号则返回,交给上级处理.

 term()与expr文法类似,函数结构也类似,在这里不再赘述,详情见calculator_myyacc.c

factor()用于判断realdigit和digit和( .如果是’(‘,则读取下一个token ,调用expr()分析,然后看下一个token是否是 ‘)’ 或’\n’不是就报错,是就返回,交给上级处理.

如果是digit 或 realdigit 则直接到yylval中读取数字,把数字内容返回.

 next_token()就是读取下一个token.

2.calculator_myyacc.h

在这里设计了myyacc.c中需要的联合体和头文件,和函数声明.详情见calculator_myyacc.h,在此不再赘述.

3. 对Makefile的修改:

修改makefile使之支持calculator 和 calculator_self的同时编译,并且调用不同的设计文件.

 五. 实验总结

5.1 调试和bug修改总结

1.一开始编写.l文件时不知道lex的语法,写完后总是报错,后来去ppt里学习了相关语法,完成实验. 一开始不知道c语言怎么将实型数字字符串识别为double ,最后上网查询调用strtod函数可以直接转换,并且 科学计数法也可以直接识别,这样省去了很多麻烦.

2.在编写calculator.y时,模仿老师的代码,在Factor中增加realdigit的支持,发现expr中没有double类型参数的调用,遂在expr.c中增加一项double realdigit,并且作为参数传入,完成实验.

3.一开始编写expr.c时,本来想如果有real类型的src,就直接把所有的val 全部赋给ralval,然后全部使用realval来计算.后来调试时发现编译器的优化会使result和src1是一个相同的的地址,最后返回的是src1,这样的话参数会总是有问题.

(个人觉得这样的优化是不合理的,目前还不知道为什么.)

4.自己根据文法写calculator_myyacc.c时,一开始根据文法规则总是递归的调用下一级分析器,发现当出现 连除 的时候,总是最后两个数先算,然后逐级向上回溯,这样和我们一般理解的从左往右计算是截然相反的,就比如4/2/2这个表达式,上述计算方法结果是4,而我们一般认为应该是1,因此后来更改为使用循环,当遇到一个term就继续判断然后计算,将结果存入src1,再继续读取下一个token直到遇到无法处理的运算符返回交给上级.

六.程序源码

TODO


http://chatgpt.dhexx.cn/article/MVodBLhh.shtml

相关文章

编译原理研究性学习专题 2——递归下降语法分析设计原理与实现

1 实验内容 完成以下描述赋值语句的 LL(1)文法的递归下降分析程序 G[S]: S→ VE E→ TE’ E’→ ATE’ | e T→ FT’ T’→ MFT’ | E F→ (E) | i A→ | - M→ * | / V→ i 设计说明:终结符号 i 为用户定义的简单变量,即标识符的定义。 2 实验要求 …

Python技法之简单递归下降Parser的实现方法

文章目录 一. 算术运算表达式求值二. 生成表达式树三、左递归和运算符优先级陷阱四. 相关包 一. 算术运算表达式求值 对于简单的算术运算表达式,假定我们已经用分词技术将其转化为输入的tokens流,如NUMNUM*NUM。 在此基础上,我们定义BNF规则…

编译实验 . 递归下降分析器

实验目的: 1.1掌握语法分析方法。 1.2掌握使用算符优先分析法。 1.3完成语法分析程序的设计和实现。 1.4程序能完成对指定语言的语法分析。 2. 递归下降分析器 在不含左递归和每个非终结符的所有候选终结首符集都两两不相交的条件下,我们就可能构造…

用c语言编译递归下降翻译器,Java实现C语言语义分析(递归下降)

说起这次的语义分析,不得不说的是我的重大的改变。上一次的语法分析是利用了预测分析法来实现的,经过多方考证,发现用预测分析法的语法分析器基础来实现语义分析的困难重重,例如在语法指导翻译的时候那个栈的变化和各种属性的传递…

递归下降分析法

介绍: 递归下降分析法是针对LL(1)文法的一种语法分析方法; 通过对文法的消除左递归,提取左公因子,对各个产生式和非终结符求first()和follow()集,通过first()和follow()集构造该文法的预测分析表,当这个预…

编译原理实验-递归下降语法分析

具体代码已放至Github(仅供参考): qxpBlog/Compiler_UESTC: 电子科技大学编译原理实验 (github.com) 具体实验过程如下: 一、实验目的、原理、内容及步骤: (1)目的:通过本实验加深…

编译原理实验--实验二 递归下降法判断算术表达式的正确性--Python实现

目录 一、实验目的和要求 二、实验内容 三、实验环境 四、实验步骤 1、语法分析所依据的文法; 2、给出消除左递归及提取左公因子的文法; 五、测试要求 六、实验步骤 1、语法分析所依据的文法 2、给出消除左递归及提取左公因子的文法&#xff1…

递归下降语法分析

一、实验目的 递归下降语法分析 二、实验题目 三、分析与设计 四、源代码 #include <iostream> #include <fstream> #include <cstring> #include <string> #include <conio.h> #define digit 1 // 1数字 #define op 2 // -*/()# #define Hh …

Java递归下降分析器_递归下降语法分析器

用java语言编写的递归下降语法分析器&#xff0c;是一种适合手写语法编译器的方法&#xff0c;且非常简单。递归下降法对语言所用的文法有一些限制&#xff0c;但递归下降是现阶段主流的语法分析方法&#xff0c;因为它可以由开发人员高度控制&#xff0c;在提供错误信息方面也…

递归下降算法

递归下降算法 算法模型&#xff1a; Term Term Expr ExprExprFactor Factor 单个元素。最小单位。 实现原理&#xff1a; 一个程式进入算法及被看作是一个项&#xff0c;分解成项加表达式的形式&#xff0c;表达式被分解成 表达式加因子的形式&#xff0c;因子是这个算法…

实验二:递归下降语法分析

文章目录 一、实验目的二、实验原理与要求 1、原理 2、要求 三、实验设备四、实验内容五、实验步骤 1. 单词内码表 2. 定义语言文法 3. 语法分析器的实现&#xff08;编码&#xff09; 4. 测试 六、配套资源 一、实验目的 理解自顶向下语法分析的基本模式&#xff0c;熟悉…

编译原理递归下降语法分析器C++实现

编译原理递归下降语法分析器C简单实现 1.递归下降分析法的功能 语法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。 2.递归下降分析法的前提 改造文法&#xff1a;消除二义性、消除左递归、提取左因子&#xff0c;判断是否为LL&#xff08;1&#xff0…

编译原理(九)——递归下降法

背景&#xff1a; 自定向下的语法分析方法&#xff0c;LL(1)是一种非常直观的方法&#xff0c;它的分析过程是按照句子的定义来进行的&#xff0c;也就是说从开始符出发对要分析的串进行推导&#xff0c;如果推导成功就证明这个被分析的串是一个合法的句子&#xff0c;否则的话…

【编译原理】【C语言】实验三:递归下降分析法

C语言 实验环境&#xff1a;Visual Studio 2019 author&#xff1a;zoxiii 递归下降分析法 1、实验内容2、前期准备2.1 递归下降分析法原理2.2 要实现的文法2.3 需要的函数 3、分析过程3.1 递归下降分析法设计思想及算法3.2 分析栈的分析过程3.3 流程图3.4 源代码3.5 运行结果 …

JAVA游戏开发-超炫酷贪吃蛇游戏源码及教程

一&#xff0e;前言 某日&#xff0c;看见隔壁家的小朋友在玩一款网络爆款贪吃蛇游戏&#xff0c;感觉很好玩。自己刚好正在学习JAVA编程&#xff0c;也想实现一个类似功能的游戏Demo练手&#xff0c;在网上查看了不少源码案例&#xff0c;全都是很古老的方块式贪吃蛇游戏案例…

Java实现贪吃蛇游戏【代码】

Java实现贪吃蛇游戏【代码】 花了两个下午写了一个贪吃蛇小游戏&#xff0c;本人想写这游戏很长时间了。作为以前诺基亚手机上的经典游戏&#xff0c;贪吃蛇和俄罗斯方块一样&#xff0c;都曾经在我们的童年给我们带来了很多乐趣。世间万物斗转星移&#xff0c;诺基亚曾经作为手…

JavaSE项目 | 纯Java实现贪吃蛇小游戏

目录 一&#xff1a;贪吃蛇游戏的实现步骤 1. 画出窗口 2. 在窗口上添加画布 3. 在画布上添加黑色游戏区 4. 放静态蛇 5. 定义蛇的数据结构 6. 控制蛇头方向 7. 放上开始提示信息 8. 按空格键开始游戏 9. 让蛇动起来 10. 实现暂停 11. 实现转向功能 12. 添加食物 …

java 贪吃蛇 源码+图片

本人也是个初学者&#xff0c;有什么不对的地方&#xff0c;请大佬指点&#xff01;&#xff01;&#xff01; 一、涉及到的知识点如下&#xff1a; 循环&#xff0c;分支方法的抽取数组的使用面向对象继承&#xff0c;子类方法的重写接口&#xff0c;接口的实现 二、游戏图形…

JAVA贪吃蛇代码(带注释)

贪吃蛇 这是游戏效果图片是代码里面的素材游戏数据类 package com.tang.retor_snaker;import javax.swing.*; import java.net.URL;public class Data {private static URL bodyURL Data.class.getResource("/com/tang/retor_snaker/statics/body.png");private st…

JAVA贪吃蛇小游戏源代码系列

欢迎关注公众号&#xff1a; 获取贪吃蛇小游戏的源代码。 贪吃蛇小游戏运行结果如下&#xff1a; 启动界面&#xff1a; 运行界面&#xff1a; 重启界面&#xff1a; 源代码框架如下&#xff1a; 注&#xff1a;在运行程序的时候&#xff0c;得重新设计窗体的大小&#x…