aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-143/wlmb/perl/ch-1.pl64
1 files changed, 37 insertions, 27 deletions
diff --git a/challenge-143/wlmb/perl/ch-1.pl b/challenge-143/wlmb/perl/ch-1.pl
index cc18d4ac91..80c20d3932 100755
--- a/challenge-143/wlmb/perl/ch-1.pl
+++ b/challenge-143/wlmb/perl/ch-1.pl
@@ -6,33 +6,42 @@
use v5.12;
use warnings;
use Scalar::Util qw(looks_like_number);
+use Try::Tiny;
my $original_string;
+my $previous;
my $current;
-my $next;
+my $token;
foreach (@ARGV){
- my $original_string=$current=$_;
- token();
- my $result=expression();
- say "$original_string=$result";
+ try {
+ $original_string=$previous=$current=$_;
+ token();
+ my $result=expression();
+ die "Extra characters: $previous\n" if defined $token->[0];
+ say "$original_string=$result";
+ }
+ catch {
+ warn $_;
+ };
}
sub token {
- $next=[$1,$1], return if $current=~s{^\s*([()*/+-])}{}; # symbol
- $next=['N',$1], return
+ $previous=$current;
+ $token=[$1,$1], return if $current=~s{^\s*([()*/+-])}{}; # symbol
+ $token=['N',$1], return
if $current=~s{^\s*([^()*/+\-\t\n ]*)}{}
and looks_like_number($1); # number?
- $next=[undef,undef], return if $current=~/^\s*$/; # nothing
- die "Unrecognizable input: $current";
+ $token=[undef,undef], return if $current=~/^\s*$/; # nothing
+ die "Unrecognizable input: $previous\n";
}
sub expression {
my $result=term();
while(1){
- my $op=$next->[0];
- last unless defined $op && $op=~m{[+-]};
- token();
- $result+=term(),next if $op eq '+';
- $result-=term(),next if $op eq '-';
+ my $op=$token->[0];
+ last unless defined $op && $op=~m{[+-]};
+ token();
+ $result+=term(),next if $op eq '+';
+ $result-=term(),next if $op eq '-';
}
return $result;
}
@@ -40,24 +49,25 @@ sub expression {
sub term {
my $result=simple();
while(1){
- my $op=$next->[0];
- last unless defined $op && $op=~m{[*/]};
- token();
- $result*=simple(),next if $op eq '*';
- $result/=simple(),next if $op eq '/';
+ my $op=$token->[0];
+ last unless defined $op && $op=~m{[*/]};
+ token();
+ $result*=simple(),next if $op eq '*';
+ $result/=simple(),next if $op eq '/';
}
return $result;
}
sub simple {
- my $op=$next->[0];
- my $val=$next->[1];
- die "Unrecognized expression: $current" unless defined $op && $op=~/[-(N]/;
+ my $op=$token->[0];
+ my $val=$token->[1];
+ die "Unrecognized expression: $previous\n" unless defined $op && $op=~/[-+(N]/;
token();
- return -simple() if $op eq '-';
- return $val if $op eq 'N';
- my $result=expression();
- $op=$next->[0];
- die "Unbalanced parenthesis: $current" unless defined $op and $op eq ')';
+ return -simple() if $op eq '-'; # unary -
+ return simple() if $op eq '+'; # unary +
+ return $val if $op eq 'N'; # number
+ my $result=expression(); # parenthesized expression
+ $op=$token->[0]; # closing parenthesis should follow
+ die "Unbalanced parenthesis: $previous\n" unless defined $op and $op eq ')';
token();
return $result;
}