Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi SQL-Datei parsen und Comments löschen (https://www.delphipraxis.net/42141-sql-datei-parsen-und-comments-loeschen.html)

static_cast 14. Mär 2005 14:20


SQL-Datei parsen und Comments löschen
 
Hallo,

ich bin gerade dabei eine Umgebung zu basteln zum entwickeln von MSSQL proceduren. Nun bin ich dabei den Parser zu bauen der zuerst mal zum internen arbeiten alle Comments durch Spaces ersetzt.

Das ist meine Aktuelle Parser procedure (z.Z. und zum Testen ersetzt sie Strings durch $ und comments durch ?):
Delphi-Quellcode:
procedure Parse;
var
  Line:String;
  Y,X,Z,Token,Flag:Integer;
begin

  FScanBuffer.Clear;
  FScanBuffer.Assign(FEditBuffer);

  Flag:=0;
  for Y:=0 to FScanBuffer.Count-1 do
  begin
    Line:=FScanBuffer[Y];

    for X:=1 to Length(Line) do
    begin

      Token:=0;

      if Copy(Line,X,1) = #039 then Token:=1 else
      if Copy(Line,X,2) = '/*' then Token:=2 else
      if Copy(Line,X,2) = '--' then Token:=3 else
      if Copy(Line,X,2) = '*/' then Token:=4;

      case Token of
         1: begin
              if (Flag <> 2) AND (Flag <> 3) then
                if Flag = 1 then Flag:=5 else Flag:=1;
            end;
         2: begin
              if Flag <> 1 then
                Flag:=2;
            end;
         3: begin
              if (Flag <> 1) AND (Flag <> 2) then
                Flag:=3;
            end;
         4: begin
              if Flag = 2then
                Flag:=4;
            end;
      end;

      case Flag of
         1: begin
              Line[X]:='$';
            end;
         2: begin
              Line[X]:='?';
            end;
         3: begin
              Flag:=0;
              for Z:=X to Length(Line) do Line[Z]:='?';
            end;
         4: begin
              Flag:=0;
              for Z:=X to X+2 do Line[Z]:='?';
            end;
         5: begin
              Flag:=0;
              Line[X]:='$';
            end;
      end;
    end;

    FScanBuffer[Y]:=Line;
  end;

  FScanBuffer.SaveToFile('C:\test.txt');
end;
Zum testen habe ich diesen Codeschnipsel erstellt:
SQL-Code:
/*
   -->
   comment
   block
   <--
*/

SET @Tmp = '/* -- Test -- */' /* comment */ ; -- comment

-- test comment

SET @Tmp = '<-->';

-- comment's & comment's /*

SET @Tmp = '*//*';

-- */
Und es kommt auch wie erwartet das als Ergebnis raus:
Code:
??
??????
??????????
????????
??????
??

SET @Tmp = $$$$$$$$$$$$$$$$$$ ??????????????; ??????????

???????????????

SET @Tmp = $$$$$$;

???????????????????????????

SET @Tmp = $$$$$$;

?????
Nur mein Problem ist das das ganze bei großen Dateien sehr inperformant wird, hatte auch schon mehrere Versuche mit dem Parser das ist jetzt der Xte der auch wohl so funzt wie er soll nur sehr langsam.

Deswegen hoffe ich auch euch, das wer eine bessere Idee hat jenes zu lösen, den ich hab keine mehr :(

Grüße,
Daniel

P.s.: Das ist mein erster Parser dieser größe den ich entwickle deswegen stelle ich mich wohl zu blöd an ;)

bttb930 14. Mär 2005 14:25

Re: SQL-Datei parsen und Comments löschen
 
Hin- und herkopieren von Strings ist immer sehr zeitintensiv.

Versuche das Kopieren von Strings wann immer es geht zu vermeiden.

Du hast doch am Anfang den String - lese Zeichen für Zeichen und lass Befehle wie Line := Buffer[y] weg.

static_cast 14. Mär 2005 14:36

Re: SQL-Datei parsen und Comments löschen
 
Hi bttb930,

also die Zeile aus der String Liste in Line zu übertragen ist denke ich mal das kleinste Übel daran liegt es nicht!

Alles was zwischen Line:=FScanBuffer[Y]; und FScanBuffer[Y]:=Line; steht ist das Zeitaufwendige.

bttb930 14. Mär 2005 14:53

Re: SQL-Datei parsen und Comments löschen
 
wir haben hier ein tool mit dem man geschwindigkeitsanalysen machen kann. schick doch mal den quellcode und eine demodatei und ich jag das mal durch. dann sieht man welche zeile wie lange braucht.

bttb930 14. Mär 2005 15:01

Re: SQL-Datei parsen und Comments löschen
 
aber ich habs mir nochmal angesehen - ich wette mit dir, dass das zeitaufwändige das hin- und herkopieren des strings ist. garantiert!

static_cast 14. Mär 2005 15:27

Re: SQL-Datei parsen und Comments löschen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab mal schnell eine Test-Anwendung zusammen geschustert, kannst ja mal schaun.

shmia 14. Mär 2005 15:38

Re: SQL-Datei parsen und Comments löschen
 
Also ein Hauptfehler deiner Procedure Parse scheint mir der fehlende Übergabeparamter zu sein.
==> nicht wiederverwendbar.

hier mal meine Version zum "Putzen" von SQL-Anweisungen.
(kann zwar nur einzeilige Kommentare entfernen, ist aber recht schnell)
Delphi-Quellcode:
{**************************************************************************
 * NAME:   CleanSqlStrings
 * DESC:   entferne Kommentarzeilen aus TStrings
 * PARAMS: [-]
 * CREATED: 28-08-2003/shmia
 *************************************************************************}
procedure CleanSqlStrings(SQL:TStrings);
var
   s : string;
   i : Integer;
begin
   Assert(Assigned(SQL));

   for i := SQL.Count-1 downto 0 do
   begin
      s := SQL[i];
      if Length(s) >= 2 then
      begin
         SetLength(s, 2);
         if (s = '--') or (s='//') then
            // Kommentarzeile entfernen
            SQL.Delete(i);
      end;
   end;
end;

bttb930 14. Mär 2005 15:51

Re: SQL-Datei parsen und Comments löschen
 
Liste der Anhänge anzeigen (Anzahl: 1)
okay, hier das ergebnis:

Die Zeile Memo2.Lines.Assign(FScanBuffer); benötigt 89,9% der Laufzeit.

FScanBuffer.Assign(Memo1.Lines); benötigt noch 6,90%.

Ich habe den Memo-Inhalt dazu auf ca. 6000 Zeilen erweitert.

Siehe Bild.

static_cast 14. Mär 2005 15:55

Re: SQL-Datei parsen und Comments löschen
 
@shmia
Das soll jetzt nicht böse klingen oder so aber das hat so gar nichts mit meinem Problem zu tun, bei mir geht es nicht um SQL Anweisungen sondern um MSSQL Stored Procedures. Nebenbei würde deine Procedure mir eine ganze Zeile rauskanten wenn dort ein Single-Line-Comment drin ist (so wie ich das verstehe nur wenn es am Anfang ist, was es ja nicht immer tut) ;)

Und wozu soll ich meinem Parse ein Parameter übergeben? Das ist doch gar nicht von nöten, da es normalerweise in einer klasse steckt, schau dir mal bitte die Test-Anwendung an, bze den Source davon!

Programmiertechnisch ist das kein Problem sondern eher eines auf der Logischen Ebene den Source durch zu Parsen ;)

static_cast 14. Mär 2005 16:08

Re: SQL-Datei parsen und Comments löschen
 
@bttb930
Hmm okay... stimmt ich hab mal

Memo2.Lines.Assign(FScanBuffer); duch Memo2.Text:=FScanBuffer.Text; getauscht geht etwas fixer aber irgendwie immer noch zu ruckelig... Es muss doch auch irgendwie Professioneller gehen so einen Parser zu schreiben, ich hab beim dem irgendwie so das Gefühl das der so... so klapperich und zu klobig ist, naja wie gesagt ich habe so etwas noch nie in der Form Programmiert, eher immer statische Parser.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:10 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz