in reply to Parse::RecDescent and mini-language parsing

OK, just taking a quick untested whack at your original language. Presuming you want and/or/xor to be at the same precedence level, I'd code it like this:
expression: <leftop: term termop term> termop: 'and' | 'or' | 'xor' term: '(' expression ')' | condition condition: field comparison value field: '<' timethingy '>' timethingy: 'DAY' | 'WEEK' comparison: '<=' | '<' | '=' | '>=' | '>' | '!=' value: /\d+/
That'll probably get you mostly started.

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

Replies are listed 'Best First'.
Re: &bull;Re: Parse::RecDescent and mini-language parsing
by Flame (Deacon) on Mar 30, 2003 at 23:50 UTC
    Wow, this certainly seems more efficient, I'll start messing around with it and see what I can come up with. Thanks!



    My code doesn't have bugs, it just develops random features.

    Flame ~ Lead Programmer: GMS (DOWN) | GMS (DOWN)

      And if you wanted 'and' to be higher precedence than 'or' and 'xor', so as not to confuse the rest of us:
      expression: <leftop: term termop term> termop: 'or' | 'xor' term: <leftop: factor factorop factor> factorop: 'and' factor: '(' expression ')' | condition condition: field comparison value field: '<' timethingy '>' timethingy: 'DAY' | 'WEEK' comparison: '<=' | '<' | '=' | '>=' | '>' | '!=' value: /\d+/

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

Re: &bull;Re: Parse::RecDescent and mini-language parsing
by Flame (Deacon) on Mar 31, 2003 at 05:26 UTC

    Note: Before I start, I have noticed your other suggestion, however this is based off of this code.

    Well, I've modified your suggestion a little, and assuming I understood your suggestion's intent, I seem to have screwed it up somewhere along the line, because it still does not handle ( ) properly, but I can't see why. This is what I now have:

    use Parse::RecDescent; use Data::Dumper; use strict; use warnings; $::RD_TRACE = 1; my $grammar = q~ expression: <leftop: term termop term> eod termop: /and/i | /xor/i | /or/i term: '(' <commit> expression ')' | condition condition: element comparison element element: '<' <commit> /-?\w+/ '>' | /\d+/ comparison: /=[><]=/ <commit> <error: Unable to match comparison> | /=?[><]=?/ | '=' | '!=' eod: /^\Z/ ~; my $parser = new Parse::RecDescent($grammar) or die; #defined($parser->RecTest('h =>= h')) or die; my $test = '(<MONTH> => <DAY>)'; # or (<MONTH> = <MARCH> and <DAY> = < +TUESDAY>)'; print Dumper($parser->expression($test));

    I repeatedly get "$VAR1 = undef;" in reply, as well as enough debugging info to scroll off my screen (unfortunately I can't capture it into a file either, Parse::RecDescent overrides any re-declarations on STDERR, and I can't use "perl language.pl | more" or any other similar methods since those don't want to capture the error messages...) Anyone see what I'm missing, it's probably obvious, but I've been staring at it for 4 hours now without anything more constructive happening than the condensing of a few rules in the grammar declaration.





    My code doesn't have bugs, it just develops random features.

    Flame ~ Lead Programmer: GMS (DOWN) | GMS (DOWN)

      Flame feels rediculously stupid.

      Ok, found THAT problem. The "eod" rule at the end of "expression", was being called upon whenever expression was used, meaning that the ')' had to somehow come after the end of the data. With that fixed, I need to do a few more tests, but this is how it looks NOW:

      my $grammar = q~ logic: expression eod expression: <leftop: term termop term> termop: /and/i | /xor/i | /or/i term: '(' <commit> expression ')' | condition condition: element comparison element element: '<' <commit> /-?\w+/ '>' | /\d+/ comparison: /=[><]=/ <commit> <error: Unable to match comparison> | /=?[><]=?/ | '=' | '!=' eod: /^\Z/ ~;




      My code doesn't have bugs, it just develops random features.

      Flame ~ Lead Programmer: GMS (DOWN) | GMS (DOWN)