AFAIK, ANTLR v2.x буферизует создание токенов.Парсер принимает TokenBuffer , который в свою очередь принимает TokenStream .Затем этот TokenStream
опрашивается с помощью метода nextToken () , когда анализатору требуется больше токенов.
Другими словами, если вы предоставляете входной источник в виде файла, ANTLR не считывает весь файл и не создает его токены, но только при необходимости создаются (и удаляются) токены.
Обратите внимание, что я никогда не работал с ANTLR 2.x, поэтому я могу ошибаться.Вы наблюдали что-то другое?Если да, то как вы предлагаете источник ANTLR: в виде файла или в виде большой строки?Если это последнее, я рекомендую вместо этого предоставить файл.
РЕДАКТИРОВАТЬ
Допустим, вы хотите проанализировать файл, который состоит из строк с числами, разделенных пробелами (которые вы хотите игнорировать).Вы также хотите, чтобы ваш синтаксический анализатор обрабатывал файл построчно, так как сбор всех чисел одновременно может привести к проблемам с памятью.
Это можно сделать, разрешив правилу основного синтаксического анализатора parse
возвращать список чисел для каждой строки.Если достигнут EOF
(конец файла), вы просто возвращаете null
вместо списка.
Демонстрация с использованием ANTLR 2.7.6:
file: My.g
class MyParser extends Parser;
parse returns [java.util.List<Integer> numbers]
{
numbers = new java.util.ArrayList<Integer>();
}
: (n:Number {numbers.add(Integer.valueOf(n.getText()));})+ LineBreak
| EOF {numbers = null;}
;
class MyLexer extends Lexer;
Number
: ('0'..'9')+
;
LineBreak
: ('\r')? '\n'
;
Space
: (' ' | '\t') {$setType(Token.SKIP);}
;
файл: Main.java
import antlr.*;
public class Main {
public static void main(String[] args) throws Exception {
MyLexer lexer = new MyLexer(new java.io.StringReader("1 2 3\n4 5 6 7 8\n9 10\n"));
MyParser parser = new MyParser(new TokenBuffer(lexer));
int line = 0;
java.util.List<Integer> numbers = null;
while((numbers = parser.parse()) != null) {
line++;
System.out.println("line " + line + " = " + numbers);
}
}
}
Для запуска демонстрации:
* nix
java -cp antlr-2.7.6.jar antlr.Tool My.g
javac -cp antlr-2.7.6.jar *.java
java -cp .:antlr-2.7.6.jar Main
или на:
Windows
java -cp antlr-2.7.6.jar antlr.Tool My.g
javac -cp antlr-2.7.6.jar *.java
java -cp .;antlr-2.7.6.jar Main
, который будет выдавать следующий вывод:
line 1 = [1, 2, 3]
line 2 = [4, 5, 6, 7, 8]
line 3 = [9, 10]
Предупреждение
Любой, кто пытается этот код, пожалуйста, обратите внимание, чтоэто использует ANTLR 2.7.6.Если у вас нет веских причин для использования этой версии, настоятельно рекомендуется использовать последнюю стабильную версию ANTLR (v3.3 на момент написания этой статьи).