如何保存 ANTLR 生成的 AST

How to save an AST generated by ANTLR

我已经在 python 中使用 ANTLR 成功生成了一个 AST,但我终究无法弄清楚如何保存它以备后用。我能想出的唯一选择是使用 tree.toStringTree() 方法,但这种方法的输出很混乱,不太方便或不太容易使用。

我如何保存它以及 best/easiest 可以使用什么格式并能够在将来可视化和加载它?

编辑: 我可以在 java 文档中看到有一个 DotGenerator() 来生成树的 DOT 文件,但我找不到在 python.

中做这样的事情的方法

您正在寻找的是 serializer/deserializer 的解析树。之前在 Whosebug here 中解决了序列化问题。它在运行时 (ASAIK) 中不受支持,因为它没有用:可以通过 re-parsing 输入非常快速地重建树。即使您想使用转换来更改树,您也可以将 sub-trees 树中的节点替换为解析器中甚至不存在的节点类型,打印出树,然后 re-parse使用语法的解析类型重建树。只有在使用语义分析进行解析非常慢时才有意义。所以,你要慎重考虑这个问题。

不过,不考虑空格、注释等“off-channel”内容的粗略serializer/deserializer并不难写。这个 C# 程序(你可以适应 python)是一个使用 grammars-v4/sexpression.g4 grammar for a target grammar arithmetic.g4 重建树的例子。使用toStringTree(rule-names),首先将树序列化为字符串。 (注意,没有解析器规则名称的 toStringTree() 很难阅读,这就是我问的原因。)然后,解析 s-expression 并使用 Antlr 访问者执行 bottom-up 重建。由于 toStringTree() 没有用标记的类型标记解析树叶子(例如,区分数字和符号),字符串被词法化以重建值。它还使用反射来创建正确的解析树节点类型。

为解析树输出一个点图也很容易,我把它包含在程序中,using a top-down recursive visitor。在这里,递归函数将每条边输出到特定节点的子节点。由于每个节点名称必须是唯一的(它是一棵树),因此我将节点的 pre-order 树编号添加到名称中。

--肯