5.1.1 a, b, c: Investigating GraphViz as a solution to presenting trees
5.1.2: Extend the SDD of Fig. 5.4 to handle expressions as in Fig. 5.1:
- L -> E N
- L.val = E.syn
- E -> F E'
- E.syn = E'.syn
- E'.inh = F.val
- E' -> + T Esubone'
- Esubone'.inh = E'.inh + T.syn
- E'.syn = Esubone'.syn
- T -> F T'
- T'.inh = F.val
- T.syn = T'.syn
- T' -> * F Tsubone'
- Tsubone'.inh = T'.inh * F.val
- T'.syn = Tsubone'.syn
- T' -> epsilon
- T'.syn = T'.inh
- E' -> epsilon
- E'.syn = E'.inh
- F -> digit
- F.val = digit.lexval
- F -> ( E )
- F.val = E.syn
- E -> T
- E.syn = T.syn
5.2.1: What are all the topological sorts for the dependency graph of Fig. 5.7?
- 1, 2, 3, 4, 5, 6, 7, 8, 9
- 1, 2, 3, 5, 4, 6, 7, 8, 9
- 1, 2, 4, 3, 5, 6, 7, 8, 9
- 1, 3, 2, 4, 5, 6, 7, 8, 9
- 1, 3, 2, 5, 4, 6, 7, 8, 9
- 1, 3, 5, 2, 4, 6, 7, 8, 9
- 2, 1, 3, 4, 5, 6, 7, 8, 9
- 2, 1, 3, 5, 4, 6, 7, 8, 9
- 2, 1, 4, 3, 5, 6, 7, 8, 9
- 2, 4, 1, 3, 5, 6, 7, 8, 9
5.2.3: 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) A.s = B.i + C.s
- No--contains inherited attribute
- Yes--"From above or from the left"
- Yes--L-attributed so no cycles
- No--contains inherited attributes
- Yes--"From above or from the left"
- Yes--L-attributed so no cycles
- Yes--all attributes synthesized
- Yes--all attributes synthesized
- Yes--S- and L-attributed, so no cycles
- A.s = D.i
- B.i = A.s + C.s
- C.i = B.s
- D.i = B.i + C.i
- No--contains inherited attributes
- No--B.i uses A.s, which depends on D.i, which depends on B.i (cycle)
- No--Cycle implies no topological sorts (evaluation orders) using the rules
- S -> L . L | L
- L -> L B | B
- B -> 0 | 1
- S -> L . Lsubone
- L.inh = 0
- Lsubone.inh = -1
- S.val = L.syn + Lsubone.syn
- S -> L
- L.inh = 0
- S.val = L.syn
- L -> Lsubone B
- Lsubone.inh = L.inh + 1
- B.inh = L.inh
- L.syn = Lsubone.syn * B.syn
- L -> B
- L.syn = B.syn * 2^L.inh
- B -> 0 | 1
- B.syn = digit.lexval
- S -> L . Lsubone
- S.val = L.lhs + Lsubone.rhs
- S -> L
- S.val = L.lhs
- L -> Lsubone B
- L.lhs = Lsubone.lhs + (2^L.lhs_exponent * B.val)
- L.rhs = Lsubone.rhs + (2^L.rhs_exponent * B.val)
- L.lhs_exponent = Lsubone.lhs_exponent + 1
- L.rhs_exponent = Lsubone.rhs_exponent - 1
- L -> B
- L.lhs = 2^L.lhs_exponent * B.val
- L.rhs = 2^L.rhs_exponent * B.val
- L.lhs_exponent = 0
- L.rhs_exponent = -1
- B -> 0 | 1
- B.val = digit.lexval
5.3.1: Below is a grammar for expressions involving operator + and integer or floating-point operands. Floating-point numbers are distinguished by having a decimal point.
- E -> E + T | T
- T -> num . num | num
- E -> Esubone + T
- E.type = if (E.type == float || T.type == float) { E.type = float } else { E.type = integer }
- E -> T
- E.type = T.type
- T -> numsubone . numsubtwo
- T.type = float
- T -> num
- T.type = integer
- E -> Esubone + T
- E.val = Esubone.val || ',' || T.val || '+'
- E -> T
- E.val = T.val
- T -> numsubone . numsubtwo
- T.val = numsubone.val || '.' || numsubtwo.val
- T -> num
- T.val = intToFloat(num.val)
- S -> E
- E.iop = nil
- S.equation = E.equation
- E -> Esubone + T
- Esubone.iop = E.iop
- T.iop = E.iop
- E.equation = Esubone.equation || '+' || T.equation
- E.sop = '+'
- E -> T
- T.iop = E.iop
- E.equation = T.equation
- E.sop = T.sop
- T -> Tsubone * F
- Tsubone.iop = '*'
- F.iop = '*'
- T.equation = Tsubone.equation || '*' || F.equation
- T.sop = '*'
- T -> F
- F.iop = T.iop
- T.equation = F.equation
- T.sop = F.sop
- F -> char
- F.equation = char.lexval
- F.sop = nil
- F -> ( E )
- if (F.iop == '*' && E.sop == '+') { F.equation = '(' || E.equation || ')' } else { F.equation = E.equation }
- F.sop = nil
- S -> E
- S.d = E.d
- E -> T
- E.d = T.d
- E.val = T.val
- T -> F
- T.d = F.d
- T.val = F.val
- T -> Tsubone * F
- T.d = '(' || Tsubone.val || ") * (" || F.d || ") + (" || Tsubone.d || ") * (" || F.val || ')'
- T.val = Tsubone.val || '*' || F.val
- E -> Esubone + T
- E.d = '(' || Esubone.d || ") + (" || T.d || ')'
- E.val = Esubone.val || '+' || T.val
- F -> ( E )
- F.d = E.d
- F.val = '(' || E.val || ')'
- F -> char
- F.d = 1
- F.val = char.lexval
- F -> constant
- F.d = 0
- F.val = constant.lexval
For 5.3 1b, I think you should put the T.val first. Otherwise you may have something like 23+4. If you switch the order it will be 423+.
ReplyDeletehey more solutions are there for other chapters of this book?
ReplyDeleteThanks!