Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
710 views
in Technique[技术] by (71.8m points)

antlr4 - ANTLR pattern for second pass errors

Once there is a parse tree, a visitor or listener walk of the parse tree to do the actual translation will encounter errors that the parse cannot know about (like references to external entities which do not exist). When the user is presented with the errors from their source code, they need to see both the errors generated by the parser, and these "semantic" errors.

Right now, I have a custom listener which captures the parse errors, and then I have a completely different mechanism for collecting second pass errors, and when I present errors to the user, I merge these two error sources into one error stream. I was in a hurry and it got the job done, now it is time to do better.

To fix this I have two choices.

  1. Change my custom listener to reformat the parse errors so they can be added to the merged stream as they are generated. Then the merged stream is the authoritative source of all errors.
  2. Somehow be able to add semantic errors to the error stream that my customer listener receives, something like being able to call notifyErrorListener from inside a visit function. Then my custom error collector is now the authoritative source of all errors.

I can easily do #1, but it feels like #2 is the right choice and I just don't quite grasp how I do that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One answer is, I can call my custom error listener directly in the second pass, I can fabricate enough of the arguments from the Context objects to generate a call to syntaxError which my custom listener can respond to.


// 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);
  }

However ... reading the comments below has clarified things a little. At this point I believe the most correct thing is to create my own custom collector for error messages, and then have the custom error listener and the semantic error method feed that collector, it is mistake to keep using the ANTLR error listener after the parse is over.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...