Luku 3. Syntaktisia kysymyksiä. 3.1 Lausekkeet

Samankaltaiset tiedostot
TIES542 kevät 2009 Lausekkeista ja vähän muustakin

TIES542 kevät 2009 Denotaatio

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

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

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

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

Tietojenkäsittelyteorian alkeet, osa 2

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

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

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

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

(1) refleksiivinen, (2) symmetrinen ja (3) transitiivinen.

11.4. Context-free kielet 1 / 17

Matematiikassa ja muuallakin joudutaan usein tekemisiin sellaisten relaatioiden kanssa, joiden lakina on tietyn ominaisuuden samuus.

Yhteydettömät kieliopit [Sipser luku 2.1]

Luonnollisten lukujen ja kokonaislukujen määritteleminen

Diskreetin matematiikan perusteet Laskuharjoitus 2 / vko 9

Ensimmäinen ohjelmointikieli

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

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä, todistuksia ym., osa I

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä, todistuksia ym., osa I

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

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

2. Minkä joukon määrittelee kaava P 0 (x 0 ) P 1 (x 0 ) mallissa M = ({0, 1, 2, 3}, P M 0, P M 1 ), kun P M 0 = {0, 1} ja P M 1 = {1, 2}?

MS-A0402 Diskreetin matematiikan perusteet

Kuvaus eli funktio f joukolta X joukkoon Y tarkoittaa havainnollisesti vastaavuutta, joka liittää joukon X jokaiseen alkioon joukon Y tietyn alkion.

Rekursiiviset tyypit

Kuvaus eli funktio f joukolta X joukkoon Y tarkoittaa havainnollisesti vastaavuutta, joka liittää joukon X jokaiseen alkioon joukon Y tietyn alkion.

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

MAT Algebra 1(s)

Lisää pysähtymisaiheisia ongelmia

Syntaksi. TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 22. syyskuuta 2009 TIETOTEKNIIKAN LAITOS. Syntaksi. Aluksi.

Jäsennys. TIEA341 Funktio ohjelmointi 1 Syksy 2005

TIEA341 Funktio-ohjelmointi 1, kevät 2008

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

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 8. syyskuuta 2016

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

815338A Ohjelmointikielten periaatteet

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

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

Valitsemalla sopivat alkiot joudutaan tämän määritelmän kanssa vaikeuksiin, jotka voidaan välttää rakentamalla joukko oppi aksiomaattisesti.

Ohjelmointikielten syntaksista ja semantiikasta

Nimitys Symboli Merkitys Negaatio ei Konjuktio ja Disjunktio tai Implikaatio jos..., niin... Ekvivalenssi... jos ja vain jos...

Attribuuttikieliopit

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

811120P Diskreetit rakenteet

Joukot. Georg Cantor ( )

Relaation ominaisuuksia. Ominaisuuksia koskevia lauseita Sulkeumat. Joukossa X määritelty relaatio R on. (ir) irrefleksiivinen, jos x Rx kaikilla x X,

2. Yhteydettömät kielet

5.5 Jäsenninkombinaattoreista

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

Joukossa X määritelty relaatio R on. (ir) irrefleksiivinen, jos x Rx kaikilla x X,

T Syksy 2004 Logiikka tietotekniikassa: perusteet Laskuharjoitus 7 (opetusmoniste, kappaleet )

Matematiikan tukikurssi

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

Luonnollisen päättelyn luotettavuus

811120P Diskreetit rakenteet

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

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

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

Täydentäviä muistiinpanoja Turingin koneiden vaihtoehdoista

Kuvauksista ja relaatioista. Jonna Makkonen Ilari Vallivaara

Loogiset konnektiivit

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

[a] ={b 2 A : a b}. Ekvivalenssiluokkien joukko

2.4 Normaalimuoto, pohja ja laskentajärjestys 2.4. NORMAALIMUOTO, POHJA JA LASKENTAJÄRJESTYS 13

8. Kieliopit ja kielet

missä on myös käytetty monisteen kaavaa 12. Pistä perustelut kohdilleen!

Lineaarialgebra ja matriisilaskenta II. LM2, Kesä /141

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

S BAB ABA A aas bba B bbs c

Konnektiivit. On myös huomattava, että vain joillakin luonnollisen kielen konnektiiveilla on vastineensa lauselogiikassa.

Täydentäviä muistiinpanoja jäsennysalgoritmeista

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

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

MS-A0402 Diskreetin matematiikan perusteet

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

Luku 2. Ohjelmointi laskentana. 2.1 Laskento

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

Chomskyn hierarkia ja yhteysherkät kieliopit

Matematiikan tukikurssi, kurssikerta 2

1. Logiikan ja joukko-opin alkeet

Uusi näkökulma. TIEA341 Funktio ohjelmointi 1 Syksy 2005

MS-A0401 Diskreetin matematiikan perusteet

Ongelma(t): Miten jollakin korkeamman tason ohjelmointikielellä esitetty algoritmi saadaan suoritettua mikro-ohjelmoitavalla tietokoneella ja siinä

8 Joukoista. 8.1 Määritelmiä

Ilkka Mellin Todennäköisyyslaskenta Liite 1: Joukko-oppi

Rekursiiviset palautukset [HMU 9.3.1]

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

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

Ohjelmointikielten periaatteet Syksy Antti-Juhani Kaijanaho

Predikaattilogiikkaa

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

8 KANNAT JA ORTOGONAALISUUS. 8.1 Lineaarinen riippumattomuus. Vaasan yliopiston julkaisuja 151

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

Algebra I Matematiikan ja tilastotieteen laitos Ratkaisuehdotuksia harjoituksiin 6 (8 sivua) OT. 1. a) Määritä seuraavat summat:

Java-kielen perusteet

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

Matematiikan johdantokurssi, syksy 2016 Harjoitus 11, ratkaisuista

3. Kirjoita seuraavat joukot luettelemalla niiden alkiot, jos mahdollista. Onko jokin joukoista tyhjä joukko?

Transkriptio:

Luku 3 Syntaktisia kysymyksiä Syntaksi eli kielioppi käsittelee ohjelmien muodollista oikeellisuutta pohtimatta merkitysopillisia eli semanttisia kysymyksiä. Kieliopilliset ominaisuudet ovat (useimmiten) staattisia. 3.1 Lausekkeet Ehkä mullistavin ero toisen ja kolmannen ohjelmointikielisukupolvien siis symbolisen konekielen ja tavanomaisen (imperatiivisen) ohjelmointikielen välillä on siinä, miten laskutoimitukset voidaan niissä ilmaista. Symbolisessa konekielessä laskentakäskyt ovat tyypillisesti muotoa ota luku muistipaikasta A, ota toinen luku muistipaikasta B ja tallenna niiden summa muistipaikkaan C. Ohjelmoijaparan epäkiitolliseksi tehtäväksi tulee siten paitsi itse laskutehtävän määritteleminen myös sen pilkkominen yksinkertaisiin osiin. Esimerkiksi hypotenuusan pituuden laskeminen c a 2 + b 2 joudutaan kirjoittamaan symbolisella konekielellä tyyliin t 1 a a t 2 b b t 3 t 1 + t 2 c t 3 Tässä nuoli vasemmalle ilmaisee muuttujaan sijoittamista. Toki jokaisella konekielellä on omat erityispiirteensä, ja kullakin konekielellä koodi näyttäisi huomattavastikin erilaiselta kuin yllä, mutta ylläolevassa tulee olennainen esille. Kun vielä tyypillisessä konekielessä nopeiden muistipaikkojen eli rekisterien määrä on erittäin rajallinen (vanhoissa koneissa muuta- 31

32 LUKU 3. SYNTAKTISIA KYSYMYKSIÄ ma, Intelin 32-bittisissä puolisen tusinaa, parhaissa muutama kymmenen) ja tyypillisessä ohjelmassa tällaista laskentaa harjoitetaan jatkuvasti, kasvavat ohjelmoijan työmäärä, turhaumat ja virhealttius merkittävästi. Monet varhaiset ohjelmointikielet eivät olleet juuri sen kummallisempia kuin symbolisten konekielten yksinkertaisia laajennuksia, joissa ohjelmoija saattoi kirjoittaa sijoituskäskyn oikealle puolelle kohtuullisen monimutkaisen aritmeettisen laskutehtävän. Vielä tänäkin päivänä tuki tällaisille lausekkeille (engl. expressions) on ohjelmointikielen yksi tärkeimmistä (mutta helposti huomaamatta jäävistä) tehtävistä. Maailman vanhimman korkean tason ohjelmointikielen nimi on FORTRAN, formula translator, syystä. Sallittujen lausekkeiden joukko riippuu kielestä. Käytännössä kaikki ohjelmointikielet tukevat ainakin tavallisia aritmeettisia lausekkeita: 1. Lukuvakio on aritmeettinen lauseke. 2. Muuttuja, joka on nykyisessä ympäristösssä sidottu lukuarvoon, on aritmeettinen lauseke. 3. Jos e ja e ovat aritmeettisia lausekkeita, niin e + e, e e, e e ja e/e ovat aritmeettisia lausekkeita. 4. Jos e on aritmeettinen lauseke, niin sekä e että (e) ovat aritmeettisia lausekkeita. Yllä esitetyt lauseketyypit voidaan jaotella primäärilausekkeisiin (engl. primary expressions) unaarilausekkeisiin (engl. unary expressions) binäärilausekkeisiin (engl. binary expressions) Primäärilausekkeita ovat sulkulausekkeet (e) sekä muut sellaiset lausekkeet, jotka eivät ala tai pääty (osa)lausekkeella, yleensä ainakin lukuvakiot ja muuttujat lausekkeiksi tulkittuina. Unaarilausekkeet jäsentyvät (yleensä) siten, että niissä on ensin jokin operaattori ja sitten alilauseke (operandi); siispä unaarilausekkeet ovat muotoa e, missä operaattori on ja operandi on e. Myös sellaisia unaarilausekkeita voi esiintyä, joissa operaattori tulee operandin perässä. Binäärilausekkeet alkavat alilausekkeella (vasen operandi), jonka jälkeen tulee operaattori (+,, tai /) ja lopuksi toinen alilauseke (oikea operandi). Tällaista lauseketta, jossa binäärinen operaattori sijaitsee operandiensa välissä, sanotaan infix-lausekkeeksi. Näin tosin ei ole aina aivan

3.1. LAUSEKKEET 33 (unaarinen) / + Taulukko 3.1: Tavanomaisten aritmeettisten operaattoreiden normaali presedenssirelaatio selvää, miten lauseke pitäisi ymmärtää. Esimerkki tällaisesta moniselitteisestä (engl. ambiguous) lausekkeesta on 1 + 2 3: pitääkö se ymmärtää samoin kuin (1 + 2) 3 vai kenties samoin kuin 1 + (2 3)? Jo muinaiset matemaatikot tiesivät tähän ratkaisun: pitää määritellä, mikä on eri operaattoreiden presedenssi (engl. precedence) ja assosiatiivisuus (engl. associativity). Jos tarkasteltavana on lauseke muotoa e e e, missä operaattorilla on korkeampi presedenssi kuin operaattorilla, lausekkeen sovitaan tarkoittavan (e e ) e ; jos taas operaattorilla on matalampi presedenssi kuin operaattorilla, lausekkeen sovitaan tarkoittavan e (e e ). Jos operaattoreilla ja on sama presedenssi, niin lausekkeen tulkinta riippuu niiden assosiatiivisuudesta. Jos molemmat operaattorit assosioituvat vasemmalle (engl. associate to the left), lauseke tulkitaan (e e ) e, ja jos molemmat assosioituvat oikealle (engl. associate to the right), lauseke tulkitaan e (e e ). Jos ne assosioituvat eri suuntaan tai ainakaan toinen ei assosioidu lainkaan, lausekkeen todetaan olevan kielen sääntöjen vastainen. Jos sama operaattori voi esiintyä sekä unaarisena että binäärisenä (esimerkiksi ), tulee sen unaarinen ja binäärinen versio pitää erillään; niillä on yleensä eri presedenssi. Presedenssi- ja assosiointisäännöt vaihtelevat kielestä toiseen. Yleensä on järkevää, että matematiikasta tutut aritmeettiset operaattorit (esimerkiksi yhteen-, vähennys-, kerto- ja vähennyslaskuoperaattorit sekä vastalukuoperaattori) noudattavat matematiikasta tuttua presedenssiä: vastalukuoperaattorilla (unaarinen ) on korkeampi presedenssi kuin kerto- ja jakolaskuoperaattoreilla, joilla puolestaan on korkeampi presedenssi kuin yhteen- ja vähennyslaskuoperaattoreilla. Kerto- ja jakolaskuoperaattoreilla on sama presedenssi, ja samoin yhteen- ja vähennyslaskuoperaattoreilla on sama presedenssi. Kaikki nämä operaattorit assosioituvat vasemmalle paitsi vastalukuoperaattori, joka assosioituu oikealle. Presedenssi muodostaa operaattoreiden välille osittaisjärjestyksen. Tavallisesti kuitenkin presedenssirelaatio on täydellinen järjestys ja se esitetään tavallisesti taulukkona. Mitä korkeampi presendenssi operaattorilla on, sitä korkeammalla se on taulukossa. Edellä esitetyt tavanomaiset presedenssisäännöt on esitetty taulukossa 3.1.

34 LUKU 3. SYNTAKTISIA KYSYMYKSIÄ / + 2 3 6 7 8 Kuva 3.1: Lausekkeen (2 + 3) 6 7/8 rakennepuu Kannattaa huomata, että presedenssi ja assosiatiivisuus eivät määrittele laskujärjestystä vaan jäsennyksen, vaikka toisin usein ajatellaankin. Esimerkiksi lausekkeessa 2 + 3 + 4 5 voidaan laskea ensin 2 + 3, vaikka koulussa opetettiinkin, että kertolasku lasketaan ensin. Vaikka infix-lausekkeet ovatkin kaikista tutuimpia, eivät ne ole ainoat mahdollisuudet. Voidaan esimerkiksi käyttää ns. puolalaisia (engl. Polish) eli prefix-lausekkeita, joissa operaattori tulee aina ensin ja vasta sitten operandit. Tämän esitystavan etu on, että sulkuja tai presedenssi- ja assosiatiivisuussääntöjä ei tarvita, jos operaattorien operandimäärä on kiinteä (eli jos sama operaattori ei ole sekä unaarinen että binäärinen): + 2 3 4 5 tarkoittaa yksiselitteisesti samaa kuin infix-lauseke (2 3) + (4 5). Vastaavasti voidaan käyttää käänteisesti puolalaisia (engl. reverse Polish) eli postfix-lausekkeita, joissa operaattori tulee operandien jälkeen. Tuo sama lauseke olisi postfix-lausekkeena 2 3 4 5 +. Postfix-lausekkeet ovat käytössä Forth- ja Postscript-kielissä. Prefix-lausekkeiden muunnelma, ns. Cambridgen-puolalainen lauseketyyppi, jossa operaattorit tulevat aina operandien edellä mutta lausekkeiden ympärillä on aina sulut, on käytössä Lisp-sukuisissa kielissä. Lausekkeita ei kannata ajatella merkkijonoina vaan puina (rakennepuu, (engl. structural tree) tai abstract syntax tree). Rakennepuissa operaattorit ovat sisäsolmuja ja operandit ovat operaattorinsa alipuita. Puun lehdet muodostuvat muuttujista ja lukuvakioista. Tällöin infix-, prefix- ja postfixesitystavat ovat vain vaihtoehtoisia tapoja kirjoittaa sama lauseke merkkijonoksi. Eräs rakennepuu on kuvattu kuvassa 3.1.

3.2. FORMAALI KIELIOPPI 35 3.2 Formaali kielioppi Ohjelmointikielten konkreetti ja abstrakti kielioppi määritellään yleensä täsmällisesti yhteydettömien kielioppien (context-free grammars) avulla. Abstrakti kielioppi ilmaistaan tavallisesti puhtaasti muunnossäntöinä (rewrite rules, productions): E E + E E E E E E/E L Tässä E ja L ovat välikesymboleja (nonterminal symbols) ja +,, ja / ovat päätesymboleja (terminal symbols). Välikesymboli L edustaa literaalisanasta, jonka rakennetta ei ole tässä kuvattu. Tärkeää tässä on huomata, että tämä kielioppi on moniselitteinen (ambiguous) se ei kelpaisi merkkijonon jäsentämiseen. Siihen se ei ole tarkoitettukaan: tämä kielioppi on abstrakti, se kuvailee nelilaskimen lausekkeiden oleelliset osat, ei kaikkea sitä, jota niiden kirjoittamiseen merkkijonona tarvitaan. Oikeastaan abstrakti kielioppi kuvaa rakennepuita merkkijonoina. Abstraktilla kieliopilla on mukava algebrallinen tulkinta: kukin kieliopin produktio määrittelee abstraktin operaattorin, ja kieliopin määrittelemälle operaattoristolle voidaan sitten määritellä erilaisia tulkintoja määrittelemällä operaattoristolle algebroja. Sattumoisin myös kyseiselle abstraktille kieliopille määritellyt konkreetit kieliopit voidaan tulkita algebroiksi (ns. initiaalialgebrat). Tämän tulkinnan johdosta Gougen ja kumppanit (1977) esittivätkin varsin näppärän, mutta abstraktin, määritelmän abstraktille syntaksille: kielen abstrakti syntaksi on kaikki kielen initiaalialgebrat tulkittuna (isomorfisuuden nojalla) samaksi vekottimeksi. Tämän lähestymistavan tarkempi kuvaus ei kuitenkaan kuulu tämän kurssin ydinsisältöön ja siksi sivuutetaan. Edellä esitetyn abstraktin kieliopin konkreetti kielioppi on yksiselitteinen ja varsin sotkuinen:

36 LUKU 3. SYNTAKTISIA KYSYMYKSIÄ E T E + T E T T F T F T/F F L (E) Edellä käytettyjen merkintöjen lisäksi tässä esiintyy kaksi uutta välikesymbolia (T ja F) seka kaksi uutta päätemerkkiä (aaltosulkeet). Konkreetti kielioppi ilmaistaan yleensä käyttäen John Backusin 1950- ja 1960-lukujen vaihteessa kehittämää merkintätapaa, jonkaa Peter Naur popularisoi Algol 60:n määrittelydokumentissa. Tätä muotoa kutsutaan Backusia ja Nauria kunnioittaen BNF:ksi (Backus Naur form). BNF:llä ilmaistuna ylläoleva kielioppi kirjoitetaan seuraavasti: Expression ::= Term Expression + Term Expression Term Term ::= Factor Term Factor Term / Factor Factor ::= Literal ( Expression ) Varsinaisen BNF:n sijasta usein käytetään jotain sen muunnelmaa. ISO ja IEC standardoivat vuonna 1996 BNF:N laajennetun version eli EBNF:n (ISO/IEC 14977). EBNF laajentaa BNF:ää lisäämällä siihen tuen valinnaisuuden, toiston, ryhmittelyn, määräkertaisen toiston ja poikkeustapausten ilmaisemiseen. EBNF sallii välikesymbolin koostua useammasta sanasta. Lisäksi EBNF sallii kommenttien lisäämisen kieliopin kuvaukseen. Internet-protokollien määrittelyissä käytetty BNF:n muunnelma (Augmented BNF eli ABNF) on myös standardoitu: RFC5234 1 on syntaktisen metakielen Internet-standardi. Konkreetin kieliopin voi ajatella kuvaukseksi, joka kuvaa merkkijonoja (tai sanasjonoja) järjestetyiksi puiksi. Näiden puiden sisäsolmut ovat välikesymboleita ja lehtisolmut päätemerkkejä (sanasia). Tällaisesta ns. jäsennyspuusta (parse tree) voidaan lukea koko merkkijono (sanasjono) käymällä puu läpi järjestyksessä ja merkitsemällä kukin kohdattu lehtisolmu ylös. 1 http://tools.ietf.org/html/rfc5234

3.2. FORMAALI KIELIOPPI 37 Kunkin (epätriviaalin) alipuun juuri (joka on alkuperäisen puun sisäsolmu) kertoo, mitä välikesymbolia kyseinen puu vastaa. Kuvassa 3.2 kuvataan erään aritmeettisen lausekkeen jäsennyspuu edellä annetun konkreetin kieliopin mukaan.

38 LUKU 3. SYNTAKTISIA KYSYMYKSIÄ L F T E E L F T L F T L F F T T E E T L F ( 2 + 3 ) 6 8 / 7 Kuva 3.2: Lausekkeen (2 + 3) 6 7/8 jäsennyspuu sivulla 36 annetun konkreetin kieliopin mukaan

Luku 4 Denotationaalinen semantiikka Ohjelmointikielten syntaksi on osattu määritellä täsmällisesti jo 1950-luvun lopulta alkaen, mutta merkitysopin kanssa on ollut enemmän ongelmia. Yksinkertaisin formaalin merkitysopin menetelmä, denotationaalinen merkitysoppi, on peräisin 1970-luvulta. Denotationaalisessa merkitysopissa kullekin (ohjelmointi)kielen konstrktiolle määritellään matemaattinen otus, jota sanotaan kyseisen konstruktion tarkoitukseksi (engl. denotation). Ajatuksena on antaa kielelle sisältö, joka on riippumaton mistään konkreetista (taikka abstraktista) tietokoneesta. Keskeinen lähtökohta on seuraava ns. kompositionaalisuusvaatimus: Ohjelmointikielen konstruktion tarkoitus saa riippua vain sen osien tarkoituksesta. Denotationaalisen merkitysopin alulle panevana voimana oli toisaalta Christopher Stracheyn ohjelmointikielen periaatteiden pohdinta (Strachey, 2000) sekä toisaalta laskennan teorian alan erään ongelman (lambdalaskennon merkitysoppi) ratkaiseminen. Ratkaisevaa oli Dana Scottin alueteorian (engl. domain theory) kehittyminen. Denotationaalisesta merkityopista ks. tarkemmin esimerkiksi Allison (1986) taikka Reynolds (1998) 4.1 Perusidea Denotationaalista merkitysoppia sovellettaessa on tapana käyttää erityisiä sulkeita (semanttiset sulkeet, semantic brackets) kohdekielen erottamiseen metakielestä. Niitä käytettäessä on hyvä noudattaa seuraavaa kahta nyrkkisääntöä: 1. Semanttisten sulkeiden sisällä oleva ilmaisu on aina kohdekieltä. 39

40 LUKU 4. DENOTATIONAALINEN SEMANTIIKKA 2. Semanttisten sulkeiden sisällä esiintyvä muuttuja on kuitenkin yleensä ns. metamuuttuja (engl. metavariable) ei siis kohdekielen muuttuja, vaan se edustaa jotakin kohdekielen ilmaisua. Näinpä esimerkiksi int v; edustaa C-kielistä kokonaislukumuuttujan v esittelyä (missa v on tuntematon tai kontekstista määrittyvä muuttujan nimi). Määritelläänpä harjoituksen vuoksi yksinkertaisen kielen denotationaalinen merkitysoppi. Tässä kielessä ei ole mitään muuta kuin aritmeettiset lausekkeet, joten abstrakti syntaksi on yksinkertainen: c N e, f, g Expr e, f, g ::= c e e + f e f e f Määrittelyn ensimmäinen rivi kertoo, että nonterminaali c edustaa luonnollisten lukujen kieltä (siis kokonaislukuvakioita). Sen täsmällinen määrittely jätetään avoimeksi, koska se toisaalta oletetaan tunnetuksi ja toisaalta sen täsmällinen määrittely ei olisi mielenkiintoista. Määrittelyn toinen rivi tarkoittaa, että nonterminaalit e, f ja g määrittelevät saman kielen (joukon merkkijonoja taikka joukon rakennepuita taikka... ), ja kielen nimi on Expr. Loput rivit määrittelevät kyseisen kielen abstraktin kieliopin. Tämän kielen denotationaalinen merkitysoppi voitaisiin esittää vaikkapa näin: E : Expr Q E c = c (4.1) E e = E e (4.2) E e + f = E e + E f (4.3) E e f = E e E f (4.4) E e f = E e E f (4.5) Tässä määritellään semanttinen funktio E : Expr Q paloittain ja rekursiivisesti. Semanttisen funktion määritteleminen paloittain ja rekursiivisesti vaatii seuraavien ehtojen täyttymisen:

4.2. MUUTTUJAT 41 1. Määrittelyssä tulee olla täsmälleen yksi yhtälö jokaista abstraktin kieliopin produktiota ja jokaista määriteltävänä olevaa semanttista funktiota kohti. 2. Kussakin yhtälössä on vasemman puolen oltava määriteltävänä olevan semanttisen funktion kutsu, jossa semanttisten sulkeiden sisällä esiintyy kyseisen produktion oikea puoli sellaisenaan (nonterminaaleista tulee näin metamuuttujia 1 ). 3. Kussakin yhtälössä oikealla puolella saadaan kutsua määriteltävänä olevaa semanttista funktiota vain siten, että semanttisten sulkeiden sisällä on jokin vasemmalla puolella esiintyvä (meta)muuttuja. Yllä annettu määritelmä täyttää nämä ehdot. Määritelmää soveltamalla voidaan selvittää lausekkeen (esimerkiksi 2 + 3 + 4) arvo: E 2 + 3 + 4 = E 2 + 3 + E 4 yhtälö (4.3) = E 2 + 3 + 4 yhtälö (4.1) = E 2 + E 3 + 4 yhtälö (4.3) = E 2 + 3 + 4 yhtälö (4.1) = 2 + 3 + 4 yhtälö (4.1) = 9 aritmetiikka 4.2 Muuttujat Tilanne monimutkaistuu hieman, jos kielessä on muuttujia: c N x, y, z Var e, f, g Expr e, f, g ::= c x e e + f e f e f 1 Jos produktion oikealla puolella esiintyy sama nonterminaali useampaan kertaan, erotellaan sen esiintymät toisistaan antamalla niille eri nimet esimerkiksi alaindeksoinnin avulla.

42 LUKU 4. DENOTATIONAALINEN SEMANTIIKKA Tällöin semanttinen funktio ei voi kuvata lausekkeita suoraan arvoiksi, vaan lausekkeiden arvo riippuu muuttujilla lausekkeen ympäristössä olevasta arvoista. Ympäristö voidaan mallittaa yksinkertaisesti osittaisfunktiona muuttujilta arvoille. Ongelmaksi tosin muodostuu se, mitä tehdään, jos ympäristö ei ole määritelty jollekin tietylle muuttujalle, mutta ratkaistaan se tässä nyt hieman fuskaten: sovitaan, että määrittelemättömien muuttujien arvo on 0. Tämän jälkeen määrittely onkin jo helppoa: Env = Var Q E : Expr Env Q E c σ = c (4.6) { 0 jos σ( x ) E x σ = (4.7) σ( x ) muuten E e σ = E e σ (4.8) E e + f σ = E e σ + E f σ (4.9) E e f σ = E e σ E f σ (4.10) E e f σ = E e σ E f σ (4.11) Näissä yhtälöissä on käytetty Gottlob Fregen ja Moses Schönfinkelin pioneroimaa tapaa, jossa funktion paluuarvo on toinen funktio. Tässä ajattelutavassa funktionuoli assosioi oikealle, joten Expr Env Q tarkoittaa samaa kuin Expr (Env Q). Funktion kutsu puolestaan assosioi vasemmalle, joten E c σ tarkoittaa samaa kuin (E c )σ (eli perinteisemmin ilmaistuna E( c )(σ)). Vaikka tämä temppu onkin Fregen ja Schönfinkelin keksimä, siitä käytetään tavallisesti englannin kielen termiä currying idean popularisoijan, Haskell Curryn, mukaan. Lasketaan nyt esimerkin vuoksi lausekkeen x + y + 2 arvo ympäristössä σ = {( x, 1)}: E x + y + 2 σ = E x + y σ + E 2 σ yhtälö (4.9) = E x + y σ + 2 yhtälö (4.6) = E x σ + E y σ + 2 yhtälö (4.9) = E x σ + 0 + 2 yhtälö (4.7), σ( y ) = 1 + 0 + 2 yhtälö (4.7), σ( x ) = 1 = 3 aritmetiikka

4.3. SUORAVIIVAOHJELMAT 43 4.3 Suoraviivaohjelmat Suoraviivaohjelmat koostuvat peräkkäin laitetuista sijoituslauseista sekä siirräntäkäskyistä (jotka tässä vaiheessa vielä jätetään huomiotta). Mitään hyppy-, ehto- tai silmukkarakenteita saatikka aliohjelmakutsuja suoraviivaohjelmissa ei ole. Niinpä voimme määritellä suoraviivaohjelmien abstraktin kieliopin seuraavasti: c N x, y, z Var e, f, g Expr s, t Stmt s, t ::= x e s ; t Lausekkeet on käsitelty edellä, joten niistä ei tässä tarvitse sanoa enempää. Suoraviivaohjelman lauseet eivät palauta arvoja, vaan niillä on sivuvaikutuksia (engl. side-effects). Ainoa sivuvaikutus, joka on tässä tilanteessa mahdollinen, on muuttujan arvon muuttuminen. Kun edellä muuttujien arvo määräytyy ympäristön (Env) perusteella, on lauseen muutettava ympäristöä. Näin ollen lauseen semanttinen tulkinta on kuvaus ympäristöltä ympäristölle: C : Stmt Env Env C x e σ = σ {( x, E e σ)} (4.12) C s ; t σ = C t (C s σ) (4.13) Tässä operaattori määritellään seuraavasti: { (r r r(x) )(x) = r (x) jos r (x) muuten. Lasketaanpa, mikä on muuttujan x arvo ohjelman y 1; x y suori-

44 LUKU 4. DENOTATIONAALINEN SEMANTIIKKA tuksen jälkeen (tyhjässä alkuympäristössä): (C y 1; x y )( x ) = (C x y (C y 1 ))( x ) yhtälö (4.13) = (C x y ( {( y, E 1 )}))( x ) yhtälö (4.12) = (C x y ( {( y, 1)}))( x ) yhtälö (4.6) = (C x y {( y, 1)})( x ) :n määritelmä = ({( y, 1)} {( x, E y {( y, 1)})})( x ) yhtälö (4.12) = {( y, 1), ( x, E y {( y, 1)})}( x ) :n määritelmä = {( y, 1), ( x, 1)}( x ) yhtälö (4.7), = 1 {( y, 1)}(y) = 1 4.4 Paikalliset muuttujat Muuttuja on paikallinen, jos se on näkyvissä vain tietyssä yhtenäisessä osassa ohjelmaa. Paikalliset muuttujat ovat suoraviivaohjelmissa varsin hyödyttömiä, mutta toisaalta niiden mallittaminen denotationaalisesti on selkeintä tehdä näin yksinkertaisessa kielessä. Ensiksi abstrakti kielioppi: c N x, y, z Var e, f, g Expr s, t Stmt s, t ::= x e s ; t { d ; s } d LocalDecl d ::= my x = e d ; d Denotationaalista semantiikkaa kirjoitettaessa hieman sotkua aiheuttaa lausekkeen laskemisessa tarvittavan ympäristön kuljettaminen mukana; tavallisesti, kuten tässä, usean määrittelyn jonossa aiempiin voi viitata myöhemmissä.

4.4. PAIKALLISET MUUTTUJAT 45 C : Stmt Env Env C x e σ = C s ; t σ = C { d ; s } σ = (C s (σ D d σ)) (σ dom D d σ ) (4.14) D : LocalDecl Env Env D my x = e σ = {(x, E e σ)} (4.15) D d 1 ; d 2 σ = (D d 2 (σ (D d 1 σ))) D d 1 σ (4.16)

Liite A Matematiikan kertausta Loogisissa kaavoissa käytetään seuraavia tavanomaisia konnektiiveja ja kvanttoreita: on konjunktio ( ja ) on disjunktio ( tai ) on implikaatio ( jos niin ) on ekvivalenssi ( jos ja vain jos ) x : on universaalikvanttori ( kaikilla x ), x : on eksistentiaalikvanttori ( jollakin x ) Merkintä x S : P on lyhennys merkinnälle x : x S P, ja merkintä x S : P on lyhennys merkinnälle x : x S P. Joukkoihin liittyen käytetään seuraavia tavanomaisia merkintöjä: a S tarkoittaa, että a kuuluu joukkoon S a S tarkoittaa, että a ei kuulu joukkoon S {2, 1, 3, 2} tarkoittaa kolmialkioista joukkoa, jossa on alkioina 1, 2 ja 3 (alkioiden järjestyksellä ei ole merkitystä, kuten ei myöskään sillä, kuinka monta kertaa kukin alkio esiintyy) ja {} tarkoittavat tyhjää joukkoa { E P } tarkoittaa niiden alkioiden E joukkoa, joille pätee väite P (huomaa, että merkinnän kanssa pitää olla varovainen, sillä sillä on mahdollista ilmaista paradokseja) 159

160 LIITE A. MATEMATIIKAN KERTAUSTA { x S P } tarkoittaa samaa kuin { x x S P } Z tarkoittaa kokonaislukujen joukkoa Q tarkoittaa rationaalilukujen joukkoa N tarkoittaa luonnollisten lukujen joukkoa, N = { n Z n 0 } A B on joukkojen A ja B yhdiste, A B = { x x A x B } A B on joukkojen A ja B leikkaus, A B = { x x A x B } A \ B on joukkojen A ja B erotus, A \ B = { x x A x B } A B tarkoittaa, että A on B:n osajoukko, A B ( x A : x B) P(S) on joukon S osajoukkojen joukko, P(S) = { x x S } A B on joukkojen A ja B karteesinen tulo, A B = { (a, b) a A b B } Relaatioihin (karteesisten tulojen osajoukkoihin) ja funktioihin liittyen käytetään seuraavia (osittain tavanomaisia) merkintöjä: a r b tarkoittaa samaa kuin (a, b) r dom r on relaation r lähtöjoukko (engl. domain) dom r = { a b : (a, b) r } ran r on relaation r maalijoukko (engl. range) ran r = { b a : (a, b) r } r S on relaation rajoittuma, r S = { (x, y) r x S } f : A B tarkoittaa, että f on osittaisfunktio A:sta B:hen eli että f A B on relaatio, jolla on funktio-ominaisuus: a A : b, b B : (a, b) f (a, b ) f b = b f : A B tarkoittaa, että f on (täydellinen) funktio A:sta B:hen eli että se on osittaisfunktio A:sta B:hen ja A = dom f pätee

161 f (x) tarkoittaa sitä y:tä, jolle pätee (x, y) f (sallittu merkintä vain, jos kyseinen y on olemassa ja yksikäsitteinen) f (x) tarkoittaa, että x dom f (eli f (x) ei ole määritelty) Sanat funktio ja kuvaus ilman tarkentavia lisämääritteitä tarkoittavat tavallisesti täydellistä funktiota. Relaatio r S S on refleksiivinen, jos a S : (a, a) r pätee symmetrinen, jos a, b S : (a, b) r (b, a) r pätee antisymmetrinen, jos a, b S : (a, b) r (b, a) r a = b pätee transitiivinen, jos a, b, c S : (a, b) r (b, c) r (a, c) r pätee ekvivalenssi, jos se on symmetrinen, refleksiivinen ja transitiivinen osittaisjärjestys, jos se on antisymmetrinen, refleksiivinen ja transitiivinen täydellinen järjestys, jos se on osittaisjärjestys ja a, b S : (a, b) r (b, a) r pätee Relaation X-nen sulkeuma (engl. closure) on pienin relaatio, jolla on ominaisuus X ja jonka osajoukko kyseinen relaatio on. Tällaisia ovat esimerkiksi refleksiivinen sulkeuma, transitiivinen sulkeuma ja refleksiivis-transitiivinen sulkeuma.