Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Infix/Postfix Notation

by xgunnerx (Initiate)
on May 20, 2002 at 14:42 UTC ( #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";

Comment on Infix/Postfix Notation
Download Code
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.

Back to Code Catacombs

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (13)
As of 2015-07-29 22:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (269 votes), past polls