4

我有一个编程语言语法我想在 PPCompositeParser 的几个子类中展开(例如,一个类将处理指令,另一个类将处理表达式,另一个类具有句柄程序结构)。我想这样做是为了避免获得一个包含数十个实例变量的大类。

我的问题是这些子语法有循环依赖:结构语法引用语句语法的'statement'规则,引用表达式语法的'expression'规则,引用结构语法的'subroutineName'(关闭依赖循环)。我尝试了一种简单的方法,例如,在表达式语法中使用 #subroutineName 方法,如下所示:

MyExpressionGrammar>>subroutineName
  ^ N2TJStructureParser newStartingAt: #subroutineName

但由于无限递归(显然),初始化失败。

为了解决这个问题,我创建了一个 PPDeferedParser:

PPParser subclass: #PPDeferedParser
    instanceVariableNames: 'creationBlock'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'PetitParser-Tools'

PPDeferedParser>>parseOn: aStream
    ^ creationBlock value parseOn: aStream

这使得之前的 #subroutineName 看起来像:

MyExpressionGrammar>>subroutineName
  ^ PPDederedParser creationBlock: [N2TJStructureParser newStartingAt: #subroutineName]

这似乎可行,但我想知道是否还有其他解决方案。

4

1 回答 1

3

PPCompositeParser目前,PetitParser 不直接支持将复合解析器拆分为多个子类。

请记住,如果您使用 PetitParser 浏览器,则无需担心实例变量,它们会自动为您管理。此外,您不一定需要为每个产品创建一个实例变量。例如,终端可以在您直接调用的方法中。

您的解决方案当然也有效,但它不是那么好,因为它需要您仔细注意您希望如何连接您的语法。同样在您的实现中,您应该延迟缓存结果,否则您的代码将在解析时创建新的复合解析器。这是非常昂贵的。

除此之外,当然可以改进PPCompositeParser以支持多个子类之间的依赖关系,例如通过声明构造函数将准备、初始化和最终解析的依赖的其他解析器。

于 2013-03-16T23:56:15.833 回答