Hello again,

I'm having some issues determining how to prod Marpa to parse in the manner 
I want instead of just a manner that fits the string :)  I have a complete 
test case at the bottom of the post here so you can copy/paste and see the 
problem in action.  Parse string is in the __DATA__ section.

The problem is this line in the input string (and other lines like it):
   Pat n2000000g0000002; #HOT#

The idea is that this would match the first alternative of this rule:
Pattern         ::= PAT_DECLARE PAT_NAME OptPatOption ';' TagStr
                 || PAT_DECLARE PAT_NAME OptPatOption ';'

The commented string at the end of the line (#HOT#) is intended to match 
the TagStr rule if possible.  If not, then it will match the alternative 
rule that does not include TagStr.    This Pattern rule is part of the Node 
rule here:

Node            ::= Pattern | GlobalPlist | ReferencePlist || COMMENT

This rule can occur multiple times in a row.    Instead of matching the 
first alternation of the Pattern rule that includes the TagStr rule, Marpa 
seems to match the second alternation without the TagStr rule, then use 
COMMENT to match the ''#HOT#' string.  I would have thought that since the 
second alternation of the Pattern rule is lower precedence due to the '||' 
alternation operator, it would have matched TagStr first.  COMMENT is also 
lower priority than the Pattern rule.

Could anyone offer some insight here?  Am I misunderstanding precedence in 
some way?


########################################################################################

use strict;
use warnings;

use Marpa::R2;
use Data::Dumper;

my $file = $ARGV[0];
my $s;

if (defined $file) {
    # parse data from file if given
    open my $fh, '<', $file
        or die "Failed to open file ($file):$!\n";

    # for processing speed, tossing out full line comments and empty lines 
now
    while (<$fh>) {
        next if /^\s*#.*$/ and !/^\s*#\s*base\s*=/;
        next if /^\s*$/;
        $s .= $_
    }

    close $fh or die "Failed to close file ($file): $!\n";
}
else {
    # parse data from DATA
    while (<DATA>) {
        next if /^\s*#.*$/ and !/^\s*#\s*base\s*=/;
        next if /^\s*$/;
        $s .= $_
    }
}

my $grammar_str = <<'END_GRAMMAR';
inaccessible is fatal by default
lexeme default    = latm => 1 action => [ name, value ]
:default        ::=           action => [ name, value ]

:start          ::= PlistFile
PlistFile       ::= VersionData GlobalPlists
VersionData     ::= 'Version' FLOAT ';'
OptPlOptions    ::= Option*
Option          ::= '[' OPTION_DATA ']'

GlobalPlists    ::= GlobalPlist+
GlobalPlist     ::= GLOBAL_PL_DECLARE PL_NAME OptPlOptions '{' 
OptEmbeddedBase Nodes '}'

OptEmbeddedBase ::= EmbeddedBase*
EmbeddedBase    ::= '#' 'base' '=' BaseNumbers [\n]
BaseNumbers     ::= BASE_NUMBER+ separator => COMMA

Nodes           ::= Node+
Node            ::= Pattern | GlobalPlist | ReferencePlist || COMMENT

Pattern         ::= PAT_DECLARE PAT_NAME OptPatOption ';' TagStr
                 || PAT_DECLARE PAT_NAME OptPatOption ';'
OptPatOption    ::= Option*
TagStr          ::= '#' TagList '#'
TagList         ::= TAG* separator => COMMA

ReferencePlist  ::= 'PList' RefPlName ';'
RefPlName       ::= OptRefFile PL_NAME
OptRefFile      ::= RefFile*
RefFile         ::= FILE_NAME ':'

COMMA             ~ ','
COMMENT           ~ '#' comment_chars [\n]
FLOAT             ~ int | int '.' int
BASE_NUMBER       ~ int
PL_NAME           ~ identifier
TAG               ~ identifier
PAT_NAME          ~ identifier
PAT_DECLARE       ~ 'Pat' | 'Pattern'
GLOBAL_PL_DECLARE ~ 'GlobalPList' | 'LocalPList' | 'PatternList'
FILE_NAME         ~ [\w\.]+
OPTION_DATA       ~ [\w \.,]*

identifier        ~ [\w]+
ws                ~ [\s]+
int               ~ [\d]+
comment_chars     ~ [^\n]+

:discard          ~ ws
END_GRAMMAR

my $grammar = Marpa::R2::Scanless::G->new({
    source         => \$grammar_str,
});

my $parser = Marpa::R2::Scanless::R->new({
    grammar           => $grammar,
    trace_values      => 2,
    trace_terminals   => 1,
});

my $time = time;
eval {
    $parser->read( \$s );
};
if ($@) {
    print "PARSE ERROR:$@\n";
    die "EXITING\n";
}
else {
    my $total_time = time - $time;

    print "PARSED ENTIRE STRING.\n";
    print "  Seconds required ($total_time)\n"; <STDIN>;

#    print $parser->show_progress(0, -1);
    print $parser->show_progress;
}

print STDERR Dumper( $parser->value );


__DATA__
Version 1.0;

GlobalPList plist1 [option1] [option2] {
    #base=111
    # this is a full line comment
    Pat n1000000g0000001; # this is a partial line comment
    Pat n2000000g0000002; #HOT#

    LocalPList plist2 {
        Pat n5000000g0000005;
        GlobalPList plist4 { Pat n8000000g0000008; #KEEP# } }

    Pat n3000000g0000003; #HOT,COLD#
    Pat n4000000g0000004;

    PList plist2;

    PList file1.plist:plist3;
}

GlobalPList plist2 [option3] {
    PList plist1;
    Pattern n6000000g0000006;
    Pattern n7000000g0000007;
}

-- 
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