Sign in to follow this  
ApochPiQ

Boost::spirit and syntax errors

Recommended Posts

Does anyone have any good resources for handling grammar parse failures with boost::spirit? I can detect that an error occurred by checking parse_info::full, but as for actually locating the area where parsing failed, I'm at a loss. Occasionally the stop iterator will point to something vaguely in the right area, but I'm after something a little more precise (something like what a real compiler produces, if possible). I'm not afraid of any dark magic if that's what it'll take [wink]

Share this post


Link to post
Share on other sites
It's been like 5 years since I've used spirit, but...

if you can make shortcut-or operator behavior for rules, then the perl-esque 'parse || die' sort of behavior will trigger a failure semantic action which can be used for errors and the such.

Share this post


Link to post
Share on other sites
Yep, I second Telastyn's suggestion. For instance, if you encounter a class in your token stream, you know that the next token is either an identifier of a syntax error, and you can provide a fairly informative error message (expected identifier after 'class' at current-position).

Share this post


Link to post
Share on other sites
I've been playing around with some options, but so far nothing works; it either matches too much or too little, so either "everything" is a syntax error, or actual problems are ignored.

Does anyone have an example grammar that properly handles syntax errors? For instance, I have this rule:

CodeBlock
= OPENBRACE[EnterBlockPP(*self.State)] >>
(*(Control | VariableDefinition | Operation)) >>
CLOSEBRACE[ExitBlockPP(*self.State)]
;


If I try to follow this with an error capture clause like | (*anychar_p)[SyntaxError()] then it incorrectly matches the code block's opening/closing braces and flags them as errors.

I suspect I just haven't quite gotten my head around something, but it's starting to look like I may need to heavily rework my grammar to get even primitive error handling to work.

Share this post


Link to post
Share on other sites
OK, I found this page which details how parser exceptions can be used for handling parse errors. This turned out to solve my particular problem beautifully. For example, the earlier rule is now changed slightly and correctly detects syntax errors:

CodeBlock
=
SyntaxErrorGuard(Expect(
OPENBRACE[EnterBlockPP(*self.State)] >>
(*(Control | VariableDefinition | Operation)) >>
CLOSEBRACE[ExitBlockPP(*self.State)])
)[SyntaxErrorHandler(*self.State)]
;



There's a guard object and an assertion object (SyntaxErrorGuard and Expect, respectively) which handle the actual work of detecting and handling an error.


So I think I've got it all handled now - thanks for the input!

Share this post


Link to post
Share on other sites
Nifty!

[edit: it looks like it uses exceptions as code path. Little icky, but seems like a reliable way of falling out of the parse tree. Going to have to look into that for my stuff]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this