(*
Feladat:
Aritmetikai kifejezés kiértékelése.
A. Részletesebben:
A1. Egy kif sztringben hagyományos infix kifejezés van.
Ezt lexikális egységeire bontjuk
(lexEgys): lexKif.
A lexEgys-eket hagyományos Text-ben
(lexKif) tároljuk:
egy sor - egy lexikális egység bontásban.
A2. Az elöbbi lexikális egységeket tartalmazó file-ból
kiindulva elöállítjuk a post-fix
lengyelformáját: pfKif.
Ez is egy Text (pfKif), elöbbivel azonos
konvencióval, azaz
egy sor - egy lexikális egység.
A3. A pfKif file-ból továbblépve kiszámoljuk a kifejezés
értékét.
Ha voltak a kifejezésben változók, akkor
e programnak kell
gondoskodnia az értékek beolvasásáról is.
B. Még részletesebben:
B1. Megengedett lexikális egységek. Azaz, amiket tartalmazhat
a bemenö (kif) sztring:
B1.1. Számkonstansok
B1.2. Számváltozók (azonosítója egy betüböl álló szöveg)
B1.3. Elemi aritmetikai müveleti jelek ('+','-','*','/','^')
B1.4. Néhány valósértékü aritmetikai függvény ('Sin','Cos',
'Sqrt','Tg','Pi'...)
B2. A bemenö kifejezéssel szemben elvárt speciális feltételek:
B2.1. Minden lexikális egység között pontosan egy szóköz van.
B2.2. A függvények argumentumát kötelezö bezárójelezni.
Pl.:
a * Sin ( b * x + Pi / 2 ) - 5.4321
B2.3. Kis- és nagybetüket nem különböztetünk meg.
B2.4. A kifejezés előtt és után nincsen szóköz.
B3. A lexikális egységek megjelenése a lexKif Text-ben: értékpár
formájában.
lexEgys --> (miféle + értéke)
A miféle és hozzárendelt kódja:
* Számkonstans: 0
* Számváltozó: 1
* Müvelet (és a zárójelek): 2
Egy néhány lexikális egységre példa:
( 0 , '5.4321' )
( 1 , 'a' )
( 2 , 'Sin' )
A lexKif file-ra példa:
( 1 , 'a' )
( 2 , '*' )
( 2 , 'Sin' )
( 2 , '(' )
( 1 , 'b' )
( 2 , '*' )
( 1 , 'x' )
( 2 , '+' )
...
( 0 , '5.4321' )
B4. A lexikális egységek megjelenése a pfKif Text-ben: értékpár
formájában.
lexEgys --> (miféle + értéke)
A pfKif file-ra példa:
( 1 , 'a' )
( 1 , 'b' )
( 1 , 'x' )
( 2 , '*' )
( 2 , 'Pi' )
( 0 , '2' )
( 2 , '/' )
( 2 , '+' )
( 2 , 'Sin' )
( 2 , '*' )
...
C. Az egyes részfeladatokat (l. A1-A3.) önállóan futó programok
végzik el. A kapcsolatot file-okon
keresztül tartják.
(Elképzelhetö, hogy a fent nevesített
file-okon túl [lexKif, pfKif]
továbbiak is célszerüek [pl. a müveleti
táblát tartalmazó file,
ami soronként felsorolja a legális
operátorokat esetleg precedenciájukkal
együtt; eképpen:
+ 5
- 5
* 6
/ 6
^ 7
Pi 10
Sin 10
Cos 10
Tg 10
Sqrt 10
)
*)
A lengyelformával kapcsolatos dolgokat, amelyeket az egyes részfeladatok programjai egyformán kell ismerjenek a lengyel.inc-ben található:
(*
Lengyel.inc: Lengyelforma kiértékelés
programjainak közös dolgai
*)
Type
TFajta=(Szam,Valt,Muv,Vege);
Const SFajta:Array [TFajta] of String=('Szam','Valt','Muv','Vege');
KFajta:Array [TFajta] of Byte=(0,1,2,Ord(Vege));
Type
TMuv=Record
jel:String;
prec:Byte
End;
Const MaxMuv=12;
Type
TMuvTabla=Array [1..MaxMuv] of TMuv;
Const EgyJeluek=7; {ennyi egy jelből
álló operátor van,
amelyek az Op elején
találhatók}
Op:TMuvTabla=((jel:'(';prec:0),(jel:')';prec:0),
(jel:'+';prec:5),(jel:'-';prec:5),(jel:'*';prec:6),
(jel:'/';prec:6),(jel:'^';prec:7),
{innentől vannak a többjeles operátorok/fv.-ek:}
(jel:'PI';prec:10),(jel:'SIN';prec:10),
(jel:'COS';prec:10),(jel:'TG';prec:10),
(jel:'SQRT';prec:10));
mifele:TFajta;
ertek:String;
Constructor
Letrehoz(mi:TFajta; er:String);
Destructor Lerombol;
Procedure Readln(Var
f:Text);
Procedure Writeln(Var
f:Text);
End;
Constructor OLexEgys.Letrehoz(mi:TFajta; er:String);
Begin
mifele:=mi; ertek:=er;
End;
Destructor OLexEgys.Lerombol;
Begin
End;
Procedure OLexEgys.Readln(Var f:Text);
Var kod:Byte;
Begin {Ef: a file-ban a lexEgys 1 sorban értékpár.
1. érték: számkód, 2. érték:
szöveg}
System.Readln(f,kod,ertek);
mifele:=TFajta(kod);
End;
Procedure OLexEgys.Writeln(Var f:Text);
Begin
System.Writeln(f,KFajta[mifele],'
',ertek);
End;
A lexikális elemekre bontás megoldása (lexKiert.pas):
Program LexikalisKiertekeles; {az A1.
reszfeladat programja}
(*
l. fent
a lengyel.fel fájlban
*)
Uses Newdelay,Crt,Crt22;
{$i AltRutin.inc}
{$i lengyel.inc -- a lengyelforma
kiértékelés programjainak közös dolgai}
Var
kif:String; {billentyű input}
lexKif:Text; {file output:
Text-esített,
soregységre tördelt OLexEgys
file}
Const lexKifFn='lexKif.txt';
Const tollSzin=Black;
papirSzin=White;
link=128;
Function Beolvasas:String;
Var i,j:Byte;
ss,s:String;
Begin
UjLap('Lengyelforma
-- kifejezés-beolvasás',0);
Write('Kérem
az aritmetikai kifejezést:');
Readln(s);
{nagybetűsit:}
For i:=1 to Length(s) do s[i]:=UpCase(s[i]);
{a műveleti jelek szóközökkel tagolása --ha még nem
lenne--:}
For i:=1 to MaxMuv do
Begin
ss:='';
Repeat
j:=Pos(Op[i].jel,s);
If j>0 then
Begin
ss:=ss+Copy(s,1,j-1)+' '+Copy(s,j,Length(Op[i].jel))+' ';
s:=Copy(s,j+Length(Op[i].jel),Length(s)-j-Length(Op[i].jel)+1)
End;
Until j=0;
s:=ss+s
End;
{elő- és végszóközök levágása:}
i:=1;
While (i>0) and (s[i]=' ') do Inc(i);
Delete(s,1,i-1);
i:=Length(s);
While (i>0) and (s[i]=' ') do Dec(i);
Delete(s,i+1,Length(s)-i);
{fölösleges szóközök elhagyása:}
i:=1;
{bármi, ami >0}
While i>0 do
Begin
i:=Pos(' ',s); Delete(s,i,1);
End;
Beolvasas:=s
End;
Procedure FileMegnyitas(fN:String; Var f:Text);
Var
hiba:Integer;
Begin
UjLap('Lengyelforma
-- file-megnyitás',0);
Repeat
{$i-}
Assign(f,fN);
Reset(f);
hiba:=IOResult;
If hiba<>0 then
Begin
Rewrite(f);
hiba:=IOResult;
If hiba<>0 then
Begin
TextColor(Red+Blink);
Writeln('A file nem nyitható meg:');
Writeln(' Hibás
file-név.');
TextColor(tollSzin);
BillreVar
End
End
Else
Begin
Rewrite(f);
TextColor(Red+Blink);
Writeln(' Ilyen file
már van. A file felülíródik.');
TextColor(tollSzin);
BillreVar
End;
{$i+}
Until hiba=0;
End;
Function Elemez(le:String):TFajta;
Var x:Real;
i,siker:Integer;
Begin
Val(le,x,siker);
If siker<>0 then
Begin
i:=1;
While (i<=MaxMuv) and (Op[i].jel<>le) do Inc(i);
If i<=MaxMuv then Elemez:=Muv
else Elemez:=Valt;
End
else
Begin
Elemez:=Szam
End;
End;
Procedure Felbont(kif:String; Var lk:Text);
{Ef: Minden lexikális egység között pontosan egy szóköz
van.}
Var miASzosz:TFajta;
ig:Byte;
le:String;
leO:OLexEgys;
Begin
UjLap('Lengyelforma
-- kifejezés-felbontás',0);
ig:=Length(kif);
While ig>0 do
Begin
ig:=Pos('
',kif);
If ig>0 then
Begin
le:=Copy(kif,1,ig-1);
kif:=Copy(kif,ig+1,Length(kif)-ig);
miASzosz:=Elemez(le);
End
else
Begin
le:=kif;
kif:='';
miASzosz:=Elemez(le);
End;
leO.Letrehoz(miASzosz,le); A def. lásd előbb.
leO.Writeln(lk);
leO.Lerombol;
{ellenőrző kiírás:}
Writeln(KFajta[miASzosz],'
(',SFajta[miASzosz],') ',le);
End;
End;
Begin
UjLap('Lengyelforma',0);
TextColor(tollSzin);
TextBackground(papirSzin);
kif:=Beolvasas;
FileMegnyitas(lexKifFn,lexKif);
Felbont(kif,lexKif);
Close(lexKif);
End.
Minden hozzávaló letöltése: lengyel.zip.