815338A Ohjelmointikielten periaatteet 2015-2016 III Ohjelmointikielten syntaksi ja semantiikka
Sisältö 1. Syntaksi ja semantiikan käsitteet 2. BNF-kielioppi 3. Syntaksikaaviot 4. Jäsentäjät 5. Semantiikka 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 2
III.1 Syntaksin ja semantiikan käsitteet Ohjelmointikieltä määriteltäessä tarvitaan kuvaus kielestä Täsmällinen Helposti ymmärrettävä Kuvattava kielen rakenne Kuvattava kielen konstruktioiden merkitys Syntaksi (syntax): kielen rakenne Määrittelee kielen lailliset ilmaukset Semantiikka (semantics): merkitysoppi Määrittelee kielen ilmauksien merkityksen 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 3
III.1 Syntaksin ja semantiikan käsitteet (2) Esimerkki: C-kielen if lauseen syntaksi: if(<expression>) <statement> *x++=*y++ Semantiikka: Jos lausekkeen <expression> arvo ei ole nolla, niin lause <statement> suoritetaan, muuten ei suoriteta Ohjelmointikielen kielioppi (grammar) = syntaksin formaali määritelmä Esittämiseen yleisesti kontekstista riippumaton (context-free, kontekstivapaa, yhteysriippumaton jne) kielioppi Semantiikalle ei yleistä formaalia esitystapaa 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 4
III.2. BNF-kielioppi Tunnetuin formaali kielioppi BNF = Backus-Naur Form Vuonna 1960 kuvaamaan ALGOL-kielen syntaksia 1959 kieliteoreetikko Noam Chomsky: kontekstista riippumaton kielioppi Kuvaa kielen, jonka määrittelyt eivät riipu yhteydestä, missä ne esitetään Ekvivalentti BNF:n kanssa -> BNF-kielioppia ja kontekstista riippumatonta kielioppia käytetään synonyymeinä 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 5
III.2. BNF-kielioppi (2) Muodostetaan äärellisestä joukosta kielioppisääntöjä, jotka yhdessä määrittelevät (formaalin) kielen. Tässä kuvataan ohjelmointikieliä Syntaktisesti kuvataan muodollisesti oikeita ohjelmia, semanttisesti voivat olla mielettömiä 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 6
III.2.1. Kielen määritelmä Kieli on joukko äärellisen pituisia, jonkin aakkoston sanoja (merkkijonoja) Aakkosto on kiinnitettävä etukäteen Saadaan muodostaa ainoastaan äärellisen mittaisia sanoja Mikä tahansa ohjelmointikieli on kieli, aakkostona yleensä ASCII- tai UNICODE-merkistö, sanoja lailliset ohjelmat 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 7
II.2.2. Kielen perusosat Pienimmät perusosat: lekseemit (tekstialkiot, leksikaaliset sanat, lexemes) Jätetään usein pois kielen formaalista kuvauksesta Tavallisesti luetellaan sanakirjamaisesti erillään syntaktisesta kuvauksesta Ohjelmointikielen lekseemit: 1.Tunnisteet (identifiers), 2.Literaalit (literals), 3.Operaattorit (operators) 4.Erikoissanat (special words, key words) 5.Erikoissymbolit (special symbols) Varatut sanat erikoissanojen erikoistapaus 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 8
III.2.3 Kielen kuvaus ja jäsentäminen Lekseemien kategoriat = alkionimet (sanaset, tokens) Kielen leksikaalinen rakenne läheisesti sidoksissa syntaktisen rakenteeseen Syntaksin tarkistus yleensä 1. Selausvaiheessa (scanning phase) kerätään lekseemit 2. Jäsennysvaiheessa (parsing) tarkistetaan varsinainen syntaktinen rakenne 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 9
III.2.3 Kielen kuvaus ja jäsentäminen (2) Esimerkki: C-kielen lause if( luku < 0) luku++; lekseemi if alkionimi erikoissana ( erikoissymboli luku tunniste < erikoissymboli 0 literaali ) erikoissymboli + operaattori ; erikoissymboli 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 10
III.2.3 Kielen kuvaus ja jäsentäminen (3) Kielen kuvauksessa tarvitaan metakieli Kuvaa kohdekieltä Erotettava metakielen ja kuvattavan kielen symbolit toisistaan BNF-kielioppi koostuu joukosta kielioppisääntöjä, joissa Vasemmalla puolella esiintyy ainoastaan määriteltävän rakenteen nimi, vasemman ja oikean puolen erotinmerkkinä toimii symboli ::= Oikealla puolella voi esiintyä symboleita ja rakenteen nimiä 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 11
III.2.3 Kielen kuvaus ja jäsentäminen (4) Rakenteiden nimet esitetään kulmasulkeiden sisällä (<rakenne>) Välisymboleita (nonterminaaleja), koska ne hajaantuvat edelleen pienempiin osiin. Lekseemit loppusymboleita (terminaaleja) Eivät hajaannu pienempiin osiin. Kielioppisääntöjä sanotaan myös produktioiksi Tuottavat kieleen kuuluvat merkkijonot johtamalla ne säännöistä 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 12
III.2.3 Kielen kuvaus ja jäsentäminen (5) Puhtaassa BNF:ssä ainoastaan seuraavat metasymbolit: < > ::= Kolme ylintä kuvattu aiemmin Symboli ilmaisee vaihtoehtoa: Symbolilla erotettuja termejä voidaan vaihtoehtoisesti käyttää johdossa 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 13
III.2.3 Kielen kuvaus ja jäsentäminen (6) Rakenteiden määrittelyssä rekursio sallittu Rakenne voi esiintyä sekä säännön oikealla että vasemmalla puolella Esimerkki <luku> ::= <luku><numero> <numero> <numero> ::= 0 1 2 3 4 5 6 7 8 9 Määrittelee kymmenjärjestelmän etumerkittömät luvut Huomaa kuitenkin: esimerkiksi 00056 voidaan johtaa 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 14
III.2.3 Kielen kuvaus ja jäsentäminen (6) Laajennettu BNF (extended BNF, EBNF), lisätty metasymbolit [ ] { } [ ] sulkujen sisäisen lausekkeen vapaaehtoinen valinta {} sulkujen sisällä olevan lausekkeen esiintyminen 0 tai useampi kertaa 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 15
III.2.3 Kielen kuvaus ja jäsentäminen (7) Esimerkkejä EBNF:stä Määrittelyssä <sana> ::= x[y] sana voi olla x tai xy. Määrittelyssä <sana> ::= x{y} sana voi olla x, xy, xyy, xyyy, jne Lisäksi EBNF:ssä Käytetään sulkuja ryhmittelyyn Voidaan käyttää muita metasymboleita 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 16
III.2.3 Kielen kuvaus ja jäsentäminen (8) Esimerkki. C-kielen if-lause EBNF:llä: <if_stmt> ::= if(<expr>) <stmt>[else <stmt>]; Esimerkki sulkujen käytöstä metakielessä, Pascalin for lause: <for_stmt> ::= for <var> := <expr> (to downto) <expr> do <stmt>; Voidaan siis valita joko to tai downto lauseeseen 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 17
III.2.4. Lauseiden johtaminen Kielen kaikki syntaktisesti oikeat lauseet voidaan johtaa kielioppisäännöistä Lähdetään liikkeelle jostakin kieliopin säännöstä ja korvataan välisymboleja joillakin määrittelyillään BNF-kieliopissa kaikki vaihtoehtoiset määrittelyt sallitaan kaikissa yhteyksissä 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 18
III.2.4. Lauseiden johtaminen. Esimerkki Olkoon jossakin ohjelmointikielessä sijoituslause yhteenja kertolaskua sisältäville aritmeettisille operaatioille määritelty seuraavasti: <assign> ::= <id> = <expr> <id> ::= X Y Z <expr> ::= <id> + <expr> <id> * <expr> (<expr>) <id> Johda lause X = X * (Y+Z) 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 19
III.2.4. Lauseiden johtaminen. Esimerkki (2) Ratkaisu: <assign> -> <id> = <expr> -> X = <expr> -> X = <id>*<expr> -> X = X*<expr> -> X = X*(<expr>) -> X = X*(<id> + <expr>) -> X = X*(Y + <expr>) -> X = X*(Y + <id>) -> X = X*(Y + Z) *x++=*y++ <assign> ::= <id> = <expr> <id> ::= X Y Z <expr> ::= <id> + <expr> <id> * <expr> (<expr>) <id> Johda X = X*(Y + Z) 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 20
III.2.4. Lauseiden johtaminen. Esimerkki (3) *x++=*y++ Voidaan esittää graafisesti johtopuuna (parse tree) 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 21
III.2.5. Monikäsitteinen kielioppi Englanniksi ambiguous grammar Samalla lauseella useita erilaisia johtopuita HUOM! Vaikka kielioppi ei monikäsitteinen, lauseella yleensä useita johtoja, näitä kuitenkin vastaa sama johtopuu 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 22
III.2.5. Monikäsitteinen kielioppi. Esimerkki Muutetaan edellisen sijoituslauseen kielioppia: <assign> ::= <id> = <expr> <id> ::= X Y Z <expr> ::= <id> + <expr> <expr> * <expr> (<expr>) <id> *x++=*y++ Lauseella X = X + Y*Z kaksi johtopuuta -> saatiin monikäsitteinen kielioppi 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 23
III.2.5. Monikäsitteinen kielioppi. Haitat Kääntäjät pohjaavat yleensä semanttisen tulkinnan syntaktiseen muotoon -> monikäsitteisyys ongelmallista Edellisessä esimerkissä kielioppi ei kerro, suoritetaanko laskutoimitus X + Y*Z muodossa (X+Y)*Z vai X+(Y*Z) Jälkimmäinen tavallisten aritmeettisten sääntöjen nojalla oikein 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 24
III.3. Syntaksikaaviot BNF:n ja EBNF:n säännöt voidaan esittää graafisessa muodossa syntaksikaaviolla (syntax graph, syntax diagram, ratapihakaavio) Suunnattua polku, jossa loppusymbolit ja välisymbolit solmuja Loppusymbolit ovaaleihin ja välisymbolit suorakaiteisiin: Terminaali Nonterminaali 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 25
III.3. Syntaksikaaviot (2) Vaihtoehtoinen toiminto kirjoittamalla vaihtoehdot rinnakkain Esimerkiksi säännöt X1 X2 ja {YN} kirjoitetaan X1 X1 YN 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 26
III.3.1 Esimerkki. Pascalin case-lause Esimerkki Pascalin case lauseesta: CASE m OF 1,2: k:=2*m+1; 3,6: k:=3*m+1; 4: k:=4*m+1; 5,7,8: k:=2*m-1; END; 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 27
III.3.1 Esimerkki. Pascalin case-lause (2) BNF muodossa: <case_stmt> ::= CASE <expression> OF <case_list> [;] END <case_list> ::= {<const_list>: <stmt>;}<const_list>: <stmt> <const_list> ::= <const> {, <const>} 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 28
III.3.1 Esimerkki. Pascalin case-lause (3) *x++=*y++ Syntaksikaaviona: <case_stmt> ::= CASE <expression> OF <case_list> [;] END <case_list> ::= {<const_list>: <stmt>;}<const_list>: <stmt> <const_list> ::= <const> {, <const>} CASE expression OF const : stmt END, ; ; 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 29
III.3.1 Esimerkki. Pascalin case-lause (4) Huomaa kolme välisymbolia, joille tulisi myös antaa säännöt Graafisen esityksen etu: syntaksidiagrammia voidaan käyttää varsin suoraviivaisesti kirjoitettaessa jäsentäjä (parser, syntax analyzer) kieliopille 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 30
III.4. Jäsentäjät Ohjelmointikieli käännettävä, tulkattava tai hybridi Käännettävä kieli: kääntäjän (compiler) avulla konekielinen ohjelma, joka suoritetaan Tulkattava kieli: ohjelman ajaa erillinen tulkki (interpreter) suoraan koodista Hybridi: kääntäjä muodostaa ohjelmasta välimuodon, joka tulkataan Java on hybridikieli: alkuperäinen ohjelma käännetään tavukoodiksi, jonka JVM suorittaa 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 31
III.4. Jäsentäjät (2) Käännettävät kielet tarvitsevat jäsentäjän osana kääntäjää Jäsentäjän tehtävä: konstruoida syötteenä saamalleen ohjelmalle jäsennyspuu Yksinkertaisimmillaan vain syntaksin tarkastaja 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 32
III.4.1 Leksikaalinen analyysi Lähes aina kääntäjä jakaa syntaksianalyysin leksikaaliseen analyysiin ja varsinaiseen jäsentämiseen Leksikaalinen analyysi jäsentämisen esioperaatio Leksikaalinen analysoija pääasiassa hahmontunnistaja: poimii ohjelmasta lekseemit ja tunnistaa niiden tyypin Leksikaalista analyysiä ei käsitellä tarkemmin Periaatteessa melko yksinkertainen hahmontunnistus 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 33
III.4.2 Jäsentäjätyypit Tyypistä riippumatta jäsentäjät yleensä tutkivat vain yhden lekseemin kerrallaan eteenpäin Jäsentäjien kaksi pääluokkaa jäsennyspuun rakentamistavan mukaan : 1. Osittavat (ylätasolta lähtevät) jäsentäjät (topdown parsers) 2. Kokoavat (alatasolta lähtevät) jäsentäjät (bottom-up parsers) 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 34
III.4.2.1 Osittavat jäsentäjät *x++=*y++ Etenevät puun juuresta lehtiin päin Päättelevät merkkijonon vasemmasta päästä lähtien, onko tutkittava lauseke loppu- vai välisymboli Redusoivat välisymbolit sovittaen ne sopivan kielioppisäännön vasemmaksi puoleksi Sanotaan LL-jäsennykseksi: syötettä luetaan vasemmalta oikealle ja tuotetaan vasen johto 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 35
III.4.2.2 Kokoavat jäsentäjät Rakentavat jäsennyspuun lehdistä juureen Sovittavat käsiteltävän merkkijonon loppuosan jonkin kielioppisäännön oikeaan puoleen; tämä redusoidaan kyseisen säännön vasemmaksi puoleksi. Sanotaan LR-jäsennykseksi Ks. tarkemmin Sebestan luku 4.5 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 36
III.4.3 Rekursiivisesti etenevä jäsennysalgoritmi Recursive-descent parser Luonnollisin (top-down) jäsentäjä (E)BNF:n tai vastaavan syntaksikaavion avulla esitetylle kieliopille Jäsentäjässä kokoelma (yleensä rekursiivisia) funktioita, jotka tuottavat jäsennyspuun ylhäältä lähtien Tarvitaan: 1. leksikaalinen analysoija ja 2. jokaista kieliopin välisymbolia kohti oma funktio, joka käsittelee kyseisen välisymbolin 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 37
III.4.3 Rekursiivisesti etenevä jäsennysalgoritmi Varsin tehokas Rajoitus: kielioppisäännöt eivät saa sisältää vasemmanpuoleista rekursiota. Esimerkki: Säännön <expr> ::= <expr> + <term> <term> ::= muuntaminen jäsentäjäksi johtaisi seuraavaan ohjelmaan 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 38
PROGRAM_EXPR String sym; GetToken(); expr(); expr(){ expr(); GetToken(); if( sym == + ){ GetToken(); term(); } else{ error(); } } term(){ // Parse term } END PROGRAM_EXPR /* Ohjelma säännön <expr> ::= <expr> + <term> <term> ::= jäsentämiseksi */ 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 39
III.4.3 Rekursiivisesti etenevä jäsennysalgoritmi Oletettu, että käytössä leksikaalinen analysoija GetToken() Hakee lekseemin merkkijonoon sym Ohjelmassa kuitenkin päättymätön rekursio! Kielioppia muutettava, jos halutaan rakentaa rekursiivisesti laskeutuva jäsentäjä 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 40
III.5 Semantiikka Voidaan jakaa staattiseen ja dynaamiseen semantiikkaan Ainoastaan dynaaminen semantiikka varsinaista semantiikkaa eli ohjelmointikielen merkitysoppia Staattisen semantiikan ongelmat liittyvät ohjelmien sallittuun muotoon Muotoseikat, joita vaikea tai mahdoton kuvata BNF:llä Esimerkiksi vaatimus, että muuttuja on määriteltävä ennen arvon sijoittamista Nimitys siitä, että vaatimukset voidaan tarkistaa jo käännöksen aikana 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 41
III.5 Semantiikka (2) Ei ole yleisesti hyväksyttyä formaalia järjestelmää kuvaamaan ohjelmien merkitysoppia Yleensä konstruktioiden merkityksen kuvaaminen tapahtuu luonnollista kieltä käyttämällä 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 42
III.5.1. Dynaamisen semantiikan tyypit 1. Operationaalinen semantiikka 2. Aksiomaattinen semantiikka 3. Denotationaalinen semantiikka 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 43
III.5.1.1 Operationaalinen semantiikka Pyrkii kuvaamaan annetun ohjelman merkityksen suorittamalla ohjelman joko reaalisessa tai virtuaalisessa tietokoneessa; koneen tilat ohjelman suorituksen aikana määrittelevät tällöin ohjelman merkityksen Formaalia operationaalista semantiikkaa käytettiin ohjelmointikielen PL/I merkitysopin kuvaamiseen Pohjautuu algoritmeihin Voi olla hyödyllinen tapa kuvata merkitysoppi kielen käyttäjille ja toteuttajille 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 44
III.5.1.2 Aksiomaattinen semantiikka *x++=*y++ Käytetään todistamaan ohjelmien korrektisuutta Pohjautuu matemaattiseen logiikkaan Voi olla hyödyksi kun on todistettava aukottomasti ohjelman korrektius 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 45
III.5.1.3 Denotationaalinen semantiikka Perustuu rekursiivisten funktioiden teoriaan Yleisesti katsotaan, että kuvaa käytettävistä menetelmistä tarkimmin ohjelmien merkitysopin Lähes mikä tahansa ohjelmointikielen piirre voidaan kuvata matemaattisen funktion avulla. Voidaan käyttää hyödyksi ohjelmointikielten suunnittelussa Ks. Tarkemmin Sebesta luku 3.5 815338A Ohjelmointikielten periaatteet, Syntaksi ja semantiikka 46