Вы должны поместить инициализацию своих списков в блок @init { ... }
правил, которые выполняются до того, как что-либо в правиле будет найдено.
Кроме того, ваше правило element
должно быть не правилом парсера, а правилом лексера (оно должно начинаться с заглавной буквы!).
И точка входа вашего парсера, правило prog
, должно заканчиваться токеном EOF
, иначе парсер может остановиться до того, как все токены будут обработаны правильно.
Наконец, секция @header { ... }
применяется только к парсеру (это сокращение для @parser::header { ... }
), вам также необходимо добавить объявление пакета в лексер.
Рабочая демонстрация:
SmallTest.g
grammar SmallTest;
@header {
package parseTest;
import java.util.ArrayList;
}
@lexer::header {
package parseTest;
}
prog returns [ArrayList<ArrayList<String>> all]
@init {$all = new ArrayList<ArrayList<String>>();}
: (stat {$all.add($stat.res);})+ EOF
;
stat returns [ArrayList<String> res]
@init {$res = new ArrayList<String>();}
: (ELEMENT {$res.add($ELEMENT.text);})* NEWLINE
;
ELEMENT : ('a'..'z'|'A'..'Z')+ ;
NEWLINE : '\r'? '\n' ;
SPACE : ' ' {skip();};
Main.java
package parseTest;
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
SmallTestLexer lexer = new SmallTestLexer(new ANTLRStringStream("a bb ccc\ndddd eeeee\n"));
SmallTestParser parser = new SmallTestParser(new CommonTokenStream(lexer));
System.out.println(parser.prog());
}
}
И чтобы запустить все это, сделайте:
java -cp antlr-3.3.jar org.antlr.Tool parseTest/SmallTest.g
javac -cp .:antlr-3.3.jar parseTest/*.java
java -cp .:antlr-3.3.jar parseTest.Main
, что дает:
[[a, bb, ccc], [dddd, eeeee]]