Grammar::PrettyErrors
Make grammars fail parsing with a pretty error instead of returning nil.
SYNOPSIS
Input:
use Grammar::PrettyErrors;
grammar G does Grammar::PrettyErrors {
rule TOP {
'orange'+ % ' '
}
}
# Handle the failure.
G.parse('orange orange orange banana') orelse
say "parse failed at line {.exception.line}";
# Don't handle it, an exception will be thrown:
G.parse('orange orange orange banana');
Output:
failed at line 1
--errors--
1 │▶orange orange orange banana
^
Uh oh, something went wrong around line 1.
Unable to parse TOP.
DESCRIPTION
When the Grammar::PrettyErrors
role is applied
to a Grammar, it changes the behavior of a parse
failure. Instead of returning nil
, a failure
is thrown. The exception object has information
about the context of the failure, and a pretty
error message that includes some context around
the input text.
It works by wrapping the <ws>
token and keeping
track of a highwater mark (the position), and the
name of the most recent rule that was encountered.
You can also use a token other than <ws>
by sending
a parameter to the role with the name of the token
to use, e.g.
grammar G does Grammar::PrettyErrors["myws"] {
...
token myws { ... }
}
This technique is described by moritz in his excellent book [0] (see below).
CLASSES, ROLES
Grammar::PrettyErrors (Role)
ATTRIBUTES
-
quiet
-- Bool, default false: just save the error, don't throw it. -
colors
-- Bool, default true: make output colorful. -
error
-- aX::Grammar::PrettyError
object (below).
METHODS
new
-- wraps the<ws>
token as described above, it also takes additional named arguments (to set the ATTRIBUTEs above).
X::Grammar::PrettyError (class)
METHODS
-
line
-- the line number at which the parse failed (starting at 1). Or 0 if no lines were parsed; -
column
-- the column at which the parse failed (starting at 1). Or 0 if no characters were parsed; -
lastrule
-- the last rule which was parsed. -
report
-- the text of a report including the above information, with a few lines before and after. (see SYNOPSIS) -
message
-- Same asreport
.
EXAMPLES
grammar G does Grammar::PrettyErrors { ... }
# Throw an exception with a message when a parse fails.
G.parse('orange orange orange banana');
# Same thing
G.new.parse('orange orange orange banana');
# Pass options to the constructor. Don't throw a failure.
my $g = G.new(:quiet, :!colors);
$g.parse('orange orange orange banana');
# Just print it ourselves.
say .report with $g.error;
# Use the failure to handle it without throwing it.
G.parse('orange orange orange banana') orelse
say "parse failed at line {.exception.line}";
SEE ALSO
-
[0] Parsing with Perl 6 Regexes and Grammars and the accompanying code
-
Grammar::ErrorReporting
AUTHOR
Brian Duggan