编译方法实验报告(中间代码生成器的设计)
中间代码生成实验报告doc
中间代码生成实验报告篇一:编译方法实验报告(中间代码生成器)编译方法实验报告XX年10月一、实验目的熟悉算术表达式的语法分析与中间代码生成原理。
实验内容二、(1)设计语法制导翻译生成表达式的四元式的算法;(2)编写代码并上机调试运行通过。
输入——算术表达式;输出——语法分析结果;相应的四元式序列。
(3)设计LL(1)分析法或LR(0)分析法的属性翻译文法,并根据这些属性翻译文法,使用扩展的语法分析器实现语法制导翻译。
三、实验原理及基本步骤●算术表达式文法:G(E):E ? E ω0 T | TT ? T ω1 F | FF ? i | (E)●文法变换:G’(E) E ? T {ω0 T(本文来自:小草范文网:中间代码生成实验报告)}T ? F {ω1 F}F ? i | (E)●属性翻译文法:E ? T {ω0 “push(SYN, w)” T “QUAT”}T ? F {ω1 “push(SYN, w)” F “QUAT”}F ? i “push(SEM, entry(w))” | (E)其中:push(SYN, w) —当前单词w入算符栈SYN;push(SEM, entry(w)) —当前w在符号表中的入口值压入语义栈SEM;QUAT —生成四元式函数i.T = newtemp;ii.QT[j] =( SYN[k], SEM[s-1], SEM[s], T); j++;iii.pop( SYN, _ ); pop( SEM, _ ); pop( SEM, _ );push( SEM, T );●递归下降子程序:数据结构:SYN —算符栈;SEM —语义栈;四、数据结构设计使用递归的结构进行四元式的设计,同时,运用堆栈结构将四元式的输出序列打印出来while ( exp[i]=='+' || exp[i]=='-'){syn[++i_syn]=exp[i];//push(SYN,w)i++; //read(w)T();quat();}while ( exp[i]=='*' || exp[i]=='/'){syn[++i_syn]=exp[i];//push(SYN,w)i++; //read(w)F();quat();}void quat(){strcpy(qt[j],"(, , , )");//QT[j]:=(SYN[k],SEM[s-1],SEM[s],temp);qt[j][1]=syn[i_syn];qt[j][3]=sem[i_sem-1];qt[j][5]=sem[i_sem];qt[j][7]=temp;j++;i_syn--;//pop(SYN);i_sem--;//pop(SEM);i_sem--;//pop(SEM);sem[++i_sem]=temp; //push(SEM,temp); temp++;}五、关键代码分析(带注释)及运行结果#include#include "string.h"#include "stdio.h"using namespace std;char syn[10]; //文法符号栈int i_syn;char sem[10]; //运算对象栈int i_sem;char exp[50]; //算术表达式区int i;char qt[30][15];//四元式区int j=0;char temp='q'; //临时变量,取值为r--z int E();int T();int F();void quat();//生成四元式函数int main(int argc, char* argv[]){printf("please input your expression:"); scanf("%s",exp); //输入四元式i=0; //read(w)E();if (exp[i]=='\0')for (i=0;i printf("%s\n",qt[i]);elseprintf("err");return 0;}int E(){T();while ( exp[i]=='+' || exp[i]=='-'){syn[++i_syn]=exp[i];//push(SYN,w)i++; //read(w)T();quat();}return 1;}int T(){F();while ( exp[i]=='*' || exp[i]=='/'){syn[++i_syn]=exp[i];//push(SYN,w)i++; //read(w)F();quat();}return 1;}int F(){if ( exp[i]=='('){i++; //read(w)E();if ( exp[i]!=')'){printf("err");return 0;}}else if ((exp[i]>='a' && exp[i]='0' && exp[i] sem[++i_sem]=exp[i]; } //push(SEM,w)else{printf("err");return 0;}i++; //read(w)return 1;}void quat(){strcpy(qt[j],"( , , , )");//QT[j]:=(SYN[k],SEM[s-1] ,SEM[s],temp);qt[j][1]=syn[i_syn];qt[j][3]=sem[i_sem-1];qt[j][5]=sem[i_sem];qt[j][7]=temp;j++;i_syn--; //pop(SYN);i_sem--; //pop(SEM);i_sem--; //pop(SEM);sem[++i_sem]=temp;//push(SEM,temp);temp++;}篇二:中间代码生成实验报告一、实验目的通过在实验二的基础上,增加中间代码生成部分,使程序能够对实验二中的识别出的赋值语句,if语句和while语句进行语义分析,生成四元式中间代码。
编译原理实验报告
编译原理实验报告编译原理实验报告一、实验目的1. 了解编译器的基本原理和工作过程;2. 掌握编译器设计和实现的基本方法和技巧;3. 通过设计和实现一个简单的编译器,加深对编程语言和计算机系统的理解和认识。
二、实验原理编译器是将高级语言程序翻译成机器语言程序的一种软件工具。
它由编译程序、汇编程序、链接程序等几个阶段组成。
本次实验主要涉及到的是编译程序的设计和实现。
编译程序的基本原理是将高级语言程序转换为中间代码,再将中间代码转换为目标代码。
整个过程可以分为词法分析、语法分析、语义分析、代码生成和代码优化几个阶段。
三、实验内容本次实验的设计目标是实现一个简单的四则运算表达式的编译器。
1. 词法分析根据规定的语法规则,编写正则表达式将输入的字符串进行词法分析,将输入的四则运算表达式划分成若干个单词(Token),例如:运算符、操作数等。
2. 语法分析根据定义的语法规则,编写语法分析程序,将词法分析得到的Token序列还原成语法结构,构建抽象语法树(AST)。
3. 语义分析对AST进行遍历,进行语义分析,判断表达式是否符合语法规则,检查语义错误并给出相应的提示。
4. 代码生成根据AST生成目标代码,目标代码可以是汇编代码或者机器码。
四、实验过程和结果1. 首先,根据输入的表达式,进行词法分析。
根据所定义的正则表达式,将输入的字符串划分成Token序列。
例如:输入表达式“2+3”,经过词法分析得到的Token序列为["2", "+", "3"]。
2. 然后,根据语法规则,进行语法分析。
根据输入的Token序列,构建抽象语法树。
3. 接着,对抽象语法树进行语义分析。
检查表达式是否符合语法规则,给出相应的提示。
4. 最后,根据抽象语法树生成目标代码。
根据目标代码的要求,生成汇编代码或者机器码。
五、实验总结通过本次实验,我对编译器的工作原理有了更深入的认识,掌握了编译器设计和实现的基本方法和技巧。
编译原理中间代码生成实验报告
竭诚为您提供优质文档/双击可除编译原理中间代码生成实验报告篇一:编译原理-分析中间代码生成程序实验报告课程名称编译原理实验学期至学年第学期学生所在系部年级专业班级学生姓名学号任课教师实验成绩计算机学院制开课实验室:年月日篇二:编译原理实验中间代码生成实验四中间代码生成一.实验目的:掌握中间代码的四种形式(逆波兰式、语法树、三元式、四元式)。
二.实验内容:1、逆波兰式定义:将运算对象写在前面,而把运算符号写在后面。
用这种表示法表示的表达式也称做后缀式。
2、抽象(语法)树:运算对象作为叶子结点,运算符作为内部结点。
3、三元式:形式序号:(op,arg1,arg2)4、四元式:形式(op,arg1,arg2,result)三、以逆波兰式为例的实验设计思想及算法(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。
如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。
(5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
四、程序代码://这是一个由中缀式生成后缀式的程序#include#include#include#include#definemaxbuffer64voidmain(){chardisplay_out(charout_ch[maxbuffer],charch[32]);//intcaculate_array(charout_ch[32]);staticinti=0;staticintj=0;charch[maxbuffer],s[maxbuffer],out[maxbuffer];cout cin>>ch;for(i=0;i {out[i]=ch[i];}cout while(out[j]!=#)cout j++;}cout display_out(s,out);//caculate_array;}chardisplay_out(charout_ch[32],charch[]) {inttop=-1;inti=0,data[maxbuffer],n;intj=0;charsta[20];while(ch[i]!=#){if(isalnum(ch[i])){while(isalnum(ch[i])){out_ch[j]=ch[i];j++;i++;}out_ch[j]=;j++;else{switch(ch[i]){case+:case-:if(sta[top]==(||top==-1) {top++;sta[top]=ch[i];i++;}else{//j--;out_ch[j]=sta[top];j++;top--;//i++;}break;//break;case*:case/:if(sta[top]==*/) {out_ch[j]=sta[top];j++;//i++;top--;}else{top++;sta[top]=ch[i];i++;}break;//break;case(:top++;sta[top]=ch[i];i++;break;case):if(sta[top]==() {top--;i++;}if(top==-1){//cout }else{//while(sta[top]!=?(?){ out_ch[j]=sta[top];top--;j++;//}break;}break;/*case?#?:out_ch[j]=?#?; j++;break;*/default:cout ch[i]=#;j=0;break;}}}while(top!=-1){out_ch[j]=sta[top];j++;top--;}out_ch[j]=#;n=0;co(:编译原理中间代码生成实验报告)utwhile(out_ch[n]!=#){cout n++;}cout j=0;returnout_ch[maxbuffer];}五、实验结果:要求:自己给出3个测试用例,观察结果。
编译器_实验报告
一、实验目的1. 理解编译器的基本原理和设计方法。
2. 掌握编译器各个阶段的功能和实现方法。
3. 通过实际编程,加深对编译器原理的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:C/C++3. 开发工具:Visual Studio 2019三、实验内容本次实验主要完成一个简单的编译器,该编译器包含词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等阶段。
四、实验步骤1. 词法分析:- 定义单词类型,如标识符、关键字、运算符、常数等。
- 实现词法分析器,读取源代码,将其分解为一个个单词。
2. 语法分析:- 定义语法规则,构建语法分析器。
- 实现语法分析器,对单词序列进行语法分析,生成抽象语法树(AST)。
3. 语义分析:- 遍历AST,进行语义检查,如类型检查、作用域检查等。
- 生成中间代码,如三地址代码。
4. 代码优化:- 对中间代码进行优化,提高代码执行效率。
- 优化策略包括:常数折叠、循环优化、死代码消除等。
5. 目标代码生成:- 将优化后的中间代码转换为机器代码。
- 生成目标程序,如汇编代码。
五、实验结果1. 词法分析:- 成功识别出标识符、关键字、运算符、常数等单词类型。
- 输出单词序列,供语法分析器使用。
2. 语法分析:- 成功生成抽象语法树(AST)。
- AST结构清晰,便于后续处理。
3. 语义分析:- 成功进行语义检查,如类型检查、作用域检查等。
- 生成中间代码,供代码优化和目标代码生成使用。
4. 代码优化:- 对中间代码进行优化,提高代码执行效率。
- 优化效果明显,如减少了循环的次数、消除了死代码等。
5. 目标代码生成:- 成功生成汇编代码。
- 汇编代码结构清晰,便于后续翻译成机器代码。
六、实验总结1. 通过本次实验,我们深入了解了编译器的基本原理和设计方法。
2. 实验过程中,我们掌握了编译器各个阶段的功能和实现方法。
3. 实验成果表明,所编写的编译器能够对源代码进行词法分析、语法分析、语义分析、代码优化和目标代码生成等处理。
编译实习报告
编译实习报告一、实习背景随着计算机技术的不断发展,编译技术在软件开发和计算机科学领域中起着至关重要的作用。
为了更好地了解编译原理在实际应用中的具体实现,提高自己的实际动手能力,我参加了为期三个月的编译实习项目。
在实习期间,我深入学习了编译原理的基本知识,并参与了编译器的开发与优化过程。
二、实习内容1. 编译原理学习在实习的第一阶段,我系统地学习了编译原理的基本知识,包括文法、语法分析、中间代码生成、代码优化和目标代码生成等。
通过学习,我掌握了编译器的基本组成部分及其工作原理,为后续的实践操作打下了坚实的基础。
2. 编译器开发在实习的第二阶段,我参与了编译器的开发过程。
首先,我使用C语言编写了一个简单的编译器前端,实现了源代码的词法分析和语法分析。
在此基础上,我进一步实现了中间代码的生成和代码优化模块。
最后,我完成了目标代码的生成和运行。
整个过程中,我深刻体会到了编译原理在实际应用中的重要性。
3. 编译器优化在实习的第三阶段,我主要负责编译器的优化工作。
通过对中间代码的分析和调整,我实现了常数折叠、死代码消除和循环优化等优化策略。
经过优化,编译器生成的目标代码在运行效率和内存占用方面都有了显著的提升。
三、实习收获1. 知识运用通过实习,我将所学的编译原理知识运用到了实际项目中,提高了自己的实际动手能力。
同时,实习过程中遇到的问题也促使我不断深入学习相关知识,提高了自己的理论水平。
2. 团队协作在实习过程中,我与团队成员密切配合,共同解决问题。
这使我更加明白了团队协作的重要性,也锻炼了我的沟通与协作能力。
3. 工程实践实习过程中,我独立完成了编译器的开发与优化任务,掌握了工程实践的基本方法。
这对我今后从事软件开发工作具有很大的帮助。
四、实习总结通过这次编译实习,我对编译原理有了更深入的了解,并在实际项目中积累了宝贵的经验。
同时,实习过程中的挑战和困难也让我明白了自身存在的不足,为我今后的学习和工作指明了方向。
(精品)编译方法实验报告(中间代码生成器的设计)
编译方法实验报告
2011年10月
一、实验目的
熟悉算术表达式的语法分析与中间代码生成原理。
二、实验内容
(1)设计语法制导翻译生成表达式的四元式的算法;
(2)编写代码并上机调试运行通过。
输入——算术表达式;
输出——语法分析结果;
相应的四元式序列。
(3)设计LL(1)分析法或LR(0)分析法的属性翻译文法,并根据这些属性翻译文法,使用扩展的语法分析器实现语法制导翻译。
三、实验原理及基本步骤
●算术表达式文法:
G(E): E →E ω0 T | T
T →T ω1 F | F
F → i | (E)
●文法变换:
G’(E) E →T {ω0 T}
T →F {ω1 F}
F → i | (E)
●属性翻译文法:
E →T {ω0“push(SYN,w)” T “QUAT”}
T →F {ω1“push(SYN, w)” F “QUAT”}
F →i “push(SEM, entry(w))” | (E)
其中:
push(SYN, w) —当前单词w入算符栈SYN;
push(SEM, entry(w)) —当前w在符号表中的入口值压入语义栈SEM;
QUAT —生成四元式函数
i.T = newtemp;
ii.QT[j] =( SYN[k], SEM[s-1], SEM[s], T); j++;
iii.pop( SYN, _ ); pop( SEM, _ ); pop( SEM, _ );
push( SEM, T );
●递归下降子程序:
数据结构:SYN —算符栈;
SEM —语义栈;。
编译原理教程实验报告
一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。
二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。
2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。
3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。
4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。
5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。
6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。
四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。
2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。
3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。
4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。
5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。
6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。
五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。
编译课设报告--pl0编译器的中间代码生成 2
课程设计报告( —年度第一学期)名称:编译技术课程设计题目:PL/0语言编译器的中间代码生成院系:班级:学号:学生姓名:指导教师:设计周数:一周成绩:日期:年月日1 课程设计的目的和要求1.1 课程设计的目的本次设计的时间为1周,目的是通过使用高级语言实现部分算法加强对编译技术和理论的理解。
设计的题目要求具有一定的规模,应涵盖本课程内容和实际应用相关的主要技术,同时使大家将理论与实际应用结合起来,受到软件设计等开发过程的全面训练,从而提高软件开发的能力。
1.2 课程设计的要求1、要求用递归子程序法/或预测分析法实现对表达式、各种说明语句、控制语句进行语法分析。
2、若语法正确,则用语法制导翻译法进行语义翻译:对说明语句,要求将说明的各符号记录到相应符号表中;对可执行语句,应产生出四元式中间代码并填写到三地址码表中;3、若语法错误,要求指出出错性质和出错位置(行号)。
出错处理应设计成一个出错处理子程序。
2 系统描述PL/0的编译程序和目标程序的解释执行程序都是用JA V A语言书写的,因此PL/0语言可在配备JA V A语言的任何机器上实现。
本次课设开发平台即为JA V A。
用递归子程序法实现了对表达式、各种说明语句、控制语句进行语法的分析。
其中,对各个变量符号保存到了符号表中。
对可执行语句,转化成四元式中间代码进行输出。
本程序中,通过出错处理子程序,也进行了语法的错误的记录,并且输出了出错的行号和出错原因。
该程序的输入是打开test文件,通过文件输入流读入,输出有生成的中间代码、符号表内容、错误分析三部分内容,分别用java界面控件显示出来。
2.1 PL/0语言的描述PL/0语言的编译程序是一个编译解释执行系统。
PL/0的目标程序为假想栈式计算机的汇编语言,与具体计算机无关。
其编译过程采用一趟扫描方式,以语法分析类为核心,词法分析和代码生成类都作为一个独立的类,当语法分析需要读单词时就调用词法分析程序,而当语法分析正确需要生成相应的目标代码时,则调用代码生成程序。
实验五+中间代码生成器
实验5 中间代码生成器一、实验目的掌握语法制导定义和翻译的原理和技术,在语法分析器的基础上,加上语义分析,构造一个中间代码生成器。
二、实验内容在实验四用Yacc生成的语法分析器基础上加入语义动作,编写一个中间代码生成程序。
1.文法(见教材附录A.1,p394)program→ blockblock→{ decls stmts }decls →decls decl | εdecl →type id ;type →type [num] //数组可以不做| basic //四种基本数据类型int | float | char | bool stmts→stmts stmt | εstmt→id=expr;| if(bool)stmt| if( bool)stmt else stmt| while(bool)stmt| do stmt while(bool ) ;| break ;//break可以不做| blockbool →bool || join| joinjoin →join&& equality | equalityequality →equality == rel | equality != rel | relrel →expr < expr| expr <= expr| expr > expr| expr >= expr| exprexpr→ expr + term| expr - term| termterm→ term * unary| term / unary| unaryunary →!unary| - unary| factorfactor→ ( e xpr ) | id| num2.中间代码的形式见教材p221~222,若有必要,可以适当扩展(加以说明)。
三、实验过程3.1符号表的定义和相关函数struct SymbolElemstruct SymbolListSymbolList CreateSymbolList( SymbolList PrevList, int StartAddr )/*创建并返回一个新的符号表(SymbolList就是书上的Env),PrevList是其的上一层符号表*/void DestroySymbolList( SymbolList List )struct SymbolElem * LookUpSymbolList( SymbolList List, char * IdName )/*在符号表List中查找是否存在标识符IdName,如果存在,则返回该结点指针,否则返回空*/struct SymbolElem * LookUpAllSymbolList( SymbolList List, char * IdName )/*从符号表List开始并不断地往上一层符号表中查找是否存在标识符IdName,如果存在,则返回该结点指针,否则返回空*/struct SymbolElem * AddToSymbolList( SymbolList List, char * IdName,int IdType, int Width )/*创建一个新的符号结点,并添加到符号表中,而后返回该结点指针*/3.2常数表的定义和相关函数union ConstVal/*存放一个常数*/struct ConstElem/*常量表*/struct ConstList/*创建并返回常量表*/void CreateConstList( int StartAddr )void DestroyConstList( void )/*在常量表ConstList中查找是否存在常量,如果存在,则返回该结点指针,否则返回空*/struct ConstElem * LookUpConstList( int ConstType, union ConstVal ConstValue, int Width )/*创建一个新的常数结点,并添加到常数表中,而后返回该结点指针*/struct ConstElem * AddToConstList( char * Str, int ConstType, union ConstVal ConstValue, int Width )3.3四元式的定义和函数/*四元式数据结构*/struct Quadruple/*四元式表*/struct QuadTablevoid CreateQuadTable(int StartAddr)void DestroyQuadTable( void )/*当Arg1是变量或临时变量时,Arg1Name是该变量的名称,用于演示时使用,其余参数类同*/int Gen( int Op, int Arg1, int Arg2, int Arg3, char *Arg1Name, char *Arg2Name, char *Arg3Name )/*把四元式所对应的三地址代码写入到文件中*/void WriteQuadTableToFile( const char * FileName )四、实验结果源程序片断运行状态图运行结果本次实验很难,做了很久都没做出来。
编译原理综合性实验报告-分析中间代码生成程序分析
编译原理综合性实验报告-分析中间代码⽣成程序分析编译原理综合性实验报告-分析中间代码⽣成程序分析XXXXXX计算机系综合性实验实验报告课程名称编译原理实验学期 XXXX ⾄ XXXX 学年第 X 学期学⽣所在系部计算机系年级 X 专业班级 XXXXXX 学⽣姓名 XXX学号 XXXXXXXXXXXX 任课教师XXX 实验成绩计算机系制《编译原理》课程综合性实验报告开课实验室: 年⽉⽇实验题⽬分析中间代码⽣成程序⼀、实验⽬的分析PL/0编译程序的总体结构、代码⽣成的⽅法和过程;具体写出⼀条语句的中间代码⽣成过程。
⼆、设备与环境PC兼容机、Windows操作系统、Turbo Pascal软件等。
三、实验内容1. 分析PL/0程序的Block⼦程序,理清PL/0程序结构和语句格式。
画出Block⼦程序的流程图,写出⾄少两条PL/0程序语句的语法格式。
2. 分析PL/0程序的Block⼦程序和Gen⼦程序,了解代码⽣成的⽅法和过程。
使⽤概要算法来描述语句的代码⽣成过程。
3. ⾃⼰编写⼀个简单的PL/0程序,能够正确通过编译,得到中间代码。
列出⾃⼰编写的源程序和编译后得到的中间代码。
4. 从中选择⼀个语句或表达式,写出代码⽣成的过程。
要求从⾃⼰的源程序中选择⼀条语句,结合这条语句写出语义分析和代码⽣成过程。
在描述这个过程中,要说清楚每个功能有哪个⼦程序的哪条语句来完成,说清楚语句和参数的含义和功能。
四、实验结果及分析(⼀)Block⼦程序分析1.常量声明的分析:常量声明部分的语法结构定义为如下形式:-> const ;-> [;]->id = C其中C可以是常量标识符或字符串或整数(可带符号)或实数(可带符号)。
常量声明分析程序的主要任务是:(1).扫描整个常量声明部分。
(2).为被声明的常量标识符建⽴符号表项。
(3).检查重复的声明。
2.变量声明部分的分析:变量声明部分的语法结构定义为如下形式:-> var-> [;]->:T->id[,]其中idList是被定义的变量标识符序列,T是类型表达式。
实验五-编译-用语法制导方式生成中间代码生成器
实验五-编译-⽤语法制导⽅式⽣成中间代码⽣成器实验5 ⽤语法制导⽅式⽣成中间代码⽣成器⼀、实验⽬的掌握语法制导定义和翻译的原理和技术,在语法分析器的基础上,加上语义分析,构造⼀个中间代码⽣成器。
⼆、实验内容在实验四⽣成的语法分析器基础上加⼊语义动作,将源程序翻译为对应的中间代码序列。
三、实验要求1. 个⼈完成,提交实验报告。
实验报告必须包括设计的思路,以及测试报告(输⼊测试例⼦,输出结果)。
2. 实验报告中给出采⽤测试源代码⽚断,及其对应的三地址码形式(内部表⽰形式可以⾃⾏考虑)。
例如,程序⽚断对应的中间代码为:四、实验过程本次实验运⽤flex和bison⼯具进⾏中间代码的⽣成。
并⾃动⽣成中间代码。
1.⾸先创建⼀个example⽂件夹,该⽂件夹中包含有flex.exe2.⽤⽂本编译器编辑相应的flex⽂件mylex.l,此次mylex.l可以在上次实验的l⽂件上做⼀些修改,再利⽤flex将l⽂件⽣成相应的lex.yy.c程序,mylex.l 的代码如下所⽰:mylex.l%{#include "myyacc.tab.h"%}delim [ \t\n\r]ws {delim}+letter [A-Za-z]digit [0-9]id {letter}({letter}|{digit})*integer {digit}+exponent E[+-]?{integer}number {integer}{exponent}?real integer(\.integer)?{exponent}?%option noyywrap%%"<"|"<="|">"|">="|"!="|"==" { filloperator(&yylval, yytext); return( REL); }if { return( IF ); }else { return( ELSE ); }while { return( WHILE ); }do { return( DO ); }for { return( FOR ); }switch { return( SWITCH ); }case { return( CASE ); } default { return( DEFAULT ); } break { return( BREAK ); } true { return( TRUE ); }false { return( FALSE ); } int { return( INT ); }long { return( LONG ); } char { return( CHAR ); } bool { return( BOOL ); } float { return( FLOAT ); } double { return( DOUBLE ); } "&&" { return( AND ); } "||" { return( OR ); } "!" { return( '!'); }"++" { return( INC ); } "--" { return( DEC ); } "+" { return( '+' ); } "-" { return( '-' ); } "*" { return( '*' ); } "/" { return( '/' ); } "=" { return( '=' ); } "{" { return( '{' ); }"}" { return( '}' ); }"[" { return( '[' ); }"]" { return( ']' ); }"(" { return( '(' ); }")" { return( ')' ); }";" { return( ';' ); }{ws} { }{id} { filllexeme(&yylval, yytext); return( ID ); }{number} { filllexeme(&yylval, yytext); return( NUMBER ); }{real} { filllexeme(&yylval, yytext); return( REAL ); }%%在代码中,先定义正则定义,即对letter,digit,专⽤符号, 空格进⾏声明;接着在转换规则中,定义⼀些识别规则的代码。
中间代码生成实验报告
中间代码生成实验报告中间代码生成实验报告一、引言在计算机编程领域中,中间代码生成是编译器的一个重要阶段。
它将源代码转化为一种中间表示形式,以便于后续的优化和目标代码生成。
本实验旨在通过实现一个简单的中间代码生成器,深入理解编译器的工作原理和中间代码的作用。
二、实验背景中间代码是一种介于源代码和目标代码之间的表示形式。
它通常是一种抽象的、与机器无关的形式,具有较高的可读性和可维护性。
中间代码生成是编译器的一个重要阶段,它将源代码转化为中间代码,为后续的优化和目标代码生成提供基础。
三、实验目的本实验的主要目的是通过实现一个简单的中间代码生成器,加深对编译器工作原理的理解,并掌握中间代码的生成过程。
具体目标包括:1. 学习使用编程语言实现中间代码生成算法;2. 理解中间代码的数据结构和语义;3. 掌握将源代码转化为中间代码的过程;4. 分析和优化生成的中间代码。
四、实验设计与实现本实验采用C++语言实现一个简单的中间代码生成器。
具体步骤如下:1. 词法分析:使用词法分析器对输入的源代码进行扫描,将其划分为一个个的词法单元。
2. 语法分析:使用语法分析器对词法单元进行解析,构建语法树。
3. 语义分析:对语法树进行语义分析,检查语法的正确性,并生成中间代码。
4. 中间代码生成:根据语义分析的结果,生成对应的中间代码。
5. 中间代码优化:对生成的中间代码进行优化,提高执行效率和代码质量。
6. 目标代码生成:将优化后的中间代码转化为目标代码。
五、实验结果与分析经过实验,我们成功实现了一个简单的中间代码生成器,并生成了相应的中间代码。
通过对生成的中间代码进行分析,我们发现其中存在一些冗余和不必要的指令,可以进一步进行优化。
例如,可以通过常量折叠、死代码删除等技术,减少中间代码的长度和执行时间。
六、实验总结通过本次实验,我们深入理解了中间代码生成的过程和作用,并通过实践掌握了中间代码生成器的实现方法。
在实验过程中,我们遇到了一些困难和挑战,但通过不断的学习和尝试,最终取得了满意的结果。
编译原理实验三:中间代码生成
编译原理——语义分析成员:杨霞 030802107王日日 030802139方艳丽 030802102实验三:语义分析:生成中间代码一、实验目的通过语法制导或翻译模式生成中间代码。
二、实验内容在自底向上语法分析基础上设计语义规则(语法制导翻译),将源程序翻译为四元式输出.三、实验环境Windows microsoft visual c++ 6.0四.实验原理三地址码的几种常见指令:1.X=Y OP Z 的赋值指令,其中OP 是一个双目运算符或逻辑运算符。
2.X= Y 的复制指令。
3.无条件转移指令 GOTO L 把下一步要执行的带有标号L的三地址指令4.IF X GOTO L 或 IF FALSE X GOTO L的条件转移指令5.IF X RELOP Y GOTO L的条件转移指令。
三地址码四元式实验环境:windows microsoft visual c++语法制导定义:控制流语句的语法制导定义:实验代码分析:struct midcode//四元式结构;{int label;//存放标号;char op;//存放操作符;char arg1;//存放操作数1;char arg2;//存放操作数2;char result;//存放目的操作数(转移标号)}m_midcode[100];如何实现语句的跳转:主要利用了语义规则与规约过程的结合;例如:Label为四元式产生的新标号;Mnew 为四元式中最新的标号;case 9:tab1=t-1;while(tab1--){if(m_midcode[tab1].op=='>'&& (int)(m_midcode[tab1].result)==0){m_midcode[tab1].result=(char)m_midcode[tab1+2].label;/E.true=newlabelm_midcode[tab1+1].result=(char)(m_midcode[tab1+2].label+1);/E.false=newlabeltab2=tab1;for(;tab2<t;tab2++)if(m_midcode[tab2].op=='g'&&(int)m_midcode[tab2].result==0)m_midcode[tab2].result=(char)(mnew-1);//S1.next=s2.next=S.nextbreak ;}实验结果:心得体会:四元式序列是编译原理最后一个实验,最后的实验也要建立在之前两个实验的基础上。
中间代码生成实验报告
中间代码生成实验报告《中间代码生成实验报告》摘要:本实验旨在通过编写中间代码生成程序,实现将高级语言源代码转换为中间代码的功能。
通过实验,我们掌握了中间代码的生成过程和相关算法,并对编译器的工作原理有了更深入的理解。
本实验采用了C语言作为源语言,通过词法分析、语法分析和语义分析,生成了对应的中间代码。
一、实验目的1. 理解编译器的工作原理,掌握中间代码生成的基本概念和方法;2. 掌握中间代码的表示方法和生成算法;3. 通过实践,提高编程能力和对编译原理的理解。
二、实验环境1. 操作系统:Windows 10;2. 编程语言:C语言;3. 开发工具:Visual Studio 2019。
三、实验内容1. 设计并实现中间代码生成程序,将给定的C语言源代码转换为中间代码;2. 实现词法分析、语法分析和语义分析,生成对应的中间代码;3. 测试程序,验证中间代码的正确性和有效性。
四、实验步骤1. 设计中间代码的表示方法,包括四元式、三地址码等;2. 实现词法分析器,将源代码转换为词法单元序列;3. 实现语法分析器,将词法单元序列转换为语法树;4. 实现语义分析器,对语法树进行语义检查并生成中间代码;5. 测试程序,验证中间代码的正确性和有效性。
五、实验结果经过测试,中间代码生成程序能够正确地将C语言源代码转换为中间代码,并且生成的中间代码能够正确地表达源代码的语义和逻辑结构。
通过实验,我们成功地掌握了中间代码的生成过程和相关算法,加深了对编译器工作原理的理解。
六、实验总结通过本次实验,我们深入了解了编译器的工作原理和中间代码生成的基本概念和方法。
通过实践,我们提高了编程能力和对编译原理的理解,为进一步深入学习编译原理和设计编译器打下了良好的基础。
希望通过不断的实践和学习,能够更加熟练地掌握编译原理的知识,为今后的学习和工作打下坚实的基础。
中间代码生成实验报告
一、实验目的1. 理解编译原理中中间代码生成的基本概念和作用。
2. 掌握中间代码生成的常用算法和策略。
3. 提高对编译器构造的理解和实际操作能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:Eclipse三、实验内容1. 中间代码生成的基本概念2. 中间代码的表示方法3. 中间代码生成算法4. 实现一个简单的中间代码生成器四、实验步骤1. 了解中间代码生成的基本概念中间代码生成是编译过程中的一个重要环节,它将源程序转换成一种中间表示形式,便于后续的优化和目标代码生成。
中间代码生成的目的是提高编译器的灵活性和可维护性。
2. 研究中间代码的表示方法中间代码通常采用三地址代码(Three-Address Code,TAC)表示。
TAC是一种低级表示,由三个操作数和一个操作符组成,例如:(t1, t2, t3) = op,其中t1、t2、t3为临时变量,op为操作符。
3. 学习中间代码生成算法中间代码生成算法主要包括以下几种:(1)栈式中间代码生成算法(2)归约栈中间代码生成算法(3)递归下降中间代码生成算法4. 实现一个简单的中间代码生成器本实验采用递归下降中间代码生成算法,以一个简单的算术表达式为例,实现中间代码生成器。
(1)定义语法规则设表达式E由以下语法规则表示:E → E + T | E - T | TT → T F | T / F | FF → (E) | i(2)设计递归下降分析器根据语法规则,设计递归下降分析器,实现以下功能:①识别表达式E②识别项T③识别因子F(3)生成中间代码在递归下降分析器中,针对不同语法规则,生成相应的中间代码。
例如:当遇到表达式E时,生成以下中间代码:(t1, t2, t3) = op1(t1, t2) // op1表示加法或减法(t4, t5, t6) = op2(t4, t5) // op2表示乘法或除法(t7, t8, t9) = op3(t7, t8) // op3表示赋值(4)测试中间代码生成器编写测试用例,验证中间代码生成器的正确性。
编译语言-中间代码生成
实验四中间代码生成一、实验内容设计一个程序,该程序能够将形如x = y op z 的简单赋值语句翻译为对应的四元式序列,其中op 可为+、-、*、/等二元运算符。
(可参考实验指导书P163 至P164)。
要求用JA V A语言编程。
例如:若输入赋值语句 a = b + c,则输出如下四元式序列。
二、程序代码InToPost.JAVApackage zlf;import java.io.IOException;public class InToPost {private Stack theStack;private String input;private String output = "";public InToPost(String in) {input = in;int stackSize = input.length();theStack = new Stack(stackSize);}public String doTrans() {for (int j = 0; j < input.length(); j++) {char ch = input.charAt(j);switch (ch) {case'+':case'-':gotOper(ch, 1);break;case'*':case'/':gotOper(ch, 2);break;case'(':theStack.push(ch);break;case')':gotParen(ch);break;default:output = output + ch;break;}}while (!theStack.isEmpty()) {output = output + theStack.pop();}// System.out.println(output);return output;}public void gotOper(char opThis, int prec1) { while (!theStack.isEmpty()) {char opTop = theStack.pop();if (opTop == '(') {theStack.push(opTop);break;}else {int prec2;if (opTop == '+' || opTop == '-')prec2 = 1;elseprec2 = 2;if (prec2 < prec1) {theStack.push(opTop);break;}elseoutput = output + opTop;}}theStack.push(opThis);}public void gotParen(char ch){while (!theStack.isEmpty()) {char chx = theStack.pop();if (chx == '(')break;elseoutput = output + chx;}}class Stack {private int maxSize;private char[] stackArray;private int top;public Stack(int max) {maxSize = max;stackArray = new char[maxSize];top = -1;}public void push(char j) {stackArray[++top] = j;}public char pop() {return stackArray[top--];}public char peek() {return stackArray[top];}public boolean isEmpty() {return (top == -1);}}}package zlf;import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.Stack;public class extends JFrame{ private static Stack<String> number = new Stack<String>();private int n = 1;private JButton jbt = new JButton("生成");private JTextArea jta = new JTextArea();private JTextField jtf = new JTextField("A=B+C*D+E",20);private boolean hasError = false;public QuaternaryTypeOfAlgorithm(){JPanel p1 = new JPanel();p1.add(jtf);p1.add(jbt);add(p1,BorderLayout.NORTH);add(new JScrollPane(jta),BorderLayout.CENTER);jbt.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){String equation = jtf.getText().trim();create(equation);number.clear();hasError = false;repaint();}});}public void create(String input){String output;InToPost theTrans = new InToPost(input);output = theTrans.doTrans();try{for(int i = 0 ; i < output.length(); i++){String t = output.substring(i, i+1);if(t.equals("+")){String n1 = number.pop();String n2 = number.pop();String n3 = "T"+n;n++;number.push(n3);jta.append(n-1+": (+,"+n2+","+n1+","+n3+")"+'\n');}else if(t.equals("-")){String n1 = number.pop();String n3 = "T"+n;n++;number.push(n3);jta.append(n-1+": (-,"+n1+","+" "+","+n3+")"+'\n');}else if(t.equals("*")){String n1 = number.pop();String n2 = number.pop();String n3 = "T"+n;n++;number.push(n3);jta.append(n-1+": (*,"+n2+","+n1+","+n3+")"+'\n');}else if(t.equals("/")){String n1 = number.pop();String n2 = number.pop();String n3 = "T"+n;n++;number.push(n3);jta.append(n-1+": (/,"+n2+","+n1+","+n3+")"+'\n');}else if(t.matches("[a-zA-Z0-9=]")){number.push(t);//System.out.println("number:"+t);}}String last2 = number.pop();number.pop();String last1 = number.pop();n++;jta.append(n-1+":(=,"+last2+", ,"+last1+")"+'\n'+'\n'+'\n');}catch(Exception e){hasError = true;}if(hasError||!number.empty()){JOptionPane.showMessageDialog(null, "你输入的算式表达式有错!请重新输入");n umber.clear();}}public static void main(String[] args){QuaternaryTypeOfAlgorithm q = new QuaternaryTypeOfAlgorithm();q.setSize(400,200);q.setTitle("生成四元式序列");q.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);q.setVisible(true);q.setLocationRelativeTo(null);}}三、实验结果。
实验 6 简单中间代码生成
实验 6 简单中间代码生成1、实验目的:综合运用所学知识,集成词法分析、符号表管理等程序的成果,在语法分析和文法属性计算的基础上,完成中间代码的生成工作。
让学生全面了解一个编译器工作的全过程,真正全面掌握编译的思想和方法。
2、实验的基本原理对于一个给定文法,通过改写文法,使其满足LR(1)文法的要求,根据语义确定文法符号的属性,确定语义规则或翻译方案;根据文法特点构造LR(1)分析表,进而构造语法分析和属性计算程序。
分析程序在分析表的驱动下,完成对给定的句子进行语法分析和属性计算工作,最后生成三地址中间代码序列。
3、实验内容及要求a.实验所用文法如下。
statmt → id = expexp → exp addop term | termaddop →+ | -term→ term mulop factor | factormulop → * | /factor → ( exp ) | id | num其中id和num为实验二中定义的标识符和常数,因此这里还需要一个小的词法分析器来得到id和num。
b.构造文法LR(1)项目集,构造ACTION和GOTO矩阵,确认文法满足LR(1)文法要求。
c.按一般高级语言赋值语句的计算要求定义文法的属性和语义规则,属性计算的结果是将给定赋值语句翻译成三地址代码序列,并输出此序列。
d.从数据文件中读出赋值语句,并对其进行语法分析,对合法语句,输出其翻译结果。
e.实验数据文件中应该有多个语句,可能有正确的也应该有错误的语句;语句中的表达式有形式简单的也应该有复杂的。
每个表达式写在一行,以$结束。
4、实验步骤准备好用于实验的赋值语句序列,并存储在文件中。
a.编写单词分析子程序,能从源程序中分离出单词(包括标识符和常数);词法分析器以子程序形式出现,当需要进行词法分析时进行调用;b.构造分析表,确认上述文法为LR(1)文法,定义属性和语义规则。
c.确定临时变量生成方案,构造其生成程序。
编译原理实验四语义分析及中间代码生成
编译原理实验四语义分析及中间代码⽣成⼀、实验⽬的(1)通过上机实验,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译⽅法。
(2)掌握⽬前普遍采⽤的语义分析⽅法─语法制导翻译技术。
(3)给出 PL/0 ⽂法规范,要求在语法分析程序中添加语义处理,对于语法正确的表达式,输出其中间代码;对于语法正确的算术表达式,输出其计算值。
⼆、实验内容(1)语义分析对象重点考虑经过语法分析后已是正确的语法范畴,本实验重点是语义⼦程序。
已给 PL/0 语⾔⽂法,在实验⼆或实验三的表达式语法分析程序⾥,添加语义处理部分,输出表达式的中间代码,⽤四元式序列表⽰。
(2) PL/0 算术表达式的语义计算:PL/0 算术表达式,例如:2+35 作为输⼊。
输出: 17PL/0 表达式的中间代码表⽰:PL/0 表达式,例如: a(b+c)。
输出: (+,b,c,t1)(,a,t1,t2)三、设计思想1.原理属性⽂法:是在上下⽂⽆关⽂法的基础上为每个⽂法符号(终结符或⾮终结符)配备若⼲个相关的“值”(称为属性)。
属性:代表与⽂法符号相关的信息,和变量⼀样,可以进⾏计算和传递。
综合属性:⽤于“⾃下⽽上”传递信息。
在语法树中,⼀个结点的综合属性的值,由其⼦结点的属性值确定。
S—属性⽂法:仅仅使⽤综合属性的属性⽂法。
语义规则: 属性计算的过程即是语义处理的过程。
对于⽂法的每⼀个产⽣式配备⼀组属性的计算规则,则称为语义规则。
(1)终结符只有综合属性,它由词法分析器提供。
(2)⾮终结符既可以有综合属性也可以有继承属性,⽂法开始符号的所有继承属性作为属性计算前的初始值。
(3)产⽣式右边符号的继承属性和产⽣式左边符号的综合属性都必须提供⼀个计算规则。
(4)产⽣式左边符号的继承属性和产⽣式右边符号的综合属性由其它产⽣式的属性规则计算。
⼀遍扫描的处理⽅法: 与树遍历的属性计算⽅法不同,⼀遍扫描的处理⽅法是在语法分析的同时计算属性值,⽽不是语法分析构造语法树之后进⾏属性的计算,⽽且⽆需构造实际的语法树。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译方法实验报告
2011年10月
一、实验目的
熟悉算术表达式的语法分析与中间代码生成原理。
二、实验内容
(1)设计语法制导翻译生成表达式的四元式的算法;
(2)编写代码并上机调试运行通过。
输入——算术表达式;
输出——语法分析结果;
相应的四元式序列。
(3)设计LL(1)分析法或LR(0)分析法的属性翻译文法,并根据这些属性翻译文法,使用扩展的语法分析器实现语法制导翻译。
三、实验原理及基本步骤
●算术表达式文法:
G(E): E →E ω0 T | T
T →T ω1 F | F
F → i | (E)
●文法变换:
G’(E) E →T {ω0 T}
T →F {ω1 F}
F → i | (E)
●属性翻译文法:
E →T {ω0“push(SYN,w)” T “QUAT”}
T →F {ω1“push(SYN, w)” F “QUAT”}
F →i “push(SEM, entry(w))” | (E)
其中:
push(SYN, w) —当前单词w入算符栈SYN;
push(SEM, entry(w)) —当前w在符号表中的入口值压入语义栈SEM;
QUAT —生成四元式函数
i.T = newtemp;
ii.QT[j] =( SYN[k], SEM[s-1], SEM[s], T); j++;
iii.pop( SYN, _ ); pop( SEM, _ ); pop( SEM, _ );
push( SEM, T );
●递归下降子程序:
数据结构:SYN —算符栈;
SEM —语义栈;
四、数据结构设计
使用递归的结构进行四元式的设计,同时,运用堆栈结构将四元式的输出序列打印出来
while ( exp[i]=='+' || exp[i]=='-'){
syn[++i_syn]=exp[i]; //push(SYN,w)
i++; //read(w)
T();
quat();}
while ( exp[i]=='*' || exp[i]=='/'){
syn[++i_syn]=exp[i]; //push(SYN,w)
i++; //read(w)
F();
quat();}
void quat(){
strcpy(qt[j],"(, , , )");
//QT[j]:=(SYN[k],SEM[s-1],SEM[s],temp);
qt[j][1]=syn[i_syn];
qt[j][3]=sem[i_sem-1];
qt[j][5]=sem[i_sem];
qt[j][7]=temp;
j++;
i_syn--; //pop(SYN);
i_sem--; //pop(SEM);
i_sem--; //pop(SEM);
sem[++i_sem]=temp; //push(SEM,temp);
temp++;}
五、关键代码分析(带注释)及运行结果
#include <iostream>
#include "string.h"
#include "stdio.h"
using namespace std;
char syn[10]; //文法符号栈
int i_syn;
char sem[10]; //运算对象栈
int i_sem;
char exp[50]; //算术表达式区
int i;
char qt[30][15]; //四元式区
int j=0;
char temp='q'; //临时变量,取值为r--z
int E();
int T();
int F();
void quat(); //生成四元式函数
int main(int argc, char* argv[]){
printf("please input your expression:");
scanf("%s",exp); //输入四元式
i=0; //read(w)
E();
if (exp[i]=='\0')
for (i=0;i<j;i++) //输出四元式序列
printf("%s\n",qt[i]);
else
printf("err");
return 0;}
int E(){
T();
while ( exp[i]=='+' || exp[i]=='-'){
syn[++i_syn]=exp[i]; //push(SYN,w)
i++; //read(w)
T();
quat();}
return 1;}
int T(){
F();
while ( exp[i]=='*' || exp[i]=='/'){
syn[++i_syn]=exp[i]; //push(SYN,w)
i++; //read(w)
F();
quat();}
return 1;}
int F(){
if ( exp[i]=='('){
i++; //read(w)
E();
if ( exp[i]!=')'){
printf("err");
return 0;}
}else if ((exp[i]>='a' && exp[i]<='p')||(exp[i]>='0' && exp[i]<='9')){ sem[++i_sem]=exp[i]; } //push(SEM,w) else{
printf("err");
return 0;}
i++; //read(w)
return 1;}
void quat(){
strcpy(qt[j],"( , , , )"); //QT[j]:=(SYN[k],SEM[s-1],SEM[s],temp);
qt[j][1]=syn[i_syn];
qt[j][3]=sem[i_sem-1];
qt[j][5]=sem[i_sem];
qt[j][7]=temp;
j++;
i_syn--; //pop(SYN);
i_sem--; //pop(SEM);
i_sem--; //pop(SEM);
sem[++i_sem]=temp; //push(SEM,temp);
temp++;}
六、总结与分析
我们知道,定义一种语言除了要求定义语法外,还要求定义语义,即对语言的各种语法单位赋予具体的意义。
语义分析的任务是首先对每种语法单位进行静态的语义审查,然后分析其含义,并用另一种语言形式,即比源语言更加接近于目标语言的一种中间代码来进行描述这种语言。
因此,中间代码就显得十分重要,它关系着整个程序语言的正确编译与否,同时也是进行下一步编译的重要先决条件。
七、实验思考题
(1)自顶向下法(推导法)
从开始符号出发,采用推导运算,试图自顶向下构造语法树。
自底向上法(归约法)
从给定的符号串出发,采用归约运算,试图自底向上构造语法树。
(2)递归下降子程序法:递归子程序法属于自顶向下语法分析方法。
故又名递归下降法。
要求文法是LL(1)文法。
LL(1)分析法:LL(1)分析法是指从左到右扫描(第一个L) 、最左推导(第二个L)和只查看一个当前符号(括号中的1)之意;LL(1)分析法又称预测分析法,属于自顶向下确定性语法分析方法。
要求文法是LL(1)文法。
(3)相同点:都要求文法是LL(1)文法;都是自顶向下的分析方法;都通过分析下个字符来判断该进入哪个状态或者调用哪个函数。
不同点:LL(1)分析法先建立起预测分析表,通过对分析栈的不断操作(出栈,入栈)来进行;递归下降子程序法是通过函数间的函数调用来实现不同状态间的转换,并简化了代码。
(4)语法制导翻译是在语法分析过程中,随着分析(推导或归约)的逐步进展,每识别出一个语法结构,根据文法的每个规则所对应的语义子程序进行翻译的方法;核心技术是构造属性翻译文法。
(5)假定:SEM(m)-- 语义栈(属性传递、赋值场所);
QT[q] –四元式区;
G``(E):E -> T | E+T{GEQ(+)} | E-T{GEQ(-)} T -> F | T*F{GEQ(*)} | T/F{GEQ(/)}
F -> i{PUSH(i)} | ( E )
其中:
⑴PUSH(i)–压栈函数(把当前i 压入语义栈);
⑵GEQ(w) –表达式四元式生成函数:
生成一个四元式送QT[q]过程:
①t := NEWT; { 申请临时变量函数;}
②SEND(w,SEM[m-1],SEM[m],t)
③POP;POP;PUSH(t)。