我有一个antlr4词法语法。 它有话很多规则,但我也希望它的任何字,它不能被其它规则匹配创建一个未知的令牌。 我有这样的事情:
Whitespace : [ \t\n\r]+ -> skip;
Punctuation : [.,:;?!];
// Other rules here
Unknown : .+? ;
现在生成的匹配器卡子“〜”为未知的,但对于输入创建3“〜”未知令牌“~~~”,而不是一个单一的“~~~”令牌。 我应该怎么做,告诉词法分析器来生成未知的连续字符字令牌。 我也试过“未知:。” 和“未知:+;” 没有结果。
编辑:在当前的ANTLR版本中+? 现在抓住剩余的话,那么这个问题似乎得到解决。
.+?
在词法规则的结尾总是会匹配单个字符。 但是.+
会消耗尽可能多的,这是在ANTLR V3(V4可能还有)一个统治的结束非法的。
你可以做的仅仅是匹配单个字符,而“粘”在一起,这些在解析器:
unknowns : Unknown+ ;
...
Unknown : . ;
编辑
...但我只有一个词法分析器,没有分析器...
啊,我明白了。 然后,你可以重写nextToken()
方法:
lexer grammar Lex;
@members {
public static void main(String[] args) {
Lex lex = new Lex(new ANTLRInputStream("foo, bar...\n"));
for(Token t : lex.getAllTokens()) {
System.out.printf("%-15s '%s'\n", tokenNames[t.getType()], t.getText());
}
}
private java.util.Queue<Token> queue = new java.util.LinkedList<Token>();
@Override
public Token nextToken() {
if(!queue.isEmpty()) {
return queue.poll();
}
Token next = super.nextToken();
if(next.getType() != Unknown) {
return next;
}
StringBuilder builder = new StringBuilder();
while(next.getType() == Unknown) {
builder.append(next.getText());
next = super.nextToken();
}
// The `next` will _not_ be an Unknown-token, store it in
// the queue to return the next time!
queue.offer(next);
return new CommonToken(Unknown, builder.toString());
}
}
Whitespace : [ \t\n\r]+ -> skip ;
Punctuation : [.,:;?!] ;
Unknown : . ;
运行它:
java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Lex.g4
javac -cp antlr-4.0-complete.jar *.java
java -cp .:antlr-4.0-complete.jar Lex
将打印:
Unknown 'foo'
Punctuation ','
Unknown 'bar'
Punctuation '.'
Punctuation '.'
Punctuation '.'
文章来源: In antlr4 lexer, How to have a rule that catches all remaining “words” as Unknown token?