Title: Infix Expression Evaluation
1 Infix Expression Evaluation
Postfix expressions are easy to evaluate
But this is not the case for infix expressions!
e.g. 9 (2 3) 8
Two approaches to evaluate an infix expression
2 Infix Expression Attributes
Left associative , -, /,
Right associative
276 (3 2 4) 5
2(76) ((3 (2 4)) 5)
Decreasing order of precedence
() gt gt / gt
3 Rank of Expression
Binary operators only.
Evaluates an infix expression based on rank.
- for any operand
- -1 for , -, , /, ,
- 0 for (, )
Cumulative rank sum of the ranks of individual
terms.
2 7 6 ( 3 2 4 ) 5
cumulative rank
1 0 1 0 1 0 0 1 0 1 0 1 1 0 1
Cumulative rank for the entire expression is
always 1.
(exactly one more operand than operator)
Invalid expression if c.r. ? 1 (e.g. 2 4 3)
4 Infix-to-Postfix Conversion
During the scan of an expression
Operator stack
5 Example 1
The stack temporally stores operators awaiting
their right-hand-side operand.
a b c
has higher priority than ? add to the
stack
Operator Stack
Postfix string
a
c
b
6 Example 2
Use the stack to handle operators with same or
lower precedence.
a b / c d
has the same priority as / ? pop and
write it to the postfix string before
adding / to the stack.
/ has higher priority than
Operator Stack
/
Postfix string
a
b
/
c
d
7 Example 3
Use precedence values to handle (right
associative).
input precedence 4 when is the input. stack
precedence 3 when resides on the stack.
a b c
2nd has precedence 4 but 1st has only 3
? 2nd goes to operator stack (so it
will be popped before 1st )
Operator Stack
Postfix string
a
c
b
8 Example 4
Two precedence values for left parenthese (
input precedence 5 which is higher than that of
any operator. (all operators on the stack must
remain because a new subexpression begins.) stack
precedence -1 which is lower than that of any
opeartor. (no operator in the subexpression may
remove ( until ) shows up.)
a ( b c )
( has precedence 5 ? it goes to the
operator stack.
( now has precedence -1 ? it stays on the
operator stack.
Operator Stack
(
Postfix string
a
c
b
9 Input and Stack Precedence
Input Precedence
Stack Precedence
Rank
Symbol
- 1 1
-1 / 2
2 -1
4 3
-1 ( 5
-1 0 )
0 0
0
10 Rules for Evaluation
11 An Example
3 (4 2 5) 6
Operator stack
2
3
3
3
3 4
postfix
3 4
3 4 2
3 4 2
3 4 2 5
3 4 2 5 -
12 contd
Pop (
3 (4 2 5) 6
2
1
1
3 4 2 5 -
3 4 2 5 -
3 4 2 5 - 6
3 4 2 5 - 6
13Class for the Symbols
Encapsulate each symbol along with the associated
input and output
precedence.
class expressionSymbol public expressionSymb
ol() // default constructor expressionSymbol(
char ch) // initializes the object for operator
ch friend bool operatorgt (const
expressionSymbol left,
const expressionSymbol right) // return true
if stackPrecedence of left is // gt
inputPrecedence of right. determines
whether // operator left on the stack should
be output before // pushing operator right on
the stack char getOp() const // return
operator private char op //
operator int inputPrecedence // input
precedence of op int stackPrecedence // stack
precedence of op
14 Class for Conversion
The infix2Postfix class uses a stack to store
expressionSymbol objects that correspond to
operators.
const char lParen '(', rParen ')' class
infix2Postfix public infix2Postfix() //
default constructor. infix expression is NULL
string infix2Postfix(const string
infixExp) // initialize the infix
expression void setInfixExp(const string
infixExp) // change the infix
expression string postfix() // return a
string that contains the equivalent postfix //
expression. the function throws expressionError
if an // error occurs during conversion
15 infix2Postfix contd
private string infixExpression // the
infix expression to convert string
postfixExpression // built to contain the
postfix equivalent of infixExpression stackltexpr
essionSymbolgt operatorStack // stack of
expressionSymbol objects void
outputHigherOrEqual(const expressionSymbol
op) // the expressionSymbol object op holds
the current // symbol. pop the stack and
output as long as the symbol // on the top of
the stack has a precedence gt that of // the
current operator bool isOperator(char ch)
const // is ch one of '','-','','/','',''
16 Output Stack Symbols
Pop symbols on the stack with stack precedence ?
input precendence of the new symbol.
void infix2PostfixoutputHigherOrEqual(const
expressionSymbol op) expressionSymbol
op2 while(!operatorStack.empty() (op2
operatorStack.top()) gt op) operatorStack.pop
() postfixExpression op2.getOp() postfixE
xpression ' '
17 Function for Infix-to-Postfix Conversion
postfix() does the following
Declarations
expressionSymbol op // maintain rank for error
checking int rank 0, i char ch
18 Processing an Operand
// process until end of the expression for
(i0 i lt infixExpression.length() i) ch
infixExpressioni // process an
operand // an operand is a single
digit non-negative integer if
(isdigit(ch)) // just add operand to
output expression, followed by // a
blank postfixExpression ch postfixExpres
sion ' ' // rank of an operand is 1,
accumulated rank // must be 1 rank if
(rank gt 1) throw expressionError("infix2P
ostfix Operator expected")
19 Processing an Operator
// process an operator or '('
else if (isOperator(ch) ch
'(') // rank of an operator is -1. rank of
'(' is 0. // accumulated rank should be
0 if (ch ! '(') rank-- if (rank lt
0) throw expressionError("infix2Postfix
Operand expected") else else //
output the operators on the stack with
higher // or equal precedence. push the
current operator // on the stack op
expressionSymbol(ch) outputHigherOrEqual(op)
operatorStack.push(op)
20 Processing a Right Parenthesis
else if (ch rParen) // build an
expressionSymbol object holding ')', which //
has precedence lower than the stack
precedence // of any operator except '('. pop
the operator stack // and output operators
from the subexpression until // '(' surfaces
or the stack is empty. if the stack is //
empty, a '(' is missing otherwise, pop off
'('. op expressionSymbol(ch) outputHigher
OrEqual(op) if (operatorStack.empty()) thr
ow expressionError("infix2Postfix Missing
'('") else operatorStack.pop() // get
rid of '(' // make sure ch is
whitespace else if
(!isspace(ch)) throw expressionError("infix2Pos
tfix Invalid input")
21 Finish Processing
// outside the for loop if (rank ! 1) throw
expressionError("infix2Postfix Operand
expected") else // flush operator stack
and complete expression evaluation. // if find
left parenthesis, a right parenthesis is
missing while (!operatorStack.empty()) op
operatorStack.top() operatorStack.pop()
if (op.getOp() lParen) throw
expressionError("infix2Postfix Missing
')'") else postfixExpression
op.getOp() postfixExpression '
' return postfixExpression
22 Evaluating an Infix Expression
void main() // use iexp for infix to postfix
conversion infix2Postfix iexp // infix
expression input and postfix expression
output string infixExp, postfixExp // use pexp
to evaluate postfix expressions postfixEval
pexp // input and evaluate infix expressions
until the // user enters an empty string //
get the first expression cout ltlt "Enter an infix
expression " getline(cin, infixExp) while
(infixExp ! "") // an exception may occur.
enclose the conversion // to postfix and the
output of the expression // value in a try
block
23 try // convert to postfix iexp.setInfi
xExp(infixExp) postfixExp
iexp.postfix() // output the postfix
expression cout ltlt "The postfix form is " ltlt
postfixExp ltlt endl // use pexp to evaluate
the postfix expression pexp.setPostfixExp(postf
ixExp) cout ltlt "Value of the expression
" ltlt pexp.evaluate() ltlt endl ltlt
endl // catch an exception and output the
error catch (const expressionError
ee) cout ltlt ee.what() ltlt endl ltlt
endl // input another expression cout ltlt
"Enter an infix expression " getline(cin,
infixExp)