ANTLR4 - 如何在引号内区分不同?

时间:2016-03-28 20:53:33

标签: parsing antlr antlr4

我正在定义一个ANTLR4语法,并且我希望它在某些 - 但不是全部 - 标记出来时,它们出现在双引号内而不是出现在双引号之外。这是我到目前为止的语法:

grammar SimpleGrammar;

AND: '&';
TERM: TERM_CHAR+;
PHRASE_TERM: (TERM_CHAR | '%' | '&' | ':' | '$')+;
TRUNCATION: TERM '!';
WS: WS_CHAR+ -> skip;

fragment TERM_CHAR: 'a' .. 'z' | 'A' .. 'Z';
fragment WS_CHAR: [ \t\r\n];

// Parser rules
expr:
    expr AND expr
    | '"' phrase '"'
    | TERM
    | TRUNCATION
    ;

phrase:
    (TERM | PHRASE_TERM | TRUNCATION)+
    ;

上述语法在解析a! & b时有效,正确解析为:

  AND
  / \
 /   \
a!    b

但是,当我尝试解析"a! & b"时,我得到:

  

第1行:4个无关输入'&'期待{'“',TERM,PHRASE_TERM,TRUNCATION}

错误消息有意义,因为&被标记为AND。但是,我想要做的是将&标记为PHRASE_TERM,当它出现在双引号内(在“短语”内)时。请注意,即使a!出现在短语中,我也希望TRUNCATION标记为for (var property in object) { if (object.hasOwnProperty(property)) { // check objects properties for existence // do whatever you want to do } }

这可能吗?

1 个答案:

答案 0 :(得分:2)

如果您使用词法分析器模式,则可能。遇到特定令牌后可以更改模式。但词法分析规则必须单独定义,而不是组合语法。

在您的情况下,在遇到报价后,您将更改模式,在遇到其他报价后,您将模式更改回默认模式。

LBRACK : '[' -> pushMode(CharSet);
RBRACK : ']' -> popMode;

有关更多信息google'ANTLR lexer Mode'