test语法分析程序.docx
《test语法分析程序.docx》由会员分享,可在线阅读,更多相关《test语法分析程序.docx(12页珍藏版)》请在冰点文库上搜索。
#include
#include
#include
#include
#include
#include
#include
intTESTparse();
intprogram();
intcompound_Stat();
intstatement();
intexpression_Stat();
intexpression();
intbool_expr();
intExchange();
intadditive_expr();
intterm();
intfactor();
intif_stat();
intwhile_stat();
intfor_stat();
intwrite_stat();
intread_stat();
intdeclaration_stat();
intdeclaration_list();
intstatement_list();
intcompound_stat();
intexpression_stat();
chartoken[20],token1[40];//token保存单词符号,token1保存单词值
externcharScanout[300];//保存词法分析输出文件名
FILE*fp;//用于指向输入文件的指
intTESTparse()
{
intes=0;
if((fp=fopen(Scanout,"r"))==NULL)
{
printf("\n打开%s错误!
\n",Scanout);
es=10;
}
if(es==0)es=program();
printf("=====语法分析结果!
=====\n");
switch(es)
{
case0:
printf("语法分析成功!
\n");break;
case10:
printf("打开文件%s失败!
\n",Scanout);break;
case1:
printf("缺少{!
\n");break;
case2:
printf("缺少}!
\n");break;
case3:
printf("缺少标识符!
\n");break;
case4:
printf("少分号!
\n");break;
case5:
printf("缺少(!
\n");break;
case6:
printf("缺少)!
\n");break;
case7:
printf("缺少操作数!
\n");break;
}
fclose(fp);
return(es);
}
//program:
:
={}
intprogram()
{
intes=0;
fscanf(fp,"%s%s\n",token,token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"{"))//判断是否为'{'
{
es=1;
return(es);
}
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=declaration_list();
if(es>0)return(es);
es=statement_list();
if(es>0)return(es);
if(strcmp(token,"}"))//判断是否为'}'
{
es=2;
return(es);
}
return(es);
}
//<声明序列>:
:
=<声明序列><声明语句>|$
//:
:
=
//|$
//改成:
:
={}
intdeclaration_list()
{
intes=0;
while(strcmp(token,"int")==0)
{
es=declaration_stat();
if(es>0)return(es);
}
return(es);
}
//<声明语句>:
:
=int<变量>;
//:
:
=intID;
intdeclaration_stat()
{
intes=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"ID"))return(es=3);//不是标识符
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,";"))return(es=4);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return(es);
}
//<语句序列>:
:
=<语句序列><语句>|$
//:
:
=|$
//改成:
:
={}
intstatement_list()
{
intes=0;
while(strcmp(token,"}"))
{
es=statement();
if(es>0)return(es);
}
return(es);
}
//<语句>:
:
=|||||<复合语句>|<表达式语句>
//:
:
=||||
intstatement()
{
intes=0;
if(es==0&&strcmp(token,"if")==0)es=if_stat();//
if(es==0&&strcmp(token,"while")==0)es=while_stat();//
if(es==0&&strcmp(token,"for")==0)es=for_stat();//
if(es==0&&strcmp(token,"read")==0)es=read_stat();//
if(es==0&&strcmp(token,"write")==0)es=write_stat();//
if(es==0&&strcmp(token,"{")==0)es=compound_stat();//<复合语句>
if(es==0&&strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")==0)
es=expression_stat();//<表达式语句>
return(es);
}
//:
:
=if(<表达式>)<语句>[else<语句>]
//:
:
=if()[else]
intif_stat()
{
intes=0;//if
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"("))return(es=5);//少左括号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=expression();
if(es>0)return(es);
if(strcmp(token,")"))return(es=6);//少右括号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement();
if(es>0)return(es);
if(strcmp(token,"else")==0)//else部分处理
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement();
if(es>0)return(es);
}
return(es);
}
//:
:
=while(<表达式>)<语句>
//:
:
=while()
intwhile_stat()
{
intes=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"("))return(es=5);//少左括号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=expression();
if(es>0)return(es);
if(strcmp(token,")"))return(es=6);//少右括号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement();
return(es);
}
//:
:
=for(<表达式>;<表达式>;<表达式>)<语句>
//:
:
=for(;;)
intfor_stat()
{
intes=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"("))return(es=5);//少左括号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=expression();
if(es>0)return(es);
if(strcmp(token,";"))return(es=4);//少分号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=expression();
if(es>0)return(es);
if(strcmp(token,";"))return(es=4);//少分号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=expression();
if(es>0)return(es);
if(strcmp(token,")"))return(es=6);//少右括号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement();
return(es);
}
//:
:
=write<表达式>;
//:
:
=write;
intwrite_stat()
{
intes=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=expression();
if(es>0)return(es);
if(strcmp(token,";"))return(es=4);//少分号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return(es);
}
//:
:
=read<变量>;
//:
:
=readID;
intread_stat()
{
intes=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"ID"))return(es=3);//少标识符
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,";"))return(es=4);//少分号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return(es);
}
//<复合语句>:
:
={<语句序列>}
//:
:
={}
intcompound_stat()//复合语句函数
{
intes=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement_list();
return(es);
}
//<表达式语句>:
:
=<<表达式>;|;
//:
:
=;|;
intexpression_stat()
{
intes=0;
if(strcmp(token,";")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return(es);
}
es=expression();
if(es>0)return(es);
if(es==0&&strcmp(token,";")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return(es);
}else
{
es=4;
return(es);//少分号
}
}
//<表达式>:
:
=<标识符>=<布尔表达式>|<布尔表达式>
//:
:
=ID=|
intexpression()
{
intes=0,fileadd;
chartoken2[20],token3[40];
if(strcmp(token,"ID")==0)
{
fileadd=ftell(fp);//记住当前文件位置
fscanf(fp,"%s%s\n",&token2,&token3);
printf("%s%s\n",token2,token3);
if(strcmp(token2,"=")==0)//'='
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=bool_expr();
if(es>0)return(es);
}else
{
fseek(fp,fileadd,0);//若非'='则文件指针回到'='前的标识符
printf("%s%s\n",token,token1);
es=bool_expr();
if(es>0)return(es);
}
}elsees=bool_expr();
return(es);
}
//<布尔表达式>:
:
=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!
=)
//<算术表达式>
//:
:
=
//|(>|<|>=|<=|==|!
=)
intbool_expr()
{
intes=0;
es=additive_expr();
if(es>0)return(es);
if(strcmp(token,">")==0||strcmp(token,">=")==0||strcmp(token,"<")==0
||strcmp(token,"<=")==0||strcmp(token,"==")==0||strcmp(token,"!
=")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=additive_expr();
if(es>0)return(es);
}
return(es);
}
//<算术表达式>:
:
=<项>{(+|-)<项>}
//:
:
={(+|-)}
intadditive_expr()
{
intes=0;
es=term();
if(es>0)return(es);
while(strcmp(token,"+")==0||strcmp(token,"-")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=term();
if(es>0)return(es);
}
return(es);
}
//<项>:
:
=<因子>{(*|/)<因子>}
//:
:
={(*|/)}
intterm()
{
intes=0;
es=factor();
if(es>0)return(es);
while(strcmp(token,"*")==0||strcmp(token,"/")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=factor();
if(es>0)return(es);
}
return(es);
}
//<因子>:
:
=(<表达式>)|<标识符>|<无符号整数>
//:
:
=()|ID|NUM
intfactor()
{
intes=0;
if(strcmp(token,"(")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=expression();
if(es>0)return(es);
if(strcmp(token,")"))return(es=6);//少右括号
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
}else
{
if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return(es);
}else
{
es=7;//缺少操作数
return(es);
}
}
return(es);
}
externintTESTscan();
externintTESTparse();
voidmain()
{
intes=0;
es=TESTscan();//调词法分析
if(es>0)printf("词法分析有错,编译停止!
");
elseprintf("词法分析成功!
\n");
if(es==0)
{
es=TESTparse();//调语法分析
if(es==0)printf("语法分析成功!
\n");
elseprintf("语法分析错误\n");
}
}
//下面定义保留字表,为简化程序,使用字符指针数组保存所有的保留字
//如果想增加保留字,可继续添加,并修改保存保留字数目keywordSum
#definekeywordSum8
char*keyword[keyw