编译原理--递归下降分析实验C++

一、实验项目要求

1.实验目的

根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。

2.实验要求

对下列文法,用递归下降分析法对任意输入的符号串进行分析:

(1)E->TG

(2)G->+TG|—TG

(3)G->ε

(4)T->FS

(5)S->*FS|/FS

(6)S->ε

(7)F->(E)

(8)F->i

输出的格式如下:

(1)递归下降分析程序,编制人:姓名,学号,班级

(2)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串例如:i+i*i#

(3)输出结果:i+i*i#为合法符号串

备注:输入一符号串如i+i*#,要求输出为“非法的符号串”。

注意:

1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;

2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);

二、理论分析或算法分析

1、程序设计:

(1)模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。

(2)写出设计方案:模块关系简图、流程图、全局变量、函数接口等。

(3)程序编写:

①定义部分:定义常量、变量、数据结构。

      ②初始化:从文件将输入符号串输入到字符缓冲区中。

      ③利用递归下降分析法,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。

三、实验方法

程序流程图如图所示:

四、实验结果分析

实验结果图

遇到的问题

(1)遇到如图所示的问题:

解决办法

(1)在文件顶部加入一行#define _CRT_SECURE_NO_WARNINGS后可以解决;

通过本次实验,学习了语法分析,让我对语法分析有了一定的认识和了解。递归下降分析法,是一种确定的自顶向下分析技术,它的实现思想是,对文法分别代表一种语法成分的每个非终结符号编写一个子程序,已完成非终结符号所对应的语法成分的分析任务。在分析过程中调用一系列过程或函数,对源程序进行语法语义分析直到整个程序处理结束;即使理解了理论知识,我也不一定会编程。

五、代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<dos.h>
#include<stdlib.h>
#include<string.h>

char a[50], b[50], d[500], e[10];
char ch;
int n1, i1 = 0, flag = 1, n = 5;
int E();
int E1();
int T();
int G();
int S();
int F();
void input();
void input1();
void output();
void main()                      /*递归分析*/
{
	int f, p, j = 0;
	char x;
	d[0] = 'E';
	d[1] = '=';
	d[2] = '>';
	d[3] = 'T';
	d[4] = 'G';
	d[5] = '#';
	printf("递归下降分析程序,编制人:***,**号,******班\n");
	printf("输入一以#结束的符号串(包括+ - * / ( ) i #,且长度小于50):");
	do {
		scanf("%c", &ch);
		a[j] = ch;
		j++;
	} while (ch != '#');
	n1 = j;
	ch = b[0] = a[0];
	printf("文法\t分析串\t\t\t分析字符\t\t剩余串\n");
	f = E1();
	if (f == 0) return;
	if (ch == '#')
	{
		printf("accept\n");
		p = 0;
		x = d[p];
		//	{
		//			printf("%c",x);p=p+1;x=d[p];          /*输出推导式*/
		//		}	
		while (a[p] != '#')
			printf("%c", a[p++]);
		printf("为合法字符!\n");
	}
	else {
		//	printf("error\n");
		j = 0;
		while (a[j] != '#')
			printf("%c", a[j++]);
		printf("非法字符!\n");
		printf("回车返回\n");
		getchar(); getchar();
		return;
	}
	printf("\n");
	printf("回车返回\n");
	getchar();
	getchar();
}
int E1()
{
	int f, t;
	printf("E-->TG\t");
	flag = 1;
	input();
	input1();
	f = T();
	if (f == 0) return(0);
	t = G();
	if (t == 0) return(0);
	else return(1);
}

int E()
{
	int f, t;
	printf("E-->TG\t");
	e[0] = 'E'; e[1] = '='; e[2] = '>'; e[3] = 'T'; e[4] = 'G'; e[5] = '#';
	output();
	flag = 1;
	input();
	input1();
	f = T();
	if (f == 0)
		return(0);
	t = G();
	if (t == 0) return(0);
	else return(1);
}
int T()
{
	int f, t;
	printf("T-->FS\t");
	e[0] = 'T'; e[1] = '='; e[2] = '>'; e[3] = 'F'; e[4] = 'S'; e[5] = '#';
	output();
	flag = 1;
	input();
	input1();
	f = F();
	if (f == 0)
		return(0);
	t = S();
	if (t == 0) return(0);
	else return(1);
}
int  G()
{
	int f;
	if (ch == '+')
	{
		b[i1] = ch;
		printf("G-->+TG\t");
		e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '+'; e[4] = 'T'; e[5] = 'G'; e[6] = '#';
		output();
		flag = 0;
		input(); input1();
		ch = a[++i1];
		f = T();
		if (f == 0)
			return(0);
		f = G();
		if (f == 0)
			return 0;
		else return 1;
	}
	else if (ch == '-')
	{
		b[i1] = ch;
		printf("G-->-TG\t");
		e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '-'; e[4] = 'T'; e[5] = 'G'; e[6] = '#';
		output();
		flag = 0;
		input(); input1();
		ch = a[++i1];
		f = T();
		if (f == 0)
		{
			//			printf("G=%d\n",f);
			return(0);
		}
		f = G();
		if (f == 0)
			return 0;
		else return 1;
	}
	else
	{
		printf("G-->^\t");
		e[0] = 'G'; e[1] = '='; e[2] = '>'; e[3] = '^'; e[4] = '#';
		output();
		flag = 1;
		input(); input1();
		return(1);
	}
}

int S()
{
	int f, t;
	if (ch == '*')
	{
		b[i1] = ch;
		printf("S-->*FS\t");

		e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '*'; e[4] = 'F'; e[5] = 'S'; e[6] = '#';
		output();
		flag = 0;
		input(); input1();
		ch = a[++i1];
		f = F();
		if (f == 0)
			return(0);
		t = S();
		if (t == 0)
			return(0);
		else return(1);
	}
	else if (ch == '/')
	{
		b[i1] = ch;
		printf("S-->/FS\t");

		e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '/'; e[4] = 'F'; e[5] = 'S'; e[6] = '#';
		output();
		flag = 0;
		input(); input1();
		ch = a[++i1];
		f = F();
		if (f == 0)
			return(0);
		t = S();
		if (t == 0)
			return(0);
		else return(1);
	}
	else
	{
		printf("S-->^\t");
		e[0] = 'S'; e[1] = '='; e[2] = '>'; e[3] = '^'; e[4] = '#';
		output();
		flag = 1;
		a[i1] = ch;
		input(); input1();
		return(1);
	}
}
int F()
{
	int f; int j;
	if (ch == '(')
	{
		b[i1] = ch;
		printf("F-->(E)\t");
		e[0] = 'F'; e[1] = '='; e[2] = '>'; e[3] = '('; e[4] = 'E'; e[5] = ')'; e[6] = '#';
		output();
		flag = 0;
		input(); input1();
		ch = a[++i1];
		f = E();
		if (f == 0) return(0);
		if (ch == ')')
		{
			b[i1] = ch;
			printf("F-->(E)\t");

			flag = 0; input(); input1();
			ch = a[++i1];
		}
		else
		{
			printf("error\n");
			j = 0;
			while (a[j] != '#')
				printf("%c", a[j++]);
			printf("非法字符!\n");
			return(0);
		}
	}
	else if (ch == 'i')
	{
		b[i1] = ch;
		printf("F-->i\t");
		e[0] = 'F'; e[1] = '='; e[2] = '>'; e[3] = 'i'; e[4] = '#';
		output();
		flag = 0; input(); input1();
		ch = a[++i1];
	}
	else {
		printf("error\n");
		j = 0;
		while (a[j] != '#')
			printf("%c", a[j++]);
		printf("非法字符!\n");
		return(0);
	}
	return(1);
}
void input()
{
	int j = 0;
	for (; j <= i1 - flag; j++)
		printf("%c", b[j]);                    /*输出分析串*/
	printf("\t\t\t");
	printf("%c\t\t\t", ch);                  /*输出分析字符*/
}

void input1()
{
	int j;
	for (j = i1 + 1 - flag; j < n1; j++)
		printf("%c", a[j]);                     /*输出剩余字符*/
	printf("\n");
}
void output() {                              /*推导式计算*/
	int m, k, j, q;
	int i = 0;
	m = 0; k = 0; q = 0;
	i = n;
	d[n] = '='; d[n + 1] = '>'; d[n + 2] = '#'; n = n + 2; i = n;
	i = i - 2;
	while (d[i] != '>'&&i != 0) i = i - 1;
	i = i + 1;
	while (d[i] != e[0]) i = i + 1;
	q = i;
	m = q; k = q;
	while (d[m] != '>')  m = m - 1;
	m = m + 1;
	while (m != q) {
		d[n] = d[m]; m = m + 1; n = n + 1;
	}
	d[n] = '#';
	for (j = 3; e[j] != '#'; j++) {
		d[n] = e[j];
		n = n + 1;
	}
	k = k + 1;
	while (d[k] != '=') {
		d[n] = d[k]; n = n + 1; k = k + 1;
	}
	d[n] = '#';
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/267931.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【并发编程篇】定义最大线程的方法

文章目录 &#x1f354;省流&#x1f3f3;️‍&#x1f308;前言&#x1f6f8;CPU密集型&#x1f339;代码实现 &#x1f6f8;IO密集型 &#x1f354;省流 池的最大大小如何去设置 使用CPU密集型和IO密集型这2种方法 &#x1f3f3;️‍&#x1f308;前言 上一篇文章我们讲解…

音视频的编码格式与封装格式

音视频的编码格式与封装格式是两个不同的概念&#xff0c;视频封装格式常见的有&#xff1a;mp4&#xff0c;rmvb&#xff0c;avi&#xff0c;mkv&#xff0c;mov&#xff0c;mpg&#xff0c;vob&#xff0c;3gp&#xff0c;asf&#xff0c;rmvb&#xff0c;wmv&#xff0c;div…

ARM GIC (五)gicv3架构-LPI

在gicv3中,引入了一种新的中断类型。message based interrupts,消息中断。 一、消息中断 外设,不在通过专用中断线,向gic发送中断,而是写gic的寄存器,来发送中断。 这样的一个好处是,可以减少中断线的个数。 为了支持消息中断,gicv3,增加了LPI,来支持消息中断。并且…

分布式事务TCC补偿机制

文章目录 概述工作流程优缺点优点&#xff1a;缺点&#xff1a; 总结Java 示例代码 概述 TCC&#xff08;Try-Confirm-Cancel&#xff09;补偿机制是一种事务处理模式&#xff0c;用于确保分布式系统中的操作成功完成或在失败时进行补偿。TCC将一个事务拆分为三个阶段&#xf…

vue3老项目如何引入vite

vue3老项目如何引入vite 安装 npm install vite vitejs/plugin-vue --save-dev Vite官方中文文档修改package.json文件 在 npm scripts 中使用 vite 执行文件 "scripts": {"serve": "vite","build": "vite build","pr…

Vue 封装echarts柱状图(Bar)组件

目的&#xff1a;减少重复代码&#xff0c;便于维护 显示效果 组件代码 <template><div class"ldw-data-content-box"><div class"ldw-chilren-box"><div class"title" v-if"title">{{ title }}</div>…

python使用opencv提取视频中的每一帧、最后一帧,并存储成图片

提取视频每一帧存储图片 最近在搞视频检测问题&#xff0c;在用到将视频分帧保存为图片时&#xff0c;图片可以保存&#xff0c;但是会出现(-215:Assertion failed) !_img.empty() in function cv::imwrite问题而不能正常运行&#xff0c;在检查代码、检查路径等措施均无果后&…

探索应用程序的指路明灯:Route 和 Router 入门指南(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

GEE学习笔记

掩膜 ​ 在遥感图像处理中&#xff0c;"掩膜"是指一种用于隐藏或保留图像特定部分的技术。掩膜通常是一个二进制图像&#xff0c;其中的像素值为0或1&#xff0c;分别表示遮蔽或保留。 ​ 在去除云的情境中&#xff0c;掩膜通常用于隐藏图像中被云覆盖的部分&#…

【c++】入门1

c关键字 命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c;以避免命名冲突或名字污染&#xff…

《工作、消费主义和新穷人》读书笔记

总结 全书前半段描写的是工作伦理论被推行的原因 &#xff0c;后半段探讨了福利国家和资本国家对于穷人的态度&#xff0c;最后描写了全球化下工作伦理从生产型社会过度到消费型社会的概念演变&#xff0c;和大众对于新穷人态度的转变。 启示 对于我的启示在前几章是最多的&…

SpringMVC:整合 SSM 中篇

文章目录 SpringMVC - 04整合 SSM 中篇一、优化二、总结三、说明注意&#xff1a; SpringMVC - 04 整合 SSM 中篇 一、优化 在 spring-dao.xml 中配置 dao 接口扫描&#xff0c;可以动态地实现 dao 接口注入到 Spring 容器中。 优化前&#xff1a;手动创建 SqlSessionTempl…

2022第十二届PostgreSQL中国技术大会-核心PPT资料下载

一、峰会简介 本次大会以“突破•进化•共赢 —— 安全可靠&#xff0c;共建与机遇”为主题&#xff0c;助力中国数据库基础软件可掌控、可研究、可发展、可生产&#xff0c;并推动数据库生态的繁荣与发展。大会为数据库从业者、数据库相关企业、数据库行业及整个IT产业带来崭…

软件测试5未来大发展路线,测试工程师发展偏向

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、软件测试的五大…

springCould中的consul-从小白开始【4】

目录 1.consul介绍 ❤️❤️❤️ 2.安装 ❤️❤️❤️ 3.创建8006模块 ❤️❤️❤️ 4.创建80模块❤️❤️❤️ 1.consul介绍 ❤️❤️❤️ Consul 是一种用于服务发现、配置和分布式一致性的开源软件。它由HashiCorp开发和维护&#xff0c;可用于帮助构建和管理现代化的分布…

ARM学习(24)Can的高阶认识和错误处理

笔者来聊一下CAN协议帧的认识和错误处理。 1、CAN协议帧认识 CAN 差分信号&#xff0c;是经过CAN收发器转成差分信号的&#xff0c;CAN RX和TX是逻辑电平。CAN的基础知识&#xff0c;可参考笔者这边文章&#xff1a;ARM学习&#xff08;21&#xff09;STM32 外设Can的认识与驱…

零基础快速上手HarmonyOS ArkTS开发2---ArkTS开发实践

ArkTS开发实践&#xff1a; 接着上一次零基础快速上手HarmonyOS ArkTS开发1---运行Hello World、ArkTS开发语言介绍继续&#xff0c; 在上一次对于ArkTS的基础知识进行了学习&#xff0c;依照官方的课程计划&#xff0c;还有两个具体的小案例需要来实践实践&#xff1a; 实践出…

蓝桥杯 1223 第 2 场 小白入门赛

蓝桥小课堂-平方和 模拟 1 2 2 2 3 2 ⋯ n 2 n ⋅ ( n 1 ) ⋅ ( 2 n 1 ) 6 1^22^23^2\cdotsn^2\dfrac{n\;\cdot\;(n 1)\;\cdot\;(2n1)}{6} 122232⋯n26n⋅(n1)⋅(2n1)​。 write(n * (n 1) * (n * 2 1) / 6);房顶漏水啦 m a x ( 最大的行 − 最小的行 , 最大的列 −…

Jmeter、postman、python 三大主流技术如何操作数据库?

1、前言 只要是做测试工作的&#xff0c;必然会接触到数据库&#xff0c;数据库在工作中的主要应用场景包括但不限于以下&#xff1a; 功能测试中&#xff0c;涉及数据展示功能&#xff0c;需查库校验数据正确及完整性&#xff1b;例如商品搜索功能 自动化测试或性能测试中&a…

CentOS 7 设置网络

CentOS 7 设置网络 正常情况 ①登陆进去之后使用下面的命令修改文件 echo ONBOOTyes >> /etc/sysconfig/network-scripts/ifcfg-ens33②如果是虚拟机重启后使用如下命令进行查看IP地址 ip addr注&#xff1a;到这里如果显示有两部分&#xff0c;则代表网络设置成功&a…