语法分析实验
一、实验目的及内容
实现下述我们定义的语言的语法分析器
这种语言的程序结构很简单,语法相当于c的函数体,即由一对大括号括起来的语句序列,没有过程或函数。声明语句、表达式语句及控制语句的写法都与c 类似,但规定:一条声明语句只能声明一个整型变量,没有数组;控制语句只是if、for和while三个语句,这三个语句本身也可以包含语句序列;表达式仅局限于布尔表达式和整型算术表达式,布尔表达式由对两个算术表达式的比较组成,该比较使用<,>,<=,>=,= =,!=比较运算符;算术表达式可以包括整型常数、变量以及+,-,*,/这四个运算符。另外,还可以有复合语句。用read和write语句实现输入输出。注释用/*和*/括起来,但注释不能嵌套。
二、实验原理及基本技术路线图(方框原理图或程序流程图)
实验所用的产生式:
<程序> →‘{’ <声明序列> <语句序列> ‘}’
<声明序列> → <声明语句> { <声明语句> }
<声明语句> → int <标志符>;
<语句序列> → <语句> { <语句> }
<语句> →
<复合语句> →‘{ ’ <语句序列>‘ }’
<表达式语句> → <表达式>; | ;
<表达式> → <布尔表达式> | <标志符> = <布尔表达式>
<布尔表达式> → <算术表达式> | <算术表达式> ( > | < | >= | <= | == | !=)
<算术表达式>
<算术表达式> → <项> { ( + | - ) <项> }
<项> → <因子> { ( * | / ) <因子> }
<因子> → (<算术表达式>) | <标识符> | <无符号整数>
实验中自定义的函数:
int parse();语法分析主函数
int program();<程序>
int statement();<语句>
int expression_stat();<表达式语句>
int expression();<表达式>
int bool_expr();<布尔表达式>
int additive_expr();<算术表达式>
int term();<项>
int factor();<因子>
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int declaration_stat();<声明语句>
int declaration_list();<声明序列>
int statement_list();<语句序列>
int compound_stat();<复合语句>
三、所用仪器、材料(设备名称、型号、规格等或使用软件)
开发环境/平台:vc++6.0
实验器材:兼容计算机一台
四、实验方法、步骤(或:程序代码或操作过程)
实验源代码:
#include
#include
#include
#include
int parse();
int program();
int statement();
int expression_stat();
int expression();
int bool_expr();
int additive_expr();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
char token[20],token1[40];//token保存单词符号,token1保存单词值char Scanout[300]; //保存词法分析输出文件名
long count=0;
FILE *fp; //用于指向输入输出文件的指针
void main()
{
strcpy(Scanout,"输出.txt");
parse();
}
//语法分析程序
int parse()
{
int es=0;
if((fp=fopen(Scanout,"r"))==NULL)
{
printf("\n打开%s错误!\n",Scanout);
es=10;
}
if (es==0) es=program();
printf("=====语法分析结果!======\n");
switch(es)
{
case 0: printf("语法分析成功!\n");break;
case 10: printf("打开文件 %s失败!\n",Scanout);break;
case 1: printf("缺少{!\n");break;
case 2: printf("缺少}!\n");break;
case 3: printf("缺少标识符!\n");break;
case 4: printf("少分号!\n");break;
case 5: printf("缺少(!\n");break;
case 6: printf("缺少)!\n");break;
case 7: printf("缺少操作数!\n");break;
case 8: printf("缺少运算符!\n");break;
}
fclose(fp);
return(es);
}
void get()
{
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
count++;
}
void back(int j)//文件指针回退一位
{
int i;
printf("文件指针回退%d位!\n",j);
rewind(fp);
for(i=0;i { fscanf(fp,"%s %s\n",&token,&token1); } } //<程序>::={<声明序列><语句序列>} //program::= '{' { int es=0; get(); if(strcmp(token,"{"))//判断是否'{' { es=1; return(es); } 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); } //<声明序列>::=<声明序列><声明语句>|<声明语句> // // int declaration_list() { int es=0; get(); while (strcmp(token,"int")==0) { es=declaration_stat(); if (es>0) return(es); } return(es); //<声明语句> ::=int <变量>; // int declaration_stat() { int es=0; get(); if (strcmp(token,"ID")) return(es=3); //不是标识符 get(); if (strcmp(token,";") ) return(es=4); get(); return(es); } //<语句序列>::=<语句序列><语句>|<语句> // //改成 int statement_list() { int es=0; while (strcmp(token,"(")==0||strcmp(token,"NUM")==0||strcmp(token,"ID")==0||s trcmp(token,"if")==0||strcmp(token,"while")==0||strcmp(token,"for")==0| |strcmp(token,"read")==0||strcmp(token,"write")==0||strcmp(token,"{")== { es=statement(); if (es>0) return(es); get(); } return es; } //<语句>::= // int statement() //error;;;;;; { int es=0; if(strcmp(token,"if")==0) { es=if_stat(); return es; } if(strcmp(token,"while")==0) { es=while_stat(); return es; } if(strcmp(token,"for")==0) { es=for_stat(); return es; } if(strcmp(token,"read")==0) { es=read_stat(); return es; } if(strcmp(token,"write")==0) { es=write_stat(); return es; } if(strcmp(token,"{")==0) { es=compound_stat(); return es; } else { es=expression_stat(); return es; } return es; } // // int if_stat(){ int es=0; int temp=0; get(); if(strcmp(token,"(")==0) { get(); if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0) { es=expression(); } else if(strcmp(token,"ID")) return (es=3); else if(strcmp(token,"NUM")) return (es=7); get(); if(strcmp(token,")")==0) { get(); es=statement(); temp=es; if(es>0) return es; get(); if(strcmp(token,"else")==0) { get(); es=statement(); } else { count-=1; back(1); es=temp; }//需要做回退操作 } else { es=6; return es; } } else es=5; return es; } // // { int es=0; get(); if(strcmp(token,"(")==0) { get(); if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0) { es=expression(); } else if(strcmp(token,"ID")) return (es=3); else if(strcmp(token,"NUM")) return (es=7); get(); if(strcmp(token,")")==0) { get(); es=statement(); return es; } } else { es=5; return es; } return es; } // // int for_stat() { int es=0; get(); if(strcmp(token,"(")==0) { get(); if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0) { es=expression(); if(es>0) return es; } else if(strcmp(token,"ID")) return (es=3); else if(strcmp(token,"NUM")) return (es=7); get(); if(strcmp(token,";")==0) { get(); if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0) { es=expression(); if(es>0) return es; } else if(strcmp(token,"ID")) return (es=3); else if(strcmp(token,"NUM")) return (es=7); get(); if(strcmp(token,";")==0) { get(); if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0) { es=expression(); if(es>0) return es; } else if(strcmp(token,"ID")) return (es=3); else if(strcmp(token,"NUM")) return (es=7); get(); if(strcmp(token,")")==0) { get(); es=statement(); return es; } else { es=6; return es; } } else { es=4; return es; } } else { es=4; return es; } } else { es=5; return es; } return es; } // // int write_stat() { int es=0; get(); if(strcmp(token,"ID")==0||strcmp(token,"NUM")==0||strcmp(token,"(")= =0) { es=expression(); if(es>0) return es; get(); if(strcmp(token,";")) return 4; } else if(strcmp(token,"ID")) return (es=3); else if(strcmp(token,"NUM")) return (es=7); return es; } // // int read_stat() { int es=0; get(); if (strcmp(token,"ID")) return(es=3); //不是标识符 get(); if(strcmp(token,";")) return 4; return es; } //<复合语句>::={<语句序列>} // { //复合语句函数