Autor Beitrag
immortuus
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 25.07.05 20:44 
volgender textdatei ist gegeben (lade diese in eine Stringliste):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
funktion1(1,true);
{
y := z;
{
showmessage('hallo');
x := 'ist egal';
}

}
for i := 0 to 12 do 
begin
  funktion5(1,'lala');
end;
{
showmessage('noch einer');
x := machwas;
}


das ganze ist delphi syntax. ich habe aber eine eigene "scriptsprache" gebaut. ich suche nun den elegantesten weg die komentare aus der datei zu entfernen.

und bitte nicht mit irgendwelchen tolls oder regex... ich will es selber schreiben nur mit delphi boardmitteln

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Mo 25.07.05 21:34 
Hallo und :welcome: im DF.
Das sollte eigentlich kein Problem sein. Du ziehst dir den gesamten Inhalt in einen String (z.B. Memo1.Lines.Text) und löscht dann alles zwischen { und } raus. Ich habe gerade kein Delphi zur Hand, aber es sollte mittels Suche in: Delphi-Forum, Delphi-Library "WHILE" und Suche in: Delphi-Forum, Delphi-Library "POS" und Suche in: Delphi-Forum, Delphi-Library "DELETE" gehen. Ich schreib nachher nochmal was, falls mir keiner zuvorkommt ;)

Gruß,
maxk

PS: Bitte benutze demnächst die Delphitags für Sourcecodeausschnitte (auch wenn es abgewandelter ist).

// Edit: Folgender Schnipsel entfernt die Kommentare, wenn die Klammern aufgehen. Falls die doppelte Zeile (7+8) kein Versehen ist, muss du allerdings daran noch ein wenig rumpfeilen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
function RemoveComments(const Str:string):string;
var p1,p2:integer;
begin
 Result:=Str;
 while pos('{',Result)<pos('}',Result) do begin
  p1:=pos('{',Result);
  p2:=pos('}',Result);

  Delete(Result,p1,p2-p1+1);
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 with Memo1.Lines do Text:=RemoveComments(Text);
end;

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
immortuus Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 26.07.05 00:06 
keine schlechte idee. aber leider kommt danach das raus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
funktion1(1,true);   
   
}   
for i := 0 to 12 do    
begin   
  funktion5(1,'lala');   
end;   
{   
showmessage('noch einer'); 
  
x := machwas;   
}


ich habe mir mal gedanken gemacht. ich überlege ob man dan nicht mit einer rekusiven funktion machen kann die wenn die letzte { in einem verschachtelten aufbau erschein rumdreht und beim zurückgehen alles bis } löscht. das währe dan für jeden komentar block einzeln

ps. zeile 7 und 8 sind kein versehen. darum geht es ja gerade ;-)
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Di 26.07.05 00:21 
Ist jetzt wahrscheinlich nicht so sauber geschrieben, aber ich schlaf schon fast ;)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function RemoveComments(Str:string):string;
var p1,p2:integer;
begin
 Result:='';
 while length(Str)>0 do begin
  p1:=pos('{',Str);

  if p1>0 then begin
   Result:=Result+copy(Str,1,p1-1);
   Delete(Str,1,p1-1);
  end else begin
   Result:=Result+Str;
   Str:='';
  end;

  p2:=pos('}',Str);
  if p2>0 then Delete(Str,1,p2);
 end;
end;


Gruß,
maxk

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
sahib
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117

Win 2000 SP4+
Delphi 5 Prof.
BeitragVerfasst: Di 26.07.05 01:30 
Hi.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function EntferneKommentare(s: String): String;
var
  KlammerZaehler: Word;
  i             : LongWord;
begin
  KlammerZaehler := 0;
  for i := Length(s) downto 1 do begin
    if s[i] = '}' then
      inc(KlammerZaehler)
    else
    if s[i] = '{' then
      dec(KlammerZaehler);

    if (KlammerZaehler > 0or (s[i] = '{'then
      Delete(s, i, 1)
  end;
  Result := s
end;


*EDIT*: Result-Zeile vergessen...

Viele Grüße,
Christian


Zuletzt bearbeitet von sahib am Di 26.07.05 01:37, insgesamt 1-mal bearbeitet
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 26.07.05 01:34 
Das Löschen der Kommenare über einzelzeichen würde ich so nicht realisieren (jedes Zeichen einzeln aus einem Kommentar löschen), da bei jedem Löschvorgang ein komplett neuer String angelegt wird, was besonders bei langen Eingabe-Strings zu extremen Problemen führen kann.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Di 26.07.05 01:36 
Verblüffent einfach :lol: Allerdings könnte ich mir vorstellen, dass das länger dauert, als mit Copy zu arbeiten, da du ja wirklich jedes Zeichen einzeln durchgehen musst. Da ich aber nur eine PE Version habe, weiss ich auch nicht wirklich, wie Copy&Delete intern arbeiten :(

Problem übrigens:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
{
1
{
2
}

1
}
Was davon gehighlighted ist, sieht Delphi selber nichtmehr als Kommentar.

Gruß,
maxk

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 26.07.05 01:42 
Jup. Zum einen Das, zum anderen folgender Source:

Str := '{Hallo}'; würden bisher beide Sources als Kommentar sehen und daher löschen.

Für das Kommentar-Handling von Delphi ist die erste Version richtig, für verschachtelte die zweite, für syntaktisch korrektes Entfernen der Kommentare in meinem Beispiel-Source keiner von beiden.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
sahib
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117

Win 2000 SP4+
Delphi 5 Prof.
BeitragVerfasst: Di 26.07.05 01:43 
Mit der Kopie des Strings stimmt natürlich. Allerdings würde ich eine solche Datei eh in einen MemoryStream laden und dort die Daten manipulieren.

Ein zu Bett gehender Christian
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Di 26.07.05 01:57 
So, damit sollte alles berücksichtig sein:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
function RemoveComment(Str:string):string;
const SD = '''';
var pS,pC:integer;
begin
 Result:='';
 while length(Str)>0 do begin
  pC:=pos('{',Str);
  if pC=0 then begin
   // Nothing to do
   Result:=Result+Str;
   Str:='';
  end else begin
   pS:=pos(SD,Str);
   if (pS<pC) and (pS<>0then begin
    // String
    Result:=Result+copy(Str,1,pS);
    Delete(Str,1,pS);
    pS:=pos(SD,Str);
    if pS>0 then begin
     Result:=Result+copy(Str,1,pS);
     Delete(Str,1,pS);
    end else begin
     raise Exception.Create('Unterminated string');
    end;
   end else begin
    // Comment
    Result:=Result+copy(Str,1,pC-1);
    Delete(Str,1,pC);
    pC:=pos('}',Str);
    if pC>0 then begin
     Delete(Str,1,pC);
    end else begin
     raise Exception.Create('Unexpected end of content in comment');
    end;
   end;
  end;
 end;
end;


Gruß,
maxk

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
sahib
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117

Win 2000 SP4+
Delphi 5 Prof.
BeitragVerfasst: Di 26.07.05 13:50 
So, in der Mittagspause habe ich auch noch ein wenig gefummelt ;)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
function EntferneKommentar(s: String): String;
var
  cnt, i, j       : LongWord;
  NichtImKommentar: Boolean;
begin
  if s = '' then Exit;
  i := 1; cnt := 0;
  NichtImKommentar := True;
  while i < Length(s) do begin
    if NichtImKommentar then
      NichtImKommentar := s[i] <> #39  // Hochkomma
    else
    if not NichtImKommentar then
      NichtImKommentar := s[i] = #39;

    if NichtImKommentar and (s[i] = '{'then begin
      j := i; inc(cnt);
      while (j < Length(s)) and (cnt > 0do begin
        inc(j);
        if s[j] = '{' then inc(cnt) else
        if s[j] = '}' then dec(cnt)
      end;
      if s[j] <> '}' then
        raise Exception.Create('Abschliessende Klammer fehlt.');
      Delete(s, i, j - i + 1)
    end;
    inc(i)
  end;
  Result := s
end;


Ich habe gerade mal für beide Funktionen die Zeit gemessen (gleicher Datensatz: 6.2MB):
EntferneKommentar: 538 ms (der Speicherverbrauch ist auch deutlich geringer)
RemoveComment : 21860 ms

Und wenn man das dann noch über einen MemoryStream macht und nur die Pointer bewegt, dürfte das noch etwas schneller werden?

Das macht ja richtig spaß ;) Und Benny, Deine Meinung als Profi ist mir natürlich auch wichtig, wegen Stil, Anwendbarkeit etc. Du siehst das doch immer mit anderen Augen. Ich ziele immer auf Spezialfälle ab, und mache die schnell und mit wenig Speichernutzung.

Viele Grüße,
Christian
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Di 26.07.05 14:30 
user profile iconsahib hat folgendes geschrieben:
Ich habe gerade mal für beide Funktionen die Zeit gemessen (gleicher Datensatz: 6.2MB):
EntferneKommentar: 538 ms (der Speicherverbrauch ist auch deutlich geringer)
RemoveComment : 21860 ms
Angeber :tongue:

Dass der Speicherverbrauch bei deiner Methode etwa halb so groß ist, ist logisch. Aber dass sie auch schneller ist, hätte ich nicht gedacht (glaub ich dir aber). Wobei mich interessieren würde, warum das so ist? Wie arbeiten pos, copy und delete den intern? Trotzdem Respekt!

Gruß,
maxk

_________________
Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 26.07.05 15:18 
user profile iconmaxk hat folgendes geschrieben:
user profile iconsahib hat folgendes geschrieben:
Ich habe gerade mal für beide Funktionen die Zeit gemessen (gleicher Datensatz: 6.2MB):
EntferneKommentar: 538 ms (der Speicherverbrauch ist auch deutlich geringer)
RemoveComment : 21860 ms
Angeber :tongue:

Dass der Speicherverbrauch bei deiner Methode etwa halb so groß ist, ist logisch. Aber dass sie auch schneller ist, hätte ich nicht gedacht (glaub ich dir aber). Wobei mich interessieren würde, warum das so ist? Wie arbeiten pos, copy und delete den intern?

Das liegt unter anderem an Pos, das geht ja auch zeichenweise durch (statt den schnelleren Boyer-Moore-Algorithmus zu benutzen).
Damit konnte ich bei einer Umsetzung in Assembler bei größeren Pattern das Pos nochmal deutlich schneller machen.

Mit BM werden die Zeichen abhängig vom gesuchten Text übersprungen, die mit dem letzten Vergleich sowieso nicht in Frage kommen. (Kann ich auch gerne noch genauer erklären :wink: )
sahib
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117

Win 2000 SP4+
Delphi 5 Prof.
BeitragVerfasst: Di 26.07.05 19:09 
Hallo Sebastian.

user profile iconjaenicke hat folgendes geschrieben:
Das liegt unter anderem an Pos, das geht ja auch zeichenweise durch (statt den schnelleren Boyer-Moore-Algorithmus zu benutzen).
Damit konnte ich bei einer Umsetzung in Assembler bei größeren Pattern das Pos nochmal deutlich schneller machen.


Boyer-Moore (BM) ist in diesem speziellen Falle allerdings völlig unangebracht. Wie Dir aufgefallen ist, hat die zu suchende Zeichenkette die Länge eins, nämlich '{'. Und da ist BM langsamer. Ohne Zweifel ist er natürlich überlegen, wenn die Suchworte länger sind.

Warum mein Code schneller ist? Zum einen habe ich nur einen Prozeduraufruf (Delete) und zum anderen kopiere ich nichts hin und her (ok, delete dürfte das machen). Aber selbst diese aufgerufene Prozedur könnte noch durch einen einfachen Move-Befehl ersetzt werden können. Kurz vor der Ergebnisübergabe müsste das nur noch die neue Zeichenkettenlänge mit SetLength neu gesetzt werden.

Christian
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 27.07.05 16:47 
Ok, du hast recht, in diesem Fall bringt Boyer Moore nix, bzw. ist durch die kompliziertere Umsetzung sogar deutlich langsamer. (Wohl auch der Grund, der Borland dazu veranlasst hat, die Standard-Methode zu benutzen)

Was ich damit ausdrücken wollte war auch nur, dass die internen Routinen von Borland nicht unbedingt auf absolute Geschwindigkeit optimiert sind, bzw. das auch nicht sein können, weil sie ja das restliche Programm nicht kennen.