2016-10-31 3 views
1

Angenommen, Sie Grammatik mit Groß- und Kleinschreibung foo Token wie folgt definiert haben:Unterstützt ANTLR4 die Zuordnung eines Literals zu einem Token?

FOO : F O O ; 

fragment F:('f'|'F'); 
fragment O:('o'|'O'); 

Für dieses Token Vocabulary.getLiteralName(token) kehrt null, da es durch Anpassen eines Musters und nicht eine wörtliche Wert definiert wurde.

Hat Antlr4 eine eingebaute Möglichkeit, einen Literalwert für das Token foo in der Grammer-Definition anzugeben?

Antwort

1

Es gibt eine Methode toString() in fast jedem ANTLR4 Laufzeitklasse. Für hierarchische Elemente wie (Parse-) Bäume und Erkennungskontexte werden die untergeordneten Einträge in der Ausgabe von toString() aufgelistet, aber normalerweise mit irgendeiner Form der Formatierung (wie Komma-getrennte Listen).

Also, die Antwort ist: nein. Es gibt keine integrierte Möglichkeit, den Text eines Teilbaums als einzelne unformatierte Zeichenfolge abzurufen. Das Schreiben einer Verkettungsfunktion ist jedoch trivial. Erstellen Sie einfach eine Funktion getText (RuleContext-Kontext), die eine Zeichenfolge zurückgibt und die untergeordneten Elemente des Kontexts iteriert und getText() aufruft (oder das Vokabular verwendet) und gibt dann eine verkettete Zeichenfolge aus den Werten zurück.

+0

Danke. Ich interessiere mich mehr für einzelne Tokens als für Teilbäume, aber das ist gut zu wissen! – dnault

+0

Nun, sogar Lexer-Token können Teilbäume enthalten. Schließlich ist auch ein einzelner Knoten ein Teilbaum (nur ohne Kinder). –

1

getSymbolicName(int) sollte zurückkehren FOO für die Eingabe "foo":

TLexer lexer = new TLexer(new ANTLRInputStream("foo")); 

for (Token token : lexer.getAllTokens()) { 
    System.out.println(TLexer.VOCABULARY.getSymbolicName(token.getType())); 
} 
+0

Vielen Dank. Das ist die Technik, die ich benutzt habe, indem ich den wörtlichen Namen aus dem symbolischen Namen nach einer bestimmten Konvention ableite. Für Token, die von der Konvention abweichen, ist eine spezielle Handhabung erforderlich. Ich hatte gehofft, die Notwendigkeit für spezielle Behandlung in meinem Code zu beseitigen. – dnault

+0

"Aber für Token, die von der Konvention abweichen, ist eine spezielle Handhabung erforderlich." - nur kurios, in welchen Fällen gibt 'getSymbolicName (...) 'nicht das erwartete Ergebnis? –

+0

'getSymbolicName' verhält sich immer korrekt; Ich versuche nur den Token-Namen vom Literal-Namen zu entkoppeln. Die Konvention, die ich verwendet habe, ist es, "UPPER_UNDERSCORE" in "dot.separated.lowercase" zu konvertieren. Jetzt flirte ich mit der Idee, einige Tokens zu haben, wo der Literalwert Leerzeichen enthält, und ich würde eher nicht etwas wie "zwei Unterstriche in Folge bedeutet, ein Leerzeichen anstelle eines Punkts zu verwenden" sagen. – dnault

Verwandte Themen