编译原理课后答案——第七章_目标代码生成
编译原理 第7章习题解答

第七章习题解答7.1 给定文法:S→(A)A→ABBA→BB→bB→c①构造它的基本LR(0)项目集;②构造它的LR(0)项目集规范族;③构造识别该文法活前缀的DFA;④该文法是SLR文法吗?若是,构造它的SLR分析表。
7.2 给定文法:E→EE+E→EE*E→a①构造它的LR(0)项目集规范族;②它是SLR(1)文法吗?若是,构造它的SLR(1)分析表;③它是LR(1)文法吗?若是,构造它的LR(1)分析表;④它是LALR(1)文法吗?若是,构造它的LALR分析表。
7.3 给出一个非LR(0)文法。
7.4 给出一个SLR(1)文法,但它不是LR(0)文法,构造它的SLR分析表。
7.5 给出一个LR(1)文法,但它不是LALR(1)文法,构造它的规范LR(1)分析表。
7.6 给定二义性文法:① E→E+E② E→E*E③ E→(E)④ E→id用所述的无二义性规则和(或)另加一些无二义性规则,例如,给算符*、+施加某种结合规则。
①构造它的LR(0)项目集规范族及识别活前缀的DFA;②构造它的LR分析表。
习题参考答案7.1 解:文法的基本LR(0)项目集为S→.(A) S→(.A) S→(A.) S→(A).A→.ABB A→A.BB A→AB.B A→ABB.A→.B A→B. B→.b B→b.B→.c B→c.构造该文法的识别活前缀的DFSA如下图所示:I文法的识别活前缀的DFSA该文法的LR(0)项目集规范族={I0,I1,I2,I3,I4,I5,I6,I7,I8}因为在构造出来的识别活前缀的DFA中,每一个状态对应的项目集都不含有移进-归约、归约-归约冲突,所以该文法是LR(0)文法,当然也是SLR文法。
因为 FOLLOW(S)={#}FOLLOW(A)=FIRST{)}∪FIRST(BB)={),b,c}FOLLOW(B)=FIRST(B)∪FOLLOW(A)={b,c,)}其对应的SLR(1)分析表如下表所示。
《编译原理教程》第七章目标代码生成

中间代码优化的重要性
提高目标代码质量
通过消除冗余和无用代码、减少计算量、改进数据结构等方式,中间代码优化可以显著提高目标代码的质量和执行效 率。
降低硬件资源消耗
通过优化循环、减少内存访问等手段,中间代码优化可以减少硬件资源的消耗,如CPU、内存和存储器等,从而降低 系统成本和能耗。
提升软件可维护性和可靠性
案例二:控制流程的目标代码生成
总结词
通过生成条件语句和循环语句的目标代码,展示了控制流程的目标代码生成方法。
详细描述
对于条件语句,如"if a>b then c else d",生成的条件分支目标代码会根据条件表达式的值选择执行相应的语句。 对于循环语句,如"for i=0 to n do ... next",生成的目标代码会包含循环变量的初始化、循环条件检查和循环体 的执行。
案例三:复杂数据结构的目标代码生成
总结词
通过生成复杂数据结构(如数组和结构体)的目标代码,展示了目标代码生成在处理复杂数据结构时 的应用。
详细描述
对于数组,生成的目标代码会包含数组的声明、初始化和访问。对于结构体,生成的目标代码会包含 结构的声明、实例化和成员访问。例如,对于一个包含整型变量a和浮点型变量b的结构体,生成的目 标代码会包含结构体的声明、实例化以及访问结构体成员的指令。
03
提高执行效率
目标代码通常比源代码更 接近机器语言,因此执行 效率更高。
兼容性
目标代码可以在不同的计 算机和操作系统上运行, 提高了程序的兼容性。
安全性
目标代码可以隐藏源代码 中的敏感信息,提高程序 的安全性。
目标代码生成的基本步骤
语法分析
根据语法规则将词素组合成抽 象语法树(AST)。
编译原理第七章 习题参考答案

第1 题已知文法A→aAd|aAb|ε判断该文法是否是SLR(1)文法,若是构造相应分析表,并对输入串ab#给出分析过程。
答案:文法:A→aAd|aAb|ε拓广文法为G′,增加产生式S′→A若产生式排序为:0 S' →A1 A →aAd2 A →aAb3 A →ε由产生式知:First (S' ) = {ε,a}First (A ) = {ε,a}Follow(S' ) = {#}Follow(A ) = {d,b,#}G′的LR(0)项目集族及识别活前缀的DFA 如下图所示在I0 中:A →.aAd 和A →.aAb 为移进项目,A →.为归约项目,存在移进-归约冲突,因此所给文法不是LR(0)文法。
在I0、I2 中:Follow(A) ∩{a}= {d,b,#} ∩{a}=所以在I0、I2 中的移进-归约冲突可以由Follow 集解决,所以G 是SLR(1)文法。
构造的SLR(1)分析表如下:对输入串ab#的分析过程:第2 题若有定义二进制数的文法如下:S→L·L|LL→LB|BB→0|1(1) 试为该文法构造LR 分析表,并说明属哪类LR 分析表。
(2) 给出输入串101.110 的分析过程。
答案:文法:S→L.L|LL→LB|BB→0|1拓广文法为G′,增加产生式S′→S若产生式排序为:0 S' →S1 S →L.L2 S →L3 L →LB4 L →B5 B →06 B →1由产生式知:First (S' ) = {0,1}First (S ) = {0,1}First (L ) = {0,1}First (B ) = {0,1}Follow(S' ) = {#}Follow(S ) = {#}Follow(L ) = {.,0,1,#}Follow(B ) = {.,0,1,#}G′的LR(0)项目集族及识别活前缀的DFA 如下图所示:在I2 中:B →.0 和 B →.1 为移进项目,S →L.为归约项目,存在移进-归约冲突,因此所给文法不是LR(0)文法。
编译原理第三版课后习题答案

编译原理第三版课后习题答案编译原理是计算机科学中的一门重要课程,它研究的是如何将高级程序语言转换为机器语言的过程。
而《编译原理》第三版是目前被广泛采用的教材之一。
在学习过程中,课后习题是巩固知识、提高能力的重要环节。
本文将为读者提供《编译原理》第三版课后习题的答案,希望能够帮助读者更好地理解和掌握这门课程。
第一章:引论习题1.1:编译器和解释器有什么区别?答案:编译器将整个源程序转换为目标代码,然后一次性执行目标代码;而解释器则逐行解释源程序,并即时执行。
习题1.2:编译器的主要任务是什么?答案:编译器的主要任务是将高级程序语言转换为目标代码,包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等过程。
第二章:词法分析习题2.1:什么是词法分析?答案:词法分析是将源程序中的字符序列划分为有意义的词素(token)序列的过程。
习题2.2:请给出识别下列词素的正则表达式:(1)整数:[0-9]+(2)浮点数:[0-9]+\.[0-9]+(3)标识符:[a-zA-Z_][a-zA-Z_0-9]*第三章:语法分析习题3.1:什么是语法分析?答案:语法分析是将词法分析得到的词素序列转换为语法树的过程。
习题3.2:请给出下列文法的FIRST集和FOLLOW集:S -> aAbA -> cA | ε答案:FIRST(S) = {a}FIRST(A) = {c, ε}FOLLOW(S) = {$}FOLLOW(A) = {b}第四章:语义分析习题4.1:什么是语义分析?答案:语义分析是对源程序进行静态和动态语义检查的过程。
习题4.2:请给出下列文法的语义动作:S -> if E then S1 else S2答案:1. 计算E的值2. 如果E的值为真,则执行S1;否则执行S2。
第五章:中间代码生成习题5.1:什么是中间代码?答案:中间代码是一种介于源代码和目标代码之间的表示形式,它将源代码转换为一种更容易进行优化和转换的形式。
编译原理(清华大学-第2版)课后习题答案

编译原理(清华⼤学-第2版)课后习题答案第三章N=>D=> {0,1,2,3,4,5,6,7,8,9}N=>ND=>NDDL={a |a(0|1|3..|9)n且 n>=1}(0|1|3..|9)n且 n>=1{ab,}a nb n n>=1第6题.(1) <表达式> => <项> => <因⼦> => i(2) <表达式> => <项> => <因⼦> => (<表达式>) => (<项>)=> (<因⼦>)=>(i)(3) <表达式> => <项> => <项>*<因⼦> => <因⼦>*<因⼦> =i*i(4) <表达式> => <表达式> + <项> => <项>+<项> => <项>*<因⼦>+<项>=> <因⼦>*<因⼦>+<项> => <因⼦>*<因⼦>+<因⼦> = i*i+i (5) <表达式> => <表达式>+<项>=><项>+<项> => <因⼦>+<项>=i+<项> => i+<因⼦> => i+(<表达式>) => i+(<表达式>+<项>)=> i+(<因⼦>+<因⼦>)=> i+(i+i)(6) <表达式> => <表达式>+<项> => <项>+<项> => <因⼦>+<项> => i+<项> => i+<项>*<因⼦> => i+<因⼦>*<因⼦> = i+i*i第7题第9题语法树ss s* s s+aa a推导: S=>SS*=>SS+S*=>aa+a*11. 推导:E=>E+T=>E+T*F语法树:E+T*短语: T*F E+T*F直接短语: T*F句柄: T*F12.短语:直接短语:句柄:13.(1)最左推导:S => ABS => aBS =>aSBBS => aBBS=> abBS => abbS => abbAa => abbaa 最右推导:S => ABS => ABAa => ABaa => ASBBaa => ASBbaa => ASbbaa => Abbaa => a1b1b2a2a3 (2) ⽂法:S → ABSS → AaS →εA → aB → b(3) 短语:a1 , b1 , b2, a2 , , bb , aa , abbaa,直接短语: a1 , b1 , b2, a2 , ,句柄:a114 (1)S → ABA → aAb | εB → aBb | ε(2)S → 1S0S → AA → 0A1 |ε第四章1. 1. 构造下列正规式相应的DFA (1)1(0|1)*101NFA(2) 1(1010*|1(010)*1)*0NFA(3)NFA(4)NFA2.解:构造DFA 矩阵表⽰b其中0 表⽰初态,*表⽰终态⽤0,1,2,3,4,5分别代替{X} {Z} {X,Z} {Y} {X,Y} {X,Y,Z} 得DFA状态图为:3.解:构造DFA矩阵表⽰构造DFA的矩阵表⽰其中表⽰初态,*表⽰终态替换后的矩阵4.(1)解构造状态转换矩阵:{2,3} {0,1}{2,3}a={0,3}{2},{3},{0,1}{0,1}a={1,1} {0,1}b={2,2}(2)解:⾸先把M的状态分为两组:终态组{0},和⾮终态组{1,2,3,4,5} 此时G=( {0},{1,2,3,4,5} ) {1,2,3,4,5}a={1,3,0,5} {1,2,3,4,5}b={4,3,2,5}由于{4}a={0} {1,2,3,5}a={1,3,5}因此应将{1,2,3,4,5}划分为{4},{1,2,3,5}G=({0}{4}{1,2,3,5}){1,2,3,5}a={1,3,5}{1,2,3,5}b={4,3,2}因为{1,5}b={4} {23}b={2,3}所以应将{1,2,3,5}划分为{1,5}{2,3}G=({0}{1,5}{2,3}{4}){1,5}a={1,5} {1,5}b={4} 所以{1,5} 不⽤再划分{2,3}a={1,3} {2,3}b={3,2}因为 {2}a={1} {3}a={3} 所以{2,3}应划分为{2}{3}所以化简后为G=( {0},{2},{3},{4},{1,5})7.去除多余产⽣式后,构造NFA如下G={(0,1,3,4,6),(2,5)} {0,1,3,4,6}a={1,3}{0,1,3,4,6}b={2,3,4,5,6}所以将{0,1,3,4,6}划分为 {0,4,6}{1,3} G={(0,4,6),(1,3),(2,5)}{0,4,6}b={3,6,4} 所以划分为{0},{4,6} G={(0),(4,6),(1,3),(2,5)}不能再划分,分别⽤ 0,4,1,2代表各状态,构造DFA 状态转换图如下;b8.代⼊得S = 0(1S|1)| 1(0S|0) = 01(S|ε) | 10(S|ε) = (01|10)(S|ε)= (01|10)S | (01|10)= (01|10)*(01|10)构造NFA由NFA可得正规式为(01|10)*(01|10)=(01|10)+9.状态转换函数不是全函数,增加死状态8,G={(1,2,3,4,5,8),(6,7)}(1,2,3,4,5,8)a=(3,4,8) (3,4)应分出(1,2,3,4,5,8)b=(2,6,7,8)(1,2,3,4,5,8)c=(3,8)(1,2,3,4,5,8)d=(3,8)所以应将(1,2,3,4,5,8)分为(1,2,5,8), (3,4)G={(1,2,5,8),(3,4),(6,7)}(1,2,5,8)a=(3,4,8) 8应分出(1,2,5,8)b=(2,8)(1,2,5,8)c=(8)(1,2,5,8)d=(8)G={(1,2,5),(8),(3,4),(6,7)}(1,2,5)a=(3,4,8) 5应分出G={(1,2), (3,4),5, (6,7) ,(8) }去掉死状态8,最终结果为 (1,2) (3,4) 5,(6,7) 以1,3,5,6代替,最简DFA为b正规式:b*a(da|c)*bb*第五章1.S->a | ^ |( T )(a,(a,a))S => ( T ) => ( T , S ) => ( S , S ) => ( a , S) => ( a, ( T )) =>(a , ( T , S ) ) => (a , ( S , S )) => (a , ( a , a ) ) S=>(T) => (T,S) => (S,S) => ( ( T ) , S ) => ( ( T , S ) , S ) => ( ( T , S , S ) , S ) => ( ( S , S , S ) , S )=> ( ( ( T ) , S , S ) , S ) => ( ( ( T , S ) , S , S ) , S ) =>( ( ( S , S ) , S , S ) , S ) => ( ( ( a , S ) , S , S ) , S ) => ( ( ( a , a ) , S , S ) , S ) => ( ( ( a , a ) , ^ , S ) , S ) => ( ( ( a , a ) , ^ , ( T ) ) , S )=> ( ( ( a , a ) , ^ , ( S ) ) , S ) => ( ( ( a , a ) , ^ , ( a ) ) , S ) => ( ( ( a , a ) , ^ , ( a ) ) , a )S->a | ^ |( T )T -> T , ST -> S消除直接左递归:S->a | ^ |( T )T -> S T’T’ -> , S T’ | ξSELECT ( S->a) = {a}SELECT ( S->^) = {^}SELECT ( S->( T ) ) = { ( }SELECT ( T -> S T’) = { a , ^ , ( }SELECT ( T’ -> , S T’ ) = { , }SELECT ( T’ ->ξ) = FOLLOW ( T’ ) = FOLLOW ( T ) = { )}构造预测分析表分析符号串( a , a )#分析栈剩余输⼊串所⽤产⽣式#S ( a , a) # S -> ( T )# ) T ( ( a , a) # ( 匹配# ) T a , a ) # T -> S T’# ) T’ S a , a ) # S -> a# ) T’ a a , a ) # a 匹配# ) T’,a) # T’ -> , S T’# ) T’ S , , a ) # , 匹配# ) T’ S a ) # S->a# ) T’ a a ) # a匹配# ) T’) # T’ ->ξ# ) ) # )匹配# # 接受2.E->TE’E’->+E E’->ξT->FT’T’->T T’->ξF->PF’F’->*F’F’->ξP->(E) P->a P->b P->∧SELECT(E->TE’)=FIRST(TE’)=FIRST(T)= {(,a,b,^)SELECT(E’->+E)={+}SELECT(E’->ε)=FOLLOW(E’)= {#,)}SELECT(T->FT’)=FIRST(F)= {(,a,b,^}SELECT(T’ —>T)=FIRST(T)= {(,a,b,^)SELECT(T’->ε)=FOLLOW(T’)= {+,#,)}SELECT(F ->P F’)=FIRST(F)= {(,a,b,^}SELECT(F’->*F’)={*}SELECT(F’->ε)=FOLLOW(F’)= {(,a,b,^,+,#,)}3. S->MH S->a H->Lso H->ξK->dML K->ξL->eHf M->K M->bLM FIRST ( S ) =FIRST(MH)= FIRST ( M ) ∪FIRST ( H ) ∪{ξ}∪{a}= {a, d , b , e ,ξ} FIRST( H ) = FIRST ( L ) ∪{ξ}= { e , ξ}FIRST( K ) = { d , ξ}FIRST( M ) = FIRST ( K ) ∪{ b } = { d , b ,ξ}FOLLOW ( S ) = { # , o }FOLLOW ( H ) = FOLLOW ( S ) ∪{ f } = { f , # , o }FOLLOW ( K ) = FOLLOW ( M ) = { e , # , o }FOLLOW ( L ) ={ FIRST ( S ) –{ξ} } ∪{o} ∪FOLLOW ( K )∪{ FIRST ( M ) –{ξ} } ∪FOLLOW ( M )= {a, d , b , e , # , o }FOLLOW ( M ) ={ FIRST ( H ) –{ξ} } ∪FOLLOW ( S )∪{ FIRST ( L ) –{ξ} } = { e , # , o }SELECT ( S-> M H) = ( FIRST ( M H) –{ξ} ) ∪FOLLOW ( S )= ( FIRST( M ) ∪FIRST ( H ) –{ξ} ) ∪FOLLOW ( S )= { d , b , e , # , o }SELECT ( S-> a ) = { a }SELECT ( H->L S o ) = FIRST(L S o) = { e }SELECT ( H ->ξ) = FOLLOW ( H ) = { f , # , o }SELECT ( K->ξ) = FOLLOW ( K ) = { e , # , o }SELECT ( L-> e H f ) = { e }SELECT ( M->K ) = ( FIRST( K ) –{ξ} ) ∪FOLLOW ( M ) = {d,e , # , o }SELECT ( M -> b L M )= { b }4 . ⽂法含有左公因式,变为S->C $ { b, a }C-> b A { b }C-> a B { a }A -> b A A { b }A-> a A’ { a }A’-> ξ{ $ , a, b }A’-> C { a , b }B->a B B { a }B -> b B’ { b }B’->ξ{ $ , a , b }B’-> C { a, b }5. <程序> --- S <语句表>――A <语句>――B <⽆条件语句>――C <条件语句>――D <如果语句>――E <如果⼦句> --FS->begin A end S->begin A end { begin }A-> B A-> B A’ { a , if }A-> A ; B A’-> ; B A’ { ; }A’->ξ{ end }B-> C B-> C { a } B-> D B-> D { if }C-> a C-> a { a }D-> E D-> E D’ { if }D-> E else B D’-> else B { else }D’->ξ{; , end } E-> FC E-> FC { if }F-> if b then F-> if b then { if }⾮终结符是否为空S-否A-否A’-是B-否C-否D-否D’-是E-否F-否FIRST(S) = { begin }FIRST(A) = FIRST(B) ∪FIRST(A’) ∪{ξ} = {a , if , ; , ξ} FIRST(A’) ={ ; , ξ}FIRST(B) = FIRST(C) ∪FIRST(D) ={ a , if }FIRST(C) = {a}FIRST(D) = FIRST(E)= { if }FIRSR(D’) = {else , ξ}FIRST(E) = FIRST(F) = { if }FIRST(F) = { if }FOLLOW(S) = {# }FOLLOW(A) = {end}FOLLOW(A’) = { end }FOLLOW(B) = {; , end }FOLLOW (C) = {; , end , else }FOLLOW(D) = {; , end }FOLLOW( D’ ) = { ; , end }FOLLOW(E) = { else , ; end }FOLLOW(F) = { a }S A A’ B C D D’ E F if then else begin end a b ;6. 1.(1) S -> A | B(2) A -> aA|a(3)B -> bB |b提取(2),(3)左公因⼦(1) S -> A | B(2) A -> aA’(3) A’-> A|ξ(4) B -> bB’(5) B’-> B |ξ2.(1) S->AB(2) A->Ba|ξ(3) B->Db|D(4) D-> d|ξ提取(3)左公因⼦(1) S->AB(2) A->Ba|ξ(3) B->DB’(4) B’->b|ξ(5) D-> d|ξ3.(1) S->aAaB | bAbB(2) A-> S| db(3) B->bB|a4(1)S->i|(E)(2)E->E+S|E-S|S提取(2)左公因⼦(1)S->i|(E)(2)E->SE’(3)E’->+SE’|-SE’ |ξ5(1)S->SaA | bB(2)A->aB|c(3)B->Bb|d消除(1)(3)直接左递归(1)S->bBS’(2)S’->aAS’|ξ(3)A->aB | c(4) B -> dB’(5)B’->bB’|ξ6.(1) M->MaH | H(2) H->b(M) | (M) |b消除(1)直接左递归,提取(2)左公因⼦(1)M-> HM’(2)M’-> aHM’ |ξ(3)H->bH’ | ( M )(4)H’->(M) |ξ7. (1)1)A->baB4)B->a将1)、2)式代⼊3)式1)A->baB2)A->ξ3)B->baBbb4)B->bb5)B->a提取3)、4)式左公因⼦1)A->baB2)A->ξ3)B->bB’4)B’->aBbb | b5)B->a(3)1)S->Aa2)S->b3)A->SB4)B->ab将3)式代⼊1)式1)S->SBa2)S->b3)A->SB4)B->ab消除1)式直接左递归1)S->bS’2)S’->BaS’ |ξ3)S->b4)A->SB5)B->ab删除多余产⽣式4)1)S->bS’(5)1)S->Ab2)S->Ba3)A->aA4)A->a5)B->a提取3)4)左公因⼦1)S->Ab4)A’-> A |ξ5)B->a将3)代⼊1)5)代⼊21)S->aA’b2)S->aa3)A->aA’4)A’-> A |ξ5)B->a提取1)2)左公因⼦1)S-> aS’2)S’->A’b | a3)A->aA’4)A’-> A |ξ5)B->a删除多余产⽣式5)1)S-> aS’2)S’->A’b | a3)A->aA’4)A’-> A |ξA A’S’S将3)代⼊4)1)S-> aS’2)S’->A’b | a3)A->aA ’4)A’-> aA’ |ξ3)S’->a4)S’->b5)A->aA ’6)A’-> aA’ |ξ对2)3)提取左公因⼦1)S->aS’2)S’->aS’’3)S’’->A’b|ξ4)S’->b5)A->aA ’6)A’-> aA’ |ξ删除多余产⽣式5)1)S->aS’2)S’->aS’’3)S’’->A’b|ξ4)S’->b第六章1S → a | ∧ | ( T )T → T , S | S解:(1) 增加辅助产⽣式 S’→#S#求 FIRSTVT集FIRSTVT(S’)= {#}FIRSTVT(S)= {a ∧ ( }= { a ∧ ( } FIRSTVT (T) = {,} ∪ FIRSTVT( S ) = { , a ∧ ( }求 LASTVT集LASTVT(S’)= { # }LASTVT(S)= { a ∧ )}LASTVT (T) = { , a ∧ )}(2)因为任意两终结符之间⾄多只有⼀种优先关系成⽴,所以是算符优先⽂法(3)a ∧( ) , #F 1 1 1 1 1 1g 1 1 1 1 1 1f 2 2 1 3 2 1g 2 2 2 1 2 1f 3 3 1 3 3 1g 4 4 4 1 2 1f 3 3 1 3 3 1g 4 4 4 1 2 1(4)栈优先关系当前符号剩余输⼊串移进或规约#<·( a,a)# 移进#( <· a ,a)# 移进#(T <·, a)# 移进#(T,<· a )# 移进#(T,a ·> ) # 规约#(T,T ·> ) # 规约#(T =·) # 移进#(T) ·> #规约#T =·#接受4.扩展后的⽂法S’→#S# S→S;G S→G G→G(T) G→H H→a H→(S)T→T+S T→S(1)FIRSTVT(S)={;}∪FIRSTVT(G) = {; , a , ( }FIRSTVT(G)={ ( }∪FIRSTVT(H) = {a , ( }FIRSTCT(H)={a , ( }FIRSTVT(T) = {+} ∪FIRSTVT(S) = {+ , ; , a , ( }LASTVT(S) = {;} ∪LASTVT(G) = { ; , a , )}LASTVT(G) = { )} ∪LASTVT(H) = { a , )}LASTVT(H) = {a, )}LASTVT(T) = {+ } ∪LASTVT(S) = {+ , ; , a , ) }构造算符优先关系表因为任意两终结符之间⾄多只有⼀种优先关系成⽴,所以是算符优先⽂法(2)句型a(T+S);H;(S)的短语有:a(T+S);H;(S) a(T+S);H a(T+S) a T+S (S) H直接短语有: a T+S H (S)句柄: a素短语:a T+S (S)最左素短语:a(3)(4)不能⽤最右推导推导出上⾯的两个句⼦。
编译原理(第二版)清华大学---答案详解

第1章引论第1题解释下列术语:(1)编译程序(2)源程序(3)目标程序(4)编译程序的前端(5)后端(6)遍答案:(1) 编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。
(2) 源程序:源语言编写的程序称为源程序。
(3) 目标程序:目标语言书写的程序称为目标程序。
(4) 编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。
通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符号表管理等工作。
(5) 后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。
(6) 遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。
第2题一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程序的总体结构图。
答案:一个典型的编译程序通常包含8个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。
其各部分的主要功能简述如下。
词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。
语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。
语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。
中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式的中间语言代码,如三元式或四元式。
中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。
目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。
表格管理程序:负责建立、填写和查找等一系列表格工作。
表格的作用是记录源程序的各类信息和编译各阶段的进展情况,编译的每个阶段所需信息多数都从表格中读取,产生的中间结果都记录在相应的表格中。
编译原理课后习题答案

编译原理课后习题答案编译原理习题答案习题11.1翻译程序:把⽤某种程序设计语⾔(源语⾔)编写的程序(源程序)翻译成与之等价的另⼀种语⾔(⽬标语⾔)的程序(⽬标程序)。
编译程序:⼀种翻译程序,将⾼级语⾔编写的源程序翻译成等价的机器语⾔或汇编语⾔的⽬标程序。
1.2词法分析、语法分析、语义分析和中间代码⽣成、代码优化、⽬标代码⽣成1.3词法分析:根据语⾔的词法规则对构成源程序的符号进⾏扫描和分解,识别出⼀个个的单词。
语法分析:根据语⾔的语法规则,把单词符号串分解成各类语法单位。
语义分析及中间代码⽣成:对语法分析识别出的语法单位分析其含义,并进⾏初步翻译。
代码优化:对中间代码进⾏加⼯变换,以产⽣更⾼效的⽬标代码。
⽬标代码⽣成:将中间代码变换成特定机器上的绝对指令代码、可重定位的指令代码或会变指令代码。
以上5个阶段依次执⾏。
习题22.1 (1)有穷⾮空的符号集合(2)利⽤产⽣是规则A->v将A替换为v时与A的上下⽂⽆关。
(3)略(4)推导是把句型中的⾮终结符⽤⼀个产⽣是规则的右部开替代的过程;直接推导是将⾮终结符的替代结果只⽤了⼀次产⽣式规则。
(5)略(6)⼀个句型的最左直接短语(7)如果⼀个⽂法存在某个句⼦对应两棵不同的语法树或有两个不同的最左(右)推导,则称这个⽂法是⼆义的。
2.2(1)VN ={Z,A,B} VT ={a,b,c,d,e}(2)abbcde,abbbcde是,acde不是。
2.3 (1)L[G]={d|n≥1,m≥0}(2)2.4 (1) A=>B=>c=>fAg=>fBg=>fCg=>feg(2)A=>AaB=>AaC=>Aae=>Bae=>BcCae=>Bceae=>Cceae=>eceae(3)A=>B=>BcC=>BcfAg=>BcfAaBg=>BcfAaCg=>BcfAaeg=>BcfBaeg =>BcfCaeg=>Bcfeaeg=>Ccfeaeg=>ecfeaeg(3)中题⽬有错应为C fCg|e2.5L[G]={a?b?c?|aab,n≥2}2.6 (1)Z→AB A→Aa|ε B→Bb|ε(2)Z→aZb|ab(3)Z→aAb A→aAb|b(4)Z→AB A→aAb|ab B→cB|ε(5)Z→aaAb|ab Z→aaBb|bb A→aaAb|ab B→aaBb|bb2.7 ⼀位数:Z→2|4|6|8两位数:Z→AB A→1|2|3|4|5|6|7|8|9 B→0|2|4|6|8三位以上:Z→ACB A→1|2|3|4|5|6|7|8|9 B→0|2|4|6|8 C→CDD→0|1|2|3|4|5|6|7|8|92.8证明:E=>E+T=>E+T*F短语:T*F E+T*F 直接短语:T*F 句柄:T*F2.9 语法树: E 短语:E*T , (E*T) , F↑(E*T) ,F ,E* F↑(E*T)E *F 直接短语:E*T , FT ↑ F 句柄:FF ( E )E * T2.10(1)语法树(2)直接短语:a , ZZ 句柄:Z( L )L , ZZ ( L )Za2.11最左推导:Z=>ZaB=>BaB=>B+AaB=>A+AaB=>(+)Z*aB=>(+)ZaB*aB =>(+)+aB*aB=>(+)+aA*aB=>(+)+a(*aB=>(+)+a(*aA=>(+)+a(*a(直接短语:(,+句柄:(2.12(1) S=>iSeS=>iiSeS=>iiIeS=>iiIeIS=>iS=>iiSeS=>iiIeS=>iiIeI(2) S=>SaS=>cSaS=>cfaS=>cfafS=>cS=>cSaS=>cfaS=>cfaf(3) E=>EOE=>EOEOE=>iOEOE=>i+EOE=>i+iOE=>i+i-E=>i+i-iE=>EOE=>iOE=>i+E=>i+EOE=>i+iOE=>i+i-E=>i+i-i2.13 Z→aABZ|cCACdA→bAB|aZA|cCCB→bAB|CzbC→cZ|c习题33.1(1)确定的有限⾃动机(2)不确定的有限⾃动机(3)正规集是⼀类特殊的单词集合,正规式是正规集的描述⼯具 3.2 (1) (1|2|3|4|5|6|7|8|9|0)*(1|3|5|7|9) (2) 11(0|1)*00 3.3 证明:b *(a|b)+={a,b,ab,ba,aa,bb …} (a|b)+={a,b,ab,ba,aa,bb …} 3.4 (1)(2)DDDD3.5(1) (2)(3)3.6(1) (01|10) *(01|10)(2) (0(1|00)*)|003.7(1) Z →1AB (2)Z →ABA →(0|1)A A →0A|εA →0|1B →(0|1)B|ε B →0B B →ε3.8 r=a(a|b )*bb3.9 Z →1BB →0Z|0 Z →0Z|ε3.10 3.11DDD习题44.1 (1)若⽂法G[Z]满⾜①⽂法不含左递归②③(2)4.2(1) First(S)={a,d} First(B)={a,d,c,ε}First(A)={a,d,e,c} First(D)={a,d,ε}Follow(S)={#,a,b,d,e} Follow(B)={a,d}Follow(A)={b} Follow(D)={e,a,d,b}(2) 不是4.3 (1) 证明: First(Z)={a,b,c} Follow(S)={#,a,b,c,d} First(A)={a,b,c,d} Follow(A)={ #,a,b,c,d }First(B)={a,d,c} Follow(B)={ a,b,c,d } 是LL(1)⽂法。
编译原理中间代码生成7

7.1 中 间 语 言
7.1.4 静态单赋值形式 • 一种便于某些代码优化的中间表示 • 和三地址代码的主要区别
– 所有赋值指令都是对不同名字的变量的赋值 – 一个变量在不同路径上都定值的解决办法
if (flag) x = 1; else x = 1; y = x a; 的条件语句改成 if (flag) x1 = 1; else x2 = 1;
assign
assign
a
+
a
+
+
+
uminus c
d
uminus
c
d
c
d
b (a) 语法树
b (b) dag
a = (b + cd) + cd的图形表示
7.1 中 间 语 言
构造赋值语句语法树的语法制导定义
产生式
语义规则
S id =E S.nptr = mkNode(‘assign’, mkLeaf (id, id.entry), E.nptr)
a = (b + cd ) + cd 语法树的代码
t1 = b t2 = c d t3 = t1 + t2 t4 = c d t5 = t3 + t4 a = t5
uminus
7.1 中 间 语 言
三地址代码是语法树或dag的一种线性表示
a = (b + cd ) + cd
语法树的代码 dag的代码
7.2 声 明 语 句
P M D; S {addWidth (top (tblptr), top (offset) ); pop(tblptr); pop (offset) }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
地址
1000 1003 1006 1008
机器码
B80100 BB1000 39D8 7702
100A
100C
01D8
第七章 目标代码生成 MOV R, a ADD R, b
MOV T, R
第一条指令是将第一操作数a由内存取到寄存器R 中;第二条指令完成加法运算;第三条指令将累加后 的结果送回内存中的变量T。是否在翻译成目标代码时 都必须生成这三条汇编指令呢?从目标代码生成的优 化角度考虑,即为了使生成的目标代码更短以及充分 利用寄存器,上面的三条指令中,第一条和第三条指 令在某些情况下是不必要的。这是因为,如果下一个 四元式紧接着需要引用操作数T,则第三条指令就不急 于生成,可以推迟到以后适当的时机再生成。
第七章 目标代码生成 此外,如果必须使用第一条指令,即第一操作数 不在寄存器而是在内存中,且此时所有可用寄存器都 已分配完毕,这时就要根据寄存器中所有变量的待用 信息(也即引用点)来决定淘汰哪一个寄存器留给当前 的四元式使用。寄存器的淘汰策略如下: (1) 如果某寄存器中的变量已无后续引用点且该 变量是非活跃的,则可直接将该寄存器作为空闲寄存 器使用。 (2) 如果所有寄存器中的变量在基本块内仍有引 用点且都是活跃的,则将引用点最远的变量所占用寄 存器中的值存放到内存与该变量对应的单元中,然后 再将此寄存器分配给当前的指令使用。
第七章 目标代码生成 【解答】 的注释): MOV R0, B SUB R0 , C 果*/ MOV R1, A MUL R1, R0 */ 该基本块的目标代码如下(指令后面为相应 /*取第一个空闲寄存器R0*/ /*运算结束后R0中为T1结果,内存中无该结 /*取一个空闲寄存器R1*/ /*运算结束后R1 中为T2 结果,内存中无该结果
/*S引用点较T引用点远,故将R1
/*R1=W*/ /*R1=U*/ /*R1=V*/
第七章 目标代码生成 7.2 假设可用的寄存器为R0 和R1 ,且所有临时单
元都是非活跃的,试将以下四元式基本块: T1=B-C T2=A*T1
T3=D+1
T4=E-F T5=T3*T4 W=T2/T5 用简单代码生成算法生成其目标代码。
MOV W, R1 /*指令翻译完毕时,寄存器中 存有最新的计算结果,必须将它们存回到内存 相应的单元中去,否则,在翻译下一个基本块 时,所有的寄存器被当成空闲的寄存器使用, 从而造成计算结果的丢失。考虑到寄存器R0 中 的T5 和寄存器R1 中的W,临时单元T5 是非活跃 的,因此只要将结果W存回对应单元即可*/
MUL R0, R1 /*运算结束后R0中为T5结果,内存中无该 结果。注意,该指令将寄存器R0中原来的结果T3冲掉了。可 以这么做的原因是,T3 在该指令后不再有引用点,且是非 活跃变量*/
第七章 目标代码生成 MOV R1, T2 /*此时R1中结果T4已经没有引 用点,且临时单元T4 是非活跃的,因此寄存器 R1可作为空闲寄存器使用*/ DIV R1, R0 /*运算结束后R1中为W结果,内存中 无该结果。此时所有指令部分已经翻译完毕*/
第七章 目标代码生成 7.3 对基本块P: S0=2 S1=3/S0 S2=T-C S3=T+C
R=S0/S3
H=R S4=3/S1 S5=T+C S6=S4/S5
H=S6*S2
第七章 目标代码生成 (1) 试应用DAG进行优化; (2) 假定只有R、H在基本块出口是活跃的,写出
第七章 目标代码生成
第七章 目标代码生成
7.1 对下列四元式序列生成目标代码: T=A-B S=C+D
W=E-F
U=W/T V=U*S 其中,V是基本块出口的活跃变量,R0和R1是可用寄存 器。
第七章 目标代码生成 【解答】 简单代码生成算法依次对四元式进行翻译。
我们以四元式T=a+b为例来说明其翻译过程。 汇编语言的加法指令代码形式为 ADD R, X 其中,ADD为加法指令;R为第一操作数,第一操作数必 须为寄存器类型;X为第二操作数,它可以是寄存器类型,也 可以是内存型的变量。ADD R,X指令的含意是:将第一操作数 R与第二操作数相加后,再将累加结果存放到第一操作数所在 的寄存器中。要完整地翻译出四元式T=a+b,则可能需要下面 三条汇编指令:
第七章 目标代码生成 因此,本题所给四元式序列生成的目标代码如下: MOV R0, A SUB R0, C MOV R1, C ADD R1, D /*R1=S*/ /*R0=T*/
MOV S, R1 的值送内存单元S*/
MOV R1, E SUB R1, F SUB R1, R0 MUL R1, S
图7-1 基本块P的DAG
第七章 目标代码生成 按图7-1(h)和原来构造结点的顺序,优化后的四元式 序列为 S0=2 S4=2 S1=1.5
S2=T-C
S3=T+C S5=S3 R=2/S3 S6=R H=S6*S2
第七章 目标代码生成 (2) 假定只有R、H在基本块出口是活跃的,则上 述优化后的四元式序列可进一步优化为
第七章 目标代码生成 7.4 参考附录1和附录2(《编译原理教程》一书), 将下列汇编程序片段翻译为对应的8086/8088机器语言 代码(汇编地址由1000开始): MOV AX,01 MOV BX,10
CMP AX,BX
JA L1 ADD AX,BX
第七章 目标代码生成 L1: 【解答】 该汇编程序片段翻译如下:
S0=T-C
S3=T+C R=2/S3 H=R*S2
第七章 目标代码生成 (3) 假定只有两个寄存器AX、BX,上述优化后的四元 式序列的目标代码为 MOV AX, T SUB AX, C MOV AX, S2
MOV AX, T
ADD AX, C MOV BX, 2
DIV
BX
MOV AX, S2 MUL BX MOV BX, H
MOV R0, 用点,且临时单元T1是 空闲寄存器使用*/ ADD R0, ″1″ 中无该结果*/
D /*此时R0 中结果T1 已经没有引 非活跃的,所以,寄存器R0可作为 /*运算结束后R0 中为T3 结果,内存
第七章 目标代码生成 MOV T2, R1 /*翻译四元式T4=E-F时,所有寄存器已经 分配完毕,寄存器R0中存的T3和寄存器R1中存的T2都是有用 的。由于T2的下一个引用点较T3的下一个引用点更远,所以 暂时可将寄存器R1中的结果存回到内存的变量T2中,从而将 寄存器R1空闲以备使用*/ MOV R1, E /*运算结束后R1中为T4结果,内存 SUB R1, F 中无该结果*/
优化后的四元序列;
(3) 假定只有两个寄存器AX、BX,试写出上述优 化后的四元式序列的目标代码。
【解答】
(1) 根据DAG的构造算法构造基本块P
的DAG步骤如图7-1所示的(a)到(h)。
第七章 目标代码生成
n4 S2 - n0 S0 2 (a) n0 S0 2 (b) n6 R / n5 S3 + n0 S0 2 n1 S1 1.5 (e) n2 T S24 S2 n - n3 C n0 S0 2 n1 S1 1.5 (f) n7 H n6 / R,H,S 6 n5 S3 + n0 S0,S4 n1 S1 2 1.5 (g) n2 T S24 S2 n - n3 C n0 S0,S4 n1 S1 2 1.5 (h) n6 / R,H,S 6 n5 S3,S5 S24 S2 n + n2 T - n3 C n1 S1 1.5 n0 S0 2 n1 S1 1.5 (c) n6 / R,H n5 S3 + n2 T S24 S2 n - n3 C n2 T n3 C n0 S0 2 n1 S1 1.5 (d ) n5 S3 + n2 T S24 S2 n - n3 C