Tietokoneen käytön ja ohjelmoinnin alkeet

Kurssin kotisivulle


5 Merkinnöistä

Tietokoneelle annettavat käyttöjärjestelmän komennot ja ohjelmointikielten lauseet eivät voi olla mitä tahansa, vaan niillä on oma kielioppinsa. Syntaksi määrittelee, millaiset komennot ja lauseet ovat muodollisesti kelvollisia. Niitä käsittelee komentotulkki, ohjelmointikielen kääntäjä tai jokin muu ohjelma. Jotta tuo ohjelma olisi toteutettavissa äärellisellä työllä, sille syötettävän kielen on noudatettava hyvin täsmällistä syntaksia.

Monet oppaat alkavatkin esittelemällä merkintätavat, joita käytetään syntaksin esittämiseen. Niissä on pieniä eroja, mutta yleensä ne perustuvat 1960-luvulta peräisin olevaan Backuksen ja Naurin esittämään formalismiin.

Tarkastellaan yksinkertaisena esimerkkinä kokonaislukujen kuvaamista tällä BN-merkintätavalla.

Kokonaisluvun perusosasia ovat numerot 0, ..., 9. BN-formalismilla ilmaistuna tämä on


      < numero > ::=  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 

Kulmasuluissa oleva symboli < numero > on metasymboli. Se on muuttuja, joka voi saada arvokseen erilaisia merkkijonoja, mutta lopullisessa ohjelmassa se ei enää esiinny.

Operaattori ::= on produktio. Se ilmoittaa, että vasemmalla puolella oleva metasymboli korvataan oikea puolen merkkijonolla eli metasymboli produsoi oikean puolen merkkijonon.

Koska metasymboleita ei saa jäädä lopulliseen tekstiin, jokaisen metasymbolin täytyy esiintyä operaattorin ::= vasemmalla puolella.

Operaattorin ::= oikealla puolella voi olla eri vaihtoehtoja, jotka erotetaan merkillä |. Edellä < numero > voi siis saada jonkin arvoista 0 tai 1 tai ... tai 9. Edellä kaikki produktion oikealla puolella olevat symbolit ovat terminaalisymboleita. Ne ovat vakioita, jotka esiintyvät lopullisessa merkkijonossa sellaisinaan. Niitä ei voida enää korvat muilla merkkijonoilla, joten ne eivät esiinny produktio-operaattorin vasemmalla puolella.

Nyt sitten näistä numeroista pitäisi koota kokonaisluku, jossa voi olla yksi tai useampia numeroita


     < luku > ::= < numero > | < luku > < numero >

Tämä on rekursiivinen määritelmä, jossa sama metasymboli esiintyy produktion kummallakin puolella. Ensimmäinen vaihtoehto on, että < luku > produsoi < numero >n ja < numero > edelleen jonkin numeroista 0, ..., 9, jolloin homma päättyy. Toinen mahdollisuus on, että produktio tuottaa merkkijonon < luku >< numero >. Jälkiosasta produsoituu taas jokin terminaalisymboli, mutta alkuosaan sovelletaan uudelleen samaa produktiosääntöä. Siitä voi taas seurata joko yksi numeromerkki tai < luku >, jota seuraa numero. Toistamalla sääntöä yhä uudestaan voidaan tuottaa mielivaltaisen pitkiä kokonaislukuja. Jokainen säännön soveltaminen lisää luvun perään yhden numeron.

Lopuksi luvun eteen voidaan vielä liittää etumerkki, mutta se ei ole pakollinen:


      < kokonaisluku > ::= [ + | - ] < luku >

Hakasuluissa [] olevat osat voidaan jättää pois. Seäännön mukaan kokonaisluku on < luku >, jota edeltää joko plus- tai miinusmerkki tai ei mitään.

Yhteenvetona saamme seuraavan kieliopin kokonaisluvuille:


      < kokonaisluku > ::= [ + | - ] < luku >
      < luku > ::= < numero > | < luku > < numero >
      < numero > ::=  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 

Toinen sääntö voidaan esittää myös muodoissa

      < luku > ::= < numero > +

tai

      < luku > := < numero >< numero > *

Nämä tarkoittavat, että luku on yksi tai useampia peräkkäin asetettuja numeroita. Asteriski (*) on iteraation eli toiston merkki ja tarkoittaa, että kyseistä oliota toistetaan mielivaltaisen monta kertaa tai ei kertaakaan. Plusmerkki (+) puolestaan tarkoittaa, että olio esiintyy ainakin yhden kerran. Kumpikin edellä esitetyistä määritelmästä sanoo siis, että luvussa on yksi tai useampia numeroita.

Käyttöjärjestelmän yhden komennon kuvaamiseen riittää tavallisesti yksi ainoa sääntö. Ohjelmointikielen syntaksin esittämiseen sen sijaan tarvitaan suuri määrä sääntöjä. Ne voisivat alkaa vaikka seuraavalla tavalla

      < program > ::= program < definitions >  
                            < statements > 
                    end program
      < definitions > ::= < definition > ; | 
                        < definition > ; < definitions >
      < statements > ::= < statement > ; | 
                       < statement > ; < statements >

Tätä luetaan niin, että ohjelma alkaa sanalla program. Sitä seuraa joukko määrittelyjä, joista kukin päättyy puolipisteeseen (;). Määrittelyjä seuraa sitten lauseita, jotka nekin päättyvät puolipisteeseen. Tämän jälkeen kieliopissa täytyy sitten seurata sääntöjä, joilla määritellään tarkemmin, millaisia määrittelyt ja lauseet ovat.

Kun ohjelmointikielellä on tällainen kielioppi, sille on suhteellisen helppoa kirjoittaa kääntäjä, joka tarkistaa, että syötetty ohjelma on kieliopian mukainan ja tuottaa sitä vastaavan suoritettavan ohjelman (luku 4).

Kieliä voidaan luokitella sen perusteella, millaisia produktioita niiden kieliopin esittämiseen tarvitaan. Tätä aihetta tutkitaan formaalien kielten teoriassa ja kääntäjäteoriassa, mutta tässä emme mene asiaan sen syvemmälle.