1 回答

TA贡献1833条经验 获得超4个赞
您正在寻找的是解析树的序列化器/反序列化器。它在运行时 (ASAIK) 中不受支持,因为它没有用:可以通过重新解析输入来非常快速地重建树。即使您想使用转换来更改树,您也可以将树中的节点替换为具有您的解析器中甚至不存在的节点类型的子树,打印出树,然后重新解析以重建树使用语法的解析类型。只有在使用语义分析进行解析非常慢时才有意义。所以,你应该仔细考虑这个问题。
然而,编写一个不考虑间距或注释等“频道外”内容的粗略序列化器/反序列化器并不困难。这个 C# 程序(您可以将其改编为 python)是一个使用grammars-v4/sexpression.g4语法为目标语法arithmetic.g4重建树的示例。使用toStringTree(rule-names)
,树首先被序列化为一个字符串。(请注意,toStringTree()
没有解析器规则名称很难阅读,这就是我问的原因。)然后,解析 s 表达式并使用 Antlr 访问器执行自下而上的重建。自从toStringTree()
没有用标记的类型标记解析树叶子(例如,区分数字和符号),字符串被词法化以重建值。它还使用反射来创建正确的解析树节点类型。
为解析树输出点图也很容易,我将其包含在程序中,使用自上而下的递归访问器。在这里,递归函数将每条边输出到特定节点的子节点。由于每个节点名称必须是唯一的(它是一棵树),因此我将节点的预购树编号添加到名称中。
--肯
添加回答
举报