Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.035 c
1-1104325019
Aleksandr.
2004-12-29 15:56
2005.01.16
Люди, какая версия для Define у Делфи 2005?


3-1102920504
vic1
2004-12-13 09:48
2005.01.16
Динамическое создание-подключение к таблице


1-1104241599
snake_r
2004-12-28 16:46
2005.01.16
Свой хинт для каждого узла дерева


3-1102687806
Apophis
2004-12-10 17:10
2005.01.16
DBGrid - Доступ к столбцу...


1-1103889771
Cosinus
2004-12-24 15:02
2005.01.16
Проблемма с кодировкой





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский