概述
目录
- 内容:
- 示例:
- 具体实现:
- C++代码:
- 运行结果:
内容:
实现以下语法的递归下降分析:
示例:
对于以下代码给出其递归下降语法分析过程:
{
i=2;
while(i<=100)
{
sum=sum+i;
i=i+2;
}
}
具体实现:
- 首先对上下文无关文法进行检查,消除左递归和左公共因子,从逻辑上检测避免死循环和低效率处理。
- 采用每个产生式的左边的文法符号对应一个函数或过程的形式,编写程序实现一个递归下降分析器。
- 语法分析是在词法分析的基础上进行的(关于词法分析的实现,具体参见我的上篇博客->【编译原理与技术】词法分析器(C++实现))。
C++代码:
#include<cstdio>
#include<cstring>
#include<ctype.h>
#include<iostream>
using namespace std;
char prog[1000],ch,ch1,token[1000],filename[30];
int p=0,sym=0,n,line=1;
FILE *fpin;
const char *keyword[22]={"if","else","while","do","main","int","float","for"
"double","return","const","void","continue","break","char",
"signed","enum","long","switch","case","auto","unsigned"};
char keywordtable[20][20]; //存放保留字
char digittable[20][20]; //存放数字
char otherchartable[20][20]; //存放其他字符
char idtable[20][20]; //存放标识符
char notetable[20][20]; //存放注释
char finaltable[100][20]; //存放终结符
int finaltableint[100];
char word[20];
void initialize();
void alpha();
void digit();
void error();
void otherchar();
void note();
void program();
void block();
void stmts();
void stmt();
void Bool();
void expr();
void expr1();
void term();
void term1();
void factor();
void YufaBegin();
void CifaBegin();
void GetToken();
void match(string str);
int digit_num=0,keyword_num=0,otherchar_num=0,id_num=0,note_num=0;
int final_num=0,finalnum=0;
int flag_error=0; //0表示没有错误,1表示有错误
int flagerror=0;
int main()
{
cout<<"请输入源文件名:";
while(1)
{
cin>>filename;
if((fpin=fopen(filename,"r"))!=NULL)//只读
{
break;
}
else
cout<<"文件输入错误!请输入源文件名:";
}
//将文件内容存储到prog中
do
{
ch=fgetc(fpin);
prog[p++]=ch;
}while(ch!=EOF);
//调用词法分析部分
printf("-----------------n");
printf("词法分析结果如下:n");
rewind(fpin);
ch=fgetc(fpin);
CifaBegin();
//调用语法分析部分
rewind(fpin);
ch=fgetc(fpin);
initialize();
YufaBegin();
return 0;
}
void YufaBegin(){
p=0;
while(1)
{
ch=prog[p++];
if(ch==EOF) break;
if(isalpha(ch)||ch=='_')
//a-z或A-Z时返回非零值(不一定是1),否则返回零
{
alpha();
initialize();
}
else if(isdigit(ch)) //用来判断字符lookahead是否为数字
{
digit();
initialize();
}
else if(ch=='t'||ch==' '||ch=='n')
{
continue;
}
else if(ch=='/')
{
ch=prog[p++];
if(ch=='*'||ch=='/')
{
note();
initialize();
}
else
{
p--; //把一个字符退回到输入流中
//lookahead是写入的字符,stdin是文件流指针
strcpy(finaltable[final_num],"/"); //将"/"放到终结符号表中
strcpy(otherchartable[otherchar_num++],"/"); //将"/"放到其他符号表中
finaltableint[final_num++]=2; //"/"的序号是2
initialize();
}
}
/*else if(ch=='#'){
break;
}*/
else
{
otherchar();
initialize();
}
}
if(flag_error==0)
{
finaltableint[final_num]='