《编译原理》课程实验报告

 

 

 

 

               实验名称:语义分析

 

 

 

 

 

 

 

 

姓名:                

学号:         

地点:      四教302       

教师:             

院系:

专业: 计算机科学与技术15-1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                                                           

一.  实验目的

 

通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。

 

二.  实验内容

 

采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。

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

输出:(1)t1=3*4   (2)t2=2+t1  (3)a=t2

      (4)t3=a+b  (5)t4=t3/c     (6) x=t4

 

三.实验步骤


语义分析主程序示意图

 







代码如下:


#include "stdio.h"

#include "string.h"

#include "stdlib.h"

char prog[100],token[8],ch;

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

int syn,p,m,n,sum,q;

int kk;

struct { char result1[8];

    char ag11[8];

    char op1[8];

    char ag21[8];

} quad[20];

char *factor();

char *expression();

int yucu();

char *term();

int statement();

int lrparser();

char *newtemp();

scaner();

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

main()

{ int j;

q=p=kk=0;

 printf("院系:计算机与通信工程学院\n");

    printf("班级:计算机科学与技术15-01\n");

    printf("姓名:汪笛\n");

    printf("学号:541507010139\n");

 

printf("\nplease input a string (end with '#'): ");

do

   {scanf("%c",&ch);

     prog[p++]=ch;

   }while(ch!='#');

p=0;

scaner();

lrparser();

if(q>19)printf(" to long sentense!\n");

else for (j=0;j<q;j++)printf("   %s = %s %s %s\n\n",quad[j].result1,quad[j].ag11,quad[j].op1,quad[j].ag21);

//getch();

}

 

 

int lrparser()

{ int schain=0;

    kk=0;

    if (syn==1)

      { scaner();

schain=yucu();/*调用语句串分析函数进行分析*/

if(syn==6)

{ scaner();

   if((syn==0)&&(kk==0)) printf("Success!\n");

}

else { if(kk!=1)printf("short of 'end' !\n");

        kk=1;

//        getch();

        exit(0);

      }

      }

    else { printf("shortof 'begin' !\n");

    kk=1;

//    getch();

    exit(0);

}

    return (schain);

}

int yucu()

{ int schain=0;

schain=statement();/*调用语句分析函数进行分析*/

while(syn==26)

   { scaner();

     schain=statement();/*调用语句分析函数进行分析*/

   }

return (schain);

}

int statement()

{ char tt[8],eplace[8];

int schain=0;

if (syn==10)

   { strcpy(tt,token);

     scaner();

     if(syn==18)

       { scaner();

strcpy(eplace,expression());

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

schain=0;

}

     else { printf("shortof sign ':=' !\n");

     kk=1;

//   getch();

     exit(0);

    }

    return (schain);

   }

}

char *expression()

{ 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==13)||(syn==14))

   { if(syn==13)strcpy(tt,"+");

     elsestrcpy(tt,"-");

     scaner();

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

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

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

     strcpy(eplace,tp);

   }

return (eplace);

}

char *term()/*仿照函数expression编写*/

{ 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==15)||(syn==16))

   { if(syn==15)strcpy(tt,"*");

     elsestrcpy(tt,"/");

     scaner();

     strcpy(ep2,factor());

     strcpy(tp,newtemp());

     emit(tp,eplace,tt,ep2);

     strcpy(eplace,tp);

   }

return (eplace);

}

char *factor()

{ 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();/*调用expression分析返回表达式的值*/

     if(syn==28) scaner();

     else { printf("erroron ')' !\n");

     kk=1;

//   getch();

     exit(0);

   }

   }

else { printf("error on '(' !\n");

kk=1;

// getch();

exit(0);

       }

return (fplace);

}

char *newtemp()

{ char *p;

char m[8];

p=(char *)malloc(8);

kk++;

itoa(kk,m,10);

strcpy(p+1,m);

p[0]='t';

return(p);

}

scaner()

{ sum=0;

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

    m=0;

    ch=prog[p++];

    while(ch=='')ch=prog[p++];

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

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

   {token[m++]=ch;

    ch=prog[p++];

   }

      p--;

      syn=10;

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

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

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

    { syn=n+1;

      break;

    }

      }

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

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

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

   ch=prog[p++];

}

p--;

syn=11;

      }

    else switch(ch)

       { case '<':m=0;

    ch=prog[p++];

    if(ch=='>')

      { syn=21;

      }

    else if(ch=='=')

      { syn=22;

      }

    else

      { syn=20;

         p--;

      }

    break;

case '>':m=0;

    ch=prog[p++];

    if(ch=='=')

      { syn=24;

      }

    else

      { syn=23;

        p--;

      }

    break;

case ':':m=0;

    ch=prog[p++];

    if(ch=='=')

      { syn=18; }

    else

      { syn=17;

        p--;

      }

    break;

case '+': syn=13; break;

case '-': syn=14; break;

case '*': syn=15;break;

case '/': syn=16;break;

case '(': syn=27;break;

case ')': syn=28;break;

case '=': syn=25;break;

case ';': syn=26;break;

case '#': syn=0;break;

default: syn=-1;break;

       }

    }

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

{

strcpy(quad[q].result1,result);

strcpy(quad[q].ag11,ag1);

strcpy(quad[q].op1,op);

strcpy(quad[q].ag21,ag2);

q++;

}

 

输出结果为:


 

 

 

 

 

 

四.总结与回顾

 

本次实验做的是语法分析子程序,采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。实现的过程也是不断的在网上查找资料,并将合适的下载下来进行参考。实现的过程也是理解的过程,不断完善才可以不断加强理解。

 













实验报告成绩评定表

评定项目

内           容

满 分

评  分

总  分

实验态度

态度端正、遵守纪律、出勤情况

20

 

 

实验过程

按要求完成算法设计、代码书写、注释清晰、运行结果正确

40

 

报告撰写

报告书写规范、内容条理清楚、表达准确规范、上交及时。

40

 

评语:












 指导老师签字:                     年    月   日