编译原理 递归下降语法分析程序

老师要求做的一个课设,但是。网上很多都不是递归下降的。

在理解编译原理基本思想的基础上,选择一个自己熟悉的程序设计语言,完成编译程序的设计和实现过程。

编译程序的设计可以采用自顶向下和自底向上两种不同的方法。由于许多高级语言(如PASCAL,C)中的语法成分都是递归定义的,所以本实验要求学生采用递归下降分析技术,这是一种自顶向下的的编译方法,其基本思想是对语言的每个(或若干个)语法成分编制一个处理子程序,从处理<程序>这个语法成分的子程序开始,在分析过程中调用一系列过程或函数,对源程序进行语法和语义分析,直到整个源程序处理完毕为止。

本上机实习是为C语言(子集)设计一个编译程序,完成词法分析、语法分析、语义分析等功能,并生成某种机器上的目标代码(汇编语言)或中间代码(四元式)。

这是老师的要求

2、C语言小子集的文法规则:

<程序>::=main(){<分程序>}

       <分程序>::=<变量说明部分>;<语句部分>

       <变量说明部分>::=<变量说明><标识符表>

<变量说明>::=int

<标识符表>::=<标识符表>,<标识符>

<标识符表>::=<标识符>

       <标识符>::=<字母>

<标识符>::=<标识符><字母>

<标识符>::=<标识符><数字>

       <语句部分>::=<语句部分><语句>;|<语句>;

<语句>::=<赋值语句>|<条件语句>|<循环语句>|

<赋值语句>::=<标识符>=<表达式>

       <条件>::=<表达式><关系运算符><表达式>

       <表达式>::=<项>|<表达式><加法运算符><项>

<项>::=<因子>|<项><乘法运算符><因子>

<因子>::=<标识符>|<常量>|(<表达式>)

<常量>::=<无符号整数>

<无符号整数>::=<数字序列>

<数字序列>::=<数字序列><数字>

<数字序列>::=<数字>

<加法运算符>::=+|-

<乘法运算符>::=*|/

<关系运算符>::=<|>|!=|>=|<=|==

<复合语句>::={<语句部分>}

<语句1>::=<语句>|<复合语句>

<条件语句>::=if(<条件>)<语句1>else<语句1>

<循环语句>::=while(<条件>)do<语句1>

<字母>::=a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z

<数字>::=0|1|2|3|4|5|6|7|8|9

输入源程序样本:(这只是一个例子,调试时可以任意修改或换其它程序)

main ()
{ int a,x,b,y,max;
a=10;  b=12;
while  (a<0) 
{ b=a+b*a;
a=a-1
};
x=a+b;  y=b+b;
if  (x>y)  max=x;
else max=y;
}

下面直接给代码(代码有点长,700行左右)

#include
#include
#include
#include
#include
#include
#include
#include
#include 
#include

using namespace std;
char const *keyword[7] = { "if", "else", "for", "while", "do", "int", "main"}; //关键字

class Word           //单词表类 
{ 
	public:
	char value[20];//单词自身的值 
	int type;//单词的种别(10标识符,20常数,30关键字,4-运算符(加法运算符为41,乘法为42,关系运算符43),50界符) 
	int line;//行号
};

class Genq  //四元式 
{
	public:
	string op;  //算符 
	string data1;//操作数1 
	string data2;//操作数2 
	string res; //结果 
};
 
FILE *fin,*fout;//文件流 
int line=1;	//单词所在行数 
char buff[10];//存放单词的数组 
int flag=0;//词法分析判断是否已经从文件流中获取字符 
Word new_w;
Genq four[100];//用数组表示类对象四元式 

int f_num=0;//四元式个数
int e;//错误次数 
char ch;//字符流中获取的字符 
int flag1,flag2=0;
string ys[100];//已经声明的变量 
int y_num=0;//已经声明变量的个数 
string op;  //算符 
string str1;//操作数1 
string str2;//操作数2 
string result; //结果
int f=0; //表达式中运算符的个数 
int aaa;  
int tj_x;//记录while和if条件的四元式的序号 
string a[200];
string a2;
string a3;
int a_num=1;

void P();//程序
int A(); //(){分程序}
void B();//分程序
void C();//变量说明部分
int F();//标识符表
int F1();//标识符
void D();//语句部分
int D1();//子语句部分
int H();//语句
int I();//赋值语句
int Q();//表达式
int X();//项 
int X1();//子项
int Q1(); //子表达式
int Y();//因子 
int J();//条件语句 
void K();//循环语句
int H1();//语句1
int TJ();//条件

void makeFour(string op,string d1,string d2,string r)//构造四元式 
{	
	four[f_num].op=op;
	four[f_num].data1=d1;
	four[f_num].data2=d2;
	four[f_num].res=r;
	f_num++;
}
void printFour()//输出四元式 
{
	ofstream out("ygro.txt");
    int i;
    for(i=0;iy_num)  
	{
		cout<<"第 "<='a'&&ch<='z')//识别字母开头的变量或者单词; 
	{
		for(i=0;i<10;i++)
		{
			buff[i]=NULL;
		}i=0;
	
		do{
			buff[i++]=ch;  //吧字符流中的字符放到buff中 
			ch=getc(fin);
			flag=1;
		}while((ch>='a' && ch<='z') || (ch>='0' && ch<='9')); 
		strcpy(new_w.value,buff);//把buff的值放到单词表 
		new_w.line=line;//行数 
		int n;
		for(n=0;n<7;n++)
		{
			if(strcmp(new_w.value,keyword[n])==0)//判断是不是关键字 
			break;
		}
		if(n<7)//是关键字 
		{
			new_w.type=30;//关键字类型为03 
		}else{
			new_w.type=10;//标识符类型为01 
		}
	return 0;
	}
	else if(ch>='0' && ch<='9')
	{
		for(i=0;i<10;i++)
		{
			buff[i]=NULL;
		}i=0;
		do{
			buff[i++]=ch;
			ch=getc(fin);
			flag=1;	
		}while(ch>='0' && ch<='9');
		strcpy(new_w.value,buff);
		new_w.type=20;//数字类型为02 
		new_w.line=line;
		
		//***************************
	//	cout<'||ch=='!')
	{	
		for(i=0;i<10;i++)
		{
			buff[i]=NULL;
		}
		i=0;
		buff[i++]=ch;
		ch=getc(fin);
		flag=1;	
		if(ch=='=')
		{
			buff[i++]=ch;
			ch=getc(fin);
			flag=1;	
		}
		strcpy(new_w.value,buff);
		new_w.type=43;	//关系运算符 
		new_w.line=line;
		
		//**************************
	//	cout<>result;
    	makeFour(op,str1,str2,result);
    	//修改while跳转到的序号 
    	stringstream ws;
    	ws<>four[tj_x].res;
		return 0; 
	 }
	 else if(strcmp(new_w.value,";")==0)
	 {
		return 0;
	 }
	 return 0;
}
int I()//赋值语句
{
	if(strcmp(new_w.value,"="))
	{error("缺乏'='");}
	getWord();
	str1=new_w.value;//str1=a  a+b*a中的a 
	//strcpy(b[b_num++].bds,new_w.value); 
	Q();//表达式
	return 0;
}
int Q()//表达式
{
	X();//项
	Q1();//子表达式 
	return 0;
} 
int X()//项 
{
	Y();//因子 
	X1();//子项 
	return 0;
}
int X1()//子项 
{
	flag1=0;
	if(strcmp(new_w.value,";")==0 || new_w.type==43||strcmp(new_w.value,")")==0)//当下一个字符为;或者关系运算符时,表达式结束 
	{
		return 0;
	}
	else if(new_w.type!=41&&new_w.type!=42&&new_w.type!=43&&strcmp(new_w.value,",")!=0 )
	{
		flag1=1;
		error("缺少';'");
		return 0;
	}
	if(new_w.type==41||new_w.type==42)//加法.乘法运算符 
	{
		
		f++;//运算符加一 
		if(f>1)
		{
			str1=str2;
			result="temp"+f;
		}
		op=new_w.value;
	}
	getWord();
	//strcpy(b[b_num++].bds,new_w.value);
	Y();
	return 0;
}
int Q1() //子表达式 
{
	if(strcmp(new_w.value,";")==0 || new_w.type==43||strcmp(new_w.value,")")==0)//当下一个字符为;或者关系运算符时,表达式结束
	{
		return 0;
	} 
	else if(new_w.type!=41&&new_w.type!=42&&new_w.type!=43&&strcmp(new_w.value,",")!=0)
	{
		if(flag1==0){
			error("缺少';'");
		}
		return 0;
	}
	if(new_w.type==41||new_w.type==42)//加法.乘法运算符 
	{
		
		f++;//运算符加一 
		if(f>1)
		{
			str1=str2;
			result="temp";
		}
		op=new_w.value;
	}
	getWord();
	//strcpy(b[b_num++].bds,new_w.value);
	X();
	return 0;
}
int Y()//因子 
{
	if(new_w.type!=10 && new_w.type!=20 && strcmp(new_w.value,"("))
	{
		error("表达式错误!!!!");
		return 0;
	}
	if(new_w.type==10||new_w.type== 20)//标识符和数字 
	{	
		if(op.compare("+")==0 || op.compare("-")==0 || op.compare("*")==0 || op.compare("/")==0)
		{
			str2=new_w.value;
			if(result=="temp")
			{
				makeFour(op,str1,str2,result);
				str2="temp";
				result="b";
				str1="a";//***************
				op="+";//*********************
			}
		}
		if(new_w.type==10)
		{
			ise(new_w.value);
		}
		getWord();//a-1 zhong de - 
	//	strcpy(b[b_num++].bds,new_w.value);
		a[a_num++]=new_w.value;

		return 0;
	}
	else if(strcmp(new_w.value,"(")==0)
	{
		getWord();
		Q();
		if(strcmp(new_w.value,")")==0)
		{
			return 0;
		}
	}
	return 0;
}
int J()//条件语句 
{
	if(strcmp(new_w.value,"("))
	{
		error("缺少'('");
	 }
	 getWord();
	 str1=new_w.value; 
	 TJ();//条件
	 makeFour(op,str1,str2,result);
	 if(strcmp(new_w.value,")"))
	 {
	 	error("缺少')'");
	 }
	 //使四元式为空 
	  op="";
	  str1="";
	  str2="";
	  result="";
	  getWord();
	  H1();//语句一 
	  if(strcmp(new_w.value,";")==0)
	  {
	   		getWord();
	  }
	  stringstream if_s;//
      if_s<>four[tj_x].res;//
      
      tj_x=f_num;
      op="go";
      str1="";
	  str2="";
	  result="";
	  makeFour(op,str1,str2,result);//满足if条件之后 ,跳过else语句 
	  
	  if(strcmp(new_w.value,"else"))
	  {
	  	error("缺少'else'"); 
	  	H1();//语句一
	  }
	  else
	  {
	  	getWord();
	  	H1();//语句一
	  } 
	  stringstream else_s;//
      else_s<>four[tj_x].res;//
	return 0; 
}
void K()//循环语句
{
	if(strcmp(new_w.value,"("))
	{
		error("缺少'('");
	}
	getWord();//(a>0)中的a 
	str1=new_w.value;
	TJ();//条件 
	makeFour(op,str1,str2,result);
	if(strcmp(new_w.value,")"))
	{
		error("缺少')'");
	}
	getWord();
	
	if(strcmp(new_w.value,"do"))
	{
		error("缺少'do'");
		H1();//语句1 
	}
	else
	{
		getWord();
		H1();//语句1

	}	
}
int H1()//语句1 
{
	if(strcmp(new_w.value,"{")==0) 
	{
		getWord();
		
		D();//语句部分
		return 0; 
	}
	else
	{
		H();//语句 
		return 0;
	}
}
int TJ()//条件
{
	//进Q之前时(a>0)中的a 
	Q();
	if(strcmp(new_w.value,">")==0)
	op="<=";
	if(strcmp(new_w.value,"<")==0)
	op=">=";
	if(strcmp(new_w.value,">=")==0)
	op="<";
	if(strcmp(new_w.value,"<=")==0)
	op=">";
	if(strcmp(new_w.value,"==")==0)
	op="!=";
	if(strcmp(new_w.value,"!=")==0)
	op="==";
	if(new_w.type!=43)
	{
		error("缺少关系运算符"); 
	}
	getWord();
	str2=new_w.value;
	tj_x=f_num;//记录条件的四元式符号,方便修改他的res 
	Q();
	return 0;
} 
int main()
{
	char Infile[100];
	
	//对文件的读出和写入借用了网上的知识 
	printf("要测试的小程序的名字(.txt):");
    scanf("%s", Infile);
    if ((fin = fopen(Infile, "r")) == NULL)
    {
        printf("\n 读入文件错误 \n");
        return (1);
    } 
   
	P();
	if(e==0)
	{
		printFour();
	}
	else
	{
		cout<<"\n存在语法错误,无法生成四元式"<


你可能感兴趣的:(编译原理 递归下降语法分析程序)