400 likes | 651 Views
5. Systeemiohjelmisto. Jotta tietokoneesta saadaan käyttökelpoinen, tulee ratkaista seuraavat ongelmat: Miten ohjelma tallennetaan tietokoneen muistiin? Miten ohjelma saa tarvitsemansa syöttötiedot ja miten se antaa tulokset ? Miten ohjelmointi voitaisiin tehdä helpommaksi?
E N D
5. Systeemiohjelmisto Jotta tietokoneesta saadaan käyttökelpoinen, tulee ratkaista seuraavat ongelmat: • Miten ohjelma tallennetaan tietokoneen muistiin? • Miten ohjelma saa tarvitsemansa syöttötiedot ja miten se antaa tulokset ? • Miten ohjelmointi voitaisiin tehdä helpommaksi? • On tuhlaavaista varata kone kerrallaan vain yhden ohjelman suoritusta varten. • Miten koneen toimintaa hallitaan, jos suoritettavana on useampia ohjelmia?
Systeemiohjelmisto ... Em. ongelmat ratkaisevat SYSTEEMIOHJELMAT (system programs, system software), jotka helpottavat laitteiden käyttöä. Koneen räätälöinti palvelemaan eri elämänalojen tehtäviä edellyttää SOVELLUSOHJELMIA.
Systeemiohjelmia ovat: • Kääntäjät (compilers) ja tulkit (translators): korkean tason ohjelmointi-kielillä kirjoitettujen ohjelmien muuntaminen konekielisiksi tai tulkitsemalla suoraan. • korkean tason kielen ohjelma käännetään konekielelle • konekieltä suoritetaan mikrotulkin avulla • Käyttöjärjestelmät (operating systems): • tiedonsiirron hallinta tietokonelaitteiston eri osien välillä (s/t ja ulkoiset muistilaitteet) (monen laitteen samanaikainen hallinta) • ohjelmien suorituksen ohjaus (monen ohjelman samanaikainen hallinta) • tietokoneen resurssien jako käyttäjille (monen käyttäjän samanaikainen hallinta) • tietojen pitkäaikaissäilytyksestä huolehtiminen (toissijaismuistin ylläpito)
Systeemiohjelmia ovat: • Linkittäjät (linkers): • kokoavat erillään käännetyt ohjelmamoduulit ja niiden käyttämät apuohjelmat yhdeksi suorituskelpoiseksi kokonaisuudeksi. • ajettavat tiedostot, esim. SimO.exe • ajettavat tiedostot talletetaan oheismuistiin • Lataajat (loaders): • siirtävät ohjelmia toissijaisesta muistista (esim. kiintolevyltä) keskusmuistiin. • Editorit (editors): • tietokoneeseen tallennetun tekstin/kuvan muokkaus • Tietoliikenneohjelmistot (communications software): • vastaavat kommunikoinnista toisten tietokoneiden kanssa • mm. takaavat tiedon virhettömän ja nopean siirron havaitsemalla virheitä ja löytämällä parhaan reitin tiedolle, mikäli vastaanottaja ja lähettäjä eivät ole suorassa yhteydessä toisiinsa
Käyttäjienlaatimatohjelmat Ohjelmistojen luokittelu
5.1. Ohjelmointikielten kääntäminen Tietokone ymmärtää suoraan: • mikrokäskyjä • mikrotulkilla tulkittuja konekielen käskyjä mutta korkean tason kielellä kirjoitetut ohjelmat on käännettävä koneen ymmärtämään muotoon. Kääntämisellä tarkoitetaan korkean tason ohjelmointikielellä kirjoitetun ohjelman kääntämistä koneen ymmärtämään muotoon eli konekieliseksi ohjelmaksi. Se voidaan sitten suorittaa mikrotulkin välityksellä
5.1. Ohjelmointikielten kääntäminen Jokainen kt-kielen käsky käännetään yhdeksi tai useammaksi konekielen käskyksi. Esimerkki: kt-kieli konekieli a:= x+y LOAD 10 ADD 11 STORE 12 keskusmuisti: 10: x:n arvo 11: y:n arvo 12: a:n arvo
x[0] x[9] 5.1. Ohjelmointikielten kääntäminen... • Tietorakenteet esitetään konekielissä bitteinä, numeroina ja muistiosoitteina. • Monimutkaisimmat tietorakenteet esitetään muistialueina. • esim. vektori X[10], jonka jokainen kokonaislukualkio on tallennettu 16 bitin avulla, vie 20 8-bittistä muistipaikkaa: 456 1001 1011 457 0110 0111 … 475 1100 1111 476 0000 1010
Korkean tason kielisen ohjelman muuntaminen konekielelle: • Tulkitseminen tai • Kääntäminen
5.1.1 Tulkitseminen... Tulkitseva suoritus: Korkean tason ohjelma Tulkki on • konekielellä kirjoitettu ohjelma • lukee ja suorittaa kt-ohjelmaa lause kerrallaan • selvittää • lauseen tyypin (esim. asetuslause), • sen oikeellisuuden • operandit • suorittaa lauseen vaatimat toimenpiteet. Tulkissa on valmiina toteutukset jokaista lähdekielen lausetyyppiä varten, ja se osaa haarautua kulloisenkin lauseen mukaisesti oikeaan kohtaan (vrt. mikrotulkki). Syöttö-tiedot Korkean tason tulkki Tulokset
Tulkit kirjoitetaan konekielellä eikä mikrokielellä, koska • konekieli on lähempänä kt-kieltä kuin mikrokieli • ROM-muisti on kallista, eikä tulkkia voisi heposti muuttaa • 2-vaiheinen tulkkaus on parempi: • 1: luetaan kt-kielen lauseita ja suoritetetaan haettua toimintoa vastaavat konekieliset käskyt (jotka ovat osaa kt-tulkkia) • 2: konekieliset käskyt tulkataan mikrotulkille
Kääntävä suoritus: Korkean tason ohjelma Kääntäjä Konekielinen ohjelma Syöttö-tiedot Tulokset Mikrotulkki 5.1.2 Kääntäminen • Lähdekielinen ohjelma (source program) käännetään ensin konekielelle objektiohjelmaksi (object program) kääntäjän toimesta. • Objektiohjelma yhdistetään muihin tiedostoihin (esim. funktiokirjastot) linkittäjän avulla • syntyy suoritettava tiedosto, latausmoduuli • Latausmoduuli talletetaan oheismuistiin • Latausmoduulin voi ladata keskusmuistiin lataajalla ja suorittaa mikrotulkilla
5.2 Syntaksin määrittely • Ohjelma (tietokoneen mielestä): jono merkkejä, esimerkiksi MODULE kertoma(n) RETURNS n-kertoma k:=1 WHILE n > 1 DO k:=k*n n:=n-1 ENDWHILE RETURN k ENDMODULE • Kielen syntaksi • säännöt, jotka kertovat, minkälaiset merkkijonot ovat oikein muodostettuja ohjelmia • toisin sanoen, syntaksin avulla määritellään merkkien mahdolliset järjestykset • esim. varatun sanan MODULE jälkeen tulee moduulin nimi, jota _mahdollisesti_ seuraa parametrit suluissa • kaikki tälläiset lailliset vaihtoehdot on kuvattu syntaksisäännöissä
5.2.1 Kieliopit • Syntaksin määrittelyyn käytetään siis kielioppia (grammar). Sen säännöt määräävät, mitä kielen symboleja saa käyttää. • Ohjelmointikielten kieliopeilla on sama tarkoitus kuin luonnollisten kielten kieliopeilla, mutta ne ovat • täsmällisempiä ja • yksinkertaisempia. • Kielioppi määrittelee, mitkä kirjoitelmat ovat oikein muodostettuja ohjelmia, ja mitkä eivät • sanotaan, että ko. kieliopilla ko. ohjelma voidaan generoida (tuottaa) • Termi generointi tarkoittaa sitä, että ohjelma muodostetaan eli johdetaan kielioppisääntöjä käyttäen.
5.2.1 Kieliopit... • ohjelmointikielten syntaksin määrää kontekstitonkielioppi • yhteysvapaa kielioppi (context-free grammar), • BNF- eli Backus-Naur Form-kielioppi • tietyn erillisen merkkijonon merkitys ei riipu sen ympäristöstä • esim. IF-varattu sanaa aina tarkoittaa valintalauseen alkamiskohtaa • := on asetuslause, = on vertailulause (nämä ovat välilyönneillä erotettuja eri merkkijonoja!)
Kontekstittoman kieliopin osat: Päätesymbolit eli terminaalit • varatut sanat ja muut merkkijonot (muuttujien tunnukset, vakiot yms) • esiintyvät ohjelmassa sellaisenaan • esim. IF, 1, =, :=, jne. • yhdessä muodostavat syntaksiluokat, kuten <asetuslause>, <moduuli> Välisymbolit eli nonterminaalit: • nimeävät syntaksiluokan, esim. asetuslauseen: <asetuslause> • eivät esiinny ohjelmakoodissa sellaisenaan, vaan niitä käytetään apuna tunnistettaessa merkkijonojen ryhmiä syntaksiluoksiksi, esim. kun ”IF A>1 THEN…ENDIF”:iä tunnistetaan <ehtolause>:ksi Produktio (johto-)säännöt: • määräävät syntaksiluokan sisällön/rakenteen, esim: <asetuslause> → <tunnus> := <lauseke> • yleinen muoto on N → w, • N on välisymboli (aina!) – ei voi olla päätesymboli • päätesymboli ei voi nimetä syntaksiluokkaa • w on väli- ja päätesymbolien jono (<tunnus> := <lauseke>) Alkusymboli: • eräs välisymboli S, josta generointi alkaa, osa sääntöä S → w • S lavennetaan w:ksi – oikean puolen symbolijonoksi • tämän symbolijonon jokainen välisymboli lavennetaan edelleen rekursiivisesti • kunnes kaikki välisymbolit on lavennettu päätesymboleksi • generoinnin lopussa ei laventamattomia välisymboleja pitäisi olla • jos on, lähdekoodissa on virhe! • jos ei erikseen merkitty, ensimmäisen johtosäännön vasemman puolen symboli.
Ohjelma on oikein muodostettu, jos se voidaan johtaa alkusymbolista S. • Lähtökohtana on kieliopin sääntö S → w, josta kaikki ohjelmat ovat johdettavissa. • Jokainen syntaktisesti kelvollinen (siis kieliopin mukainen) päätesymbolijono voidaan esittää johto- eli jäsennyspuuna (parse tree). • Sen lehdissä ovat päätesymbolit, sisäsolmuina on syntaksiluokkia (välisymboleita) ja juurena on johdettava välisymboli. • jos sääntöä N → w otetaan generoinnissa käyttöön, puuhun tulee solmu, jonka juuri on N. • w:n väli- ja päätesymbolit ovat puun lapsisolmuina
Välisymbolit <tunnus> ja <luku> määritellään harjoituksissa. Ks. esimerkiksi javan syntaksia: string java grammar
5.3 Kääntäjän toiminta Kääntäjä muuntaa korkean tason kielellä kirjoitetun ohjelman konekieliseksi ohjelmaksi 3 vaiheessa: • Selaaminen eli leksikaalinen analyysi (lexical analysis). • etsitään ohjelman loogisesti yhteenkuuluvat tekstialkiot eli symbolit: tunnukset, operaattorit ja varatut sanat. • esim MunMuuttuja, +,/,*, IF, THEN, ELSE • Jäsentäminen eli syntaktinen analyysi (syntax analysis) • johtosääntöjä käytetään ohjelmakoodin jäsentämiseksi syntaksikokonaisuuksiin: lauseksi, moduleiksi jne • oikein kirjoitetun koodin kaikki syntaksikokonaisuudet jäsentyvät oikein viimeiseen merkkiin (päätesymboliin) saakka • esim. IF-ehtolauseessa ei ole ihmeellisiä merkkejä, jotka eivät sinne kuulu IF-lauseen syntaksin mukaan, jne • vaihe vastaa luonnollisen kielen lauseenjäsentämistä • tulos talletetaan johto-(jäsennys-)puuhun.
5.3 Kääntäjän toiminta: kolmas vaihe 3. Koodin generointi • muodostetaan konekieliset käskyt eli objektikoodi • varataan ohjelmalle muistitilaa • optimoidaan objektikoodi • penennetään koodin kokoa • nopeutetaan koodia Jäsennys-puu Teksti-alkioiden lista Lähdekielinen ohjelma Koodin generointi Objekti-ohjelma Jäsennys Selaus
5.3.1 Selaaminen tunnistetaan, • mitkä merkit kuuluvat yhteen symboliin eli tekstialkioon • mikä on tekstialkion tyyppi. Tekstialkion tyyppejä: • varattu sana: MODULE, IF, THEN, ELSE, CASE, OF, DO, REPEAT, UNTIL • operaattori: =, :=, <, >, +,-,*,/ jne. • välimerkki: (), välilyönti, rivinvaihto, pilkku, ; , : , . • tunnus: muuttuja, nimetty vakio, moduulin tunnus • luku- tai merkkivakio: -12.47, 3, "ATK"
5.3.1 Selaaminen • selaaja (scanner) • ohjelma, joka suorittaa alkiorakenteen tunnistuksen • selauksen tulos: • selattujen tekstialkioiden lista + symbolitaulu • peräkkäiset merkit kuuluvat yhteen symboliin • peräkkäisiä symboleja erottaa välimerkki • tarpeettomat välimerkit - välilyönnit, rivitvaihdot - (white spaces) poistetaan. • esim z := x - y → z:=x-y • jos löytyy merkki, joka ei kuulu kielen aakkostoon, esim. ﷲ, annetaan virheilmoitus • merkkijonot luokitellaan eri luokkiin tai tyyppeihin. • tunnukset viedään symbolitauluun • siihen talletetaan kunkin tunnuksen nimi ja tyyppi
Miten selaaja toimii? • sillä on käytössään merkkijonovektorit, joissa on: • kaikki kielen operaattorit • kaikki kielen varatut sanat • kaikki kielen välimerkit • selaaja käsittelee lähdekoodin merkkijonoja yksitellen verraten niitä vektoreiden sisältöön • jos merkkijono ei löydy mistään vektorista, sen täytyy olla luku tai tunnus • tehdään vähimmäistoimenpiteet sen tunnistamiseksi, onko kyseessä luku vai tunnus
5.3.1 Selaaminen Esimerkki. Selataan seuraava lause: IF x < 5 THEN x := x + 1 IF varattu sana x tunnus < operaattori 5 lukuvakio THEN varattu sana x tunnus := operaattori x tunnus + operaattori 1 lukuvakio • Tämän jälkeen ohjelma on tekstialkoiden muodostama lista Symbolitaulu x INTEGER
5.3.2 Jäsentäminen • Kääntäjä käyttää selaajan tuottamaa tekstialkioiden listaa hyväksi tutkiessaan ohjelman syntaktista rakennetta ja jäsentäessään lähdekoodia syntaktisiski kokonaisuuksiksi • oikein kirjoitetun koodin kaikki syntaksikokonaisuudet jäsentyvät oikein viimeiseen merkkiin (päätesymboliin) saakka • esim. IF-ehtolauseessa ei ole merkkejä, jotka eivät kuulu sinne IF-lauseen syntaksin mukaan, jne • tulos talletetaan jäsennyspuuhun • lehtisolmuina ovat päätesymbolit • sisäsolmuina syntaksiluokat Esimerkiksi asetuslause x:=k-m: <asetuslause> <:=> <tunnus> <lauseke> <tunnus> <operaattori> x <tunnus> - k m
Jäsentämisen strategiat Osittava (top-down) jäsennys: • juuresta lehtiin • lähdetään liikkeelle lähtösymbolista • ositetaan selaajan tekstialkoiden lista alemman tason syntaksiluokkiin, kunnes se voidaan esittää puun lehdissä Kokoava (bottom-up) jäsennys: • lehdistä juureen • vierekkäiset tekstialkiot yhdistetään yksinkertaisten syntaksiluokkien osiksi, jotka edelleen yhdistellään korkeamman tason syntaksiluokkien osiksi jne • lopetetaan kun päästään lähtösymboliin Jäsentämisen ongelma - kieliopin epädeterministisyys: • usein on mahdollista soveltaa useampaa kuin yhtä sääntöä • täytyy päättää, missä järjestyksessä johtosääntöjä kokeillaan • yleensä kokeillaan siinä järjestyksessä, missä ne on annettu
Osittava jäsentäminen • jos ohjelma P on oikein muodostettu, se voidaan johtaa alkusymbolista S. • otetaan sääntö S1→ s1 ... sm kokeiltavaksi • si:t ovat välisymboleja tai päätesymboleja. • esim. olk P: ”MODULE NollaanAsti(n) WHILE n>0 DO n:=n-1 ENDWHILE ENDMODULE” • kokeillaan sääntöä <ohjelma>→<moduuli> • silloin s1=<moduuli> • ohjelmateksti on jaettavissa m:ään alijonoon p1 ... pm, jotka vastaavat symboleja s1 ... sm • nyt p1=”MODULE NollaanAsti(n) WHILE n>0 DO n:=n-1 ENDWHILE ENDMODULE”, m=1
4.1. Tässä vaiheessa si voi olla joko väli- tai päätesymboli Jos si on on päätesymobli ja jos pi = si on jäsennys valmis • esim. päätesymboli alimerkkijonoa ”n>0” jäsennettäessä:<ehto>→<alkio><relaatio><alkio>, <relaatio>→ > • silloin ”>” on s1ja päätesymboli • jäsennys siis onnistuisi >-relaatiomerkille käyttämällä esitettyä sääntöä Jos taas pi ≠ si (kuvitellaan esim. ”n!0” merkkijonoa) • voidaan yrittää uutta P:n jakoa (merkkijono ei ollut ehto!) • jos mikään pi:n jako ei onnistu, peräännytään rekursiossa ulomalle tasolle kokeilemaan seuraavaa sääntöä S2→ s1 ... sm (askel 2.) • kun kaikki säännöt on kokeiltu tuloksetta, ohjelmassa täytyy olla syntaksivirhe! • ilmoitetaan käyttäjälle, keskeytetään kääntäminen
4.2. Jos si on on välisymbooli: • esim. olk P: ”MODULE NollaanAsti(n) WHILE n>0 DO n:=n-1 ENDWHILE ENDMODULE” • kokeiltavana oleva sääntö on <ohjelma>→<moduuli> • silloin s1=<moduuli> • s1 – välisymboli! Sovelletaan jäsennystä rekursiivisesti alimerkkijonoon pi kokeilemalla si:lle määriteltyjä sääntöjä: • p1 on siis ”MODULE NollaanAsti(n) WHILE n>0 DO n:=n-1 ENDWHILE ENDMODULE” • uusi rekursiokutsu, ja kokeillaan <moduuli>→MODULE <tunnus> (<parametrilista>)… • s1=MODULE; s2=<tunnus>; s3=(; s4=<parametrilista> etc • p1=MODULE, p2=NollaanAsti,p3=(,p4=n etc • s1-päätesymb., p1=s1, jäsennys sen osalta valmis • s2-välisymb.<tunnus>, p2=NollaanAsti, syntyy uusi rekursiokutsu, jossa ”NollaanAsti”:a jäsennetään tunnukseksi • näin käsitellään jokaista sk-pk paria, k=1..m!
Jos kaikki rekursiiviset alijäsennykset onnistuvat, jäsennys on valmis. • Jos jossain vaiheessa kokeiltu sääntö on väärä, se hylätään ja kokeillaan seuraavaa vaihtoehtoa. • Jos mikään ei onnistu, palataan rekursiossa ylemmälle tasolle. Jos ylemmälläkään tasolla ei enää ole kokeilemattomia sääntöjä, ohjelman jäsennys ei onnistu => lähdeohjelma ei ole oikein muodostettu → annetaan virheilmoitus
tai S→s1, ja w=p1, ja p1=s1, jäsennys onnistuu suoraan, luodaan lehtisolmu! säännön oikea puoli on väli- ja päätesymboleja jaetaan w siten, että päätesymbolit ovat u1..uk, ja muut alimerkkijonot w1..wk vastaavat välisymboleja, joita jäsennetään rekursiivisissa jäsennys-kutsuissa ** luodaan alipuu, jonka lapset ovat u0, P1, u1…ylemmällä rekursiotasolla tämä syntyvä P yhdistetään isompaan puuhun jos w:n jako ei onnistu millään johtosäännöllä, palautetaan tältä rekursiotasolta ei, ja ulomalla rekursiotasolla siirrytään seuraavalle WHILE-kierrokselle kokeilemaan uutta w:n jakoa! (kohta merkitty **:llä)