[antlr-interest] C# Error Recovery
Johannes Luber
jaluber at gmx.de
Thu Apr 17 10:02:17 PDT 2008
Terence Parr schrieb:
>
> On Apr 16, 2008, at 1:55 PM, Johannes Luber wrote:
>
>> Gavin Lambert schrieb:
>>> I have a rule like this in my grammar (C# target, latest interim build):
>>> tag[String name]
>>> : WS? t=TAG { $t.text.Equals("<" + $name + ">") }? NL
>>> ;
>>> catch [FailedPredicateException ex] { throw new
>>> RecognitionException("Expected <" + $name + "> but found " + $t.text,
>>> ex, Input); }
>>> The intent should be clear -- I want to validate that I'm receiving
>>> the tag I'm expecting to get at that point in the input, but I want
>>> to give it a custom error message.
>>> I want all the normal ANTLR backtracking and recovery mechanisms to
>>> take effect, which basically seems to mean that I need to be throwing
>>> a RecognitionException or derived class thereof.
>>> The problem lies in BaseRecognizer.GetErrorMessage, which completely
>>> ignores the Message of the incoming exception and uses a series of
>>> type-specific tests to construct a new message; leaving it blank if a
>>> base RecognitionException is thrown. I can work around this by
>>> deriving a new exception from RecognitionException and overriding
>>> GetErrorMessage to deal with that appropriately, but I shouldn't need
>>> to.
>>> Proposed fixes:
>>> 1. At minimum, the first line of GetErrorMessage should be changed to
>>> assign "e.Message" as the default message, not null.
>>> 2. Preferably, *all* the type specific code in GetErrorMessage should
>>> be removed, and the exception Message should be set to the equivalent
>>> when the exception is thrown in the first place (in their
>>> constructors). It just seems silly to try to "fix it up" after the
>>> fact.
>> I'm not opposed against a fix, but the last paragraph isn't quite
>> clear to me. Equivalent of what? Furthermore, Ter, why is that code,
>> as it is? After all, it is like this in the Java target, too.
>
> Here were my thoughts at the time:
>
> /** What error message should be generated for the various
> * exception types?
> *
> * Not very object-oriented code, but I like having all error message
> * generation within one method rather than spread among all of the
> * exception classes. This also makes it much easier for the exception
> * handling because the exception classes do not have to have
> pointers back
> * to this object to access utility routines and so on.
With object you mean BaseRecognizer?
> Also, changing
> * the message for an exception type would be difficult because you
> * would have to subclassing exception, but then somehow get ANTLR
> * to make those kinds of exception objects instead of the default.
> * This looks weird, but trust me--it makes the most sense in terms
> * of flexibility.
How about extracting the strings into an extra file? Or look for a such
file and use defaults for not overwritten messages?
> *
> * For grammar debugging, you will want to override this to add
> * more information such as the stack frame with
> * getRuleInvocationStack(e, this.getClass().getName()) and,
> * for no viable alts, the decision description and state etc...
> *
> * Override this to change the message generated for one or more
> * exception types.
> */
>
> Still seems valid I guess.
I believe you only missed another alternative design.
Johannes
More information about the antlr-interest
mailing list