当前位置:文档之家› 编译原理龙书课后部分答案(英文版)

编译原理龙书课后部分答案(英文版)

编译原理龙书课后部分答案(英文版)
编译原理龙书课后部分答案(英文版)

1) What is the difference between a compiler and an interpreter

A compiler is a program that can read a program in one language - the source language - and translate it into an equivalent program in another language – the target language and report any errors in the source program that it detects during the translation process.

Interpreter directly executes the operations specified in the source program on inputs supplied by the user.

2) What are the advantages of:

(a) a compiler over an interpreter

a. The machine-language target program produced by a compiler is usually much faster than an interpreter at mapping inputs to outputs.

(b) an interpreter over a compiler

b. An interpreter can usually give better error diagnostics than a compiler, because it executes the source program statement by statement.

,

3) What advantages are there to a language-processing system in which the compiler produces assembly language rather than machine language

The compiler may produce an assembly-language program as its output, because

assembly language is easier to produce as output and is easier to debug.

4.2.3 Design grammars for the following languages:

a) The set of all strings of 0s and 1s such that every 0 is immediately followed by at least 1.

<

S -> SS | 1 | 01 |

4.3.1 The following is a grammar for the regular expressions over symbols a and b only, using + in place of | for unions, to avoid conflict with the use of vertical bar as meta-symbol in grammars:

rexpr -> rexpr + rterm | rterm

rterm -> rterm rfactor | rfactor

rfactor -> rfactor * | rprimary

rprimary -> a | b

a) Left factor this grammar.

rexpr -> rexpr + rterm | rterm

rterm -> rterm rfactor | rfactor

rfactor -> rfactor * | rprimary

rprimary -> a | b

b) Does left factoring make the grammar suitable for top-down parsing

No, left recursion is still in the grammar.

c) In addition to left factoring, eliminate left recursion from the original grammar.

rexpr -> rterm rexpr’

r expr’ -> + rterm rexpr |

rterm -> rfactor rterm’

rterm’ -> rfactor rterm |

rfactor -> rprimary rfactor’

rfactor’ -> * rfactor’ |

rprimary -> a | b

d) Is the resulting grammar suitable for top-down parsing

Yes.

Exercise 4.4.1 For each of the following grammars, derive predictive parsers and show the parsing tables. You may left-factor and/or eliminate left-recursion from your grammars first.

A predictive parser may be derived by recursive decent or by the table driven approach. Either way you must also show the predictive parse table.

a) The grammar of exercise 4.2.2(a).

4.2.2 a) S -> 0S1 | 01

This grammar has no left recursion. It could possibly benefit from left factoring. Here is the recursive decent PP code.

s() {

match(‘0’);

if (lookahead == ‘0’)

s();

match(‘1’);

}

Or

Left factoring the grammar first: S -> 0S’

S’ -> S1 | 1

s() {

match(‘0’); s’();

}

(

s’() {

if (lookahead == ‘0’)

s(); match(‘1’);

else

match(‘1’);

}

Now we will build the PP table

S -> 0S’

S’ -> S1 | 1

First(S) = {0}

First(S’) = {0, 1}

Follow(S) = {1, $}

The predictive parsing algorithm on page 227 and can use this table for non-recursive predictive parsing.

b) The grammar of exercise 4.2.2(b).

4.2.2 b) S -> +SS | *SS | a with string +*aaa.

Left factoring does not apply and there is no left recursion to remove.

{

s() {

if(lookahead == ‘+’)

match(‘+’); s(); s();

else if(lookahead == ‘*’)

match(‘*’); s(); s();

else if(lookahead == ‘a’)

match(‘a’);

else

report(“syntax error”);

}

First(S) = {+, *, a}

Follow(S) = {$, +, *, a}

The predictive parsing algorithm on page 227 and can use this table for non-recursive predictive parsing.

}

5.1.1 a, b, c: Investigating GraphViz as a solution to presenting trees

Extend the SDD of Fig. to handle expressions as in Fig. :

1.L -> E N

1.=

2. E -> F E'

1.= E'.syn

2.E'.inh =

3.E' -> + T Esubone'

1.、

2.Esubone'.inh = E'.inh +

3.E'.syn = Esubone'.syn

4.T -> F T'

1.T'.inh =

2.= T'.syn

5.T' -> * F Tsubone'

1.Tsubone'.inh = T'.inh *

2.T'.syn = Tsubone'.syn

6.T' -> epsilon

1.T'.syn = T'.inh

7.~

8.E' -> epsilon

1.E'.syn = E'.inh

9. F -> digit

1.=

10.F -> ( E )

1.=

11.E -> T

1.=

5.1.3 a, b, c: Investigating GraphViz as a solution to presenting trees

What are all the topological sorts for the dependency graph of Fig.

1.1, 2, 3, 4, 5, 6, 7, 8, 9

2.(

3.1, 2, 3, 5, 4, 6, 7, 8, 9

4.1, 2, 4, 3, 5, 6, 7, 8, 9

5.1, 3, 2, 4, 5, 6, 7, 8, 9

6.1, 3, 2, 5, 4, 6, 7, 8, 9

7.1, 3, 5, 2, 4, 6, 7, 8, 9

8.2, 1, 3, 4, 5, 6, 7, 8, 9

9.2, 1, 3, 5, 4, 6, 7, 8, 9

10.2, 1, 4, 3, 5, 6, 7, 8, 9

11.2, 4, 1, 3, 5, 6, 7, 8, 9

5.2.2 a, b: Investigating GraphViz as a solution to presenting trees

Suppose that we have a production A -> BCD. Each of the four nonterminals A, B, C, and D have two attributes: s is a synthesized attribute, and i is an inherited attribute. For each of

the sets of rules below, tell whether (1) the rules are consistent with an S-attributed definition (2) the rules are consistent with an L-attributed definition, and (3) whether the rules are consistent with any evaluation order at all?

a) = +

1.·

2.No--contains inherited attribute

3.Yes--"From above or from the left"

4.Yes--L-attributed so no cycles

b) = + and = +

1.No--contains inherited attributes

2.Yes--"From above or from the left"

3.Yes--L-attributed so no cycles

c) = +

1.Yes--all attributes synthesized

2.Yes--all attributes synthesized

3.…

4.Yes--S- and L-attributed, so no cycles

d)

=

= +

=

= +

1.No--contains inherited attributes

https://www.doczj.com/doc/4714845554.html,es , which depends on , which depends on (cycle)

3.No--Cycle implies no topological sorts (evaluation orders) using the rules

Below is a grammar for expressions involving operator + and integer or floating-point operands. Floating-point numbers are distinguished by having a decimal point.

1.,

2. E -> E + T | T

3.T -> num . num | num

a) Give an SDD to determine the type of each term T and expression E.

1. E -> Esubone + T

1.= if == float || == float) { = float } else { = integer }

2. E -> T

1.=

3.T -> numsubone . numsubtwo

1.= float

4.T -> num

1.…

2.= integer

b) Extend your SDD of (a) to translate expressions into postfix notation. Use the binary operator intToFloat to turn an integer into an equivalent : I use character ',' to separate floating point numbers in the resulting postfix notation. Also, the symbol "||" implies concatenation.

1. E -> Esubone + T

1.= || ',' || || '+'

2. E -> T

1.=

3.T -> numsubone . numsubtwo

1.= || '.' ||

4.T -> num

1.= intToFloat

`

5.3.2 Give an SDD to translate infix expressions with + and * into equivalent expressions without redundant parenthesis. For example, since both operators associate from the left, and * takes precedence over +, ((a*(b+c))*(d)) translates into a*(b+c)*d. Note: symbol "||" implies concatenation.

1.S -> E

1.= nil

2.=

2. E -> Esubone + T

1.=

2.=

3.= || '+' ||

4.= '+'

3. E -> T

1.*

2.=

3.=

4.=

4.T -> Tsubone * F

1.= '*'

2.= '*'

3.= || '*' ||

4.= '*'

5.T -> F

1.=

2.&

3.=

4.=

6. F -> char

1.=

2.= nil

7. F -> ( E )

1.if == '*' && == '+') { = '(' || || ')' } else { = }

2.= nil

5.3.3: Give an SDD to differentiate expressions such as x * (3*x + x * x) involving the operators + and *, the variable x, and constants. Assume that no simplification occurs, so that, for example, 3*x will be translated into 3*1 + 0*x. Note: symbol "||" implies concatenation. Also, differentiation(x*y) = (x * differentiation(y) + differentiation(x) * y) and differentiation(x+y) = differentiation(x) + differentiation(y).

1.S -> E

1.=

2. E -> T

1.=

2.=

3.T -> F

1.=

2.=

4.T -> Tsubone * F

1.= '(' || || ") * (" || || ") + (" || || ") * (" || || ')'

2.= || '*' ||

5. E -> Esubone + T

1.= '(' || || ") + (" || || ')'

2.= || '+' ||

6. F -> ( E )

1.=

2.= '(' || || ')'

7. F -> char

1.= 1

2.=

8. F -> constant

1.= 0

2.=

相关主题
文本预览
相关文档 最新文档