Textparsing / Lexing

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Traggger
User
Beiträge: 27
Registriert: Mittwoch 17. Dezember 2008, 11:33
Wohnort: Regensburg

Hi Leute,

ich habe grad ein kleines Problem. Ich möchte im Quellcode einer C ähnliche Sprache diverse Stellen finden (dabei handelt es sich um Set Funktionen oder Zuweisungen). Also ich will Werte an bestimmten Stellen auslesen, speichern und später wieder an diese Stelle im Quellcode schreiben.
Dabei ist aber wichtig, dass die Formatierung des Quellcodes erhalten bleibt (Idents und Kommentare).

Ich habe grad gar keine Idee, wie man das akkurat lösen könnte. Hat da jemand Ansätze die mir helfen könnten??

Greetz Traggger
There are 10 kinds of people. Those who understand binary notation, and those who do not.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Kannst Du uns mal ein minimales Beispiel geben? Also mal eine solche Datei hier posten und beschreiben, was Du auslesen willst und wie es dann später wieder aussehen soll?

Um was für eine Sprache handelt es sich denn genau?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Traggger
User
Beiträge: 27
Registriert: Mittwoch 17. Dezember 2008, 11:33
Wohnort: Regensburg

Bei dem zu bearbeitenden Code handelt es sich um CAPL (Vector Programmiersprache für CAN Zugriff).

Hier ein Beispiel Quellcode...

Also habe da mal ein kleines Beispiel zusammengeschrieben wie der Quelltext etwa aussieht. Ich bräuchte daraus die Funktionsaufrufe wie

Code: Alles auswählen

SetTemplateTitle ("Template 1.")
oder die Namen (Strings) der Gruppen aus dem Array

Code: Alles auswählen

char aGroups[iNumberOfGroups][50]  = { ...
jeweils mit den Parametern oder Values.

Diese geparsten Werte will ich dann in einem XML-Format speichern und darauf weiter arbeiten. Zum Schluß nach dem bearbeiten soll der Ursprungsquelltext mit den Änderungen wieder geschrieben werden können ohne das dabei die Formatierung verloren geht, da es ja von diversen CAPL Editoren noch gelesen werden muß.

Hilft das soweit??

Greetz
There are 10 kinds of people. Those who understand binary notation, and those who do not.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Traggger hat geschrieben: Diese geparsten Werte will ich dann in einem XML-Format speichern und darauf weiter arbeiten. Zum Schluß nach dem bearbeiten soll der Ursprungsquelltext mit den Änderungen wieder geschrieben werden können ohne das dabei die Formatierung verloren geht, da es ja von diversen CAPL Editoren noch gelesen werden muß.
So, schon mal nicht schlecht zu wissen. Nun noch ein paar Fragen:

1.) Was genau planst Du in dem XML zu erledigen? (Wieso überhaupt XML?) Inwiefern brauchst Du da die Namen aus bestehenden Dateien? Woher stammen diese Dateien?

2.) Ist das eine einmalige Aktion oder soll das öfter ablaufen? Bleiben die Ausgangsdateien immer gleich und ändern sich nur die Werte, die dann zurückgeschrieben werden sollen?

Wenn wir das geklärt haben, kann man sicherlich eine Strategie ausarbeiten, wie man da sinnvoller Weise vorgehen kann :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Einen Quelltext in eine Baumstruktur zu zerlegen, die man dann manipulieren kann und wieder zu einem Quelltext machen kann klingt so, als wenn man einen Parser für einen CST (concrete syntax tree) braucht. Klassische Parser-Generatoren sind da nicht so gut geeignet, weil sie auf ASTs zielen, wo z.B. Leerzeichen und Kommentare automatisch entfernt wurden.

PyParsing als PEG-Parser würde mir als Bibliothek einfallen, allerdings finde ich dieses relativ alte Projekt nicht so gelungen. PLY ist ein klassischer LALR(1)-Parser-Generator, wo man wahrscheinlich auch abschalten kann, dass er Leerzeichen überspringt. PyPEG wäre noch ein PEG-Parser der speziell auf AST-Generation ausgelegt ist. Ob's auch einfach für CSTs geht, weiß ich nicht. Und zu LEPL kann ich nur sagen, dass es ein relativ umfangreiches Tutorial gibt.

Oder man macht es selbst. Ist die Sprache einfach als LL(1) ausdrückbar, kann man von Hand einen Recursive-Descent-Parser bauen. Mit wenig mehr Aufwand (oder wenn das ganze Programm immer in den Hauptspeicher passt) kann man das auf LL(*) ausdehnen.

Aufwändig finde ich, dass man in jedem Fall bei der Grammatik jede Stelle, wo Leerzeichen oder Kommentare stehen können, berücksichtigen muss. Das macht eine Grammatik schnell unlesbar. Aber das ist der Preis für ein Dokumentmodell, den es wohl zu zahlen gilt. Wenn man sich z.B. anschaut, was Eclipse oder IDEA als Java-IDEs für einen Aufwand treiben, um eine Objektrepräsentation des Java-Quelltexts zu bekommen, die man dann verändern kann und wo sich dann automatisch der Quelltext im Editor ändert, damit Refactorings einfacher programmierbar sind, weiß, was ich meine.

Stefan
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@sma: Ich wollte eigentlich herausfinden, ob dem OP eine Template-Engine reicht... ggf will er ja nur marginale Änderungen durchführen und letztlich immer das gleiche Code-Gerüst wiederverwenden.

Aber war wie immer interessant zu lesen :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Traggger
User
Beiträge: 27
Registriert: Mittwoch 17. Dezember 2008, 11:33
Wohnort: Regensburg

Danke für die schnellen Antworten!!
Hyperion hat geschrieben: 1.) Was genau planst Du in dem XML zu erledigen? (Wieso überhaupt XML?) Inwiefern brauchst Du da die Namen aus bestehenden Dateien? Woher stammen diese Dateien?
Das mit dem XML ist eine Idee von mir gewesen um nicht immer sofort bei Änderungen auf den Strings arbeiten zu müssen und da sich die Funktionsblöcke recht gut als Datensätze sozusagen speichern lassen (viele Blöcke mit gleichem Aufbau), und somit auch als eine Art Output zu dem ganzen Vorgang sein kann (zu evtl Dokumentationszwecken).
Die Namen der Funktionen sind feste Namen von der Umgebung wo der Quellcode herkommt, also sprich immer da... :)
Das Ganze stammt aus einer Testumgebung und enthält in den Funktionsblöcken, die Implementierungen der Testfälle. Also das Grundgerüst ist immer das Gleiche.
Hyperion hat geschrieben: 2.) Ist das eine einmalige Aktion oder soll das öfter ablaufen? Bleiben die Ausgangsdateien immer gleich und ändern sich nur die Werte, die dann zurückgeschrieben werden sollen?
Das Ganze soll natürlich immer wieder für gleiche Dateien passieren können, also der Inhalt ändert sich schon, aber die Struktur bleibt gleich. Es sollen also nur Parameter für die Funktionsaufrufe geändert werden bzw Werte die in Variablen gesetzt werden.

@sma:
Ich habe eine Sprachbeschreibung für CAPL als EBNF nahezu vollständig vorliegen. Wie du schön ausgedrückt hast:
Hyperion hat geschrieben:Aber das ist der Preis für ein Dokumentmodell, den es wohl zu zahlen gilt
Mir wars bis jetzt ein zu großer Aufwandt für "nur" ein paar Codestellen, werd aber nicht drumrum kommen, da eben Kommentare etc drin bleiben sollen und überall stehen können :(...
Ich habe mich bis jetzt etwas ausführlicher mit Plex beschäftigt. Das ist ein Event steuerbarer Lexer, der anfangs recht brauchbar schien, aber mittlerweile habe ich meine Zweifel, ob das der Richtige ist.
Auf den ersten Blick wäre vielleicht LEPL etwas werde mich da mal etwas ein lesen...

Bin aber gern für weitere Ideenvorschläge zu haben, da ich immer noch nix akkurates gefunden habe... :(
There are 10 kinds of people. Those who understand binary notation, and those who do not.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Traggger hat geschrieben: Das Ganze stammt aus einer Testumgebung und enthält in den Funktionsblöcken, die Implementierungen der Testfälle. Also das Grundgerüst ist immer das Gleiche.

Das Ganze soll natürlich immer wieder für gleiche Dateien passieren können, also der Inhalt ändert sich schon, aber die Struktur bleibt gleich. Es sollen also nur Parameter für die Funktionsaufrufe geändert werden bzw Werte die in Variablen gesetzt werden.
Das spricht imho für den Einsatz einer Template Engine. Damit kannst Du das Grundgerüst gleich belassen und anhand was auch immer einen konkreten Output erzeugen.

Ich würde Dir jinja2 empfehlen - es gibt aber noch zig andere wie Mako, genshi usw.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten