编译原理实验报告
实验名称: 语法分析
实验类型: 设计性实验
指导教师: 蒋勇
专业班级: 软件1001班
姓 名: 李岳东
学 号: 20101557
实验地点: 东6A-319
实验成绩:____________________________
日期:20##年 月 日
一、实验目的
编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
二、实验设计
三、实验过程
1)给定文法:(文法举例)
EàE+T|T
TàT*F|F
Fà(E)|i
2)构造FIRST()集和FOLLOW()集
表3-1 FIRST()集和FOLLOW()集
四、实验结果
表 4-1 分析成功
表 4-2 分析失败
表 4-3 载入文件出错
流程图如下所示:
五、附录:关键代码
#include <iostream>
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
using namespace std;
int TESTparse();
int program();
int compound_Stat();
int statement();
int expression_Stat();
int expression_r();
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]; //保存词法分析输出文件名
FILE *fp; //用于指向输入输出文件的指针
//语法分析程序
int TESTparse()
{
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;
}
fclose(fp);
return(es);
}
//<程序>::={<声明序列><语句序列>}
//program::={<declaration_list><statement_list>}
int program()
{
int es=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);
}
//<声明序列>::=<声明序列><声明语句>|<声明语句>
//<declaration_list>::=
//<declaration_list><declaration_stat>|<declaration_stat>
//该成<declaration_list>::={<declaration_stat>}
int declaration_list()
{
int es=0;
while (strcmp(token,"int")==0)
{
es=declaration_stat();
if (es>0) return(es);
}
return(es);
}
//<声明语句> ::=int <变量>;
//<declaration_stat>::=int ID;
int declaration_stat()
{
int es=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);
}
//<语句序列>::=<语句序列><语句>|<语句>
//<statement_list>::=<statement_list><statement>|<statement>
//改成<statement_list>::={<statement>}
int statement_list()
{
int es=0;
while (strcmp(token,"}"))
{
es=statement();
if (es>0) return(es);
}
return(es);
}
//<语句>::=<if语句>|<while语句>|<for语句>|<read语句>
// |<write语句>|<复合语句>|<表达式语句>
//<statement>::= <if_stat>|<while_stat>|<for_stat>
// |<compound_stat> |<expression_stat>
int statement()
{
int es=0;
if (es==0 && strcmp(token,"if")==0) es=if_stat();//<IF语句>
if (es==0 && strcmp(token,"while")==0) es=while_stat();//<while语句>
if (es==0 && strcmp(token,"for")==0) es=for_stat();//<for语句>
//可在此处添加do语句调用
if (es==0 && strcmp(token,"read")==0) es=read_stat();//<read语句>
if (es==0 && strcmp(token,"write")==0) es=write_stat();//<write语句>
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 语句>::= if (<表达式>) <语句 > [else <语句 >]
//<IF_stat>::= if (<expr>) <statement > [else < statement >]
int if_stat(){
int es=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_r();
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(<表达式>) <语句>
//<while_stat>::= while (<expr >) < statement >
int while_stat()
{
int es=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_r();
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(<表达式>;<表达式>;<表达式>) <语句 >
//<for_stat>::= for(<expr>,<expr>,<expr>)<statement>
int for_stat()
{
int es=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_r();
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_r();
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_r();
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 <表达式>;
//<write_stat>::=write <expression>;
int write_stat()
{
int es=0;
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
es=expression_r();
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_语句>::=read <变量>;
//<read_stat>::=read ID;
int read_stat()
{
int es=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);
}
//<复合语句>::={<语句序列>}
//<compound_stat>::={<statement_list>}
int compound_stat(){ //复合语句函数
int es=0;
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
es=statement_list();
return(es);
}
//<表达式语句>::=<<表达式>;|;
//<expression_stat>::=<expression>;|;
int expression_stat()
{
int es=0;
if (strcmp(token,";")==0)
{
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
return(es);
}
es=expression_r();
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);//少分号
}
}
//<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>
//<expr>::=ID=<bool_expr>|<bool_expr>
int expression_r()
{
int es=0,fileadd;
char token2[20],token3[40];
printf("aaaaaaaaaaa%s\n",token);
if (strcmp(token,"ID")==0)
{
fileadd=ftell(fp); //记住当前文件位置
fscanf(fp,"%s %s\n", &token2,&token3);
printf("%s %s\n",token2,token3);
if (es>0) return(es);
if (strcmp(token2,"=")==0) //'='
{
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
es=bool_expr();
} else
{
fseek(fp,fileadd,0); //若非'='则文件指针回到'='前的标识符
printf("%s %s\n",token,token1);
es=bool_expr();
if (es>0) return(es);
}
}else es=bool_expr();
return(es);
}
//<布尔表达式>::=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式>
//<bool_expr>::=<additive_expr>
// |< additive_expr >(>|<|>=|<=|==|!=)< additive_expr >
int bool_expr()
{
int es=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);
}
//<算术表达式>::=<项>{(+|-)<项>}
//<additive_expr>::=<term>{(+|-)< term >}
int additive_expr()
{
int es=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);
}
//<项>::=<因子>{(*|/)<因子>}
//< term >::=<factor>{(*| /)< factor >}
int term()
{
int es=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);
}
//<因子>::=(<算术表达式>)|<标识符>|<无符号整数>
//< factor >::=(<additive_expr>)| ID|NUM
int factor()
{
int es=0;
if (strcmp(token,"(")==0)
{
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
es=expression_r();
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);
}
extern int TESTscan();
extern int TESTparse();
FILE *fin,*fout; //用于指向输入输出文件的指针
void main(){
int es=0;
es=TESTscan();//调词法分析
if (es>0) printf("词法分析有错,编译停止!");
else printf("词法分析成功!\n");
if (es==0)
{
es=TESTparse(); //调语法分析
if (es==0) printf("语法分析成功!\n");
else printf("语法分析错误!\n");
}
}
七、实验者自评
1.对实验原理有更深的理解。
2.理解了编译原理知识点及学科间的容和渗透,将以前学习的C++基础技术应用于设计实现,加深了对vc++界面升序设计的理解达到了学以致用的目的
编译原理实验报告实验名称实验类型指导教师专业班级姓名学号实验地点实验成绩编写语法分析程序上机实验蒋勇软件1002班20xx1东6A…
语法分析器的设计实验报告一实验内容语法分析程序用LL1语法分析方法首先输入定义好的文法书写文件所用的文法可以用LL1分析先求出所输…
编译原理语法分析实验报告软工082班兰洁20xx31104044一实验内容二实验目的三实验要求四程序流程图主函数scannerir…
实验三语法分析器一实验目的理解和掌握LL1语法分析方法的基本原理根据给出的LL1文法掌握LL1分析表的构造及分析过程的实现掌握语法…
编译原理实验报告编译原理实验报告1编译原理实验报告一实验内容设计编制并调式一个语法分析程序加深对语法分析原理的理解二实验目的及要求…
实验四用excel进行方差分析的实验报告实验目的学会在计算机上利用excel进行单因素方差分析和有交互的双因素分析以及无交互的双因…
认识实习常用电子仪器使用专业班级姓名学号完成时间20xx年6月实验示波器和信号发生器的使用一实验目的1学习示波器的基本使用方法2学…
管理统计实验报告实验一一实验目的掌握用spss软件对数据进行相关性分析熟悉其操作过程并能分析其结果二实验原理相关性分析是考察两个变…
实验室间比对和能力验证结果的分析报告质管办为了通过适时开展比对试验和能力验证等质量控制活动对检测质量及其过程的有效性进行监控保证检…
资料5能力验证和实验室比对结果的分析报告120xx年参见项目伤残程度鉴定结果满意20xx年本所首次参加能力验证活动接到能力验证计划…
编译原理实验报告实验名称实验类型指导教师专业班级姓名学号实验地点实验成绩编写语法分析程序上机实验蒋勇软件1002班20xx1东6A…