编译原理与技术
北京邮电大学《编译原理与技术》课程教学大纲

《编译原理与技术》课程教学大纲一、课程编号:1311020二、课程名称:编译原理与技术(64学时)Compiler Principle and Technology三、课程教学目的通过本课程的学习,使学生了解并掌握程序设计语言的编译程序的设计原理与实现技术,了解编译程序的构造方法;加深学生对高级程序设计语言的理解,做到触类旁通;使学生体会到其他专业基础知识如算法与数据结构、程序设计、操作系统、形式语言与自动机、计算机组成原理、汇编语言、软件工程等综合应用,对计算机的软硬件工作原理建立比较深刻的理解,提高学生的专业素养,使学生能够利用所学的理论知识解决实际问题,培养学生分析问题、解决问题的能力。
四、课程教学基本要求1.了解编译的基本概念和步骤,编译程序的基本组成、结构、编译环境等基本概念。
2.掌握词法分析的原理、词法分析程序的设计和实现方法。
3.掌握语法分析的原理和实现技术、简单的语法分析程序的设计和实现。
4.掌握语法制导翻译技术。
5.理解利用语法制导翻译技术进行语义分析、中间代码生成的实现。
6.理解程序运行环境、代码生成相关的基本概念和实现方法。
7.了解代码优化技术的基本概念和方法。
五、教学内容及学时分配(含实验)第一章编译概述2学时1.翻译和解释2.编译的阶段3.编译程序的前后处理器(预处理器、汇编程序、连接装配程序)第二章词法分析4学时1.词法分析器的作用2.词法分析器的输入与输出3.记号的描述与识别4.词法分析程序的设计与实现5*.软件工具LEX(规格说明、工作原理)1.语法分析器的作用2.自顶向下分析(预测分析器、非递归的预测分析器)3.自底向上分析(规范归约、移进-归约方法实现)4.LR分析器(模型及工作过程、SLR(1)分析器、LR(1)分析器、LALR(1)分析器)5.LR分析方法对二义文法的应用6*.软件工具YACC (规格说明、二义性处理)第四章语法制导翻译技术8学时1.语法制导定义与翻译方案2.S属性定义的自底向上翻译3.L属性的自顶向下翻译4.L属性的自底向上翻译第五章语义分析4学时1.语义分析的概念2.符号表的组织与管理3.类型检查(类型表达式、类型等价)4.简单类型检查器的说明(语言说明、确定标识符的类型、表达式及语句的类型检查)5*.类型检查有关的其他主题(函数和运算符的重载、类型转换、多态函数)第六章运行环境6学时1.程序运行时的存储组织2.存储分配策略(静态存储分配、栈式存储分配、堆式存储分配)3.访问非局部名字4.参数传递方式第七章中间代码生成6学时1.中间代码形式2.赋值语句的翻译3.布尔表达式的翻译4.控制语句的翻译5.过程调用语句的翻译1.代码生成概述2.基本块与流图3.一个简单的代码生成程序第九章代码优化2学时1.优化概述2.基本块的优化3.循环优化教学实践:实验1.设计并实现一个C语言程序的词法分析程序4学时实验2.设计并实现一个简单赋值语句的语法分析程序12学时六、教学重点、难点重点:语法分析、语法制导翻译技术、运行环境、中间代码生成难点:语法分析、语法制导翻译技术七、先修课程:计算机导论与程序设计、算法与数据结构、形式语言与自动机、计算机组成原理八、适用专业:计算机科学与技术、网络工程九、使用教材及参考书目《编译原理与技术》李文生编著清华大学出版社 2009.1执笔人: 李文生。
编译原理与技术--答案

《编译原理与技术》90分答案须用《西安电子科技大学网络与继续教育学院标准答题纸》手写完成,要求字迹工整、卷面干净。
一、单选题1、A2、C3、B4、B5、B二、填空题1、语法分析、语义分析、目标代码生成、语义分析2、自上而下3、移进,归约4、下推自动机5、a+120,编译,运行三、简答题1、答案:有了正规式和有限自动机的理论基础后,就可以构造出编译程序的词法分析模块。
构造词法分析器的一般步骤如下。
(1)用正规式描述语言中的单词构成规则。
(2)为每个正规式构造一个NFA,它识别正规式所表示的正规集。
(3)将构造出的NFA转换成等价的DFA。
(4)对DFA进行最小化处理,使其最简。
(5)从DFA构造词法分析器。
2、答案:常用的中间代码:三地址码,后缀式,DAG图。
中间代码的特点是与具体机器(指令系统)无关;采用中间代码可以明确区分前端与后端;便于优化和移植。
解释:编译器各阶段的完整输出,均可以被认为是源程序的某种中间表示。
本章讨论的是中间代码生成器输出的中间表示,称之为中间代码。
中间代码实际上应起一个编译器前端与后端分水岭的作用。
为此要求中间代码具有如下特性,以便于编译器的开发移植和代码的优化:(1)便于语法制导翻译;(2)既与机器指令的结构相近,又与具体机器无关。
3、答案:N = {S, A, B}T = {a, b, c, d}S → aAcB | Bd A → AaB | c B → bScA | b | ε四、综合题1、 (a)NFA如下图所示(b)s0 = {A}ε_闭包(s0) = s0 初态ε_闭包(smove(s0,1)) = {B} 记为s1ε_闭包(smove(s1,0)) = {B} = s1ε_闭包(smove(s1,1)) = {B,C} 记为s2,终态ε_闭包(smove(s2,0)) = {B} = s1ε_闭包(smove(s2,1)) = {B,C } = s2DFA如下图所示2、答案:(a) FIRST(B) = {b, ε} FIRST(A) = {a, b} FIRST(S) = {a, b}FOLLOW(S) = {#} FOLLOW(A) = {b} FOLLOW(B) = {c, #}(b) 可以推导出baabbb3、答案:(a) 识别该文法活前缀的DFA如下图所示(b) 句子id(id+id(id))分析树var_no = 2 arr_no = 2 exp_no = 3。
编译原理与技术

编译原理与技术编译原理与技术是计算机科学与技术中的一门重要课程,旨在教授学生如何设计、实现和优化编译器以及相关的编程工具和技术。
本文将介绍编译原理与技术的基本概念、主要任务以及在实际应用中的作用和挑战,并探讨编译原理与技术在不同编程语言和开发环境中的应用。
一、编译原理与技术的基本概念编译原理与技术研究的对象是编译器,而编译器是一种从一种语言(源语言)到另一种语言(目标语言)的程序转换工具。
编译器的主要任务是将源程序转换为等价的目标程序,以便计算机能够执行。
编译原理与技术的基本概念包括词法分析、语法分析、语义分析、中间代码生成、代码优化和代码生成等。
1. 词法分析词法分析是编译器的第一个阶段,它将源程序的字符流转换为有意义的词法单元序列。
词法单元是编程语言中具有独立含义的最小单元,例如关键字、标识符、运算符和常量等。
词法分析器通常通过有限自动机或正则表达式来实现。
2. 语法分析语法分析是编译器的第二个阶段,它通过对词法单元序列的分析来构造语法树。
语法树反映了源程序的语法结构,其中每个节点代表一个语法单元,每个子节点代表一个子表达式。
语法分析器通常使用上下文无关文法和分析方法(如递归下降分析和LR分析)来实现。
3. 语义分析语义分析是编译器的第三个阶段,它对语法树进行静态检查以确定源程序是否符合语义规则。
语义分析器通常处理类型检查、作用域分析和语义动作等任务,以确保生成的中间代码具有准确的语义含义。
4. 中间代码生成中间代码生成是编译器的第四个阶段,它将语法树转换为一种中间表示形式,以便后续的优化和目标代码生成。
中间代码通常是一种抽象的、与机器无关的形式,例如三地址码、虚拟机代码或中间表示IR。
5. 代码优化代码优化是编译器的第五个阶段,它利用各种优化技术来改进中间代码的性能和效率。
常见的代码优化技术包括常量传播、公共子表达式消除、循环优化和内联展开等。
6. 代码生成代码生成是编译器的最后一个阶段,它将优化后的中间代码转换为目标代码。
北邮-编译原理-词法分析

实验报告编译原理与技术ytinrete程序设计1题目:词法分析程序的设计与实现。
实验内容:设计并实现C语言的词法分析程序,要求如下。
(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
(2)、可以识别并读取源程序中的注释。
(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。
(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。
|实验要求:方法1:采用C/C++作为实现语言,手工编写词法分析程序。
方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。
算法思路:首先通过遍历,统计行号和字符数,并记录所有的注释。
其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。
对于整行数据的处理,依靠空格将其分成单个单词再具体处理。
对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。
&程序源代码:==*p || 'E'==*p || 'e'==*p)//小数和指数形式{(1,*p);p++;while(isdigit(*p)){(1,*p);p++;}}{sum_word++;(temp_word);cout<<endl<<"第"<<sum_word<<"个单词:"<<" 无符号数:" <<temp_word<<endl;}}elseif('#'==*p)//预处理文件特殊处理{while('\0'!=*p){(1,*p);》p++;}//p指向换行,完成直接退出(temp_word);}elseif('"'==*p)//字符串{();p++;while('"'!=*p)<{(1,*p);p++;}p++;sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 字符串:" <<temp_word<<endl;}elseif('+'==*p)//处理符号{。
编译原理及实现技术:7.语法分析__语法树、二义性文法

SSS|a 可以推导出SSS串,必有二义性 SS+S 可以推导出S+S+S,必有二义 性
10
2.2 文法二义性的判定和利用
文法二义性的利用 对二义性文法进行修改,消除其二义性
会导致文法的复杂程度和符号数目迅速升 高。 可以利用二义性文法状态少,分析快的 特点,使用二义性文法,对具体问题加入 语义规则,约束其二义性即可。
16
若干历年考试题
设有一个文法G[S]: S->V V->T|ViT T->F|T+F F->V*|[
F+Fi[
句型F+Fi[的短语,简 单短语和句柄分别为: 首F,F+F, F+Fi[, [ 首F,[; 首F。
17
14
若干历年考试题
构造一个文法G,使 L(G)={anbmck|m=n+k,n≥1,m>1,k≥1}
G[S]: SAB AaAb| ab BbBc| bc
15
若干历年考试题
已知文法G[Z]: ZWV WaB | aW | a Bb | bB VbV | dD Dd | dD
判断文法G[Z]是否为二义性文法,如果是请举 例 句子abdd有两棵语法树。
语法树:设G是给定的语法,称满足下列条
件的树为G的一棵语法树: 1. 树的每个节点都标有G的一个语法符号,且根
节点标有初始符S。 2. 如果一个非叶节点A按从左到右顺序有n个儿子
节点B1、B2、…、Bn,则: AB1B2…Bn 一定是 G的一个产生式.
2
1.1 语法树的定义
例子:有文法
E
E E+T E T T T *F
北邮-编译原理-词法分析

实验报告编译原理与技术ytinrete程序设计1题目:词法分析程序的设计与实现。
实验内容:设计并实现C语言的词法分析程序,要求如下。
(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
(2)、可以识别并读取源程序中的注释。
(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。
((5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。
实验要求:方法1:采用C/C++作为实现语言,手工编写词法分析程序。
方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。
算法思路:首先通过遍历,统计行号和字符数,并记录所有的注释。
其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。
对于整行数据的处理,依靠空格将其分成单个单词再具体处理。
对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。
-程序源代码:==*p || 'E'==*p || 'e'==*p)//小数和指数形式{(1,*p);p++;while(isdigit(*p)){(1,*p);—p++;}}sum_word++;(temp_word);cout<<endl<<"第"<<sum_word<<"个单词:"<<" 无符号数:" <<temp_word<<endl;}}elseif('#'==*p)//预处理文件特殊处理&while('\0'!=*p){(1,*p);p++;}//p指向换行,完成直接退出(temp_word);}else-if('"'==*p)//字符串{();p++;while('"'!=*p){(1,*p);p++;}p++;:sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 字符串:" <<temp_word<<endl;elseif('+'==*p)//处理符号{();if('='==*(p+1))//自加{temp_word = "+=";¥(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自加号:" <<temp_word<<endl;p+=2;//推进}elseif('+'==*(p+1))//自加1{temp_word = "++";(temp_word);—sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自加1号:" <<temp_word<<endl;p+=2;//推进}elseif(isdigit(*(p+1)))//有符号数{temp_word="+";for(int j=1; isdigit(*(p+j));j++)(1,*(p+j));,(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 有符号数:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "+";(temp_word);sum_word++;,cout<<endl<<"第"<<sum_word<<"个单词:"<<" 加号:" <<temp_word<<endl;p+=2;//推进}}elseif('-'==*p)//处理符号{();if('='==*(p+1))//自减{—temp_word = "-=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自减号:" <<temp_word<<endl;p+=2;//推进}elseif('-'==*(p+1))//自减1{temp_word = "--";、(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自减1号:" <<temp_word<<endl;p+=2;//推进}elseif(isdigit(*(p+1)))//有符号数{temp_word="-";for(int j=1; isdigit(*(p+j));j++)~(1,*(p+j));(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 有符号数:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "-";(temp_word);:sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 减号:" <<temp_word<<endl;p+=2;//推进}}elseif('*'==*p)//处理符号{();if('='==*(p+1))//自乘!{temp_word = "*=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自乘号:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "*";[(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 乘号:" <<temp_word<<endl;p+=2;//推进}}elseif('/'==*p)//处理符号{'();if('='==*(p+1))//自除{temp_word = "*=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自除号:" <<temp_word<<endl;p+=2;//推进}else|if('/'==*(p+1))//行注释return;// 直接跳出elseif('*'==*(p+1))//多行注释{in_comment=true;p+=2;while('\0'!=*p)//判断这行为止注释能不能结束{if(('*'==*p)&&('/')==*(p+1)),{in_comment = false;break;}p++;}}else{temp_word = "/";—(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 除号:" <<temp_word<<endl;p+=2;//推进}}elseif('='==*p)//处理等号{();¥if('='==*(p+1))//比较{temp_word = "==";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 比较号:"<<temp_word<<endl;p+=2;//推进}else{}temp_word = "=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 赋值号:" <<temp_word<<endl;p+=2;//推进}}elseif('>'==*p)){();if('='==*(p+1)){temp_word = ">=";(temp_word);sum_word++;<<temp_word<<endl;p+=2;//推进}·else{temp_word = ">";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 大于号:" <<temp_word<<endl;p+=2;//推进}}《elseif('<'==*p){();if('='==*(p+1)){temp_word = "<=";(temp_word);sum_word++;<<temp_word<<endl;&p+=2;//推进}else{temp_word = "<";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 小于号:" <<temp_word<<endl;p+=2;//推进}[}elseif('!'==*p){();if('='==*(p+1)){temp_word = "!=";(temp_word);;sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 不等于号:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "!";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 取反号:" <<temp_word<<endl;'p+=2;//推进}}elseif(':'==*p || '('==*p || ')'==*p || ';'==*p || '{' ==*p|| '}'==*p || ','==*p||'['==*p||']'==*p||'\0'==*p||'\n'==*p)//标点不算单词{if('('==*p)small_bracket++;//查错`if(')'==*p)small_bracket--;//查错if('{'==*p)big_bracket++;//查错if('}'==*p)big_bracket--;//查错p++;//推进}else//非法字符{`cout<<endl<<"error: 在第"<<current_line<<"行,出现非法字符:"<<*p<<endl;p++;}}}void analyse(void)//循环填充buffer并进行词法分析{char *p=buffer;(0);//文件指针回到头]while(!()){(*p);if('\n'==*p)//充满一句{*(p+1)='\0';*(p+2)='\0';current_line++;word_analyse();if(0!=small_bracket),{cout<<endl<<"error: 在第"<<current_line<<"行,小括号不匹配!"<<endl;small_bracket=0;}p=buffer;//重新填充}elsep++;{}if(0!=big_bracket)cout<<endl<<"error: 大括号不匹配!"<<endl;}void show_result(void)//显示统计结果{cout<<endl<<"the number of words is:"<<sum_word<<endl;cout<<endl<<"the number of char is:"<<sum_char<<endl;cout<<endl<<"the number of line is:"<<sum_line<<endl;¥cout<<"the followings are header:"<<endl;for(int i=0; i<(); i++){cout<<(i);}cout<<"the followings are comment:"<<endl;for(int i=0; i<(); i++){cout<<(i);}$}int main(void){("");if(NULL==file)》cout<<endl<<"找不到文件!"<<endl;else{//开始处理init();//初始化关键字analyse();();sum();//统计行数字节数注释show_result();//显示统计结果}int test;cin>>test;return 0;}实验结果测试:正常文件运行结果:有问题文件:运行结果:。
916073-编译原理原理与技术-第3章 语法分析

id
id
E E+E E E +E id E + E id id + E id id + id E
E +E
E
*
E id
id
id
3.2 语言和文法
• 文法的优点
–文法为语言给出了精确的、易于理解的语法规范 –自动产生高效的分析器 –可以给语言定义出层次结构 –以文法为基础的语言的实现便于语言的修改
FIRST(E) = FIRST(T) = FIRST(F) = { ( , id } FIRST(E ) = {+, } FRIST(T ) = {, } FOLLOW(E) = FOLLOW(E ) = { ), $} FOLLOW(T) = FOLLOW (T ) = {+, ), $} FOLLOW(F) = {+, , ), $}
id
+ term
term * factor
factor
id
id id + id id 分析树
3.2 语言和文法
3.2.5 消除二义性 stmt if expr then stmt
| if expr then stmt else stmt | other • 句型:if expr then if expr then stmt else stmt • 两个最左推导: stmt if expr then stmt if expr then if expr then stmt else stmt stmt if expr then stmt else stmt if expr then if expr then stmt else stmt
3.3 自上而下分析
编译原理与技术1

编译原理与技术模拟试题一一、填空题(20分,每空2分)1.1编译程序的工作过程可划分为词法分析、语法分析、、中间代码生成、代码优化、等阶段,一般在阶段对表达式中运算对象的类型进行检查。
答案:语义分析、目标代码生成、语义分析解释:要求掌握编译器的工作原理和特点。
编译和解释方式是翻译高级程序设计语言的两种基本方式。
解释程序也称为解释器,它或者直接解释执行源程序,或者将源程序翻译成某种中间表示形式后再加以执行;而编译程序(编译器)则首先将源程序翻译成目标语言程序,然后在计算机上运行目标程序。
编译过程包含词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成,以及符号表管理和出错处理。
表达式的类型信息属于语义信息,所以在语义分析阶段进行类型检查。
1.2 和预测分析法是自上而下的语法分析方法。
答案:递归下降法解释:语法分析的任务是根据语言的语法规则,分析单词串是否构成短语和句子,即表达式、语句和程序等基本语言结构,同时检查和处理程序中的语法错误。
根据语法树(或分析树)的建立方式,语法分析可分为自上而下分析和自下而上分析两类,递归下降分析和预测分析属于自上而下的语法分析方法。
1.3常用的存储分配策略有存储分配和动态存储分配,其中,动态存储分配策略包括分配和分配。
答案:静态、栈、堆解释:编译器怎样对存储空间进行组织和采用什么样的存储分配策略,很大程度上取决于程序设计语言中所采用的机制。
编译器具体实现时,根据语言机制的特性,采用静态分配策略、栈分配策略和堆分配策略三种方式的其中若干种。
静态分配策略是指编译时安排所有数据对象的存储,即绑定是静态确定的;栈分配策略是指按栈的方式管理运行时的存储;堆分配策略是指在运行时根据要求从堆数据区动态地分配和释放存储。
1.4移进、归约是分析中的典型操作。
答案:自下而上或LR解释:自下而上分析的一般思路是从句子ω开始,从左到右扫描ω,反复用产生式的左部替换产生式的右部、谋求对ω的匹配,最终得到文法的开始符号,或者发现一个错误。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
- 属性计算次序仅由分析方法限定。如S-属性定义可以在自 下而上分析时,在归约前计算。如YACC中的语义动作。
2020/10/10
《编译原理与技术》讲义
10
e.g. 3 属性计算次序: 3+4×5
2
E. val = 3
1
number. lex_val = 3
8
E. val = 23
2020/10/10
《编译原理与技术》讲义
8
e.g. 2 属性依赖图: 3+4×5
E. val = 23
E. val = 3 +
E. val = 20
number. lex_val = 3 E. val = 4 ×
E. val = 5
number. lex_val = 4 number. lex_val = 5
assign
a := b* -c + b * -c
assign
a
+
a
+
* b@
* b@
* b@
c
c
语法树
c DAG
2020/10/10
《编译原理与技术》讲义
15
e.g.4 构造表达式的语法树(DAG)
产生式
语义规则
EE1 + E2 EE1 - E2 EE1 * E2 EE1 / E2 E( E1 ) E - E1 Enumber
2020/10/10
《编译原理与技术》讲义
13
语法树 vs. 分析树
a := b* -c + b * -c
语法树
分析树
assign
算符 E
a
+
a
*
*
b@
b@
c
c
赋值语句
assign E
E+
E
E*E E*E
b @E b @E
c
c
2020/10/10
《编译原理与技术》讲义
14
语法树 vs. DAG
DAG(去除了公共子表达式的无环有向图)
产生式
EE1 ‘+’ E2 EE1 ‘*’ E2 E’(‘ E1 ‘)’ Enumber
语法制导定义
E.val := E1.val + E2.val E.val := E1.val * E2.val E.val := E1.val E.val := number.lex_val
2020/10/10
《编译原理与技术》讲义
7
+
E. val = 20
4
E. val = 4 ×
6
E. val = 5
2020/10/10
3
5Leabharlann number. lex_val = 4 number. lex_val = 5
《编译原理与技术》讲义
11
S-属性定义
-语义规则仅包含综合属性计算(可以有固有 属性出现)。
-适合自底向上计算
e.g. 语法树 -语法树与分析树
E.nptr := mknode(‘+’,E1.nptr, E2.nptr) E.nptr := mknode(‘-’,E1.nptr, E2.nptr) E.nptr := mknode(‘*’,E1.nptr, E2.nptr) E.nptr := mknode(‘/’,E1.nptr, E2.nptr) E.nptr := E1.nptr E.nptr := mknode(‘@’,E1.nptr, -) E.nptr := mkleaf(‘NUM’,number.lex_val)
- 固有属性:终结符仅有的属性。如 number.lex_val。通常由词法程序提供。
2020/10/10
《编译原理与技术》讲义
7
A的继承属性
属性依赖图
A.b
A的继承属性 A
X1.c1 X2.c2 …
综合属性A.b的计算
X1.c1 X2.c2 Xk.b … 继承属性Xk.b的计算
2020/10/10
《编译原理与技术》讲义
9
语义规则的计算方法
分析树方法
- 为输入串建立分析树 - 由语义规则建立属性依赖图(没有属性循环依赖的) - 对依赖图进行拓扑排序,得到属性计算次序 - 依次计算属性,得到“翻译”结果
基于规则的方法
- 构造编译器时,事先对产生式的语义规则进行分析,得到 属性计算次序
属性-用来描述文法符号的语义特征,如 常量的“值”、变量的类型和存储位置等。
e.g. 二义性表达式文法G,非终结符E有属性E.val (表达式的值)
EE ‘+’ E | E ‘*’ E | ‘(‘ E ‘)’ | number 属性计算规则(语义规则)
与产生式相关联的反映文法符号属性之间关系的 “规则”
语法树可看作分析树的浓缩。也称抽象语法 树。而分析树可看成具体语法树。
2020/10/10
《编译原理与技术》讲义
12
语法树 vs. 分析树
S if B-expr then S1 else S2
语法树
if-then-else
分析树
S
B-expr S1 S2 if B-expr then S1 else S2
2020/10/10
《编译原理与技术》讲义
6
属性文法
属性的分类
若产生式AX1X2…Xn,与之相关的属性计算规则 b := f ( c1, c2, … )
-如果属性b是产生式左部符号A的属性则称其为A
的综合属性; -X如i的果继属承性属b是性产;生式右部符号Xi的属性则称其为 -性c1或, cA2,的…继一承般属是性产;生式右部其它符号的(综合)属
2020/10/10
《编译原理与技术》讲义
3
属性文法
语法制导定义(文法+属性+语义规则)
语义规则仅表明属性间“抽象”关系,不涉及具体 翻译实现细节,如计算次序等。 翻译方案(文法+属性+语义动作) 语义规则-即语义动作,可体现若干实现的细节。
2020/10/10
《编译原理与技术》讲义
4
e.g.1算术表达式的计算器
5
e.g.1算术表达式的计算器
产生式
翻译方案
EE1 ‘+’ E2 EE1 ‘*’ E2 E’(‘ E1 ‘)’ Enumber
{ E.val := E1 .val + E2.val } { E.val := E1.val * E2.val } { E.val := E1.val } { E.val := number.lex_val }
编译原理与技术
语法制导翻译
2020/10/10
《编译原理与技术》讲义
1
语法制导翻译
属性文法
S-属性定义 L-属性定义 语法制导定义与翻译方案
自底向上翻译
S-属性定义自底向上计算 自底向上计算继承属性
自顶向下翻译
2020/10/10
《编译原理与技术》讲义
2
属性文法
属性文法(Attributed Grammar) 上下文无关文法+属性+属性计算规则