Väljundtegevuste lisamine

Regulaarse avaldise poolt määratud keelt tunnistavast automaadist saab väljundtegevuste lisamisega teisendaja (transducer), mis samaaegselt tunnistamisega tõlgib (transleerib) sisendsõna väljundsõnaks.

Näiteks täisarve tunnistab automaat ; siin # on nn lõpumärgend, mis on kirjutatud tunnistatava täisarvu järele - ilma selleta poleks võimalik otsustada, millal täisarv lõpeb; kui täisarv esineb programmi tekstis, siis tuleb lomulikult # asemel täisarvule järgneva lekseemi esimene sümbol.

Regulaarsele avaldisele või lõplikule automaadile vastava programmilõigu kirjutamisel peab meeles pidama, et programmilõigu käivitamisel (need käivitatakse skannerist) on sisendi esimene sümbol juba loetud, s.t. see on muutuja CH väärtuseks. Sellepärast on nii regulaarseted avaldised kui ka automaadid esitatud kujul, kus sisendi esimene sümbol on välja eraldatud, näiteks täisarv on avaldise (NUM)+ asemel esitatud (samaväärse) regulaarse avaldisega NUM(NUM)*.

Avaldisele NUM(NUM)* vastab täisarve tunnistav programmilõik:

procedure ARV is
begin while CH in DIGIT loop READ; end loop; end while; end NUMBER;

Et täisarve tähistavast märgijadast (sisend) saada arvu, tuleb: - esimese numbri lugemisel omistatakse see muutujale, kuhu kogutakse täisarvu väärtus - seda teeb alamprotseduur FirstDigit; - iga uue numbri lugemise järel lisada see juba loetud osale, s.t. väärtust salvestavale muutujale, seda teeb alamprotseduur NextDigit; ; - kui kogu numbrite jada on loetud, tuleb saadud arv kuhugi salvestada; seda teeb alamprotseduur OutInt .

Nende väljundtegevuste lisamisega muutub ülalesitatud lõplik automaat teisendajaks, mis muudab numbrite jada (sisendi) arvuks (iga kaare peal on vastava ülemineku põhjustanud sisend ja all - käivitatav väljund). ehk väljundtegevustega laiendatud regulaarse avaldisena

NUM FirstDigit (NUM NextDigit)* OutInt

Väljundtegevuste lisamisega ülalesitatud programmilõiku saame skanneri protseduuri, mis loeb ja salvestab täisarve. Selle struktuur (loogika) on täielikult määratud regulaarse avaldise struktuuriga, kuid väljundtegevusi realiseerivate protseduuride lisamisel peab arvestama, et selle protseduuri käivitumisel on arvu esimene number juba loetud, s.t. see on juba muutuja CH väärtuseks:

procedure ARV is
begin FirstDigit; while CH in DIGIT loop READ; NextDigit; end loop; end while; OutInt; end NUMBER;

Protseduur FirstDigit initsialiseerib täisarvu-tüüpi muutuja CONST, kuhu salvestatakse kogu loetud arvu väärtus; ORD on tüübiteisendus, mis teisendab märgi (character) vastavaks numbriks :

procedure FirstDigit
(CH: in CHARACTER CONST: in out INTEGER) is DIGIT=ORD(CH); CONST = DIGIT; end FirstDigit

Protseduur NextDigit lisab loetud numbri muutuja CONST väärtusele:

procedure NextDigit
(CH: in CHARACTER CONST: in out INTEGER) is DIGIT=ORD(CH); CONST = 10 * CONST + DIGIT; end FirstDigit

Protseduur OutConst kirjutab saadud arvkonstandi (lekseemi) väljundisse.

Veel lihtsam skanneri alamprotseduur identifikaatorite jaoks. Identifikaatoreid kirjeldavale regulaarsele avaldisesele TÄHT(TÄHT|NUM)* väljundtegevuste FirstChar - initsialiseerib string-tüüpi muutuja WORD, andes selle väärtuseks identifikaatori esimese tähe NextChar - lisab loetud tähe muutuja WORD lõppu (& - stringide liitmine, konkatenatsioon) OutWord - kontrollib, kas loetud sõna oli programmeerimiskeele võtmesõna; kui sõna on identifikaator, lisab selle transleeritava programmi nimede tabelisse lisamise järel modifitseerime selle põhjal eespoolesitatud protseduuri:

procedure SÕNA is
begin FirstChar; while CH in TÄHT or CH in NUMBER loop READ; NextChar; end loop; end while; OutWord; end WORD;

Protseduur FirstChar- initsialiseerib string-tüüpi muutuja WORD:

procedure FirstChar
(WORD: in out STRING (CH: in CHARACTER) WORD = CH; end FirstChar;

Protseduur NextChar lisab loetud tähe muutuja WORD lõppu; ühtlasi saab siin ka kontrollida lisatingimusi, näiteks paljudes programmeerimiskeeltes on identifikaatorite (ka võtmesõnade) pikkus piiratud:

procedure NextChar
(WORD: in out STRING; CH: in CHARACTER) if length(WORD) = 8 then RECORD_ERROR(3, POSITION) else WORD = WORD & CH; end if; end NextChar;


lesandeid:
1. Ylesande tekst

K simused, probleemid: ©2004 Jaak Henno