pl@nereida:~/Lperltesting$ cat calc510withactions4.pl #!/usr/local/lib/perl/5.10.1/bin//perl5.10.1 use v5.10; # Infix to postfix translator using 5.10 regexp # Original grammar: # exp -> exp [-+] term # | term # term -> term [*/] digits # | digits # Applying left-recursion elimination we have: # exp -> term re # re -> [+-] term re # | # empty # term -> digits rt # rt -> [*/] rt # | # empty sub rc { my $ofs = - shift; my $np = @-; substr($_, $-[$ofs], $+[$np+$ofs] - $-[$ofs]) } my $input; my @stack; my $regexp = qr{ (?&exp) (?(DEFINE) (? (?&term) (?&re) (?{ say "exp -> term re" }) ) (? \s* ([+-]) (?&term) \s* (?{ push @stack, $^N }) (?&re) (?{ say "re -> [+-] term re" }) | # empty (?{ say "re -> empty" }) ) (? ((?&digits)) (?{ # intermediate action push @stack, $^N }) (?&rt) (?{ say "term-> digits($^N) rt"; }) ) (? \s*([*/]) ((?&digits)) \s* (?{ # intermediate action push @stack, rc(1), rc(2) }) (?&rt) # end of definition (?{ say "rt -> [*/] digits($^N) rt" }) | # empty (?{ say "rt -> empty" }) ) (? \s* \d+ ) ) }xms; $input = <>; chomp($input); if ($input =~ $regexp) { say "matches: $&\nStack=(@stack)"; } else { say "does not match"; }