【编译原理】实验二:实现递归下降分析器

本文详细介绍了一种基于高级语言实现的递归下降分析器,用于解析特定文法的符号串。通过具体实例,展示了如何利用栈数据结构进行自顶向下的语法分析,包括输入串的读取、符号栈的操作、递归过程的实现及调试技巧。

实验内容

用高级语言实现课本3.2文法的递归下降分析程序。
课本3.2文法要求:
可使用书上提供的输入串i1*(i2+i3),也可以是自己定义的其他符号串;输出栈中所有内容,并给出分析结果。

开发环境

windows 10
visual studio 2019

数据结构

1 符号栈

栈是一种有存取限制的线性表,它只允许在一端进行插入或删除操作。遵循“先进先出”原则。
栈示意图
递归下降分析法是一种自顶向下的分析方法,文法的每个非终结符对应一个递归过程(函数),可用栈来表示分析过程。

2 分析过程

序号 符号栈 待分析字符 表达式
0 # i*(i+i)#
1 #E i*(i+i)# E→TE’
2 #E’T i*(i+i)# T→FT’
3 #E’T’F i*(i+i)# F→i
4 #E’T’ i*(i+i)# T’→*FT’
5 #E’T’F i*(i+i)# F→(E)
6 #E’T’E i*(i+i)# E→TE’
7 #E’T’E’T i*(i+i)# T→FT’
8 #E’T’E’T’F i*(i+i)# F→i
9 #E’T’E’T’ i*(i+i)# T’→ε
10 #E’T’E’ i*(i+i)# E’→+TE’
11 #E’T’E’T i*(i+i)# T→FT’
12 #E’T’E’T’F i*(i+i)# F→i
13 #E’T’E’T’ i*(i+i)# T’→ε
14 #E’T’E’ i*(i+i)# E’→ε
15 #E’T’ i*(i+i)# T’→ε
16 #E’ i*(i+i)# E’→ε
17 #

 i*(i+i)分析栈示意图

3 数组

1、分析串数组char token[token_size]:存放待分析串。
2、符号栈char stack[10] = {’#’}:存放符号栈内容,初始压入‘#’。

实验步骤

分析与设计

教材上的例题已然分析地较详细:
1、 已消除左递归。
2、 无回溯。
我们直接进行递归下降分析器的构造。
递归下降分析法大致流程图

编程

1 全局变量

① token_len:int类型变量,存放待分析串的长度。
② step:int类型变量,记录当前分析步数。

2 栈

① char stack[10] = {’#’}:char类型数组,存放符号栈内容,初始压入‘#’。
② stack_top:int类型变量,为符号栈的栈顶指针。

3 数组

token[token_size]:cha类型数组,存放待分析串。

4 函数

① 非终结符表达式:
void E();
void E1();
void T();
void T1();
void F();
② 打印函数:void print()。

5 伪代码

见《编译原理教程(第四版)》P52-53

void match(token t){
	if (lookahead == t)
			lookahead = nexttoken;
	else
			error();
}

void E(){
	T();
	E();
}

void E'(){
	if (lookahead == '+'){
		match('+');
		T();
		E'();
	}
}

void T(){
	F();
	T'();
}

void T'(){
	if (lookahead == '*'){
		match('*');
		F();
		T'();
	}
}

void F(){
	if (lookahead == 'i')
		match('i');
	else if (lookahead == '('){
		match('(');
		E();
		if (lookahead == ')')
			match(')');
		else
			error();
	}
	else
		error();
}

运行与调试

根据调试情况进行相应的代码修改。

运行结果

i*(i+i)为合法字符串
++为非法字符串

所遇问题与解决方案

1 E’和T’的压栈

因为E’不属于一个字符,在考虑存放的时候本来是准备实现字符串数组的,问题有点多,所以就直接按照’E’和’\’’两个字符来存储E’了,T’同理。

2 栈的实现

心得体会

对递归下降分析器的构造有了更深的理解,也更熟练地掌握了栈的实现。

实验代码

1 主函数main()

int main(void){
   
   
	printf("请输入字符串(以#结束):");		//输入待分析字符串
	while (token[lookahead] != '#'){
   
   		//如果没有按下#结束
		char scan_char;						//扫描字符
		do{
   
   									//若没有扫描到结束符#,就继续扫描
			scanf_s("%c", &scan_char,1);
			token[token_len
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

社恐患者

赚钱不易呜呜呜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值