Hallo,
man könnte das Problem auch mit einigen geschachtelten Routinen lösen:
Delphi-Quellcode:
function Eval (s:
string): Integer;
function EatChar (
const aSet: TSysCharSet;
var ch: Char): Boolean;
begin
Result := ((s <> '
')
and (s[1]
in aSet));
if Result
then
begin
ch := s[1];
s := TrimLeft(Copy(s, 2, MaxInt));
end;
end;
function Term: Integer;
function Summand: Integer;
function Factor: Integer;
var
ErrPos: Integer;
op: Char;
begin
if EatChar(['
+', '
-', '
('], op)
then
case op
of
'
+': Result := Factor;
'
-': Result := -Factor;
'
(':
begin
Result := Term;
if (
not EatChar(['
)'], op))
then
raise Exception.Create('
missing ")"');
end;
else
Result := 0;
// calm compiler
end
else
begin
Val (s, Result, ErrPos);
if (ErrPos = 0)
then
s := '
'
else
s := TrimLeft(Copy(s, ErrPos, MaxInt));
end;
end;
var
op: Char;
begin
Result := Factor;
while EatChar(['
*', '
/'], op)
do
case op
of
'
*': Result := Result * Factor;
'
/': Result := Result
div Factor;
end;
end;
var
op: Char;
begin
Result := Summand;
while EatChar(['
+', '
-'], op)
do
case op
of
'
+': Result := Result + Summand;
'
-': Result := Result - Summand;
end;
end;
begin
s := Trim(s);
Result := Term;
if (s <> '
')
then
raise Exception.Create('
unknown operation');
end;
In der jetzigen Form verarbeitet der Parser nur Integer-Ausdrücke, die Fehlerbehandlung verdient ihren Namen eigentlich nicht. Aber es soll ja lediglich das Prinzip verdeutlicht werden.
Gruß Hawkeye