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

一. 实验目的

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
利用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();
}


结果:
(编译原理)实验三 递归下降分析法_第1张图片
(编译原理)实验三 递归下降分析法_第2张图片

你可能感兴趣的:(编译原理,c语言)