【编译原理】自上而下语法分析(C/C++源码+实验报告)
文章目录
- 1 实验目的和内容
- 1.1 实验目的
- 1.2 实验内容
- 1.3 实验要求
- 2 设计思想
- 2.1 根据BNF描述该文法
- 2.2 根据文法画相应的语法图
- 2.3 判断是否是LL(1)文法---求First、Follow集
- 2.4 递归下降子程序
- 3 算法流程
- 4 源程序
- 5 调试数据
- 6 思考:词法分析+语法分析
- 6.1 将实验一的词法分析作为函数写入语法分析程序
- 6.2 调试数据
- 6.3 调试结果
- 7 实验调试情况及体会
- 7.1 实验调试情况
- 7.2 实验体会
1 实验目的和内容
1.1 实验目的
(1)给出 PL/0 文法规范,要求编写 PL/0 语言的语法分析程序。
(2)通过设计、编制、调试一个典型的自上而下语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步 掌握常用的语法分析方法。
(3)选择最有代表性的语法分析方法,如递归下降分析法、预测分析法; 选择对各种常见程序语言都具备的语法结构,如赋值语句,特别是表达式,作为分析对象。
1.2 实验内容
(1)已给 PL/0 语言文法,构造表达式部分的语法分析器。
(2)分析对象〈算术表达式〉的 BNF 定义如下:
<表达式> ::= [+|-]<项>{<加法运算符> <项>}
<项> ::= <因子>{<乘法运算符> <因子>}
<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’
<加法运算符> ::= +|-
<乘法运算符> ::= *|/
<关系运算符> ::= =|#|<|<=|>|>=
1.3 实验要求
(1)将实验一“词法分析”的输出结果,作为表达式语法分析器的输入,
进行语法解析,对于语法正确的表达式,报告“语法正确”;对于语
法错误的表达式,报告“语法错误”, 指出错误原因。
(2)把语法分析器设计成一个独立一遍的过程。
(3)采用递归下降分析法或者采用预测分析法实现语法分析。
2 设计思想
2.1 根据BNF描述该文法
(1)对BNF中的各对象简称如下
B:表达式 C:乘法运算符
J:加法运算符 N:无符号整数
X:项 S:标识符
Y:因子 G:关系运算符
(2)文法如下
B->JX(JX)|X(JX)
X->Y(CY)*
Y->S|N|(B)
J->+|-
C->*|/
G->=|#|<|<=|>|>=
2.2 根据文法画相应的语法图
(1)表达式
图1 表达式—语法图
(2)项
图2 项—语法图
(3)因子
图3 因子—语法图
2.3 判断是否是LL(1)文法—求First、Follow集
(1)改文法没有左递归。
(2)各非终结符的First、Follow集如下所示
(3)根据LL(1)文法的判断规则可知,该文法满足LL(1)文法的条件,所以该文法是LL(1)文法。
2.4 递归下降子程序
(1)表达式
PROCEDUER B;
BEGINIF SYM = '+' OR SYM = '-' THEN ADVANCE;ELSE IF SYM 在 First(X) THENBEGINADVANCE;X;ENDELSE ERROR; WHILE SYM = '+' OR SYM = '-' THENBEGINADVANCE;X;END
END
(2)项
PROCEDUER X;
BEGINIF SYM 在 First(Y) THENBEGINADVANCE;Y;ENDELSE ERROR; WHILE SYM = '*' OR SYM = '/' THEN ADVANCE;IF SYM 在 First(Y) THENBEGIN ADVANCE;Y;ENDELSE ERROR;
END
(3)因子
PROCEDUER Y;
BEGINIF SYM = '(' THENBEGINADVANCE;B;ADVANCE;IF SYM = ')' THEN ADVANCE;ELSE ERROR;ENDELSE IF SYM 在 First(Y) THEN ADVANCE;ELSE ERROR;
END
3 算法流程
语法分析程序的输入是一个个单词符号的二元组,输出是一个个语法单位,它的任务是在词法分析识别出单词符号串的基础上,分析并判定程序的语法结构是否符合语法规则。
首先逐行扫描单词符号二元组,然后遍历串的每一个字符,判断字符是不是+或-、*或/、因子的first集,再进行下一步的判断,选择进行表达式分析、项分析和因子分析,并输出相应的语句。如果不符合这几种情况,将会归入出错处理。完整算法流程如下图所示。
图4 算法流程图
4 源程序
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std; #define L 8 void fac_aly();
void all_aly();string input_str[L];//存储单词符号
int str_i = 0;//访问input_str的下标//字符串数组下标往前移
void str_i_adv()
{str_i++;if(str_i > L-1){cout<<"下标越界,请重新输入!";exit(0);//重新输入string str;for(int i=0;i<L-1;i++){cin>>str;//检测输入的结束int zero_id = str.find(',', 0);//存储识别出来的字母到字符串数组中input_str[i] = str.substr(1, zero_id - 1);}}
} //对表达式进行分析
void exp_aly()
{//对表达式中的每一个因子做分析fac_aly();while(input_str[str_i] == "times" || input_str[str_i] == "slash"){//数组下标前移str_i_adv();//对表达式中的每一个因子做分析fac_aly();}return;
} //对表达式中的每一个因子做分析
void fac_aly()
{//判断是否是字母if(input_str[str_i] == "ident"){//数组下标前移str_i_adv();}//判断是否是数字else if(input_str[str_i] == "number"){//数组下标前移str_i_adv();}//判断是否是左括号else if(input_str[str_i] == "lparen"){//数组下标前移str_i_adv();//对目前的数组进行整体分析all_aly();//判断是否是右括号if(input_str[str_i] == "rparen"){//数组下标前移str_i_adv();}else {cout<<"ERROR!"<<endl;exit(0);}}return;
}//对目前的表达式进行整体分析
void all_aly()
{if(input_str[str_i] == "plus" || input_str[str_i] == "minus"){//数组下标前移str_i_adv();}exp_aly();while(input_str[str_i] == "plus" || input_str[str_i] == "minus"){//数组下标前移str_i_adv();exp_aly();}return;
} int main()
{string str;//输入词法分析的结果for(int i=0;i<L-1;i++){cin>>str;//检测输入的结束int zero_id = str.find(',', 0);//存储识别出来的字母到字符串数组中input_str[i] = str.substr(1, zero_id - 1);} //对字符串数组中的表达式进行分析if(input_str[str_i] == "plus" || input_str[str_i] == "minus"){//数组下标前移str_i_adv();}//表达式分析exp_aly();while(input_str[str_i] == "plus" || input_str[str_i] == "minus"){//数组下标前移str_i_adv();//表达式分析exp_aly();}if(str_i == L-1) cout<<"Yes,it is correct."<<endl;else cout<<"No,it is wrong.";return 0;
}
5 调试数据
(1)测试样例如下
【样例输入】
(lparen,()
(ident,a)
(plus,+)
(number,15)
(rparen,))
(times,*)
(ident,b) 【样例输出】
Yes,it is correct.
(2)测试样例结果如下
图5 样例测试结果
6 思考:词法分析+语法分析
6.1 将实验一的词法分析作为函数写入语法分析程序
int main()
{string st1r;//输入源程序for(int i=0;i<L-1;i++){cin>>str1;//检测输入的结束string str;str = fun_cifa(str1);//调用词法分析子程序int zero_id = str.find(',', 0);//存储识别出来的字母到字符串数组中input_str[i] = str.substr(1, zero_id - 1);}//对字符串数组中的表达式进行分析if(input_str[str_i] == "plus" || input_str[str_i] == "minus"){//数组下标前移str_i_adv();}//表达式分析exp_aly();while(input_str[str_i] == "plus" || input_str[str_i] == "minus"){//数组下标前移str_i_adv();//表达式分析exp_aly();}if(str_i == L-1) cout<<"Yes,it is correct."<<endl;else cout<<"No,it is wrong.";return 0;
}
6.2 调试数据
【样例输入】
(a+15)*b【样例输出】
(lparen,()
(ident,a)
(plus,+)
(number,15)
(rparen,))
(times,*)
(ident,b)
Yes,it is correct.
6.3 调试结果
图6 样例测试结果
7 实验调试情况及体会
7.1 实验调试情况
由上两步中的测试样例可以得到,所有的测试样例均得到了相应的输出结果,说明代码编写成功,并且在代码中设置了出错处理,以便解决其他情况。
本次实验同时也实现了词法分析与语法分析合在一起去识别源程序的程序,但依然存在一些问题,比如语句只能一句一句地去识别,而不能进行整体识别,该问题会在后续过程中加以解决。
7.2 实验体会
这次实验采用的方法是自上而下分析中的递归下降分析法,首先画出了递归下降分析的语法图,然后判断文法是否属于LL(1)文法,最后写出了递归下降的子程序,并写出了代码,在代码中即可以调用上次词法分析的程序,直接对输入的字符串进行分割传入字符串str。
通过这次实验对于LL(1)文法的三个条件有了更深刻的认识,以及加深对于first 和follow 集合的求法,并且独立完成递归调用函数的书写和实现,对于递归思想又有了进一步的认识,要写函数结束出口,防止函数进入死循环。
通过这次实验进一步了解了自上而下的语法分析:对于输入的词法分析结果,进行左推导,得到一个合法句子或者非法结构,是一种递归和试探的方法,并且自上而下建立输入序列的分析树,而且需要消除左递归并且提取公因子,进一步理解了理论课所学的具体内容,加深对于一些自上而下课后题的理解。这次实验课的收获很大。
最后,感谢刘善梅老师和其他同学在这次实验中给予我的帮助,不胜感激!
【编译原理】自上而下语法分析(C/C++源码+实验报告)相关推荐
- 【编译原理】自上而下语法分析(CC++源码+实验报告)
文章目录 1 实验目的和内容 1.1 实验目的 1.2 实验内容 1.3 实验要求 2 设计思想 2.1 根据BNF描述该文法 2.2 根据文法画相应的语法图 2.3 判断是否是LL(1)文法-求Fi ...
- 编译原理预测分析法c语言,编译原理预测分析法C语言的实验报告.doc
题目:编写识别由下列文法所定义的表达式的预测分析程序. EàE+T | E-T | T TàT*F | T/F |F Fà(E) | i 输入:每行含一个表达式的文本文件. 输出:分析成功或不成功信息 ...
- 编译原理——自上而下语法分析
自上而下分析面临的问题 回溯 (当候选有多个的时候,匹配失败会造成回溯) 文法左递归问题 那么他这个语法树就会无限增长但是分析并没有继续进行下去,就会导致分析进入死循环中 LL1文法消除左递归 消除直 ...
- 基于SSM的商城项目项目源码+实验报告
基于SSM的商城项目 本项目是今年暑假小学期时完成的,耗时四天时间,在小学期结束项目答辩时,在年级里斩获冠军,在此很感谢我的团队,正是我们各个环节的配合,最终才能够获得如此好的成绩. 目录 基于SSM ...
- c语言五子棋源代码vc6,五子棋源码实验报告及人机对战说明.docx
1. 五子棋对战说明 2. 实验报告 3. 源代码 五 子 棋 作品特点:C 语言程序 五子棋 作品功能:五子棋人机对战,人人对战. 目录:1 五子棋介绍. 五子棋棋型介绍. 人人对战的实现. 电脑下 ...
- java编译使用androidsdk,详解Android源码的编译
本文将为大家介绍的是如何设置Android源码的编译环境,包括Linux下的配置.主要基于Android 1.0环境,希望对大家了解Android开发有所帮助. 本次编译过程主要参考官方文档(http ...
- vs+cmake完美编译RTS游戏,类似魔兽争霸源码
网上的一个RTS游戏,网上的代码比较老,不能直接编译.这个仓库是我整理编译通过的.代码版权归于原作者. 源码下载 vs+cmake完美编译RTS游戏,类似魔兽争霸源码下载-其他文档类资源-CSDN文库 ...
- 实时编译、动态执行C/C++源码函数
实时编译.动态执行C/C++源码函数 语法格式:fileCLASS *pObj = <file.cpp> 该语法获得源代码file.cpp的函数接口对象指针pObj,通过pObj调用fil ...
- ubuntu 14.04.5 编译Android 4.4.4 r1源码(最新)
本文博客链接:http://blog.csdn.net/qq1084283172/article/details/54426189 吐槽:ubuntu系统真是让人又爱又恨,也有可能是VMware Wo ...
- 【2021软件创新实验室暑假集训】SpringMVC框架(设计原理、简单使用、源码探究)
系列文章目录 20级 Java篇 [2021软件创新实验室暑假集训]计算机的起源与大致原理 [2021软件创新实验室暑假集训]Java基础(一) [2021软件创新实验室暑假集训]Java基础(二) ...
最新文章
- The 30 CSS Selectors you Must Memorize
- Flash 组件应用与开发
- ospf避免环路_【网络干货】超全的OSPF路由协议技术汇总解析
- 微信小程序 网学习址
- MATLAB 距离函数及用法
- Exchange Server 2013部署系列之一:部署环境介绍
- Linux内核移植入门
- vue实现codemirror代码编辑器中的SQL代码格式化功能
- html中引入字体包
- Beetl页面模板文档
- 中考英语听说计算机考试满分,关于做好北京2018年中考英语听说计算机考试工作的通知...
- 坐标转换程序:布尔沙七参数计算、投影正反算、坐标换带等
- android 第三方相册,相册选择图片
- 第三方支付躺赚的好日子结束:银行直连模式瓦解
- 家装企业如何开展网络营销?
- CDR无法启动此程序 因为计算机丢失,教您快速解决CorelDRAW X7因缺少VGCore.dll无法启动的难题...
- Word/Excel文档操作API哪家强?一张表带你了解Aspose和Spire系列全功能对比
- 【HTCVR】VRTK插件案例分析之0011~020
- 小学有计算机课程吗,小学计算机是不是就是信息技术啊
- uniapp——云打包安卓教程
热门文章
- 向量积的二维物理意义,二维向量叉乘几何意义
- 只更新服务器代码有变更的文件,签出TFS 2010变更集中的文件(check out files in TFS 2010 changeset)...
- 赵鹏的《大师之路》教程
- 如何下载朝阳区卫星地图高清版大图
- python毕业论文参考文献格式范例_毕业论文参考文献范例
- 计算机电源性能怎么调,笔记本电脑如何将电源模式更改为高性能模式? -
- 中证登 中债登 上清所 证券清算 证券账户 资金账户
- php PDO连接mysql
- 什么是Trunk端口模式?此模式有何作用?
- 一个20岁工作了4年男网管真情自白书