实验三 语义分析程序的设计与实现

实验三   语义分析程序的设计与实现

一、实验目的:

加深对语法分析器工作过程的理解;能够采用一种编程语言实现简单的语义分析程序;能够使用自己编写的分析程序对简单的程序段进行语义分析,生成中间代码。

二、实验内容:

在实验2的基础上,用递归下降分析法编制语义分析程序,语义分析程序的实现可以采用任何一种编程工具。

三、实验要求:

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

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

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

4. 实验报告要求用文法的形式对语义详细说明,说明语义分析程序的工作过程,说明相应翻译动作的实现*

四、实验学时:4学时

五、实验步骤:

1. 定义语法规则;

2. 设置语义过程,插入语义动作;

3. *对遇到的语法、语义错误做出错误处理。

六、算法思想:

1、设置语义过程。

1emit(char *result,char *ag1,char *op,char *ag2)

该函数的功能是生成一个三地址语句送到四元式表中。

四元式表的结构如下:

struct

{     char result[8];

char ag1[8];

char op[8];

char ag2[8];

}quad[20];

 (2) char *newtemp()

该函数回送一个新的临时变量名,临时变量名产生的顺序为T1T2,…

char *newtemp(void)

{     char *p;

             char  m[8];

             p=(char *)malloc(8);

              k++;

             itoa(k,m,10);

             strcpy(p+1,m);

             p[0]=’t’;

             return(p);

}

2、函数lrparser 在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。

1)源程序代码:

#include<stdio.h>

#include<string.h>

#include<iostream.h>

#include<stdlib.h>

 

struct

{

       char result[12];

       char ag1[12];

       char op[12];

       char ag2[12];

}quad;

 

char prog[80],token[12];

char ch;

int syn,p,m=0,n,sum=0,kk;    //p是缓冲区prog的指针,mtoken的指针

char *rwtab[6]={"begin","if","then","while","do","end"};

void scaner();

char *factor(void);

char *term(void);

char *expression_r(void);

int yucu();

void emit(char *result,char *ag1,char *op,char *ag2);

char *newtemp();

int statement();

int k=0;

 

void emit(char *result,char *ag1,char *op,char *ag2)

{

       strcpy(quad.result,result);

       strcpy(quad.ag1,ag1);

    strcpy(quad.op,op);

       strcpy(quad.ag2,ag2);

             

    cout<<quad.result<<"="<<quad.ag1<<quad.op<<quad.ag2<<endl;

}

 

char *newtemp()

{

       char *p;

       char m[12];

       p=(char *)malloc(12);

       k++;

       itoa(k,m,10);

       strcpy(p+1,m);

       p[0]='t';

       return (p);

}

 

void scaner()

{

       for(n=0;n<8;n++) token[n]=NULL;

       ch=prog[p++];

       while(ch==' ')

       {

              ch=prog[p];

              p++;

       }

       if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))

       {

              m=0;

              while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))

              {

                     token[m++]=ch;

                     ch=prog[p++];

              }

              token[m++]='\0';

              p--;

              syn=10;

              for(n=0;n<6;n++)

                     if(strcmp(token,rwtab[n])==0)

                     {

                            syn=n+1;

                            break;

                     }

       }

       else if((ch>='0'&&ch<='9'))

       {

              {

                     sum=0;

                     while((ch>='0'&&ch<='9'))

                     {

                            sum=sum*10+ch-'0';

                            ch=prog[p++];

                     }

              }

              p--;

              syn=11;

              if(sum>32767)

                     syn=-1;

       }

       else switch(ch)

       {

case'<':m=0;token[m++]=ch;

       ch=prog[p++];

       if(ch=='>')

       {

              syn=21;

              token[m++]=ch;

       }

       else if(ch=='=')

       {

              syn=22;

              token[m++]=ch;

       }

       else

       {

              syn=23;

              p--;

       }

       break;

case'>':m=0;token[m++]=ch;

       ch=prog[p++];

       if(ch=='=')

       {

              syn=24;

              token[m++]=ch;

       }

       else

       {

              syn=20;

              p--;

       }

       break;

case':':m=0;token[m++]=ch;

       ch=prog[p++];

       if(ch=='=')

       {

              syn=18;

              token[m++]=ch;

       }

       else

       {

              syn=17;

              p--;

       }

       break;

case'*':syn=13;token[0]=ch;break;

case'/':syn=14;token[0]=ch;break;

case'+':syn=15;token[0]=ch;break;

case'-':syn=16;token[0]=ch;break;

case'=':syn=25;token[0]=ch;break;

case';':syn=26;token[0]=ch;break;

case'(':syn=27;token[0]=ch;break;

case')':syn=28;token[0]=ch;break;

case'#':syn=0;token[0]=ch;break;

default: syn=-1;break;

       }

}

 

int lrparser()

{//cout<<"调用lrparser"<<endl;

       int schain=0;

    kk=0;

    if(syn==1)

       { 

              scaner();

        schain=yucu();

        if(syn==6)

              {        

                     scaner();

            if(syn==0 && (kk==0))

               cout<<"success!"<<endl;

              }

 

        else

              {

                     if(kk!=1)

                            cout<<"end!"<<endl;

kk=1;

              }

       }

   else

   {cout<<"begin!"<<endl;kk=1;}

 

  return(schain);

}

 

int yucu()

{//   cout<<"调用yucu"<<endl;

       int schain=0;

    schain=statement();

    while(syn==26)

       {

              scaner();

        schain=statement();

       }

  return(schain);

}

 

int statement()

{//cout<<"调用statement"<<endl;

       char *eplace,*tt;

    eplace=(char *)malloc(12);

    tt=(char *)malloc(12);

    int schain=0;

       switch(syn)

       {

       case 10:

              strcpy(tt,token);

              scaner();

              if(syn==18)

              {

                     scaner();

                     strcpy(eplace,expression_r());

                     emit(tt,eplace,"","");

                     schain=0;

              }

              else

              {

                     cout<<"缺少赋值符!"<<endl;

                     kk=1;

              }

              return(schain);

              break;

       }

       return(schain);

}

 

char *expression_r(void)

{

       char *tp,*ep2,*eplace,*tt;

       tp=(char *)malloc(12);

       ep2=(char *)malloc(12);

       eplace=(char *)malloc(12);

       tt =(char *)malloc(12);

       strcpy(eplace,term ());          //调用term分析产生表达式计算的第一项eplace

      

       while((syn==15)||(syn==16))

       {

              if(syn==15)strcpy(tt,"+");

              else strcpy(tt,"-");

              scaner();

              strcpy(ep2,term());        //调用term分析产生表达式计算的第二项ep2

              strcpy(tp,newtemp());    //调用newtemp产生临时变量tp存储计算结果

              emit(tp,eplace,tt,ep2);    //生成四元式送入四元式表

              strcpy(eplace,tp);

       }

       return(eplace);

}

 

char *term(void)

{//   cout<<"调用term"<<endl;

       char *tp,*ep2,*eplace,*tt;

       tp=(char *)malloc(12);

       ep2=(char *)malloc(12);

       eplace=(char *)malloc(12);

       tt=(char *)malloc(12);

       strcpy(eplace,factor());

 

       while((syn==13)||(syn==14))

       {

              if(syn==13)strcpy(tt,"*");

              else strcpy(tt,"/");

              scaner();

              strcpy(ep2,factor());      //调用factor分析产生表达式计算的第二项ep2

              strcpy(tp,newtemp());    //调用newtemp产生临时变量tp存储计算结果

              emit(tp,eplace,tt,ep2);    //生成四元式送入四元式表

              strcpy(eplace,tp);

       }

       return(eplace);

}

 

char *factor(void)

{

       char *fplace;

       fplace=(char *)malloc(12);

       strcpy(fplace,"");

       if(syn==10)

       {

              strcpy(fplace,token);             //将标识符token的值赋给fplace

              scaner();

       }

       else if(syn==11)

       {

              itoa(sum,fplace,10);

              scaner();

       }

       else if(syn==27)

       {

              scaner();

              fplace=expression_r();             //调用expression分析返回表达式的值

              if(syn==28)

                     scaner();

              else

              {

                     cout<<")错误!"<<endl;

                     kk=1;

              }

       }

       else

       {

              cout<<"(错误!"<<endl;

              kk=1;

       }

       return(fplace);

}

 

void main()

{

       p=0;

       cout<<"**********语义分析程序**********"<<endl;

       cout<<"Please input string:"<<endl;

       do

       {

              cin.get(ch);

              prog[p++]=ch;

       }

       while(ch!='#');

       p=0;

       scaner();

       lrparser();

}

(2)结果验证:

(a)给定源程序

begin  a:=2+3*4;  x:=(a+b)/c  end#

输出结果

(b)源程序

begin  a:=9;  x:=2*3-1;  b:=(a+x)/2  end#


输出结果

posted @ 2017-05-31 14:43  天涯海角路  阅读(3292)  评论(0)    收藏  举报