我有两个语法文件/访问者,简单和复杂,它们将JSON对象解析为字符串。我要解析的Complex对象本质上可以包含许多Simple对象(以及其他内容)。为了简单起见,假设当我解析基本的Simple对象(而不是Complex对象中包含的Simple对象)时,我想使用类似“ Simple start:”的字符串开头,但是当我到达Complex对象中的Simple对象时我想从别的东西开始,说“ Simple in Complex:”。
因此,当前我有两个不同的访问者类,简单访问者的visitSimpleObject
方法将返回以“ Simple Start:”开头的字符串,而复杂访问者的visitSimpleObject
方法将返回以“ Simple Start”开头的字符串在Complex中:“。除了这种区别之外,其他所有对象都应该相同,无论是在对象本身还是在Complex对象内部,Simple对象中的其他所有内容都可以解析为相同。
我的问题是,如何在这两个访问者之间共享代码?显然,我可以将所有适用的SimpleVisitor
代码复制并粘贴到ComplexVisitor
中,但随后必须保持同步以进行任何更改。
注意:两个访问者类已经扩展了BaseVisitor
类,所以我不能使用典型的继承
答案 0 :(得分:0)
您可以使用继承来做到这一点,例如: https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
一个简短的例子是:
abstract class Visitor{
public void sharedMethod() {
//Do something
}
public abstract void visitSimpleObject();
}
class SimpleVisitor extends Visitor{
@Override
public void visitSimpleObject() {
System.out.println("Simple Start:");
}
}
class ComplexVisitor extends Visitor{
@Override
public void visitSimpleObject() {
System.out.println("Simple within Complex:");
}
}
在这种情况下,两个访问者都将从共享代码所在的同一超类(访问者)扩展。这两个子类都可以定义自己的行为。超类本身也可以扩展其他类型的访问者(或实现接口)。
评论之后,可能更像这样:
示例g4: 语法Ex;
START_COMPLEX : 'complex';
START_SIMPLE : 'simple';
SEPERATOR : ':';
TEXT : [A-Za-z]+;
simple : START_SIMPLE ' ' SEPERATOR ' ' TEXT;
complex : START_COMPLEX ' ' SEPERATOR ' ' TEXT;
还有一个代码示例:
public class Example{
abstract class Visitor extends ExBaseVisitor<String>{
@Override
public String visitComplex(ExParser.ComplexContext ctx) {
System.out.println("Visiting complex");
return "";
}
}
class SimpleVisitor extends Visitor{
@Override
public String visitSimple(ExParser.SimpleContext ctx) {
System.out.println("Visiting Simple! " + ctx.TEXT());
return "";
}
}
class ComplexVisitor extends Visitor{
@Override
public String visitSimple(ExParser.SimpleContext ctx) {
System.out.println("Visiting Simple, from within complex! " + ctx.TEXT());
return "";
}
}
public static void main(String[] args) {
String text = "simple : hi";
CharStream charStream = new ANTLRInputStream(text);
ExLexer exLexer = new ExLexer(charStream);
TokenStream tokenStream = new CommonTokenStream(exLexer);
ExParser exParser = new ExParser(tokenStream);
ComplexVisitor complexVisitor = new Example().new ComplexVisitor();
complexVisitor.visit(exParser.simple());
String text2 = "simple : hmmmmm";
CharStream charStream2 = new ANTLRInputStream(text2);
ExLexer exLexer2 = new ExLexer(charStream2);
TokenStream tokenStream2 = new CommonTokenStream(exLexer2);
ExParser exParser2 = new ExParser(tokenStream2);
SimpleVisitor simpleVisitor = new Example().new SimpleVisitor();
simpleVisitor.visit(exParser2.simple());
}
}
对我来说,此打印:
从复杂内部访问简单!嗨
访问简单! hmmmmm
现在共享的代码是visitComplex,这可能有点愚蠢,但对于示例来说可能还可以。