Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Infix/Postfix Notation

by xgunnerx (Initiate)
on May 20, 2002 at 14:42 UTC ( [id://167842]=sourcecode: print w/replies, xml ) Need Help??
Category: Miscellaneous
Author/Contact Info xgunnerx
Description: A script that does infix/postfix polish notation. Define the notation on line 5. Enjoy!
#!/usr/bin/perl -w
use strict;

## DEFINE THE NOTATION HERE!
my $notation = "((118-117)x(2+7))"; 

## Position hash with anony array
my %pos_hash = ("!" => 0, "+" => 1, "-" => 2, "x" => 3, "/" => 4, "(" 
+=> 5, ")" => 6);
my @postfix;
#infix data
my %action_hash = ("!" => [4, 1, 1, 1, 1, 1, 5],
                            "+" => [2, 2, 2, 1, 1, 1, 2],
                            "-" => [2, 2, 2, 1, 1, 1, 2],
                            "x" => [2, 2, 2, 2, 2, 1, 2],
                            "/" => [2, 2, 2, 2, 2, 1, 2],
                            "(" => [5, 1, 1, 1, 1, 1, 3]
                           );
#holders
my @texas;
my @cali;
$texas[0] = "!";
my $current_pos = 0;

#Define functions
sub seek_action {
    my $cur_texas = shift;
    $cur_texas = $texas[$cur_texas];
    my $symbol = shift;
    my $move_to = $pos_hash{$symbol};
    return $action_hash{"$cur_texas"}->[$move_to];
}

sub postfix_cal {
    my $a;
    my $b;
    my @postfix1 = @_;
    my @ret_stack;
    my $result;
    print "Postfix is @postfix1\n";
    foreach my $o (@postfix1) {
        if ($o =~ /\d+/) {
            push (@ret_stack, $o);
        }
        else {
            $b = pop (@ret_stack);
            $a = pop (@ret_stack);
            if ($o eq '+') {
                $result = $a + $b;
            }
            elsif ($o eq '-') {
                $result = $a - $b;
            }
            elsif ($o eq 'x') {
                $result = $a * $b;
            }
            elsif ($o eq '/') {
                $result = $a / $b;
            }
            push (@ret_stack, $result);
        }
    }
    return pop(@ret_stack);
}


while ($notation =~ /(\d+|\/|x|\-|\+|\(|\))/g) {
    push (@postfix, $1);
}

my $i;
for ($i = 0; $i < scalar@postfix; $i++) {
    my $action;
    #find action
    if ($postfix[$i] !~ /\d+/) {
        $action = seek_action($current_pos, $postfix[$i]);
    }
    else {
        push(@cali, "$postfix[$i]");
        next;
    }
    if (defined($action)) {
        #perform action
        if ($action == 1) {
            push (@texas, $postfix[$i]);
            $current_pos = scalar@texas;
            $current_pos--;
            next;
        }
        elsif ($action == 2) {
            my $move_cali = pop(@texas);
            push(@cali, $move_cali);
            $current_pos = scalar@texas;
            $current_pos--;
            $i--;
            next;
        }
        elsif ($action == 3) {
            pop(@texas);
            $current_pos = scalar@texas;
            $current_pos--;
            next;
        }
        elsif ($action == 4) {
            last;
        }
        elsif ($action == 5) {
            print "Error!\n";
            last;
        }
    }
}
my $result = postfix_cal(@cali);

print "Answer is: $result\n";
Replies are listed 'Best First'.
Re: Infix/Postfix Notation
by Anonymous Monk on Mar 03, 2005 at 17:37 UTC
    Works great, but does work with decimal or floating point numbers. I would like to explan to include cos(), sin() etc. Not much "comments" thus a little diffcult in reverse engineering the program, esp how "action_hash" was formatted.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://167842]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-03-29 15:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found