DFS的AST的退出条件

时间:2019-03-30 15:51:27

标签: parsing recursion abstract-syntax-tree

我正在尝试使用DFS方法编写通用的AST构建器。

语法的原理很简单:一个表达式可以具有一个或多个选项,每个选项都由节点列表组成,其中每个节点可以是终结符或表达式。

我的状态正常,但是正在为“无穷循环”寻找退出条件。

如果我这样定义语法:

expr := addExpr;

addExpr := NUMBER
         | NUMBER OPERATOR expr
         ;

它通过。该结构在语义上是正确的,但是遍历时将产生错误的结果。将“ 4-2 + 2”计算为“ 4-(2 + 2)”,而不是所需的“(4-2)+ 2”。

我需要这样定义语法:

expr := addExpr;

addExpr := NUMBER
         | expr OPERATOR NUMBER
         ;

这里的问题是,它导致无休止的迭代:

expr -> addExpr -> expr -> addExpr -> ...

这就是我被困住的地方。关于何时停止尝试,我无法提出退出条件。我当时想拥有一个历史,如果我将相同的表达式与其余标记进行比较,我可以停下来。但这停止得太早了,不会产生任何结果。

我想我需要的堆栈看起来像这样:

expr (against 4 - 2 + 2)
  addExpr (against 4 - 2 + 2)
    0: NUMBER -> matches 4, won't finish.
    1: expr OPERATOR NUMBER
      expr (against 4 - 2 + 2) -> I cannot break yet.
        addExpr (against 4 - 2 + 2) -> I cannot break yet.
          0: NUMBER -> matches 4, won't finish.
          1: expr OPERATOR NUMBER
            expr (against 4 - 2 + 2) -> I cannot break yet.
              addExpr (against 4 - 2 + 2) -> I cannot break yet.
                0: NUMBER -> matches 4, will resolve in the end.
                1: expr OPERATOR NUMBER
                  expr (against 4 - 2 + 2) -> BREAK!

何时中断似乎有些武断。是否有一些良好的规则或条件可以实现这一目标?

如果可以避免的话,我真的不想只设置一个“随机”最大深度。也许我应该考虑采用BFS方法(一系列不同的问题),但是如果可能的话,我想坚持使用DFS。

0 个答案:

没有答案