2014-05-14 29 views
0

作为练习,我试图实现一个堆栈来计算后缀表达式。不能使用未定义的值作为子程序引用

use strict; 
use warnings; 

use Scalar::Util qw(looks_like_number); 

my %operators = (
    '+' => \&sum, 
    '-' => \&subs, 
    '*' => \&mul, 
    '/' => \&div, 
); 

print 'Enter an expression to evaluate : '; 
chomp($_ = <STDIN>); 
my @lettres=split(//); 

my @stack; 

for(my $i = 0; $i < @lettres; $i++){ 
    if(looks_like_number($lettres[$i])){ 
     unshift @stack, $lettres[$i]; 
    } else { 
     my $nb1 = shift @stack; 
     my $nb2 = shift @stack; 
     unshift @stack, $operators{$lettres[$i]}->($nb1,$nb2); 
    } 
} 

print 'Answer : ' .shift @stack; 

sub sum { return $_[0] + $_[1];} 
sub mul { return $_[0] * $_[1];} 
sub subs { return $_[0] - $_[1];} 
sub div { return $_[0]/$_[1];} 

当运行它,我得到:

Can't use an undefined value as a subroutine reference at polonaise.pl line 25, 
<STDIN> line 1. 

第25行是:

unshift @stack, $operators{$lettres[$i]}->($nb1,$nb2); 

我怀疑$operators{$lettres[$i]}->($nb1,$nb2);是造成问题,但我不知道为什么,因为我开始与Perl。

为什么会发生这种情况,我该如何解决这个问题?

+0

它表示'$ operators {$ lettres [$ i]}'返回undef。 – ikegami

+0

@ikegami我现在看到。这是因为我输入'8 6 2 -/3 +'作为输入,所以我在'letters'数组中获得了空格。还有没有更好的方法来做到这一点?就像只创建一个函数一样,也需要运算符作为参数?我的第一个实现是使用交换机,但由于它不被支持,我使用这种方法。 – user2336315

+0

而不是在所有的空格上分割所有空格/ \ s + /'这只会使用非空白的元素;即你的数字和运营商 –

回答

2

首先,只考虑非空格字符的有效令牌序列。其次,如果令牌看起来不像数字,请确保%operators散列中的句柄exists。我发现pushpop在处理堆栈时更自然,但这并不重要;

#!/usr/bin/env perl 

use strict; 
use warnings; 

# Turn on autoflush 
local $| = 1; 

use Scalar::Util qw(looks_like_number); 

my %operators = (
    '+' => \&add, 
    '-' => \&subtract, 
    '*' => \&multiply, 
    '/' => \&divide, 
); 

print 'Enter an expression to evaluate : '; 

my $input = <STDIN>; 

my @tokens = split ' ', $input; 

my @stack; 

for my $token (@tokens) { 
    if (looks_like_number($token)) { 
     push @stack, $token; 
    } 
    else { 
     if (exists $operators{$token}) { 
      my $op = $operators{$token}; 
      my $x = pop @stack; 
      my $y = pop @stack; 
      push @stack, $op->($x, $y); 
     } 
     else { 
      warn "Unknown token '$token'\n"; 
     } 
    } 
} 

print "Answer: $stack[-1]\n"; 

sub add  { $_[0] + $_[1];} 
sub multiply { $_[0] * $_[1];} 
sub subtract { $_[0] - $_[1];} 
sub divide { $_[0]/$_[1];} 
+0

是的,我喜欢移位和不移位原因,这就像我想象堆栈。 – user2336315

相关问题