a.选择测试代码,begin a:=9;x:=2*3;b:=a+xend#,即词法分析器的输入,所示。
b.统计测试程序包含的单词符号,假定关键字、界符、运算符都是一符一种,设计单词符号对应的种别码,如表1
c.词法分析得到的种别码串为1,10,18,11,26,10,18,11,15,11,26,10,18,10,13,10,6,0,此为语法分析的输入。
源程序:
//递归下降语法分析程序
#include<stdio.h>
#include<stdlib.h>
//#define debug
//定义全局变量
char *str; //词法分析所得的单词符号串
int p_token=0; //字符串指针
int syn; //种别码数值(十进制)
int kk = 0; //错误标志
//函数声明
int scaner(); //读取下一单词(种别码)
void lrparse(); //递归下降分析函数
void statements(); //语句串分析函数
void statement(); //语句分析函数
void expression(); //表达式分析函数
void term(); //项分析函数
void factor(); //因子分析函数
int main()
{
FILE *p; //词法分析器输出的单词符号串的文件指针
int filesize; //单词符号串长度
char *fname = "a.txt"; //单词符号串所在的文件
//打开单词符号串所在的文件
p = fopen(fname,"rb"); //p = fopen("D:\\a.txt","rb");
if(p == NULL)
{
printf("打开文件%s错误\n",fname);
exit(1);//exit(-1);
}
fseek(p,0,SEEK_END); //指向文件末尾
filesize = ftell(p); //获取文件长度
str = (char*)malloc(filesize+1);//动态内存分配
rewind(p);
fread(str,sizeof(char),filesize,p);
str[filesize] = '\0'; //字符串结束标志
fclose(p);
//输出文件中的代码
printf("a.txt文件中的单词符号串为:\n");
puts(str);
#ifdef debug
printf("\n%d\n",scaner());
printf("%d\n",scaner());
printf("%d\n",scaner());
printf("%d\n",scaner());
printf("%d\n",scaner());
#endif
lrparse();
return 0;
}
/* *****************************************/
/* 函数定义 */
/* *****************************************/
int scaner()
{
char syns[7]; //种别码字符串
int i = 0; //数组下标
char ch = str[p_token++];//等价于char ch = str[p_token];p_token++;
//去除空格
while(' '==ch || '\r'==ch || '\n'==ch || '\t'==ch) //文件回车='\r\n',windows
{
ch = str[p_token++];
}
syns[i++] = ch; //空格后的第一个非空格字符
ch = str[p_token++];
while(' '!=ch && '\r'!=ch && '\n'!=ch && '\t'!=ch && '\0'!=ch) //'\0'!=ch,单词符号串结束标志
{
syns[i++] = ch;
ch = str[p_token++];
}
//printf("%d\n",atoi(syns));
return atoi(syns);
}
//递归下降分析函数
void lrparse()
{
syn = scaner();
if(syn == 1) //begin
{
syn = scaner();
statements();
if (syn == 6) //end
{
syn = scaner();
if(syn==0 && kk==0) //#
printf("success\n");
}
else //缺end
{
if(kk != 1)
{
printf("缺end错误\n");
kk = 1;
}
}
}
else
{
printf("begin错误\n");
kk = 1;
}
}
//语句串分析函数
void statements()
{
statement();
while(syn == 26) //分号;
{
syn = scaner();
statement();
}
}
//语句分析函数
void statement()
{
if(syn == 10) //标识符
{
syn = scaner();
if(syn == 18) //:=
{
syn = scaner();
expression();
}
else
{
printf("赋值号错误\n");
kk = 1;
}
}
else
{
printf("语句错误\n");
kk = 1;
}
}
//表达式分析函数
void expression()
{
term();
while(syn==13 || syn==14) //+或-
{
syn = scaner();
term();
}
}
//项分析函数
void term()
{
factor();
while(syn==15 || syn==16) //*或/
{
syn = scaner();
factor();
}
}
//因子分析函数
void factor()
{
if(syn==10 || syn==11) //标识符或常数
syn = scaner();
else if(syn == 27) //(
{
syn = scaner();
expression();
if(syn == 28)
syn = scaner();
else
{
printf(")错误\n");
kk = 1;
}
}
else
{
printf("表达式错误\n");
kk = 1;
}
}
运行结果: