[antlr-interest] Any known good ways to recover from simple parse errors
Matthew Ford
Matthew.Ford at forward.com.au
Mon May 13 13:53:20 PDT 2002
This is what I used for commands, you may be able to modify it for
statements inside a Java program.
matthew
----- Original Message -----
From: "Matthew Ford" <matthew.ford at forward.com.au>
To: <antlr-interest at yahoogroups.com>
Sent: Friday, August 24, 2001 9:07 AM
Subject: Recovery from exceptions
> This is what I posted previously
> If I get any positive feed back I might be encourage to submit an FAQ
>
> matthew
> ----- Original Message -----
> From: "Matthew Ford" <matthew.ford at forward.com.au>
> To: <antlr-interest at yahoogroups.com>
> Sent: Saturday, June 30, 2001 9:05 AM
> Subject: Re: [antlr-interest] how do i skip unmatched characters?
>
>
> > I had this problem when handling commands comming in via telnet
> > I think this should be a common requirement. There should be an FAQ
about
> > it.
> > matthew
> >
> > This is what I did to skip to the next ; and then continue parsing
> > (ErrorLog and Debug are my own reporting logs)
> >
> >
> > In the Parser
> >
> > options {
> > k = 1; // one token lookahead
> > defaultErrorHandler = false; // Don't generate parser error
handlers
> > buildAST = true;
> > importVocab = TIMEFRAMECOMMONLEXER;
> > exportVocab = TIMEFRAMESERVERPARSER;
> >
> > }
> >
> >
> > {
> >
> > ICommandGeneratorServer commandGenerator;
> > TimeFrameCommonLexer TFlexer;
> > static String nl = System.getProperty("line.separator","\n");
> >
> > final static int MAJOR = 401;
> > final static int TRANSLATION_ERROR = 1;
> > final static int FIELD_QUALIFIER_ERROR = 2;
> > final static int QUERY_NOT_DEFINED = 3;
> > final static int NO_AGE_INDEX = 4;
> >
> > public TimeFrameCommandsParser(TimeFrameCommonLexer lexer,
> > ICommandGeneratorServer commandGenerator, IScope iScope) {
> > this(lexer);
> > TFlexer = lexer;
> > this.commandGenerator = commandGenerator;
> > this.iScope = iScope;
> > }
> >
> > 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; // block new errors until 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 clearErrorFlag() {
> > errorFlag = false;
> > }
> >
> >
> >
> > After the SEMI is seen I expect to find a new statement
> > if I do then after I find a valid statement I call clearErrorFlag()
> >
> > // SetAttribute("attribute1","attributeValue");
> > setattribute!
> > : SETATTRIBUTE
> > LPAREN attr:STRING_LITERAL COMMA value:STRING_LITERAL RPAREN SEMI
> > { clearErrorFlagAndScope();
> >
>
commandGenerator.setAttribute(TFlexer.getLineBuffer(),attr.getText(),value.g
> > etText());
> > }
> > ;
> >
> >
> >
> > Finally to tie it all together
> >
> > In the main program I start the parser like this (in its own thread)
> > The command the parser finds are put on a command stack to be handled by
> > another thread. This lets you issue cancel commands at any time.
> >
> > /**
> > * The method reads in commands one by one.
> > */
> > public void run() {
> > Debug.out(""+GlobalData.nl+" ---------- InputThread " + connectionNo +
"
> > starts.",MAJOR,0);
> >
> > try {
> > do {
> > try {
> > Debug.out("InputThread Call Parser",MAJOR,0);
> > parser.program();
> > } catch (RecognitionException ex) {
> > ErrorLog.log.println("RecognitionException: "+ ex.getMessage());
> > Debug.out("InputThread RecognitionException: "+
> > ex.getMessage(),MAJOR,0);
> > parser.processError(ex);
> > } catch (TokenStreamRecognitionException ex) {
> > ErrorLog.log.println("TokenStreamRecognitionException: " +
> > ex.getMessage());
> > Debug.out("InputThread TokenStreamRecognitionException: " +
> > ex.getMessage(),MAJOR,0);
> > parser.processError(ex);
> > } catch (TokenStreamRetryException ex) {
> > ErrorLog.log.println("TokenStreamRetryException: " +
> ex.getMessage());
> > Debug.out("InputThread TokenStreamRetryException: " +
> > ex.getMessage(),MAJOR,0);
> > parser.processError(ex);
> > } catch(TokenStreamIOException ex) {
> > Debug.out("InputThread TokenStreamIOException: " +
> > ex.getMessage(),MAJOR,0);
> > if (getStopped()) {
> > break;
> > }
> > }
> > if (parser.isEOF()) {
> > Debug.out("parser found EOF *****************",MAJOR,0);
> > break; // do not call the program again
> > }
> > } while (!getStopped()); // was while true
> >
> > }
> > catch(Exception e) { //TokenStream IO exceptions or
CharStreamExceptions
> > Debug.out(ExceptionBuffer.getStackTrace(e), Debug.STACKTRACE, 0);
> > // Close stream on IO errors
> > if (e instanceof antlr.TokenStreamIOException) {
> > Debug.out("TokenStreamIOException: one connection is lost",MAJOR,0);
> > listener.cancelConnection();
> > }
> > else {
> > Debug.out("other exception:",MAJOR,0);
> > TimeFrameException tfe =
> > TimeFrameException.makeTimeFrameException(MAJOR,EXCEPTION,e.toString() +
> > e.getMessage());
> > Errors error = new Errors(tfe);
> > beaconit.serverutils.CommandLog.log.printCommand(sessionNo,
> > connectionNo, error.toLogText());
> > ErrorLog.log.printError(sessionNo, connectionNo, error, "");
> > stack.add(error);
> > }
> > }
> >
> >
> > This is how I stop the input thread
> > /**
> > * This method is used to set the stop flag.
> > */
> > synchronized public void stopThread() {
> > Debug.out("stopThread is called in InputThread " +
> connectionNo,MAJOR,0);
> > stopped = true;
> > }
> >
> > /**
> > * Synchronized method returns the status of stop flag.
> > * @return the status of stop flag.
> > */
> > synchronized public boolean getStopped() {
> > return stopped;
> > }
> >
> > ----- Original Message -----
> > From: "Stdiobe" <stdiobe at enneya.com>
> > To: <antlr-interest at yahoogroups.com>
> > Sent: Saturday, June 30, 2001 4:47 AM
> > Subject: [antlr-interest] how do i skip unmatched characters?
> >
> >
> > >
> > > Hi,
> > >
> > > when the lexer generated by ANTLR encounters an unmatched character,
> > > it throws a TokenStreamRecognitionException which causes my lexer
> > > to exit (and also my parser).
> > >
> > > Does anyone know how I can skip unmatched characters in the lexer
> > > by reporting the error to the user (with linenumber, etc.), and have
> > > the lexer continue scanning for valid tokens.
> > >
> > > Stdiobe.
> > >
> > >
> > >
> > >
> > >
> > >
> > > 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