Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

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

by 7stud (Deacon)
on Feb 07, 2013 at 16:58 UTC ( #1017698=note: print w/ replies, xml ) Need Help??


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

Question #1 is ... what do you want? (No, seriously.) What interpretation of these three strings do you want to be “correct?” Are they three distinct cases, or examples of the same one?

Sorry, I know the frustration. I see now that what I said has multiple interpretations, and that I didn't even follow what I tell others to do when posting questions like this. To clarify: I want to be able to apply my grammar to take this string:

     { hello }

...and find a match.. Then I want to be able to apply the same grammar to this string:

     {{ hello }}

...and also find a match. Then I want to be able to apply the same grammar to this string:

     {{{ hello }}}

and also find a match. By "match", I mean that my program should produce no errors, and these lines:

my $parser = Parse::RecDescent->new($grammar) or die "Bad grammar!\n"; defined $parser->startrule($text) or die "Can't match text";

...should not produce any output. So when I run my program three times on each of those strings, each time there should be no output at all. What I am trying to code is a backreference.

But now that I think about it, applying my desired grammar to this three line block of text:

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

...would only require a trivial adjustment to the grammar:

startrule: brace_block(s) #adjustment brace_block: lbrace(1..) 'hello' <something> lbrace: / [{] /xms rbrace: / [}] /xms

In any case, I figured out a solution. The grammar below allows me to parse 'hello', preceded by a variable number of braces, followed by the same number of braces that preceded 'hello':

startrule: <rulevar: $rbraces> startrule: lbrace(s) { my $lbraces = join '', @{$item[1]}; $rbraces = "}" x length $lbraces; } 'hello' "$rbraces" lbrace: / [{] /xms

Instead of using a rule for the right braces, I am using a literal. Is there a better way to produce a backreference?

Please provide a full representative example of the type of data you need to parse, and we’ll help you write the proper grammar-mojo. It does take practice.

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:

Can't use string ("{{") as an ARRAY ref while "strict refs" in use at +(eval 14) line 377
I find it frustrating that Damian didn't use Carp, so that I could pin down exactly which line in my code is causing that error--I could care less which line in his code is causing the error. Another thing I find frustrating is that a rule doesn't return its whole match to another rule. Why in the heck is the default to return only what matched the last term of a rule? I have no idea how the default behavior would ever be useful.


Comment on Re: Parse::RecDescent: how does <matchrule:> work?
Select or Download Code

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (10)
As of 2015-07-30 10:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (271 votes), past polls