一旦有了解析树,访问者或监听器在解析树中进行实际翻译时会遇到解析无法知道的错误(比如对不存在的外部实体的引用(。当用户看到源代码中的错误时,他们需要看到解析器生成的错误,以及这些"错误";语义";错误。
现在,我有一个自定义侦听器来捕获解析错误,然后我有一种完全不同的机制来收集第二次传递错误,当我向用户显示错误时,我将这两个错误源合并为一个错误流。我当时很着急,它完成了任务,现在是时候做得更好了。
要解决这个问题,我有两个选择。
- 更改我的自定义侦听器以重新格式化解析错误,这样它们就可以在生成时添加到合并流中。那么合并后的流就是所有错误的权威来源
- 不知何故,能够将语义错误添加到我的客户侦听器接收到的错误流中,就像能够从访问函数内部调用
notifyErrorListener
一样。然后,我的自定义错误收集器现在是所有错误的权威来源
我可以很容易地做到#1,但感觉#2是正确的选择,我只是不太明白我是如何做到的。
一个答案是,我可以在第二次传递中直接调用我的自定义错误侦听器,我可以从Context对象中编造足够多的参数来生成对syntaxError
的调用,我的自定义侦听器可以对此进行响应。
// Typescript fragment implementation of visitor with ability to add
// semantic errors to error stream
export class MYLANGUAGETranslator
extends AbstractParseTreeVisitor<MYNODETYPE>
implements MYLANGUAGEVisitor<MYNODETYPE> {
/**
* Adds a second pass error to the error stream.
*
* @param ecx The context token which triggered the error
* @param msg The error message
*/
semanticError(ecx: ParserRuleContext, msg: string): void {
customErrorListenerInstance.syntaxError(undefined, undefined, ecx.start.line, ecx.start.charPositionInLine, msg, undefined);
}
然而。。。阅读下面的评论已经稍微澄清了一些。在这一点上,我认为最正确的做法是为错误消息创建我自己的自定义收集器,然后让自定义错误侦听器和语义错误方法为该收集器提供信息,在解析结束后继续使用ANTLR错误侦听器是错误的。