Marpa::R2 uses a *rewrite* to implement priority. It's done in Marpa::R2::Internal::MetaAST_Nodes::priority_rule::evaluate() <https://metacpan.org/source/JKEGL/Marpa-R2-3.000000/lib/Marpa/R2/MetaAST.pm#L568> in the Marpa::R2 code.
As for using rule ranks, the SLIF allows the user to use them as well, so I don't use them in the SLIF to implement prioritization -- I am not even sure they can be used in this way. On Wed, Aug 31, 2016 at 4:43 PM, <[email protected]> wrote: > I'm working on Ruby bindings for libmarpa. They're coming along quite > well. Right now I'm trying to implement prioritized alternatives ('||' in > SLIF). I think I'm close, but the following example has me scratching my > head. Please be patient as I try to give just enough background. (It's > really not that much if you skip the code and dumps.) > > First of all, to implement priorities in the Ruby wrapper, I'm using the > rule ranking. I'm not modifying the symbol rankings at all. Here is the > Perl version. (I know there are plenty of examples on how to do the > calculator grammar "right." It's the most straightforward example I could > come up with.) > > my $grammar_str = " > :default ::= action => [name,values] > :start ::= expr > expr ::= number || > expr '*' expr || > expr '+' expr > number ~ [\\d]+ > "; > my $input = '3+4*5+6*7*8'; > > my $grammar = Marpa::R2::Scanless::G->new({ source => \$grammar_str }); > my $recce = Marpa::R2::Scanless::R->new({ grammar => $grammar}); > > # check for complete parsing > my $len_read = $recce->read( \$input ); > die "Incomplete read" if $len_read != length $input; > > # check for ambiguous parse result > if ( my $ambiguous_status = $recce->ambiguous() ) { > chomp $ambiguous_status; > die "Parse is ambiguous\n", $ambiguous_status; > } > > I get a single parse result with the '+' before the 6 at the top of the > expression tree. > > In my Ruby bindings, I'm assigning the ranks so that the "number" rule has > the highest rank, the multiply rule has the middle rank, and the addition > rule has the lowest rank. Here is the output of the 'show_rules' method > for my grammar. (The default rank is 0. If the rank is equal to zero, it > is not printed.) > > R0: S2 ::= S3 > number ::= number.rule > R1: S1 ::= S2 rank 2 > expr.rule ::= NUMBER > R2: S4 ::= S0 S5 S0 > EXPR /\*/ EXPR ::= EXPR /\*/ EXPR > R3: S1 ::= S4 rank 1 > expr.rule ::= EXPR /\*/ EXPR > R4: S6 ::= S0 S7 S0 > EXPR /\+/ EXPR ::= EXPR /\+/ EXPR > R5: S1 ::= S6 > expr.rule ::= EXPR /\+/ EXPR > R6: S0 ::= S1 > expr ::= expr.rule > > The DSL gets in the way a little on the LHS of the productions (no, this > is not a CSG). Remember, it's a work in progress. :-) The point is that > I'm generating the rules with the ranks I expect because the output above > reads the rule rank back from libmarpa. > > The parsing result I get has five results, with the '*' operators at the > top of the tree. In prefix notation, the results are as follows. > > "(* (* (* (+ 3 4) (+ 5 6)) 7) 8)" > "(* (* (+ 3 4) (* (+ 5 6) 7)) 8)" > "(* (* (+ 3 4) (+ 5 6)) (* 7 8))" > "(* (+ 3 4) (* (* (+ 5 6) 7) 8))" > "(* (+ 3 4) (* (+ 5 6) (* 7 8)))" > > This looks like an equivalent of the 'dangling-else' ambiguity. > > I have two questions. > > 1. Why is my priority backwards? Marpa::R2 gave me the '+' rule at the > outer-most level, while my Ruby wrapper gave the '*' rule at the outer-most > level every time. In other words, help me understand what 'rank' means in > the Marpa context, and how it is applied. > > 2. Why does Marpa::R2 give an unambiguous result? Even with the '+' rule > on the outside, there are two choices for associativity. > > Thanks! > > - Ryan > > -- > You received this message because you are subscribed to the Google Groups > "marpa parser" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "marpa parser" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
