我正在将 Jack Crenshaw 的“让我们构建一个编译器”从 Turbo Pascal 4.0 重写为 JAVA。这是令人鼓舞的,因为经典书籍还没有 O-O 版本
Is there a more modern, OO version of "Let's Build a Compiler"?
本书共15章。编译器以递增的方式介绍:第一章提供了整个编译器的样板代码,然后每一章都在前一章的 Pascal 程序中添加了一些行。
我已经翻译了前两章,每一章都是一个包,每个 Pascal 过程都是 JAVA 中的静态保护方法,一章的过程聚集在一个类中,该类扩展了从其前一章翻译的类。
package td1;
public class Cradle {
protected final static char TAB='\t';
protected static char look;
protected static void getChar() throws IOException {
look=(char) System.in.read();
}
...
}
package td2;
public class Cradle extends td1.Cradle{
protected static void factor() throws IOException {
...
}
...
}
然而,当我来到td3时,我必须更新td2.Cradle的factor(),但我不想在td2.Cradle中改变factor(),因为那样会使td2中的factor()做的比它应该在 td2 中呈现的更多。我想到了“扩展”td2.Cradle(),但是,扩展静态类似乎是不可能的。
也许我应该将每个静态方法都改为非静态方法?
我当然需要一些设计模式,有人可以帮忙吗?我希望我说得很清楚。总而言之,这个项目逐渐为每个过程提供了越来越多的说明,我希望使用一些 JAVA 机制(如继承)记录中间步骤。
Pascal 代码是经典书籍在这里 LBC 。我觉得试图使用继承,因为
- 每一章调用/添加更多行到前面章节中定义的过程
- 我希望我的JAVA源代码能被所有想一步步跟随LBC的人使用。所以用一个单独的类放在作者编译器的最终源代码中是不合适的。像 Crenshaw 所做的那样,按章节拆分代码并逐渐增加它们是很重要的。
我的实际解决方案是将 tp1.Cradle 的方法保持为静态。 tp2.Cradle、tp3.Cradle、... 直到 tp15.Cradle 中的方法将是非静态的,并且它们都静态导入 tp1.Cradle.*。此外,对于每个大于 2 的整数 i,tp[i].Cradle extends tp[i-1].Cradle。
不要犹豫,告诉我更好的解决方案。
最佳答案
听起来您的方向是正确的。为了能够覆盖这些方法,它们应该是实例方法。因此,您应该从依赖这些“全局方法”的模型转移到基于实例的模型,在该模型中您创建 Cradle 类的实例并在该实例上调用适当的方法。
关于java - 重写 Crenshaw 的 "let' 构建编译器的设计模式”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10463070/