You are on page 1of 5

Introduction Expression Evaluation

Evaluating expressions is a classic application context for both grammars and stacks Grammars permit parsing of the expressions and creating data structures that represent the expression semantics correctly Stacks are useful for evaluating many kinds of expressions, most obviously algebraic expressions a*b-c, a/b*c, ((c+16)/b)+42 Recall that humans most commonly use infix notation for these expressions, i.e. val op val Problem: infix grammar is not a complete specification of expression semantics Operator precedence and parentheses are also required EECS 268 2 Dr. Douglas Niehaus 2008

Chapter 6 EECS 268 Dr. Douglas Niehaus

EECS 268

Dr. Douglas Niehaus 2008

Introduction
Solution: use prefix or postfix notation since their grammars are definitive, unambiguous, without needing precedence rules or parentheses Simple Algebraic Expression Grammars (1) infix = infix operator infix | operand | ( infix ) (2) prefix = operator prefix prefix | operand (3) postfix = postfix postfix operator | operand Example: Infix Prefix Postfix a bc Prefix: abc Postfix: ab c a (bc) Prefix: abc Postfix: abc
EECS 268 3 Dr. Douglas Niehaus 2008

Introduction
We thus want to be able to (1) Evaluate postfix (prefix) expressions, and (2) Convert from infix to postfix (prefix) expression. Evaluating postfix using a stack is amazingly easy once the basic pattern is understood Using a stack to convert from infix to postfix is also fairly simple, but is complicated by the operator precedence and parenthesis semantics Postfix grammar:
<postfix> = <identifier>|<postfix><postfix><operator> <identifier> = a | b | | z <operator> = + | - | * | /
EECS 268 4 Dr. Douglas Niehaus 2008

Postfix Expression Evaluation


We can use stack to help evaluate a postfix expression, while reading the expression elements (tokens) from left to right Operands are pushed on the stack Operators pop 2 operands and push results Stack contains 1 element, the result, when a valid expression is fully evaluated Algorithm is slightly more complex if we permit negative numbers (unary operator) Note we need a separate operator for this in postfix Excellent exercise for the student
EECS 268 5 Dr. Douglas Niehaus 2008

Postfix Expression Evaluation


Algorithm
for each token in postfix-expr if operand, push its value; if operator pop operand2; pop operand1; result = operand1 operator operand2; push result; value at top of stack is result of expression;

Consider the example Infix: 2 * (3+4) Postfix: 2 3 4 + *


EECS 268 6 Dr. Douglas Niehaus 2008

Postfix Expression Evaluation

Postfix Expression Evaluation


Postfix: abc/de+f*
ch a b c / d e + action push push pop op2 pop op1 calc & push push pop op2 pop op1 calc & push push push pop op2 pop op1 calc & push stack a ab a ab ab c ab (ab)/c (ab)/c d (ab)/c d e (ab)/c d (ab)/c (ab)/c (d+e)
8 Dr. Douglas Niehaus 2008

Infix: ((ab)/c)*((d+e)f
ch f pop * action push pop op2 op1 calc & push pop op2 pop op1 calc & push stack (ab)/c (d+e) f (ab)/c (d+e) (ab)/c (ab)/c (d+e)f (ab)/c ((ab)/c)*((d+e)f)

EECS 268

Dr. Douglas Niehaus 2008

EECS 268

Infix to Postfix Conversion


Assertions about the algorithm Operands never change order, infix postfix Operands can thus be written to the developing postfix sting as soon as they are read Operators, in contrast, move to the right and change order to reflect calculation order Move right: to follow the two operands Change order: due to operator precedence rules and grouping by parentheses Algorithm requires a data structure to hold a set of pending operators until we know they can be emitted in the right position within the postfix string
EECS 268 9 Dr. Douglas Niehaus 2008

Infix to Postfix Conversion


Pending operator set contents should be ordered from lowest to highest precedence, with the highest precedence being the one we work with Stack is good for that, if we follow the right push and pop rules when an operator is encountered in reading the infix token stream 1) if the stack is empty or if the new operator is higher precedence than that on top of the stack then push the new operator 2) Otherwise pop operators and append them to the growing postfix string until condition (1) applies Hard to realize it will work, but easy to specify as an algorithm
EECS 268 10 Dr. Douglas Niehaus 2008

Infix to Postfix Conversion


create an empty postfix string; while operator stack not empty { create an empty operator stack; pop operator while (next symbol S from infix != NULL) { append to postfix string if S is an operand then } append S to postfix string else if S == ( then push S else if S == ) then pop and append operators until matching ( found else { // must be some other operator while ( operator stack not empty AND precedence(tos) >= precedence(S) AND tos != ( ) pop operator & append to postfix string push S } }
EECS 268 11 Dr. Douglas Niehaus 2008

Infix to Postfix Conversion


Convert a-(b+c*d)/e to postfix form

EECS 268

12

Dr. Douglas Niehaus 2008

Postfix Expression Evaluation


Convert (ab)/c*(d+ef/g)
ch ( a b ) / c * action push output push output pop to ( push output pop push op stack ( ( ( ( / / * Postfix a a ab ab ab abc abc/

Prefix Evaluation
Reverse prefix and evaluate it
reverse given prefix expression; scan the reversed prefix expression; for each symbol in reversed prefix if operand then push its value onto stack S; if operator then { pop operand1; pop operand2; compute result = operand1 op operand2; push result back onto stack S; } return value at top of stack;
EECS 268 14 Dr. Douglas Niehaus 2008

ch ( d + e f / g )

action op stack push *( output *( push *(+ output *(+ pop *( push *( output *( push *(/ output *(/ pop to ( * pop until empty stack

Postfix abc/ abc/d abc/d abc/de abc/de+ abc/de+ abc/de+f abc/de+f abc/de+fg abc/de+fg/ abc/de+fg/*

EECS 268

13

Dr. Douglas Niehaus 2008

Prefix Evaluation Example


Prefix: */abc+def
ch f e d + c b a action push push push pop op1 pop op2 calc &push pop op1 pop op2 calc & push push push push pop op1 pop op2 calc & push stack f fe fed fe f f (d+e) f ((d+e)f) ((d+e)f) c ((d+e)f) c b ((d+e)f) c b a ((d+e)f) c b ((d+e)f) c ((d+e)f) c (ab)
15 Dr. Douglas Niehaus 2008

Infix to Prefix Conversion


reverse a given legal infix string (RIS); create empty reversed prefix string (RPS); create empty operator stack S; for each symbol ch in RIS { if ch is an operand { append ch to RPS; } else if ch == ) { push ch on S; } else if top(S) == ( { pop & append ops to RPS until matching ) // discard the two parentheses } else { // ch must be some other operator while ( S not empty AND prec(top(S)) > prec(ch) AND top(S) != ) ) { pop op; append op to RPS; } push S } }
EECS 268 16

Reversed: fed+cba/*
ch / * action stack pop op1 ((d+e)f) c pop op2 ((d+e)f) calc & push ((d+e)f) ((ab)/c) pop op1 ((d+e)f) pop op2 calc & push ((ab)/c)*((d+e)f)

while ( ! empty(S) ) { pop op from S; append op to RPS; } reverse RPS; output Prefix String

EECS 268

Dr. Douglas Niehaus 2008

Infix to Prefix Conversion Example


Infix: (ab)/c*(d+ef/g) Reversed: )g/fe+d(*c/)ba(
ch ) g / f e + d ( * action push output push output pop & out push output push output pop until ) push op stack ) ) )/ )/ ) ) ) )+ )+ * RPS g g gf gf/ gf/ gf/e gf/e gf/ed gf/ed+ gf/ed+ ch c / ) b a ( action op stack output * push */ push */) output */) push */) output */) pop until ) * / pop until empty stack RPS gf/ed+c gf/ed+c gf/ed+c gf/ed+cb gf/ed+cb gf/ed+cba gf/ed+cba gf/ed+cba/*

Summary
Various uses if stacks connected to parsing algebraic expressions and evaluating them Unlikely to be something you write as fresh code as many libraries exist for doing expression evaluation and the problem can be approached in other ways But possible Good practice for imagining and tracing actions of code using stacks

Prefix: */abc+de/fg

EECS 268

17

Dr. Douglas Niehaus 2008

EECS 268

18

Dr. Douglas Niehaus 2008

You might also like