当前位置:网站首页>编译原理研究性学习专题 2——递归下降语法分析设计原理与实现
编译原理研究性学习专题 2——递归下降语法分析设计原理与实现
2022-07-28 21:51:00 【dor.yang】
1 实验内容
完成以下描述赋值语句的 LL(1)文法的递归下降分析程序
G[S]: S→ V=E
E→ TE’
E’→ ATE’ | e
T→ FT’
T’→ MFT’ | E
F→ (E) | i
A→ + | -
M→ * | /
V→ i
设计说明:终结符号 i 为用户定义的简单变量,即标识符的定义。
2 实验要求
(1)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1” 的输出结果,输出为输入串是否为该文法定义的算术表达式的判断结果;
(2)递归下降分析程序应能发现简单的语法错误;
(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果;
(4)选做:如有可能,考虑如何用文法描述 C 语言的 if 语句,使整个文 法仍然为 LL(1)文法,并使得你的递归下降程序可以分析赋值语句和 if 语句
3.程序功能描述
结合实验要求,完成实验二程序,具体实现功能为读取同目录下的实验一输出的词法判别的二元式文件,根据给定文法,按照递归下降分析的方式判断输入的语句是否合理。对于不合理的部分,在判定出错之后输出错误的点。
4.程序结构描述
由于语法是给定的,所以可以先完成first和follow集合的计算:
根据first和follow集合以及给定的文法,可以确定递归向下分析程序的结构。
所以程序的整体表达式结构为:
S的递归分析程序结构如下图
E的递归下降分析程序结构如下图:
E’的递归向下分析的结构图
T的递归下降分析程序结构如下:
T’的递归下降分析程序结构如下:
F的递归下降分析程序结构如下:
A的递归下降分析程序结构如下:
M的递归下降分析程序结构如下:
V的递归下降分析程序结构如下:
5.实现代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include <cassert>
#include<fstream>
#define MAX_LINE 1024
using namespace std;
// 函数声明
void S();
void E();
void E_();
void T();
void T_();
void F();
void A();
void M();
void V();
// 定义一个长度为100的字符数组
char s[100];
// 用来作数组索引,当每次匹配成功存入数据时index自增1
int i;
// 用来标记语句是否正确
int SIGN;
int main()
{
// printf("请输入你的语句(记得在最后带上#)\n");
cout<<"读取文件可知输入语句:"<<endl;
FILE *fp;
char buf[MAX_LINE];
string shizi,like;
if((fp = fopen("text.txt","r"))!=NULL){
while(fgets(buf,MAX_LINE,fp) != NULL)
{
int len = strlen(buf);
buf[len-1] = '\0'; /*去掉换行符*/
printf("%s \n",buf);
int flag=0;
if(buf[1]=='1'){
like+='i';
}
for(int i=0;i<len;i++){
if(buf[i]=='"'&&flag==0){
i++;
while(buf[i]!='"'){
shizi+=buf[i];
if(buf[1]!='1'){
like+=buf[i];
}
i++;
}
}
}
}
}
shizi+='#';
like+='#';
fclose(fp);
cout<<"输入的语句为:"<<shizi<<endl;
cout<<"可以理解为:"<<like<<endl;
SIGN = 0;//语句是否正确用SIGN
i=0;
//将输入的式子按照修改为字符串格式char*
int length=like.length();
for(int i=0;i<length;i++){
s[i]=like[i];
}
// 当输入的第一个字符为#时,程序直接结束
if( s[0] == '#')
return 0;
S();
// 如果最后的字符以#结束则输出下面
if(s[i]=='#'&&SIGN==0){
printf("\n语句合法\n");
}else{
printf("\n语句不合法\n");
}
// printf("请输入你的语句(记得在最后带上#)\n");
// }
return 1;
}
void S()
{
if(SIGN==0)
{
printf("S检查 ");
// 当输入的字符串中首字母为a时
if(s[i]=='i'){
V();
if(SIGN==0&&s[i]=='='){
// printf("(%c) ",s[i]);
i++;
E();
}
else{
SIGN=1;
cout<<"S处出现错误"<<endl;
}
}
else{
SIGN=1;
cout<<"S处出现错误"<<endl;
}
}
}
void E()
{
if(SIGN==0){
printf("E ");
if(s[i]=='('||s[i]=='i'){
T();
if(SIGN==0){
if(s[i]=='+'||s[i]=='-'){
E_();
}
else if(s[i]==')'||s[i]=='#'){
return;
}
else{
SIGN=1;
cout<<"E处出现错误"<<endl;
}
}
}
else{
SIGN=1;
cout<<"E处出现错误"<<endl;
}
}
}
void E_()
{
if(SIGN==0){
printf("E' ");
if(s[i]=='+'||s[i]=='-'){
A();
if(SIGN==0){
if(s[i]=='('||s[i]=='i'){
T();
if(SIGN==0){
if(s[i]=='+'||s[i]=='-'){
E_();
}
else if(s[i]==')'||s[i]=='#') {
return;
}
else{
SIGN=1;
cout<<"E'处出现错误"<<endl;
}
}
}
else{
SIGN=1;
cout<<"E'处出现错误"<<endl;
}
}
}
else if(s[i]==')'||s[i]=='#'){
return;
}
else{
SIGN=1;
cout<<"E'处出现错误"<<endl;
}
}
}
void T()
{
if(SIGN==0){
printf("T ");
if(s[i]=='('||s[i]=='i'){
F();
if(SIGN==0){
if(s[i]=='*'||s[i]=='/'){
T_();
}
else if(s[i]=='+'||s[i]=='-'||s[i]==')'||s[i]=='#') {
return;
}
else{
SIGN=1;
cout<<"T处出现错误"<<endl;
}
}
}
else{
SIGN=1;
cout<<"T处出现错误"<<endl;
}
}
}
void T_()
{
if(SIGN==0){
printf("T' ");
if(s[i]=='*'||s[i]=='/'){
M();
if(SIGN==0){
F();
if(SIGN==0){
T_();
}
}
}
else if(s[i]=='+'||s[i]=='-'||s[i]==')'||s[i]=='#'){
return;
}
else{
SIGN=1;
cout<<"T'处出现错误"<<endl;
}
}
}
void F()
{
if(SIGN==0){
printf("F ");
if(s[i]=='('){
// printf("(%c) ",s[i]);
i++;
if(s[i]=='('||s[i]=='i'){
E();
if(SIGN==0){
if(s[i]==')'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"F处出现错误"<<endl;
}
}
}
else{
SIGN=1;
cout<<"F处出现错误"<<endl;
}
}
else if(s[i]=='i'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"F处出现错误"<<endl;
}
}
}
void A()
{
if(SIGN==0){
printf("A ");
if(s[i]=='+'||s[i]=='-'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"A处出现错误"<<endl;
}
}
}
void M()
{
if(SIGN==0){
printf("M ");
if(s[i]=='*'||s[i]=='/'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"M处出现错误"<<endl;
}
}
}
void V()
{
if(SIGN==0){
printf("V ");
if(s[i]=='i'){
// printf("(%c) ",s[i]);
i++;
}
else{
SIGN=1;
cout<<"V处出现错误"<<endl;
}
}
}
6.程序测试
按照实验要求,提供两个测试样例,一个正确一个错误:
首先是正确的测试样例,将a=b*(c+d)输入在input文件中,启动程序lab1,产生对应的二元式,这里为了便于判断和操作,将标识符的二元式输出修改为(1,‘符号’),得到的输出二元式如下:

接下来启动Lab2,可以得到如下结果:
将上图的输出部分单独显示:
读取文件可知输入语句:
(1,“a”)
(运算符,“=”)
(1,“b”)
(运算符,"“)
(分隔符,”(“)
(1,“c”)
(运算符,”+“)
(1,“d”)
(分隔符,”)")
输入的语句为:a=b(c+d)#
可以理解为:i=i*(i+i)#
S检查 V E T F T’ M F E T F E’ A T F T’
语句合法
其中倒数第二行的输出是进行递归下降分析的过程中,每一个非终结符号对应函数的使用的输出。
接下来是错误的测试样例:将a=b*(c+d输入在input文件中,启动程序lab1,产生对应的二元式,得到的输出二元式如下:
启动Lab2的程序之后得到的结果如下:
将程序输出部分单独显示:
读取文件可知输入语句:
(1,“a”)
(运算符,“=”)
(1,“b”)
(运算符,"“)
(分隔符,”(“)
(1,“c”)
(运算符,”+")
(1,“d”)
输入的语句为:a=b(c+d#
可以理解为:i=i*(i+i#
S检查 V E T F T’ M F E T F E’ A T F
F处出现错误
语句不合法
边栏推荐
- Input element label
- 深度剖析集成学习Adaboost
- CV语义分割模型小抄(2)
- 【自】-刷题-字符串
- Few people can really play in the "aftermarket" of the whole house intelligent fire collection
- String string
- 2022g3 boiler water treatment test simulation 100 questions simulation test platform operation
- 22 Niu Ke multi school Day1 J - serval and essay heuristic merging
- 如何开一家盈利的健身房?我用1年回本的经验告诉你,别谈恋爱
- 以流量为主导的数字零售的发展模式,仅仅只是一个开始
猜你喜欢

电脑不知卸载什么,打不开计算器无法编辑截图功能打不开txt文件等等解决方案之一
![[self] - question brushing - dynamic programming](/img/84/edc683494756d5af755204fe4f4d93.png)
[self] - question brushing - dynamic programming

Win11快捷复制粘贴不能用怎么办?Win11快捷复制粘贴不能用

深度剖析集成学习GBDT

2022T电梯修理考试试题及模拟考试

trivy【3】自定义扫描策略

Programmer growth Chapter 30: artifact of identifying true and false needs

字节8年女测试总监工作感悟—写给想转行或即将进入测试行业的女生们...

2022t elevator repair examination questions and simulation examination

【自】-刷题-字符串
随机推荐
[self] - question brushing - string
2022 G2 power plant boiler stoker examination question bank simulated examination platform operation
2022年R2移动式压力容器充装考题模拟考试平台操作
[self] - brush questions set
Samba service setup
【自】-刷题-数组
22牛客多校day1 J - Serval and Essay 启发式合并
How to embed AI digital human function in VR panorama? Create a cloud experience
如何将一个mongodb中集合的索引 添加到另一个mongodb中集合中
从XSS Payload学习浏览器解码
ACM SIGIR 2022 | 美团技术团队精选论文解读
Wechat applet development ④
MyCms 自媒体商城 v3.6 发布,兼容微擎应用开发(Laravel框架)
What if win11 cannot find the DNS address? Win11 can't find DNS and can't access the web page solution
trivy【2】工具漏洞扫描
2022 simulated examination platform operation of hoisting machinery command examination questions
mongodb索引添加、查看、导出、删除
【自】-刷题-集合
酒店预订系统数据库房间库存设计思路
MySQL transaction and storage system