5.1.1比较简单,就是自底向上语法树中加上 .val就行
5.1.2
5.2.1 保证下表中从左到右排就行
1->3->5 2->4 |
4,5->6 | 6->7 | 7->8 | 8->9 |
5.2.2 依赖图比注释语法分析树增加了依赖关系
本题中的注释语法分析树完全类似图5-9
5.2.3 A->BCD
S属性 | L属性 | 求值顺序是否影响规则(中文书中翻译有问题) | |
A.s=B.i+C.s | no(有继承属性) | yes | |
A.s=B.i+C.s D.i=A.i+B.s |
no | yes | |
A.s=B.s+D.s | yes | yes | |
A.s=D.i B.i=A.s+C.s C.i=B.s D.i=B.i+C.i |
no | no |
5.2.4
S->L1.L2 L1.side = left L2.side=right S.value=L1.value+L2.value
S->L L1.side = left S.value=L.value
L->L1B L1.side=L.side if(L.side==left) L.value=L1.value*2+B.value else L.value=L1.value+B/2^(length(L1))
L->B if(L.side==left) L.value=B.value else L.value=B.value/2
B->0 B.value = 0
B->1 B.value = 1
5.2.5
S->LEFT.RIGHT | LEFT
LEFT->LEFT B | B
RIGHT->B RIGHT | B
B->0|1
5.3.1 1)
E->E1+T if(E1.type==float||T.type==float) E.type=float else E.type=int
E->T E.type=T.type
T->num.num T.type=float
T->num T.type = int
2)
E->E1+T if(E1.t==T.t) E1.b T.b + else if(E1.t==float) E1.b intToFloat(E2.b) + else intToFloat(E1.b) E2.b +
E->T E.b = T.b
T->num.num T.b = num.num
T->num T.b = num
5.3.2 首先添加语义,继承属性t导出每个非终结符号是怎么组成的(+or*or exp or (+)),综合属性b表示表达式
如果exp=(expr1),则RemoveBra(exp)=exp1
exp
E -> E1+T E.t = +; 如果E1或T为(+)类型,则将其两边括号去掉
E -> T E.t = T.t
T -> T1*F T.t = *
T ->F T.t = F.t
F -> (E) if(E.t==* || E.t==exp) { F.b=E.b; F.t = E.t } else { F.b='('+E.b+')',F.t = (+); }
F->exp F.t = exp F.b = exp
5.3.3
E -> E1+T E.v=E1.v+T.v E.diff=E1.diff+T.diff
E -> T E.v=T.v E.diff=T.diff
T -> T1*F T.v = T1.diff*F.v + T1.v*F.diff
T ->F T.v = F.v T.diff=F.diff
F -> (E) F.v = E.v F.diff=E.diff
F -> EXP F.v = EXP, F.diff=1
F -> NUM F.v = NUM,F.diff=0
5.4.1 这是LR语法分析的特征
5.4.2
A -> 0 C
C -> {a}BC | B{b}C
B ->1D
D -> {c}AD | A{d}D
5.4.3 类似图5-23,需要增加一个继承属性,综合属性变为向上传值的属性,生成的SDT应该类似5.4.4结尾的一组式子
B -> 1 { C.i=1 } C { B.a=C.a }
C -> 0 { C1.i=2*C.i } C1 { C.a=C1.a }
C -> 1 { C1.i=2*C.i+1 } C1 { C.a=C1.a }
最后的B.val就等于B.a
5.4.4 考虑S->if(C) S1 else S2
L1 = new() // S1开始代码处
L2 = new() // S2开始代码处
S1.next = S.next
S2.next = S.next
C.true = L1
C.false = L2
S.code = C.code label L1 S1.code label L2 S2.code
5.4.5
S->if( { L1=new(); L2=new(); C.true=L1; C.false=L2 }
C) { S1.next = S.next; S2.next=S.next }
S1
else
S2 { S.code = C.code label L1 S1.code label L2 S2.code }
5.4.6 5.4.7
表达式 | 5.4.6 | 5.4.7 |
S->B | ||
B->B1B2 | B.le=B1.le+B2.le | |
B->B1 sub B2 | B.le=B1.le+B2.le | |
B->B1 sup B2 | B.le=B1.le+B2.le | B1.ps=B.ps B2.ps=0.7*B.ps B.ht=max(B1.ht, B2.ht+0.25*B.ps) B.dp=max(B1.dp, B2.dp-0.25*B.ps |
B->(B1) | B.le=B1.le | |
B->text | B.le=getLe(B.ps,text.lexval) |
考虑 S -> if ( C ) S1 else S2 语句的实现,类似while,
S包含继承属性.next和综合属性.code,C包含继承属性.true和.false,综合属性.code
5.5.1
string S(label next) { string Ccode, S1code, S2code; label L1, L2; if(current input==token while) { advance input; check '(' is next on the input, and advance; L1 = new(); L2 = new(); Ccode = C(L1, L2); check ')' is next on the input, and advance; S1code = S(next); check else; S2code = S(next); return (Ccode L1 S1code L2 S2code); } else // other statement types }
5.5.2
void S(label next) { label L1, L2; if(current input==token while) { advance input; check '(' is next on the input, and advance; L1 = new(); L2 = new(); Ccode = C(L1, L2); check ')' is next on the input, and advance; printf("label", L1); S(next); check else; printf("label", L2); S(next); } else // other statement types }
5.5.3 首先不考虑综合属性,仿照例5.23
S | |||||||||
next=x |
if | ( | Action | C | ) | Action | S1 | else | Action | S2 |
L1=? L2=? |
false=? true=? |
al1=? | next=x | al2=? | next=x |
L1=new()
L2=new()
stack[top-1].false = L2
stack[top-1].true = L1
stack[top-3].al1 = L1
stack[top-5].al2 = L2
C | ) | Action | S1 | else | Action | S2 | |||
false=L2 true=L1 |
al1=L1 | next=x | al2=L2 | next=x |
S1前面Action printf("label", al1) S2前面Action printf("label", al2)
例5.24中对于每个包含代码的非终结符号下面增加了一个记录综合属性的位置,其它与例5.23基本相同
5.5.4 S -> if ( X C ) Y S1 else Z S2
X-> ε; Y-> ε; Z-> ε;
? | if | ( | X | C | ) | Y | S1 | else | Z | S2 | |
S.next | C.true C.false L1 L2 |
C.code | S1.next | S1.code | S2.next | S2.code |
L1 = new()
L2 = new()
C.true = L1
C.false = L2
tempCode = C.code label stack[top-4].L1 stack[top-3].code label stack[top-4].L2 stack[top].code
top -= 9
stack[top].code = tempCode