老师要求做的一个课设,但是。网上很多都不是递归下降的。
在理解编译原理基本思想的基础上,选择一个自己熟悉的程序设计语言,完成编译程序的设计和实现过程。
编译程序的设计可以采用自顶向下和自底向上两种不同的方法。由于许多高级语言(如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 ()下面直接给代码(代码有点长,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存在语法错误,无法生成四元式"<