当前位置:网站首页>编译原理研究性学习专题 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处出现错误
语句不合法
边栏推荐
- Wechat applet development ③
- Fundamental inquiry binary tree
- Price for volume has encountered "six consecutive declines" in sales. Can Volvo, which is no longer safe, turn around?
- 电脑不知卸载什么,打不开计算器无法编辑截图功能打不开txt文件等等解决方案之一
- 22 Niuke multi school Day1 I - Introduction to chiitoitsu DP
- 行泊一体迎爆发期,抢量产还是修技术护城河?
- 金仓数据库 KingbaseES与Oracle的兼容性说明(2. 数据类型)
- Binary search tree
- 金仓数据库KingbaseES 客户端编程接口指南 - ODBC特性支持约束
- Use of typescript class
猜你喜欢

Optimization and implementation of custom MVC
![[self] - brush questions set](/img/de/46582086addbe5465d658081516f4c.png)
[self] - brush questions set

Win11找不到DNS地址怎么办?Win11找不到DNS无法访问网页解决方法

22 Niuke multi school Day1 I - Introduction to chiitoitsu DP

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

2022焊工(初级)上岗证题目及答案

Achieve high throughput through Wi Fi 7 - insight into the next generation of Wi Fi physical layer

宝塔 phpmyadmin未授权访问漏洞

阻塞式队列

Samba service setup
随机推荐
General addition, deletion, modification and query of custom MVC
行泊ADAS摄像头前装搭载同比增长54.15%,TOP10供应商领跑
In order for digital retail to continue to play its role, we need to give new connotation and significance to digital retail
2022 R2 mobile pressure vessel filling test question simulation test platform operation
事件抽取文献整理(2008-2017)
苹果官网正在更新维护 Apple Store,国行 iPhone 13 / Pro 等产品将最高优惠 600 元
金仓数据库 KingbaseES 与 Oracle 的兼容性说明(4. SQL)
Read the recent trends of okaleido tiger and tap the value and potential behind it
2022t elevator repair examination questions and simulation examination
Achieve high throughput through Wi Fi 7 - insight into the next generation of Wi Fi physical layer
Function function
可视化全链路日志追踪
MyCms 自媒体商城 v3.6 发布,兼容微擎应用开发(Laravel框架)
MySQL introduction
从XSS Payload学习浏览器解码
金仓数据库KingbaseES 客户端编程接口指南 - ODBC特性支持约束
机器学习问题笔记
英特尔数据中心GPU正式发货,以开放灵活提供强劲算力
【数据挖掘工程师-笔试】2022年大华股份
2022起重机械指挥考试题模拟考试平台操作