#!/usr/bin/perl
#####
# from http://www.adp-gmbh.ch/perl/rec_descent.html
###############
use strict;
use warnings;

use Parse::RecDescent;

my $grammar = q {
                                         { my %vars }
start:          statements               

statements:     statement ';' statements 
              | statement                

statement:      variable '=' statement   { $vars{$item[1]} = $item[3] }
              | expression               

expression:     term '+' expression      { $item[1] + $item[3] }
              | term '-' expression      { $item[1] - $item[3] }
              | term			 

term:           factor '*' term          { $item[1] * $item[3] }
              | factor '/' term          { $item[1] / $item[3] }
              | factor			 

factor:         number
              | variable                 { $vars{$item[1]} ||= 0 }
              | '+' factor               { $item[2] }
              | '-' factor               { -1 * $item[2] }
              | '(' statement ')'        { $item[2] }

number:         /\d+/                    

variable:       /[a-z]+/i

};

my $parser = Parse::RecDescent->new($grammar);

my @text = ( "three=3;six=2*three;eight=three+5;2+eight*six+50",
	     "x",
	     "x+1",
	     "x=0; x+1",
	     "x=0; x=x+1",
	     "x=0; x=x+1; x",
	     "x=0; x=x+1; x+1",
	    );
for my $text (@text){
  my $result = $parser->start($text);
  print "result of '$text' is $result .\n";
}



