当前位置:网站首页>编译原理研究性学习专题 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处出现错误
语句不合法
边栏推荐
- 2022起重机械指挥考试题模拟考试平台操作
- MyCms 自媒体商城 v3.6 发布,兼容微擎应用开发(Laravel框架)
- 金仓数据库 KingbaseES 与 Oracle 的兼容性说明(3. 常用函数)
- 金仓数据库 KingbaseES V8.3至V8.6迁移最佳实践(3. KingbaseES移植能力支撑体系)
- Combination of smart TV and applet
- 苹果官网正在更新维护 Apple Store,国行 iPhone 13 / Pro 等产品将最高优惠 600 元
- Arduino UNO驱动合宙1.8‘TFT SPI屏幕示例演示(含资料包)
- 阻塞式队列
- Optimization and implementation of custom MVC
- [self] - brush questions array
猜你喜欢

With the "integration of driving and parking", freytek's high-performance domain controller leads the new track

Pin mapping relationship of stm32f103c series single chip microcomputer under Arduino framework

MySQL log management, backup and recovery

CV目标检测模型小抄(2)

Zero vision technology completed the pre-A round of financing and promoted the domestic replacement of intelligent driving platform software

CV实例分割模型小抄(1)

Read the recent trends of okaleido tiger and tap the value and potential behind it
![[self] - brush questions BFS](/img/e9/e90557c63c217a43c6a5d9de0d0869.png)
[self] - brush questions BFS

新一代超安全蜂窝电池 思皓爱跑上市13.99万元起售

【自】-刷题-峰值
随机推荐
使用这个,你发的消息就无法被监控了
CV语义分割模型小抄(2)
MySQL introduction
Development of small programs ①
KingbaseES客户端编程接口指南-ODBC(4. 创建数据源)
零视科技 H5S视频平台 GetUserInfo 信息泄漏漏洞 CNVD-2020-67113
字节8年女测试总监工作感悟—写给想转行或即将进入测试行业的女生们...
金仓数据库 KingbaseES 与 Oracle 的兼容性说明(4. SQL)
Byte 8 years' experience of female test Director - for girls who want to change careers or are about to enter the testing industry
Object object
With the "integration of driving and parking", freytek's high-performance domain controller leads the new track
网络流量监控工具iftop
2022G3锅炉水处理考试模拟100题模拟考试平台操作
英特尔数据中心GPU正式发货,以开放灵活提供强劲算力
Achieve high throughput through Wi Fi 7 - insight into the next generation of Wi Fi physical layer
2022 simulated examination platform operation of hoisting machinery command examination questions
Rhce第一天
The front mounted ADAS camera in parking increased by 54.15% year-on-year, with TOP10 suppliers taking the lead
Objc4-841.13 debuggable / compiled source code update
What is utxo?