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

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

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处出现错误

语句不合法


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

相关文章

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

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

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

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

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

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

递归下降分析法

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

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

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

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

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

JAVA 实现《贪吃蛇大作战》游戏|CSDN创作打卡

前言 贪吃蛇&#xff08;也叫做贪食蛇&#xff09;游戏是一款休闲益智类游戏&#xff0c;有PC和手机等多平台版本。既简单又耐玩。该游戏通过控制蛇头方向吃东西&#xff0c;从而使得蛇变得越来越长。 本程序是通过java的swing来实现《贪吃蛇大作战》这款游戏。 主要需求 1…