[antlr-interest] how to force unexpected token error

hawkwall hawkwall at yahoo.com
Sat Nov 8 19:01:33 PST 2003


I am still missing something.  The following runs as I expect, and the
action is executed.

Input:
THREAT.CLASSES.110
NUMBER.OF.SURFACE.TO.AIR.THREAT.CLASSES:  3
end of Input:

Parser:
startSACLASS : (rules)+ ;

rules : threatclass 
        | sathreatclass
        ;
	
threatclass: THREAT_CLASSES ONETEN;
			
sathreatclass: SURFACE_TO_AIR COLON  NUMBER
	{System.out.println("Got Here");}
	;
end of Parser:


Lexer:
options {
	k=5; // character lookahead
	testLiterals=false;
}


tokens
{
	THREAT_CLASSES="THREAT.CLASSES.";
	SURFACE_TO_AIR="NUMBER.OF.SURFACE.TO.AIR.THREAT.CLASSES";
}



IDENTIFIER options { testLiterals=true;} : (LETTER | '.')+;
NUMBER : (DIGIT)+;

DOT : '.' ;
COLON : ':';
ONETEN : ("110") => "110" ; //predicate is an attempt to remove
nondetermism with NUMBER, but didn't work
private DIGIT : ('0'..'9') ;
private LETTER : ('A'..'Z');


WS	:	(	' '
		|	'\t'
		|	'\f' 
		|	(	options {generateAmbigWarnings=false;}
			:	"\r\n"  // DOS
			|	'\r'    // Macintosh
			|	'\n'	// Unix
			)
			{newline();}
		)+

    // now the overall whitespace action -- skip it!
    { $setType(Token.SKIP); }
    ;

end of Lexer:

I need the parser to catch it if the input is mispelled.  
The parser complains if I change the first line to 
THREAT.CASSES.110 or THREAT.CLASSES.112

It doesn't fail when I correct the first line and change the second
line to something like
NUMBER.OF.USRFACE.TO.AIR.THREAT.CLASSES: 3

I turned on the trace, and with the incorrect input on the second
line, it matches IDENTIFIER and 
then finished normally.  The action is never executed.  What is the
difference?  Why is unexpected token given 
in the first case but not the other.  I tried setting
defaultErrorHandler=false, but it didn't fix my problem.  I tried
putting EOF at the end of my start rule, but to no avail.  I tried to
factor
out the THREAT.CLASSES from the end of SURFACE_TO_AIR, also removing
the final dot from the THREAT_CLASSES token.
I changed the threatclass rule to :
THREAT_CLASSES DOT ONETEN
and then got a
line 1:1: unexpected token: THREAT.CLASSES.
error.  

I see why it is happening in the parser.  Here is the relevent java:
public final void startSACLASS() throws RecognitionException,
TokenStreamException {
		
		try {      // for error handling
			{
			int _cnt1421=0;
			_loop1421:
			do {
				if ((LA(1)==THREAT_CLASSES||LA(1)==SURFACE_TO_AIR)) {
					rules();
				}
				else {
					if ( _cnt1421>=1 ) { break _loop1421; } else {throw new
NoViableAltException(LT(1), getFilename());}
				}
				
				_cnt1421++;
			} while (true);
			}
		}
		catch (RecognitionException ex) {
			reportError(ex);
			consume();
			consumeUntil(_tokenSet_0);
		}
	}

	
The problem is the if ( _cnt1421>=1).  If I remove that and make the
code look like this:
				if ((LA(1)==THREAT_CLASSES||LA(1)==SURFACE_TO_AIR)) {
					rules();
				}
				else {
					throw new NoViableAltException(LT(1), getFilename());
				}

I get the expected result.  Is this correct, and if so, how do I do
this in the grammar file.
I took a look at the antlr source, and I think this is done in
JavaCodeGenerator.java, but I 
got lost pretty quick.

Thanks for your time, sorry for such a long post.

Mike Wall
   


 

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




More information about the antlr-interest mailing list