0

我对 antlr 4 Lexer.getCharPositionInLine() 函数的理解是,它应该返回“标记的第一个字符从零开始计数的行内的字符位置”——The Definitive Antlr 4 Reference

使用下面的 antlr 4 语法,Lexer 函数 getCharPositionInLine() 似乎总是返回 0。注意 COMMENT lexer 规则中的 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 : ~[\u000c\r\n] ;

我从命令行使用这三个命令:

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 词法分析器规则包括匹配换行符,所以词法分析器已经将行号加一并将字符位置重置为 0。但是,这与“The Definitive Antlr 4 Reference”中的文档不匹配说。我究竟做错了什么?或者这是 Antlr 4 中的错误?

4

1 回答 1

2

Token.getCharPositionInLine()Lexer.getCharPositionInLine(). 后者返回当前的词法分析器位置,对于您的操作而言,该位置显然始终为 0,因为您的操作立即放置在所需的换行符之后。

于 2013-10-23T04:04:51.853 回答