获取ParserVisitor中的行号?

时间:2013-11-05 10:50:01

标签: antlr parse-tree

我正在尝试在ParserVisitor中获取更具体的错误消息的行号(访问由antlr生成的解析树)。但是,我在这个课程中的所有内容都是上下文ctx,我可以执行ctx.getText()而不是getLine()之类的操作。有没有办法做到这一点?

可以在这里使用ctx.getPayload()吗?如果是这样,怎么样?

编辑:我正在使用ANTLR 4来创建java文件。

尝试使用以下方法访问访问者中的行号:

@Override 
public Type visitStatAssign(@NotNull BasicParser.StatAssignContext ctx) {
...
// some semantic error detected
int lineNo = ...
System.err.("Semantic error at line " + lineNo); 
}

编辑2: 我的词法分析器和解析器规则是相当标准的,例如在词法分析器中:

INT : 'int' ;
CHAR : 'char' ;
BOOL : 'bool' ;
STRING : 'string' ; 

...在解析器规则baseType:

baseType : INT | CHAR | BOOL | STRING ; 

3 个答案:

答案 0 :(得分:30)

您可以使用ctx.startctx.getStart()获取规则中的第一个令牌。然后在令牌上使用getLine()获取行号(并getCharPositionInLine()获取列号。)

答案 1 :(得分:13)

您可以使用ctx.getSourceInterval()来获取规则所使用的令牌范围。您可以使用TokenStream.get(int index)获取与源间隔关联的令牌,然后从令牌获取位置信息。

Interval sourceInterval = ctx.getSourceInterval();
Token firstToken = commonTokenStream.get(sourceInterval.a);
int line = firstToken.getLine();

答案 2 :(得分:2)

如果有一个ParserRuleContext对象,则可以按照@njlarsson的建议直接获取行号:

ParserRuleContext ctx; 
int line = ctx.getStart().getLine();

但是,如果只有RuleContext对象,则需要先将其类型转换为ParserRuleContext:

RuleContext rctx;
ParserRuleContext ctx = (ParserRuleContext) rctx; 
int line = ctx.getStart().getLine();

注意:>>我正在使用ANTLR4 >>在上面的代码段中,为简洁起见,ctxrctx未初始化。您需要使用适当的值来初始化它们,例如ParserRuleContext ctx = parser.compilationUnit();