const NIC =0; SOUCET =1; ODECET =3; NASOBENI=4; DELENI =5; ZAPORNE_NASOBENI =6; ZAPORNE_DELENI =7; CHYBA_ZADNA = 0; CHYBA_ZADANI = 1; CHYBA_DELENI_0 = 2; var pozice_chyby:byte; druh_chyby:byte; Function Operace2(r,r2:real;o:byte):real; begin case o of NIC : r:=r2; NASOBENI : r:=r*r2; DELENI : if r2=0 then begin druh_chyby:=CHYBA_DELENI_0; Operace2:=0; Exit; end else r:=r/r2; ZAPORNE_NASOBENI: r:=-r*r2; ZAPORNE_DELENI : r:=-r/r2; end; {case} Operace2:=r; end; Function Operace1(r,r2:real;o:byte):real; begin case o of NIC: r:=r2; SOUCET:r:=r+r2; ODECET:r:=r-r2; end; {case} Operace1:=r; end; Function Uroven2(const s:string):real; var i,o:byte; r,r2:real; k:integer; t:string; begin t:=''; o:=NIC; r:=0; for i:=1 to Length(s) do if not (s[i] in ['*','/','@','#']) then t:=t+s[i] else begin Val(t,r2,k); r:=Operace2(r,r2,o); if druh_chyby<>CHYBA_ZADNA then begin Uroven2:=0; Exit; end; t:=''; case s[i] of '*':o:=NASOBENI; '/':o:=DELENI; '@':o:=ZAPORNE_NASOBENI; '#':o:=ZAPORNE_DELENI; end; {case} end; {else begin} {dodelame posledni cislo, za kterym uz neni znak zadne operace} Val(t,r2,k); Uroven2:=Operace2(r,r2,o); end; Function Uroven1(const s:string):real; var o:byte; {typ operace: (ZADNA, SOUCET, ODECET)} i:byte; r,r2:real; t:string; begin t:=''; o:=NIC; r:=0; for i:=1 to Length(s) do if not (s[i] in ['+','-']) then t:=t+s[i] else begin r2:=Uroven2(t); r:=Operace1(r,r2,o); t:=''; case s[i] of '+':o:=SOUCET; '-':o:=ODECET; end; {case} end; {else begin} {dodelame posledni cislo, za kterym uz neni zadny matematicky symbol} if druh_chyby<>CHYBA_ZADNA then begin Uroven1:=0; Exit; end; r2:=Uroven2(t); Uroven1:=Operace1(r,r2,o); end; Function ZrusMezery(s:string):string; var t:string; i:byte; begin t:=''; for i:=1 to Length(s) do if s[i]<>' ' then t:=t+s[i]; ZrusMezery:=t; end; Procedure Preprocesor(s:string;var t:string;var chyba:byte); var i,j:byte; k:integer; r:real; uvnitr:boolean; u:string; begin t:=ZrusMezery(s); s:=''; if t[1] in ['-'] then t:='0'+t; {cely vyraz zacina znamenkem minus?} uvnitr:=true; {zaciname uvnitr cisla} u:=''; for i:=1 to Length(t) do begin if uvnitr=true then {uvitr cisla...} begin if t[i] in ['.','0'..'9'] then u:=u+t[i] else begin Val(u,r,k); if (k<>0) or (u='') then {ze znaku '.' a '0'..'9' nevzniklo smysluplne cislo?} begin {(nejspise dve desetinne tecky v jednom cisle)} chyba:=i-Length(u)+k; Exit; end; s:=s+u; u:=t[i]; uvnitr:=false; end; end else begin {jsme vne cisla...} if not (t[i] in ['.','0'..'9']) then u:=u+t[i] else begin if Length(u)>1 then {kombinace symbolu?} begin if u='--' then u:='+' else if u='+-' then u:='-' else if u='*-' then u:='@' else {ZAPORNE NASOBENI} if u='/-' then u:='#' else {ZAPORNE DELENI} if u='*--' then u:='*' else if u='/--' then u:='/' else begin {ostatni kombinace nejsou povolene} chyba:=i; Exit; end; end; s:=s+u; u:=t[i]; uvnitr:=true; end; end; end; {for} if uvnitr=false then {na konci vyrazu musi byt cislo, ne symbol} begin chyba:=i; Exit; end; chyba:=0; s:=s+u; t:=s; end; Function Parser(s:string):real; var n:byte; r:real; t:string; begin Preprocesor(s,t,n); if n<>0 then begin druh_chyby:=CHYBA_ZADANI; pozice_chyby:=n; Parser:=0; end else begin pozice_chyby:=0; druh_chyby:=CHYBA_ZADNA; r:=Uroven1(t); Parser:=r; end; end; var s:string; r:real; begin s:='-3*4+5*-2/0+5'; {s:='-1+2+3+4';} {s:='10+30+5+5-60+5';} r:=Parser(s); writeln(s); if druh_chyby<>0 then writeln('Chyba!') else writeln(r:3:3); readln; end.