[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