Update: Most helpfully Simon pointed out on #perl that I am using return instead of $return = ... Where were those eyedrops again?!
I have been playing a bit with the RecDescent tutorial at perl.com. It doesn't quite work. In particular if I try running
"a = 5 ; print a ; print 20"
with the parser in that program, then it only prints 5 and doesn't process anything that follows... Grrh. Any clues? I have pasted the full program below for your convenience:
#!/usr/bin/perl -w
use strict;
use Parse::RecDescent;
use Data::Dumper;
use vars qw(%VARIABLE);
# Enable warnings within the Parse::RecDescent module.
$::RD_ERRORS = 1; # Make sure the parser dies when it encounters an error
$::RD_WARN = 1; # Enable warnings. This will warn on unused rules &c.
$::RD_HINT = 1; # Give out hints to help fix problems.
my $grammar = <<'_EOGRAMMAR_';
# Terminals (macros that can't expand further)
#
OP : m([-+*/%]) # Mathematical operators
INTEGER : /[-+]?\d+/ # Signed integers
VARIABLE : /\w[a-z0-9_]*/i # Variable
expression : INTEGER OP expression
{ return main::expression(@item) }
| VARIABLE OP expression
{ return main::expression(@item) }
| INTEGER
| VARIABLE
{ return $main::VARIABLE{$item{VARIABLE}} }
print_instruction : /print/i expression
{ print $item{expression}."\n" }
assign_instruction : VARIABLE "=" expression
{ $main::VARIABLE{$item{VARIABLE}} = $item{expression} }
dump_instruction : "dump"
{ print Data::Dumper->Dump([\%main::VARIABLE], [qw(VAR)]); }
instruction : print_instruction
| assign_instruction
| dump_instruction
startrule: instruction(s /;/)
_EOGRAMMAR_
sub expression {
shift;
my ($lhs,$op,$rhs) = @_;
$lhs = $VARIABLE{$lhs} if $lhs=~/[^-+0-9]/;
return eval "$lhs $op $rhs";
}
my $parser = Parse::RecDescent->new($grammar);
my $foo = "a = 5 ; print a ; print 20";
print "$foo\n";
$parser->startrule($foo);
Abigail points out on #perl that it seems like a bug in Parse::RecDescent. It does the print_instruction and then puts "a" back into what needs to be parsed. I noticed that too when enabling RD_TRACE; but thought I was just doing somethign wrong. Am I, or is it a bug as Abigail said it might be?