1. S : S1 B {S.even = B.even} | B {S.even = B.even} B : 0 {B.even = true} | 1 {B.even = false} // A binary number is divisible by 3 if the diff of the odd-bits sum // and even-bits sum is divisible by 3. S : E {S.d3 = E.d3} | O {S.d3 = O.d3} E : E Pair {E.diff = Pair.diff + E1.diff; E.d3 = E.diff % 3} | Pair {E.d3 = Pair.diff % 3} Pair : B1 B2 {Pair.diff = B1.bit - B2.bit} O : E B {O.diff = E.diff - B.bit; O.d3 = O.diff %3} | B {O.d3 = !B.bit} B : 0 {B.bit = 0} | 1 {B.bit = 1} 2. receive n (val) L0: t1 = n % 3 t2 = t1 == 0; if (t2) goto L1 t3 = t1 == 1; if (t3) goto L2 goto L3; L1: t4 = a[i]; t5 = j + 1; j = t5; t6 = n + 1; t4[t5] = t6; n = t6; goto L3: L2: t7 = a[i] n = n + 1; t7[j] = n; i = i + 1; goto L3: L3: tx = n < 100 if (tx) goto L0; return n; 2 (Bonus) receive q; // q is an array int x[2]; x[0] = 5; t1 = x[1]; q[0] = t1 3. Note: 1. else attaches to nearest if 2. in the for loop the increment happens as the last instruction in the loop-body. 3. goto takes a single argument. 4. a) we have the extend the liveness info to each of the instructions. b) we have to carefully compute the BB "def" and "use", by doing a liveness analysis for the basic block first. For instance: b = a; x = b In this example, b and x are "def" in the BB, and 'a' is "used" in the BB. But not b.