14
July
2007

Программа-калькулятор на Perl

Posted in: Полезные программы |

“Сколько ты знае?ь языков, столько раз ты человек” - подумал я и ре?ил посмотреть на какой-нибудь скриптовый язык.
Выбор довольно боль?ой, но из наиболее на?умев?их языков, а именно Python, Ruby, Perl, я ре?ил попробовать последний.
Даже не знаю, чем был обоснован мой выбор.
Ва?ему вниманию предлагается простая программка - “калькулятор” на Perl.

Не судите строго, это все таки первое, что я написал используя Perl.
?так, исходник программки.

$args_len = scalar(@ARGV);
die "1 argument needed" unless $args_len == 1;

($expression) = @ARGV;

unless ($expression =~ /^d[+|-|*|/|d]+d$/) {
  die "invalid expression (invalid symbols)";
}

if ($expression =~ /[+-*/]{2,}/) {
  die "invalid expression (duplicate operations)";
}

@numbers = split /(?:[+|-|*|/])/, $expression;

@signs = split /(?:d+)/, $expression;
unless (@signs[0]) {
  @signs = @signs[1..$#signs];
}

$changed = 1;
while ($changed) {
  $changed = 0;
  for ($i = 0; $i < = $#signs; $i++) {
    if (@signs[$i] eq "*" || @signs[$i] eq "/") {
      my $first = @numbers[$i];
      my $second = @numbers[$i + 1];
      my $result = &calcula ($first, $second, @signs[$i]);

      print ($first . @signs[$i] . $second . "=" . $result . "n");

      if ($i == 0) {
        if ($i == $#signs) {
          @signs = ();
        } else {
          @signs = (@signs[$i+1..$#signs]);
        }
      } else {
        if ($i == $#signs) {
          @signs = (@signs[0..$i-1]);
        } else {
          @signs = (@signs[0..$i-1], @signs[$i+1..$#signs]);
        }
      }

      if ($i == 0) {
        if ($i == $#numbers - 1) {
          @numbers = ($result);
        } else {
          @numbers = ($result, @numbers[$i+2..$#numbers]);
        }
      } else {
        if ($i == $#numbers - 1) {
          @numbers = (@numbers[0..$i-1], $result);
        } else {
          @numbers = (@numbers[0..$i-1], $result, @numbers[$i+2..$#numbers]);
        }
      }

      $changed = 1;
      last;
    }
  }
}

$changed = 1;
while ($changed) {
  $changed = 0;
  for ($i = 0; $i <= $#signs; $i++) {
    if (@signs[$i] eq "+" || @signs[$i] eq "-") {
      my $first = @numbers[$i];
      my $second = @numbers[$i + 1];
      my $result = &calcula ($first, $second, @signs[$i]);

      print ($first . @signs[$i] . $second . "=" . $result . "n");

      if ($i == 0) {
        if ($i == $#signs) {
          @signs = ();
        } else {
          @signs = (@signs[$i+1..$#signs]);
        }
      } else {
        if ($i == $#signs) {
          @signs = (@signs[0..$i-1]);
        } else {
          @signs = (@signs[0..$i-1], @signs[$i+1..$#signs]);
        }
      }

      if ($i == 0) {
        if ($i == $#numbers - 1) {
          @numbers = ($result);
        } else {
          @numbers = ($result, @numbers[$i+2..$#numbers]);
        }
      } else {
        if ($i == $#numbers - 1) {
          @numbers = (@numbers[0..$i-1], $result);
        } else {
          @numbers = (@numbers[0..$i-1], $result, @numbers[$i+2..$#numbers]);
        }
      }

      $changed = 1;
      last;
    }
  }
}

print ($expression . "=" . @numbers[0]);

sub calcula {
  my $res;
  my ($lex1, $lex2, $sign) = @_;

  if ($sign eq "+") {
    $res = $lex1 + $lex2;
  } elsif ($sign eq "-") {
    $res = $lex1 - $lex2;
  } elsif ($sign eq "*") {
    $res = $lex1 * $lex2;
  } elsif ($sign eq "/") {
    $res = $lex1 / $lex2;
  } else {
    die "unknown operation";
  }

  return $res;
}

Входящий параметр должен быть один и представлять собой строку из чисел и знаков сложения, вычитания, умножения и деления без пробелов.
Например, 2+3*4-8/2+1.
Приоритет операций учитывается.

Код, как вы заметите, очень похож по форматированию на Java код :).
Буду благодарен за любые советы, особенно идеалогические.

4 Comments »

RSS feed for comments on this post.



Vlad
February 18, 2008 #

Хочу задать только один вопрос почему только PERL ???
Ведь не из легких…

February 18, 2008 #

Потому что я был молод и наивен. Нужно учить javascript, тем более что базовые знания уже есть.

Прохожый
July 19, 2008 #

$numbers = ” 2 * ( 2 + 2 )”;
print eval($numbers);

:)

mardong
February 25, 2009 #

2Прохожый

Даже с пробелами. Любым количеством пробелов…
Другое дело - о?ибки - их нужно вылавливать - ну это еще несколько строк

2c0nst

Понятно, что целью было почувствовать язык, и для этого была взята типовая задача. Но ведь вот в чем дело: если типовые задачи ре?ать на Perl типовыми же методами, то язык не пойме?ь. Можно попробовать, например, организовывать и работать с хэ?ем - забыв о том, что хэ? - встроенная тип переменных Perl’а. ? что получим?

Поэтому - незачот

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> <pre>