Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: Can I get some rules help with PARSE::RECDESCENT

by Anonymous Monk
on Mar 12, 2018 at 14:07 UTC ( #1210723=note: print w/replies, xml ) Need Help??


in reply to Can I get some rules help with PARSE::RECDESCENT

Normally a rule such as expr would be written in right-recursive style: expr: expression expr(?) So, the output always contains two productions but the second may be a recursive instance. Alsobear in mind this tool generates recursive descent compilers which do not know about niceties like operator precedence. So the definition of expr normally has to consist of other rules (such as term and factor) expressly to handle precedence. The author points out some differences between this and tools like yacc but there are many others.
  • Comment on Re: Can I get some rules help with PARSE::RECDESCENT

Replies are listed 'Best First'.
Re^2: Can I get some rules help with PARSE::RECDESCENT
by DevM (Initiate) on Mar 15, 2018 at 19:14 UTC

    Ok, thanks to 7studs example I have had some success with this version of the parser.

    ################################################################### use strict; use warnings; $::RD_HINT=1; use Data::Dumper; #use autodie; use Parse::RecDescent; my $grammar =<<'END_OF_GRAMMAR'; #Start up action(executed in parser namespace): { use Data::Dumper; } startrule: expr { print "startrule:"; print Dumper(\@item); $return = \@item; } expr: operand(s) { print "expr rule:"; print Dumper(\@item); my $result = $item[1]; print 'Inside expr rule: $result='; print Dumper($result); $return = $result; } operand: /and|or/i { print "operand and/or:"; print Dumper(\@item); $return = lc($item[1]); } operand: /not/i { print "operand not:"; print Dumper(\@item); $return = [lc($item[1])]; } operand: '(' expr ')' { print "operand rule:"; print Dumper(\@item); $return = $item[2]; } | term { $item[1] } term: /[\w\s=><\/:"'\*_]+/ END_OF_GRAMMAR my $input = "(cvtype='problem') and ((problem_description match '*') a +nd (((problem_synopsis match 'FCSIM') or (problem_synopsis match 'ATT +E')) OR not ((create_time>time('06/01/2014 0:00:00')) and (create_tim +e<time('09/30/2014 0:00:00')))))"; #my $input = "(cvtype='problem') OR not (problem_description match '*' +)"; print "Text: $input\n"; my $parser = Parse::RecDescent->new($grammar); my $result = $parser->startrule($input) or die "Could Not Parse!\n"; print "\n\nresult:"; print Dumper $result;

    The results look almost exactly like what I was hoping for:

    result:$VAR1 = [ 'startrule', [ [ 'cvtype=\'problem\'' ], 'and', [ [ 'problem_description match \'*\'' ], 'and', [ [ [ 'problem_synopsis match \'FCSIM\'' ], 'or', [ 'problem_synopsis match \'ATTE\'' ] ], 'or', 'not', [ [ 'create_time>time', [ '\'06/01/2014 0:00:00\'' ] ], 'and', [ 'create_time<time', [ '\'09/30/2014 0:00:00\'' ] ] ] ] ] ], $VAR1 ];

    My only complaint is that 'not' and 'and/or' are on the same level. I really want 'not' to be of higher precedence than 'and/or'. Hopefully making the output look like this:

    result:$VAR1 = [ 'startrule', [ [ 'cvtype=\'problem\'' ], 'and', [ [ 'problem_description match \'*\'' ], 'and', [ [ [ 'problem_synopsis match \'FCSIM\'' ], 'or', [ 'problem_synopsis match \'ATTE\'' ] ], 'or', [ [ 'not', ] [ [ 'create_time>time', [ '\'06/01/2014 0:00:00\'' ] ], 'and', [ 'create_time<time', [ '\'09/30/2014 0:00:00\'' ] ] ] ] ] $VAR1 ];

    I have tried to make a callback to expr. But that cuts the run short. Any help I can get would be greatly appreciated.

    DevM

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1210723]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2018-06-18 23:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?



    Results (111 votes). Check out past polls.

    Notices?