Я прочитал много , пытаясь найти способ чистого использования списков в древовидной грамматике ANTLR. Вот то, что я попробовал и их результаты (я действительно надеюсь, что упускаю что-то тривиальное) ...
Использование + = Синтаксис
program returns [someInterface result]
: m+=method* EOF {result = new SomeClass(m);};
method returns [SomeMethod result] : <definition here>
Это не с ...
правило '+ =' метки списка не допускаются
без опции вывода
Если я установлю для вывода либо «AST», либо «template» (единственные опции), сигнатуры методов сгенерированного класса изменятся. То есть m
будет не списком SomeMethod, а списком узлов или шаблонов соответственно. Я открыт для предложений, если есть способ заставить этот метод работать.
Использование областей действия правил
program returns [CompilesToJavaByteCode result]
scope {
List<SomeMethod> methods;
}
@init {
$program::methods = new ArrayList<SomeMethod>();
}
: (m=method {$program::methods.add(m);})*
EOF {result = new SomeClass($program::methods);};
Кажется, это работает, хотя я признаю, что я еще не тестировал его с вложенными / рекурсивными случаями.
Конечная цель
Я хочу создать набор классов, представляющих мой язык (класс, метод, переменная, оператор и т. Д.), Чтобы я мог провести некоторый статический анализ и оптимизацию перед созданием скомпилированного кода. Для этого мне нужно иметь возможность использовать списки. Я ожидал, что синтаксис + = «просто сработает», но я мог что-то упустить. Второй метод работает, но кажется слишком многословным и не элегантным.
Вопрос
Как правильно использовать список в древовидной грамматике ANTLR для перехода к моим конкретным классам?