1

我有一个ANTLR固定节点,而不是错误的节点产生,使用C靶Java解析器和它工作得很好。问题是我也希望它解析错误的代码并产生一个有意义的AST。如果我为它提供一个带有一个导入的最小Java类,之后缺少一个分号,它会生成两个“树错误节点”对象,其中导入类的令牌和令牌应该是。AST在ANTLR

但由于它正确地解析下面的代码,并产生正确的节点为这个编码它必须从错误通过将分号或通过重新同步恢复。有没有办法让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目标产生将允许我检索错误节点的文本?

+0

我认为你应该删除C标签,因为这似乎不是使用或理解C的问题。你应该添加解析器或解析标签。 – nategoose 2010-05-14 17:36:15

回答

0

我通过添加新的规则交替的语法针对所有可能的错误语句解决了这个问题。

每个Java import语句被转换到与人造符号导入为根例如一个AST树。为了确保我可以的AST之间的正确和错误的代码区分的错误言论的规则他们改写为与前缀ERR_根符号的AST,所以在import语句的例子中,人工根符号是ERR_IMPORT。

可以使用更多不同的根符号来编码关于分析错误的更详细的信息。

我的语法分析器现在可以像我所需要的那样容错了,并且在我需要的时候添加新的错误输入规则非常简单。不过,你必须小心,不要在你的语法中引入任何含糊之处。

0

我没有用ANTLR多,但通常你处理这种类型的错误的方法是添加规则匹配错误的语法,使他们产生错误的节点,并尝试错误后,修复起来,这样就可以保持解析。之后解决问题是因为您不希望一个错误为每个新的令牌触发越来越多的错误直到结束。