📄 词法-语法(项目).cpp
字号:
{
do
{
ch=fgetc(fp);
}while(ch!='\n');
errorline++;
}
else
{
fseek(fp,-1,1);
for(u=0;u<3;u++)
{
token[n].id=DEV;
strcpy(token[n].name,"/");
token[n].line=errorline;
}
n++;
out(DEV,0,"/");
}
break;
case '+':
out(ADD,0,"+");
for(u=0;u<3;u++)
{
token[n].id=ADD;
strcpy(token[n].name,"+");
token[n].line=errorline;
}
n++;
break;
case '-':
out(SUB,0,"-");
for(u=0;u<3;u++)
{
token[n].id=SUB;
strcpy(token[n].name,"-");
token[n].line=errorline;
}
n++;
break;
case '*':
out(MUL,0,"*");
for(u=0;u<3;u++)
{
token[n].id=MUL;
strcpy(token[n].name,"*");
token[n].line=errorline;
}
n++;
break;
case ';':
out(FG,0,";");
for(u=0;u<3;u++)
{
token[n].id=FG;
strcpy(token[n].name,";");
token[n].line=errorline;
}
n++;
break;
case ' ':
break; //删除程序中的空格
case '\n':
errorline++;
break; //删除程序中的回车,并记录程序编译到第几行
case ' ':
break; //删除程序中的横向制表符
case -1 :
break; //删除文件尾符号
default :
reporterror(ch);
break;
}
}
return;
}
void CmpGramAnalyse()
{
Advance();
yujubiao();
if(count==0)
printf("\n恭喜你!你的语法分析成功通过\n\n");
else
printf("\n你的程序语法有误! 请检查你的源代码!\n\n");
return;
}
void Advance()
{
int Match=0;
if(flag<n)
{
lookuphead=token[flag].id;
strcpy(ErrorName,token[flag].name);
ErrorLine=token[flag].line;
if(lookuphead==4)
Match++;
flag++;
}
else
lookuphead=30; //结束标志
return;
}
void yujubiao() //S 语句表
{
if(lookuphead==1||lookuphead==3||lookuphead==5||lookuphead==8)//Y的first集
yuju();
if(lookuphead==23)
{
Advance();
yujubiao();
}
return;
}
void yuju() //Y 语句
{
switch(lookuphead)
{
case 1:
fuzhi();
break;
case 3:
fuhe();
break;
case 5:
tiaojian();
break;
case 8:
whileyuju();
break;
default:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(Y)\t行\n",ErrorName,ErrorLine);
count=1;
}
return;
}
void fuzhi() //F 赋值语句
{
bianliang();
if(lookuphead==20)
Advance();
else
goto out;
if(lookuphead==1||lookuphead==2||lookuphead==21)
suanshu();
else
goto out;
return;
out:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(F)\t行\n",ErrorName,ErrorLine);
count=1;
return;
}
void tiaojian() //T 条件语句
{
if(lookuphead==5)
{
Advance();
if(lookuphead==1||lookuphead==2||lookuphead==21)
guanxi();
else
goto out;
if(lookuphead==6)
Advance();
else
goto out;
if(lookuphead==1||lookuphead==3||lookuphead==5||lookuphead==8)//Y的first集
yuju();
else
goto out;
if(lookuphead==7)
Advance();
else
goto out;
if(lookuphead==1||lookuphead==3||lookuphead==5||lookuphead==8)//Y的first集
yuju();
else
goto out;
}
else
goto out;
return;
out:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(T)\t行\n",ErrorName,ErrorLine);
count=1;
return;
}
void whileyuju() //W WHILE语句
{
if(lookuphead==8)
{
Advance();
if(lookuphead==1||lookuphead==2||lookuphead==21)
guanxi();
else
goto out;
if(lookuphead==9)
Advance();
else
goto out;
if(lookuphead==1||lookuphead==3||lookuphead==5||lookuphead==8)//Y的first集
yuju();
else
goto out;
}
else
goto out;
return;
out:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(W)\t行\n",ErrorName,ErrorLine);
count=1;
return;
}
void fuhe() //H 复合语句
{
if(lookuphead==3)
{
Advance();
if(lookuphead==1||lookuphead==3||lookuphead==5||lookuphead==8)//Y的first集
yujubiao();
else if(lookuphead!=4)
goto out;
if(lookuphead==4)
Advance();
else
goto out;
}
else
goto out;
return;
out:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(H)\t行\n",ErrorName,ErrorLine,lookuphead);
count=1;
return;
}
void suanshu() //K 算术表达式
{
if(lookuphead==1||lookuphead==2||lookuphead==21)
xiang();
else
goto out;
if(lookuphead==4||lookuphead==6||lookuphead==7||
lookuphead==9||lookuphead==10||lookuphead==11||lookuphead==14||lookuphead==15||lookuphead==16||lookuphead==17||lookuphead==18||lookuphead==19||lookuphead==22||lookuphead==23)
{
Ksuanshu();
}
return;
out:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(K)\t行\n",ErrorName,ErrorLine);
count=1;
return;
}
//递归调用
void Ksuanshu()
{
while(lookuphead==10||lookuphead==11) //循环
{
Advance();
if(lookuphead==1||lookuphead==2||lookuphead==21)
xiang();
}
return;
}
void xiang() //X 项
{
if(lookuphead==1||lookuphead==2||lookuphead==21)
yinshi();
else
goto out;
if(lookuphead==4||lookuphead==6||lookuphead==7||
lookuphead==9||lookuphead==10||lookuphead==11||lookuphead==12||lookuphead==13||lookuphead==14||lookuphead==15||lookuphead==16||lookuphead==17||lookuphead==18||lookuphead==19||lookuphead==22||lookuphead==23)
{
XXfun();
}
return;
out:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(X)\t行\n",ErrorName,ErrorLine);
count=1;
return;
}
void XXfun()
{
while(lookuphead==12||lookuphead==13)
{
Advance();
if(lookuphead==1||lookuphead==2||lookuphead==21)
yinshi();
}
return;
}
void yinshi() //E 因式
{
switch(lookuphead)
{
case 1:
bianliang();
break;
case 2:
changshu();
break;
case 21:
Advance();
if(lookuphead==1||lookuphead==2||lookuphead==21)
suanshu();
else
goto out;
if(lookuphead==22)
Advance();
else
goto out;
break;
out:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(E)\t行\n",ErrorName,ErrorLine);
count=1;
}
return;
}
void guanxi() //G 关系表达式
{
int pre=14;
suanshu();
for(;pre<=19;pre++)
if(lookuphead==pre)
{
guanxifu();
break;
}
if(pre>19)
goto out;
if(lookuphead==1||lookuphead==2||lookuphead==21)
suanshu();
else
goto out;
return;
out:
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(G)\t行\n",ErrorName,ErrorLine);
count=1;
return;
}
void bianliang() //C 变量
{
Advance();
return;
}
void changshu() //N 常数
{
Advance();
return;
}
void guanxifu() //A 关系符
{
int pre=14;
for(;pre<=19;pre++)
if(lookuphead==pre)
{
Advance();
break;
}
if(pre>19)
{
printf(" 语法存在错误!\t the token is '%s' 在第 '%d'(A)\t行\n",ErrorName,ErrorLine);
count=1;
}
return;
}
void main(int argc,char *argv[])
{
int k,i,o;
o=1;
char string[max];
char ca;
FILE *fp;
while(o)
{
printf("请输入源程序文件的路径\n");
gets(string);
if((fp=fopen(string,"rt"))==NULL)
printf("源文件不存在或者路径不正确请重输!!!!!\n");
else o=0;
}
printf("------------词法分析开始------------\n");
printf("\n");
example(fp);
printf("该程序共有 %d 处错误\n",errornum);
printf("经过修复后,输出的二元式流如下:\n");
for(k=0;k<n;k++)
{
printf("%s\t\t(%d,%d)\n",token[k].name,token[k].line,token[k].id);
}
printf("按确定键进行语法分析\n");
ca=getchar();
if(ca=='\n')
{
printf("------------分析结束结果如下------------\n");
CmpGramAnalyse();
}
fclose(fp);
getchar();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -