Recognizing when a parsing error has occurred in a C++ ANTLR generated parser

One of the most compelling reasons to use ANTLR is that it the ANTLR generated recursive decent parser has excellent error reporting and error recover.

A compiler that uses an ANTLR generated parser would produce an abstract syntax tree (AST) represenation of the source code as a result of parsing. Subsequent compiler phases would walk this tree to perform operations like type resolution, semantic analysis, tree restructuring and control flow graph creation. But if an error is recognized by the parser, these later passes should not be performed.

The parser produced by ANTLR is a subclass of the Parser class. In order to recognize the that an error has occurred, the virtual reportError functions in the Parser class must be overridden by deriving a new class. This new class will be used to define the object that you use to invoke the parser.

The reportError functions are defined in Parser as:


class Parser {
     ...
        /** Parser error-reporting function can be overridden in
	subclass */
        virtual void reportError(const ParserException& ex);

        /** Parser error-reporting function can be overridden in
	subclass */
        virtual void reportError(const std::string& s);

     ...
};

The ANTLR parser generator will read the language grammar and crate a new parser class derived from Parser. In this example, my grammar is named MyTinyC. ANTLR will create a class, MyTinyCParser, which is derived from Parser to parse the grammar. To override the reportError functions a new parser class must be derived from MyTinyCParser. This is shown below:


class ParserPrime : public MyTinyCParser {
private:
  Boolean parse_OK;

protected:
  void set_parse_OK( Boolean l) { parse_OK = l; }

public:
  ParserPrime(TokenStream& lexer) : MyTinyCParser( lexer )
  {
    parse_OK = TRUE;
  }

  Boolean is_parse_OK() { return parse_OK; }

  // Override the reportError function defined in the Parse base
  // class.
  void reportError(const std::string& s);

  // Override the reportError function defined in the Parse base
  // class.
  void reportError(const ParserException& ex);

};  // ParserPrime

The class functions that override reportError are similar to the "stock" functions in Parse.cpp, but in this case they call the set_parse_OK class function to set the parse_OK class variable to FALSE. The implementations for reportError are shown below:


void ParserPrime::reportError(const std::string& s)
{
  if ( getFilename()=="" )
    std::cout << "Error: " << s << std::endl;
  else
    std::cout << "Error in " << getFilename() << ": " << s << std::endl;

  set_parse_OK( FALSE );
}


void ParserPrime::reportError(const ParserException& ex)
{
  if ( getFilename()=="" )
    std::cout << "Error: " << ex.toString() << std::endl;
  else
    std::cout << "Error in " << getFilename() << ": " << ex.toString() << std::endl;

  set_parse_OK( FALSE );
}

The code the instantiates the parser class is shown below:

          MyTinyCLexer *pLexer = new MyTinyCLexer( *pStream );
          ParserPrime *pParser = new ParserPrime( *pLexer );

	  // Parse the source code from the funclist production
          funclist = pParser->funclist();

          if (pParser->is_parse_OK()) {
	     // subsequent compiler passes are invoked here
          }

Ian Kaplan, September 11, 1999


back to ANTLR table of contents