编辑: sunny爹 | 2015-08-28 |
S1.next = S.begin;
S.code = 'label' S.begin || expr.code || 'gotofalse' S.next || S1.code || 'goto' S.begin || 'label' S.next;
} | S1 ;
S2 { S1.begin = S.begin;
S1.next = S2.begin = newlabel();
S2.next = S.next;
S.code = S1.code || S2.code;
} | break { S.code = 'goto' S.next;
} | other { S.code = other.code;
} (Aho)5.12 下列文法产生包含赋值操作的表达式 S → E E → E := E | E + E | ( E ) | id 试构造一个语法制导定义,检查赋值表达式的左部是否为左值.用E的继承属性side来指明E应该出现在赋值号左部还是右部 解:语法制导定义如下 S → E { E.side = right;
} E → E1 := E2 { if (E.side == left) error;
else { E1.side = left;
E2.side = right;
}} E → E1 + E2 { if (E.side == left) error;
else { E1.side = E2.side = right;
}} E → ( E1 ) { if (E.side == left) error;
else { E1.side = right;
}} E → id 扩充a)中语法制导定义,使得在检查同时将表达式翻译为抽象堆栈机代码 解:语法制导定义如下,其中,valcode表示取表达式右值的代码 S → E { E.side = right;
S.code = E.code;
} E → E1 := E2 { if (E.side == left) error;
else { E1.side = left;
E2.side = right;
} E.code = E1.code || E2.code E1.valcode;
} E → E1 + E2 { if (E.side == left) error;
else { E1.side = E2.side = right;
} E.code = E1.code || E2.code E → ( E1 ) { if (E.side == left) error;
else { E1.side = right;
} E.code = E1.code;
} E → id { E.code = 'lvalue' id.lexeme;
E.valcode = 'rvalue' id.lexeme;
} (Aho)5.16 下面文法是书中图5-22文法的无二义性版本,其中{}只是用来为盒子分组,在翻译过程中无实际意义. S → L L → L B | B B → B sub F | F F → { L } | text 试改写图5-22的语法制导定义,以适用于上面改写后的文法 解:语法制导定义如下,其中,ps为继承属性,ht为综合属性 S → L { L.ps = 10;
S.ht = L.ht;
} L → L1 B { L1.ps = L.ps;
B.ps = L.ps;
L.ht = max(L1.ht, B.ht);
} L → B { B.ps = L.ps;
L.ht = max(L1.ht, B.ht);
} B → B1 sub F { B1.ps = B.ps;
F.ps = shrink(B.ps);
B.ht = disp(B1.ht, F.ht);
} B → F { F.ps = B.ps;
B.ht = F.ht;
} F → { L } { L.ps = F.ps;
F.ht = L.ht;
} F → text { F.ht = text.h * F.ps;
} 将a)的结果转换为翻译模式 解:翻译模式如下 S → { L.ps = 10;
} L { S.ht = L.ht;
} L → { L1.ps = L.ps;
} L1 { B.ps = L.ps;
} B { L.ht = max(L1.ht, B.ht);
} L → { B.ps = L.ps;
} B { L.ht = max(L1.ht, B.ht);
} B → { B1.ps = B.ps;
} B1 sub { F.ps = shrink(B.ps);
} F { B.ht = disp(B1.ht, F.ht);
} B → { F.ps = B.ps;
} F { B.ht = F.ht;
} F → { L.ps = F.ps;
} { L } { F.ht = L.ht;
} F → text { F.ht = text.h * F.ps;
} (Aho)5.17 扩充5.5节中消除左递归的变换方法,使之允许(5-2)中的非终结符A具有: 由复制规则定义的继承属性 解:具有复制规则定义的继承属性的左递归文法的翻译模式为 A → { A1.in = A.in;
} A1 Y { A.a = g(A1.a, Y.y, A.in);
} A → X { A.a = f(X.x, A.in);
} 消除左递归后变为,其中R.r为继承属性,R.s为综合属性 A → X { R.r = f(X.x, A.in);
R.in = A.in;
} R { A.a = R.s;
} R → Y { R1.r = g(R.r, Y.y, R.in);
R1.in = R.in;
} R1 { R.s = R1.s;
} R → ? { R.s = R.r;
} 继承属性 解:具继承属性的左递归文法的翻译模式为 A → { A1.in = h(A.in);
} A1 Y { A.a = g(A1.a, Y.y, A.in);
} A → X { A.a = f(X.x, A.in);
} 消除左递归后变为,其中R.r为继承属性,R.s为综合属性 A → X { R.r = f(X.x, A.in);