Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: Parse::RecDescent: how does <matchrule:> work?

by 7stud (Deacon)
on Feb 07, 2013 at 19:07 UTC ( [id://1017715]=note: print w/replies, xml ) Need Help??


in reply to Parse::RecDescent: how does <matchrule:> work?

Yes, this is part of a larger grammar I'm working on, but I don't think posting the whole thing would be helpful. I would love to have you take a look at the complete grammar when I'm done. My current problem: when I incorporate the solution above into one of my rules, I can't get the blasted rule to return the entire match to other rules without causing the error:

Jiminy Christmas. It looks like an action appearing in the middle of a rule inserts the return value of the action as an additional entry in @item! The inserted value *immediately follows* the current subrule's match:

use strict; use warnings; use 5.012; use Parse::RecDescent; $::RD_ERRORS = 1; #Parser dies when it encounters an error $::RD_WARN = 1; #Enable warnings - warn on unused rules &c. $::RD_HINT = 1; #Give out hints to help fix problems. #$::RD_TRACE = 1; #Trace parsers' behaviour my $text = <<'END_OF_TEXT'; { hello } END_OF_TEXT my $grammar = <<'END_OF_GRAMMAR'; { use 5.012; use Data::Dumper; } startrule: brace_block(s) brace_block: <rulevar: ($lbraces, $rbraces)> brace_block: lbrace(1..) { $lbraces = join '', @{$item[1]}; $rbraces = '}' x length $lbraces; } 'hello' "$rbraces" { say Dumper(\@item); #$return = "$lbraces $item[2] $rbraces"; } lbrace: / [{] /xms --output:-- $VAR1 = [ 'brace_block', [ '{' ], '}', 'hello', '}' ]; ... ... ...

The output shows that in the brace_block rule, the match for the subrule lbrace(1..), i.e. $item[1], is an array containing the matching braces. That is as expected. However, immediately following that match is the closing brace returned by the action that follows the lbrace(1..) rule. As a result, the matches for the other subrules are at indexes one higher than where they normally would be at. So the last line in the last action, which attempts to return all the matching text for the brace_clause rule, i.e.

$return = "$lbraces $item[2] $rbraces";

needs to be changed to:

$return = "$lbraces $item[3] $rbraces";

The same grammar can be used for parsing the three line block of text:

{ hello }
{{ hello }}
{{{ hello }}}

use strict; use warnings; use 5.012; use Parse::RecDescent; $::RD_ERRORS = 1; #Parser dies when it encounters an error $::RD_WARN = 1; #Enable warnings - warn on unused rules &c. $::RD_HINT = 1; #Give out hints to help fix problems. #$::RD_TRACE = 1; #Trace parsers' behaviour my $text = <<'END_OF_TEXT'; { hello } {{ hello }} {{{ hello }}} END_OF_TEXT my $grammar = <<'END_OF_GRAMMAR'; { use 5.012; use Data::Dumper; } startrule: brace_block(s) { say Dumper(\@item); } brace_block: <rulevar: ($lbraces, $rbraces)> brace_block: lbrace(1..) { $lbraces = join '', @{$item[1]}; $rbraces = '}' x length $lbraces; } 'hello' "$rbraces" { $return = "$lbraces $item[3] $rbraces"; } lbrace: / [{] /xms END_OF_GRAMMAR my $parser = Parse::RecDescent->new($grammar) or die "Bad grammar!\n"; defined $parser->startrule($text) or die "Can't match text"; --output:-- $VAR1 = [ 'startrule', [ '{ hello }', '{{ hello }}', '{{{ hello }}}' ] ];

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1017715]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-03-19 11:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found