编译原理预测分析法实验报告

编译原理实验预测分析法

姓名                     **                                  

学号                     **                                    

班级                     **                                         

完成日期                 **                                    

1.实验目的

加深对语法分析器工作过程的理解;加强对预测分析法实现语法分析程序的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法翻译。

2.实验要求

1.对语法规则有明确的定义;

2.编写的分析程序能够对实验一的结果进行正确的语法分析;

3.对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程;

4.实验报告要求用文法的形式对语法定义做出详细说明,说明语法分析程序的工作过程,说明错误处理的实现。

3.实验原理

对文法G进行语法分析,文法G如下所示:

*0.      S→a */

*1.     S→^ 

*2.      S→(T)

*3.      T→SW *

*4.   W→,SW

*5.      W→ε;

4.软件设计与编程

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

char str[100];  //存储待分析的句子

const char T[ ]   = "a^(),#";  //终结符,分析表的列符

const char NT[ ]  = "STW"; //非终结符,分析表的行符

/*指向产生式右部符号串*/ 

const char *p[] = {

/*0.  S→a */   "a",

/*1.    S→^       */  "^",

/*2.  S→(T)  */     "(T)",

/*3.  T→SW */       "SW",

/*4.    W→,SW  */   ",SW",

/*5.  W→ε;  */    ""

};

//设M[i][j]=x,通过p[M[i][j]]=p[x]获取右部符号串。

const int M[][6] = {             

    /*         a   ^   (   )   ,   #   */

       /*S*/       {  0,  1,  2, -1, -1, -1 },                                        

       /*T*/       {  3,  3,  3, -1, -1, -1 },                                        

       /*W*/     {  -1, -1,-1,  5,  4,  -1 } 

};

void init()//输入待分析的句子

{

       printf("请输入待分析的句子(以$结束):\n");

       scanf("%s",str);

}

int lin(char c);//非终结符转换为行号

int col(char c);//终结转换为列号

bool isNT(char c);//isNT判断是否是非终结符

bool isT(char c);//isT判断是否是终结符。

void main(void)

{    

       int i,j=0;

       int flag=1,flag2=0;

       char A;    //设置指示句子的当前字符

       char stack[20]=      {'#','S'}; //栈赋初值

       int top = 1 ;    //设置栈顶指针

       char X = ' ' ;   //存储栈顶字符

       init();

       A=str[0];   

       printf("\t步数\t分析栈\t输入串\t所用规则\n");       //在屏幕上输出列表标题

       while ( 1 )

       {                                

              printf("\n\t(%d)\t",++j); //输出当前执行步数           

              for ( i = 0 ; i <= top ; i++ )  //输出当前栈的内容(出栈前)

              {                  

                     printf("%c",stack[i]);                  

              }    

              printf("\t");

              for ( i = flag-1 ; str[i]!='$' ; i++ )

              {

                     printf("%c",str[i]);              

              }    

              if(flag2==1)

              {

                     printf("\t%d",M[ lin(X) ][col(A)]);

                     flag2=0;

              }

              //出栈

              X = stack[top--] ;         

              if (X=='#')//是结束符

              {                                                     

                     if (X==A)//是结束符

                     {                                                     

                            printf("\tAcc\n");

                     }

                     else printf("\tERROR\n");                  

                            break;                  

              }

              else if (isT(X))//是终结符

              {                         

                            A=str[flag++];             

              }

              else if (isNT(X))//是否是非终结符

              {                         

                         flag2=1;

                            //逆序入栈

                            for( i = strlen( p[ M[ lin(X) ][col(A)] ] ) - 1; i >= 0; i--)

                            {

                                   stack[++top] = *(p[M[lin(X)][col(A)]] + i ) ;

                            }                  

              }

              else

              {                  

                     printf("Error in main()>%c\n",X);                    

                     exit(0);

              }

       }

}

int lin(char c)

{                  

       for(int i = 0; i < (int)strlen(NT); i ++ )

       {

              if (c == NT[i])

              {

                     return i ;

              }

       }    

       printf("Error in lin()>%c\n",c);

       exit(0) ;

}

int col(char c)

{                  

       for (int i=0; i<(int)strlen(T); i ++ )

       {

              if (c == T[i])  return i;         

       }    

       printf("Error in col()>%c\n",c);

       exit(0);

}

bool isNT(char c)  //是否是非终结符

{

       for (int i = 0; i < (int)strlen(NT); i ++ )

       {

              if (c==NT[i])                      

                     return true;           

       }

       return false;

}

bool isT(char c)  //是否是终结符(不包括'#')

{

       for (int i = 0; i < (int)strlen(T) - 1; i ++ )

       {

              if (c == T[i])

              {

                     return true;

              }

       }

       return false;

}

5.程序测试结果

 

第二篇:编译原理实验报告LR(1)分析法

河南工业大学实验报告

课  程      编译原理           实验名称   实验四 LR(1)分析法

一.      实验目的

  1.掌握LR(1)分析法的基本原理;

 2.掌握LR(1)分析表的构造方法;

 3.掌握LR(1)驱动程序的构造方法。

二.      实验内容及要求

根据某一文法编制调试LR(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对LR(1)分析法的理解。

   对下列文法,用LR(1)分析法对任意输入的符号串进行分析:

(0)E->S

(1)S->BB

(2)B->aB

(3)B->b

       程序输入一以#结束的符号串(包括a、b、#),如:abb#。输出过程如下:

三.      实验过程及结果

       (说明:实验结果可以是运行画面的抓屏,抓屏图片要尽可能的小。)

实验代码:

#include<stdio.h>

#include<string.h> 

char *action[10][3]={"S3#","S4#",NULL,            /*ACTION表*/

    NULL,NULL,"acc",

       "S6#","S7#",NULL,

       "S3#","S4#",NULL,

       "r3#","r3#",NULL,

       NULL,NULL,"r1#",

       "S6#","S7#",NULL,

       NULL,NULL,"r3#",

       "r2#","r2#",NULL, 

          NULL,NULL,"r2#"};

int goto1[10][2]={

         1,2,                          /*GOTO表*/

      0,0,

         0,5,

      0,8,

      0,0,

      0,0,

      0,9,

      0,0,

      0,0,

      0,0};

char vt[3]={'a','b','#'};                       /*存放非终结符*/

char vn[2]={'S','B'};                           /*存放终结符*/

char *LR[4]={"E->S#","S->BB#","B->aB#","B->b#"};/*存放产生式*/

int a[10];

char b[10],c[10],c1;

int top1,top2,top3,top,m,n;

void main(){

       int g,h,i,j,k,l,p,y,z,count;

       char x,copy[10],copy1[10];

       top1=0;top2=0;top3=0;top=0;

       a[0]=0;y=a[0];b[0]='#';

       count=0;z=0;

       printf("请输入表达式\n");

/*输出状态栈、输出符号栈、输出输入串*/

 do{

  scanf("%c",&c1);

  c[top3]=c1;

  top3=top3+1;

 }while(c1!='#');

 printf("步骤\t状态栈\t\t符号栈\t\t输入串\t\tACTION\tGOTO\n");

 do{

        y=z;m=0;n=0;                      /*y,z指向状态栈栈顶*/

        g=top;j=0;k=0;

        x=c[top];

        count++;

        printf("%d\t",count);

  while(m<=top1){                    /*输出状态栈*/

   printf("%d",a[m]);

   m=m+1;

  }

  printf("\t\t");

  while(n<=top2){                    /*输出符号栈*/

   printf("%c",b[n]);

   n=n+1; 

}

  printf("\t\t");

  while(g<=top3){                    /*输出输入串*/

   printf("%c",c[g]);

   g=g+1;

  }

  printf("\t\t");

  while(x!=vt[j]&&j<=2) j++;

  if(j==2&&x!=vt[j]){ 

   printf("error\n");

   return;

  }

   if(action[y][j]==NULL){

   printf("error\n");

   return;

  }

  else

         strcpy(copy,action[y][j]);

  if(copy[0]=='S'){                      /*处理移进*/

         z=copy[1]-'0';

         top1=top1+1;

      top2=top2+1;

         a[top1]=z;

         b[top2]=x;

         top=top+1;

      i=0;

   while(copy[i]!='#'){

    printf("%c",copy[i]);

    i++;

   }

   printf("\n");

  }

  if(copy[0]=='r'){                      /*处理归约*/

   i=0;

   while(copy[i]!='#'){

    printf("%c",copy[i]);

    i++;

   }

   h=copy[1]-'0';

   strcpy(copy1,LR[h]);

   while(copy1[0]!=vn[k]) k++;

   l=strlen(LR[h])-4;

   top1=top1-l+1;

   top2=top2-l+1;

   y=a[top1-1]; 

   p=goto1[y][k];

   a[top1]=p;

   b[top2]=copy1[0];

   z=p;

   printf("\t");

   printf("%d\n",p);

  } }

 while(action[y][j]!="acc");

 printf("acc\n");

 getchar();

}

截屏如下:

      

四.      实验中的问题及心得

同前面一样。实验加深了对LR(1)的理解,再接再厉吧

相关推荐