#include <stdio.h>
#include <string.h>
#include <conio.h>
char prog[80],token[6];
char ch;
int syn,p,m,n,sum,kk = 0;
char *rwtab[6] = {"begin","if","then","while","do","end"};
void scaner();
void lrparser();
void factor();
void expression();
void term();
void statement();
void yucu();
int main()
{
FILE *fp= fopen("file1.txt","r");
fread(prog,sizeof(char),80,fp);
fclose(fp);
printf("file1:");
p = 0;
scaner();
lrparser();
fp= fopen("file2.txt","r");
fread(prog,sizeof(char),80,fp);
fclose(fp);
printf("file2:");
p = 0;
scaner();
lrparser();
return 0;
}
/*扫描器,进行词法分析*/
void scaner()
{
for(int i = 0; i < 8; i++)
token[i] = NULL;
m = 0;
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';
ch = prog[--p];
syn = 10; //syn=10表示标识符
for(n = 0; n < 6; n++)
if(strcmp(token,rwtab[n]) == 0)//判断token数组与rwtab[n]关键字数组是否相等
{
syn = n + 1; //若相等,则置syn为对应的关键字的种别码值
break;
}
}
else if(ch <= '9' && ch >= '0')
{
sum = 0;
while(ch <= '9' && ch >= '0')
{
sum = sum * 10 + ch - '0';
ch = prog[p++];
}
ch = prog[--p];
syn = 11; //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;
ch = prog[--p];
}
break;
case '>':m = 0;token[m++] = ch;
ch = prog[p++];
if(ch == '=')
{
syn = 24;
token[m++] = ch;
}
else
{
syn = 23;
ch = prog[--p];
}
break;
case ':':m = 0;token[m++] = ch;
ch = prog[p++];
if(ch == '=')
{
syn = 18;
token[m++] = ch;
}
else
{
syn = 17;
ch = prog[--p];
}
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 = 18;token[0] = ch;break;
case '<>':syn = 21;token[0] = ch;break;
case '<=':syn = 22;token[0] = ch;break;
case '>=':syn = 24;token[0] = ch;break;
case '=':syn = 25;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 = 0;token[0] = ch;break;
default:syn = -1;
}
}
}
/*递归下降分析*/
void lrparser() //<程序>::=begin<语句串>end
{
if(syn == 1) //syn=1表示的单词符号是begin
{ //如果是begin
scaner(); //扫描下一个单词
yucu(); //进行语句串分析
if(syn == 6)//如果是end
{
scaner();//扫描下一个单词
if(syn == 0 && kk == 0)//如果是'#',则成功
printf("success\n\n");
}
else{
if(kk != 1)
printf("error:lack end\n\n");
kk = 1;
}
}
else{//第一个单词不是begin
printf("error:lack begin\n\n");
kk = 1;
}
}
/*语句串分析*/
void yucu() //<语句串>::=<语句>{;<语句>}
{
statement(); //分析语句
while(syn == 26) //如果单词是';',则扫描下一个单词
{
scaner();
statement();
}
}
/*语句分析*/
void statement()//<语句>::=<赋值语句> <赋值语句>::=ID:=<表达式>
{
if(syn == 10) //如果是标识符,则扫描下一个单词
{
scaner();
if(syn == 18) //如果标识符后面是赋值号,则扫描下一个单词
{
scaner();
expression(); //表达式分析
}
else //如果标识符后面不是赋值号
{
printf("赋值号错误!");
kk = 1;
}
}
else //如果不是标识符
{
printf("语句错误!");
kk = 1;
}
}
/*表达式分析函数*/
void expression()//<表达式>::=<项>{+<项> | -<项>}
{
term();//项分析
while(syn == 13 || syn == 14)//如果是'+'或'-',则扫描下一个单词
{
scaner();
term();//项分析
}
}
/*项分析函数*/
void term()//<项>::=<因子>{*<因子> | /<因子>
{
factor();//因子分析
while(syn == 15 || syn == 16)//如果是'*'或'/',则扫描下一个单词
{
scaner();
factor();//因子分析
}
}
/*因子分析函数*/
void factor()//<因子>::=ID | NUM | (<表达式>)
{
if(syn == 10 || syn == 11)//如果是标识符或数字,则扫描下一个单词
scaner();
else if(syn == 27)//如果是左括号
{
scaner();//扫描下一个单词
expression();//表达式分析
if(syn == 28)//如果是右括号
scaner();//扫描下一个单词
else{
printf("')'错误!");
kk = 1;
}
}
else{
printf("表达式错误!");
kk = 1;
}
}
递归下降的语法分析
最新推荐文章于 2023-05-07 08:41:26 发布