2015-04-22 12 views
6

Viele Sprachen verpflichtet, eine Zeichenfolge mit irgendeiner Art von Zitat, wie folgt aus:Wie kann ich einen Escape-Charakter mit ANTLR 4 entkommen lassen?

QuotedString : '"' .*? '"';

zu benutzen:

"Rob Malda is smart."

ANTLR 4 kann mit einem Lexer Regel wie diese eine solche Zeichenfolge übereinstimmen bestimmte Zeichen in der Zeichenfolge, sie müssen maskiert werden, etwa so:

"Rob \"Commander Taco\" Malda is smart."

ANTLR 4 kann diese Zeichenfolge ebenfalls abgleichen;

EscapedString : '"' ('\\"|.)*? '"';

(genommen von P96 von The Definitive ANTLR 4 Referenz)

Hier ist mein Problem: Nehmen wir an, dass das Zeichen für die Flucht der gleichen Charakter wie der String-Begrenzer ist. Zum Beispiel:

"Rob ""Commander Taco"" Malda is smart."

(. Dies ist völlig legal in Powershell)

Welche Lexer Regel würde dieses Spiel? Ich würde denken, dies funktionieren würde:

EscapedString : '"' ('""'|.)*? '"';

Aber es funktioniert nicht. Der Lexer markiert das Escape-Zeichen " als das Ende des Zeichenfolgebegrenzers.

Antwort

7

Negieren bestimmte Zeichen mit dem ~ Betreiber:

EscapedString : '"' ('""' | ~["])* '"'; 

oder, wenn es keine Zeilenumbrüche in der Zeichenfolge sein kann, tun:

EscapedString : '"' ('""' | ~["\r\n])* '"'; 

Sie wollen nicht die verwenden nicht-gieriger Operator, sonst würde "" niemals verbraucht werden und "a""b" würde als "a" und "b" anstelle eines einzelnen Tokens Tokens werden.

+1

Es funktioniert, danke. Aber es funktioniert nur, wenn ich den gierigen Quantifizierer benutze, nicht den nicht-gierigen. Warum das? –

+1

@ james.garriss du bist willkommen. Ich habe einige zusätzliche Informationen zum nicht-gierigen Matching hinzugefügt. –

+0

Es ist sehr interessant zu sehen, wie die Negation wie ein nicht gieriger Quantifizierer funktioniert. Cool. –

1

(Wählen Sie nicht für diese Antwort; Votum für @Bart Kiers' Antwort.)

Ich biete diese auf Vollständigkeit, da es ein kleines Stück einer Powershell-Grammatik ist. die Escape-Logik von p76 in The Definitive ANTLR 4 Referenz mit Bart Antwort kombinierend, hier sind die Regeln für lexing notwendig entkam Strings in Powershell:

EscapedString 
    : '"'  (Escape | '""' | ~["])* '"' 
    | '\''  (Escape | '\'\'' | ~['])* '\'' 
    | '\u201C' (Escape | .)*? ('\u201D' | '\u2033') // smart quotes 
    ; 

fragment Escape 
    : '\u0060\'' // backtick single-quote 
    | '\u0060"'  // backtick double-quote 
    ; 

Diese Regeln behandeln die folgenden vier Möglichkeiten Strings in Powershell zu entkommen:

'Rob ''Commander Taco'' Malda is smart.' 
"Rob ""Commander Taco"" Malda is smart." 
'Rob `'Commander Taco`' Malda is smart.' 
"Rob `"Commander Taco`" Malda is smart."