Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Smalltalk 自参考小手笔';PPS复合分离机_Smalltalk_Pharo_Petitparser - Fatal编程技术网

Smalltalk 自参考小手笔';PPS复合分离机

Smalltalk 自参考小手笔';PPS复合分离机,smalltalk,pharo,petitparser,Smalltalk,Pharo,Petitparser,我有一个编程语言语法,我想在PPCompositeParser的几个子类中展开(例如,一个类将处理指令,另一个类将处理表达式,另一个类具有句柄程序结构)。我想这样做是为了避免得到一个包含数十个实例变量的大类 我的问题是这些子语法具有循环依赖性:结构语法引用语句语法的“statement”规则,它引用表达式语法的“expression”规则,它引用结构语法的“subroutiname”(关闭依赖项循环)。我尝试了简单的方法,例如,在表达式语法中有一个#subroutiname方法,它看起来像: M

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

我的问题是这些子语法具有循环依赖性:结构语法引用语句语法的“statement”规则,它引用表达式语法的“expression”规则,它引用结构语法的“subroutiname”(关闭依赖项循环)。我尝试了简单的方法,例如,在表达式语法中有一个#subroutiname方法,它看起来像:

MyExpressionGrammar>>subroutineName
  ^ N2TJStructureParser newStartingAt: #subroutineName
MyExpressionGrammar>>subroutineName
  ^ PPDederedParser creationBlock: [N2TJStructureParser newStartingAt: #subroutineName]
但这在初始化时失败,因为存在无限递归(显然)

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

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

PPDeferedParser>>parseOn: aStream
    ^ creationBlock value parseOn: aStream
这使得前面的#子例程看起来像:

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

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

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

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

您的解决方案当然也很有效,但它并没有那么好,因为它需要您仔细注意如何连接语法。此外,在您的实现中,您应该延迟缓存结果,否则您的代码将在解析时创建新的复合解析器。这个很贵


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

更新:我发布了一个实验版本(PetitParser lr.230)这添加了一级依赖项:(1)添加一个方法
#dependencies
,该方法返回依赖复合解析器的集合,(2)通过
dependencyAt:
访问这些依赖解析器。检查方法注释。像这样,不同类之间的循环依赖关系应该是开箱即用的。你的更新很棒!我的代码现在更简单、更快:-)。谢谢卢卡斯