Adding match override to AntlrInput, in attempt to workaround Bug #76
authorChristopher L. Conway <christopherleeconway@gmail.com>
Mon, 5 Apr 2010 16:21:27 +0000 (16:21 +0000)
committerChristopher L. Conway <christopherleeconway@gmail.com>
Mon, 5 Apr 2010 16:21:27 +0000 (16:21 +0000)
src/parser/antlr_input.cpp
src/parser/antlr_input.h

index 61d61821b149390045ff71a792838f49a471d993..ab937ac1a05a01852a0736d103bb6ec7ea9fe178 100644 (file)
@@ -92,6 +92,84 @@ pANTLR3_COMMON_TOKEN_STREAM AntlrInput::getTokenStream() {
   return d_tokenStream;
 }
 
+
+/// Match current input symbol against ttype.  Upon error, do one token
+/// insertion or deletion if possible.
+/// To turn off single token insertion or deletion error
+/// recovery, override mismatchRecover() and have it call
+/// plain mismatch(), which does not recover.  Then any error
+/// in a rule will cause an exception and immediate exit from
+/// rule.  Rule would recover by resynchronizing to the set of
+/// symbols that can follow rule ref.
+///
+// [chris 4/5/2010] Copy and paste from antlr3baserecognizer.c
+void *
+AntlrInput::match(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype,
+      pANTLR3_BITSET_LIST follow) {
+  pANTLR3_PARSER parser;
+  pANTLR3_TREE_PARSER tparser;
+  pANTLR3_INT_STREAM is;
+  void * matchedSymbol;
+
+  switch(recognizer->type) {
+  case ANTLR3_TYPE_PARSER:
+
+    parser = (pANTLR3_PARSER)(recognizer->super);
+    tparser = NULL;
+    is = parser->tstream->istream;
+
+    break;
+
+  case ANTLR3_TYPE_TREE_PARSER:
+
+    tparser = (pANTLR3_TREE_PARSER)(recognizer->super);
+    parser = NULL;
+    is = tparser->ctnstream->tnstream->istream;
+
+    break;
+
+  default:
+
+    ANTLR3_FPRINTF(
+                   stderr,
+                   "Base recognizer function 'match' called by unknown parser type - provide override for this function\n");
+    return ANTLR3_FALSE;
+
+    break;
+  }
+
+  // Pick up the current input token/node for assignment to labels
+  //
+  matchedSymbol = recognizer->getCurrentInputSymbol(recognizer, is);
+
+  if(is->_LA(is, 1) == ttype) {
+    // The token was the one we were told to expect
+    //
+    is->consume(is); // Consume that token from the stream
+    recognizer->state->errorRecovery = ANTLR3_FALSE; // Not in error recovery now (if we were)
+    recognizer->state->failed = ANTLR3_FALSE; // The match was a success
+    return matchedSymbol; // We are done
+  }
+
+  // We did not find the expected token type, if we are backtracking then
+  // we just set the failed flag and return.
+  //
+  if(recognizer->state->backtracking > 0) {
+    // Backtracking is going on
+    //
+    recognizer->state->failed = ANTLR3_TRUE;
+    return matchedSymbol;
+  }
+
+  // We did not find the expected token and there is no backtracking
+  // going on, so we mismatch, which creates an exception in the recognizer exception
+  // stack.
+  //
+  matchedSymbol = recognizer->recoverFromMismatchedToken(recognizer, ttype,
+                                                         follow);
+  return matchedSymbol;
+}
+
 void AntlrInput::parseError(const std::string& message)
     throw (ParserException) {
   Debug("parser") << "Throwing exception: "
@@ -346,6 +424,7 @@ void AntlrInput::setParser(pANTLR3_PARSER pParser) {
   // it would have to be declared separately in every input's grammar and we'd have to
   // pass it in as an address anyway.
   d_parser->super = getParserState();
+  d_parser->rec->match = &match;
   d_parser->rec->reportError = &reportError;
   d_parser->rec->recoverFromMismatchedToken = &recoverFromMismatchedToken;
 }
index c338c528a05025de1b3ca3f4364e68b062b689a4..d77a2b586e096fa88b943c33237bfce7e2e1b3e9 100644 (file)
@@ -64,6 +64,9 @@ class AntlrInput : public Input {
    *  NOTE: We assume that we <em>can</em> free it on exit. No sharing! */
   pANTLR3_INPUT_STREAM d_input;
 
+  static void *match(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype,
+                     pANTLR3_BITSET_LIST follow);
+
   /** Turns an ANTLR3 exception into a message for the user and calls <code>parseError</code>. */
   static void reportError(pANTLR3_BASE_RECOGNIZER recognizer);