(Not so) fun with Parse::RecDescent

ask on 2003-01-13T10:29:34

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?