首页 > 解决方案 > 如果我想构建一个抽象语法树,关于规则右侧的项目数量的最佳实践是什么?

问题描述

我使用 Flex & Bison 生成解析器。解析器工作得很好。它生成一个 XML 文档。它有这样的规则:

monthdatetime: TWODIGITS TWODIGITS TWODIGITS TWODIGITS timezone { $$ = concat(10, "<MonthNumeric>", $1, "</MonthNumeric><Day>", $2, "</Day><HourTime>", $3, "</HourTime><MinuteTime>", $4, "</MinuteTime>", $5); }

现在我想用构建抽象语法树 (AST) 的操作替换这些操作。启动规则的动作将是调用一个“序列化”函数,该函数遍历 AST 以一举生成 XML。

这就是我的计划。

在我上面展示的规则中,右侧有 5 个项目。有些规则有更多的项目。哎呀!我应该设计 AST 以支持具有任意数量分支的节点(N 元节点)吗?在上面的规则中,我需要用这样的操作替换操作:

{ $$ = new_ast("field", $1, $2, $3, $4, $5); } 

这是一个好方法吗?或者,我是否应该重新设计我的规则,使每条规则的右侧最多包含两个项目?这样,我可以创建一个二叉树的 AST。

你有什么建议吗?关于规则右侧的项目数量,是否有设计解析器规则的最佳实践?创建作为二叉树的 AST 还是作为 N 叉树的 AST 更好?

标签: parsingabstract-syntax-treebisonflex-lexeryacc

解决方案


这是关于计算机科学的。任何树结构(具有 n 路分支)都可用于表示具有 m 分支的所有其他树。

如果m小于n它是微不足道的,因为 null 用于填充 nm 子条目。何时n等于mthen 也没有问题。

您在询问m大于时该怎么做n。简单的; 使它们成为子树,这很容易做到。假设您希望树节点中有 9 个项目,而只有 5 个空间(如您的示例),您将其编码如下:

{$$ = new_ast("field",$1,$2,$3,$4, new_ast("child",$5,$6,$7,$8,$9)); }

现在,您将来的 tree-walk 将知道这是一个更长的节点。


推荐阅读