2012-05-05 46 views
6

我正在将Jack Crenshaw的“让我们编译一个编译器”从Turbo Pascal 4.0重写到JAVA。这是因为激励的经典书籍没有尚未一个O-O版本重写Crenshaw的“让我们编译一个编译器”的设计模式?

Is there a more modern, OO version of "Let's Build a Compiler"?

这本书包含15章。编译器以递增方式呈现:第一章为整个编译器提供样板代码,然后每章添加一些行到先例章节的Pascal程序。

我已经翻译的前2章,各章为包,每个帕斯卡的步骤,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的因素(),但我不想在td2.Cradle改变因子(),因为这将使因素()在td2中做的比它应该在td2中提供的要多。我想到“扩展”td2.Cradle(),但是,似乎不可能扩展一个静态类。

My related question here

也许我应该改变对非静态的每一个静态方法?

我当然需要一些设计模式,任何人都可以帮忙吗?我希望我很清楚。总之,这个项目递增地为每个过程提供越来越多的指导,我希望使用一些像继承一样的JAVA机制来记录中间步骤。

Pascal代码是经典书籍,在这里是LBC。我觉得尝试使用继承,因为

  1. 每章的呼叫/平添了几分更多的行中的先例章规定的程序
  2. 我希望把我的JAVA源代码可用来大家谁愿意跟着LBC一步步。因此,使用单个类来放置作者编译器的最终源代码是不合适的。按照Crenshaw的说法,逐个分割代码并逐渐增加它们是非常重要的。

我的实际解决方案是保持tp1.Cradle的方法为静态。在tp2.Cradle,tp3.Cradle,...中,直到tp15.Cradle的方法将是非静态的,它们全部是静态导入 tp1.Cradle。*。此外,对于大于2的每个整数i,tp [i] .Cradle 延伸 tp [i-1] .Cradle。

不要犹豫,告诉我更好的解决方案。

+1

您可以添加您尝试重写的Pascal代码吗?我知道你已经在Pascal的程序中使用了Java静态方法。从不清楚的问题到我为什么要使用继承。 – Seitaridis

+1

@Seitaridis LBC本身包含pascal代码,只需按照链接... –

回答

1

这听起来像你在正确的轨道上。为了能够覆盖这些方法,它们应该是实例方法。所以你应该从一个依赖于这些“全局方法”的模型转移到一个基于实例的模型,在这个模型中创建一个Cradle类的实例,并在该实例上调用适当的方法。

+0

感谢您的回答。我上面更新我的实际解决方案。它可能不是一个优雅的,但它的工作原理。 – zell