in reply to An adventure with 5.10 regular expressions

I haven't read everything yet, but I thought I'd post a link to a tutorial of mine before I come back to this. Operator Associativity and Eliminating Left-Recursion in Parse::RecDescent was written for Parse::RecDescent, but the principles apply to other LL parsers too.

Quickly, I think

expr : expr expr binop { [ BINOP => [ $item[3], $item[1], $item[2] ] ] } | term

can be transformed into

expr : term { push($item[1]) } expr_ | term expr_ : expr binop { [ BINOP => [ $item[2], pop(), $item[1] ] ] }

Factoring out common prefixes for speed:

expr : term { push($item[1]) } expr_1 expr_1 : expr_2 | # Automatic match { pop() } expr_2 : expr binop { [ BINOP => [ $item[2], pop(), $item[1] ] ] }

Inlining expr_2 for simplicity:

expr : term { push($item[1]) } expr_ expr_ : expr binop { [ BINOP => [ $item[2], pop(), $item[1] ] ] } | # Automatic match { pop() }

In short, keep looking for terms until you meet something that isn't (an operator), then eat up the last two terms that have been met.

I'll come back later to verify this and put it into 5.10 regex syntax.

Update: Fixed link

Replies are listed 'Best First'.
Re^2: An adventure with 5.10 regular expressions
by hipowls (Curate) on Feb 09, 2008 at 09:49 UTC

    Thanks for the link, it is great article. I've only skimmed it but it gets to the nub of the problem I had. I'll reread it and explore further, this time with a map;)

      The push and pop aren't accurate. I was trying to emulate P::RD's args. At the very least, the push needs to undo on backtracking (which is easy to implement even in pre-5.10).

      I need to read up on Perl 5.10 regexps before I can deliver a regexp version of that grammar, but right now, I'm out of town on a small screen. It'll have to wait.