【问题标题】:Grako "code" generationGrako“代码”生成
【发布时间】:2016-06-04 13:16:13
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: python code-generation grako


    【解决方案1】:

    如果您查看 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 的方式允许使用CodeGenerator 完成的调度内联指定str 模板,这是我进行翻译的首选方式。但是当我只需要从模型中提取信息时,我会使用grako.model.DepthFirstNodeWalker,例如在生成符号表或计算指标时。

    步骤 3 不能自动化,因为将源语言的语义映射到目标语言的语义需要脑力,即使源语言和目标语言相同。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-03
      • 2018-09-26
      • 2018-06-15
      • 2010-10-31
      • 2015-05-07
      • 2016-12-11
      相关资源
      最近更新 更多