java - 规则参数和规则返回值;antlr4 中的替代方案是什么?
问题描述
您可以为规则指定参数和返回值,如在这里接受的答案中所示。Sam Harwell 回复接受的答案:
请记住,每次使用此功能都会使过渡到 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[]) {
}
}
输入:
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() 调用。
解决方案
- 与其将数据集传递给语句,不如将语句访问者生成的值返回给数据集访问者更容易(并且可能更好)。
- 类 testingBaseVisitor 的多个扩展应该在类 Testing 中实现,一个对应于特定访问者返回的每个 T 类型。
Jakub Dziworski 的例子很有帮助。它显示了如何解决这两个问题。
推荐阅读
- html - 盒子阴影仅适用于标题
- hadoop - 使用转义字符创建外部 Hadoop 表
- reporting-services - SSRS - 我想过滤平均值中使用的数据
- reactjs - 使用 Formik 和 Yup 在 React 中未提交表单
- unity3d - Rigidbody2d 相互挤压,为什么?
- javascript - jsonResponse 返回 id 而不是对象名 django
- latex - for-loop LaTeX \i 减法
- android - 默认情况下,标签和条目在 Xamarin.Forms 中没有颜色
- matplotlib - matplotlib 按钮未触发
- c++ - C++ 中的每个表达式是否都有非指针类型,如非引用类型