如果我的术语已经关闭,请原谅我。
让我说我有一点简化的语法:
// 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 [男孩vs女孩],即它匹配我的查询很好,但现在我希望能够做类似的事情,获得当前令牌的子标记。
我的直觉告诉我,我需要使用树,但在Antlr4中我真的不知道如何做这个例子。感谢
答案 0 :(得分:1)
目前,COMPARATIVE
是词法分析器规则,这意味着它将尝试从与规则匹配的所有文本中生成单个标记。您应该改为生成解析器规则comparative
:
comparative : ITEM WS* COMPARATOR WS* ITEM;
由于COMPARATIVE
将不再被视为单个令牌,因此您将获得ITEM
,WS
和COMPARATOR
的个人令牌。
两个旁注:
如果空格不重要,可以将其隐藏在解析器规则中,如下所示:
WS : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ -> channel(HIDDEN);
然后,您可以将comparative
解析器规则简化为:
comparative : ITEM COMPARATOR ITEM;
在ANTLR 4中,您可以使用新语法简化字符集:
WS : [ \t\r\n\u000C]+ -> channel(HIDDEN);