[antlr-interest] [Bulk] Re: Correct way to handle custom errors?

Victor Giordano power_giordo at yahoo.com.ar
Tue Feb 8 16:00:21 PST 2011


Hello Sthepen: i was having problems with "custom errors handling" too .
So far, to catch the errors i added to my grammar.g file this snippet of 
code:


@lexer::members
{
     @Override
     protected Object recoverFromMismatchedToken (IntStream input,int 
ttype,BitSet follow) throws RecognitionException
     {
         throw new MismatchedTokenException (ttype, input);
     }

     @Override
     public Object recoverFromMismatchedSet (IntStream input, 
RecognitionException e, BitSet follow) throws RecognitionException
     {
         throw new MismatchedSetException (follow, input);
     }

     @Override
     public void reportError (RecognitionException e)
     {
         Class exceptionClass = e.getClass ();
         String msg = "Línea invalida";
         if (exceptionClass == NoViableAltException.class)
         {
             NoViableAltException nvae = (NoViableAltException) e;
             msg = "Símbolo invalido " + nvae.c;
         }
         throw new RuntimeException (msg);
     }	
}

@parser::members
{
     /** Para atrapar errores cuando se repiten tokens válidos*/
     @Override
     protected Object recoverFromMismatchedToken (IntStream input,int 
ttype,BitSet follow) throws RecognitionException
     {
         // Desactivo el mecanismo de recuperación por defecto
         throw new MismatchedTokenException (ttype, input);
     }

     @Override
     public void reportError (RecognitionException e)
     {
         Class exceptionClass = e.getClass ();
         String msg = "Línea invalida";
         if (exceptionClass == NoViableAltException.class)
         {
             NoViableAltException nvae = (NoViableAltException) e;
             msg = "Símbolo en posición " + (nvae.charPositionInLine+1) 
+ " invalido : " + nvae.token.getText ();
         }
         if (exceptionClass == EarlyExitException.class)
         {
             EarlyExitException eee = (EarlyExitException) e;
			msg = "La expresión esta mal formada. Revisar el '" + 
eee.token.getText () + "'";
         }
         if (exceptionClass == MismatchedTokenException.class)
         {
             MismatchedTokenException mte = (MismatchedTokenException) e;
             msg = "La expresión esta mal formada. Revisar el '" + 
mte.token.getText () + "'";
         }
         throw new RuntimeException (msg);
     }
}

And works perfectly... but i still think that is only a work around... 
cuz i really don't understand how to catch every kind of error propertly.

Hope that helps.
Grettins!

P.D: The message strings are in spanish: Basically the sayd you put 
thinks wrong.


El 07/02/2011 02:48 p.m., Stephen McGruer escribió:
> Jim,
>
> Thanks for the suggestion - although I don't quite want the level of detail
> you guys go into (and I don't quite understand all of it, possibly because I
> don't know the JavaFX syntax!) the source code was very useful and I think
> I've now got enough to put in some decent error messages.
>
> There are two things I'm still having trouble with that I think are related
> to this question strongly enough to not warrant a new thread. The first is
> printing out the line that the error occurred on. I wanted to try out
> mimicking the sort of print out that javac does when it encounters an error,
> but I can't work out how to get access to the text of the line that is
> having the problem. I read here -
> http://www.antlr.org/wiki/pages/viewpage.action?pageId=1769 - that if you
> are using the CommonTokenStream you should have access to a "token" with the
> information, but in my getErrorMessage override that simply returns null for
> most of the errors I've tried (currently MisMatchedToken exceptions):
>
> public String getErrorMessage(RecognitionException e, String[] tokenNames) {
>      // Prints out true!
>      System.out.println(e.token == null);
> }
>
> I then read that you can use the inputstream attached to the
> RecognitionException instead (can't quite remember where... the official
> docs?), but can't figure out how to do this. Currently I have tried casting
> it from an IntStream to a CharStream (I think it will always be a CharStream
> for me... maybe XD) and played with the various methods available, but none
> of them seem to offer a way to just print out the current line. The most
> promising looks like substring(start, stop), but I cannot find a way to get
> the length of the line to give as the "stop" parameter! I also assume that
> if I do this method I should mark the stream before I begin, and rewind it
> once I'm done?
>
> Alternatively, if there's a "better" way to do this when overriding the
> getErrorMessage method please tell me.
>
> The second problem I'm having is with is stopping the parser from running if
> the lexer has spat out any errors. As far as I can tell, it's very possible
> and easy to stop the lexer after a single error message is thrown, but I
> cannot find anywhere that shows how to let the lexer continue but not let
> the parser run. Since all error messages are only thrown once you call
> something like "program_return parserResult = parser.program();" (i.e. the
> lexer has no errors until after this line), then I can't stop it parsing the
> syntactically invalid file and spitting out more (useless, imo) error
> messages! Is there a 'correct' or even just any way to achieve this?
>
> Thanks,
> Stephen
>
> On 5 February 2011 16:28, Jim Idle<jimi at temporal-wave.com>  wrote:
>
>> If you download the source code to the Java FX compiler you will have a
>> complete example to work from, assuming a Java target. Start by creating a
>> superclass for the parser and overriding various error reporting points.
>> The JavaFX compiler will show you how to do that.
>>
>> Jim
>>
>>> -----Original Message-----
>>> From: antlr-interest-bounces at antlr.org [mailto:antlr-interest-
>>> bounces at antlr.org] On Behalf Of Stephen McGruer
>>> Sent: Friday, February 04, 2011 4:14 PM
>>> To: antlr-interest at antlr.org
>>> Subject: [antlr-interest] Correct way to handle custom errors?
>>>
>>> I was wondering what the "correct" way to handle custom errors in ANTLR
>>> 3 was. I'm implementing a parser/lexer for a small subset of C, and
>>> want to give better error messages than the general mismatched tokens
>>> error.
>>>
>>>   From this post -
>>> http://www.antlr.org/wiki/display/ANTLR3/Error+reporting+and+recovery I
>>> implemented my own error reporting class which grabs the recognition
>>> exception from the Parser. However, I'm then unsure about the best
>>> approach is to start recognising errors - from things as basic as
>>> replacing the name of my variable name rule (ID) with a more user-
>>> friendly term such as "identifier", to more complex things such as
>>> giving nice error messages when the user attempts to set a variable to
>>> a value that isn't an integer or character (the only two allowable
>>> types in my subset). The recognition exception doesn't seem to be too
>>> useful - getMessage() seems to return null.
>>> I assume that the getErrorHeader and getErrorMessage methods do
>>> something different to get information. The only way I can think of
>>> checking for errors at the moment is manually scraping the strings
>>> returned by these methods, which seems... clumsy.
>>>
>>> So, is there a sort of "normal" or "usual" method to approaching
>>> parser/lexer error message handling when doing programming language
>>> parsing?
>>>
>>> I hope the above contained enough information, and made sense.
>>>
>>> Thanks,
>>> Stephen
>>>
>>> List: http://www.antlr.org/mailman/listinfo/antlr-interest
>>> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-
>>> email-address
>>
>> List: http://www.antlr.org/mailman/listinfo/antlr-interest
>> Unsubscribe:
>> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>>
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>


More information about the antlr-interest mailing list