Без чего-либо, непосредственно размещенного после .*
, ANTLR будет потреблять как можно больше (до EOF). Итак, правило:
DATA : .*;
должно быть изменено (должно быть что-то после .*
).
Кроме того, каждое правило лексера должно как минимум соответствовать одному символу. Но ваше правило STREAM
может потенциально соответствовать пустой строке, из-за чего ваш лексер может создавать бесконечное количество пустых лексем.
Наконец, ANTLR предназначен для анализа текстового ввода, а не двоичных данных. См. эти вопросы и ответы в списке рассылки ANTLR для получения дополнительной информации или выполните поиск в списке .
EDIT
Помимо размещения чего-либо после .*
, вы также можете выполнить немного «ручного» просмотра в лексере. Небольшая демонстрация того, как вы можете сказать ANTLR продолжать потреблять символы, пока лексер не «увидит» что-то впереди ("HDR"
, в вашем случае):
grammar T;
@parser::members {
public static void main(String[] args) throws Exception {
String input = "HDR1 foo HDR2 bar \n\n baz HDR3HDR4 the end...";
TLexer lexer = new TLexer(new ANTLRStringStream(input));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.parse();
}
}
@lexer::members {
private boolean hdrAhead() {
return input.LA(1) == 'H' &&
input.LA(2) == 'D' &&
input.LA(3) == 'R';
}
}
parse : stream EOF;
stream : packet*; // parser rules _can_ match nothing
packet : HEADER DATA? {System.out.println("parsed :: " + $text.replaceAll("\\s+", ""));};
HEADER : 'HDR' '0'..'9'+;
DATA : ({!hdrAhead()}?=> .)+;
Если вы запустите демонстрацию выше:
java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar TParser
(в Windows последняя команда: java -cp .;antlr-3.3.jar TParser
)
на консоль выводится следующее:
parsed :: HDR1foo
parsed :: HDR2barbaz
parsed :: HDR3
parsed :: HDR4theend...
для входной строки:
HDR1 foo HDR2 bar
baz HDR3HDR4 the end...