Warum speichern wir nicht den Syntaxbaum anstelle des Quellcodes?

111

Wir haben viele Programmiersprachen. Jede Sprache wird analysiert und die Syntax überprüft, bevor sie in Code übersetzt wird, sodass ein abstrakter Syntaxbaum (AST) erstellt wird.

Wir haben diesen abstrakten Syntaxbaum. Warum speichern wir diesen Syntaxbaum nicht anstelle des Quellcodes (oder neben dem Quellcode)?

Durch die Verwendung eines AST anstelle des Quellcodes. Jeder Programmierer in einem Team kann diesen Baum in jede gewünschte Sprache serialisieren (mit der entsprechenden kontextfreien Grammatik) und nach Abschluss des Vorgangs wieder zu AST analysieren. Dies würde also die Debatte über die Codierungsstil-Fragen beseitigen (wo die {und} zu setzen sind, wo Whitespace, Einrückung usw. zu setzen sind).

Was sind die Vor- und Nachteile dieses Ansatzes?

Calmarius
quelle
37
Lisp wird normalerweise als abstrakter Syntaxbaum geschrieben. Es hat nicht so viel verstanden wie Algol-ähnliche Sprachen.
David Thornley
2
Ich kann nicht glauben, dass David der einzige ist, der erwähnt, dass LISP-Programme ein abstrakter Syntaxbaum sind.
WuHoUnited
3
Neben anderen Punkten: AST ist noch nicht einmal das Letzte. Es dauert auch nicht so lange, AST aus Code zu erstellen. Wenn ich StyleCop in meinem kleinen VS2010-Projekt ausführe, werden Dutzende verschiedener AST-basierter Regeln in Tausenden von Codezeilen sehr schnell ausgeführt (manchmal ein oder zwei Sekunden). Es ist auch ziemlich einfach, StyleCop zu erweitern und eine benutzerdefinierte Regel zu schreiben. Ich vermute, dass das Parsen des Quellcodes in einen AST ein gut verstandenes und relativ einfaches Problem ist. Es kommt in erster Linie auf die gute Sprache und die Optimierung und all die Bibliotheken an, die schwierig sind, nicht zu analysieren.
Job
1
Nachdem der Code analysiert wurde , ist es nicht so einfach, den Code für eine andere Sprache zu generieren. (Wie würden Sie die implizite Vereinigung von Prolog in C übersetzen?) Meistens haben Sie einen AST für das ursprüngliche Programm.
Ira Baxter
3
Das Problem des Parsens ist technisch gut verstanden, aber es ist keine leichte Aufgabe, C oder C ++ zu analysieren, da es sich um unangenehme Sprachen handelt. Viele Compiler analysieren C oder C ++ mit ASTs: Clang, GCC, ... Sie sind nicht für die Speicherung von Programmen vorgesehen, und GCC möchte unbedingt Compiler und kein Programmanalysetool sein. Unser DMS Software Reengineering Toolkit analysiert viele Dialekte von C und C ++, erstellt ASTs, Symboltabellen und verschiedene Arten von Flussanalyse-Artefakten. Der große Vorteil dieses Ansatzes ist die Fähigkeit, automatisierte Änderungswerkzeuge zu erstellen. semanticdesigns.com/Products/DMS/DMSToolkit.html
Ira Baxter

Antworten:

72

Leerzeichen und Kommentare

Im Allgemeinen enthält ein AST keine Leerzeichen, Zeilenabschlusszeichen und Kommentare.

Sinnvolle Formatierung

Sie haben Recht, dass dies in den meisten Fällen positiv ist (wodurch heilige Kriege beseitigt werden), und dass die Formatierung des Originalcodes in vielen Fällen eine gewisse Bedeutung hat, z Anweisungen mit einer Leerzeile).

Code, der nicht kompiliert werden kann

Während viele Parser sehr widerstandsfähig gegen fehlende Syntax sind, führt fehlerhafter Code häufig zu einem sehr seltsamen Syntaxbaum, der bis zu dem Punkt, an dem der Benutzer die Datei neu lädt, in Ordnung und fehlerfrei ist. Haben Sie jemals einen Fehler in Ihrer IDE gemacht und plötzlich hat die gesamte Datei "Squigglies"? Stellen Sie sich vor, wie das in einer anderen Sprache nachgeladen würde.

Möglicherweise schreiben Benutzer keinen nicht analysierbaren Code ein, aber sie müssen auf jeden Fall lokal speichern.

Keine zwei Sprachen passen perfekt zusammen

Wie andere betont haben, gibt es fast keine zwei Sprachen, die eine perfekte Feature-Parität aufweisen. Ich kann mir vorstellen, dass VB und C # oder JavaScript und CoffeeScript am nächsten kommen, aber selbst dann verfügt VB über Funktionen wie XML-Literale, die in C # keine Entsprechungen aufweisen, und die Konvertierung von JavaScript in CoffeeScript führt möglicherweise zu vielen JavaScript-Literalen.

Persönliche Erfahrung:

In einer Softwareanwendung, die ich schreibe, müssen wir dies tatsächlich tun, da von den Benutzern erwartet wird, dass sie "normales Englisch" eingeben, das im Hintergrund in JS konvertiert wird. Wir haben erwogen, nur die JS-Version zu speichern, aber kaum eine akzeptable Möglichkeit gefunden, um diese zuverlässig zu laden und zu entladen. Daher haben wir immer sowohl den Benutzertext als auch die JS-Version sowie ein Flag gespeichert, das angibt, ob "normales Englisch" vorliegt msgstr "Version wurde perfekt analysiert oder nicht.

Kevin McCormick
quelle
9
Es gibt Parser, die Kommentare und Layouts im AST erfassen. Mit unserem DMS Software Rengineering Toolkit ist dies in Ordnung. Es tut sich schwer mit illegalem Code; es hat einen präzisen Sprachparser.
Ira Baxter
2
Es gibt tatsächlich ein Tool, das Javascript in CoffeeScript konvertiert , also denke ich, dass JavaScript und CoffeScript ohne Javascript-Literale gegenseitig übersetzbar sind.
Peter Olson
Interessantes Werkzeug, Peter, mir war es nicht bewusst.
Kevin McCormick
+1 für sinnvolle Formatierung und die interessante persönliche Erfahrung. - Leerzeichen sind für die Frage nicht wichtig und Kommentare können beibehalten werden. Fehlerhafte Codes wären ohnehin einfacher zu beheben, und natürlich war der Teil der Frage "Eine Sprache, die alle beherrscht" nicht erreichbar.
Cregox
43

Warum speichern wir diesen Syntaxbaum nicht anstelle des Quellcodes? Jeder Programmierer in einem Team kann diesen Baum in jede Sprache serialisieren, die er möchte, und nach Abschluss des Vorgangs zu AST zurückkehren.

Das ist in der Tat eine vernünftige Idee. Microsoft hatte in den neunziger Jahren ein Forschungsprojekt, um genau das zu erreichen .

Es kommen mehrere Szenarien in den Sinn.

Das erste ist eher trivial; Wie Sie sagen, könnte der AST in Abhängigkeit von den Vorlieben verschiedener Programmierer für Dinge wie Abstand usw. in verschiedene Ansichten gerendert werden. Das Speichern eines AST ist für dieses Szenario jedoch zu teuer. schreib dir einfach einen hübschen Drucker. Wenn Sie eine Datei in Ihren Editor laden, führen Sie den Pretty-Printer aus, um sie in Ihr bevorzugtes Format und beim Speichern wieder in das ursprüngliche Format zu bringen.

Der zweite ist interessanter. Wenn Sie den abstrakten Syntaxbaum speichern können, wird eine Änderung, die sich vom Code unterscheidet, nicht textuell, sondern syntaktisch. Refactorings, bei denen Code verschoben wird, sind viel einfacher zu verstehen. Der Nachteil ist natürlich, dass das Schreiben der Tree-Diff-Algorithmen nicht gerade trivial ist und oft pro Sprache erfolgen muss. Text Diff funktioniert für fast jede Sprache.

Das dritte ist eher das, was Simonyi sich für die absichtliche Programmierung vorgestellt hat: Die grundlegenden Konzepte, die Programmiersprachen gemeinsam haben, sind serialisiert, und dann haben Sie unterschiedliche Ansichten dieser Konzepte, die in verschiedenen Sprachen wiedergegeben werden. Obwohl es eine schöne Idee ist, ist die hässliche Tatsache, dass Sprachen in ihren Details so unterschiedlich sind, dass ein Ansatz mit dem kleinsten gemeinsamen Nenner nicht wirklich funktioniert.

Kurz gesagt, es ist eine schöne Idee, aber es ist eine enorme Menge an zusätzlicher Arbeit für einen vergleichsweise geringen Nutzen. Deshalb tut es kaum jemand.

Eric Lippert
quelle
3
Tatsächlich können Sie das Tree-Diff sprachunabhängig durchführen. Sie benötigen sprachspezifische Parser, um die Bäume zu bauen. Sehen Sie sich unsere Smart Differencer-Tools an, die die ASTs für viele Sprachen vergleichen. Sie verwenden alle dieselbe zugrunde liegende Diff-Engine. semanticdesigns.com/Products/SmartDifferencer
Ira Baxter
1
Ich hoffe, dass ich eines Tages in Visual Studio das Bild "Mein Stil, hübsch, Drucken beim Laden, Teamstil, hübsch, Drucken beim Speichern" sehen kann ... ich habe jahrelang gehofft ... noch kein Glück ...
Roman Starkov
19

Sie könnten argumentieren, dass dies genau der Bytecode in .NET ist. Das Reflektorprogramm von Infact redgate übersetzt Byte-Code zurück in eine Reihe von .NET-Programmiersprachen.

Es gibt jedoch Probleme. Syntax ist sprachspezifisch, da es Dinge gibt, die Sie in einer Sprache darstellen können, die in anderen Sprachen nicht dargestellt sind. Dies tritt in .NET auf, wobei C ++ die einzige .NET-Sprache ist, die Zugriff auf alle sieben Zugriffsebenen hat.

Außerhalb der .NET-Umgebung wird es viel kniffliger. Jede Sprache verfügt dann über einen eigenen Satz zugeordneter Bibliotheken. Es wäre nicht möglich, sowohl in C als auch in Java eine generische Syntax wiederzugeben, die die gleiche Ausführung von Befehlen widerspiegelt, da sie ähnliche Probleme auf sehr unterschiedliche Weise lösen.

Michael Shaw
quelle
5
Haben Sie jemals versucht, MSIL von F # zu dekompilieren?
SK-logic
12

Ich mag einige Ihrer Ideen, aber Sie überschätzen deutlich, wie einfach es ist, Sprache in Sprache zu übersetzen. Wenn es so einfach wäre, müssten Sie den AST nicht einmal speichern, da Sie immer die Sprache X in den AST analysieren und dann von AST zu Sprache Y wechseln könnten.

Ich wünsche mir jedoch, dass die Compilerspezifikationen ein bisschen mehr darüber nachdenken, einen Teil des AST durch eine Art API verfügbar zu machen. Dinge wie aspektorientiertes Programmieren, Refactoring und statische Programmanalyse könnten über eine solche API implementiert werden, ohne dass der Implementierer dieser Funktionen so viel von der Arbeit wiederholen muss, die bereits von Compiler-Autoren implementiert wurde.

Es ist merkwürdig, wie oft die Datenstruktur eines Programmierers zur Darstellung eines Programms aus einer Reihe von Dateien besteht, die Zeichenfolgen enthalten.

bA
quelle
5
Haben Sie die Entwicklung des Microsoft- Projekts " Roslyn " verfolgt, um die VBc- und C # -Compiler als APIs zu öffnen? Es ist eine Vorschau-Version verfügbar.
Carson63000
11

Ich denke, die wichtigsten Punkte sind folgende:

  • Es gibt keinen Vorteil. Sie sagten, das würde bedeuten, dass jeder seine Haustiersprache benutzen könnte. Dies ist jedoch nicht der Fall - bei Verwendung einer Syntaxbaumdarstellung würden nur syntaktische, nicht jedoch semantische Unterschiede beseitigt. Es funktioniert bis zu einem gewissen Grad für sehr ähnliche Sprachen - wie VB und C # oder Java und Scala. Aber auch da nicht ganz.

  • Das ist problematisch. Sie haben die Freiheit der Sprache gewonnen, aber die Freiheit der Werkzeuge verloren. Sie können den Code nicht mehr in einem Texteditor oder in einer beliebigen IDE lesen und bearbeiten. Sie sind zum Lesen und Bearbeiten des Codes auf ein bestimmtes Tool angewiesen , das Ihre AST-Darstellung spricht. Hier ist nichts gewonnen.

    Um diesen letzten Punkt zu veranschaulichen, werfen Sie einen Blick auf RealBasic, eine proprietäre Implementierung eines leistungsstarken BASIC-Dialekts. Eine Zeitlang sah es fast so aus, als ob die Sprache abheben könnte, aber es war vollständig herstellerabhängig, bis zu dem Punkt, dass Sie den Code nur in ihrer IDE anzeigen konnten, da er in einem proprietären Nicht-Text-Format gespeichert war. Großer Fehler.

Konrad Rudolph
quelle
4
Der potenzielle Vorteil wäre, dass endlose Debatten wie "Tabs vs. Spaces", "Unix vs. Windows Bracing / Indentation", "m_ Prefixes vor Mitgliedern oder nicht" beendet werden könnten, da sie in einfache IDE-Optionen umgewandelt werden könnten.
Nikie
1
@nikie Stimmt, aber Sie können dies bereits mithilfe von Neuformatierungswerkzeugen wie "like" astyleoder "UnniversalIndent" tun. Keine Notwendigkeit für arkane Binärformate.
Konrad Rudolph
2
Der eigentliche Vorteil wäre das Potenzial von Diff / Patch-Tools, mit denen Sie besser verstehen, was sich wirklich geändert hat. Dies scheint jedoch eine völlig neue Toolchain für die Versionskontrolle zu erfordern, was eine schwerwiegende Einschränkung darstellt.
Peter Taylor
1
Wenn Sie der Meinung sind, dass es keinen Nutzen gibt, haben Sie die Domain Workbench von Intentional Software noch nicht gesehen.
Craig Stuntz
1
Auf den Punkt gebracht, kann dieselbe Logik in verschiedene Darstellungen projiziert werden, die nicht auf Text basieren, sodass die Regeln auch für Nicht-Programmierer zugänglich sind. Zum Beispiel können Domain-Experten wie Aktuare die versicherungsmathematischen Teile eines Versicherungsantrags schreiben. Wie ein DSL, nur nicht auf diese Darstellung beschränkt. Dies hängt jedoch stark mit der Frage zusammen. Es gibt eine gute Demo .
Craig Stuntz
6

Ich denke, wenn Sie sowohl den Text als auch den AST speichern, haben Sie nichts wirklich Nützliches hinzugefügt, da der Text bereits in einer Sprache vorhanden ist und der AST schnell aus dem Text rekonstruiert werden kann.

Wenn Sie dagegen nur den AST speichern, verlieren Sie Dinge wie Kommentare, die nicht wiederhergestellt werden können.

Tesserex
quelle
6
und wenn Sie die Kommentare zum Teil des Syntaxbaums machen (mit Kommentarknoten, die ein Kind von irgendetwas sein können)?
Ratschenfreak
Unsere Werkzeuge machen genau das. Siehe meine anderen Kommentare in diesem Thread.
Ira Baxter
4

Ich glaube, die Idee ist theoretisch interessant, aber nicht sehr praktisch, da verschiedene Programmiersprachen verschiedene Konstrukte unterstützen, von denen einige keine Entsprechungen in anderen Sprachen haben.

Zum Beispiel hat X ++ eine 'while select'-Anweisung, die ohne viel zusätzlichen Code (zusätzliche Klassen, zusätzliche Logik usw.) nicht in C # geschrieben werden kann. http://msdn.microsoft.com/en-us/library/aa558063.aspx

Ich sage hier, dass viele Sprachen syntaktische Zucker haben, die in großen Codeblöcken derselben Sprache übersetzt werden, oder sogar Elemente, die in anderen überhaupt nicht existieren. Hier ist ein Beispiel, warum der AST-Ansatz nicht funktioniert:

Die Sprache X hat ein Schlüsselwort K, das in AST in 4 Anweisungen übersetzt wird: S1, S2, S3 und S4. Der AST ist jetzt in die Sprache Y übersetzt und ein Programmierer ändert S2. Was passiert nun mit der Übersetzung zurück nach X? Der Code wird als 4 Anweisungen anstelle eines einzelnen Schlüsselworts übersetzt ...

Das letzte Argument gegen den AST-Ansatz sind die Plattformfunktionen: Was passiert, wenn eine Funktion in die Plattform eingebettet ist? Wie bei .NET Environment.GetEnvironmentVariable. Wie übersetzen Sie das?

Victor Hurdugaci
quelle
4

Um diese Idee herum gibt es ein System: JetBrains MPS . Ein Editor ist ein bisschen seltsam oder einfach anders, aber im Allgemeinen ist es kein so großes Problem. Das größte Problem ist, na ja, dass es kein Text mehr ist, so dass Sie keine der normalen textbasierten Tools verwenden können - andere Editoren grep, sedverschmelzen und diff Werkzeuge usw.

SK-Logik
quelle
2
... aber Sie erhalten eine Menge Editor-Funktionen aus der Box. Erwägen Sie, diese Antwort ein wenig zu erweitern. Es handelt sich um eine sehr interessante Technologie, die es verdient, die Vorteile, Quellcode nicht als Text zu speichern, ein wenig genauer zu betrachten. ZB wie ich auf diese Frage auf Tabs vs. Leerzeichen geantwortet habe .
Steven Jeuris
AST kann in einem für Menschen lesbaren Format und nicht in einer Binärdatei gespeichert werden. Können Sie jetzt mit Linux-Tools zum Beispiel jede Methode in Code ersetzen, die als Parameter serialisierbares Objekt nimmt? es wäre sehr schwer zu schreiben, aber AST macht das sehr einfach.
IAdapter
1
Diesen Fehler machen die Leute immer wieder. Der AST macht es einfacher, als wenn Sie nur rohen Text haben. Aber für alles Interessante benötigen Sie eine Reihe zusätzlicher Informationen: Kontrolle und Datenfluss, Symboltabellen, Bereichsanalyse, ... ASTs helfen, sind aber nur ein kleiner Teil dessen, was wirklich benötigt wird.
Ira Baxter
@Ira Baxter, mit AST ist es natürlich einfacher. Die Integration in die bestehende Infrastruktur gestaltet sich jedoch wesentlich schwieriger .
SK-logic
4

Tatsächlich gibt es mehrere Produkte, die allgemein als "Sprachwerkbänke" bekannt sind, die ASTs speichern und in ihren Editoren eine "Projektion" des AST in eine bestimmte Sprache zurückgeben. Wie @ sk-logic sagte, ist das MPS von JetBrains ein solches System. Ein weiteres Beispiel ist die Intentional Workbench von Intentional Software.

Das Potenzial für Sprachwerkbänke scheint insbesondere im Bereich domänenspezifischer Sprachen sehr hoch zu sein, da Sie eine domänenspezifische Projektion erstellen können. Beispiel: Intentional demonstriert eine DSL in Bezug auf Elektrizität, die als Schaltplan projiziert wird - viel einfacher und genauer als eine Schaltung, die in einer textbasierten Programmiersprache beschrieben wird.

In der Praxis haben sich Sprach-Workbenches nur langsam durchgesetzt, da Entwickler neben der DSL-Arbeit wahrscheinlich lieber in einer vertrauten, allgemeinen Programmiersprache arbeiten würden. Im direkten Vergleich mit einem Texteditor oder einer Programmier-IDE sind die Sprach-Workbenches mit einem enormen Aufwand verbunden, und ihre Vorteile sind bei weitem nicht so deutlich. Keine der Sprach-Workbenches, die ich gesehen habe, hat sich so weit selbst gebootet, dass sie ihre eigenen IDEs problemlos erweitern können. Wenn Sprach-Workbenches also die Produktivität steigern, warum wurden die Tools der Sprach-Workbench nicht besser? -und-besser bei immer schnelleren Raten?

Larry OBrien
quelle
Eine "Sprach-Workbench" sollte nicht unbedingt auf der Speicherung roher ASTs basieren. Sie können sich auch an der Syntax von einfachem Text orientieren, siehe zum Beispiel meta-alternative.net/pfront.pdf (und dieser erweitert den Visual Studio- und Emacs-Editor tatsächlich um jede darüber implementierte eDSL).
SK-logic
Das ist ein interessantes Papier; es erinnert mich (in Ehrgeiz, nicht in Umsetzung) ein Werkzeug namens SugarJ , die vor einigen Wochen bei SPLASH / OOPSLA vorgestellt wurden: uni-marburg.de/fb12/ps/research/sugarj
Larry OBrien
Interessant, ich werde das auch versuchen.
SK-logic
3

Du hast meine Gedanken gelesen.

Als ich vor ein paar Jahren an einem Compilerkurs teilgenommen habe, habe ich festgestellt, dass Sie Lisp erhalten, wenn Sie einen AST mit Präfixnotation anstelle der üblichen Infixnotation nehmen und Klammern verwenden, um ganze Anweisungen abzugrenzen. Während ich in meinem Grundstudium etwas über Scheme (ein Lisp-Dialekt) gelernt hatte, hatte ich nie wirklich eine Anerkennung dafür bekommen. Durch diesen Kurs habe ich definitiv eine Wertschätzung für Lisp und seine Dialekte gewonnen.

Probleme mit dem, was Sie vorschlagen:

  1. Es ist schwierig / langsam, einen AST in einer grafischen Umgebung zu erstellen. Schließlich können die meisten von uns schneller tippen, als wir eine Maus bewegen können. Und dennoch stellt sich die Frage, wie man mit einem Tablet Programmcode schreibt. Das Tippen auf einem Tablet ist im Vergleich zu einer Tastatur / einem Laptop mit einer Hardwaretastatur langsam / umständlich. Wenn Sie einen AST erstellen könnten, indem Sie Komponenten von einer Palette auf eine Leinwand auf einem großen Touchscreen-Gerät ziehen und dort ablegen, könnte die Programmierung auf einem Tablet zu einer echten Sache werden.

  2. nur wenige / keine unserer vorhandenen Tools unterstützen dies. Wir haben jahrzehntelange Entwicklungsarbeit in die Erstellung immer komplexerer IDEs und immer intelligenterer Editoren gesteckt. Wir haben all diese Tools zum Neuformatieren von Text, Vergleichen von Text und Durchsuchen von Text. Wo sind die Werkzeuge, die eine Suche nach regulären Ausdrücken über einen Baum hinweg durchführen können? Oder ein Unterschied von zwei Bäumen? All diese Dinge lassen sich leicht mit Text erledigen. Aber sie können nur die Wörter vergleichen. Ändern Sie einen Variablennamen so, dass die Wörter unterschiedlich sind, die semantische Bedeutung jedoch gleich ist und diese Diff-Tools Probleme bekommen. Mit solchen Tools, die entwickelt wurden, um ASTs anstelle von Text zu verarbeiten, können Sie die semantische Bedeutung besser vergleichen. Das wäre eine gute Sache.

  3. Während das Umwandeln von Programm-Quellcode in einen AST relativ gut verstanden ist (wir haben Compiler und Interpreter, nicht wahr?), ist das Umwandeln eines AST in Programmcode nicht so gut verstanden. Das Multiplizieren von zwei Primzahlen, um eine große, zusammengesetzte Zahl zu erhalten, ist relativ einfach, aber das Zurückrechnen einer großen, zusammengesetzten Zahl in Primzahlen ist viel schwieriger; Das ist der Punkt, an dem wir uns mit dem Parsen und Dekompilieren von ASTs befassen. Hier werden die Unterschiede zwischen den Sprachen zum Problem. Selbst innerhalb einer bestimmten Sprache gibt es mehrere Möglichkeiten, einen AST zu dekompilieren. Zum Beispiel durch eine Sammlung von Objekten iterieren und ein Ergebnis erhalten. Verwenden Sie eine for-Schleife, die ein Array durchläuft? Das wäre kompakt und schnell, aber es gibt Einschränkungen. Verwenden Sie einen Iterator, Arbeiten an einer Sammlung? Diese Sammlung kann eine variable Größe haben, was die Flexibilität auf (mögliche) Kosten der Geschwindigkeit erhöht. Karte verkleinern? Komplexer, aber implizit parallelisierbar. Und das nur für Java, abhängig von Ihren Vorlieben.

Mit der Zeit wird der Entwicklungsaufwand erhöht und wir werden mit Touchscreens und ASTs entwickeln. Tippen wird weniger notwendig. Ich sehe das als logische Weiterentwicklung von unserem derzeitigen Stand an, wenn wir uns ansehen, wie wir heute mit Computern umgehen. Das wird die erste Aufgabe lösen.

Wir arbeiten bereits mit Bäumen. Lisp ist lediglich serialisierte ASTs. XML (und HTML als Erweiterung) ist nur ein serialisierter Baum. Für die Suche haben wir bereits einige Prototypen: XPath und CSS (für XML bzw. HTML). Wenn grafische Werkzeuge erstellt werden, mit denen wir CSS-artige Selektoren und Modifikatoren erstellen können, haben wir einen Teil von # 2 gelöst. Wenn diese Selektoren erweitert werden können, um reguläre Ausdrücke zu unterstützen, sind wir näher dran. Ich suche noch ein gutes grafisches Diff-Tool zum Vergleichen von zwei XML- oder HTML-Dokumenten. Während die Leute diese Tools entwickeln, wird # 2 gelöst werden können. Die Leute arbeiten bereits an solchen Dingen; Sie sind einfach noch nicht da.

Die einzige Möglichkeit, diese ASTs in Programmiersprachentexte zu dekompilieren, wäre etwas Zielstrebendes. Wenn ich vorhandenen Code ändere, kann das Ziel durch einen Algorithmus erreicht werden, der meinen geänderten Code dem Startcode so ähnlich wie möglich macht (minimaler Textunterschied). Wenn ich Code von Grund auf neu schreibe, ist das Ziel möglicherweise der kleinste und engste Code (wahrscheinlich eine for-Schleife). Oder es könnte Code sein, der so effizient wie möglich parallelisiert (wahrscheinlich eine Karte / Verkleinerung oder etwas, das CSP einbezieht). Aus diesem Grund kann derselbe AST auch in derselben Sprache zu erheblich unterschiedlichem Code führen, je nachdem, wie die Ziele festgelegt wurden. Die Entwicklung eines solchen Systems würde # 3 lösen. Es wäre rechenintensiv, was bedeutet, dass wir wahrscheinlich eine Art Client-Server-Anordnung benötigen würden.

Meower68
quelle
1

Wenn Sie die Debatte über Formatierungsstile beenden möchten, möchten Sie vielleicht einen Editor, der eine Quelldatei einliest und sie nach Ihren persönlichen Wünschen für die Anzeige und Bearbeitung formatiert. Wenn Sie sie jedoch speichern, formatieren Sie den ausgewählten Stil im Team neu Verwendet.

Es ist ganz einfach, wenn Sie einen Editor wie Emacs verwenden . Das Ändern des Formatierungsstils einer gesamten Datei erfolgt mit drei Befehlen.

Sie sollten auch in der Lage sein, die Hooks zu erstellen, um eine Datei beim Laden automatisch in Ihren eigenen Stil umzuwandeln und beim Speichern in den Teamstil umzuwandeln.

Gustav Bertram
quelle
1
Dann brauchen Sie noch ein semantisches Diff und Merge (also wieder AST-Level).
SK-logic
Nein, der Editor formatiert den Teamstil zum Speichern der Quelle neu. Sie würden also einen Quellentyp mit demselben Typ vergleichen.
Gustav Bertram
ein guter Punkt, eine einzige normalisierte Darstellung löst alle Probleme
SK-Logik
1
Nein, es löst nur die Probleme, zwei Dateien für die Identität zusammenzufassen. Wenn Sie Unterschiede zwischen den Dateien sehen möchten, benötigen Sie im Idealfall etwas, das die Struktur versteht. Ich liebe meinen Emacs, aber er versteht die Struktur nicht.
Ira Baxter
Emacs ist großartig, aber ich benutze es nie, um zu unterscheiden. Um meinen Source Tree vor dem Einchecken zu vergleichen, benutze ich immer meld . Es versteht eigentlich SVN und Git. Unter Windows würde ich WinMerge wahrscheinlich in Kombination mit Tortoise verwenden.
Gustav Bertram
1

Es ist schwierig, einen AST anstatt des Quellcodes zu lesen und zu ändern.

Einige compilerbezogene Tools ermöglichen jedoch die Verwendung des AST. Java-Bytecode und .NET-Zwischencode funktionieren ähnlich wie ein AST.

umlcat
quelle
1
Es ist einfacher, einen AST zuverlässig mit mechanischen Werkzeugen zu ändern, als dies mit Text zu tun. Sie können dies mit mustergesteuerten Änderungen tun. Siehe semanticdesigns.com/Products/DMS/ProgramTransformation.html
Ira Baxter,
2
Sagen Sie dies jetzt den LISPern ...
hugomg
@Ira Baxter. Ich weiß, ich arbeite tatsächlich an einem benutzerdefinierten visuellen Tool, das direkt mit einem AST zusammenarbeitet. Manchmal müssen Entwickler jedoch mit Text anstelle von visuell arbeiten. Einige AST werden auch als kürzere Programmiersprache im Text dargestellt.
umlcat
@umlcat, kannst du mir mehr über deine Arbeit an einem visuellen Tool für ASTs erzählen?
Daniel Albuschat
@Daniel Albuschat Ich arbeite an einem Programmiersprachenprojekt für Haustiere. Der Parser ist schwierig zu implementieren, daher überspringe ich ihn im Moment und erstelle ein Tool, in dem ich das AST (Formular mit Strukturansichtskontrolle) zeige und direkt Ausdrücke hinzufüge. Und kann das Gegenteil tun, den Code aus dem AST generieren.
Umlcat
0

es ist eine nette Idee; Das AST jeder Sprache unterscheidet sich jedoch von jedem anderen.

Die einzige mir bekannte Ausnahme betrifft VB.NET und C #, bei denen Microsoft argumentiert, dass es sich um "genau dieselbe Sprache mit unterschiedlicher Syntax" handelt. Sogar andere .NET-Sprachen (IronPython, F #, was auch immer) sind auf AST-Ebene unterschiedlich.

Dieselbe Sache mit JVM-Sprachen, alle zielen auf denselben Bytecode ab, aber die Sprachkonstrukte sind unterschiedlich, wodurch es unterschiedliche Sprachen und unterschiedliche ASTs gibt.

Selbst "Thin Layer" -Sprachen wie CoffeScript und Xtend teilen einen Großteil der Theorie der zugrunde liegenden Sprachen (JavaScript bzw. Java). Einführung von Konzepten auf höherer Ebene, die auf AST-Ebene beibehalten werden (oder sollten).

Wenn Xtend aus einem Java-AST rekonstruiert werden könnte, wäre es meiner Meinung nach als Java-to-Xtend-Uncompiler definiert worden, der auf magische Weise Abstraktionen auf höherer Ebene aus vorhandenem Java-Code erzeugt.

Javier
quelle
1
Als jemand, der sowohl mit C # - als auch mit VB-Compilern bestens vertraut ist, kann ich Ihnen sagen, dass sie sicherlich ähnlich sind, aber es gibt genügend wichtige Details, die sich so unterscheiden, dass es unpraktisch ist, sie als "dieselbe Sprache mit unterschiedlicher Syntax" zu behandeln. Wir haben darüber nachgedacht, dies für das Roslyn-Projekt zu tun. Erstellen eines einzigen Compilers, der beide Sprachen mit gleicher Funktionalität kompilieren kann - und nach langen Debatten beschlossen, zwei Compiler für zwei Sprachen zu verwenden.
Eric Lippert
@ EricLippert: das ist eine Schande. nicht, dass ich jemals geplant hätte, eine der beiden Sprachen zu lernen, aber es klang wie eine nette Ausnahme. Ich denke, dass lisp-like-Dylan und algol-like-Dylan das einzige Beispiel für dieselbe Sprache mit unterschiedlichen Syntaxen sind.
Javier