2017-02-22 3 views
2

ANLTR 4 in einem einzigen String in Anführungszeichen zwei gleiche Zeichen in einer Lexer Regel zu negieren 'Das wird zusätzliche Parsing benötigen. Daher müssen beide Beispiele unterstützt werden. Ich bin nicht so besorgt um das zweite Beispiel, denn das scheint trivial zu sein, wenn ich das erste zum Laufen bringen kann und nicht doppelte geschweifte Klammercharaktere.Grammar

1. 'this is a string literal with an escaped\' character' 2. 'this is a string {{functionName(x)}} literal with double curlies'

StringLiteral 
: '\'' (ESC | AnyExceptDblCurlies)*? '\'' ; 

fragment 
ESC : '\\' [btnr\'\\]; 

fragment 
AnyExceptDblCurlies 
: '{' ~'{' 
| ~'{' .; 

ich viel Forschung auf diesem getan haben und verstehen, dass Sie nicht mehrere Zeichen negieren können, und haben auch einen ähnlichen Ansatz Arbeit in Barts Antwort in diesem Beitrag nicht gesehen ...

Negating inside lexer- and parser rules

Aber was ich sehe ist, dass im obigen Beispiel 1, das entwichene Apostroph wird nicht erkannt wird und ich einen Parser-Fehler erhalten, dass es nicht ‚Charakter‘ mithalten kann.

, wenn ich die Stringliteral Token-Regel das ändern folgende es funktioniert ...

StringLiteral 
: '\'' (ESC | .)*? '\'' ; 

Irgendwelche Ideen, wie man dieses Szenario behandeln besser? Ich kann ableiten, dass der Escape-Zeichen von AnyExceptDblCurlies statt ESC abgeglichen wird, aber ich bin mir nicht sicher, wie dieses Problem zu lösen ist.

+0

müssen Sie wirklich den Inhalt eines String-Literals zu diesem Zeitpunkt tokenisieren? Sie sagen nicht, welche Art von Grammatik Sie verwenden; Ich denke an Sprachen wie C oder C#, die normalerweise das Parsen von Literalen zu Laufzeitfunktionen, printf, String.Format und dergleichen lassen – dlatikay

+0

@dlatikay, ich muss in der Lage sein, den Fall zu analysieren, wo das Literal '{{x} enthält } ', so kann ich nicht bis zur Laufzeit verzögern. Schlägst du vor, dass es einfacher ist, diesen Fall auf Parser-Regelebene zu behandeln? – ichrisnichols

+0

Ich sehe ... ja, Parser-Regel> es erinnert mich an [diese] (http://stackoverflow.com/questions/1850468/parsing-string-interpolation-in-antlr) – dlatikay

Antwort

1

Um die Template-Definition aus der Zeichenkette zu analysieren, muss man sich im Parser ziemlich gut zurechtfinden. Verwenden Sie Lexer-Modi, um zwischen Zeichenfolgen und dem Vorlagennamen zu unterscheiden.

Parser:

options { 
    tokenVocab = TesterLexer ; 
} 

test : string EOF ; 
string : STRBEG (SCHAR | template)* STREND ; // allow multiple templates per string 
template : TMPLBEG TMPLNAME TMPLEND ; 

Lexer:

STRBEG : Squote -> pushMode(strMode) ; 

mode strMode ; 
    STRESQ : Esqote -> type(SCHAR) ; // predeclare SCHAR in tokens block 
    STREND : Squote -> popMode ; 
    TMPLBEG : DBrOpen -> pushMode(tmplMode) ; 
    STRCHAR : .  -> type(SCHAR) ; 

mode tmplMode ; 
    TMPLEND : DBrClose -> popMode ; 
    TMPLNAME : ~'}'* ; 

fragment Squote : '\'' ; 
fragment Esqote : '\\\'' ; 
fragment DBrOpen : '{{' ; 
fragment DBrClose : '}}' ; 

Aktualisiert die TMPLNAME Regel zu korrigieren, fügen Hauptregel und Optionen blockieren.

+0

das sieht genau so aus, was ich brauche ... Ich stoße weiterhin auf eine Mauer und versuche, semantische Prädikate zu verwenden, aber die Verwendung eines Modus-Stacks scheint das Ticket zu sein! Lassen Sie mich das ausprobieren ... Ich kann nicht glauben, dass dieses Szenario eine solche Artikulation erfordert. – ichrisnichols

+0

GRosenberg, ich kann nicht einmal die einfachsten Versionen Ihres Beispiels in ANTLR kompilieren, mit dem Ziel C# (.NET 4.5.2) ... Ich habe ein paar Bugs in Ihrem Sample korrigiert, aber trotzdem scheint es mir nicht zu passen sogar ein einfacher String in Anführungszeichen ... Ich werde meinen Code in einem Update auf dem Hauptthread anzeigen. Bitte lassen Sie mich wissen, wenn ich etwas verpasse. – ichrisnichols

+0

Es wird angezeigt, dass dem Parser der Optionsblock fehlt: 'options { \t tokenVocab = TesterLexer; } Dies ist eine Standardanforderung aller Split-Grammatiken. – GRosenberg

Verwandte Themen