(编译原理)实验三 递归下降分析法

一. 实验目的

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

二. 实验要求

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。
例如:
输入begin a:=9;x:=23;b:=a+x end #
输出success
输入x:=a+b
c end #
输出error

三. 实验内容

用递归下降法编写一个语法分析程序,使之与词法分析器结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。(注意,需要改写文法,消除左递归等)
1.对于每一条语法的推导都有一个函数实现
2.有较为详细的错误提示(如:第几个字符出现错误,希望出现XX字符,结果出现了XX字符)
3.特别注意:什么时候调用其他的解析函数,什么时候报错,什么时候利用First集合和Fllow集合进行预测,以及左右括号匹配的地方

代码实现:

#include "string.h"
 
char prog[80],token[8];
int syn,p,m,n,sum=0;
char ch;
char *rwtab[6]= {"begin","if","then","while","do","end"};
void scaner() {
	m=0;
	for(n=0; n<8; n++) token[n]=NULL;
	ch=prog[p++];
	while(ch==' ') ch=prog[p++];
	if((ch>='a' && ch<='z') ||(ch>='A' && ch<='Z')) {
		while((ch>='a' && ch<='z') ||(ch>='A' && ch<='Z')||(ch>='0' && ch<='9')) {
			token[m++]=ch;
			ch=prog[p++];
		}
		token[m++]='\0';
		syn=10;
		p=p-1;      //回退一个字符
		for(n=0; n<6; n++) {
			if(strcmp(token,rwtab[n])==0) {
				syn=n+1;
				break;
			}
		}
	} else if(ch>='0' && ch<='9') {
		sum=0;
		while(ch>='0' && ch<='9') {
			sum=sum*10+ch-'0';
			ch=prog[p++];
		}
		p=p-1;
		syn=11;
	} else {
		switch(ch) {
			case '<':
				m=0;
				token[m++]=ch;
				ch=prog[p];
				if(ch=='>') {
					syn=21;
					token[m++]=ch;
				} else if(ch=='=') {
					syn=22;
					token[m++]=ch;
				} else {
					syn=20;
					p=p-1;
				}
				p=p+1;
				token[m]='\0';
				break;
			case '>':
				m=0;
				token[m++]=ch;
				ch=prog[p++];
				if(ch=='=') {
					syn=24;
					token[m++]=ch;
				} else {
					syn=23;
					p=p-1;
				}
				break;
			case ':':
				m=0;
				token[m++]=ch;
				ch=prog[p++];
				if(ch=='=') {
					syn=18;
					token[m++]=ch;
				} else {
					syn=17;
					p=p-1;
				}
				break;
			case '+':
				syn=13;
				token[0]=ch;
				break;
			case '-':
				syn=14;
				token[0]=ch;
				break;
			case '*':
				syn=15;
				token[0]=ch;
				break;
			case '/':
				syn=16;
				token[0]=ch;
				break;
			case ';':
				syn=26;
				token[0]=ch;
				break;
			case '(':
				syn=27;
				token[0]=ch;
				break;
			case ')':
				syn=28;
				token[0]=ch;
				break;
			case '=':
				syn=25;
				token[0]=ch;
				break;
			case '#':
				syn=0;
				token[0]=ch;
				break;
			default:
				syn=-1;
		}
	}
}


#include "head.h"
#include "stdio.h"
#include "conio.h"
//#include "stdlib.h"

void lrparser();
void yucu();
void statement();
void expression();
void term();
void factor();
int kk=0;
 
void lrparser() {
	if (syn==1) { //begin
		scaner();
		yucu();
		if (syn==6) { //end
			scaner();
			if (syn==0 && kk==0) printf("success \n");
		} else {
			if(kk!=1) printf("error,lose 'end' ! \n");
			kk=1;
		}
	} else {
		printf("error,lose 'begin' ! \n");
		kk=1;
	}
	return;
}
 
void yucu() {
	statement();
	while(syn==26) { 
		scaner();
		statement();
	}
	return;
}
 
void statement() {
	if (syn==10) { //为标识符
		scaner();
		if (syn==18) { //为 :=
			scaner();
			expression();
		} else {
			printf("error!");
			kk=1;
		}
	} else {
		printf("error!");
		kk=1;
	}
	return;
}
 
 
void expression() {
	term();
	while(syn==13 || syn==14) {
		scaner();
		term();
	}
	return;
}
 
 
void term() {
	factor();
	while(syn==15 || syn==16) {
		scaner();
		factor();
	}
	return;
}
 
 
void factor() {
	if(syn==10 || syn==11)scaner(); //为标识符或整常数时,读下一个单词符号
	else if(syn==27) {
		scaner();
		expression();
		if(syn==28)scaner();
		else {
			printf(" ')' 错误\n");
			kk=1;
		}
	} else {
		printf("表达式错误\n");
		kk=1;
	}
	return;
}
 
 
void main() {
	p=0;   //int i;
	printf("********************语法分析程序***************\n");
	printf("请输入源程序:\n");
	do {
		scanf("%c",&ch);
		prog[p++]=ch;
	} while(ch!='#');
	p=0;
	scaner();
	lrparser();
	printf("语法分析结束!\n");
	getch();
}


结果:
在这里插入图片描述
在这里插入图片描述

实验2 语法分析 一、 实验目的 编制一个递归下降分析程序实现词法分析程序提供单词序列语法检查和结构分析。 二、 实验内容 利用C语言编制递归下降分析程序,并对简单语言进行语法分析。 1、 待分析的简单语言的语法 用扩充的BNF表示如下: (1)::=beginend (2)::={;} (3)::= (4)::=ID:= (5)::={+|-} (6)::={*|/} (7)::=ID| NUM|() 2、实验要求说明 输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。 三、 结果验证 1. 输入:begin_a:=9;_x:=2*3;_b:=a+x_end# 输出:success! 2. 分别验证其他错误(至少2个) 四、 语法分析程序的源程序代码 #include #include #include char prog[80],token[8]; char ch; int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针,m是token的指针 char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner(); void factor(); void term(); void expression(); void statement(); #include #include #include char prog[80],token[8]; char ch; int syn,p,m=0,n,sum=0; //p是缓冲区prog的指针,m是token的指针 char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner() { 同实验一代码 } void factor() { …完成函数代码 } void term() { ……完成函数代码 } void expression() { ……完成函数代码 } void statement() {//cout<<"调用statement,syn="<<syn<<endl; if(判断语句) {scaner(); if(syn==18) {//cout<<"syn=18"<<endl; scaner(); expression(); } else{cout<<"缺:=错误!"<<endl;kk=1;} } else {cout<<"error!"<<endl;kk=1;} return; } void yucu() {…..完成函数代码 } //return; } void lrparser() {//cout<<"调用Irparser"<<endl; if(syn==1) {scaner(); yucu(); if(syn==6){scaner(); if(syn==0&&(kk==0)) cout<<"success!"<<endl; } else {if(kk!=1) cout<<"缺end错误!"<<endl;kk=1;} } else{cout<<"缺begin错误!"<<endl;kk=1;} //return; } void main() {p=0; cout<>ch; 执行语句3; }while(ch!='#'); p=0; scaner(); lrparser(); //cout<<syn<<','<<kk<<endl; }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值