我对antlr 4 Lexer.getCharPositionInLine()函数的理解是,它应该返回"标记的第一个字符从零开始计数的行内的字符位置" --The Definitive Antlr 4 Reference
使用以下 antlr 4 语法,似乎词法分析器函数 getCharPositionInLine() 总是返回 0。 请注意 COMMENT 词法分析器规则中的 Java 代码。 它包含打印从getCharPositionInLine()返回的值的代码。
grammar Expr;
compilUnit : stat+ EOF ;
stat : assign NEWLINE ;
assign : IDENT ASSIGN INT ;
// Lexer rules
ASSIGN : '=' {System.out.println(getLine() + ":" + getCharPositionInLine() + " /" + getText() + "/");} ;
APOS : ''' {System.out.println(getLine() + ":" + getCharPositionInLine() + " /" + getText() + "/");} ;
INT : ('0' | '-'? [1-9][0-9]*) {System.out.println(getLine() + ":" + getCharPositionInLine() + " /" + getText() + "/");} ;
IDENT : [a-zA-Z][a-zA-Z0-9]* {System.out.println(getLine() + ":" + getCharPositionInLine() + " /" + getText() + "/");} ;
/* For lines that have only a comment preceeded by optional white space,
* skip the entire line including the newline. For lines that have a
* comment preceeded by other code skip the comment and return a
* NEWLINE. */
COMMENT : [ t]* APOS NEND* END
{
int line = getLine();
int pos = getCharPositionInLine();
System.out.println("COMMENT " + line + ":" + pos + " /" + getText() + "/");
if (pos == 0) {
skip();
}
else {
setType(NEWLINE);
setText("n");
}
}
;
NEWLINE : END+ {System.out.println(getLine() + ":" + getCharPositionInLine() + " /" + getText() + "/");} ;
WS : [ t]+ {System.out.println(getLine() + ":" + getCharPositionInLine() + " /" + getText() + "/"); skip();} ;
fragment END : 'u000c'? 'r'? 'n' ;
fragment NEND : ~[u000crn] ;
我从命令行使用这三个命令:
java -jar antlr/antlr-4.1-complete.jar Expr.g4
javac -cp antlr/antlr-4.1-complete.jar Expr*.java
java -cp "antlr/antlr-4.1-complete.jar;." org.antlr.v4.runtime.misc.TestRig Expr compilUnit -tokens progs/hello.laf
对于此输入:
'Yo
x = 3 'Yay
我得到这个输出:
COMMENT 2:0 /'Yo
/
2:1 /x/
2:2 / /
2:3 /=/
2:4 / /
2:5 /3/
COMMENT 3:0 / 'Yay
/
[@0,4:4='x',<4>,2:0]
[@1,6:6='=',<1>,2:2]
[@2,8:8='3',<3>,2:4]
[@3,16:15='<EOF>',<-1>,3:0]
line 3:0 missing NEWLINE at '<EOF>'
看来,由于 COMMENT 词法分析器规则包括匹配换行符,因此词法分析器已将行号递增 1 并将字符位置重置为 0。 但是,这与"最终Antlr 4参考"中的文档所说的不符。 我做错了什么? 或者这是 Antlr 4 中的错误?
您将Token.getCharPositionInLine()
与Lexer.getCharPositionInLine()
混淆了。后者返回当前的词法分析器位置,对于您的操作,该位置显然始终为 0,因为您的操作紧跟在所需的换行符之后。