0

如果我的术语不正确,请原谅我。

假设我有一点简化的语法:

// parser
expr : COMPARATIVE;

// lexer
WS : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+; 
COMPARATOR 
        : 'vs'
    | 'versus'
        ;
ITEM 
        : 'boy'
        | 'girl'
        ;
COMPARATIVE :ITEM WS* COMPARATOR WS* ITEM;

所以这当然会匹配'boy vs girl'or'girl vs boy'等​​。但我的问题是当我创建 Lexer 时,即

CharStream stream = new ANTLRInputStream("boy vs girl");
SearchLexer lex = new SearchLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lex);
tokens.fill();
for(Token token : tokens) {
    System.out.print(token.getType() + " [" + token.getText() + "] ");
}

这会打印出类似这样的内容:9 [boy vs girl],即它与我的查询匹配得很好,但现在我希望能够执行类似的操作,获取当前令牌的子令牌。

我的直觉告诉我我需要使用树,但对于我的示例,我真的不知道如何在 Antlr4 中执行此操作。谢谢

4

1 回答 1

1

目前,COMPARATIVE是一个词法分析器规则,这意味着它将尝试从与该规则匹配的所有文本中生成单个标记。您应该改为制定解析器规则comparative

comparative : ITEM WS* COMPARATOR WS* ITEM;

由于COMPARATIVE将不再被视为单个令牌,因此您将获得ITEMWS和的单独令牌COMPARATOR

两个旁注:

  1. 如果空格不重要,您可以将其隐藏在解析器规则中,如下所示:

    WS : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ -> channel(HIDDEN);
    

    然后,您可以将comparative解析器规则简化为:

    comparative : ITEM COMPARATOR ITEM;
    
  2. 在 ANTLR 4 中,您可以使用新语法来简化字符集:

    WS : [ \t\r\n\u000C]+ -> channel(HIDDEN);
    
于 2013-04-03T00:19:14.853 回答