📄 yufafenxi.cpp
字号:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#define MAXBUF 255
int Cur=0;
int type[MAXBUF];//用来存放词法分析器生成的每个单词的种别号,语法分析器通过调用该数组中的值来判断是否符合文法定义。
int line[MAXBUF];//用来标记所处程序的行号方便查出错误位置。
int FuZhiYuJu();
int TiaoJianYuJu();
int XunHuanYuJu();
void BoolLiang();
void BiaoDaShi();
void Xiang();
void YinZi();
void YuJuChuan();
void YuJu();
void Body();
void ChengXu();
void Yacc();
int Judge(char*);
void lexscanf(FILE*,FILE*);
int Judge(char *p)
{
char *word[]={"if","then","else","while","do","begin","end","program"};
int ptr,i,flag;
flag=0;
for(i=0;i<8;i++)
{
ptr=stricmp(p,word[i]);
if(ptr==0)
{
flag=1;
return(i+1);
}
}
if(flag==0)
{
return 0;
}
return 0;
}
void lexscanf(FILE *fpin,FILE*fpout)
{
char arr[MAXBUF];
int i=0;
int j=0;
int lineo=1;
char ch;
while(1)
{
fscanf(fpin,"%c",&ch); //从输入文件中读入字符
if(ch==' '||ch=='\t') //清除空白
;
else if(ch=='\n') //识别回车,行数+1
lineo++;
else if(isdigit(ch)) //如果输入字符为数字
{
while(isdigit(ch)) //一直读字符,直到读入的字符不是数字
{
arr[j]=ch;
j++;
fscanf(fpin,"%c",&ch);
}
arr[i] = 0;
fseek(fpin,-1L,SEEK_CUR);
char* temp1=(char*)malloc(j+1);
memcpy(temp1,arr,j); //将缓冲区的内容拷贝到temp1中去
temp1[j]='\0';
j=0;
fprintf(fpout,"%s\t\t%d\n",temp1,10); //在文件中写入数字
type[Cur]=10;
line[Cur]=lineo;
Cur++;
free(temp1);
}
else if(isalpha(ch)) //如果读入的字符为字母
{
while(isalpha(ch)||isdigit(ch))
{
arr[i]=ch;
i++;
fscanf(fpin,"%c",&ch);
}
arr[i] = 0;
fseek(fpin,-1L,SEEK_CUR);
char* temp=(char*)malloc(i+1);
memcpy(temp,arr,i);
temp[i]='\0';
i=0;
if(Judge(temp)) //如果读入的字母能与关键字相等
{
fprintf(fpout,"%s\t\t%d\n",temp,Judge(temp)); //输出该关键字,并且输出类型号
type[Cur]=Judge(temp);
line[Cur]=lineo;
Cur++;
}
else
{
fprintf(fpout,"%s\t\t%d\n",temp,9); //否则,认定为标示符
type[Cur]=9;
line[Cur]=lineo;
Cur++;
}
free(temp);
}
else if(ch==':') //处理二字符运算符:=
{
fscanf(fpin,"%c",&ch);
if(ch=='=')
{
fprintf(fpout,"%s\t\t%d\n",":=",11);
type[Cur]=11;
line[Cur]=lineo;
Cur++;
}
else
fprintf(fpout,"error in compiling line %d! Unknown character %c \n",lineo,ch);
}
else //处理各种单字符运算符
{
if(ch=='+')
{
fprintf(fpout,"%c\t\t%d\n",'+',12);
type[Cur]=12;
line[Cur]=lineo;
Cur++;
continue;
}
if(ch=='-')
{
fprintf(fpout,"%c\t\t%d\n",'-',13);
type[Cur]=13;
line[Cur]=lineo;
Cur++;
continue;
}
if(ch=='(')
{
fprintf(fpout,"%c\t\t%d\n",'(',14);
type[Cur]=14;
line[Cur]=lineo;
Cur++;
continue;
}
if(ch==')')
{
fprintf(fpout,"%c\t\t%d\n",')',15);
type[Cur]=15;
line[Cur]=lineo;
Cur++;
continue;
}
if(ch=='*')
{
fprintf(fpout,"%c\t\t%d\n",'*',16);
type[Cur]=16;
line[Cur]=lineo;
Cur++;
continue;
}
if(ch==';')
{
fprintf(fpout,"%c\t\t%d\n",';',17);
type[Cur]=17;
line[Cur]=lineo;
Cur++;
continue;
}
if(ch=='#') //终止符
{
fprintf(fpout,"%c\t\t%d\n",'#',18);
type[Cur]=18;
line[Cur]=lineo;
Cur++;
break;
}
else //若都没找到,输入错误!
fprintf(fpout,"error in compiling line %d! Unkonwn character %c \n",lineo,ch);
}
}
}
int FuZhiYuJu() //赋值语句
{
if(type[Cur]!=9)
{
printf("语法错误,缺少标示符。错误行号%d\n",line[Cur]);
}
Cur++;
if(type[Cur]!=11)
{
printf("语法错误,缺少:=。错误行号%d\n",line[Cur]);
}
Cur++;
BiaoDaShi();
return 1;
}
int TiaoJianYuJu() //条件语句
{
if(type[Cur]!=1)
{
printf("语法错误,缺少if。错误行号%d\n",line[Cur]);
}
Cur++;
BoolLiang();
if(type[Cur]!=2)
{
printf("语法错误,缺少then。错误行号%d\n",line[Cur]);
}
Cur++;
YuJu();
if(type[Cur]!=3)
{
return 0;
}
Cur++;
YuJu();
return 1;
}
int XunHuanYuJu() //循环语句
{
if(type[Cur]!=4)
{
printf("语法错误,缺少while。错误行号%d\n",line[Cur]);
}
Cur++;
BoolLiang();
if(type[Cur]!=5)
{
printf("语法错误,缺少do。错误行号%d\n",line[Cur]);
}
Cur++;
YuJu();
return 1;
}
void BoolLiang() //布尔量
{
if(type[Cur]!=9)
{
printf("语法错误,布尔量错误。错误行号%d\n",line[Cur]);
}
Cur++;
}
void BiaoDaShi() //表达式
{
Xiang();
while(type[Cur]==12||type[Cur]==13)
{
Cur++;
Xiang();
}
}
void Xiang() //项数
{
YinZi();
while(type[Cur]==16)
{
Cur++;
YinZi();
}
}
void YinZi() //因子
{
switch(type[Cur])
{
case 9:
Cur++;
break;
case 10:
Cur++;
break;
case 14:
Cur++;
BiaoDaShi();
if(type[Cur]!=15)
{
printf("语法错误,缺少)。错误行号%d\n",line[Cur]);
}
Cur++;
break;
default:
printf("语法错误,缺少因子。错误行号%d\n",line[Cur]);
}
}
void YuJuChuan() //语句串
{
YuJu();
while(type[Cur]==17)
{
Cur++;
YuJu();//每次遇到一个分号表示上一个语句判断完毕,进行下一个语句判断。
}
}
void YuJu() //语句判断循环、分支、赋值语句的入口。
{
switch(type[Cur])
{
case 9:
if(FuZhiYuJu()==1)
{
printf("赋值语句\n");
}
break;
case 1:
if(TiaoJianYuJu()==0)
{
printf("if then 分支语句\n");
}
else
{
printf("if then else 分支语句\n");
}
break;
case 4:
if(XunHuanYuJu()==1)
{
printf("while do 循环语句,嵌套赋值语句\n");
}
break;
case 7:
return;
default:
printf("语法错误,缺少语句。错误行号%d\n",line[Cur]);
}
}
void Body() //程序体用于识别程序主体开始
{
switch(type[Cur])
{
case 6:
break;
default:
printf("语法错误,缺少begin。错误行号%d\n",line[Cur]);
}
Cur++;
if(type[Cur]!=7)
{
YuJuChuan();
}
switch(type[Cur])
{
case 7:
break;
default:
printf("语法错误,缺少end。错误行号%d\n",line[Cur]);
}
}
void ChengXu() //程序用来识别程序段开始和结束字符
{
switch(type[Cur])
{
case 8:
break;
default:
printf("语法错误,缺少program。错误行号%d\n",line[Cur]);
}
Cur++;
switch(type[Cur])
{
case 9:
break;
default:
printf("语法错误,缺少标示符。错误行号%d\n",line[Cur]);
}
Cur++;
switch(type[Cur])
{
case 17:
break;
default:
printf("语法错误,缺少; 。错误行号%d\n",line[Cur]);
}
Cur++;
Body();
Cur++;
switch (type[Cur])
{
case 18:
break;
default:
printf("语法错误,缺少# 。错误行号%d\n",line[Cur]);
}
printf("语法分析完成!\n");
}
void Yacc() //语法分析器
{
Cur=0;
ChengXu();
}
void main()
{
FILE *fpin;
FILE *fpout;
if((fpin=fopen("d:\\lexin.txt","rt"))==NULL)
{
printf("Cannot open file!");
exit(1);
}
if((fpout=fopen("d:\\lexout.txt","wt"))==NULL)
{
printf("Cannot open file!");
exit(1);
}
lexscanf(fpin,fpout);
Yacc();
fclose(fpin);
fclose(fpout);
system("pause");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -