The code to do it is in Marpa::R2::Internal::MetaAST_Nodes::priority_rule:: evaluate() <https://metacpan.org/source/JKEGL/Marpa-R2-3.000000/lib/Marpa/R2/MetaAST.pm#L568> .
On Wed, Aug 31, 2016 at 8:15 PM, <[email protected]> wrote: > Interesting. Can you suggest any references on how to implement this > grammar rewriting? > > Thanks! > > - Ryan > > On Wednesday, August 31, 2016 at 8:55:21 PM UTC-6, Jeffrey Kegler wrote: >> >> I've remembered a major reason for preferring the rewrite approach. If >> you parse then rank, you're using ambiguous parsing -- Marpa is cool with >> that, but it is not necessarily as fast as an unambiguous parse. If the >> expression is of size X the parse could be as bad as O(X^3) and that can >> make a difference if you have a lot of long expressions. >> >> If the grammar enforces precedence, ambiguous parsing can be avoided. >> >> 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. > -- 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.
