ARF*_*ARF 5 python code-generation grako
我试图理解如何重新创建由grako生成的解析器解析的文档.
在深入了解grako源代码后,我相信我终于明白了如何从AST返回到生成的文档.有人可以检查我的以下理解是否正确,如果有更直接的方法,请告诉我?
grako.model.Node语法中每个规则的单独类(子类).每个类必须至少有一个构造函数,其中包含相应规则中每个命名元素的参数,并将其值存储在类属性中.grako.codegen.ModelRenderer定义了"代码"生成模板,用于(或多或少)一个语法中的每个规则.grako.codegen.CodeGenerator().render(...)来创建输出.这可能是对的吗?这看起来根本不直观.
如果您查看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()
...
Run Code Online (Sandbox Code Playgroud)
如果参数中不存在这些类,则这些类将被合成types=。所ModelBuilderSemantics需要的只是每个语法规则都带有一个参数,该参数给出相应的类名Node:
module::Module = .... ;
Run Code Online (Sandbox Code Playgroud)
或者,
module(Module) = ... ;
Run Code Online (Sandbox Code Playgroud)
步骤 3 是不可避免的,因为必须在“某处”指定翻译。Grako的方式允许str内联指定模板并由 完成调度CodeGenerator,这是我首选的翻译方式。但当我grako.model.DepthFirstNodeWalker只需要从模型中提取信息时,例如生成符号表或计算指标时,我会使用它。
步骤 3 无法自动化,因为将源语言的语义映射到目标语言的语义需要脑力,即使源语言和目标语言相同。
正如您所建议的,人们也可以通过遍历类似 JSON 的 Python 结构parse()或grako.model.Node.asjson()生成(AST),但处理代码将充满区分if-then-elseif一个字典与另一个字典,或一个列表与另一个列表的区别。对于模型,层次结构中的每个字典都有一个 Python 类作为类型。
最后,Grako并没有强加一种方法来创建解析内容的模型,也没有强加一种将其转换为其他内容的方法。在其基本形式中,如果元素命名使用得当,Grako只提供具体语法树(CST) 或抽象语法树(AST)。其他一切都是由特定的语义类产生的,它可以是任何人想要的。