| Production | Semantic Rules | 
|---|---|
| pg → pd pg1 | pd.next = newLabel()pg.code = pd.code || label(pd.next) || pg1.code | 
| pg → ε | pg.code = "" | 
| pd → PROC np IS ds BEG s ss END ; | 
	ds.offset = 0pd.code = s.code || label(s.next) || ss.code s.next = newLabel() ss.next = pd.next | 
| np → di ( ps ) | di | not used yet | 
| ps → p | p , ps | not used yet | 
| p → di : ty | not used yet | 
| ds → d ds1 | 
	d.offset = ds.offsetds.totalSize = ds1.totalSize ds1.offset = d.newoffset | 
| ds → ε | ds.totalSize = ds.offset | 
| d → di : ty ; | addType(di.entry, ty.type) addBaseType(di.entry, ty.basetype) addSize(di.entry, ty.size) addOffset(di.entry, d.offset) d.newoffset = d.offset + ty.size | 
| d → TYPE di IS ty ; | not used yet | 
| di → IDENTIFIER | di.entry = IDENTIFIER.entry | 
| ty → INT | ty.type = integer ty.basetype = integer ty.size = 4 | 
| ty → REAL | ty.type = real ty.basetype = real ty.size = 8 | 
| ty → ARRAY [ NUM ] OF ty1 | ty.type = array(NUM.value, ty1.type) ty.basetype = ty1.basetype ty.size = NUM.value * ty1.size | 
| ty → IDENTIFIER | not used yet | 
| ss → s ss1 | s.next = newLabel() ss1.next = ss.nextss.code = s.code || label(s.next) || ss1.code | 
| ss → ε | ss.code = "" | 
| s → ks | ks.next = s.nexts.code = ks.code | 
| s → ids | s.code = ids.code | 
| ks → rs | ks.code = rs.code | 
| ks → ws | ws.next = ks.nextks.code = ws.code | 
| ks → ifs | ifs.next = ks.nextks.code = is.code | 
| rs → RETURN ; | rs.code = gen(return) | 
| rs → RETURN e ; | rs.code = e.code || gen(return e.addr) | 
| ws → WHILE be DO ss END ; | ws.begin = newLabel() be.true = newLabel() be.false = ws.next ss.next = ws.beginws.code = label(ws.begin) || be.code || label(be.true) || ss.code || gen(goto begin) | 
| ifs → IF be THEN ss oe END ; | be.true = newLabel() be.false = newLabel() ss.next = ifs.next oe.next = ifs.nextifs.code = be.code || label(be.true) || ss.code || gen(goto is.next) || label(be.false) || oe.code | 
| oe → ELSE ss | ss.next = oe.nextoe.code = ss.code | 
| oe → ε | oe.code = "" | 
| ids → IDENTIFIER rc | rc.id = IDENTIFIER.entryids.code = rc.code | 
| ids → IDENTIFIER ra | ra.id = IDENTIFIER.entryids.code = ra.code | 
| rc → ; | rc.code = gen(call rc.id.lexeme,0) | 
| rc → ( es ) ; | not done yet | 
| es → e | e , es | not done yet | 
| ra → := e ; | widen(e.addr, e.type, ra.id.basetype, ra.code1, ra.addr) ra.code = e.code || ra.code1 || gen(ra.id.lexeme=ra.addr) | 
| ra → i = e ; Note: index not indices | ra.t1 = newTemp() widen(e.addr, e.type, ra.id.basetype, ra.code1, ra.addr) ra.code = i.code || gen(ra.t1 = getBaseWidth(ra.id)*i.addr) || e.code || ra.code1 || gen(ra.id.lexeme[ra.t1]=ra.addr) | 
| be → bt OR be1 | bt.true = be.true bt.false = new Label() be1.true = be.true be1.false = be.falsebe.code = bt.code || label(bt.false) || be1.code | 
| be → bt | bt.true = be.true bt.false = be.falsebe.code = bt.code | 
| bt → bf AND bt1 | bf.true = new Label() bf.false = bt.false bt1.true = bt.true bt1.false = bt.falsebt.code = bf.code || label(bf.true) || bt1.code | 
| bt → bf | bf.true = bt.true bf.false = bt.falsebt.code = bf.code | 
| bf → NOT bf1 | bf1.true = bf.false bf1.false = bf.truebf.code = bf1.code | 
| bf → e RELOP e1 | bf.code = e.code || e1.code || gen(if e.addr RELOP.lexeme e1.addr goto bf.true) || gen(goto bf.false) | 
| bf → TRUE | bf.code = gen(goto bf.true) | 
| bf → FALSE | bf.code = gen(goto bf.false) | 
| bf → IDENTIFIER | bf.code = gen(if get(IDENTIFIER.lexeme) goto bf.true) || gen(goto bf.false) | 
| e → e1 ADDOP t | e.addr = new Temp() e.type = LUB(e1.type, t.type) widen(e1.addr, e1.type, e.type, e.code1, e.addr1) widen(t.addr, t.type, e.type, e.code2, e.addr2) e.code = e1.code || e.code1 || t.code || e.code2 || gen(e.addr = e.addr1 ADDOP.lexeme e.addr2) | 
| e → t | e.addr = t.addr e.type = t.type e.code = t.code | 
| t → t1 MULOP f | t.addr = new Temp() t.type = LUB(t1.type, f.type) widen(t1.addr, t1.type, t.type, t.code1, t.addr1) widen(f.addr, f.type, t.type, t.code2, t.addr2) t.code = t1.code || t.code1 || f.code || t.code2 || gen(t.addr = t.addr1 MULOP.lexeme t.addr2) | 
| t → f | t.addr = f.addr t.type = f.type t.code = f.code | 
| f → ( e ) | f.addr = e.addr f.type = e.type f.code = e.code | 
| f → NUMBER | f.addr = get(NUMBER.lexeme) f.type = NUMBER.entry.type f.code = "" | 
| f → IDENTIFIER (i.e., indices=ε) | f.addr = IDENTIFIER.lexeme f.type = getBaseType(IDENTIFIER.entry) f.code = "" | 
| f → IDENTIFIER i Note: index not indices | f.t1 = new Temp() f.addr = new Temp() f.type = getBaseType(IDENTIFIER.entry) f.code = i.code || gen(f.t1=i.addr*getBaseWidth(IDENTIFIER.entry)) || gen(f.addr=IDENTIFIER.lexeme[f.t1]) | 
| i → [ e ] | i.addr = e.addr i.type = e.type i.code = e.code |