-
-
Save latk/1aa3265ed938ee4e309470d648827f39 to your computer and use it in GitHub Desktop.
Marpa ranks don't work as expected in sequence rules
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
#!perl | |
use strict; | |
use warnings; | |
use feature 'say'; | |
use Marpa::R2; | |
sub display_ast { my ($self) = @_; my $class = ref $self; "$class(@$self)" } | |
package Item { use overload q("") => \&main::display_ast } | |
package List { use overload q("") => \&main::display_ast } | |
# This grammar tries to be equivalent to a PEG or Regex with ordered choice: | |
# List: Item* | |
# Item: VAR = VAR // VAR = // VAR | |
# In order to force that "order", this grammar specifies "rank"s. | |
# This seems to fail because ranks are not evaluated left-to-right? | |
use constant BNF => <<'BNF'; | |
:default ::= bless => ::lhs | |
:discard ~ ws; ws ~ [\s]+ | |
List ::= Item* | |
Item ::= VAR '=' VAR rank => 2 | |
Item ::= VAR '=' rank => 1 | |
Item ::= VAR rank => 0 | |
VAR ~ [\w]+ | |
BNF | |
my $g = Marpa::R2::Scanless::G->new({ source => \BNF, bless_package => 'main' }); | |
sub all_parses { | |
my ($input) = @_; | |
my $r = Marpa::R2::Scanless::R->new({ grammar => $g, ranking_method => 'high_rule_only' }); | |
$r->read(\$input); | |
say "Input: $input"; | |
my $i = 0; | |
while (my $value_ref = $r->value()) { | |
$i++; | |
say "Parse $i: $$value_ref"; | |
} | |
return $i; | |
} | |
all_parses("a = b"); | |
# expected: List(Item(a = b)) | |
# actual 1: List(Item(a = b)) | |
# actual 2: List(Item(a =) Item(b)) | |
all_parses("a = b c"); | |
# expected: List(Item(a = b) Item(c)) | |
# actual 1: List(Item(a = b) Item(c)) | |
# actual 2: List(Item(a =) Item(b) Item(c)) | |
all_parses("a = b c = d"); | |
# expected: List(Item(a = b) Item(c = d)) | |
# actual 1: List(Item(a = b) Item(c = d)) | |
# actual 2: List(Item(a =) Item(b) Item(c = d) | |
# but not this one??? List(Item(a = b) Item(c =) Item(d)) ?? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment