语法在单个带引号的字符串中否定词法规则中的两个相似字符

时间:2017-02-22 21:39:09

标签: antlr antlr4 parser-generator

ANLTR 4:

我需要支持带有转义字符的单引号字符串文字,并且能够使用双花括号作为转义序列'这将需要额外的解析。因此,需要支持这两个示例。我并不那么担心第二个例子,因为如果我能让第一个工作并且不匹配双花括号字符,这似乎微不足道。

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 
: '{' ~'{' 
| ~'{' .;

我已经对此进行了大量研究,并且明白你不能否定多个角色,甚至在这篇文章中看到类似的方法在巴特的答案中有用...... / p>

Negating inside lexer- and parser rules

但我所看到的是,在上面的示例1中,转义的单引号未被识别,并且我得到一个无法匹配的解析器错误'字符'

如果我将字符串文字标记规则更改为以下它可以...

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

如何更好地处理这种情况?我可以推断,转义后的角色会被 AnyExceptDblCurlies 而不是 ESC 匹配,但我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

要解析字符串中的模板定义,需要在解析器中进行处理。使用词法分析器模式区分字符串字符和模板名称。

分析器:

options {
    tokenVocab = TesterLexer ;
}

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

词法:

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  : '}}' ;

更新了以更正TMPLNAME规则,添加主规则和选项块。