Форум: "Основная";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];
ВнизTParser - как побороть? Найти похожие ветки
← →
Roobee © (2005-01-03 13:34) [0]Мастера, подскажите как побороть TParser чтобы он распознавал токен "-"
код ниже.
строку "5 - 6" не обрабатывает, а "-6 + 5" запросто.
как справиться с этим?
-----
unit ExpParse;
interface
uses Classes, Math;
{ Набор парсируемых элементов определяется как подмножество
выражений Delphi Object Pascal, подобно этому:
Expr ::= Term + Expr | Term - Expr | Term
Term ::= Factor * Term | Factor / Term | Factor
Factor ::= + Item | - Item | Item
Item ::= ( Expr ) | Fn( Expr ) | Number
Fn ::= Sin | Cos | другое...
Number ::= floating point literal number (плавающая точка литерала числа)
}
type
TExpressionParser = class(TParser)
protected
function SkipToken(Value: char): boolean;
function EvalItem: double; virtual;
function EvalFactor: double; virtual;
function EvalTerm: double; virtual;
public
function EvalExpr: double;
end;
implementation
uses SysUtils, EvalForm;
function TExpressionParser.SkipToken(Value: char): boolean;
begin
{ возвращаем истину, если текущий признак Value,
и если так, то получаем следующий признак }
Result := Token = Value;
if Result then
NextToken;
end;
function TExpressionParser.EvalItem: double;
var
Expr: double;
Fn: integer;
begin
case Token of
toInteger: Result := TokenInt;
toFloat: Result := TokenFloat;
"(":
begin
NextToken;
Result := EvalExpr;
CheckToken(")");
end;
toSymbol:
begin
if CompareText(TokenString, "SIN") = 0 then
Fn := 1
else if CompareText(TokenString, "COS") = 0 then
Fn := 2
else if CompareText(TokenString, "TRUNC") = 0 then
Fn := 3
else
raise EParserError.CreateFmt("Неизвестный элемент "%s"", [TokenString]
);
NextToken;
CheckToken("(");
NextToken;
Expr := EvalExpr;
CheckToken(")");
case Fn of
1: begin
Result := SIN(Expr);
end;
2: begin
Result := COS(Expr);
end;
3: begin
Result := TRUNC(Expr);
end;
end;
end;
else
raise EParserError.CreateFmt("Неожидаемый символ "%s"", [Token]);
end;
NextToken;
end;
function TExpressionParser.EvalFactor: double;
begin
case Token of
"+":
begin
NextToken;
Result := EvalItem;
end;
"-":
begin
NextToken;
Result := -EvalItem;
end;
else
Result := EvalItem;
end;
end;
function TExpressionParser.EvalTerm: double;
var
AToken: char;
n, m : double;
begin
Result := EvalFactor;
n := Result;
if SkipToken("*") then
begin
m := EvalTerm;
Result := Result * m;
end
else
if SkipToken("/") then
begin
m := EvalTerm;
Result := Result / m;
end;
end;
function TExpressionParser.EvalExpr: double;
var
n, m : double;
begin
Result := EvalTerm;
n := Result;
if SkipToken("+") then
begin
m := EvalExpr;
Result := Result + m;
end;
if SkipToken("-") then
begin
m := EvalExpr;
Result := Result - m;
end;
if SkipToken("^") then
begin
m := EvalExpr;
Result := Power(Result, m);
end;
end;
end.
-----
procedure TForm1.Button1Click(Sender: TObject);
var
s : string;
MemStream: TMemoryStream;
ExpressionParser: TExpressionParser;
begin
{ get the string to evaluate }
s := Edit1.Text;
{ создаем поток для работы с памятью, содержащий текст -
TParser может разбирать выражения из потока}
MemStream := TMemoryStream.Create;
try
MemStream.SetSize(Length(s));
MemStream.WriteBuffer(s[1], Length(s));
MemStream.Position := 0;
{ создаем анализатор выражения, используя поток }
ExpressionParser := TExpressionParser.Create(MemStream);
try
Label2.Caption := Format("Результат=%g", [ExpressionParser.EvalExpr]);
finally
ExpressionParser.Free;
end;
finally
MemStream.Free;
end;
end;
← →
Roobee © (2005-01-03 15:16) [1]уважаемые мастера, все еще надеюсь на ответ. (ГОРИТ проект)
плз. выскажитесь!!!
← →
Sandman25 © (2005-01-03 15:22) [2]Я думаю, никто не желает разбираться в логике чужого компонента. Отлаживать чужой код не очень интересно, мягко говоря.
← →
Roobee © (2005-01-03 15:51) [3]сорри, это не чужой компонент...
это стандартный парсер из поставки борланд...
← →
Sandman25 © (2005-01-03 15:52) [4]это стандартный парсер из поставки борланд...
С комментариями на русском языке? :)
← →
Anatoly Podgoretsky © (2005-01-03 15:58) [5]Roobee © (03.01.05 15:51) [3]
Нехорошо обманывать.
← →
roobee © (2005-01-03 15:59) [6]да, сэр...
анализатор взят из дельфи-ворлд 6, но судя по справке,он почти не отличается от предложенного...
но все это не суть важно,
главное то, что парсер в стандартной поставке не желает понимать токен "-" любой другой вместо него понимает а минус не хочет.
вот в чем проблема.
если обладаете знаниями - помогите. очень нужно.
← →
roobee © (2005-01-03 16:02) [7]Анатолию Подгорецкому:
с уважением... в чем обман, уважаемый..
я искал парсер.. нашел.. но он не работает как следует. пытался понять, как работает. Зашел в тупик, спрашиваю у Мастеров. В ЧЕМ ОБМАН?
← →
Anatoly Podgoretsky © (2005-01-03 16:05) [8]В том, что данный код не из Дельфи.
И ты ожидаешь, что кто то будет такой объем кода анализировать и тем более смотреть трассировщиком? Про трассируй сам и укажи неработающую часть.
← →
roobee © (2005-01-03 16:11) [9]отлично сэр.
но, думаю что после того как я найду место возникновения ошибки, я обнаружу и причину.
В любом сучае Вы получите код с четко указанной строкой вызывающей ошибку.
С Уважением.
roobee
← →
roobee © (2005-01-03 16:12) [10]>> такой объем кода...
это объем?!
← →
Anatoly Podgoretsky © (2005-01-03 16:23) [11]А так ты ленивый или хуже, но тогда ты зря сюда пришел.
Это уже заказ работы.
← →
Roobee © (2005-01-03 21:41) [12]Вот код полностью мой. ни у кого не своровал.
и тем не менее, проблема осталась.
-----
unit EvalForm;
{
Ограничения:
все данные в анализируемой строке должны быть
разделены пробелами
Имеем:
строку "5 sin 9.1 6" понимает (с учетом DecimalSeparator)
строку "5 + 9.1 6" понимает
строку "5 -9.1 6" понимает
a строку "5 - 9.1 6" не понимает.
орет что - не является нормальным целым числом
Вопрос - как побороть?
}
interface
uses
Windows, Messages, SysUtils, Variants, Graphics, Controls, Forms,
Dialogs, StdCtrls, Classes;
type
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Button1: TButton;
lb1: TListBox;
lb2: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
s : string;
MemStream: TMemoryStream;
begin
lb1.Clear; lb2.Clear;
s := Edit1.Text;
MemStream := TMemoryStream.Create;
try
MemStream.SetSize(Length(s));
MemStream.WriteBuffer(s[1], Length(s));
MemStream.Position := 0;
with TParser.Create(MemStream) do
try
while Token <> toEOF do
begin
lb2.Items.Add(IntToStr(Ord(Token)));
if Token = toSymbol then
lb1.Items.Add(TokenString);
if Token = toInteger then
lb1.Items.Add(IntToStr(TokenInt));
if Token = toFloat then
lb1.Items.Add(FloatToStr(TokenFloat));
if Token = toString then
lb1.Items.Add(TokenString);
if Token = toWString then
lb1.Items.Add(TokenWideString);
if (Ord(Token) > 4) then
lb1.Items.Add(Token);
NextToken;
end;
finally
Free;
end;
finally
MemStream.Free;
end;
end;
end.
← →
Sandman25 © (2005-01-04 08:56) [13]a строку "5 - 9.1 6" не понимает.
орет что - не является нормальным целым числом
И правильно делает.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.038 c