[antlr-interest] Re: exception thrown in syntatic predicate c an't be caught!

Matthew Ford Matthew.Ford at forward.com.au
Mon Apr 14 19:31:52 PDT 2003


Hi I had exactly the same problem,
This is what I used. (I think I posted this before, perhaps I should
formalize it for the FAQ :-?)

(Sorry there is some other stuff in here you don't need)

In the Parser

header {

package beaconit.translator.server;

} // end of Antlr intro block

options {
 mangleLiteralPrefix = "TF_";
}

options {
 k = 1;                           // one token lookahead
 defaultErrorHandler = false;     // Don't generate parser error handlers
 buildAST = true;
  importVocab = TIMEFRAMECOMMONLEXER;
  exportVocab = TIMEFRAMESERVERPARSER;

}


 public void reportError(ANTLRException ex) {
    Debug.out("in reportError", MAJOR, 0);

   commandGenerator.translationError(TFlexer.getLineBuffer(),

0,0,null,null,TimeFrameException.makeTimeFrameException(MAJOR,TRANSLATION_ER
ROR,ex.getMessage()));
    Debug.out("******* end reportError *******", MAJOR, 0);
 }

 public void processError(ANTLRException ex) throws TokenStreamException,
    CharStreamException {
  // actually only throws TokenStreamIOException others caught here
  int tokenType=0;
  LexerSharedInputState inputState = TFlexer.getInputState();
  inputState.guessing = 0; // clear guessing mode
    Debug.out("in processError", MAJOR, 0);
    if (!errorFlag) { // first error
     reportError(ex);
     errorFlag=true;  //don't block new errors after syncing.
    }

  do {
   try {
    if (ex instanceof TokenStreamRecognitionException) {
     TokenStreamRecognitionException rex =
(TokenStreamRecognitionException)ex;
      // get underlying exception
     ex = null; // have handled this one now
     if ((rex.recog instanceof MismatchedCharException) ||
        (rex.recog instanceof NoViableAltForCharException)) {
      try {
          TFlexer.consume(); // remove current error char;
      } catch (CharStreamException cse) {
       if ( cse instanceof CharStreamIOException ) {
        throw new TokenStreamIOException(((CharStreamIOException)cse).io);
       } else {
        throw new TokenStreamIOException(new IOException(cse.getMessage()));
       }
      }
     }
      }

      tokenType = LA(1);
       if ((tokenType != EOF) && (tokenType != SEMI)) {
        consume(); // remove ;
          Debug.out("Input buffer:'"+TFlexer.getLineBuffer()+"'", MAJOR, 0);
       }

   } catch (TokenStreamRecognitionException ex1) {
     ex = ex1; // and loop
//      TFlexer.consume(); // remove current error char;
      Debug.out("** found :"+ ex1, MAJOR, 0);
   } catch (TokenStreamRetryException ex1) {
      Debug.out("** found :"+ ex1, MAJOR, 0);
     throw new TokenStreamIOException(new IOException(ex1.getMessage()));
   }
    } while ( tokenType != SEMI && tokenType != EOF && !isEOF());
    Debug.out("** end processError *******", MAJOR, 0);
    // if telnet print prompt again (How??)

 }

 private boolean errorFlag = false;

 private boolean eofFlag = false;

 public boolean isEOF() {
  return eofFlag;
  }

 private void clearErrorFlagAndScope() {
  scope=null; // clear scope aswell
  errorFlag = false;
 }


/* *****************
 public static void main(String[] args) {
  ITimeFrameBufferedReader sin;
  long sessionNo=0;
  TestIScope iScope=null;
  ConnectionData cd=null;
  SampleCommandGeneratorServer cG=null;
  TimeFrameCommonLexer lexer=null;
  IConnectionListener icl = new IConnectionListener() {
     public void cancelConnection() {System.exit(1);}
  };

  try {
    beaconit.commondata.GlobalData.data.load();
    Debug.out("GlobalData:"+beaconit.commondata.GlobalData.data.toString(),
MAJOR, 0);
    // add user and session no.
    cd = GlobalData.data.checkUser(
                new CommandLogin("dba","dba"), icl);
  } catch (Exception ex) {
      Debug.out(ex.toString(), MAJOR, 0);
      System.exit(1);
  }

Debug.out("sessionNo "+sessionNo, MAJOR, 0);
  sessionNo = cd.getSessionNo();
  iScope = new TestIScope(sessionNo);

  try {
//   ErrorLog.log.println("");
   Debug.out("Start parse1", MAJOR, 0);
    // open a simple stream to the input
   sin = (ITimeFrameBufferedReader)new InputStreamReader(System.in);
   lexer = new TimeFrameCommonLexer(sin);
   cG = new SampleCommandGeneratorServer();
   TimeFrameCommandsParser parser = new TimeFrameCommandsParser(lexer,cG,
       (IScope)iScope);
   do {
     try {
//Debug.out("call parser", MAJOR, 0);
     parser.program();
    } catch (RecognitionException ex) {
//Debug.out("commandBuffer:'"+lexer.getCommandBuffer()+"'", MAJOR, 0);
     parser.processError(ex);
    } catch (TokenStreamRecognitionException ex) {
//Debug.out("commandBuffer:'"+lexer.getCommandBuffer()+"'", MAJOR, 0);
     parser.processError(ex);
    } catch (TokenStreamRetryException ex) {
//Debug.out("commandBuffer:'"+lexer.getCommandBuffer()+"'", MAJOR, 0);
     parser.processError(ex);
    }
    if (parser.isEOF()){
//Debug.out("break on EOF", MAJOR, 0);
      break; // do notcall the program again
    }
   } while (true);

  } catch(Exception e) { //TokenStream IO exceptions or CharStreamExceptions
   // Close stream on IO errors
   if (cG!=null) {
     cG.translationError(lexer==null?null:lexer.getLineBuffer(),
      0, 0,null,null,e.getMessage());
   } else {
    // throw excepion
    throw new Error("Could not create SampleCommandGeneratorServer: "+e);
   }
  }
  System.exit(0);  // for parseview
 }
 ***********************************/
} // end of class Main


// here is the first part of the Parser

program
{ inputState.guessing = 0; // clear guessing mode
}
 :
 ( logout
 | cancel
 | login
 | getqueries
 | changepassword
 | getviewinfo
 | getfieldvalues
 | getdefinition
 | createquery
  | createdisplayjoin
  | modifyname
  | delete
  | executequery
  | sessionno
  | copy
  | rename
  | resetdisplay
  | makepublic
  | getattribute
  | setattribute
  | emptystatement
  | modifyDisplay
  | help
  | modifySearch

   )* EOF!  // perhaps none
   {// set EOF
    eofFlag = true; }
 ;

help!
: QUESTIONMARK // after ;
{ clearErrorFlagAndScope();
commandGenerator.helpCommand(TFlexer.getLineBuffer());
}
;

emptystatement!
: SEMI  // just skip
{ //clearErrorFlagAndScope();
  commandGenerator.emptyCommand(TFlexer.getLineBuffer());
}
;

// GetAttribute("attribute1");
// GetAttribute "attribute1" ;
getattribute!
: GETATTRIBUTE
 (LPAREN attr1:STRING_LITERAL RPAREN SEMI
  { clearErrorFlagAndScope();
commandGenerator.getAttribute(TFlexer.getLineBuffer(),attr1.getText());
  }
  | attr2:STRING_LITERAL SEMI
  { clearErrorFlagAndScope();
commandGenerator.getAttribute(TFlexer.getLineBuffer(),attr2.getText());
  }
)
;

----- Original Message -----
From: "martinkbraid" <mbraid at sqlworks.com>
To: <antlr-interest at yahoogroups.com>
Sent: Tuesday, April 15, 2003 12:12 PM
Subject: [antlr-interest] Re: exception thrown in syntatic predicate c an't
be caught!


> It's tricky. A stmt could be invalid because there are (a) invalid
> characters; (b) it is syntactically invalid (eg wrong sequence of
> tokens), or (c) it is semantically invalid (eg things stmt refers to
> doesn't exist). If it's invalid for any reason I want to skip to the
> next stmt. Trouble is, if the lexer skips to the next stmt (ie
> semicolon), the parser won't see the trailing invalid tokens and
> there is a possibility the initial subset of valid tokens are
> syntactically and semantically valid (ie I will have silently
> truncated the stmt - not good).
>
> The problem would be simplified if the filter=rule option didn't
> necessarily require the rule to be protected, that way I could always
> let the parser deal with invalid tokens. I'm basically coming round
> to the idea I need a lexer rule that captures everything that isn't
> lexacaly(?) valid (using the ~) and let the parser deal with these
> tokens which will not fit any rule and correctly signify a
> syntactcally invalid stmt.
>
> Thanks for your help.
> Martin
>
> PS. I'm parsing user written stmts, so you never know what's coming
> down the pike.
>
> --- In antlr-interest at yahoogroups.com, mzukowski at y... wrote:
> > Why do you have garbage characters in statements?
> >
> > You could handle this in your lexer too, by consuming characters
> until you
> > see a SEMICOLON, but you also have to handle comments and strings
> properly.
> > Then when you throw that exception, the next thing the parser sees
> should
> > always be a SEMICOLON.
> >
> > Monty
> >
> > -----Original Message-----
> > From: martinkbraid [mailto:mbraid at s...]
> > Sent: Monday, April 14, 2003 3:08 PM
> > To: antlr-interest at yahoogroups.com
> > Subject: [antlr-interest] Re: exception thrown in syntatic predicate
> > can't be caught!
> >
> >
> > The input to my lexer/parser is a series of statements delimited by
> > semicolons. I was using the lexer exception to tell the parser to
> > skip over the current statement and consumeUntil() the next
> semicolon
> > (ie skip over the remainder of the stmt). Since I posted my message
> I
> > made some progress by using the filter=rule option in the lexer and
> > have that rule automatically throw a TokenStreamException which my
> > parser captures. That works ... to a point. When the parser gets
> that
> > exception it does a consumeUntil(SEMICOLON), but if there is a 2nd
> > garabage character the lexer throws another exception and the whole
> > thing becomes a mess.
> >
> > Think I'll heed your advice and look at controlling the lexer more
> > carefully.
> >
> >
> > --- In antlr-interest at yahoogroups.com, mzukowski at y... wrote:
> > > Syntactic predicates work by trying a piece of syntax and then
> > checking if
> > > an exception was thrown.  When it finds a predicate that works it
> > then calls
> > > the parser for real, with actions turned back on.  Syntactic
> > predicates
> > > won't work if you can catch their exceptions.  Catch the
> exception
> > after the
> > > predicate has decide where to go.
> > >
> > > Or just catch and handle the exception in the lexer.  What
> exactly
> > are you
> > > doing with the exceptions anyhow?
> > >
> > > Monty
> > >
> > > -----Original Message-----
> > > From: martinkbraid [mailto:mbraid at s...]
> > > Sent: Sunday, April 13, 2003 7:07 PM
> > > To: antlr-interest at yahoogroups.com
> > > Subject: [antlr-interest] exception thrown in syntatic predicate
> > can't
> > > be caught!
> > >
> > >
> > > Because I need to be able to handle garbage characters passed to
> my
> > > parser/lexer, I'm doing my own error processing in a top level
> rule
> > > by catching ANTLRExceptions.
> > >
> > > By chance, during syntactic predicate processing, the lexer
> > > encounters a garbage character and throws a TokenStreamException.
> > But
> > > because inputState.guessing > 0 (because it was in a syntactic
> > > predicate), my exception handler does NOT get control and the
> > > exception passes out of the parser. What do I do? It would be
> > > impossible to avoid syntatic predicates?
> > >
> > > Thanks, Martin Braid
> > >
> > >
> > >
> > >
> > > Your use of Yahoo! Groups is subject to
> > http://docs.yahoo.com/info/terms/
> >
> >
> >
> >
> > Your use of Yahoo! Groups is subject to
> http://docs.yahoo.com/info/terms/
>
>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>


 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ 




More information about the antlr-interest mailing list