Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Werkzeuge (https://www.delphipraxis.net/63-sonstige-werkzeuge/)
-   -   Regulärer Ausdruck - Unerwartetes Verhalten (https://www.delphipraxis.net/182079-regulaerer-ausdruck-unerwartetes-verhalten.html)

Neutral General 28. Sep 2014 12:46

Regulärer Ausdruck - Unerwartetes Verhalten
 
Hallo,

Heute habe ich mal ein ganz anderes Problem. Wie vielleicht der ein oder andere weiß (oder auch nicht) kann man sich in Notepad++ eine Funktionsliste der gerade geöffneten Quelltextdatei anzeigen lassen.
Das funktioniert standardmäßig allerdings nicht mit .pas Dateien.

Nun gibt es bei Notepad++ eine XML Datei in der man für andere Sprachen reguläre Ausdrücke hinterlegen kann die den Anfang einer function/procedure erkennen.

Erkannt werden sollen aber nur die wirklichen Implementierungen, nicht die Deklaration im interface-Teil, weswegen ich meine RegEx vom Prinzip her so aufgebaut habe. (Sie funktioniert auch soweit gut, aber dazu gleich mehr):

1) "procedure" oder "function" finden
2) Danach ein Bezeichner
3) Ggf. Klammern mit beliebig vielen "Parameter: Typ;" Vorkommen
4) Ggf. ": FunktionsResultTyp"
5) beliebig viele Modifier in der Form "Modifier;"
5.1) Leerzeichen/Zeilenumbrüche
6) "begin" oder "asm" oder "var"/"const"

Der Algorithmus ist auf keinen Fall wasserdicht aber er reicht für meine Zwecke.
Die RegEx dazu:

Code:
1)  ((function|procedure)\b)
2)  [\s]+[\w]+
3)  (\((([\s]*[\w]+[\s]*,?)*:[\s]*[\w]+;?)*\))?
4)  ([\s]*:[\s]*[\w]*)?;
5)  ([\s]*[\w]+;)*
5.1) [\s]*[\n]*
6)  (begin|var|const|asm)\b
Das klappt wie gesagt ganz gut. Folgende einfache Unit (ich habe es mal aufs Minimum runtergeschraubt):

Delphi-Quellcode:
unit cga;

interface

procedure pic_init(slaveIRQ: Byte; IRQStartIndex: Byte);
procedure cga_setattr(color: Cardinal; flags: Byte);

implementation

end.
Dort wird natürlich letztendlich nichts gefunden weil das ja nur die interface-Definitionen der Prozeduren sind. Allerdings braucht Notepad++ und auch einige online RegEx Parser sehr sehr lange (10-20 Sekunden) für das parsen der Datei. Notepad++ hängt sich dabei fast auf.

Es scheint an der Zeile

Delphi-Quellcode:
procedure pic_init(slaveIRQ: Byte; IRQStartIndex: Byte);

zu hängen. Genauer: An den Parametern. Der Prozedurname kann so bleiben. Wenn
ich der Prozedur die Parameter von cga_setattr gebe, dann dauert das parsen < 1 Sekunde.
Habe auch große .pas Dateien mit 20+ Prozeduren inkl. interface Deklarationen die in < 1 Sekunde durchlaufen. Nur diese eine Prozedur macht aus irgendwelchen Gründen Probleme.

Kann mir irgendjemand vielleicht helfen und sagen warum meine RegEx bei dieser Zeile so ins Stolpern kommt?

(regexe.de meldet "Regulärer Ausdruck ist zu tief verschachtelt. Bitte vereinfachen Sie den Ausdruck.")

Dalai 28. Sep 2014 13:21

AW: Regulärer Ausdruck - Unerwartetes Verhalten
 
Müssten nicht die ersten beiden Fragezeichen bei 3) hinter die Klammern? Denn der ganze Ausdruck in den Klammern soll doch optional sein, richtig? Das Fragezeichen macht immer den direkt davorstehenden Ausdruck/Zeichen/Klasse optional - so wie es da steht, also nur das Komma und das Semikolon.

Bzw. genaugenommen können die Fragezeichen komplett weg, denn der Stern macht es ja bereits optional, denn * findet kein oder mehr Vorkommen der/des davorstehenden Klasse/Zeichen/Gruppe. regexe.de ist ohne Fragezeichen jedenfalls zufrieden.

MfG Dalai

Valle 28. Sep 2014 13:31

AW: Regulärer Ausdruck - Unerwartetes Verhalten
 
Zitat:

Zitat von Dalai (Beitrag 1274122)
Müssten nicht die ersten beiden Fragezeichen bei 3) hinter die Klammern?

Nein, denn nur das Komma, bzw. das Semikolon soll optional sein. Das Komma wird nur bei mehrere Parametern des selben Typs gebraucht, das Semikolon trennt mehrere Parameter (wird beim letzten also nicht gebraucht).

Sehr spannend, aber ich habe auch noch keine Idee.

Wenn man den (begin|var|...)-Teil weglässt, funktioniert der Regex übrigens und findet die Deklarationen.

Dalai 28. Sep 2014 14:06

AW: Regulärer Ausdruck - Unerwartetes Verhalten
 
Zitat:

Zitat von Valle (Beitrag 1274123)
Zitat:

Zitat von Dalai (Beitrag 1274122)
Müssten nicht die ersten beiden Fragezeichen bei 3) hinter die Klammern?

Nein, denn nur das Komma, bzw. das Semikolon soll optional sein. Das Komma wird nur bei mehrere Parametern des selben Typs gebraucht, das Semikolon trennt mehrere Parameter (wird beim letzten also nicht gebraucht).

Ah, du hast ja sowas von recht. Daran hab ich gar nicht gedacht. Nett, was der Compiler alles kann (letztlich steckt in diesem ja ebenfalls ein RegEx-Parser).

Andere Möglichkeit: bei 3) die Sternchen nach den Klammern in Fragezeichen umwandeln, also so
Code:
(\((([\s]*[\w]+[\s]*,?)?:[\s]*[\w]+;?)?\))?
Funktioniert auf regexe.de ohne zu tiefe Verschachtelung.

MfG Dalai

Neutral General 28. Sep 2014 14:27

AW: Regulärer Ausdruck - Unerwartetes Verhalten
 
@Valle: Der begin/var Teil SOLL ja da sein. Es ist schon richtig dass er die Interface-Deklarationen nicht findet. Er soll nur die Implementierungen der Funktionen finden ;)
@Dalai: Die Sternchen brauche ich sonst können die proceduren nur einen Parameter haben und mehrere Parameter vom selben Typ kommagetrennt geht dann auch nicht mehr.

Habe neue Informationen:

1. Umso mehr Großbuchstaben in den Parameterbezeichnungen enthalten sind desto länger dauert es :gruebel:

2. Wenn ich das erste [\s]* im Parameterausdruck weglasse (3) dann geht das ganze (auch mit Großbuchstaben ruckzuck. Natürlich findet er dann keine Funktionen mehr wo Leerzeichen vor dem Parameternamen sind. :gruebel:

Ich sehe aber irgendwie nicht den Zusammenhang bzw. die Gründe dafür.

Falls ihr Lust habt könnt ihr mit der RegEx auf regexe.de selbst mal rumspielen.
Nochmal die gesamte RegEx in einem Stück:

Code:
((function|procedure)\b)[\s]+[\w]+(\((([\s]*[\w]+[\s]*,?)*:[\s]*[\w]+;?)*\))?([\s]*:[\s]*[\w]*)?;([\s]*[\w]+;)*[\s]*[\n]*(begin|var|const|asm)\b

Valle 28. Sep 2014 15:47

AW: Regulärer Ausdruck - Unerwartetes Verhalten
 
Zitat:

Zitat von Neutral General (Beitrag 1274127)
@Valle: Der begin/var Teil SOLL ja da sein. Es ist schon richtig dass er die Interface-Deklarationen nicht findet. Er soll nur die Implementierungen der Funktionen finden ;)

Das ist mir schon klar. :stupid:

War so eine Info wie dein 2. aus deinem letzten Post. ;-)

Ich vermute mittlerweile irgendwie, dass du einen Bug in der entsprechenden Library gefunden hast. Hast du mal untersucht, inwiefern dieses Verhalten mit unterschiedlichen Platformen und Implementationen zusammenhängt?

Dalai 28. Sep 2014 16:27

AW: Regulärer Ausdruck - Unerwartetes Verhalten
 
Mal ein bisschen vereinfacht:
Code:
((function|procedure)\b)[\s]+[\w]+(\(.*\))?([\s]*:[\s]*[\w]*)?;([\s]*[\w]+;)*[\s]*[\n]*(begin|var|const|asm)\b
Denn was innerhalb der Klammern nach dem Funktionsnamen steht, ist eigentlich egal. Warum das bei regexe.de allerdings auch auf den Deklarationsteil match, weiß ich nicht, bei www.regexr.com funktioniert's.

[EDIT] regexe.de erfasst die Deklaration, wenn die Option "Punkt erfasst auch Umbrüche" aktiviert ist. Schaltet man diese aus, matcht die Seite dasselbe wie regexr.com [EDIT]

MfG Dalai

Neutral General 28. Sep 2014 16:48

AW: Regulärer Ausdruck - Unerwartetes Verhalten
 
@Dalai: Deine RegEx funktioniert bei mir nicht gut aber ich habs etwas umgebaut und jetzt funktionierts super. Du hast Recht: Es interessiert eigentlich nicht was in der Klammer steht.

Aber ein "." ist scheinbar zu viel des Guten. Benutze statt dem . jetzt [\w\s:,;]* und damit scheints gut zu funktionieren. Das müssten ja soweit alle Zeichen sein die normalerweise auftauchen könnten oder? ansonsten wird das da noch hinzugefügt.

Auf jeden Fall jetzt schonmal Danke an euch beide! :)

Warum mein ursprünglicher Ausdruck so Probleme gemacht hat weiß ich zwar immer noch nicht so genau (vllt. ist es wirklich ein Fehler?) aber solange es jetzt klappt :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:35 Uhr.

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