ICS-C2000 Tietojenkäsittelyteoria

Samankaltaiset tiedostot
jäsennyksestä TIEA241 Automaatit ja kieliopit, syksy 2016 Antti-Juhani Kaijanaho 29. syyskuuta 2016 TIETOTEKNIIKAN LAITOS Kontekstittomien kielioppien

TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 10. kesäkuuta 2013

uv n, v 1, ja uv i w A kaikilla

Vasen johto S AB ab ab esittää jäsennyspuun kasvattamista vasemmalta alkaen:

jäsentämisestä TIEA241 Automaatit ja kieliopit, syksy 2015 Antti-Juhani Kaijanaho 27. marraskuuta 2015 TIETOTEKNIIKAN LAITOS

Yhteydettömät kieliopit [Sipser luku 2.1]

Laskennan mallit (syksy 2010) Harjoitus 8, ratkaisuja

jäsentäminen TIEA241 Automaatit ja kieliopit, syksy 2015 Antti-Juhani Kaijanaho 26. marraskuuta 2015 TIETOTEKNIIKAN LAITOS

follow(a) first(α j ) x

ICS-C2000 Tietojenkäsittelyteoria

ICS-C2000 Tietojenkäsittelyteoria. Tähän mennessä: säännölliset kielet. Säännöllisten kielten pumppauslemma M :=

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 12. kesäkuuta 2013

S BAB ABA A aas bba B bbs c

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 30. marraskuuta 2015

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 3. lokakuuta 2016

T Syksy 2002 Tietojenkäsittelyteorian perusteet Harjoitus 8 Demonstraatiotehtävien ratkaisut

Ei-yhteydettömät kielet [Sipser luku 2.3]

2. Yhteydettömät kielet

Jäsennysalgoritmeja. TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 29. syyskuuta 2009 TIETOTEKNIIKAN LAITOS. Jäsennysalgoritmeja

3.3 KIELIOPPIEN JÄSENNYSONGELMA Ratkaistava tehtävä: Annettu yhteydetön kielioppi G ja merkkijono x. Onko

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 29. huhtikuuta 2011

Jäsennys. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Täydentäviä muistiinpanoja jäsennysalgoritmeista

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 2. helmikuuta 2012

Attribuuttikieliopit

Rajoittamattomat kieliopit

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 16. helmikuuta 2012

Olkoon G = (V,Σ,P,S) yhteydetön kielioppi. Välike A V Σ on tyhjentyvä, jos A. NULL := {A V Σ A ε on G:n produktio};

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 9. lokakuuta 2016

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 3. joulukuuta 2015

Pinoautomaatit. Pois kontekstittomuudesta

4. Tehtävässä halutaan todistaa seuraava ongelma ratkeamattomaksi:

T Syksy 2006 Tietojenkäsittelyteorian perusteet T Harjoitus 7 Demonstraatiotehtävien ratkaisut

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Täydentäviä muistiinpanoja Turingin koneiden vaihtoehdoista

Kontekstittomien kielten jäsentäminen Täydentäviä muistiinpanoja TIEA241 Automaatit ja kieliopit, syksy 2016

Esimerkki 2.28: Tarkastellaan edellisen sivun ehdot (1) (3) toteuttavaa pinoautomaattia, jossa päätemerkit ovat a, b ja c ja pinoaakkoset d, e ja $:

Yhteydettömän kieliopin jäsennysongelma

M = (Q, Σ, Γ, δ, q 0, q acc, q rej )

Testaa: Vertaa pinon merkkijono syötteeseen merkki kerrallaan. Jos löytyy ero, hylkää. Jos pino tyhjenee samaan aikaan, kun syöte loppuu, niin

Chomskyn hierarkia ja yhteysherkät kieliopit

LR-jäsennys. Antti-Juhani Kaijanaho. 3. lokakuuta 2016

Täydentäviä muistiinpanoja kontekstittomien kielioppien jäsentämisestä

Jäsennysaiheesta lisää Täydentäviä muistiinpanoja TIEA241 Automaatit ja kieliopit, syksy 2016

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Osoitamme, että jotkut kielet eivät ole säännöllisiä eli niitä ei voi tunnistaa äärellisellä automaatilla.

Pinoautomaatit. TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 6. kesäkuuta 2013 TIETOTEKNIIKAN LAITOS. Pinoautomaatit.

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 29. syyskuuta 2009

Rajoittamattomat kieliopit (Unrestricted Grammars)

on rekursiivisesti numeroituva, mutta ei rekursiivinen.

6.5 Turingin koneiden pysähtymisongelma Lause 6.9 Kieli. H = {c M w M pysähtyy syötteellä w}

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

Vaihtoehtoinen tapa määritellä funktioita f : N R on

Rekursio. Funktio f : N R määritellään yleensä antamalla lauseke funktion arvolle f (n). Vaihtoehtoinen tapa määritellä funktioita f : N R on

Rekursiivinen Derives on periaatteessa aivan toimiva algoritmi, mutta erittäin tehoton. Jos tarkastellaan esim. kieliopinpätkää

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 5. marraskuuta 2015

Logiikan kertausta. TIE303 Formaalit menetelmät, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos.

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 12. lokakuuta 2016

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 19. tammikuuta 2012

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 12. tammikuuta 2012

δ : (Q {q acc, q rej }) (Γ k {, }) Q (Γ k {, }) {L, R}.

Miten käydä läpi puun alkiot (traversal)?

Esimerkki 47. Kieli {a i b j c k : i = j tai j = k} on luonnostaan moniselitteinen.

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 16. toukokuuta 2011

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 16. marraskuuta 2015

11.4. Context-free kielet 1 / 17

TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 29. toukokuuta 2013

Ydin-Haskell Tiivismoniste

Säännöllisen kielen tunnistavat Turingin koneet

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

JOHDATUS TEKOÄLYYN TEEMU ROOS

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 26. tammikuuta 2012

Muodolliset kieliopit

vaihtoehtoja TIEA241 Automaatit ja kieliopit, syksy 2016 Antti-Juhani Kaijanaho 13. lokakuuta 2016 TIETOTEKNIIKAN LAITOS

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 12. marraskuuta 2015

Mutta esimerkiksi 0-kertaisesti pumpattaessa: Siten L ei voi olla säännöllinen.

Hahmon etsiminen syotteesta (johdatteleva esimerkki)

Äärellisten automaattien ja säännöllisten kielten ekvivalenssi

Laskennan teoria (kevät 2006) Harjoitus 3, ratkaisuja

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Laskennan rajoja. TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 10. joulukuuta 2015 TIETOTEKNIIKAN LAITOS.

Säännölliset kielet. Sisällys. Säännölliset kielet. Säännölliset operaattorit. Säännölliset kielet

FORMAALI SYSTEEMI (in Nutshell): aakkosto: alkeismerkkien joukko kieliopin määräämä syntaksi: sallittujen merkkijonojen rakenne, formaali kuvaus

5.5 Jäsenninkombinaattoreista

(0 1) 010(0 1) Koska kieli on yksinkertainen, muodostetaan sen tunnistava epädeterministinen q 0 q 1 q 2 q3

5 Kontekstittomat kielet ja pinoautomaatit

802328A LUKUTEORIAN PERUSTEET OSA III BASICS OF NUMBER THEORY PART III. Tapani Matala-aho MATEMATIIKKA/LUTK/OULUN YLIOPISTO

Pinoautomaatit. TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 6. lokakuuta 2016 TIETOTEKNIIKAN LAITOS

33. pohjoismainen matematiikkakilpailu 2019 Ratkaisut

Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia, niin A on rekursiivinen.

1. Esitä rekursiivinen määritelmä lukujonolle

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina

Laskennan rajoja. TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 20. kesäkuuta 2013 TIETOTEKNIIKAN LAITOS.

Englannin lausekerakenteita ja taulukkojäsentäminen

TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 26. kesäkuuta 2013

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 31. maaliskuuta 2011

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 9. marraskuuta 2009

Transkriptio:

ICS-C2000 Tietojenkäsittelyteoria Luento 6: Jäsennyspuut, LL(1)-kielioppien jäsennys Aalto-yliopisto Perustieteiden korkeakoulu Tietotekniikan laitos Alue ja aiheet: Orposen prujun luvut 3.3 3.5 Kielioppien jäsennysongea Osittava jäsentäminen, LL(1)-kieliopit Attribuuttikieliopit Kevät 2016 2/65 Kertausta: yhteydettömät kieliopit Kielioppi C-tyyppisen ohjeointikielen aritmeettisille lausekkeille funktiokutsuilla (yksinkertaistettu). T + T T F T F F a ( ) f ( L ) L ε L L, L Jäsennyspuut simerkiksi lausekkeen f (a + a) a tuottaminen: T T F F F f (L) F f (L ) F f () F f ( + T) F f (T + T) F f (F + T) F f (a + T) F f (a + F) F f (a + a) F f (a + a) a. 3/65 4/65

3.3 Kielioppien jäsennysongea Ratkaistava tehtävä: Annettu yhteydetön kielioppi G ja merkkijono x. Onko x L(G)? Ratkaisumeneteä = jäsennysalgoritmi. Useita vaihtoehtoisia meneteiä, erityisesti kun G on jotain rajoitettua (käytännössä esiintyvää) muotoa. Johdot ja jäsennyspuut Olkoon γ V kieliopin G = (V,Σ,P,S) lausejohdos. Lähtösymbolista S merkkijonoon γ johtavaa suorien johtojen jonoa S = γ 0 γ 1 γ n = γ sanotaan γ:n johdoksi G:ssä. Johdon pituus on siihen kuuluvien suorien johtojen määrä (edellä n). Lauseen a + a johtoja kieliopissa G expr : (i) + T T + T F + T a + T a + F a + a (ii) + T + F T + F F + F F + a a + a (iii) + T + F + a T + a F + a a + a. 5/65 6/65 Johto γ γ on vasen johto, merkitään γ γ, jos kussakin johtoaskelessa on produktiota sovellettu merkkijonon vasemmanpuoleisimpaan välikkeeseen (edellä johto (i)). Vastaavasti määritellään oikea johto (edellä (iii)), jota merkitään γ γ rm Suoria vasempia ja oikeita johtoaskelia merkitään γ γ ja γ γ. rm Olkoon G = (V, Σ, P, S) yhteydetön kielioppi. Kieliopin G mukainen jäsennyspuu on järjestetty puu, jolla on seuraavat ominaisuudet: 1. puun sout on nimetty joukon V {ε} alkioilla siten, että sisäsoujen nimet ovat välikkeitä (so. joukosta N = V Σ) ja juurisoun nimenä on lähtösymboli S; 2. jos A on puun jonkin sisäsoun nimi, ja X 1,...,X k ovat sen jälkeläisten nimet järjestyksessä, niin A X 1...X k on G:n produktio. Jäsennyspuun τ tuotos on merkkijono, joka saadaan liittämällä yhteen sen lehtisoujen nimet esijärjestyksessä ( vasemmalta oikealle ). 7/65 8/65

Lauseen a + a jäsennyspuu kieliopissa G expr : Johtoa S = γ 0 γ 1 γ n = γ Lauseen johto: + T T F a + T T + T F + T a + T a + F a + a F a vastaavan jäsennyspuun muodostaminen: 1. puun juuren nimeksi tulee S; jos n = 0, niin puussa ei ole muita souja; muuten 2. jos ensimmäisessä johtoaskelessa on sovellettu produktiota S X 1 X 2...X k, niin juurelle tulee k jälkeläissoua, joiden nimet vasemmalta oikealle ovat X 1,X 2,...,X k ; 3. jos seuraavassa askelessa on sovellettu produktiota X i Y 1 Y 2...Y l, niin juuren i:nnelle jälkeläissoulle tulee l jälkeläistä, joiden nimet vasemmalta oikealle ovat Y 1,Y 2,...,Y l ; ja niin edelleen. Konstruktiosta huomataan, että jos τ on jotakin johtoa S γ vastaava jäsennyspuu, niin τ:n tuotos on γ. 9/65 10/65 Olkoon τ kieliopin G mukainen jäsennyspuu, jonka tuotos on päätemerkkijono x. Tällöin τ:sta saadaan vasen johto x:lle käymällä puun sout läpi esijärjestyksessä ( ylhäältä alas, vasemmalta oikealle ) ja laventamalla vastaan tulevat välikkeet järjestyksessä puun osoittamalla tavalla. Oikea johto saadaan käymällä puu läpi käänteisessä esijärjestyksessä ( ylhäältä alas, oikealta vasemmalle ). Muodostamalla annetusta vasemmasta johdosta S x ensin jäsennyspuu edellä esitetyllä tavalla, ja sitten jäsennyspuusta vasen johto, saadaan takaisin alkuperäinen johto; vastaava tulos pätee myös oikeille johdoille. Lauseen a + a vasemman johdon muodostaminen jäsennyspuusta. Jäsennyspuu: 1 2 + T 1 T 2 F 2 F 1 a 2 Sout esijärjestyksessä: 1 2 T 2 F 1 a 1 + T 1 F 2 a 2 Vasen johto: + T T + T F + T a + T a + F a + a a 1 11/65 12/65

Lause 3.3 Olkoon G = (V, Σ, P, S) yhteydetön kielioppi. Tällöin: jokaisella G:n lausejohdoksella γ on G:n mukainen jäsennyspuu τ, jonka tuotos on γ; jokaista G:n mukaista jäsennyspuuta τ, jonka tuotos on päätemerkkijono x, vastaavat yksikäsitteiset vasen ja oikea johto S x ja S x. rm Kieliopin moniselitteisyys simerkki Tarkastellaan yksinkertaisten aritmeettisten lausekkeiden kielioppia G expr = { +,, a, ()}. Lauseella a + a a on tässä kieliopissa kaksi jäsennystä: Seuraus 3.4 Jokaisella G:n lauseella on vasen ja oikea johto. a + + a Siis: yhteydettömän kieliopin tuottamien lauseiden jäsennyspuut, vasemmat ja oikeat johdot vastaavat yksikäsitteisesti toisiaan. Jäsennysongean ratkaisuun katsotaan usein kuuluvan pelkän päätösongean Onko x L(G)? ratkaisemisen lisäksi jonkin näistä jäsennysesityksistä tuottaminen. a a Yhteydetön kielioppi G on moniselitteinen, jos jollakin G:n lauseella x on kaksi erilaista G:n mukaista jäsennyspuuta. Muuten kielioppi on yksiselitteinen. a a 13/65 14/65 Moniselitteisyys on tietojenkäsittelysovelluksissa yleensä ei-toivottu ominaisuus, koska se merkitsee että annetulla lauseella on kaksi vaihtoehtoista tulkintaa. Yhteydetön kieli, jonka tuottavat kieliopit ovat kaikki moniselitteisiä, on luonnostaan moniselitteinen. simerkiksi kielioppi G expr on moniselitteinen, kieliopit G expr ja G match yksiselitteisiä. Kieli L expr = L(G expr) ei ole luonnostaan moniselitteinen, koska sillä on myös yksiselitteinen kielioppi G expr. Luonnostaan moniselitteinen on esimerkiksi kieli Osittava jäsentäminen (Todistus sivuutetaan.) {a i b j c k i = j tai j = k}. 15/65 16/65

3.4 Osittava jäsentäminen Yksi (yleisessä muodossa tehoton!) tapa etsiä vasenta johtoa (jäsennyspuuta) annetun kieliopin G mukaiselle lauseelle x on aloittaa G:n lähtösymbolista ja generoida systemaattisesti kaikki mahdolliset vasemmat johdot (jäsennyspuut), samalla sovittaen muodostetun lausejohdoksen päätemerkkejä (puun lehtiä) x:n merkkeihin. i-yhteensopivuuden ietessä peruutetaan viimeksi tehty produktiovalinta ja kokeillaan järjestyksessä seuraavaa vaihtoehtoa. Tällaista lauseenjäsennystapaa sanotaan osittavaksi, koska siinä tarkasteltu lause yritetään johtaa kieliopin lähtösymbolista osittamalla se valittujen produktioiden mukaisiin rakenneosiin ja yrittämällä näin, tarvittaessa toistuvasti edelleen osittamalla, sovittaa kieliopin tuottamaa rakennetta yhteen lauseen rakenteen kanssa. 17/65 Tarkastellaan kielioppia G: T + T T T a ( ) Lauseen a a osittava jäsennys G:n suhteen: T + a + T [ristiriita; peruutetaan] () + T [ristiriita; peruutetaan] T a a T + a a + [ristiriita; peruutetaan] a () + [ristiriita; peruutetaan] a T a a [ristiriita; peruutetaan] a () [ristiriita; peruutetaan] a T a a [OK!] 18/65 m. osittava jäsennystekniikka saadaan huomattavasti tehokkaammaksi, jos kieliopilla on sellainen ominaisuus, että jäsennyksen joka vaiheessa määrää tavoitteena olevan lauseen seuraava merkki yksikäsitteisesti sen, mikä lavennettavana olevaan välikkeeseen liittyvä produktio on valittava. Kielioppia, jolla on tämä ominaisuus, sanotaan LL(1)-tyyppiseksi. Muokataan G:stä välikkeen produktiot tekijöimällä ekvivalentti kielioppi G : T + ε T a ( ) simerkiksi lauseen a a jäsentäminen G :n suhteen (kulloisenkin produktiovalinnan määräävä syötemerkki on tässä merkitty vastaavan johtonuolen päälle): T a a a a T a a a ε a a. LL(1)-tyyppiselle kieliopille on helppo kirjoittaa jäsennysohjea suoraan rekursiivisina proseduureina; esimerkiksi kieliopille G Pythonilla seuraavasti: from sys import e x i t, s t d i n def e r r o r ( s ) : p r i n t s ; e x i t ( 1 ) def e ( ) : p r i n t " > T " t ( ) ; eprime ( ) def eprime ( ) : g l o b a l next i f next== " + " : p r i n t " > +" e ( ) e l i f next== " " : p r i n t " > " e ( ) else : p r i n t " >" Jatkuu seuraavalla kalvolla... 19/65 20/65

def t ( ) : g l o b a l next i f next== " a " : p r i n t "T > a " e l i f next== " ( " : p r i n t "T > () " e ( ) i f next!= " ) " : e r r o r ( " ) expected. " ) else : e r r o r ( "T cannot s t a r t with %s "%(next ) ) e ( ) simerkiksi syötejonoa a-(a+a) käsitellessään ohjea tulostaa seuraavat rivit: T T a - T T () T T a + T T a Tulostus vastaa vasenta johtoa: T a a a T a () a (T ) a (a ) a (a + ) a (a + T ) a (a + a ) a (a + a) a (a + a). 21/65 22/65 LL(1)-kieliopit Tarkastellaan seuraavassa LL(1)-kielioppien yleistä muotoa LL(1) parse input from Left to right, produce Leftmost derivation and use 1 token lookahead li luetaan syötettä vasemmalta oikealle ja tehdään vasen johto. Lisäksi tarkastellaan aina vain yhtä seuraavaa merkkiä syötteessä. simerkiksi kielioppi S A b C d A a A ε C c C ε on LL(1)-muodossa, vaikka sen kaikkien produktioiden oikeat puolet eivät alakaan päätesymbolilla 23/65 24/65

Vasen rekursio Vasen rekursio on vaikea osittavalle jäsennykselle Määriteä Kielioppi G = (V, Σ, P, S) on vasemmalle rekursiivinen jos jostakin välikkeestä A voidaan johtaa yhdellä tai useammalla askeleella merkkijono Aα, missä α V. Kielioppi Vasen rekursio on ongea osittavalle jäsennykselle, koska se takaa siukkaan jäämisen. Kielioppissa + T T T T F F F a ( ) + T T T T F F F a ( ) on vasemmalle rekursiivinen koska + T ja T T F. Tällaista jo yhdellä askeleella ienevää vasenta rekursiota sanotaan välittömäksi vasemmaksi rekursioksi. 25/65 osittava jäsentäminen voi jäädä tekemään johtoa + T + + T... ian, että merkkijonon alkuun tulee päätesymbolia 26/65 Myös kielioppi S A S a b A B B d A B b ε Vasemman rekursion poisto Välitön vasen rekursio muotoa A A β 1... A β n α 1... α m voidaan poistaa muuttamalla se oikeaksi rekursioksi A α 1 A... α m A A β 1 A... β n A ε Nyt esimerkiksi johtoa on vasemmalle rekursiivinen koska esimerkiksi S ASa BBSa BSa Sa. voidaan simuloida johdolla A Aβ 1 Aβ 2 β 1 α 1 β 2 β 1 A α 1 A αβ 2 A α 1 β 2 β 1 A α 1 β 2 β 1 (Myös yleinen vasen rekursio voidaan poistaa, katso esim. luku 4.3 kirjassa Aho, Sethi, Ulan: Compilers Principles, Techniques, and Tools, ei vaadita kurssilla) 27/65 28/65

Kieliopista + T T T T T F F F a ( ) saadaan välittömän vasemman rekursion poistolla kielioppi T + T T ε T F T T F T ε F a ( ) Vasen tekijöinti Toinen osittavalle jäsennykselle hankala konstruktio on samalla tavalla alkavat produktiot simerkiksi C++-kielen lauseet: stmt selection-stmt iteration-stmt... selection-stmt if ( expr ) then stmt if ( expr ) then stmt else stmt switch ( expr ) stmt missä iteration-stmt ja muut eivät ala if-päätesymbolilla. nsimmäisen if-päätesymbolin perusteella ei voida valita, pitääkö käyttää välikkeen selection-stmt ensimmäistä vai toista produktiota 29/65 30/65 Yhteiset alkuosat A α β 1... α β n γ voidaan tekijöidä seuraavasti A α A γ A β 1... β n C++-kielen tyylisen if-the-else -rakenteen selection-stmt if ( expr ) then stmt if ( expr ) then stmt else stmt switch ( expr ) stmt LL(1)-kielioppien formaali määriteä Määritellään seuraavaksi LL(1)-kieliopit formaalisti Tämä tapahtuu kahden apujoukon avulla FIRST kertoo, mitkä päätesymbolit voivat esiintyä ensimmäisenä produktiosta johdettavissa lauseissa FOLLOW kertoo, mitkä päätesymbolit voivat esiintyä heti annetun välikkeen jälkeen johdoissa vasen tekijöinti: selection-stmt if ( expr ) then stmt selection-stmt switch ( expr ) stmt selection-stmt else stmt ε 31/65 32/65

Tarvitaan käyttöön vielä tyhjentyvän välikkeen apukäsite Määriteä Välike A on tyhjentyvä jos A ε. Kieliopissa S A S a b A B B d A B b ε FIRST-joukot Määritellään jokaiselle välikkeelle A joukko FIRST(A) päätesymboleja (ml. ε jos A on tyhjentyvä), jotka voivat olla A:sta johdettavien merkkijonojen ensimmäisiä symboleja: Kieliopissa FIRST(A) = {a Σ A aγ jollekin γ V } {ε A ε} S A b C d A a A ε C c C ε välikkeet A ja B ovat tyhjentyviä koska A BB B ε B ε FIRST(C) = {c,ε} koska C cc ja C ε FIRST(A) = {a,ε} koska A aa ja A ε FIRST(S) = {a,b,c,d} koska S Ab aab ja S Ab b S Cd ccd ja S Cd d 33/65 34/65 Kieliopissa on S A S a b A B B d A B b ε FIRST(S) = {b,d} koska S b ja S ASa dasa FIRST(A) = {b,d,ε} koska A BB bb, A da ja A BB B ε FIRST(B) = {b,ε} koska B b ja B ε. FIRST-joukkojen laskeminen (sekä välikkeille että päätesymboleille) induktiivisesti: Jos a on päätesymboli (eli a Σ), niin FIRST(a) = {a} Jos X ε on produktio, niin ε FIRST(X) Jos X X 1 X 2...X k on produktio, päätesymboli a FIRST(X i ) jollekin 1 i k ja ε FIRST(X j ) kaikille 1 j < i, niin a FIRST(X) Jos X X 1 X 2...X k on produktio ja ε FIRST(X j ) kaikille 1 j k, niin ε FIRST(X) Pätee: ε FIRST(A) jos ja vain jos A on tyhjentyvä 35/65 36/65

Tarkastellaan kielioppia S A b C d A a A ε C c C ε FIRST(a) = {a}, FIRST(b) = {b}, FIRST(c) = {c}, FIRST(d) = {d} ε FIRST(C) koska C ε on produktio c FIRST(C) koska C cc on produktio ε FIRST(A) koska A ε on produktio a FIRST(A) koska A aa on produktio a FIRST(S) koska S Ab on produktio ja a FIRST(A) b FIRST(S) koska S Ab on produktio, ε FIRST(A) ja b FIRST(b) Laajennetaan FIRST aakkoston V merkkijonoille, jotta voimme tarkastella produktioiden oikeiden puolten ensimmäisiä merkkejä Määritellään induktiivisesti: FIRST(X 1...X k ) on joukon Σ {ε} pienin osajoukko, jolle pätee seuraavat ehdot: ε FIRST(ε) a FIRST(a) jokaiselle a Σ Jos x Σ, x FIRST(X i ) jollekin 1 i k ja ε FIRST(X j ) kaikille 1 j < i, niin x FIRST(X 1...X k ) Jos ε FIRST(X j ) kaikille 1 j k, niin ε FIRST(X 1...X k ) c, d FIRST(S) samasta syystä 37/65 38/65 Tarkastellaan taas kielioppia Kieliopissa S A b C d A a A ε C c C ε Nyt FIRST(A) = {a,ε} ja FIRST(b) = {b} FIRST(C) = {c,ε} ja FIRST(d) = {d} FIRST(S) = {a,b,c,d} FIRST(Ab) = {a,b} FIRST(Cd) = {c,d} voidaan johdon alussa ensimmäisen merkin perusteella valita, kumpaako produktiota S Ab vai S Cd tulee käyttää + T T T T F F F a ( ) on FIRST(F) = {a,(} FIRST(T) = {a,(} FIRST() = {a,(} FIRST( + T) = {a,(} sekä produktiota + T että T soveltamalla voidaan saada johdoksen ensimmäiseksi merkiksi a alussa ei voida ensimmäisen merkin perusteella valita, kumpaako produktiota pitää käyttää 39/65 40/65

Kielioppi: T + T ε T F T T F T ε F a ( ) FIRST-joukot: Tarkastellaan johdon tekemistä lauseelle a a + a: T FT at FIRST() = {a,(} FIRST( ) = {+,ε} FIRST(T) = {a,(} FIRST(T ) = {,ε} FIRST(F) = {a,(} Pitäisikö nyt käyttää produktiota T F T vai T ε? Miksi? Pieni if-then-else -kielioppi tekijöinnin jälkeen: FIRST-joukkoja: FIRST(S) = {s,if} S s if C then S S FIRST(S ) = {else,ε} S else S ε FIRST(C) = {c} C c FIRST(else S) = {else} FIRST(ε) = {ε} Muodostetaan vasenta johtoa lauseelle ifcthenifcthenselses: S ifc thenss ifcthenss ifcthenifc thenss S ifcthenifcthenss S ifcthenifcthenss S Pitäisikö nyt käyttää produktiota S elses vai S ε? 41/65 42/65 FOLLOW-joukot Tyhjentyville produktioille FIRST-joukko sisältää symbolin ε Miten tämä tulisi tulkita kun päätetään, mitä produktiota käytetään? Määritellään jokaiselle välikkeelle A joukko FOLLOW(A) päätemerkkejä (ml. erikoissymboli $, joka kuvaa syötteen loppua), jotka voivat seurata A:ta jossain johdossa: c FOLLOW(A) jos c Σ ja S αacβ jollekin α,β V $ FOLLOW(A) jos S αa jollekin α V Kielioppi: Nyt T + T ε T F T T F T ε F a ( ) FIRST-joukot: FOLLOW() = FOLLOW( ) = {$,)} koska on aloitusvälike, ()T ja T FIRST(F) = {a,(} FIRST(T ) = {,ε} FIRST(T) = {a,(} FIRST( ) = {+,ε} FIRST() = {a,(} FOLLOW(T) = FOLLOW(T ) = {+,$,)} koska T T + T, T T ja T FT FOLLOW(F) = {+,,$,)} koska T FT F FT T FT F (mikä seuraa F:ää, seuraa T:tä) 43/65 44/65

Kielioppi: T + T ε T F T T F T ε F a ( ) Koska FOLLOW() = FOLLOW( ) = {$,)} FIRST-joukot: FOLLOW(T) = FOLLOW(T ) = {+,$,)} FOLLOW(F) = {+,,$,)} tehtäessä vasenta johtoa lauseelle a a + a T FT at FIRST(F) = {a,(} FIRST(T ) = {,ε} FIRST(T) = {a,(} FIRST( ) = {+,ε} FIRST() = {a,(} tiedetään nyt, että pitää käyttää produktiota T F T eikä T ε koska välikettä T ei voi missään johdossa seurata symboli. 45/65 Pieni if-then-else -kielioppi tekijöinnin jälkeen: S s if C then S S S else S ε C c Muodostetaan taas vasenta johtoa lauseelle ifcthenifcthenselses: Nyt S ifc thenss... sekä else FIRST(else S) FOLLOW-joukkoja: ifcthenifcthenss S että S ε ja else FOLLOW(S ) FOLLOW(S) = {$, else} FOLLOW(S ) = {$,else} FOLLOW(C) = {then} emme voi pelkän seuraavan symbolin else perusteella valita, pitäisikö käyttää produktiota S elses vai S ε 46/65 FOLLOW-joukkojen laskeminen induktiivisesti FOLLOW-joukot ovat pienimpiä joukkoja, jotka täyttävät seuraavat ehdot: Jos S on kieliopin aloitussymboli, niin $ FOLLOW(S) Jos A αbβ on produktio ja päätesymboli a FIRST(β), niin a FOLLOW(B) Jos A αb on produktio ja a FOLLOW(A), niin a FOLLOW(B) Jos A αbβ on produktio, ε FIRST(β) ja a FOLLOW(A), niin a FOLLOW(B) Kielioppi: Nyt T + T ε T F T T F T ε F a ( ) FIRST-joukot: $ FOLLOW() koska on aloitussymboli ) FOLLOW() koska F ( ) on produktio FIRST(F) = {a,(} FIRST(T ) = {,ε} FIRST(T) = {a,(} FIRST( ) = {+,ε} FIRST() = {a,(} $,) FOLLOW( ) koska T on produktio + FOLLOW(T) koska +T ja + FIRST( ) jne... 47/65 48/65

Tehdään kaksiuloitteinen jäsennystaulu M, jossa joukkoarvoinen alkio M(A, a) sisältää ne säännöt, joita voidaan soveltaa välikesymbolista A kun seuraava syötemerkki on a: Jos A α on produktio ja päätesymboli a FIRST(α), niin A α M(A,a) Jos A α on produktio, ε FIRST(α) ja b FOLLOW(A), niin A α M(A,b) Määriteä Kielioppi on LL(1)-kielioppi jos sen jäsennystaulun jokaisessa kentässä on korkeintaan yksi produktio. ( Orposen prujussa erilainen mutta vastaava määriteä) Tarkastellaan jälleen kielioppia Jäsennystaulu on T + T ε T F T T F T ε F a ( ) a + ( ) $ T T +T ε ε T T F T T F T T T ε T F T T ε T ε F F a F ( ) 49/65 50/65 Attribuuttikieliopit 51/65 3.5 Attribuuttikieliopit Tapa liittää yhteydettömiin kielioppeihin yksinkertaista kielen semantiikan kuvausta. Kukin kieliopin mukaisen jäsennyspuun sou, jonka nimenä on symboli X, ajatellaan tietueeksi, joka on tyyppiä X. Tietuetyyppiin X kuuluvia kenttiä sanotaan X:n attribuuteiksi ja merkitään X.s, X.t jne. Kussakin X-tyyppisessä jäsennyspuun soussa ajatellaan olevan X:n attribuuteista eri ientymät. Kieliopin produktioihin A X 1...X k liitetään attribuuttien evaluointisääntöjä, jotka iaisevat miten annetun jäsennyspuun soun attribuutti-ientymien arvot määräytyvät sen isä- ja jälkeläissoujen attribuutti-ientymien arvoista. Säännöt voivat olla periaatteessa minkälaisia funktioita tahansa, kunhan niiden argumentteina esiintyy vain paikallisesti saatavissa olevaa tietoa. Tarkemmin sanoen: produktioon A X 1...X k liitettävissä säännöissä saa mainita vain symbolien A,X 1,...,X k attribuutteja. 52/65

tumerkillisten kokonaislukujen arvojen määrittäminen Kuhunkin jäsennyspuun X-tyyppiseen välikesouun liitetään attribuuttiientymä X.v, jonka arvoksi tulee X:stä tuotetun numerojonon lukuarvo; erityisesti juurisoun v-ientymän arvoksi tulee koko puun tuotoksena olevan numerojonon luku. Produktiot: valuointisäännöt: I +U I.v := U.v I U I.v := U.v I U I.v := U.v U D U.v := D.v U UD U 1.v := 10 U 2.v + D.v D 0 D.v := 0 D 9 D.v := 9 Produktioon U UD liittyvässä evaluointisäännössä on välikkeen U eri esiintymät erotettu indekseillä. simerkiksi näitä sääntöjä käyttäen attributoitu lauseen -319 jäsennyspuu on seuraava: U v = 3 I v = 319 U v = 31 U v = 319 D v = 3 D v = 1 D v = 9 3 1 9 53/65 54/65 Attribuuttikieliopin attribuutti t on synteettinen, jos sen kuhunkin produktioon A X 1...X k liittyvä evaluointisääntö on muotoa A.t := f (A,X 1,...,X k ). Tällöin jäsennyspuussa kunkin soun mahdollisen t- ientymän arvo riippuu vain soun omien ja sen jälkeläisten attribuutti-ientymien arvoista. Muunlaiset attribuutit ovat periytyviä. Attribuuttisemantiikan kuvauksessa pyritään käyttämään pääasiassa synteettisiä attribuutteja, koska ne voidaan evaluoida helposti yhdellä jäsennyspuun lehdistä juureen suuntautuvalla läpikäynnillä. Mitään periaatteellista estettä myös perittyjen attribuuttien käyttöön ei kuitenkaan ole kunhan attribuutti-ientymien riippuvuusverkkoihin ei tule syklejä. Kokonaislukujen arvon määrittäminen periytyvää positiokerroin - attribuuttia s ja synteettistä arvo -attribuuttia v käyttäen: Produktiot: valuointisäännöt: I +U U.s := 1, I.v := U.v I U U.s := 1, I.v := U.v I U U.s := 1, I.v := U.v U D U.v := (D.v) (U.s) U UD U 2.s := 10 (U 1.s), U 1.v := U 2.v + (D.v) (U 1.s) D 0 D.v := 0. D 9 D.v := 9 55/65 56/65

m. positiokerrointekniikkaa käyttäen saadaan lauseelle -319 seuraava attributoitu jäsennyspuu: I v = 319 U U s = 10 v = 310 s = 1 v = 319 Attribuutti-ientymien arvot voidaan usein laskea suoraan jäsennysrutiineissa muodostamatta jäsennyspuuta eksplisiittisesti. Ohjea, joka muuntaa syötteenä annettuja aritmeettisia lausekkeita postfix-esitykseen. Tavanomaiseen, yksinkertaisia aritmeettisia lausekkeita tuottavaan kielioppiin liitetään yksi synteettinen, merkkijonoarvoinen attribuutti pf ; kuhunkin välikkeeseen X liittyvän attribuutti-ientymän X.pf arvo on X:stä tuotetun alilausekkeen postfix-esitys. U 3 s = 100 v = 300 D v = 3 D v = 1 D v = 9 1 9 Produktiot: valuointisäännöt: T + 1.pf := (T.pf) ( 2.pf) ( + ) T.pf := T.pf T F T T 1.pf := (F.pf) (T 2.pf) ( ) T F T.pf := F.pf F a F.pf := a F () F.pf :=.pf 57/65 58/65 Rekursiivisesti etenevä jäsentäjä, joka evaluoi attribuutti-ientymien arvot suoraan jäsennyksen yhteydessä: from sys import s t d i n def e r r o r ( s ) : p r i n t s ; e x i t ( 1 ) def e ( ) : # > T + T g l o b a l next pf1= t ( ) i f next== " + " : r e t u r n pf1+e ( ) + " + " # 1. pf := T. pf 2. pf + else : r e t u r n pf1 #. pf := T. pf def t ( ) : # T > F * T F g l o b a l next pf1= f ( ) i f next== " * " : r e t u r n pf1+ t ( ) + " * " # T1. pf := F. pf T2. pf * else : r e t u r n pf1 # T. pf := F. pf def f ( ) : # F > a () g l o b a l next i f next== " a " : r e t u r n " a " # F. pf := a e l i f next== " ( " : pf=e ( ) i f next!= " ) " : e r r o r ( " ) expected. " ) r e t u r n pf # F. pf :=. pf else : e r r o r ( "F cannot s t a r t with t h i s. " ) p r i n t e ( ) Jatkuu seuraavalla kalvolla... 59/65 60/65

kskursio Scala-maaiaan i kuulu tenttivaatimuksiin Viitteitä: Scala-kielen mukana tulee kirjasto (rajoitettuun) osittavaan jäsentämiseen Myös säännöllisiä lausekkeita voidaan käyttää suoraan luku 31 kirjassa Programming in Scala, First dition Parsers-piirre abstrakti Parser-luokka RegexParsers-piirre 61/65 62/65 Yksinkertaisten lausekkeiden jäsennin ja evaluaattori: import u t i l. parsing. combinator. _ object parser extends RegexParsers { val i n t e g e r = " [0 9]+ ". r / / Regular expression } def expr : Parser [ B i g I n t ] = ( / / > T + T term~" + "~expr ^^ { case t~" + "~e => t + e } term ^ ^ { case t => t } ) def term : Parser [ B i g I n t ] = / / T > F * T T rep1sep ( f a c t o r, " * " ) ^ ^ { f a c t o r s => f a c t o r s. product } def f a c t o r : Parser [ B i g I n t ] = ( / / F > i n t e g e r ( ) i n t e g e r ^ ^ { case i n t S t r i n g => B i g I n t ( i n t S t r i n g ) } " ( " ~> expr <~ " ) " ^ ^ { case e => e } ) def parse ( i n p u t : S t r i n g ) : ( Option [ B i g I n t ], S t r i n g ) = { parseall ( expr, i n p u t ) match { case Success ( value, _ ) => ( Option ( value ), " success " ) case f => ( None, f. t o S t r i n g ) } } Hyvinmuodostetulla syötteellä saadaan odotettu lopputulos: scala > parser. parse ("123+4 * 5") res0 : ( Option [ B i g I n t ], S t r i n g ) = (Some(143), success ) kun taas virheellinen syöte antaa virheioituksen: scala > parser. parse ("123++4 * 5") res1 : ( Option [ B i g I n t ], S t r i n g ) = ( None, [ 1. 5 ] f a i l u r e : ( expected but + found 123++4 * 5 ^ ) 63/65 64/65

Klassikkokirja aiheista: Aho, Sethi, Ulan: Compilers Principles, Techniques, and Tools Kääntäjätekniikan kurssi Aallossa: T-106.4200 Johdatus kääntäjätekniikkaan 65/65