[EMAIL PROTECTED] writes: > If anyone has a working tpr05a solution using Parse::RecDescent > or other CPAN module can you please post it to the list, as I > am also interested in comparing that solution to the others.
#!perl use Parse::RecDescent; sub Parse::RecDescent::reorder { my ($list) = @_; my $val = shift @$list; while (@$list) { my ($op, $arg) = splice @$list, 0, 2; $val .= " $arg $op"; } return $val; } my $grammar = <<'EndGrammar'; INPUT: INFIX /\Z/ { $item[1] } INFIX: <leftop:FACTOR m!(\+|\-)! FACTOR> { reorder($item[1]) } FACTOR: <leftop:EXPR m!(\/|\*)! EXPR> { reorder($item[1]) } EXPR: '(' INFIX ')' { $item[2] } | m!(-?)\s*([0-9]+)! { "$1$2" } EndGrammar my $parser = new Parse::RecDescent ($grammar); while (<>) { print $parser->INPUT($_),"\n"; } __END__ I haven't tested this against the full battery of tests but I'm confident it will pass---eventually (since we're no longer in competition the important thing is the algorithm, right?). The grammar is pretty simple, but there are probably three points to explain: 1) INPUT: INFIX /\Z/ The /\Z/ token needs to be matched so that the INPUT rule tries to consume all the input; otherwise the program will stop after matching just one INFIX. 2) EXPR: m!(-?)\s*([0-9]+)! { "$1$2" } This is the "single number" version of an expression; previous versions made this rule more explicit: INTEGER: '-' INTEGER { "-$item[2]" } | m/[0-9]+/ 3) C<reorder> simply transforms something like: "1 + 2 + 3 - 9" into "1 2 + 3 + 9 -". The grammar is much simpler if it uses the <leftop> pragma to deal with expressions like that one instead of trying to parse them piece by piece. See the <leftop> section in the Parse::RecDescent manpage for further explanation. Cheers, jason -- ||----|---|------------|--|-------|------|-----------|-#---|-|--|------|| | ``Ooooaah! | | I'm getting so excited about cheese-making I can't stand it!'' | ||--|--------|--------------|----|-------------|------|---------|-----|-|