[Newcompiler] Re: [SmaCC] error handling

John Brant brant at refactory.com
Sat Sep 23 14:06:12 UTC 2006


Mathieu Suen wrote:

> Thanks for your previous answer about this topic. I am bit confuse with error handling:
> 
> When you have this grammar:
> 
> Expression
>     : "(" Expression ")"
>     | "(" Expression error {self signalError: 'Missing ")"' beforeToken: '2'}
>     | "(" error {self signalError: 'Missing expression' beforeToken: '2'
> "-- for an expression like ()"}
>     | ...other rules...
>     ;
> 
> What occur after #signalError:beforeToken: ?

It would depend on what the #signalError:beforeToken: did. If it
returns, then it will continue parsing. At the end, it will signal an
error so it doesn't return a buggy parse (#checkForErrors).


> Is there a way to continue parsing? (This could be usefull for syntax highlighting)

If you want a syntax highlighter, you could start with the one in VW
(http://wiki.cs.uiuc.edu/VisualWorks/RB+Code+Highlighter).

> I have an others questions:
> 
> I have read your suggestion about #handleError:. So if I understand you, you propose to override
> #handleError: in our Parser?
> 
> I don't see where you put:
> (self actionFor: self rightParenthesisId) ~= self errorAction
> 	ifTrue: [self signalError: 'Missing ")" beforeToken: currentToken]

In your parser's subclass, you can just define #handleError: as:
handleError: anInteger
	(self actionFor: self rightParenthesisId) ~= self errorAction
		ifTrue: [self signalError: 'Missing ")" beforeToken: currentToken].
	^super handleError: anInteger

Essentially, this would check if you are in a state that can accept a ).
If you are, then it would signal an exception with the message that you
want displayed to the user. Instead of using a special message for
reporting the error, you could use the #reportErrorMessage: that
SmaCCParser already defines -- you'll need to set the errorToken
instance variable first though:
handleError: anInteger
	(self actionFor: self rightParenthesisId) ~= self errorAction
		ifTrue:
			[errorToken := currentToken.
			self reportErrorMessage: 'Missing ")"'].
	^super handleError: anInteger


> I have read the default implementation of #handleError: but I don't really understand how things go
> on. Can #findErrorHandlerIfNoneUseErrorNumber: be usefull for error handling?

I doubt that it would be that helpful. It is a larger method which will
make it harder to override. The method finds all states on the stack
that will shift an "error", and collects their next state after shifting
the "error". It then dismisses the input tokens until it finds a token
that will shift from one of the next states. If it finds a token that
will shift, it patches the stack and continues parsing with that token.
If it can't find any token that will shift, then it calls #reportError:.



John Brant


More information about the Newcompiler mailing list