【编译原理】中间代码生成的实现(实验报告+C/C++源程序)

JuneInDec 2024-07-01 14:35:12 阅读 50

一、实验目的

        通过设计、开发一个高级语言的中间代码生成程序,加深对相关课堂教学内容,包括语法制导翻译技术、类型确定、类型检查、常见可执行语句(如赋值语句)翻译技术的理解。

二、实验要求

        编写一个中间代码生成程序。

        要求输出四元式。

三、实验设备与环境

1.硬件:处理器:12th Gen Intel(R) Core(TM) i5-12500H(16 CPUs),~2.5GHZ

2.软件:dev c++

四、实验内容

五、实验步骤

        语法制导翻译的基本思想:为每个产生式配上一个语义子程序,(该子程序描述了一个产生式所对应的翻译工 作。这些工作包括:生成中间代码,查填有关的符号表,检查和报错,修改编译程序某些工作变量的值等)。在语法分析过程中,每当一个产生式用于推导(自顶向下分析)或归约(自底向上分析)时,就调用该产生式所对应的语义子程序,以完成既定的翻译任务。

        具体步骤

        首先输入表达式,进行词法分析,把词法分析的结果存在字符数组中,之后调用递归下降分析器中的表达式子程序进行分析,最后得到四元组并输出,最后判断程序的输入是否结束,如果没有结束,就再次输入表达式,重复上述步骤,如果结束,则程序退出。

        bool isAlpha(char s)  //判断扫描字符是否为字母

        string scan()  //扫描读取字符

        string F()  //文法F的调用程序

        string T()  //文法T的调用程序

        string E()  //文法E的调用程序

        void S()  //文法开始S的入口入口程序

        int main()  //主函数

六、实验结果及分析

测试一:  

测试二:  

测试三:

        先读取表达式,采用递归下降分析法进行分析,对输入字符进行移进、归约,产生四元式。对于测试一,读取表达式,依次调用函数S、E、T、F、E、T、F,再回退到E,产生四元式“+”操作,再依次调用...最后得到四元式序列。

        一组数据具有偶然性,测试多组数据,来保证程序的可用性,发现分析都较为准确。

七、实验小结和思考

        本次实验我学会了如何将语法分析器与词法分析器相结合设计出生成目标代码的过程,加深了对语法制导翻译技术、常见可执行语句(如赋值语句)翻译技术的理解。

        编写代码的时候,需要用到词法分析器和语法分析器的编写方法,用词法分析器的编写思想来读取表达式,用语法分析器的编写思想来进行递归调用,最后在特殊位置输出四元式结果。

        通过这次实验,从词法分析到语法分析到语义分析的知识点有了串联的整合,重点回顾了不同阶段的作用以及相关性。但还需要进一步优化自己的代码,改进指针移动位置,减少冗余代码,使代码变得简洁,提高执行效率。

八、源程序清单

#include<iostream>

#include<string>

using namespace std;

string s;

int i,j=1; //i指向当前语句的位置,j表示当前表达式序号

string E();

bool isAlpha(char s){ //判断扫描字符是否为字母

if((s>='a'&&s<='z')||(s>='A'&&s<='Z')) return true;

else return false;

}

string scan(){ //扫描读取字符

char token[50];

int tem=0;

if(isAlpha(s[i])){

while(isAlpha(s[i])){

token[tem++]=s[i++];

}

token[tem]='\0';

}

return token;

}

string F(){ //文法F的调用程序

if(s[i]=='-'){

i++;

string t1=F();

cout<<"(-,"<<t1<<",-,T"<<j<<")"<<endl;

string j1=to_string(j);

string t='T'+j1;

j++;

return t;

}

else if(s[i]=='('){

i++;

string t=E();

i++;

return t;

}

else {

string I3=scan();

return I3;

}

}

string T(){ //文法T的调用程序

string t1=F();

string t=t1;

if(s[i]=='*'){

i++;

string t2=F();

cout<<"(*,"<<t1<<","<<t2<<",T"<<j<<")"<<endl;

string j1=to_string(j);

string t='T'+j1;

return t;

}

return t;

}

string E(){ //文法E的调用程序

string t1=T();

string t=t1;

if(s[i]=='+'){

i++;

string t2=scan();

cout<<"(+,"<<t1<<","<<t2<<",T"<<j<<")"<<endl;

string j1=to_string(j);

string t='T'+j1;

j++;

return t;

}

return t;

}

void S(){ /文法开始S的入口入口程序

string t=scan();

i+=2;

string t1=E();

cout<<"(:=,"<<t1<<",-,"<<t<<")"<<endl;

}

int main(){

cout<<"请输入赋值语句:";

cin>>s;

cout<<"四元式序列为:"<<endl;

S();

return 0;

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。