语法分析 实验报告

编译原理实验报告

实验名称:              语法分析                           

实验类型:              设计性实验                    

指导教师:                   蒋勇                          

专业班级:              软件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++界面升序设计的理解达到了学以致用的目的

相关推荐