#!/usr/bin/perl # parse.pl -- learning Parse::RecDescent ex. use strict; use warnings; use diagnostics; use Parse::RecDescent; my $parser = new Parse::RecDescent( q{ startrule: calculation eofile {$return = $item[1];} statement: grouped_op | number grouped_op: '(' calculation ')' {$return = $item[2];} calculation: add_calculation | sub_calculation | mul_calculation | div_calculation add_calculation: statement '+' statement {$return = $item[1] + $item[3];} sub_calculation: statement '-' statement {$return = $item[1] - $item[3];} mul_calculation: statement '*' statement {$return = $item[1] * $item[3];} div_calculation: statement '/' statement {$return = $item[1] / $item[3];} number: /\d+/ eofile: /^\Z/ }); my @tests = ( '4 + 8', '6 + (3 - 2)', '(6 + (3 - 2)) + 1', '4 + 8 + 5', '5 * 5', '5 / 5', ); my $result; foreach my $test (@tests) { if ( $result = $parser->startrule($test) ) { print "'$test' = $result\n"; } else { print "'$test' failed parser\n"; } }