の直後に何も配置しない.*
と、ANTLR は可能な限り (EOF まで) 消費します。したがって、ルールは次のとおりです。
DATA : .*;
変更する必要があります( の後 .*
に何かがある必要があります)。
また、すべてのレクサー ルールは、少なくとも 1 つの文字に一致する必要があります。ただし、STREAM
ルールが空の文字列と一致する可能性があり、レクサーが無限の数の空の文字列トークンを作成する原因になります。
最後に、ANTLR はバイナリ データではなく、テキスト入力を解析することを目的としています。詳細については、ANTLR メーリング リストでこの Q&Aを参照するか、リストで検索してください。
編集
の後に何かを配置するだけでなく.*
、レクサーで「手動の」先読みを少し実行することもできます。レクサーが先に何かを「見る」まで文字を消費し続けるように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...