translation of flow-of-control statements S→if(E)S1 I if (E)S else S2 while (E)S IS S2 S.next the label that is attached to the first three-address code to be executed after the code for S
translation of flow-of-control statements S → if (E) S 1 | if (E) S 1 else S 2 | while (E) S 1 | S S 1 2 S.next : the label that is attached to the first three-address code to be executed a fter the code for S
code for flow-of-control statements to E.true to E.true E.code to E.false E.code to E.false E.true: E.true: S.code S.code E.false: goto S.next E.false: S2.code (a)if-then S.next: (b)if-then-else S.begin: to E.true E.code to E.false E.true: S.code goto S.begin E.false: (c)while-do
code for flow code for flow-of-control statements control statements to E.true to E.true E.code S1.code E.true: to E.false E.code S1.code E.true: to E.false 1 ... 1 E.false: goto S.next S2.code E.false: (a) if-then ... S2.code (b) if-then-else S b i t E t S.next: E.code E.true: to E.true to E.false S.begin: S1.code ... goto S.begin E false: (c) while-do E.false:
利用fall through E→E1 relop E2 {test E relop E2 s=if E.true !fall and E.false !fall then gen(if test 'goto',E.true)ll gen('goto',E.false) else if (E.true !fall)then gen('if test goto',E.true) else if (E.false !fall)then gen('if test 'goto',E.false) else E.code :E-code ll E2.codell s
利用fall through E → E1 relop E2 {test = E1 relop E2 s = if E.true != fall and E.false != fall then gen(‘if’ test ‘goto’, E.true) || gen(‘goto’, E.false) else if (E.true != fall) then gen(‘if’ test ‘goto’, E.true) else if (E.false != fall) then gen(‘if’ ! test ‘goto’, E.false) else ‘’ E.code := E1.code || E2 .code || s }
backpatching allows generation of intermediate code in one pass (the problem with translation scheme before is that we have inherited attributes such as S.next,which is not suitable to implement in bottom-up parsers) idea:the labels (in the three-address code)will be filled when we know the places attributes:E.truelist (true exit讴:真标号表),E.falselist (false exits)
backpatching allows generation of intermediate code in one pass (the problem with translation scheme before is that we have inherited attributes such as S.next, which is not suitable to implement in bottom-up parsers) idea: the labels (in the three-address code) will be filled when we know the places • attributes: E.truelist (true exits:真标号表), E.falselist (false exits)
。S→if E then MS1 (backpatch(E.truelist,M.quad); S.nextlist :merge(E.falselist,S.nextlist ·S→if E then M1S1 V else M2S2 (backpatch(E.truelist,M.quad); backpatch(E.falselist,M.quad); S.nextlist :merge(S.nextlist,N.nextlist,S2.nextlist)}
• S → if E then M S1 {backpatch(E.truelist, M.quad); S.nextlist := merge(E.falselist, S1.nextlist} • S → if E then M S N l M S 1 S1 N else M2 S2 {backpatch(E.truelist, M1.quad); backpatch(E falselist M backpatch(E.falselist, M quad); 2.quad); S.nextlist := merge(S1.nextlist, N.nextlist, S2.nextlist)}