Skip to content

Instantly share code, notes, and snippets.

@pstuifzand
Created May 18, 2013 15:31
Show Gist options
  • Save pstuifzand/5604827 to your computer and use it in GitHub Desktop.
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,…
#!/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