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;//语句是否正确用SIGNi=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处出现错误

语句不合法

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

  1. 基于C++的递归下降语法分析设计原理与实现

    资源下载地址:https://download.csdn.net/download/sheziqiong/85949206 资源下载地址:https://download.csdn.net/downl ...

  2. 实验2 递归下降语法分析程序设计

    [开发语言及实现平台或实验环境] C++/Clion [实验目的] (1)理解语法分析在编译程序中的作用,以及它与词法分析程序的关系 (2)加深对递归下降语法分析原理的理解 (3)掌握递归下降语法分析 ...

  3. 【Compile】递归下降语法分析(C++)

    实验题目 编写识别由下列文法G[E]所定义的表达式的递归下降语法分析器. E→E+T∣E−T∣TE \rightarrow E+T | E-T | TE→E+T∣E−T∣T T→T∗F∣T/F∣FT ...

  4. 《编译原理》实验预习报告——递归下降语法分析器的构建

    一.实验目的 根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析.本次实验的目的主要是加深对递归下降分析法的理解. 二.实验预习提示 1.递归下降分析法的功能 词法分析器的功能是利用 ...

  5. android qq功能实现原理,Android QQ、微信聊天消息界面设计原理与实现

     Android QQ.微信聊天消息界面设计原理与实现 原理:Android平台上,典型的以腾讯的QQ.微信这些聊天消息界面通常可以采用ListView设计与实现,需要使用ListView 适配器 ...

  6. 递归下降语法分析程序

    文法G[E] E –> E + T | T T –> T + F | F F –> i | (E) 消除左递归 E –> TE' E'-> +TE' E'-> ε ...

  7. java数组设计的原理_动态图-Java常用数据结构及其设计原理

    > 转载 - [图解Java常用数据结构(一) - 大道方圆 - 博客园 ](https://www.cnblogs.com/xdecode/p/9321848.html) > https ...

  8. 《编译原理》实验报告——递归下降语法分析器的构建

    一.实验要求 运用递归下降法,针对给定的上下文无关文法,给出实验方案.预估实验中可能出现的问题. 二.实验方案 1.构造LL(1),通过设计.编制.调试递归下降语法分析程序,对输入的符号串进行分析匹配 ...

  9. 编译原理8:递归下降分析器、扩充巴斯克范式、JavaCC

    递归下降分析器 递归下降分析器设计示例 E'不考虑follow集的隐患会被后续的子程序考虑到,所以没有问题 扩充的巴科斯范式和语法图 JavaCC简介 小结

  10. 编译原理实验-递归下降语法分析器的构建

    实验目的: 针对给定的上下文无关文法,编制一个递归下降分析程序. 分析: 递归下降语法分析的前提是保证LL(1)文法 递归下降的思路就是暴力dfs.对每个程序直接不管三七二十一搜进去,只要能搜到就继续 ...

最新文章

  1. 便利vector_C++面试题之list和vector的区别
  2. Winforn中导入Excel并显示然后获取多选框选中的内容
  3. 测试功能范围_我们该如何制定手机浏览器菜单改版测试范围呢?
  4. 离散哈特莱变换(DHT)及快速哈特莱变换(FHT)学习
  5. C#获取本执行程序所在的当前路径
  6. 语言软件生成outsid_常用的C语言开发工具有哪些
  7. SQL查询语句中参数带有中文查询不到结果
  8. JAVA计算机毕业设计钢材商贸公司网络购销管理系统Mybatis+系统+数据库+调试部署
  9. 1183 连接字符串
  10. Linux作为哑终端连接服务器,linux – TERM =哑终端必须具备的功能
  11. scrapy解析网页时,针对一些特别格式的数据的处理
  12. 中国富豪掘第一桶金的九大方式
  13. CnOpenData中国上市公司公告数据简介
  14. 小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖
  15. 妹子图 Spider
  16. 连接到物联网的12中通信技术
  17. C++将两个字符串合并在一起
  18. 理解 rb_tree
  19. 20220712 初识JS
  20. 关闭Hyper-v虚拟服务

热门文章

  1. tecplot批量导出图片_tecplot使用教程
  2. java a标签实现文件下载_a标签实现文件下载 避免直接打开问题
  3. m7405d粉盒清零方法_联想打印机 多功能一体机全系列硒鼓清零方法
  4. (附源码)小程序 校园二手交易平台 毕业设计 191637
  5. 微信公众号支付失败的各种原因
  6. java代码jar包混淆,proguard对java代码进行混淆
  7. jquery ajax提交form表单,jquery+ajax提交form表单方法总结
  8. 从python学编程pdf_教孩子学编程-Python语言版 PDF 高清完整版 网盘资源分享
  9. 【分享】5G+北斗RTK高精度人员定位解决方案
  10. 安卓学习之路-RecyclerView的简单用法