gpt4 book ai didi

python - Grako "code"代

转载 作者:太空狗 更新时间:2023-10-30 01:13:22 24 4
gpt4 key购买 nike

我试图了解如何重新创建由 grako 生成的解析器解析的文档.

在深入研究 grako 源代码之后,我相信我终于理解了如何从 AST 返回到生成的文档。有人可以检查我的以下理解是否正确,让我知道是否有更直接的方法?

  1. 创建一个希望解析的 PEG 语法。 Grako 基于它创建一个解析器类和一个语义学类。
  2. 为语法中的每个规则创建(手动)一个 python 模块(或多或少)包含一个单独的类(grako.model.Node 的子类)。每个类必须至少有一个构造函数,其中包含相应规则中每个命名元素的参数,并将其值存储在类属性中。
  3. 一个子类(手动)生成的语义类,用步骤 2 中创建的相应类替换每个规则的 ast。
  4. (手动)创建一个 python 模块,它是 grako.codegen.ModelRenderer 的一个子类,定义了一个人的语法中(或多或少)每个规则的“代码”生成模板。
  5. 将由 Node 子类和包含模板的 python 模块组成的 AST 提供给 grako.codegen.CodeGenerator().render(...) 以创建输出。

这是对的吗?这看起来一点也不直观。

  • 为什么要经过第 2 步和第 3 步的巨大努力,除了存储已经包含在 AST 中的信息外什么都不做?
  • 这种方法比直接从 AST 工作有什么优势?
  • 如果只想用原始语法重新创建文档,是否有办法自动执行或回避步骤 2 和 3?
  • 给定 PEG 语法定义,理论上是否可以像创建“解析器生成器”一样自动创建“代码生成器生成器”?

最佳答案

如果您查看 Grako 本身如何解析语法,您会注意到步骤 2 类是由 ModelBuilderSemantics 后代综合创建的:

# from grako/semantics.py
class GrakoSemantics(ModelBuilderSemantics):
def __init__(self, grammar_name):
super(GrakoSemantics, self).__init__(
baseType=grammars.Model,
types=grammars.Model.classes()
)
self.grammar_name = grammar_name
self.rules = OrderedDict()
...

如果 types= 参数中没有出现类,则这些类被合成。 ModelBuilderSemantics 所需要的只是每个语法规则都带有一个参数,该参数为相应的 Node 提供类名:

module::Module = .... ;

或者,

module(Module) = ... ;

第 3 步是不可避免的,因为必须在“某处”指定翻译。 Grako 的方式允许 str 模板与 CodeGenerator 完成的分派(dispatch)内联指定,这是我首选的翻译方式。但是当我只需要从模型中提取信息时,例如生成符号表或计算指标时,我会使用 grako.model.DepthFirstNodeWalker

第 3 步无法自动化,因为将源语言的语义映射到目标语言的语义需要脑力,即使源语言和目标语言相同也是如此。

还可以通过遍历 parse()grako.model.Node.asjson() 生成的类似 JSON 的 Python 结构(AST),正如您所建议的,但是处理代码将充满 if-then-elseif 以区分一个字典与另一个字典,或一个列表与另一个列表。对于模型,层次结构中的每个字典都有一个 Python 类作为类型。

最后,Grako 没有强加一种方法来创建已解析内容的模型,也没有强加一种将其转换为其他内容的方法。如果使用元素命名,Grako 的基本形式仅提供具体语法树 (CST) 或抽象语法树 (AST)明智地。其他一切都由特定的语义类产生,可以是任何人想要的。

关于python - Grako "code"代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35565052/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com