Guten Tag!
Wie kann ich eine einfache ANTLR-Grammatik erstellen, die mehrzeilige Ausdrücke ohne Semikolon oder umgekehrte Schrägstriche behandelt?
Ich versuche eine einfache DSLs für Ausdrücke zu schreiben:
%Vor%Insgesamt möchte ich, dass meine Anwendung dem Skript einige anfängliche benannte Werte zur Verfügung stellt und das Endergebnis herauszieht. Ich bin jedoch auf die Syntax angewiesen. Ich möchte mehrere Zeilenausdrücke wie die folgenden unterstützen:
%Vor%Ich begann mit einer ANTLR-Grammatik wie folgt:
%Vor%Es scheint einfach, aber ich habe bereits Probleme mit den Zeilenumbrüchen:
%Vor%Grafisch in org.antlr.works.IDE:
Ich habe die Grammatik gekickt, aber immer mit Verletzungen des erwarteten Verhaltens:
Ich kann Beispiel-ANTLR-Grammatiken mit vielen dieser Eigenschaften finden. Ich finde, wenn ich sie abschneide, um ihre Ausdruckskraft auf das zu beschränken, was ich brauche, zerbringe ich am Ende etwas. Andere sind zu einfach, und ich breche sie, weil ich Ausdruckskraft hinzufüge.
Welchen Winkel sollte ich mit dieser Grammatik nehmen? Können Sie auf Beispiele verweisen, die keine trivialen oder vollständigen Turing-vollständigen Sprachen sind?
Ich würde Ihren Tokenizer das Heavy Lifting durchführen lassen, anstatt Ihre Newline-Regeln in Ihre Grammatik zu mischen:
Zählen Sie Klammern, Klammern und geschweifte Klammern, und generieren Sie keine NL-Tokens, wenn nicht geschlossene Gruppen vorhanden sind. Das gibt dir Zeilenweiterungen kostenlos, ohne dass deine Grammatik etwas weiser ist.
Generiere immer ein NL-Token am Ende der Datei, egal ob die letzte Zeile mit einem '\n'
-Zeichen endet oder nicht, dann musst du dir keine Gedanken über einen Sonderfall einer Anweisung ohne NL machen. Anweisungen immer enden mit einem NL.
Der zweite Punkt würde Ihnen helfen, Ihre Grammatik etwas zu vereinfachen:
%Vor%Ich nehme an, Sie haben entschieden, dass NL optional ist, weil die letzte Anweisung in Ihrem Eingabecode nicht mit einer neuen Zeile enden muss.
Obwohl es sehr sinnvoll ist, machen Sie das Leben für Ihren Parser viel schwieriger. Trennzeichen (wie NL) sollten geschätzt werden, da sie die Wahrscheinlichkeit von Konflikten deutlich machen und die Wahrscheinlichkeit von Konflikten verringern.
In Ihrem Fall weiß der Parser nicht, ob er "Zuweisung NL" oder "Zuweisung Leerzeile" analysieren soll. Es gibt viele Möglichkeiten, es zu lösen, aber die meisten von ihnen sind nur Band-Helfer für eine unkluge Design-Wahl.
Meine Empfehlung ist ein unschuldiger Hack: Machen Sie NL obligatorisch und hängen Sie NL immer an das Ende Ihres Eingabestreams an!
Es mag ein wenig unappetitlich erscheinen, aber in Wirklichkeit wird es Ihnen viele zukünftige Kopfschmerzen ersparen.