Trying to understand prioritized rules, but my grammar fails to parse when I use the loosen operator

20 views
Skip to first unread message

mha...@gmail.com

unread,
Feb 3, 2017, 12:59:23 AM2/3/17
to marpa parser
I am using the simple boolean expression grammar below to learn how to use Marpa::R2. I am trying to understand how the Marpa loosen operator works.

#!/usr/bin/perl

use lib qw(/opt/share/perl/lib/perl5');

use strict;
use warnings;
use Marpa::R2;

my $BOOLEAN_EXPRESSION_DSL = q(
:default ::= action => eval
lexeme default = latm => 1
<boolean expression> ::=
      <bit>
    | ('(') <boolean expression> (')') action => ::first
    | ('!') <boolean expression> action => not
    | <boolean expression> '&&' <boolean expression> assoc => left action => and
   || <boolean expression> '||' <boolean expression> assoc => left action => or
<bit> ~ [01]
<blank> ~ [\s]+

:discard ~ <blank>
);
my $BOOLEAN_EXPRESSION_GRAMMAR = Marpa::R2::Scanless::G->new({source => \$BOOLEAN_EXPRESSION_DSL});

sub parse
{
    my $e = shift;
    my $recce = Marpa::R2::Scanless::R->new({grammar => $BOOLEAN_EXPRESSION_GRAMMAR, semantics_package => 'BOOLEAN_EXPRESSION_ACTIONS'});
    my $length_read = $recce->read(\$e);
    ($length_read != length $e) and die("!!!ERROR: Syntax error in boolean expression [$e:$length_read].\n"); 
    my $ambiguous_status = $recce->ambiguous();
    ($ambiguous_status) and die("!!!ERROR: Parse is ambiguous:\n$ambiguous_status");
    my $ret = $recce->value;
    print $$ret . "\n";
}

parse("0 && (1 || 1)");

sub BOOLEAN_EXPRESSION_ACTIONS::not
{
    my (undef, $b) = @_; 
    return $b != 0 ? 0 : 1;
}

sub BOOLEAN_EXPRESSION_ACTIONS::and
{
    my (undef, $lhs, undef, $rhs) = @_; 
    return ($lhs != 0 and $rhs != 0) ? 1 : 0;
}

sub BOOLEAN_EXPRESSION_ACTIONS::eval
{
    my (undef, $v) = @_;
    return (defined $v and $v != 0) ? 1 : 0;
}

When I run the program above I get this error:

Error in SLIF parse: No lexeme found at line 1, column 9
* String before error: 0 && (1\s
* The error was at line 1, column 9, and at character 0x007c '|', ...
* here: || 1)
Marpa::R2 exception at ./test.pl line 29.

If I change my grammar and replace the loosen operator with the alternation operator, then it works! Why?

I am trying to use '||' to make the grammar unambiguous, so that I can drop the parenthesis, and be able to write 0 && 1 || 1.

Thank you!

Jeffrey Kegler

unread,
Feb 3, 2017, 1:07:32 AM2/3/17
to Marpa Parser Mailing LIst
Off the top of my head and not tested, but:

I think you're trying to use the parentheses for grouping, but you have not written the grammar to do that.

For an example of how see the synopsis of the Scanless::G POD.

I hope this helps!

--
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 marpa-parser+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ruslan Shvedov

unread,
Feb 3, 2017, 5:05:09 AM2/3/17
to marpa-...@googlegroups.com
With group associativity specified for parens, like this

    | ('(') <boolean expression> (')') _assoc => group_ action => ::first

your script works for me. It complains about the lack of rule action named 'or' though.

--
Reply all
Reply to author
Forward
0 new messages