How can error reporting in grammars be improved?

2020-01-29 01:00发布

问题:

Is there a way to get Perl 6 to generate an error message if a grammar does not match? Or at least return the position of the last data it processed? It is quite hard to fix syntax errors if all I get from the parser is 'no match'.

回答1:

If your focus is generating messages for users of your grammar, see Generating Good Parse Errors from a Parser and Grammar::ErrorReporting.

The rest of this answer is about debugging.

First, you can embed arbitrary closures (code) in Perl 6 rules (or tokens or regexes). Just type { your code goes here } in the middle of a rule. So you could just sprinkle { say ... } statements where helpful for debugging. (Note that $/ and its relatives $0, $1 etc. and named sub-captures $<foo> etc. are automatically updated to refer to the current Match object and its sub-captures corresponding to the enclosing rule immediately prior to entering the closure so you can introspect how the match is going at that point in the regex.)

But there are better options.

Are you using the "batteries included" Rakudo Star distribution? (You should be unless you've got good reason not to.) If so, you can add the line use Grammar::Tracer; (as described in the slides at http://www.jnthn.net/papers/2011-yapceu-grammars.pdf) to get a full trace of a parse.

My personal preference is to use the Rakudo debugger which provides everything Grammar::Tracer does plus a whole lot more besides (single stepping, breakpoints, etc. of all Perl 6 code including regexes and grammars). The debugger is introduced in this video.

If you have any more questions, I recommend you visit the always friendly IRC channel #perl6.