【问题标题】:Is it possible to use Recursive Descent Parser to both verify the grammar AND build the parse tree at the same time?是否可以使用递归下降解析器同时验证语法和构建解析树?
【发布时间】:2023-12-24 00:12:01
【问题描述】:

是否可以在我使用递归下降解析器检查数据是否符合语法的同时生成解析树?

如果是这样,当我递归下降时,我会使用什么方法来构建一棵树?

谢谢,博达·赛多。

注意:我是解析新手。 (已经问了几个关于 SO 的问题,我正在变得更好。)

【问题讨论】:

    标签: parsing recursive-descent parse-tree


    【解决方案1】:

    是的,这是可能的。如何做到这一点将取决于您想要的实现。下面是一个可能对您有用的示例:

    首先,定义你的节点:

    class ParseTreeNode {
      private final String name;
      private final List<ParseTreeNode> children = /* new */;
      public ParseTreeNode(String name) {
        this.name = name;
      }
      public void addChild(ParseTreeNode child) {
        children.add(child);
    }
    

    接下来,您需要将其集成到递归下降函数中:

    class RDParser {
      ParseTreeNode parse(Input input) {
        ParseTreeNode root = createParseTreeNodeNamed("Root")
        switch (input.nextToken()) {
          case OPT1:
            root.addChild(createParseTreeNodeNamed("Opt1"));
            break;
          case OPT2:
            while (/*someCondition*/) {
              root.addChild(createParseTreeNodeNamed("Opt2-sibling" + /* i */));
            }
          case SUBTREE:
            ParseTreeNode subtree = createParseTreeNodeNamed("Subtree");
            root.addChild(subtree);
            parseSubtree(subtree, input);
            break;
          default:
            error("Input %s was not in the expected first/follow sets", input.nextToken());
        }
      }
      void parseSubtree(ParseTreeNode node, Input input) {
        node.addChild(createParseTreeNodeNamed("subtree-child"));
        /* ... */
      }
    
      /* and other functions do similarly */
      ParseTreeNode createParseTreeNodeNamed(String name) {
        return new ParseTreeNode(name);
      }
    }
    

    当您向下分析树时,您可能希望发送新的“根”节点,以便可以将子节点添加到其中。或者,parseSubtree 可以创建并返回一个节点,然后将其添加到根节点。

    您可以使用上述过程构建解析树或简单的抽象树。由于 parse 函数返回根节点,该根节点将引用所有子节点,因此您将在解析后拥有对解析树的完全访问权限。

    无论您使用异构还是同构解析树,您都需要一种方法来存储足够的信息以使其有用。

    【讨论】:

    • 出色的答案,卡莱布。它让我立即开始,我想我现在可以自己写了!但是您能否澄清“parse tree”和“abstract tree”以及“heterogeneuous”和“homogeneous”解析树之间的区别? (我还不知道有什么区别,但我很想知道!)
    • homogeneous - 由相同类型的节点组成的树。异构 - 由不同类型的节点组成的树。解析树表示输入数据的结构,通常包含不必要的语法。抽象句法树是保持基本结构和信息但消除不必要的结构或句法的树。我修改了我的帖子以显示树如何变得更深——我希望能澄清一下。
    • 感谢您的解释!我已经在实施了。 :) 我会问我是否卡住了。我的树将是抽象的异构树。 :)
    • @KalebPederson AST 是二叉树吗?
    最近更新 更多