编译原理语义分析实验报告

时间:2024.4.8

实验3  语义分析实验报告

一、      实验目的

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

二、      实验要求

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

三、      算法思想

1、设置语义过程。

(1)emit(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()

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

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 在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。

四、        源程序代码:

#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的指针,m是token的指针

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

void scaner();

char *factor(void);

char *term(void);

char *expression(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());

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

                     schain=0;

              }

              else

              {

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

                     kk=1;

              }

              return(schain);

              break;

       }

       return(schain);

}

char *expression(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();             //调用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();

}

五、        结果验证

1、给定源程序

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

输出结果

2、 源程序

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


输出结果

六、      收获(体会)与建议

通过此次实验,让我了解到如何设计、编制并调试语义分析程序,加深了对语法制导翻译原理的理解,掌握了将语法分析所识别的语法成分变换为中间代码的语义翻译方法。


第二篇:编译原理实验报告模版-语义分析


编译原理课程实验报告

实验3:语义分析

更多相关推荐:
编译原理语义分析实验报告 免费

编译原理综合训练语义分析实验报告指导老师班级学生zeadom学号学生学号20xx629目录语言文法的形式化描述3语义规则3运行环境介绍5关键算法的流程图及文字解释51本编译器的总框架52在语义分析中的主要函数介...

北邮 编译原理 语义分析实验报告

编译原理第六章语义分析目录1234实验题目和要求2实验分析和思考3翻译方案4LR实现自底向上分析摘自语法分析实验541构造识别所有活前缀的DFA542构造LR分析表65S属性定义的自底向上实现751扩充分析栈7...

编译原理 语义分析

编译原理实验报告姓名闫梦丽班级软件工程学号日期语义分析器0901090801010120xx年4月1题目要求11实验目的通过上机实习加深对语法制导翻译原理的理解掌握将语法分析所识别的语法成分变换为中间代码的语义...

编译原理语义分析实验报告——免费!

语义分析实验报告一实验目的通过上机实习加深对语法制导翻译原理的理解掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法二实验要求采用递归下降语法制导翻译法对算术表达式赋值语句进行语义分析并生成四元式序列三...

实验三报告:编译原理语义分析

编译原理实验词义分析指导老师学生学号班级时间20xx541文件构成2代码中宏函数变量宏定义函数变量3简易流程图参见图片函数调用图副本bmp4实验结果使用的源代码生成的词最终代码分析5改进增加注释来表明生成经历的...

语义分析实验报告(实验三)

编译原理语义分析实验报告软工082班兰洁20xx31104044一实验内容二实验目的三实验要求四程序流程图五程序代码与主要过程说明六测试用例七输出结果八实验心得一实验内容定义模拟的简单语言的语义成分将语义分析程...

编译原理_ 语义分析_实验报告

编译原理实验三语义分析实验报告学院数学与计算机科学技术学院专业计算机科学与技术班级级计算机班小组组员姓名姓名学号姓名学号姓名学号编译原理实验三语义分析实验题目一实验目的要求学生用与实验2相同的语言编制语义分析程...

编译原理实验报告模版-语义分析

编译原理课程实验报告实验3语义分析

编译原理实验报告

南华大学计算机科学与技术学院实验报告20xx20xx学年度第二学期课程名称编译原理词法分析语法分析语义分课程设计析以及中间代码的生成姓名胡艳霞学号20xx4440238专业计算机班级计算机092班地点8212教...

北邮编译原理LR语法分析程序实验报告

LR语法分析程序实验报告说明该程序使用实现对算术表达式自底向上的语法分析并且在对输入表达式进行分析的过程中输出分析动作移进或者用哪个产生式进行规约该程序使用的是LR语法分析程序手动构造了识别所有活前缀的DFA为...

编译原理词法分析器语法分析器实验报告

编译技术课程设计班级学号姓名指导老师二零一零年七月一目的ltlt编译技术gtgt是理论与实践并重的课程而其实验课要综合运用一二年级所学的多门课程的内容用来完成一个小型编译程序从而巩固和加强对词法分析语法分析语义...

编译原理语法分析实验报告

实验二语法分析实验报告一实验内容11实验目的编制一个递归下降分析程序实现对词法分析程序所提供的单词序列的语法检查和结构分析12实验要求利用C语言编制递归下降分析程序并对简单语言进行语法分析121待分析的简单语言...

编译原理语义分析实验报告(22篇)