Вы можете указать параметры и возвращаемые значения для правил, как показано в принятом ответе здесь .Сэм Харвелл отвечает на принятый ответ:
Имейте в виду, что каждое использование этой функции усложнит переход к ANTLR 4, где использование пользовательских аргументов и возвращаемых значений в грамматике "обескуражен "в лучшем случае.
Я предполагаю, что способ сделать это - не встроить его в грамматику, но я не могу понять, как это сделать (переопределение / перегрузка методов, которые я предполагаю? Но как ??)
Это фиктивная грамматика:
grammar testing;
@header{package testing;}
program: dataset+;
dataset: ID ds_options* ';';
ds_options
: (NEW|DROP) ID+ #newdrop
| RENAME ID #rename
;
DROP: 'drop';
NEW: 'new';
RENAME: 'rename';
ID: [A-Z0-9]+;
WS: [ \r\t\u000C\n]+ -> skip;
Вот как выглядит фиктивный класс набора данных:
package testing;
import java.util.ArrayList;
public class Dataset {
public String name;
public ArrayList<String> dropList;
public Dataset(String name) {
this.name = name;
dropList = new ArrayList<String>();
}
public void addDropVar(String var) {
dropList.add(var);
}
}
Мой класс приложения:
package testing;
import java.util.ArrayList;
import testing.testingParser.DatasetContext;
import testing.testingParser.NewdropContext;
import testing.testingParser.RenameContext;
public class Testing {
ArrayList<Dataset> datasets = new ArrayList<Dataset>();
public static class MyVisitor<T> extends testingBaseVisitor<T>{
@Override
public T visitDataset(DatasetContext ctx) {
return super.visitDataset(ctx);
}
@Override
public T visitNewdrop(NewdropContext ctx) {
// TODO Auto-generated method stub
return super.visitNewdrop(ctx);
}
@Override
public T visitRename(RenameContext ctx) {
// TODO Auto-generated method stub
return super.visitRename(ctx);
}
}
public static void main(String args[]) {
}
}
input:
TEST0 new A B C D E F G H;
TEST0 drop A B C new U;
TEST1 drop J K;
TEST1 rename TEST88;
TEST0 new E F;
TEST0;
TEST1;
TEST1;
TEST1 new A B;
TEST0;
TEST0 new A B X Y drop B C D Q R;
TEST1 rename TEST3;
ожидаемый результат:
TEST0 new A B C D E F G H; /*called TEST0 new dataset with vars A to H*/
TEST0 drop A B C new U; /*A B C removed from TEST0, U created in TEST0*/
TEST1 drop J K; /*does nothing because TEST1 hasn't been created*/
TEST1 rename TEST88; /*does nothing*/
TEST0 new E F; /*does nothing these already exist in this dataset*/
TEST0;
TEST1;
TEST1;
TEST1 new A B; /*TEST1 created with vars A B*/
TEST0;
TEST0 new A B X Y drop B C D Q R; /*A B X Y created in TEST0, B C D Q R deleted from TEST0*/
TEST1 rename TEST3; /*TEST1 renamed to TEST3*/
/*I should have TEST3 with vars A B and TEST1 with vars A E-H U X Y*/
Проблема заключается в том, что если я перегружу методы из testingBaseVisitor, они не будут вызваны из общего метода visit () в суперклассе.