電卓
Perlで逆ポーランドの電卓を作ろうという話題
#!/bin/perl
use strict;
my @stack;
my $actions = {
'+' => sub { push @stack, pop(@stack) + pop(@stack) },
'*' => sub { push @stack, pop(@stack) * pop(@stack) },
'-' => sub { my $s = pop(@stack); push @stack, pop(@stack) - $s },
'/' => sub { my $s = pop(@stack); push @stack, pop(@stack) / $s },
'NUMBER' => sub {push @stack, $_[0] },
'_DEFAULT_' => sub { die "Unrecognized token '$_[0]'; aborting" }
};
my $result = evaluate($ARGV[0], $actions);
print "Result: $result\n";
sub evaluate {
my ($expr, $actions) = @_;
my @tokens = split /\s+/, $expr;
for my $token (@tokens) {
my $type;
if ($token =~ /^\d+$/) {
$type = 'NUMBER';
}
my $action = $actions->{$type} || $actions->{$token} || $actions->{_DEFAULT_};
$action->($token, $type, $actions);
}
return pop(@stack);
}
ざっとこんな感じ。
my $action = $actions->{$type} || $actions->{$token} || $actions->{_DEFAULT_};
この辺りがLLぽい。一つめのハッシュが駄目なら、次のハッシュ。
class calclator {
public:
int calc(std::vector
std::vector
for(it=tokens.begin();it!=tokens.end();it++) {
if(it->type() == NUMBER) {
st.push(*it);
} else if(it->type() == OPERATOR) {
token op2 = st.top(); st.pop();
token op1 = st.top(); st.pop();
st.push((*it)(op1, op2));
} else {
std::cout << "error" << std::endl;
}
}
token result = st.top();
st.pop();
return result.value();
}
private:
std::stack
};
一応C++でもそれっぽくできて動いたけど、なんかダサイ。
スタックに、文字列でも数字でも入れられるようにしようとしたのが失敗。逆ポーランド記法ではスタックに入るのは数字のみと気がついたのは、完成間近。それに気がついたとたんやる気がなくなった。なんでもほいほいpushできるLLすげー。普通の会社でC++で開発していて、やべー設計間違ってるって時、どうしてるんだろうな。
'+'のアクションで、std::plus
Perl、入出力込みで数時間。(丸写しだけどね)
C++、3日がかりで、入力はソースに直書き。
むう、そろそろC++挫折しそうになってきた。
« MINIX本 | Main | 中はLISPです »
The comments to this entry are closed.
Comments