[JAVA] Entwicklung von DSL mit ANTLR 4.7.1

Vorwort

Dieses Mal verwende der Benutzer, der das von Java erstellte Tool zur automatischen Codegenerierung, Damaskus verwendet, einfach die Vorlage für die automatische Generierung. Stattdessen wurde angefordert, eine Vorlage aus dem Quellcode zu generieren und eine benutzerdefinierte Vorlage zu erstellen.

Ich konnte mit regulären Ausdrücken allein nicht gut damit umgehen, und als ich nach einer Lösung suchte, löste ich sie, indem ich mit dem Compiler / Compiler ANTLR eine einfache DSL erstellte.

Nach einigem Ausprobieren konnte ich DSL implementieren, sodass ich diesmal meinen Entwicklungsablauf offenlegen werde. Als Beispielprojekt werde ich diesmal meine Arbeit Damaskus verwenden.

Verstehen Sie die grundlegende Funktionsweise von ANTLR

ANTLR ist ein Java-Tool zum Erstellen eines eigenen Verarbeitungssystems (Programmiersprache). Der Phrasenanalysator (Lexer) und der Syntaxanalysator (Parser) werden automatisch aus der im erweiterten BNF beschriebenen Datei `` `* .g4``` generiert.

Ich weiß weder rechts noch links, aber ich bezog mich auf das Kommentarbuch "[The Definitive ANTLR 4 Reference](https://pragprog.com/book/tpantlr2/the-definitive]" von Professor Terence Parr, dem Autor von ANTLR. -antlr-4-Referenz) ". (Im Folgenden ANTLR-Buch) Die Anzahl der Seiten beträgt ungefähr 300 Seiten, was ziemlich dick ist, aber es ist in einfachem Englisch geschrieben, mit zahlreichen Codebeispielen im Text und Beispielcode auf Github Da es Remenska / Grammatik gibt, habe ich tatsächlich versucht, es zu verschieben, während ich es mir ansah, und ich konnte es lesen, indem ich das Codebeispiel in ungefähr 2 Wochen berührte.

Zuerst habe ich mir nur den Beispielcode angesehen und damit herumgespielt, aber schließlich war ich mir nicht sicher, also habe ich von Anfang an das ANTLR-Buch gelesen. Immerhin dachte ich, das sei der schnellste Weg. Es gibt viele Informationen auf der Website und im Github-Repository von Antlr, aber es ist fragmentiert und nicht alle abgedeckt, so [ANTLR Book](https://pragprog.com/book/tpantlr2/the-definitive- Es wird dringend empfohlen, zuerst alle Kapitel von Antlr-4-Referenz zu lesen.

Entwicklungsumgebung

Normalerweise verwende ich IntelliJ, aber ich fand, dass das Antler-Plug-In von Eclipse am besten geeignet ist. So bin ich

Ich habe das gleiche Projekt entwickelt, indem ich es in zwei IDEs geöffnet habe. Ab Januar 2018 ist Oxygen die neueste Version. Hier erfahren Sie, wie Sie den Antrl-Stecker damit installieren.

  1. Suchen Sie Antlr unter Hilfe-> Eclipse-Marktplatz.
  2. Installieren Sie ANTLR 4 IDE 0.3.6
  3. Eclipse wird nach der Installation neu gestartet
  4. Wählen Sie im oberen Menü Fenster-> Ansicht anzeigen-> Andere-> ANTLR 4
  5. Wählen Sie sowohl Analysebaum als auch Syntaxdiagramm aus.
  6. Öffnen Sie den Analysebaum in Eclipse (ein Bereich sollte angezeigt werden).
  7. Importieren Sie Damaskus als Projekt in Eclipse und öffnen Sie `` `DmscSrcParser.g4```.
  8. Doppelklicken Sie auf die `Datei``` -Regel oben in` DmscSrcParser.g4, um `` `DmscSrcParser :: file im Parse Tree-Bereich anzuzeigen und das Blockdiagramm wird angezeigt. Wird angezeigt

Entwicklungsfluss

Lexer / Parser Design

In Damaskus gibt es zwei Dateien: `` DmscSrcParser.g4``` und `DmscSrcLexer.g4```. Es wurde im folgenden Zyklus entwickelt.

Lexer Design

Unter Verwendung der erweiterten BNF-Notation habe ich eine Token-Definition in `` `DmscSrcLexer.g4``` erstellt, während ich das Syntaxdiagramm des installierten Antrl-Steckers überprüft habe. Wenn die Syntax falsch ist, wird eine Fehlermeldung angezeigt. Da es schwierig ist, eine Token-Definition von Grund auf neu zu erstellen, lesen Sie Beispiel im ANTLR-Buch und in diesem Fall die Inselsprache im ANTLR-Buch. ) War geplant, mit Tags erstellt zu werden, siehe ModeTagsLexer.g4 usw. , Erstellt die Basis.

Parser-Design

Unter Verwendung der oben beschriebenen Token-Definition habe ich eine Syntax-Parsing-Regel in `` `DmscSrcParser.g4``` definiert. Es kann schwierig sein, eine Regel von Anfang an gut zu definieren. Wenn Sie jedoch eine sehr komplizierte Regel in Parser definieren müssen oder in einer Situation stecken bleiben, in der die Regel nicht gut angewendet wird, überprüfen Sie die Definition des Tokens von Reexer. Bitte versuche. Wenn Lexer gut gestaltet ist, sollte Parser präzise sein.

Hier denke ich, dass es notwendig ist, Versuch und Irrtum zu wiederholen, während Feineinstellungen wiederholt werden, unter Bezugnahme auf das Beispiel des ANTLR-Buches. Es ist schwierig, von Anfang an eine große Regel zu erstellen. Erstellen Sie daher in dieser Inselsprache eine kleine Regel, anhand derer zunächst beurteilt werden kann, ob es sich um ein DSL-Start-Tag handelt oder nicht. Wenn diese Operation funktioniert, wird ein Tag erstellt Ich denke, der Punkt ist das Bewusstsein, kleine Regeln lokal zu testen, z. B. die Regeln der darin enthaltenen Attribute zu testen und sie zu einer großen Regel zu kombinieren.

DmscSrcParser.Top-Level-Regel in g4 (Datei für Damaskus))Klicken Sie hier, um die gewünschte Syntax einzufügen und visuell zu überprüfen, ob sie im Analysebaum korrekt in Blockdiagramme zerlegt wurde. Während Sie sich den Syntaxfehler ansehen, wird Parser angezeigt/Wir werden Lexer anpassen.



### Hörerentwicklung
 Jetzt, da Lexer und Parser die Syntax fast korrekt verarbeiten können, ist es Zeit, den Listener zu implementieren. ANTLR kann die Listner-Methode und die Visitor-Methodenschnittstelle / -implementierung ausgeben. Die Visitor-Methode eignet sich für die sequentielle Verarbeitung wie ein Interpreter. Dieses Mal werden wir jedoch alles auf einmal verarbeiten, sodass wir sie mit Listner entwickelt haben.

 Für das `` `build.gradle``` von [Damascus](https://github.com/yasuflatland-lf/damascus) ist eine` `` generateGrammarSource``` Aufgabe definiert, die als Projektstamm verwendet wird. Wenn Sie `` `gradle generateGrammarSource``` ausführen, wird ein Lexer / Parser aus der` `` * .g4```-Datei generiert. Erben Sie den generierten `` `DmscSrcParserBaseListener``` und entwerfen Sie die Implementierung.

 In dieser Phase werden wir den Unit-Test implementieren. JUnit ist in Ordnung, aber da Sie mit dem Testframework Spock flexibel Tests erstellen können, verwendet [Damascus](https://github.com/yasuflatland-lf/damascus) Spock-Tests.

## Zusammenfassung
 Ich habe gelernt, dass das Entwerfen von Lexer und Paser am schwierigsten ist, insbesondere beim Entwerfen von Paser, und dass das Lexer-Design schlecht ist. Das mehrfache Umschreiben von Lexer macht Parser daher einfach. Es war eine große Überraschung, mit der von ANTLR generierten Syntaxanalyse-Engine problemlos mit komplizierter Syntax umgehen zu können, die von regulären Ausdrücken nicht verarbeitet werden kann.

 Es ist ein Gedicht-ähnlicher Artikel, aber ich hoffe, er hilft jemandem!

 Tips
### Wenn Sie Lexer ändern und es nicht richtig neu geladen wird
 Der Antlr-Plug von Eclipse funktioniert gut, aber wenn ich Lexer häufig ändere, wird die geänderte Syntax manchmal nicht gut geladen. Ich habe es mit der folgenden Methode gelöst, also werde ich es als Referenz schreiben.

 1. Führen Sie `` `gradle generateGrammarSource``` aus und führen Sie dann` `` gradle eclipse``` aus
 2. Wenn es immer noch nicht funktioniert, in dem Verzeichnis, in dem sich `` `* .g4``` befindet (` `/ src / main / antlr```)` `antlr4 DmscSrcLexer.g4; antlr4 DmscSrcParser.g4; javac Führen Sie Dms * .java``` aus und konvertieren Sie die generierten `` `* .tokens``` und` `` * .interp``` in `` src / main / java / com / liferay / damascus / antlr / In Vorlage kopieren```, `` `gradle eclipse``` ausführen, in`` DmscSrcParser.g4```, `` Parse Tree`` auf` `file``` doppelklicken `Überprüfen Sie das Fenster erneut.
 3. Wenn dies nicht funktioniert, starten Sie Eclipse neu.


Recommended Posts

Entwicklung von DSL mit ANTLR 4.7.1
Entwicklung von Flink mit der DataStream-API
[Rails 6] API-Entwicklung mit GraphQL (Query)
HTML5-Entwicklung von Java mit TeaVM
Hinweise zur MOD-Entwicklung mit Minecraft 14.4 Fabric API # 1
Erstellen einer Kotlin-Entwicklungsumgebung mit SDKMAN
Spieleentwicklung mit zwei Personen mit Java 2
Spieleentwicklung mit zwei Personen mit Java 1
Spieleentwicklung mit zwei Personen mit Java 3