The Full SDD

The Full SDD
ProductionSemantic 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 = 0
s.next = newLabel()
ss.next = pd.next
pd.code = s.code || label(s.next) || ss.code
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.offset
ds1.offset = d.newoffset
ds.totalSize = ds1.totalSize
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.next
ss.code = s.code || label(s.next) || ss1.code
ss → ε ss.code = ""
s → ks
ks.next = s.next
s.code = ks.code
s → ids s.code = ids.code
ks → rs ks.code = rs.code
ks → ws
ws.next = ks.next
ks.code = ws.code
ks → ifs
ifs.next = ks.next
ks.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.begin
ws.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.next
ifs.code = be.code || label(be.true) || ss.code ||
    gen(goto is.next) || label(be.false) || oe.code
oe → ELSE ss
ss.next = oe.next
oe.code = ss.code
oe → ε oe.code = ""
ids → IDENTIFIER rc
rc.id = IDENTIFIER.entry
ids.code = rc.code
ids → IDENTIFIER ra
ra.id = IDENTIFIER.entry
ids.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.false
be.code = bt.code || label(bt.false) || be1.code
be → bt
bt.true = be.true
bt.false = be.false
be.code = bt.code
bt → bf AND bt1
bf.true = new Label()
bf.false = bt.false
bt1.true = bt.true
bt1.false = bt.false
bt.code = bf.code || label(bf.true) || bt1.code
bt → bf
bf.true = bt.true
bf.false = bt.false
bt.code = bf.code
bf → NOT bf1
bf1.true = bf.false
bf1.false = bf.true
bf.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