Overriding ANTLR3 error recovery routine
authorChristopher L. Conway <christopherleeconway@gmail.com>
Fri, 2 Apr 2010 20:04:34 +0000 (20:04 +0000)
committerChristopher L. Conway <christopherleeconway@gmail.com>
Fri, 2 Apr 2010 20:04:34 +0000 (20:04 +0000)
src/parser/antlr_input.cpp
src/parser/antlr_input.h
src/parser/cvc/Cvc.g
src/parser/smt/Smt.g

index 0d6f63812c0be4b9b76c4bb6af93489d8989c8e6..3d9006e04d84f92e768cb927d78275946f0fd645 100644 (file)
@@ -104,6 +104,47 @@ void AntlrInput::parseError(const std::string& message)
                         d_lexer->getCharPositionInLine(d_lexer));
 }
 
+void *
+AntlrInput::recoverFromMismatchedToken(pANTLR3_BASE_RECOGNIZER recognizer,
+                                       ANTLR3_UINT32 ttype,
+                                       pANTLR3_BITSET_LIST follow) {
+
+  pANTLR3_PARSER parser = (pANTLR3_PARSER) (recognizer->super);
+  pANTLR3_INT_STREAM is = parser->tstream->istream;
+  void *matchedSymbol;
+
+
+  // Create an exception if we need one
+  //
+  if(recognizer->state->exception == NULL) {
+    antlr3RecognitionExceptionNew(recognizer);
+  }
+
+  if(recognizer->mismatchIsUnwantedToken(recognizer, is, ttype) == ANTLR3_TRUE) {
+    recognizer->state->exception->type = ANTLR3_UNWANTED_TOKEN_EXCEPTION;
+    recognizer->state->exception->message
+        = (void*)ANTLR3_UNWANTED_TOKEN_EXCEPTION_NAME;
+  }
+
+  if(recognizer->mismatchIsMissingToken(recognizer, is, follow)) {
+    // We can fake the missing token and proceed
+    //
+    matchedSymbol = recognizer->getMissingSymbol(recognizer, is,
+                                                 recognizer->state->exception,
+                                                 ttype, follow);
+    recognizer->state->exception->type = ANTLR3_MISSING_TOKEN_EXCEPTION;
+    recognizer->state->exception->message = (void*)ANTLR3_MISSING_TOKEN_EXCEPTION_NAME;
+    recognizer->state->exception->token = matchedSymbol;
+    recognizer->state->exception->expecting = ttype;
+
+    // Print out the error after we insert so that ANTLRWorks sees the
+    // token in the exception.
+    //
+  }
+  reportError(recognizer);
+  Unreachable("reportError should have thrown exception in AntlrInput::recoverFromMismatchedToken");
+}
+
 void AntlrInput::reportError(pANTLR3_BASE_RECOGNIZER recognizer) {
   pANTLR3_EXCEPTION ex = recognizer->state->exception;
   pANTLR3_UINT8 * tokenNames = recognizer->state->tokenNames;
@@ -310,6 +351,7 @@ void AntlrInput::setParser(pANTLR3_PARSER pParser) {
   // pass it in as an address anyway.
   d_parser->super = getParserState();
   d_parser->rec->reportError = &reportError;
+  d_parser->rec->recoverFromMismatchedToken = &recoverFromMismatchedToken;
 }
 
 
index dee7c1491096727a38aa3c0967a9338f7c9e4f1b..c338c528a05025de1b3ca3f4364e68b062b689a4 100644 (file)
@@ -67,6 +67,13 @@ class AntlrInput : public Input {
   /** Turns an ANTLR3 exception into a message for the user and calls <code>parseError</code>. */
   static void reportError(pANTLR3_BASE_RECOGNIZER recognizer);
 
+  /** Collects information from a parse error and calls reportError. Replaces the default
+   * implementation, which tries to recover from the error.
+   */
+  static void *
+  recoverFromMismatchedToken(pANTLR3_BASE_RECOGNIZER recognizer,
+                             ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow);
+
 public:
 
   /** Create a file input.
index 8b8f251ae8459f44e7404343e9051d2f7f57cc68..428e2432e05bdd727b8898fd05a46fa75d1a56c4 100644 (file)
@@ -79,6 +79,7 @@ using namespace CVC4::parser;
 #define MK_CONST EXPR_MANAGER->mkConst
 }
 
+
 /**
  * Parses an expression.
  * @return the parsed expression
index 93b8560d010fb4b47c05ec9d890510bbbfe4f5fd..c0b184abf465d0eaca981e7582773929fa5a69c4 100644 (file)
@@ -79,6 +79,7 @@ using namespace CVC4::parser;
 #define MK_CONST EXPR_MANAGER->mkConst
 }
 
+
 /**
  * Parses an expression.
  * @return the parsed expression