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.

Reply via email to