【问题标题】:AST with fixed nodes instead of error nodes in antlr具有固定节点而不是 antlr 中的错误节点的 AST
【发布时间】:2010-05-13 23:22:23
【问题描述】:

我有一个使用 C 目标的 antlr 生成的 Java 解析器,它运行良好。问题是我还希望它解析错误代码并生成有意义的 AST。如果我给它一个最小的 Java 类,一个导入后缺少分号,它会生成两个“树错误节点”对象,其中“导入”令牌和导入类的令牌应该是。

但由于它正确解析了以下代码并为此代码生成了正确的节点,它必须通过添加分号或重新同步来从错误中恢复。有没有办法让 antlr 反映它在 AST 内部产生的这个固定输入?或者我至少可以得到产生“树节点错误”的令牌/文本吗?

在 C 目标中 antlr3commontreeadaptor.c 第 200 行附近的以下片段表明 C 目标目前仅创建虚拟错误节点:

static  pANTLR3_BASE_TREE
errorNode                               (pANTLR3_BASE_TREE_ADAPTOR adaptor,   pANTLR3_TOKEN_STREAM ctnstream, pANTLR3_COMMON_TOKEN startToken, pANTLR3_COMMON_TOKEN stopToken, pANTLR3_EXCEPTION e)
{
    // Use the supplied common tree node stream to get another tree from the factory
    // TODO: Look at creating the erronode as in Java, but this is complicated by the
    // need to track and free the memory allocated to it, so for now, we just
    // want something in the tree that isn't a NULL pointer.
    //
    return adaptor->createTypeText(adaptor, ANTLR3_TOKEN_INVALID, (pANTLR3_UINT8)"Tree Error Node");
}

我是不是运气不好,只有 Java 目标生成的错误节点才能让我检索错误节点的文本?

【问题讨论】:

  • 我认为您应该删除 C 标签,因为这似乎不是使用或理解 C 的问题。您应该添加解析器或解析标签。

标签: error-handling parsing antlr parser-generator error-recovery


【解决方案1】:

我没怎么用过antlr,但是通常你处理这种类型的错误的方式是添加匹配错误语法的规则,让它们产生错误节点,并在错误后尝试修复,这样你就可以继续解析。事后修复是个问题,因为您不希望一个错误为每个新令牌触发越来越多的错误,直到最后。

【讨论】:

    【解决方案2】:

    我通过向语法中添加新的替代规则来解决所有可能的错误陈述的问题。

    例如,每个 Java 导入语句都被转换为以人工符号 IMPORT 作为根的 AST 子树。为了确保我可以将 AST 与正确代码和错误代码区分开来,错误语句的规则将它们重写为带有前缀 ERR_ 的根符号的 AST,因此在导入语句的示例中,人造根符号将是 ERR_IMPORT。

    更多不同的根符号可用于编码有关解析错误的更详细信息。

    我的解析器现在可以像我需要的那样容错,并且在我需要时可以很容易地为新的错误输入添加规则。不过,您必须注意不要在语法中引入任何歧义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-29
      • 2014-03-04
      相关资源
      最近更新 更多