Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.01.16;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.029 c
8-1096434448
_Дельфин_
2004-09-29 09:07
2005.01.16
Как проиграть видео-файл?


9-1096091575
4МО
2004-09-25 09:52
2005.01.16
Игра типа Contra(Dendy)


3-1102706621
sloug
2004-12-10 22:23
2005.01.16
Выделение записи в таблице


6-1099153246
eRoR_rrr
2004-10-30 20:20
2005.01.16
IRC


8-1097394748
X-Disa
2004-10-10 11:52
2005.01.16
Grayscale > X-Scale