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