当前位置:文档之家› 编译原理试题

编译原理试题

中间语言与语法制导翻译重点与难点重点:语法制导翻译的基本思想,属性文法,翻译模式,说明语句的翻译方案。

三地址码,各种语句的目标代码结构、属性文法与翻译模式。

难点:属性的意义,对综合属性,继承属性,固有属性的理解,属性计算,怎么通过属性来表达翻译。

布尔表达式的翻译,对各种语句的目标代码结构、属性文法与翻译模式的理解。

基本要求掌握语法制导翻译的基本思想,属性文法,综合属性,继承属性,固有属性,属性计算,S_属性文法,L_属性文法,说明语句的翻译方案,翻译模式、属性文法的实现掌握中间语言与语义分析的基本概念;熟练掌握语法(结构)树、三地址代码、赋值与控制语句的翻译、说明语句的翻译;掌握组合数据说明的翻译、过程调用翻译。

例题解析例1 给定文法 E --> T { R.i := T.p }R { E.p := R.s }R --> addopT { R1.i := mknode( addop.val, R.i, T.p ) }R { R.s := R1.s }R --> { R.s := R1.s }T --> ( E ) { T.p := E.p }T --> id { T.p := mkleaf( id, id.entry ) }T --> num { T.p := mkleaf( num, num.val ) }(1) 指出文法中的各非终结符具有哪些综合属性和哪些继承属性⑵画出按本翻译模式处理表达式 a + 20 + ( b - 10 ) 时所生成的语法树【解】(1)E的综合属性 p,R的继承属性i,综合属性s;T的综合属性p(2) 处理表达式 a + 20 + ( b - 10 ) 时所生成的语法树如下+(ID, a) +(NUM, 20) -( ID, b) (NUM, 10)例2 定义一个计算器的属性文法,完成一个输入表达式值的计算和显示,【解】计算器的文法L → EE → E1 + T | TT → T1 * F | FF → ( E ) | digit引进属性val ,计算器的属性文法:L → E print( E.val )(L 的虚属性)E → E1 + T E.val := E1.val + T.valE → T E.val := T.valT → T1 * F T.val := T1.val * F.valT → F T.val := F.valF → ( E ) F.val := E.valF → digit F.val := digit.lexvallexval 是单词 digit 的属性例3给出对输入串6-3 3*5+4 的分析树与属性计算【解】3*5+4 的分析树与属性计算例4定义一个说明语句的属性文法【解】说明语句的文法D → T LT → intT → realL → L1,idL → id要解决的问题:记录标识符的类型和类型信息传递方法:引进属性type,和in,用T.type记录类型信息,并传给L.in,说明语句的属性文法如下:D → T L L.in := T.typeT → int T.type := ‘integer’T → real T.type := ‘real’L → L1,id L1.in := L.inaddtype( id.entry, L.in )L → id addtype( id.entry, L.in )entry 单词 id 的属性addtype 在符号表中为变量填加类型信息例5 给出输入串real id1,id2,id3 的分析树和属性计算例6 设下列文法生成变量的类型说明D → id LL → , id L | : TT → integer | real试构造一个翻译模式,把每个标识符的类型存入符号表。

【解】解题思路这是一个对说明语句进行语义分析的题目,不需要产生代码,但要求把每个标识符的类型填入符号表中。

解答对D,L,T设置综合属性type。

过程addtype(id,type)用来把标识符id及其类型type 填入到符号表中。

翻译模式如下:D → id L {addtype(id.entry,L.type)}L → ,id L1 {addtype(id.entry,L1.type);L.type:=L1.type;}L → : T {L.type:=T.type}T → integer {T.type:=interger}T → real {T.type:=real}例7文法G的产生式如下:S → (L) | aL → L , S | S(1)试写出一个语法制导定义,它输出配对括号个数;(2)写一个翻译方案,打印每个a的嵌套深度。

如((a),a),打印2,1。

【解】解题思路本题包括两部分,第1部分要求写语法制导定义,第2部分要求写翻译方案。

语法制导定义(或属性文法)可以看作是关于语言翻译的高级规范说明,其中隐去实现细节,使用户从明确说明翻译顺序的工作中解脱出来。

翻译方案(也称翻译模式)给出了使用语义规则进行计算的次序,把某些实现细节表示出来。

读者从下面解答中可体会两者的区别。

解答为S、L引入属性h,代表配对括号个数。

语法制导定义如下:产生式语义规则S → (L) S.h:=L.h+1S → a S.h:=0L → L1 , S L.h:=L1.h+S.hL → S L.h:=S.hS’→S print(S.h)(2)为S、L引入d,代表a的嵌套深度。

翻译方案如下:S’→{S.d:=0;}SS →‘(’{L.d:=S.d+1;}L‘)’S →a{print(S.d);}L → {L1.d:=L.d;}L1{S.d:=L.d;}SL → {S.d:=L.d}S例8下列文法对整型常数和实型常数施用加法运算符“+”生成表达式;当两个整型数相加时,结果仍为整型数,否则,结果为实型数:E → E+T | TT → num.num | num(1)试给出确定每个子表达式结果类型的属性文法。

(2)扩充(1)的属性文法,使之把表达式翻译成后缀形式,同时也能确定结果的类型。

应该注意使用一元运算符inttoreal把整型数转换成实型数,以便使后缀形如加法运算符的两个操作数具有相同的类型。

【解】解题思路确定每个子表达式结果类型的属性文法是比较容易定义的。

关键是如何扩充此属性文法,使之把表达式翻译成后缀形式。

我们将不在name或num.num向T归约的时候输出该运算对象,而是把运算对象的输出放在T或E+T向E归约的时候。

这是因为考虑输出类型转换算符inttoreal的动作可能在E+T归约的时候进行,如果这时两个运算对象都在前面name或num.num向T归约的时候已输出,需要为第1个运算对象输出类型转换算符时就已经为时太晚。

还要注意的是,在E+T向E归约时,该加法运算的第1个运算对象已经输出。

所以E →E+T的语义规则不需要有输出E运算对象的动作。

解答(1)为文法符号E和T配以综合属性type,用来表示它们的类型。

类型值分别用int和real 来表示。

确定每个子表达式结果类型的属性文法如下:产生式语义规则E→E1+T{T.type:=if E1.type=int and T.type=int then int else realE→T {E.type:=T.type}T→num.num T.type:=realT→num T.type:=int(2)下面属性文法将表达式的后缀表示打印输出,其中lexeme属性表示单词的拼写。

产生式语义规则E→E1+T if E1.type=real and T.type=int thenbeginE.type:=real;print(T.lexeme);print(‘inttoreal’);endelse if E1.type=int and T.type=real thenbeginE.type:=real;print(‘inttoreal’);print(T.lexeme);endelse beginE.type:=E1.type;print(T.lexeme);endprint(‘+’);E→T E.type:=T.type;print(T.lexeme);T→num.num T.type:=real;T.lexeme:=num1.lexeme||“.”||num2.lexemeT→num T.type:=int;T.lexeme:=num.lexeme;例9 将下列语句翻译为逆波兰表示(后缀式)、三元式和四元表示:a:=(b+c)*e+(b+c)/f【解】解题思路把中缀式转换为后缀式的简单方法:按中缀式中各运算符的优先规则,从最先执行的部分开始写,一层层套。

如a≤b+c∧a>d∨a+b≠e,先把b+c写为bc+;然后把a≤套上去,成为abc+≤;再把a>d表示为ad>;然后把∧套上去,成为abc+≤ad>∧,依此类推。

四元式由4个部分组成:算符op、第1和第2运算量arg1和arg2,以及运算结果result。

运算量和运算结果有时指用户自定义的变量,有时指编译程序引进的临时变量。

如果op是一个算术或逻辑算符,则result总是一个新引进的临时变量,用于存放运算结果。

三元式只需3个域:op、arg1和arg2。

与四元式相比,三元式避免了临时变量的填入,而是通过计算这个临时变量的语句的位置来引用这个临时变量。

我们很容易把一个算术表达式或一个赋值句表示为四元式序列或三元式序列。

解答逆波兰表示为:bc+e*bc+f/+:=三元式序列为:(1)(+,b,c)(2)(* ,(1) ,e)(3)(+ ,b,c)(4)(/ ,(3) ,f)(5)(+ ,(2) ,(4))(6)(:= ,a,(5))四元式序列为:(1)(+ ,b,c,T1)(2)(* ,T1,e,T2)(3)(+ ,b,c,T3)(4)(/ ,T3,f,T4)(5)(+ ,T2,T4,T5)(6)(:= ,T5,-,a)例10 利用回填技术把语句while a>0 or b>0 doif c>0 and d<0 then x:=y+1;翻译为三地址代码。

【解】解题思路把表达式或赋值语句翻译为三地址代码是容易理解的,如x:=y*z+1翻译为:T1:=y*zT2:=T1+1x:=T2while语句和if语句的翻译涉及到布尔表达式,我们一并讨论。

产生布尔表达式三地址代码的语义规则如表7.1所示。

按表1的定义,每个形如A relop B的表达式(其中relop 为任一关系运算符)将被翻译为如下形式的两条转移指令:if A relop B goto …goto …因此,假定表达式的待确定的真假出口已分别为Ltrue和Lfalse,则a>0 or b>0将被翻译为:if a>0 goto Ltruegoto L1L1: if b>0 goto Ltruegoto Lfalse而c>0 and d<0将被翻译为:if c>0 goto L3goto LfalseL3: if d<0 goto Ltruegoto Lfalse有关if和while语句的属性文法如表2所示。

相关主题