编译原理课后第十一章答案
编译原理第六章到第十一章课后习题答案
编译原理第六章到第十一章课后习题答案p116/1.已知文法G[S]为:S→a|∧|(T)T→T,S|S(1) 计算FIRSTVT -- LASTVT表(2) 构造算符优先关系表(OPERATER PRIORITY RELATION TABLE),说明是否为算符优先文法。
=: #=#, (=)<: (< FIRSTVT(T) , ,<firstvt(s)<="" ,="" p="">>:LASTVT(S)># , LASTVT(T)>), LASTVT(T)> ,表中无多重人口所以是算符优先(OPG)文法。
(3)计算G[S]的优先函数。
收敛(4)对输入串(a,a)#的算符优先分析过程为Success!3.有文法G(S):s->Vv->T/ViTT->F/T+FF->)V*|((1)(+(i(的规范推导S=>V=>ViT=>ViF=>Vi(=>Ti(=>T+Fi(=>T+(i(=>F+(i(=>(+(i((2)F+Fi(的短语、句柄、素短语。
短语S: F+Fi(T1:F+F (素短语)T2:F (句柄)F:( (素短语)(3) G(S)是否为OPG?若是,给出(1)中句子的分析过程!S’->#S# S->V V->T/ViT T->F/T+F F->)V*|(算符优先关系表(OPERATER PRIORITY RELATION TABLE)对输入串(+(I(的算符优先分析过程为:p152/2文法:S→L.L|LL→LB|BB→0|1拓广文法为G′,增加产生式S′→SI3若产生式排序为: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如下图所示:I5B →.0和B →.1为移进项目,S →L.为归约项目,存在移进-归约冲突,因此所给文法不是LR(0)文法。
编译原理(清华大学-第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短语: T*F E+T*F直接短语: T*F句柄: T*F12.<E><E> <T> <POP><T> <F> <MOP>短语:<T><F><MOP> <E><T><F><MOP><POP>直接短语:<T><F><MOP>句柄: <T><F><MOP>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 矩阵表示a,bb其中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如下确定化,构造DFA 矩阵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 )T -> T , S | S(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-> d M L ) = { d }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->baB2)A->ξ3)B->Abb4)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’2)S’->BaS’ |ξ3)S->b4)B->ab(5)1)S->Ab2)S->Ba3)A->aA4)A->a提取3)4)左公因子1)S->Ab2)S->Ba3)A->aA’4)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’ |ξ将4)代入2)1)S-> aS’2)S’->aA’b3)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’3)S’’->A’b|ξ4)S’->b5)A’-> aA’ |ξ第六章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)# 移进# (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)分析a;(a+a)不能用最右推导推导出上面的两个句子。
CPrimer 第11章泛型算法课后习题答案
第11章-泛型算法1.algorithm头文件定义了一个名为count的函数,其功能类似于find。
这个函数使用一对迭代器和一个值做参数,返回这个值出现的次数的统计结果。
编写程序读取一系列int型数据,并将它们存储到vector对象中然后统计某个指定的值出现了多少次。
// 11.17_11.1_int_to_vector_count.cpp : 定义控制台应用程序的入口点。
//#include"stdafx.h"#include<vector>#include<iostream>#include<algorithm>using namespace std;int _tmain(int argc, _TCHAR* argv[]){cout << "\tInput some int numbers ( ctrl + z to end):\n\t ";vector<int> iVec;int iVal;while ( cin >> iVal )iVec.push_back( iVal );cout << "\n\tInput a num to search in the iVec: ";cin.clear();cin >> iVal;int iCnt = 0;if ( iCnt = count( iVec.begin(), iVec.end(), iVal )){cout << "\n\tThe value " << iVal << " occurs " << iCnt << " times." << endl;}system("pause");return 0;}2.重复前面的程序,但是,将读入的值存储到一个string类型的list对象中。
编译原理蒋宗礼课件第11章
关键任务
进行类型检查、确定符号引 用的含义,以及生成中间代 码等。
工具
语义分析是编译过程中相当 复杂的一部分,通常需要使 用自定义的算法和工具进行 实现。
中间代码生成
1 什么是中间代码生成?
在编译过程的中间阶段,将源代码转化为计算机独立的中间表示形式。
2 优点
中间代码的生成可以简化编译器的设计和实现,并提供了优化和代码生成的灵活性。
编译原理蒋宗礼课件第11章
在本章中,我们将深入探讨编译原理的各个方面,包括词法分析、语法分析、 语义分析等等。
编译原理概述
什么是编译原理?
编译原理是计算机科学中的重要领域,研究如 何将高级语言编写的程序转化为计算机能够理 解和执行的机器码。
编译原理的应用
编译原理在各个领域都有广泛的应用,包括编 译器设计、程序语言设计以及软件工程等。
通过使用上下文无关文法 (Context-Free Grammar),语法 分析器可以验证源代码是否符合 语言的语法规则。
工具
常用的语法分析工具包括ANTLR、 Bison等,它们能够根据预先定义 好的文法生成语法分析器。
语义分析
什么是语义分析?
语义分析是编译过程中的第 三步,通过对语法树进行遍 历和分析,对源代码进行意 义的理解和检查。
为不同的Token类型,如标识符、关键字、
运算符等。
3
什么是词法分析?
词法分析是编译过程中的第一步,将源 代码转化为单词序列(Token Sequence)。
工具
常用的词法分析工具包括Flex等,它们能 够根据预先定义好的规则生成词法分析 器。
语法分析
什么是语法分析?
关键概念
语法分析是编译过程中的第二步, 将词法分析得到的Token序列转化 为语法树(Parse Tree)。
编译原理第11章
W:= V + U
ADD R0 , R1
R0含有W
W在R0中
§11.3一个简单的代码生成器
§11.4寄存器分配
一、问题引入:如何有效的利用寄存器; 1、基本块内: ①运算对象的值在寄存器中,则把该寄存器作为操作数地址; ②尽可能把各变量的现行值保存在寄存器中; ③基本块中不再引用的变量所占用的寄存器及早释放; 2、循环内: 按执行代价把寄存器固定分配给几个变量单独使用; 二、指令的执行代价 1、定义:指令的执行代价=指令访问内存单元的次数+1 2、例:op Ri,Ri执行代价为1; op Ri,M执行代价为2; op Ri,*Ri执行代价为2; op Ri,*M执行代价为3 3、应用:对循环中每个变量计算把某寄存器分配给它时执行代 价能节省多少,以决定寄存器的固定分配方案;
三、寄存器描述和地址描述 1、寄存器描述数组RValue:记录寄存器使用情况(空闲或已分配) 2、变量地址描述数组AValue:记录各变量现行值的存放位置(在 寄存器或内存单元); 四、基本块内代码生成算法 对块内每个中间代码 i: A:= B op C,依次执行:
调用GetReg(i:A:=B op C)得一寄存器R,用以存放A现行值; 利用AValue[B]和AValue[C]确定B和C现行值的存放位置B 和C 若B ≠R 则生成目标代码:LD R,B 和op R,C 若B =R 则生成op R,C 若B 或C 为R 则删除AValue[B]或AValue[C]中的R 令AValue[A]={R},RValue[R]={A} 若B或C的现行值在块内不再被引用且也不是块出口后的活跃变量 (由中间代码i的附加信息可知)且现行值在某寄存器Rk中 则删除RValue[Rk]中的B或C及AValue[B]或AValue[C]中的Rk
(完整版)编译原理课后答案(第三版蒋立源康慕宁编)
编译原理课后答案(第三版蒋立源康慕宁编)第一章习题解答1解:源程序是指以某种程序设计语言所编写的程序。
目标程序是指编译程序(或解释程序)将源程序处理加工而得的另一种语言(目标语言)的程序。
翻译程序是将某种语言翻译成另一种语言的程序的统称。
编译程序与解释程序均为翻译程序,但二者工作方法不同。
解释程序的特点是并不先将高级语言程序全部翻译成机器代码,而是每读入一条高级语言程序语句,就用解释程序将其翻译成一段机器指令并执行之,然后再读入下一条语句继续进行解释、执行,如此反复。
即边解释边执行,翻译所得的指令序列并不保存。
编译程序的特点是先将高级语言程序翻译成机器语言程序,将其保存到指定的空间中,在用户需要时再执行之。
即先翻译、后执行。
2解:一般说来,编译程序主要由词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、代码优化程序、目标代码生成程序、信息表管理程序、错误检查处理程序组成。
3解:C语言的关键字有:auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while。
上述关键字在C语言中均为保留字。
4解:C语言中括号有三种:{},[],()。
其中,{}用于语句括号;[]用于数组;()用于函数(定义与调用)及表达式运算(改变运算顺序)。
C语言中无END关键字。
逗号在C语言中被视为分隔符和运算符,作为优先级最低的运算符,运算结果为逗号表达式最右侧子表达式的值(如:(a,b,c,d)的值为d)。
5略第二章习题解答1.(1)答:26*26=676(2)答:26*10=260(3)答:{a,b,c,...,z,a0,a1,...,a9,aa,...,az,...,zz,a00,a01,...,zzz},共26+26*36+26*36*36=34658个2.构造产生下列语言的文法(1){anbn|n≥0}解:对应文法为G(S) = ({S},{a,b},{ S→ε| aSb },S)(2){anbmcp|n,m,p≥0}解:对应文法为G(S) = ({S,X,Y},{a,b,c},{S→aS|X,X→bX|Y,Y→cY|ε},S)(3){an # bn|n≥0}∪{cn # dn|n≥0}解:对应文法为G(S) = ({S,X,Y},{a,b,c,d,#}, {S→X, S→Y,X→aXb|#,Y→cYd|# },S)(4){w#wr# | w?{0,1}*,wr是w的逆序排列}解:G(S) = ({S,W,R},{0,1,#}, {S→W#, W→0W0|1W1|# },S)(5)任何不是以0打头的所有奇整数所组成的集合解:G(S) = ({S,A,B,I,J},{-,0,1,2,3,4,5,6,7,8,9},{S→J|IBJ,B→0B|IB|e, I→J|2|4|6|8, Jà1|3|5|7|9}, S)(6)所有偶数个0和偶数个1所组成的符号串集合解:对应文法为S→0A|1B|e,A→0S|1C B→0C|1S C→1A|0B3.描述语言特点(1)S→10S0S→aAA→bAA→a解:本文法构成的语言集为:L(G)={(10)nabma0n|n, m≥0}。
编译原理课后习题答案(陈火旺+第三版)
编译原理课后习题答案(陈火旺+第三版)第二章P36-6(1)L G ()1是0~9组成的数字串(2) 最左推导:N ND NDD NDDD DDDD DDD DD D N ND DD D N ND NDD DDD DD D ⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒0010120127334556568最右推导:N ND N ND N ND N D N ND N D N ND N ND N D ⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒⇒77272712712701274434886868568P36-7G(S)O N O D N S O AO A AD N→→→→→1357924680|||||||||||P36-8文法:E T E T E T TF T F T F F E i→+-→→|||*|/()|最左推导:E E T T TF T i T i T F i F F i i F i i i E T T F F F i F i E i E T i T T i F T i i T i i F i i i ⇒+⇒+⇒+⇒+⇒+⇒+⇒+⇒+⇒⇒⇒⇒⇒⇒+⇒+⇒+⇒+⇒+⇒+********()*()*()*()*()*()*()最右推导:E E T E TF E T i E F i E i i T i i F i i i i i E T F T F F F E F E T F E F F E i F T i F F i F i i i i i ⇒+⇒+⇒+⇒+⇒+⇒+⇒+⇒+⇒⇒⇒⇒⇒+⇒+⇒+⇒+⇒+⇒+⇒+**********()*()*()*()*()*()*()*()语法树:/********************************EE FTE +T F F T +iiiEEFTE-T F F T -iiiEEFT+T F FTiii*i+i+ii-i-ii+i*i*****************/P36-9句子iiiei 有两个语法树: S iSeS iSei iiSei iiiei S iS iiSeS iiSei iiiei ⇒⇒⇒⇒⇒⇒⇒⇒P36-10/**************)(|)(|S T T TS S →→***************/1 ε ε 1 0 11 确定化:1 1111 1 最小化:{,,,,,},{}{,,,,,}{,,}{,,,,,}{,,,}{,,,,},{},{}{,,,,}{,,}{,,,},{},{},{}{,,,}{,012345601234513501234512460123456012341350123456012310100==== 3012312401234560110112233234012345610101}{,,,}{,,}{,},{,}{},{},{}{,}{}{,}{,}{,}{}{,}{}{},{},{,},{},{},{}=====0 1111 1P64–8(1) 01)0|1(*(2))5|0(|)5|0()9|8|7|6|5|4|3|2|1|0)(9|8|7|6|5|4|3|2|1(*(3)******)110|0(01|)110|0(10P64–12(a)aa确定化:给状态编号:aaa b b ba0 1最小化:{,},{,}{,}{}{,}{}{,}{,}{,}{}{,},{},{}012301101223032330123a ba b ====aabb ab (b)b baa baa baa a已经确定化了,进行最小化最小化:{{,}, {,,,}}012345011012423451305234523452410243535353524012435011012424{,}{}{,}{,}{,,,}{,,,}{,,,}{,,,}{,}{,}{,}{,}{,}{,}{,}{,}{{,},{,},{,}}{,}{}{,}{,}{,}a b a b a b a b a b a =============={,}{,}{,}{,}{,}{,}{,}10243535353524 b a baa baP64–14(1) 00 (2):(|)*0100 1 ε确定化:给状态编号:1 0110 最小化:{,},{,}{,}{}{,}{}{,}{,}{,}{}{,},{},{}0123011012231323301230101====1 11第四章P81–1(1) 按照T,S 的顺序消除左递归ε|,)(||^)(T S T T S T T a S S G '→''→→'递归子程序: procedure S; beginif sym='a' or sym='^' then abvance else if sym='(' then beginadvance;T;if sym=')' then advance;else error;endelse errorend;procedure T;beginS;'Tend;procedure 'T;beginif sym=','then beginadvance;S;'Tendend;其中:sym:是输入串指针IP所指的符号advance:是把IP调至下一个输入符号error:是出错诊察程序(2)FIRST(S)={a,^,(} FIRST(T)={a,^,(} FIRST('T )={,,ε} FOLLOW(S)={),,,#} FOLLOW(T)={)} FOLLOW('T )={)} 预测分析表是LL(1)文法P81–2文法:|^||)(|*||b a E P F F F P F T T T F T E E E T E →'→''→→''→+→''→εεε(1)FIRST(E)={(,a,b,^} FIRST(E')={+,ε}FIRST(T)={(,a,b,^} FIRST(T')={(,a,b,^,ε} FIRST(F)={(,a,b,^} FIRST(F')={*,ε} FIRST(P)={(,a,b,^} FOLLOW(E)={#,)} FOLLOW(E')={#,)} FOLLOW(T)={+,),#} FOLLOW(T')={+,),#} FOLLOW(F)={(,a,b,^,+,),#} FOLLOW(F')={(,a,b,^,+,),#} FOLLOW(P)={*,(,a,b,^,+,),#} (2)考虑下列产生式:'→+'→'→'→E E T T F F P E a b||*|()|^||εεεFIRST(+E)∩FIRST(ε)={+}∩{ε}=φ FIRST(+E)∩FOLLOW(E')={+}∩{#,)}=φ FIRST(T)∩FIRST(ε)={(,a,b,^}∩{ε}=φ FIRST(T)∩FOLLOW(T')={(,a,b,^}∩{+,),#}=φFIRST(*F')∩FIRST(ε)={*}∩{ε}=φFIRST(*F')∩FOLLOW(F')={*}∩{(,a,b,^,+,),#}=φFIRST((E))∩FIRST(a) ∩FIRST(b) ∩FIRST(^)=φ所以,该文法式LL(1)文法.(3)(4)procedure E;beginif sym='(' or sym='a' or sym='b' or sym='^'then begin T; E' endelse errorendprocedure E';beginif sym='+'then begin advance; E endelse if sym<>')' and sym<>'#' then errorendprocedure T;beginif sym='(' or sym='a' or sym='b' or sym='^'then begin F; T' endelse errorendprocedure T';beginif sym='(' or sym='a' or sym='b' or sym='^'then Telse if sym='*' then errorendprocedure F;beginif sym='(' or sym='a' or sym='b' or sym='^'then begin P; F' endelse errorendprocedure F';beginif sym='*'then begin advance; F' endendprocedure P;beginif sym='a' or sym='b' or sym='^'then advanceelse if sym='(' thenbeginadvance; E;if sym=')' then advanceelse errorendelse error end;P81–3/***************(1) 是,满足三个条件。
编译原理课后习题答案清华大学出版社第二版
答案:
程序执行到赋值语句 b∶=10 时运行栈的布局示意图为:
第3题
写出题2中当程序编译到r的过程体时的名字表table的内容。
name
kind
level/val
adr
size
答案:
题 2 中当程序编译到 r 的过程体时的名字表 table 的内容为:
条机器代码,予以执行,然后再读入下一条高级语句,翻译为机器代码,再执行,如此反复。
总而言之,是边翻译边执行。
像C,Pascal之类的语言,属于编译型的高级语言。它们的特点是计算机事先对高级语言进行全盘翻译,将其全部变为机器代码,再统一执行,即先翻译,后执行。从速度上看,编译型的高级语言比解释型的高级语言更快。
CAL L A
调用过程,完成填写静态链、动态链、返回地址,给出被调用过程的基地址值,送入基址寄存器 B 中,目标程序的入口地址 A 的值送指令地址对PL/0语言作如下功能扩充时的语法图和EBNF的语法描述。
(1)扩充条件语句的功能使其为:
if〈条件〉then〈语句〉[else〈语句〉]
广义上讲,编译程序和解释程序都属于翻译程序,但它们的翻译方式不同,解释程序是边翻译(解释)边执行,不产生目标代码,输出源程序的运行结果。而编译程序只负责把源程序翻译成目标程序,输出与源程序等价的目标程序,而目标程序的执行任务由操作系统来完成,即只翻译不执行。
第4题
对下列错误信息,请指出可能是编译的哪个阶段(词法分析、语法分析、语义分析、代码生成)报告的。
RA 的用途说明如下:
T: 栈顶寄存器 T 指出了当前栈中最新分配的单元(T 也是数组 S 的下标)。
编译原理作业题答案编译原理课后题答案
第二章高级语言的语法描述6、令文法G 6为:N →D|ND D → 0|1|2|3|4|5|6|7|8|9(1)G 6 的语言L (G 6)是什么?(2)给出句子01270127、、34和568的最左推导和最右推导。
解答:思路:由N N →→ D|ND 可得出如下推导N =>=>ND ND ND=>=>=>NDD NDD NDD=>…=>=>…=>=>…=>D D n(n >=1=1))可以看出,N 最终可以推导出1个或多个(也可以是无穷)D ,而D D →→ 0|1|2|3|4|5|6|7|8|9可知,每个D 为0~9中的任一个数字,所以,中的任一个数字,所以,N N N 最终推导出的就是由最终推导出的就是由0~9这10个数字组成的字符串。
(1)G 6 的语言L (G 6)是由0~9这10个数字组成的字符串个数字组成的字符串,,或{0{0,,1,1,……,9}+。
(2)(2)句子句子01270127、、34和568的最左推导分别为的最左推导分别为: : N =>=>ND ND ND=>=>=>NDD NDD NDD=>=>=>NDDD NDDD NDDD=>=>=>DDDD DDDD DDDD=>=>=>0DDD 0DDD 0DDD=>=>=>01DD 01DD 01DD=>=>=>012D 012D 012D=>=>=>0127 0127 N =>=>ND ND ND=>=>=>DD DD DD=>=>=>3D 3D 3D=>=>=>34 34N =>=>ND ND ND=>=>=>NDD NDD NDD=>=>=>DDD DDD DDD=>=>=>5DD 5DD 5DD=>=>=>56D 56D 56D=>=>=>568 568 句子01270127、、34和568的最右推导分别为的最右推导分别为: :N =>=>ND ND ND=>=>=>N7N7N7=>=>=>ND7ND7ND7=>=>=>N27N27N27=>=>=>ND27ND27ND27=>=>=>N127N127N127=>=>=>D127D127D127=>=>=>0127 0127 N =>=>ND ND ND=>=>=>N4N4N4=>=>=>D4D4D4=>=>=>34 34N =>=>ND ND ND=>=>=>N8N8N8=>=>=>ND8ND8ND8=>=>=>N68N68N68=>=>=>D68D68D68=>=>=>568 5687、写一个文法,使其语言是奇数集,且每个基数不以0开头。
编译原理(第2版)陈意云张昱编著课后答案
8
(b) 对于句子abab构造两个相应的最右推导.
S aSbS aSb abSaSb abSab abab
rm
rm
rm
rm
rm
S aSbS aSbaSbS aSbaSb aSbab abab
rm
rm
rm
rm
rm
(c)对于句子abab构造两个相应的分析树.
S
S
aSbS
(b) 句子a|aa的两种最左推导. 句子aa*的两种最左推导.
R
R
R
R
R
*
(c)消除二义性
R R ‘|’ S | S S ST | T T U* | U U (R) | a | b
aR
*
R
R
a
a
a
28
4.5 dangling-else文法: stmt if expr then stmt | matched-stmt
tcodenumlexval冶膝嘉篮瞄畅耽找捕案赶骂恭凶魏承弹特选虽丰仁宇汀刺蚁疵夷铁蟹暑牡编译原理第2版陈意云张昱编著课后答案编译原理第2版陈意云张昱编著课后答案stcetcetcttcetcttcnumnumttcnumnum俗铸涣甩呕灿樱涨巾陆蕾胯涣吁飞猜放渭溢惕想诊祭冕捌责境楔烦贴玛耀编译原理第2版陈意云张昱编著课后答案编译原理第2版陈意云张昱编著课后答案55s
( bexpr ) bexpr or bterm bterm bfactor bfactor false
11
true
(c) 试说明此文法产生的语言是全体布尔表达式.
12
练习: 长度为n的字符串, 分别有多少个 前缀, 后缀, 子串, 真前缀, 子序列 ? 前缀: n+1 后缀: n+1 子串: 1+ n+(n-1)+...+1 = 1+n(n+1)/2 真前缀: n 子序列: 1+Cn1+Cn2+Cn3+...+Cnn = 2n
(完整版)编译原理课后答案
第二章2.3叙述由下列正规式描述的语言(a) 0(0|1)*0在字母表{0, 1}上,以0开头和结尾的长度至少是2的01串(b) ((ε|0)1*)*在字母表{0, 1}上,所有的01串,包括空串(c) (0|1)*0(0|1)(0|1)在字母表{0, 1}上,倒数第三位是0的01串(d) 0*10*10*10*在字母表{0, 1}上,含有3个1的01串(e) (00|11)*((01|10)(00|11)*(01|10)(00|11)*)*在字母表{0, 1}上,含有偶数个0和偶数个1的01串2.4为下列语言写正规定义C语言的注释,即以 /* 开始和以 */ 结束的任意字符串,但它的任何前缀(本身除外)不以 */ 结尾。
[解答] other → a | b | … other指除了*以外C语言中的其它字符other1 → a | b | …other1指除了*和/以外C语言中的其它字符 comment → /* other* (* ** other1 other*)* ** */(f) 由偶数个0和偶数个1构成的所有0和1的串。
[解答]由题目分析可知,一个符号串由0和1组成,则0和1的个数只能有四种情况:x 偶数个0和偶数个1(用状态0表示); x 偶数个0和奇数个1(用状态1表示); x 奇数个0和偶数个1(用状态2表示); x 奇数个0和奇数个1(用状态3表示);所以,x 状态0(偶数个0和偶数个1)读入1,则0和1的数目变为:偶数个0和奇数个1(状态1)x 状态0(偶数个0和偶数个1)读入0,则0和1的数目变为:奇数个0和偶数个1(状态2)x 状态1(偶数个0和奇数个1)读入1,则0和1的数目变为:偶数个0和偶数个1(状态0)x 状态1(偶数个0和奇数个1)读入0,则0和1的数目变为:奇数个0和奇数个1(状态3)x 状态2(奇数个0和偶数个1)读入1,则0和1的数目变为:奇数个0和奇数个1(状态3)x 状态2(奇数个0和偶数个1)读入0,则0和1的数目变为:偶数个0和偶数个1(状态0)x 状态3(奇数个0和奇数个1)读入1,则0和1的数目变为:奇数个0和偶数个1(状态2)x 状态3(奇数个0和奇数个1)读入0,则0和1的数目变为:偶数个0和奇数个1(状态1)因为,所求为由偶数个0和偶数个1构成的所有0和1的串,故状态0既为初始状态又为终结状态,其状态转换图:由此可以写出其正规文法为:S0 → 1S1 | 0S2 | ε S1 → 1S0 | 0S3 | 1 S2 → 1S3 | 0S0 | 0 S3 → 1S2 | 0S1在不考虑S0 →ε产生式的情况下,可以将文法变形为: S0 = 1S1 + 0S2 S1 = 1S0 + 0S3 + 1 S2 = 1S3 + 0S0 + 0S3 = 1S2 + 0S1 所以: S0 = (00|11) S0 + (01|10) S3 + 11 + 00(1) S3 = (00|11) S3 + (01|10) S0 + 01 + 10(2) 解(2)式得: S3 = (00|11)* ((01|10) S0 + (01|10)) 代入(1)式得:S0 = (00|11) S0 + (01|10) (00|11)*((01|10) S0 + (01|10)) + (00|11) => S0 = ((00|11) + (01|10) (00|11)*(01|10))S0 + (01|10) (00|11)*(01|10) + (00|11) => S0 = ((00|11)|(01|10) (00|11)*(01|10))*((00|11) + (01|10) (00|11)* (01|10)) => S0 = ((00|1 1)|(01|10) (00|11)* (01|10))+因为S0→ε所以由偶数个0和偶数个1构成的所有0和1的串的正规定义为: S0 → ((00|11)|(01|10) (00|11)* (01|10))* (g) 由偶数个0和奇数个1构成的所有0和1的串。
C++Primer第5版第十一章课后练习答案
C++Primer第5版第⼗⼀章课后练习答案练习11.1map和vector相⽐是通过关键字⽽不是位置来查找值。
练习11.2list:需要在中间进⾏操作的情况。
vector:若没有必要使⽤其他容器则优先使⽤deque:只需要在头尾进⾏操作的情况map:字典set:key-value相同的集合练习11.3int main(int argc, char* argv[]){map<string, size_t> word_count;string word;while (cin >> word) {++word_count[word];}for (const auto& w : word_count) {cout << w.first << "" << w.second << endl;}}练习11.4int main(int argc, char* argv[]){map<string, size_t> word_count;string word;while (cin >> word) {word.erase(remove_if(word.begin(), word.end(), [](char& c) {if (isupper(c)) { tolower(c); } return ispunct(c); }));++word_count[word];}for (const auto& w : word_count) {cout << w.first << "" << w.second << endl;}}练习11.5map是关键字-值对的集合,set是关键字的集合,看使⽤场景需要key-value还是key集合练习11.6set是关联容器,进⾏查找、修改操作效率⾼list是顺序容器,插⼊删除操作效率低,随机访问速度慢练习11.7int main(int argc, char* argv[]){map<string, vector<string>> familys;string surname, name;while (cin >> surname>> name) {familys[surname].emplace_back(name);}for (const auto& f : familys) {cout << f.first << ":";for (const auto& n : f.second) {cout << n << "";}cout << endl;}}练习11.8int main(int argc, char* argv[]){vector<string> words;string word;while (cin >> word) {words.emplace_back(word);}auto it = unique(words.begin(), words.end());words.erase(it, words.end());}set查找速度快练习11.9map<string, list<size_t>> m;练习11.10不能,因为map所提供的操作必须在关键字类型上定义⼀个严格弱序,⽽迭代器之间是⽆法⽐较的练习11.11int main(int argc, char* argv[]){typedef bool (*Comp)(const Sales_data&, const Sales_data&);//和decltype(compareIsbn)*等价multiset<Sales_data, Comp>bookStore(Comp);}练习11.12int main(int argc, char* argv[]){vector<string>str_vec(10);vector<int> i_vec(10);vector<pair<string, int>> psi1;vector<pair<string, int>> psi2;vector<pair<string, int>> psi3;string str, int num;for (auto i = 0; i < 10; ++i) {cin >> str >> num;str_vec.emplace_back(str);i_vec.emplace_back(num);}for (auto i = 0; i < 10; ++i) {psi1.push_back({ str_vec[i],i_vec[i] });psi1.emplace_back(pair<string, int>(str_vec[i], i_vec[i]));psi1.emplace_back(make_pair(str_vec[i], i_vec[i]));}}练习11.13int main(int argc, char* argv[]){vector<string>str_vec(10);vector<int> i_vec(10);vector<pair<string, int>> psi1;vector<pair<string, int>> psi2;vector<pair<string, int>> psi3;string str, int num;for (auto i = 0; i < 10; ++i) {cin >> str >> num;str_vec.emplace_back(str);i_vec.emplace_back(num);}for (auto i = 0; i < 10; ++i) {psi1.push_back({ str_vec[i],i_vec[i] });//不能⽤emplace_back来进⾏pair的列表初始化psi1.emplace_back(pair<string, int>(str_vec[i], i_vec[i]));psi1.emplace_back(make_pair(str_vec[i], i_vec[i]));}}练习11.14int main(int argc, char* argv[]){map<string, vector<pair<string, string>>> familys;string surname, name, birthday;while (cin >> surname >> name>>birthday) {familys[surname].emplace_back(make_pair(name, birthday));}for (const auto& f : familys) {cout << f.first << ":";for (const auto& n : f.second) {cout << n.first << "'s birthday is "<<n.second<<"";}cout << endl;}}练习11.15mapped_type:vector<int>key_type:intvalue_type:pair<const int,vector<int>>练习11.16int main(int argc, char* argv[]){map<int, int>i_i_map;auto it = i_i_map.begin();(*it).second = 5;}练习11.17copy(v.begin(), v.end(), inserter(c, c.end()));//调⽤insert成员函数插⼊到multiset尾后迭代器之前copy(v.begin(), v.end(), back_inserter(c));//multiset没有push_back成员函数,因此⽆法使⽤copy(c.begin(), c.end(), inserter(v,v.end()));//调⽤insert成员函数插⼊到vector尾后迭代器之前copy(c.begin(), c.end(), back_inserter(v));//调⽤push_back成员函数插⼊到vector尾后迭代器之前练习11.18map<string,size_t>::iterator练习11.19int main(int argc, char* argv[]){typedef bool (*Comp)(const Sales_data&, const Sales_data&);//和decltype(compareIsbn)*等价multiset<Sales_data, Comp>bookStore(compareIsbn);multiset<Sales_data, Comp>::iterator it = bookStore.begin();}练习11.20int main(int argc, char* argv[]){map<string, size_t> word_count;string word;while (cin >> word) {auto ret = word_count.insert({ word,1 });if (!ret.second)++ret.first->second;}for (const auto& w : word_count) {cout << w.first << "" << w.second << endl;}}//下标操作更容易编写和阅读练习11.21输⼊word,并将其设置为关键字插⼊到容器中,对应的值为0,然后对值进⾏递增,若此时容器中已有重复关键字则直接对该关键字对应的值进⾏递增。
编译原理第十一章汇总
11.3 一个简单的代码生成器 在一个基本块范围实现代码生成器,它依次把每条中间代 码变换成目标代码,并且在一个基本块范围内考虑如何充 分利用寄存器的问题。即,一方面在基本块中,当生成计 算某变量值的目标代码时,尽可能地让该变量的值保留在 寄存器中,直到该寄存器必须用来存放别的变量或者已到 达基本块的出口为止;另一方面,后续的目标代码尽可能 地引用变量在寄存器中的值,而不访问主存。
2019年2月23日10时12分
例11.1 考察基本块 T:=A-B U:=A-C V:=T+U W:=V+U 假设W 是基本块出口的活跃变量,只有R0和 R1是可用的 寄存器。
2019年2月23日10时12分
中间代码 T: =A-B U: =A-C
V: = T+U
W: =V+U
目标代码 LD R0, A SUB R0, B LD R1, A SUB R1, C ADD R1, R0 ADD R1,R0
op Ri, M
op Ri, *Rj
执行代价为 2
执行代价为 2
op Ri, *M
执行代价为 3
2019年2月23日10时12分
11.5 DAG的目标代码 为了生成更有效的目标代码, 要考虑的另一个问题是, 对基本块中中间代码序列。 例11.4 考察下面基本块的中间代码序列G T1:=A+B T2:=C+D T3:=E-T2 T4:=T1-T3 假设R0和R1是两个可使用的寄存器。T4是基本块出口之 后的活跃变量。
2019年2月23日10时12分
G的 目标代码:
(b) 在随后的寄存器指派阶段,挑出变量将要驻留的具体 寄存器。 2019年2月23日10时12分
(5)计算顺序选择
编译原理课后答案_第三版
三
12将图a确定化最小化
a,b
a
a
图a
解:引入新的初态结点X和终态结点Y(X,Y不属于源非确定集)得图如下:
a
εε εε
a,b a
列出状态转换矩阵如下所示:
ab
A {X,0,Y}{0,1,Y}{1}
解:构造正规式为:(0|10)*
则可构造如下NFA:
ε
0
εε
εε
ε10
ε
ε
列出状态转换矩阵如下:
01
A {q0,F,A,C,qf}{B,G,F,A,C,qf}{D}
B {B,G,F,A,C,qf}{B,G,F,A,C,qf}{D}
C {D}{E,G,F,A,B,C,qf}ø
D {E,G,F,A,B,C,qf} {B,G,F,A,C,qf}{D}
解:(1) S->a|^|(T)
T->ST’
T’->,ST’|ε
(2)
FIRSTFOLLOW
Sa,^,(#, , , )
Ta,^,()
T’, ,ε)
预分析表:
a^ ( ),#
SS->a S->^ S->(T)
TT->ST’T->ST’T->ST’
T’T’->εT->,ST’
是LL(1)的。
五
5.文法S->AS|b
{0,1}b={2,4}∈{2,3,4,5}
∴{0,1}不能再分
非终态{2,3,4,5}a={0,1,3,5}
{2,4}a={0,1} {2,4}b={3,5}
编译原理陈火旺版10-11章.
对于给定的一个程序,可以将其划分为一系列的基本 块,分别在块内进行局部优化(基本块内的优化)。
以下先给出划分基本块的算法。
1. 求出程序中可做基本块入口的语句,它们是: (1)程序的第一个语句;
(2)能由条件转移语句或无条件转移语句转移到的语句; (3)紧跟在条件转移语句后面的语句。
T0:=3.14
8B
T1:=6.28
*
T3:=6.28 T2:=R+r T4:= T2 A:=6.28*T2 T5:=A
B A 6 T5
*
5 +
T2 T4
7 -
T6
T6:=R-r
B:=A*T6 已完成了如下优化:
1 T0
2
T1 T3
3
4
合并已知量;
3.14 6.28 R
r
删除无用代码;(B:=A)
删除公共子表达式。
经前述各种优化处理后,最终的中间代码如下:
B1
i:=m-1; j:=n ; T1:=4*n; v:=a[T1];
T2:=4*i; T4:=4*j;
B2
T2:=T2+4;T3:=a[T2]; if T3<v goto B2
B3
T4:=T4+4;T5:=a[T4]; if T5>v goto B3
B4 if T2>=T4 goto B6
第十一章 目标代码生成
目标代码生成器的位置:
源 程序
编译前端
中间 代码
代码优化
中间 代码
代码生成器
目标 程序
符号表
目标代码的形式: 1、已定位的可立即执行的机器语言代码; 2、可浮动的机器语言代码,需装配连接再执行; 3、汇编语言目标代码,需汇编再执行。
(完整版)编译原理课后习题答案
(完整版)编译原理课后习题答案第一章1.典型的编译程序在逻辑功能上由哪几部分组成?答:编译程序主要由以下几个部分组成:词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成、错误处理、表格管理。
2. 实现编译程序的主要方法有哪些?答:主要有:转换法、移植法、自展法、自动生成法。
3. 将用户使用高级语言编写的程序翻译为可直接执行的机器语言程序有哪几种主要的方式?答:编译法、解释法。
4. 编译方式和解释方式的根本区别是什么?答:编译方式:是将源程序经编译得到可执行文件后,就可脱离源程序和编译程序单独执行,所以编译方式的效率高,执行速度快;解释方式:在执行时,必须源程序和解释程序同时参与才能运行,其不产生可执行程序文件,效率低,执行速度慢。
第二章1.乔姆斯基文法体系中将文法分为哪几类?文法的分类同程序设计语言的设计与实现关系如何?答:1)0型文法、1型文法、2型文法、3型文法。
2)2. 写一个文法,使其语言是偶整数的集合,每个偶整数不以0为前导。
答:Z→SME | BS→1|2|3|4|5|6|7|8|9M→ε | D | MDD→0|SB→2|4|6|8E→0|B3. 设文法G为:N→ D|NDD→ 0|1|2|3|4|5|6|7|8|9请给出句子123、301和75431的最右推导和最左推导。
答:N?ND?N3?ND3?N23?D23?123N?ND?NDD?DDD?1DD?12D?123N?ND?N1?ND1?N01?D01?301N?ND?NDD?DDD?3DD?30D?301N?ND?N1?ND1?N31?ND31?N431?ND431?N5431?D5431?7 5431N?ND?NDD?NDDD?NDDDD?DDDDD?7DDDD?75DDD?754 DD?7543D?75431 4. 证明文法S→iSeS|iS| i是二义性文法。
答:对于句型iiSeS存在两个不同的最左推导:S?iSeS?iiSesS?iS?iiSeS所以该文法是二义性文法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
对假设(2) B:=3 D:=A+C E:=A*C F:=D+E K:=B*5 L:=K+F
计算机咨询网()陪着您
10
《编译原理》课后习题答案第十一章
第7题 分别对图 11.25 和 11.26 的流图: (1) 求出流图中各结点 n 的必经结点集 D(n)。 (2) 求出流图中的回边。 (3) 求出流图中的循环。
(1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)
i:=m-1 j:=n t1:=4*n v:=a[t1] i:=i+1 t2:=4*i t3:=a[t2] if t3< v goto (5) j:=j-1 t5:=4*j t5:=a[t4] if t5> v goto (9) if i >=编译原理》课后习题答案第十一章
第 5 题: 如下程序流图(图 11.24)中,B3 中的 i∶=2 是循环不变量,可以将其提到前置结点吗? 你还能举出一些例子说明循环不变量外移的条件吗?
图 11.24 答案: 不能。因为 B3 不是循环出口 B4 的必经结点。 循环不变量外移的条件外有: (a)(I)s 所在的结点是 L 的所有出口结点的必经结点 (II)A 在 L 中其他地方未再定值 (III)L 中所有 A 的引用点只有 s 中 A 的定值才能到达 (b)A 在离开 L 之后不再是活跃的,并且条件(a)的(II)和(III)成立。所谓 A 在离开 L 后不再是活跃的是指,A 在 L 的任何出口结点的后继结点的入口处不是活跃的(从此点后 不被引用) (3)按步骤(1)所找出的不变运算的顺序,依次把符合(2)的条件(a)或(b)的 不变运算 s 外提到 L 的前置结点中。如果 s 的运算对象(B 或 C)是在 L 中定值的,则只有 当这些定值四元式都已外提到前置结点中时,才可把 s 也外提到前置结点。
分别应用 DAG 对它们进行优化,并就以下两种情况分别写出优化后的四元式序列: (1)假设只有 G、L、M 在基本块后面还要被引用。 (2)假设只有 L 在基本块后面还要被引用。
答案: B1: 基本块对应的 DAG 如下:
计算机咨询网()陪着您
7
《编译原理》课后习题答案第十一章
计算机咨询网()陪着您 2
《编译原理》课后习题答案第十一章
(14) t6:=4*i (15) x:=a[t6] (16) t7:=4*i (17) t6:=4*j (18) t9:=a[t8] (19) a[t7]:=t9 (20) t10:=4*j (21) a[t10]:=x (22) goto (5) (23) t11:=4*i (24) x:=a[t11] (25) t12:=4*i (26) t13:=4*n (27) t14:=a[t13] (28) a[t12]:=t14 (29) t15:=4*n (30) a[t15]:=x 图 11.23 (1) (2) (3) (4) 请将图 11.23 的三地址代码序列划分为基本块并做出其流图。 将每个基本块的公共子表达式删除。 找出流图中的循环,将循环不变量计算移出循环外。 找出每个循环中的归纳变量,并在可能的地方删除它们。
计算机咨询网()陪着您
6
《编译原理》课后习题答案第十一章
第6题 试对以下基本块 B1 和 B2: B1: A:=B*C D:=B/C E:=A+D F:=2*E G:=B*C H:=G*G F:=H*G L:=F M:=L B2: B:=3 D:=A+C E:=A*C F:=D+E G:=B*F H:=A+C I:=A*C J:=H+I K:=B*5 L:=K+J M:=L
或者:
计算机咨询网()陪着您
8
《编译原理》课后习题答案第十一章
B2: 基本块对应的 DAG 如下:
优化后的四元式序列: 对假设(1) B:=3
计算机咨询网()陪着您 9
《编译原理》课后习题答案第十一章
D:=A+C E:=A*C F:=D+E G:=B*F K:=B*5 L:=K+F M:=L
问题 2: 基本块的 DAG 如下图所示,若(1)B 在该基本块出口处不活跃,(2)B 在该基本块出口处 活跃的,请分别给出以下代码经过优化后的代码。 A:=B+C B:=A-D C:=B+C D:=A-D
-2-
《编译原理》课后习题答案第十一章
答案: ①当 B 在出口不活跃时,则 B 在外面就无用了,故 B:=A-D 这条赋值语句可删去,另外, 由于代码生成方面的关系,可把 D 的赋值语句提前到 C 的赋值语句以前。 故得到: A:=B+C D:=A-D C:=D+C ②当 B 在出口活跃时,则 B 在出口处要引用,B 的赋值语句就不可删去了,然而 D 与 B 充 全一样,故 D 的赋值语句可简化,得: A:=B+C B:=A-D D:=B C:=B+C
对图 11.26: (1)流图中各结点 N 的必经结点集 D(n): D(l)={1} D(2)={1,2} D(3)={1,2,3} D(4)={1,2,3,4} D(5)={1,2,5} D(6)={1,2,5,6} (2)求出流图中的回边: 5→2,4→3 (3)求出流图中的循环: 回边 5→2 对应的循环: {2,5,3,4} 回边 4→3 对应的循环: {3,4}
《编译原理》课后习题答案第十一章
第 11 章
代码优化
第1题 何谓代码优化?进行优化所需要的基础是什么? 答案: 对代码进行等价变换, 使得变换后的代码运行结果与变换前代码运行结果相同, 而运行 速度加快或占用存储空间减少,或两者都有。 优化所需要的基础是在中间代码生成之后或目标代码生成之后。 第2题 编译过程中可进行的优化如何分类? 答案: 依据优化所涉及的程序范围,可以分为:局部优化、循环优化和全局优化。 第3题 最常用的代码优化技术有哪些? 答案: 1. 2. 3. 4. 5. 6.
计算机咨询网()陪着您 4
《编译原理》课后习题答案第十一章
… (29) t15:=t13 (3) 循环 ① {B2} ② {B3} ③ {B2,B3,B4,B5} (4) 在循环{B2,B3,B4,B5}中,原来的(14)(17)都可以删除。
计算机咨询网()陪着您
-3-
计算机咨询网()陪着您
12
《编译原理》课后习题答案第十一章
附加题
问题 1: 给出如下 4 元式序列: (1) J:=0; (2)L1:I:=0; (3) IF I<8,goto L3; (4)L2:A:=B+C; (5) B:=D*C; (6)L3:IF B=0,goto L4; (7) Write B; (8) goto L5; (9)L4:I:=I+1; (10) IF I<8,goto L2; (11)L5:J:=J+1; (12) IF J<=3,goto L1; (13) STOP ①画出上述 4 元式序列的程序流程图 G, ②求出 G 中各结点 N 的必经结点集 D(n), ③求出 G 中的回边与循环。 答案: ①四元式程序基本块入口语句的条件是: (1)它们是程序的第一个语句;或, (2)能由条件转移语句或无条件转移语句转移到的语句;或, (3)紧跟在条件转移语句后的语句。 (4)根据这 3 个条件,可以判断,设 1,2,3,4,6,7,9,11,13 为入口语句,故基本块 为 l,2/3,4/5,6,7/8,9/1O,11/12,13, 故可画出程序流图如下图所示
图 11.25
图 11.26
计算机咨询网()陪着您
11
《编译原理》课后习题答案第十一章
答案: 对图 11.25: (1)流图中各结点 N 的必经结点集 D(n): D(1)={1} D(2)={1,2} D(3)={1,2,3} D(4)={1,2,3,4} D(5)={1,2,3,5} D(6)={1,2,3,6} D(7)={1,2,7} D(8)={1,2,7,8} (2)回边: 7→2 (3)循环: {2,3,4,5,6,7}
答案: (1) 基本块
计算机咨询网()陪着您
3
《编译原理》课后习题答案第十一章
流图
(2) B5 中(14)和(16)是公共子表达式、 (17)和(20)是公共子表达式,B5 变为 (14) t6:=4*I (15) (16) t7:=t6 (17) t8:=4*J … (20) t10:=t8 (21) (22) B6 中(23)和(25)是公共子表达式、 (26)和(29)是公共子表达式,B6 变为 (23) t11:=4*I (24) (25) t12:=t11 (26) t13:=4*n
根据 DAG 图,优化后的语句序列为 A:=B*C G:=A D:=B/C E:=A+D H:=A*A F:=A*H L:=F M:=F (1)假设只有 G、L、M 在基本块后面还要被引用; S1:=B*C G:=S1 S2:=S1*S1 S3:=S1*S2 L:=S3 M:=S3 (2)假设只有 L 在基本块后面还要被引用; S1:=B*C S2:=S1*S1 S3:=S1*S2 L:=S3 (备注:S1,S2,S3 为新引入的临时变量)
删除多余运算 代码外提 强度削弱 变换循环控制条件 合并已知量与复写传播 删除无用赋值
计算机咨询网()陪着您
1
《编译原理》课后习题答案第十一章
第4题 图 11.23 是图 11.22 的 C 代码的部分三地址代码序列。 void quicksort(m,n) int m,n; { int i,j; int v,x; if (n<=m) return; /* fragment begins here */ i = m-1; j = n; v = a[n]; while(1) { do i = i+1;while (a[i]<v); do j = j-1; while (a[j]>v); if (i>=j) break; x = a[i]; a[i] = a[j]; a[j] = x; } x = a[i]; a[i] = a[n]; a[n] = x; /* fragment ends here */ quicksort (m,j); quicksort(i+1,n); } 图 11.22