Ответ 1
Вы можете получить первый токен в правиле с помощью ctx.start
или ctx.getStart()
. Затем используйте getLine()
на токене, чтобы получить номер строки (и getCharPositionInLine()
, чтобы получить столбец).
Я пытаюсь получить номера строк для более конкретных сообщений об ошибках в моем 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: Мои правила lexer и parser довольно стандартизированы, например, в lexer:
INT : 'int' ;
CHAR : 'char' ;
BOOL : 'bool' ;
STRING : 'string' ;
... находится в правиле правила анализатораType:
baseType : INT | CHAR | BOOL | STRING ;
Вы можете получить первый токен в правиле с помощью ctx.start
или ctx.getStart()
. Затем используйте getLine()
на токене, чтобы получить номер строки (и getCharPositionInLine()
, чтобы получить столбец).
Вы можете использовать ctx.getSourceInterval()
, чтобы получить диапазон токенов, потребляемых правилом. Вы можете использовать TokenStream.get(int index)
, чтобы получить токен, связанный с интервалом источника, а затем получить информацию о позиции из токена.
Interval sourceInterval = ctx.getSourceInterval();
Token firstToken = commonTokenStream.get(sourceInterval.a);
int line = firstToken.getLine();