Leksika korrektsust kontrolliv programm

Eelmises loengus esitatud Pico-Algoli leksika grammatika põhjal on lihtne kirjutada programmi, mis kontrollib sisestatud programmiteksti (Pico-Algolis) leksilist korrektsust, s.t. et lähtetekst vastab Pico-Algoli leksika kirjeldusele, nagu see oli grammatika abil defineeritud; sellele programmile saab hiljem lisada väljundtegevused, nii et sellest saab Pico-Algol-i leksika analüüsi teostava programmi (skanner).

Allpool toodud programminäide on esitatud programmeerimiskeele ADA süntaksis.

Defineerime algul kõik tarvisminevad andmetüübid; ADA sisseehitatud funtsiooni "in" abil võimaldavad need hiljem lihtsalt kontrollida, et lähteteksti sümbol on korrektne. ADA loetlustüübi definitsioon koosneb lihtsalt sellise tüübiga muutuja kõigi lubatud väärtuste loetelust; alamtüübi definitsioonis näitatakse baastüübi (loetlustüüp) esimene ja viimane element; -- on kommentaari algus:

type SYMBOL is (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, z, t, u, v, w, õ, ä, ü, x, y, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, Z, T, U, V, W, Õ, Ä, Ö, Ü, X, Y, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, -, *, /, ^, ;, :, ., =, (, ), , CRLF);

subtype LETTER is SYMBOL range a..Y;

subtype DIGIT is SYMBOL range 0..9;

subtype MÄRK is SYMBOL range +..CRLF;

subtype OP is SYMBOL range +..^;

Et sisendtekstis esinevaid vigu paigaldada, on tarvis andmetüüpi, mis võimaldab kirjeldada sisendteksti sümbolite asukohta:

type textposition is record

LINENUMBER: 1..99999; -- s.t. PICO-ALGOLI programmis ei või olla rohkem ridu!
CHARPOSITION: 0..80
end record;

Vea korral salvestatakse veakood ja selle esinemiskoht:

type ERROR is record

ERRORCODE: INTEGER;
ERRORPOSITION: TEXTPOSITION;
end record;

Vead salvestatakse ja teatatakse kasutajale alles kogu analüüsi lõppedes (s.t. programm püüab sisendtekstis vea leidmisel tööd jätkata):

ERRORLIST: array 1..ERRORMAX of ERROR
-- ERRORMAX on maksimaalne lubatud vigade arv sisendtekstis

Protseduur READ annab globaalse muutuja CH väärtuseks sisendteksti järgmise sümboli ja muutuja POSITION väärtuseks saab selle asukoht lähtetekstis:

procedure READ(

CH: in SYMBOL,
POSITION: in TEXTPOSITION); -- protseduuri READ ehitus meid siin ei huvita !

Protseduur RECORD_ERROR salvestab vea koodi ja asukoha:
procedure RECORD_ERROR(

ERRORCODE: in INTEGER;
ERRORPOSITION: in TEXTPOSITION);

Kasutades alamprotseduure WORD, NUMBER, ERALDAJA (need vastavad alamautomaatidele, mis kirjeldavad vastavalt identifikaatoreid, arve ja eraldajaid) võib kogu leksikat tunnistava (kontrolliva) programmi kirjutada täpses vastavuses leksikat defineeriva grammatika struktuuriga:

procedure SCAN(SISEND: in FILE) is

begin
READ;
while CH in SYMBOL
loop
--
PROGRAMM (ERALDAJA | IDENT ERALDAJA | CONST ERALDAJA )*
case CH is
when LETTER WORD;ERALDAJA;
when DIGIT NUMBER;ERALDAJA;
when MÄRK ERALDAJA;
end case;
end loop;
if CH='#' then ACCEPT
else RECORD_ERROR(0,POSITION)
-- # - sisendteksti lõpusümbol
-- veakood 0: lubamatu sümbol
end SCAN;

procedure WORD is
--
PROGRAMM (ERALDAJA | IDENT ERALDAJA | CONST ERALDAJA )*

begin
while CH in LETTER or CD in DIGIT
loop
READ;
end loop;
end while;
end WORD;

procedure NUMBER is

begin
while CH in DIGIT
loop
READ;
end loop;
end while;
end NUMBER;

procedure ERALDAJA is

begin
case CH is
when '+'|'-'|'*'|'/'|'='|';'|'('|')' READ;
when ':' READ;
if CH = '=' ther READ
else RECORD_ERROR(1,POSITION);
-- veakood 1: oodati sümbolit '='
end case;
end ERALDAJA;



Ülesandeid:


Küsimused, probleemid:
jaak@cc.ttu.ee

Tagasi loengute sisukorra juurde