Doch das geht prima, weil man den "/" eher erkennt als das "-" (Punktrechnung vor Strichrechnung).
So in etwa:
Delphi-Quellcode:
function Parse(s:
String): TParseTreeNode;
begin
if s[1] = '
-'
then s := '
0'+s;
if FindToken('
*', s)
then
result := TParseTreeNode.Create(opMul, Parse(PartBeforeToken('
*', s)), Parse(PartAfterToken('
*', s)))
else
if FindToken('
/', s)
then
result := TParseTreeNode.Create(opDiv, Parse(PartBeforeToken('
*', s)), Parse(PartAfterToken('
*', s)))
else
if FindToken('
+', s)
then
result := TParseTreeNode.Create(opAdd, Parse(PartBeforeToken('
*', s)), Parse(PartAfterToken('
*', s)))
else
if FindToken('
-', s)
then
result := TParseTreeNode.Create(opSub, Parse(PartBeforeToken('
*', s)), Parse(PartAfterToken('
*', s)))
else
begin
try
result := TParseTreeNode.Create(opConst, StrToFloat(s));
except
raise Exception.Create('
Grammar Error');
end;
end;
end;
Alles was oben im if-then-else-Wurm Steht bindet stärker.
Was die Bools angeht, so habe ich die bei mir nicht separat implementiert, sondern nutze ganz normale Zahlenwerte (0 und 1), womit die Operatoren in den selben Ablauf passen. Verliert etwas Typsicherheit, klappt aber wie ne eins.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)