我正在为编译器构建一个解析器,以及我希望解析器找到的每个术语都有一个类(static
)方法。此方法应返回一个正则表达式,该表达式可用于确定Scanner提供的令牌是否为该术语,并将其表示为boolean
值。它应该是static
方法,保证所有派生类都有。
不幸的是,Java语言并不善待这种方法扩展。代码要么不编译,要么引用方法的错误版本。我相信我会自己提出一些解决方法,可能涉及反思或谨慎HashMap
;但这不是我第一次遇到像这样的问题,我很好奇。有没有其他人在这里提出一个解决方案,提供static
方法的可传递的可扩展性?
好的,让我们澄清一下。我不是在寻找一个为什么 - 不是这个编译,也不是在寻找一个怎么做我做这个工作。我正在寻找一种方法,通过该方法我可以检查一个方法,该方法不需要实例化类,可以依赖于任何扩展类的存在。并且,它需要为我的项目选择武器,即Java。
众所周知,我所讨论的事实上并不是一种静态方法(原谅我,我以为我很清楚),没有代码可以告诉你;而我所拥有的主要是切向的。我想出的是这个,在一个抽象的构造函数中:
public Item(String token) {
if(!check(token)) {
throw new MismatchException(this.getClass() + " cannot be instantiated for \"" + token + "\"");
}
this.setData(derive(token));
}
public abstract boolean check(String token);
同时,每个令牌的创建(在这个例子中,除了抽象的解析树之外)都是这样的(虽然我相信它仍然需要一点点抛光):
for(Sting token : tokenList) {
for(Class<?> cls : buildables) {
try {
Constructor constructor = cls.getConstructor(String.class);
result.add((Buildable)constructor.newInstance(c.toString()));
} catch(InvocationTargetException ex) {
//"MismatchException" is my own creation, for this exact purpose
if(ex.getTargetException() instanceof MismatchException)
continue;
} catch (Exception ex) {
//Again, a point for polishing:
ex.printStackTrace();
continue;
}
}
}
作为附录,对于那些真正想要查看当前项目代码的人,您可以在https://github.com/MichaelEricOberlin/Builder-Tutorial从github获取完成(并推送)的所有内容。无论如何,它当然是公开的。
编辑(David Wallace):
所以我们有一个类Foo
,方法public static void bar()
- 或者可能是不同的签名。然后我们有子类RedFoo
,GreenFoo
和BlueFoo
,每个子类都有自己的public static void bar()
版本。显然,这在Java中是非法的。问题是如何解决这个问题。
答案 0 :(得分:0)
我或多或少解决了这个问题:
用于终端符号的类Symbol
(一个RegexSymbol就足够了)和非终结符号(NonTerminalSymbol,SequenceSymbol,AlternativesSymbol,...)。子课程可以是本地包。
类Token
,带有字段符号,以及开始和结束位置:符号出现。
一个类Grammar
,它有符号的工厂方法。
Grammar myGrammar = new Grammar() {
Symbol op = regex("\\+|-|\\*|/");
Symbol number = regex("\\d+");
Symbol expr = nonterminal();
{
define(expr,
alternatives(seq(number, op, expr),
number));
}
};
不确定,这是如何映射您的案例的。但我将语法(符号)与AST抽象语法树或解析的令牌出现分开。