{TEKSTI ANALYYSIMINE OTSUSTUSTABELI ALUSEL} program kalkulaator; {Teeb binaarseid aritmeetilisi tehteid. Eeldatakse, et avaldis on kirjutatud ja"rgmiste BNF-reeglite kohaselt: avaldis ::= arv vahe mark vahe arv arv ::= number | arv number mark ::= + | - | * | / vahe ::= tyhi | vahe tyhik tyhi ::= Alamprogrammis 'analyys' toimub avaldise analyys otsustustabeli alusel: --------------------------------------------------------------------------- \Jarjekordne | | | | | | \symbol c= | number | tyhik | tehtemark | rea lopp | muu | Olek \ =s[i] | | | | | | =========================================================================== O1: esimese | a:=c | viga1 | viga2 | viga3 | viga4 | arvu eel | olek:=O2 | | | | | --------------------------------------------------------------------------- O2: esimesel | a:=10a+c | olek:=O3 | m:=s[i] | viga5 | viga6 | arvul | | | olek:=O4 | | | --------------------------------------------------------------------------- O3: tehte- | viga7 | - | m:=s[i] | viga8 | viga9 | margi eel | | | olek:=O4 | | | --------------------------------------------------------------------------- O4: teise | b:=c | | | | | arvu eel | olek:=O5 | - | viga10 | viga11 | viga12 | --------------------------------------------------------------------------- O5: teisel | b:=10b+c | viga13 | viga14 | kui arvud ei | viga16 | arvul | | | | ole korras,| | | | | | siis viga15; | | | | | | lopp | | ===========================================================================} uses Strings; var s: array [0..60] of char; {antud tekstirida (avaldis)} a,b: real; ia, ib: integer; {antud arvud} m: char; {antud tehtmark} OK: Boolean; {avaldise korrektsuse tunnus} i:integer; {vaadeldava symboli indeks so~nes s} {===================================================================} procedure viga(v:integer{vea number}); {veateadete va"ljastamine, seatakse OK = FALSE} begin case v of 1: writeln('VIGA1: Tyhik alguses!'); 2: writeln('VIGA2: Tehtemark (',s[i], ') alguses!'); 3: writeln('VIGA3: Tyhi rida!'); 4: writeln('VIGA4: Esimene symbol (',s[i], ') vale!'); 5: writeln('VIGA5: Ainult yks arv!'); 6: writeln('VIGA6: Vale symbol (',s[i], ') esimeses arvus!'); 7: writeln('VIGA7: Puudub tehtemark!'); 8: writeln('VIGA8: Puudub tehtemark!'); 9: writeln('VIGA9: Tehte mark vale (',s[i], ')!'); 10: writeln('VIGA10: Vale symbol (',s[i], ') teises arvus!'); 11: writeln('VIGA11: Teine arv puudub!'); 12: writeln('VIGA12: Teine arv algab vale symboliga (',s[i], ')!'); 13: writeln('VIGA13: Teine arv lopeb tyhikuga!'); 14: writeln('VIGA14: Teine arv lopeb tehtemargiga (',s[i], ')'); 15: writeln('VIGA15: Ei saa arvutada!'); 16: writeln('VIGA16: Teise arvu lopus ylearune symbol (',s[i], ')'); end; OK := FALSE; end; {====================================================================} function korras:Boolean; {kontrollib avaldisest saadud arvude a ja b ning tehte tulemuse suurust, omistab a ja b vaa"rtused ta"isarvudena muutujatele ia ja ib} label lopp; begin korras := FALSE; if a > MAXINT then begin write('Esimene arv liiga suur'); goto lopp end; ia := round(a); if b > MAXINT then begin write('Teine arv liiga suur'); goto lopp end; ib := round(b); case m of '+': if a+b > MAXINT then begin write('Summa liiga suur'); goto lopp end; '*': if a*b > MAXINT then begin write('Korrutis liiga suur'); goto lopp end; '/': if ib=0 then begin writeln('Jagamine nulliga.'); exit end; end; korras := TRUE; exit; lopp: writeln(' (suurim lubatud arv on ',MAXINT,').'); end; {===============================================================} procedure analyys; {otsustustabeli realisatsioon} var c:integer; {vaadeldav symbol} olek: 1..5; begin olek := 1; i := 0; OK := TRUE; while OK do begin c := ord(s[i])-ord('0'); {kui symbol s[i] on number, siis c on vastav arv} case s[i] of {------------------------ number} '0','1','2','3','4','5','6','7','8','9': case olek of 1: begin a := c; olek := 2 end; 2: a := 10*a + c; 3: viga(7); 4: begin b := c; olek := 5 end; 5: b := 10*b + c; end; ' ': {------------------------ tyhik} case olek of 1: viga(1); 2: olek := 3; 3: ; 4: ; 5: viga(13); end; '+','-','*','/': {------------------------ tehtemark} case olek of 1: viga(2); 2: begin m := s[i]; olek := 4 end; 3: begin m := s[i]; olek := 4 end; 4: viga(10); 5: viga(14); end; chr(0): {------------------------ realopp} case olek of 1: viga(3); 2: viga(5); 3: viga(8); 4: viga(11); 5: begin if not korras then viga(15); break end; end; else {------------------------ muu symbol} case olek of 1: viga(4); 2: viga(6); 3: viga(9); 4: viga(12); 5: viga(16); end; end; i := i + 1; end; end; {===================================================================} begin {peaprogramm} writeln('Palun ridu kujul: arv tehe arv (katkestamiseks ^Z)'); while not eof do begin readln(s); {lugeda avaldis} analyys; {leida avaldisest arvud ia, ib ja tehtemark m} if OK then case m of {va"ljastada tulemus} '+': writeln(ia+ib); '-': writeln(ia-ib); '*': writeln(ia*ib); '/': writeln(ia/ib:5:1) end end end.