Created
May 18, 2013 15:31
-
-
Save pstuifzand/5604827 to your computer and use it in GitHub Desktop.
Jeffrey reminded me of a technique for generating error messages that I tried some time ago. This technique is quite easy to implement now that completion events are implemented in Marpa. The following example shows how. The grammar contains a rule for a common error in a certain non-existent example language. Some people like to extend a class,…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use strict; | |
use 5.10.0; | |
use Marpa::R2 2.054000; | |
use Data::Dumper; | |
my $grammar = Marpa::R2::Scanless::G->new({ | |
source => \<<'SOURCE', | |
:start ::= <class definition> | |
<class definition> ::= <class normal definition> block | |
| <class unimplemented definition> block | |
<class normal definition> | |
::= 'class' name | |
block ::= '{' '}' | |
event class_def_err = completed <class unimplemented definition> | |
<class unimplemented definition> | |
::= 'class' name 'extends' name | |
:discard ~ ws | |
ws ~ [\s]+ | |
name ~ [\w]+ | |
SOURCE | |
}); | |
my $re = Marpa::R2::Scanless::R->new({grammar => $grammar}); | |
my $input = <<'INPUT'; | |
class Hello extends Test {} | |
INPUT | |
my $pos = $re->read(\$input); | |
while ($pos < length $input) { | |
for (my $i = 0; my ($event) = $re->event($i); $i++) { | |
if ($event->[0] eq 'class_def_err') { | |
my ( $g1_start, $g1_length ) = $re->last_completed('class unimplemented definition'); | |
return 'No expression was successfully parsed' if not defined $g1_start; | |
my $last_expression = $re->substring( $g1_start, $g1_length ); | |
my ($line,$column) = $re->line_column(); | |
die(sprintf 'When defining a class \'extends\' is not valid in "%s" at line %d', $last_expression, $line); | |
} | |
} | |
$pos = $re->resume($pos); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment