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.
© Copyright 2024