Svarforslag

Oppgaver og svar om symboltabell og typesjekking
Foiler ved Birger Møller Pedersen
Forelest av Stein Krogdahl
24. mars, 2015
Oppgaver (fra boka):
6.17, 6.18, 6.20, 6.21, 6.22.
NB:
- Ingen forelesning torsdag 26. mars
- Oblig 2 blir lagt ut før påske, men
orientering om den blir etter påske
6.17
4. Med «sequential» deklarasjon er dette lovlig:
Men med «collatereral» regel for deklarasjoner er
dette ikke lovlig, fordi «x» i «y=x+1» da ikke vil være
definert.
Utgangspunkt: Tabell 6.9 «sequetial declarations», på side 311 i boka
Alle «ferdige» enkelt-deklarasjoner til venstre for deg er synlige
2
3
3/27/2015
3
Tabell 6.9, fortsatt:
4
4
1
3/27/2015
4
Først, de gamle attributtene brukt i tabell 10.9, så forandringene:
Funksjoner:
Attributter:
exp: symtab
nestlevel
err
arvet
arvet
syntetisert
• insert(tab, name, lev)
• isIn(tab, name)
• lookup(tab, name)
Nytt, for å få til «collateral declaration»:
dec-list: intab
arvet
outtab
syntetisert
nestlevel arvet
decl: intab
outtab
nestlevel
arvet
syntetisert
arvet
id:
mottas fra scanneren
name
3/27/2015
leverer ny tabell
leverer ja/nei
gir nivået
For å få til dette må vi (for ‘decl’ og ‘dec-list’)
skifte ut attributtet «intab» med to attributter
med navn f.eks. «addintab» og «readintab»,
og vi omnavner også attributtet «outtab» til
«addouttab».
5
Tanken er da at, mens vi arbeider med en
deklarasjonsliste, så skal «readintab» hele
tiden ha bare deklarasjonene fra forrige
blokknivå, mens vi i «addintab» setter inn
også de nye deklarsjonene vi passerer forbi.
Siden «read»-listen ikke forandrer seg
trenger vi ikke noe attributt «readouttab»
Den nye attributt-grammatikken for «Collateral declarations»
Forklaring på de nye attributtene «readintab», «addintab» og «addouttab» på forrige slide
Grammar Rule
Semantic Rule
S → exp
As before
exp1 → exp2 + exp3
As before
exp1 → ( exp2 )
As before
exp → id
As before
exp → num
As before
exp1 → let dec-list in exp2
dec-list.addintab = exp1.symtab
dec-list.readintab = exp1.symtab
dec-list.nestlevel = exp1.nestlevel+1
exp2.symtab = dec-list2.addouttab
exp2.nestlevel = exp1.nestlevel+1
dec-list1 → dec-list2 , decl
dec-list2.addintab = dec-list1.addintab
dec-list2.readintab = dec-list1.readintab
decl.addintab = dec-list2.addouttab
decl.readintab = dec-list1.readintab
dec-list1.addouttab = decl.addouttab
Side 2 av attributt-grammatikken
Grammar Rule
Semantic Rule
dec-list → decl
decl.addintab = dec-list.addintab
decl.readintab = dec-list.readintab
decl.nestlevel = dec-list.nestlevel
dec-list.addouttab = decl.addouttab
decl → id = exp
exp.symbtab = decl.readintab
decl.addouttab =
if ((decl.addintype = errtab) or exp.err)
then errtab
else if ( lookup(decl.addintype,id.name) =
decl.nestlevel )
then errtab
else
insert(decl.addintab,id.name,decl.nestlevel)
6.18
Her skal vi altså ha sekvensiell tolkning av deklarasjonene
Her har vi altså en bare syntetiserte attributter (og det er en L-attributtgrammatikk). «insert (…, …)» (på neste foil) lager her en ny tabell, så vi
behøver aldri fjerne noe fra tabellene.
Grammar Rule
Semantic Rule
exp1 →
exp1.val =
if (exp2.val = error) or
(exp3.val = error)
then error
else exp2.val + exp3.val
exp2 + exp3
exp1 → (exp2)
exp1.val = exp2.val
exp → id
exp.val = lookupVal(exp.symtab,
id.name)
exp → num
exp.val = num.val
exp1 → let dec-list in exp2
exp1.val =
if (decl-list.outtab = errtab)
then error
else exp2.val
6.20
INF5110: Vi beregner i stedet verdien av et slikt uttrykk!
Vi regner her med at vi bare vil beregne verdien av et slikt uttrykk (det
inneholder bare tallverdier). Om man vil lage Modula-II-kode må man ha et
tekst-attributt, f.eks. «code».
Oppgave 6.21: Her er det ingen navn på typer, så type-uttrykkene
må skrives helt ut for hver var-decl. Dermed kan det også bare ha
strukturell typelikhet, og vi må altså teste for det i denne
grammatikken:
Svar 6.21.a
Svar 6.21.b
Operasjonen «+» setter her en liste og et element sammen til en ny liste
NB: Dette er slikt man bør unngå om lager et nytt språk!
Her er det nemlig rimelig å bringe inn semantisk informasjon mens man
holder på parseringen, og det skaper ukarheter mellom nivåene. Og ikke
minst: der som regel uproblematisk å unngå! Om man ikke bringer inn
sematisk informasjon på denne måten må man gjøre parserings-aktige
ting under semantisk analyse.
a)
Hvis parseren skal skille mellom cast-uttrykk og aritmetiske uttrykk må parseren, når
den behandler A, kunne slå opp i symboltabellen og finne ut om A erdeklarart som et
typenavn eller som et variabelnavn. For å kunne gjøre dette må parseren sette inn
navn (sammen med oplysning om det er et typenavn eller et variablenavn) i
symboltabellen når det deklarares. Parseren konstruerer da en node (eller subtre) i
syntakstreet som representerer «casting til typen A». I motsatt fall setter den inn en
vanlig expression-node for A. Basert på dette kan så parseren avgjøre om det riktige
alternativet er (-x) som skal castes, eller om det er en vanlig binær minus.
b)
Hvis skanneren skal skille mellom forskjellig bruk av A, da må skanneren kunne slå
opp A i symboltabellen. Dette krever også at parseren setter inn navn på variable og
typer når de deklarares, da skanneren ikke ser nok av input til å bestemme om et
navn er et typenavn eller et variabelnavn. Hvis skanneren slår opp A og finner ut at det
er et typenavn, da kan den returnere et tilsvarende token: i stedet for en ID kan den
returnere en TypeID token. Parseren trenger da ikke å foreta noe oppslag. Basert på
det token den får fra skanneren kan den generere det riktige syntakstre.