如果我的用语不对,请原谅我。

可以说我有一些简化的语法:

// parser
expr : COMPARATIVE;

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


因此,这当然会匹配'boy vs girl''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中做到这一点。谢谢

最佳答案

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

comparative : ITEM WS* COMPARATOR WS* ITEM;


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

两个注意事项:


如果空格不重要,则可以将其从解析器规则中隐藏起来,如下所示:

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


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

comparative : ITEM COMPARATOR ITEM;

在ANTLR 4中,您可以使用新语法简化字符集:

WS : [ \t\r\n\u000C]+ -> channel(HIDDEN);

关于java - Antlr获取子 token ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15776494/

10-12 21:28