Может ли ANTLR возвращать строки кода при лексинге? - PullRequest
0 голосов
/ 30 марта 2012

Я пытаюсь использовать ANTLR для анализа большого набора кода с использованием полной грамматики Java.Поскольку ANTLR нужно открыть все исходные файлы и сканировать их, мне интересно, может ли он также вернуть строки кода.

Я проверил API для Lexer и Parser, похоже, они не возвращают LoC.Легко ли немного сложить грамматическое правило, чтобы получить LoC?Полное правило Java сложное, я не хочу сильно его испортить.

Ответы [ 3 ]

0 голосов
/ 31 марта 2012

В цели C структура данных ANTLR3_INPUT_STREAM имеет функцию getLine (), которая возвращает текущую строку из потока ввода.Кажется, Java-версия этого - CharStream.getLine ().Вы должны быть в состоянии вызвать это в любое время и получить текущую строку во входном потоке.

0 голосов
/ 18 августа 2015

Используйте посетителя, чтобы посетить контекст CompilationUnit, затем context.stop.getLine () выдаст вам номер последней строки контекста модуля компиляции.

@Override public Integer visitCompilationUnit(@NotNull JAVAParser.CompilationUnitContext ctx) {
    return ctx.stop.getLine();
}
0 голосов
/ 30 марта 2012

Если у вас есть существующая грамматика ANTLR и вы хотите подсчитывать определенные вещи во время анализа, вы можете сделать что-то вроде этого:

grammar ExistingGrammar;

// ...

@parser::members {
  public int loc = 0;
}

// ...

someParserRule
 : SomeLexerRule someOtherParserRule {loc++;}
 ;

// ...

Итак, всякий раз, когда ваш опарсер встречает someParserRule, вы увеличиваете loc на единицу, помещая {loc++;} после (или до) правила.

Итак, каким бы ни было ваше определение строки кода , просто поместите {loc++;} в правило, чтобы увеличить счетчик. Будьте осторожны, чтобы не увеличить его вдвое:

statement
 : someParserRule {loc++;}
 | // ...
 ;

someParserRule
 : SomeLexerRule someOtherParserRule {loc++;}
 ;

EDIT

Я только что заметил, что в заголовке вашего вопроса вы спрашивали, можно ли это сделать во время лексизма. Это не будет возможно. Допустим, LoC всегда заканчивается ';'. Во время lexing вы не сможете провести различие между ';' после, скажем, присваивания (которое является одним LoC), и 2 ';' s внутри оператора for(int i = 0; i < n; i++) { ... } (который не будет быть 2 LoC).

...