Beiträge von BugFix

    Hm, recursiv... ist das denn nicht eher ein iteratives Durchsuchen?

    - Öffne Datei-1

    - Finde Include1 - Öffne dieses (Sub)Include und finde dort ein weiteres Include usw. usf.

    - Finde Include2- Öffne dieses (Sub)Include ......


    Das ist m.M. ein rekursives Vorgehen (auf das, was ich gefunden habe, erneut mit demselben Verfahren zugreifen)

    In dem Bsp. im obigen Post habe ich die Funktion BalancedPairs, die ich schon mal als Einzelfunktion erstellt hatte, aufgesplittet in Einzelfunktionen. Die Einzelfunktion hatte sich nach jedem Fund selbst aufgerufen um weiterzusuchen (eindeutig rekursiv). In der neuen Version ist das Vorgehen aufgesplittet. Somit eher keine Rekursion.


    Ich bin mir nicht ganz sicher was genau du versuchst

    Im Moment sammele ich erstmal Lösungsansätze. Ich habe zwei Baustellen (GetUnsusedVars, ManageIncludes), die beide auf derselben Basis arbeiten (sollen) --> On-The-Fly müssen Dateien und Includes (und Includes in Includes..) durchsucht werden.

    Ich werde sehr wahrscheinlich den zeitintensiven Part auslagern (Nim). Aber das steckt alles noch am Anfang, wobei das Vorgehen selbst von der Sprache unabhängig ist.


    Einen eierlegenden RegEx zu finden halte ich für eine sehr schlechte Idee, das Ding zu parsen für sinnvoller.

    Die eierlegende Wollmilchsau zu finden war auch eher scherzhaft gemeint. Aber RegEx wird für einzelne Prüfungen/Selektionen sicher dabei sein.


    Wenn du es als Subpattern schreibst wird es auch deutlich übersichtlicher:

    Ich habe jetzt mal einige Pattern aus meiner Patternsammlung umgeschrieben in Subpattern-Definition. Ich muss sagen: Wenn man das 2..3 mal gemacht hat, wird das Erstellen von RegEx-Pattern geradezu ein Kinderspiel.

    Durch die Definition werden die Pattern viel besser lesbar und verständlich (vor allem wenn man später mal wieder in den Code schaut). Auch ein Plus, wenn mal jemand anders da reinguckt. Ist zwar etwas mehr Schreibaufwand, aber aufgrund des Benefits auf jeden Fall gerechtfertigt.



    Auf jeden Fall schon mal vielen Dank für euer Interesse und eure Anregungen.


    EDIT:

    Was mir beim Schreiben der Definitionen mal wieder aufgefallen ist: In AutoIt fehlt ganz klar der MultiLine-String. In Lua: [[ multiline ]], in einigen anderen Sprachen: """ multiline """, und in AutoIt wurde der FeatureRequest dazu mit wenig Interesse behandelt und abgelehnt. :thumbdown:

    Oscar

    Nach dieser Methode habe ich auch meine "Balanced Pairs" erstellt. Da ich damit jedoch den String rekursiv durchforstet habe, führte das mit Stringbegrenzern nicht zu sinnvollen Ergebnissen.


    AspirinJunkie

    Die Subpattern Definition sieht schon mal super aus. :thumbup:

    Das Pattern zum Kommentare killen muss ich mal auf meine Skripte loslassen. Meines war etwa halb so lang und hatte ein paar mögliche Fehlerkennungen. :whistling:

    Kommentare muss ich eh entfernen. Im zweiten Schritt werden alle Zeilenfortschreibungen aufgehoben und dann kann ich mit meinem eigentlichen Parsen beginnen.


    Danke erst mal für eure Ideen.

    Wenn ich es mit meinem Projekt verheiratet habe, gibt es das natürlich hier im Forum.

    PapaPeter

    Dein letzter Post war 4:20 Uhr ?! - Und was machst du tagsüber? :rofl:


    Danke für deine Gedanken und das Hilfsangebot.

    Momentan erledige ich erstmal einiges "drumherum". Da ich die ManageIncludes endlich fertigstellen will schreibe ich mir erst mal externe Parser, in der Hoffnung dann auf das Abspeichern von Funktionen/Konstanten etc. verzichten zu können und tatsächlich On-The-Fly zu arbeiten. Mal sehen ob das performancemäßig möglich ist. Wird evtl. davon abhängen, wie ich IPC hier umsetzen kann.

    Ggf. werde ich dann auf dein Angebot zurückkommen.


    Und jetzt geh erst mal schlafen. :P

    Ich möchte mal etwas Brainstorming mit euch betreiben.


    Ziel: Ausbalanzierte Stringsequenzen in (auch geschachtelten) Strings erkennen.

    Mir geht es darum, in Programmzeilen, die aus der au3 Datei gelesen werden, die Stringbereiche eindeutig zuordnen zu können.

    Im Editor selbst ist die Zuordnung recht unproblematisch, da dort jeder Position auch der Style zugeordnet ist (editor.StyleAt[pos]).

    Wenn ich z.B. folgende fiktive Programmzeile habe:

    _SomeFunc($param1, '"', ';', "'", $param5, "text, text, text", '"') ; Kommentar, hat auch "string"


    Hier zeigen sich auch schon Probleme:

    - kann nicht als Parametertrenner gelesen werden, da evtl. auch Bestandteil von Parametern oder Kommentar

    - " kann selbst ein Parameter sein, aber auch Stringbegrenzer (oder auch zum Maskieren von sich selbst im String)

    - Stringbegrenzer als oder erleichtern es auch nicht unbedingt und das Bsp. kann man natürlich noch unberechenbarer gestalten.


    Wahrscheinlich bleibt hier nur die Lösung, wie sie vermutlich auch vom Interpreter durchgeführt wird: Regex mit Subpattern-Definitionen, sieht z.B. so aus:

    Wobei ich (obwohl ich Regex mag) hier mit der PCRE-Syntax etwas fremdele. Ich habe vor längerer Zeit mal mit Oniguruma gearbeitet, ist zwar ähnlich (alle Regex Dialekte ähneln sich irgendwo) - aber lag mir mehr. Naja, das ist aber nur Gewohnheitssache.


    Im obigen Bsp. habe ich einen Funktionsaufruf, dadurch lässt sich der Kommentar sauber abtrennen. Habe ich aber Variablenzuweisungen mit Text (der enthält) wird es schon wieder unangenehmer und die ausbalanzierte Erkennung des Strings ist zwingend notwendig.


    Also Lösungsvariante #1 ist, dass ich mir das Eierlegende-Wollmilchsau-Regex-Pattern bastele. :rofl:

    Wenn ihr ein paar Gedanken beibringen möchtet, bin ich sicher nicht böse. :whistling:

    Kann man immer brauchen, Paare (auch verschachtelt) mit den Begrenzern "< >  [ ]  { }  ( )" lassen sich so sauber auslesen. Es wird nur das öffnende Zeichen übergeben:

    Standardmäßig ist in Nim kein Ternärer Operator implementiert. Ich habe dazu etwas gefunden:

    ":" lässt sich nicht überladen, deshalb "!". "a" und "b" müssen selbstverständlich vom selben Typ sein.

    Kommandozeilenaufrufe in Nim erlauben eine genaue Spezifikation der Parameter (Short, Long, Argument) .

    Für die Auswertung gibt es fertige Funktionen.

    Doku: parseopt

    Das da wäre die beste Lösung, da Windows deinem Skript bescheid gibt, wenn sich in einem bestimmten Pfad was tun sollte,

    Zitat von _WinAPI_ShellChangeNotifyRegister

    Registers a window to receive notifications from the file system or Shell

    Kann man dann aber nur anwenden, wenn man eine Anwendung mit GUI laufen hat, was für Überwachungsskripte eher nicht der Fall ist. Ich habe bei mir ein Skript laufen, das alle 5 Sekunden in einem Ordner schaut, ob eine neue PDF abgelegt wurde. Diese wird dann nach bestimmten Kriterien umbenannt und an eine andere Anwendung weitergereicht. Dafür existiert selbstredend keine grafische Oberfläche.

    Ich vermute mal, bei HansJ54 sieht das ähnlich aus.

    Ach das ist so etwas wie ein If ... then ... elseif ... elseif?

    Das ist ein Ternärer Operator, hier mehrfach verschachtelt. Wirkt wie If-Then-Else, wobei Else immer belegt sein muss. Wenn man es untereinander schreibt, wird es deutlich:

    AutoIt
    $sTCPErrorText = _ ; Zuweisung
    (@error = -2) ? 'not connected' : _ ; wie: If-Then
    (@error = 1) ? 'IPAddr is incorrect' : _ ; wie: ElseIf-Then
    (@error = 2) ? 'Port is incorrect' : _ ; wie: ElseIf-Then
    (@error = 10060) ? 'Connection timed out' : _ ; wie: ElseIf-Then
    'Unknown error' ; wie: Else

    wie gut sieht es mit der geplanten Nutzung von Variablendeklarationen in Include Dateien aus?

    Kennst du vielleicht: Bei der Entwicklung des Skriptes fällt dir auf, dass sich noch ein ständig wachsender Haufen an Folgemaßnahmen erforderlich macht und dann schiebst du das erst mal vor dir her. :whistling: Ein wesentlicher Punkt (der mich auch bei meinem ManageIncludes gebremst hat) ist eine Routine zum rekursiven Auslesen/Vergleichen der Includes. Da habe ich schon etliche Ansätze probiert aber noch nichts (geschwindigkeitsmäßig) zufriedenstellendes gefunden. Dadurch dass viele Includes Querverweise auf andere Includes haben, landet man da schnell in einem InfinityLoop. <X

    Ich werde vermutlich das Parsen der Includes in ein externes (Nicht-AutoIt) Programm auslagern, das mit der notwendigen Geschwindigkeit arbeitet.

    Bei dem Projekt sind die Variablen nicht in der Hauptroutine deklariert, sondern die Dekalaration erfolgt über eine include Datei die die Variablendeklaration enthält. Um es noch komplizierter zu machen, gibt es für die Internationalisierung der GUI auch Include-dateien in zweiter Schachtelungsebene

    He, da ticken wir ähnlich. ;)

    In meinen (größeren) Projekten baue ich das so auf:

    - Mainskript (meist nur ein paar Zeilen: Includes, Initialisierungsaufrufe(Variablen, GUI), Mainloop)

    - getrennte Includes: Variablendeklaration, Variableninitialisierung, GUI-Erstellung, GUI-Funktionen, Programmfunktionen

    Aber ich halte das alles in einer Ebene.


    Bei derartigen Konstrukten ist das Problem, dass ein Include auf Variablen zugreift, welche in einem anderen Include deklariert sind, aber dieses Include noch nicht geparst wurde.

    Hier die richtigen Abhängigkeiten zu finden ist nicht ohne. Eigentlich müsste man dasselbe tun, wie der Interpreter: Alle Includes in einen gemeinsamen Kontext zusammenführen und dann parsen.

    Aber, wie schon oben beschrieben, wird eine Lösung für ManageIncludes auch hier ein bessere Umsetzung ermöglichen.

    wohin muss die GetUnusedVars.au3 kopiert werden

    $(SciteDefaultHome) ist das Installationsverzeichnis von SciTE. Das würde ich nicht zum Speichern eigener Anwendungen empfehlen. Verwende besser einen Ordner im Bereich USER, indem du Skripte (au3 und lua) für SciTE ablegst. Z.B. C:\Users\USER\MySciTE.

    Am Besten speicherst du diesen Pfad in der SciTEUser.properties (SciTE-Optionen-Benutzereinstellungen) als:

    User.Scripts.Path=C:\Users\USER\MySciTE

    Dann kannst du später in den SciTE.properties auf den Pfad immer zugreifen in der Form $(User.Scripts.Path).


    In deinem Fall also entweder:

    command.39.*.au3="$(autoit3dir)\autoit3.exe" "C:\Users\USER\MySciTE\GetUnusedVars.au3" "$(FilePath)" "1" "0"

    oder:

    command.39.*.au3="$(autoit3dir)\autoit3.exe" "$(User.Scripts.Path)\GetUnusedVars.au3" "$(FilePath)" "1" "0"

    Vorschlag für folgende Funktion:

    Ich habe mich jetzt mal etwas intensiver in das Thema eingelesen. Das Thema ist schon sehr vielfältig. Ich habe jetzt mal ein einfach zu handhabendes Szenario als Bsp. erstellt.

    Grundsätzlich gibt es ja 2 Möglichkeiten:

    a) Ich lasse das Programm/die Funktion in einen Fehler laufen und fange diesen dann ab

    b) Ich prüfe vor Ausführung ob z.B. Parameter fehlerhaft sind und generiere sofort selbst einen Fehler, der dann im Errorhandling weiter bearbeitet wird.


    Hier soll z.B. eine Datei eingelesen werden. Ich prüfe jetzt vorher, ob sie überhaupt existiert und generiere einen Fehler, falls nicht. Wenn Prozeduren Fehler generieren, ist die Art des Fehlers in den entsprechenden Modulen vermerkt (IOError, wImageError, ..). Fehler enden immer auf ..Error.

    Meine Dateiprüfung liefert aber keinen Fehler, sondern true/false. Somit ist es erforderlich einen eigenen Fehlertyp zu erstellen, dem ich dann auch einen entsprechenden Text beim Setzen mitgebe.

    Falls z.B. ein Dateihandle existiert, weil eine Datei zum Schreiben geöffnet wurde und dort ein Fehler auftrat, muss dem "except:" ein "finally:" folgen mit (in diesem Fall) close(f). Wichtig!: Der finally-Zweig wird IMMER ausgeführt (unabhängig ob Fehler oder nicht), also muss diese Aktion auch ausführbar sein und nicht selbst in einen Fehler laufen.


    Doku: Raise & Try


    P.S.

    Falls ihr noch weitere Bsp. zum Errorhandling habt, bitte hier posten. Das Thema ist so komplex, da ist eine Sammlung sicher hilfreich.