Docstoc

Stack

Document Sample
Stack Powered By Docstoc
					CSS342: Stacks and Compilers

    Professor: Munehiro Fukuda




          CSS342: Stacks and Compilers   1
                    Topics
• Basic concepts of stacks
• Stack implementation
• Applying to language processing
  – Example 1: Balance-symbol checker
  – Example 2: Algebraic expressions
• Calculator design (lab/home work)


                CSS342: Stacks and Compilers   2
                                                                                      Basic Concepts

              Concepts of Stack
                                                       push                                    pop
• Stack of cafeteria dishes
  – Inherently unfair in day-by-day
    situations
• Useful problem-solving
  techniques in Computer                           push push push push

  Science                                          abc c
                                                                                     pop
  – Using a backspace key to                       abc                               c
    correct typos                                                push push push push

                                                   abcddde
  – Checking for balanced braces                                                 pop pop pop
                                                   abcd                              dde
       abcc ddde      ef                                                 push push

                                                   abcde f
                    CSS342: Stacks and Compilers                                           3
                                                                                Basic Concepts

                      Stack Specification

template<class Object>
class stack                            push to the      top
{                                                              pop (): remove from the top
public:                                        a
   stack();
   bool empty( ) const;                                              pop(stacktop): remove
   void push( const Object &newItem );                                and get the top item
   void pop( );
   void pop( Object &stackTop ); // not in STL
   const Object top( ) const;
}                                                              c
                             retrieve the top item
                             but do not remove it              c
                                                               b
                                                               a
     Axiom: (aStack.push(newItem)).pop() is equal to aStack
                                CSS342: Stacks and Compilers                         4
                                                                                           Basic Concepts

                              STL Class stack
#include <stack>
stack();
Creates an empty stack. You can convert a list into a new stack. See your text page 249 (Sec. 7.6.2)
Example: stack<int>, vector<int>> aStack; stack<int> bStack;
bool empty( ) const;
Returns if the stack is empty.
Example: while ( aStack.empty( ) == false ) { … }
size_type size( ) const;
Returns the number of elements. Size_type is an integral type. You can compare it with an integer.
Example: while (aStack.size( ) > 0) { … }
T &top( );
Returns a reference to the top of the stack.
Example: while( !aStack.empty() ) { cout << aStack.top() << endl; aStack.pop(); }
void pop();
Remove the top item from the stack.
Example: See the top( ) example.
void push(const T& value)
Adds an item with value to the top of the stack.
Example: stack<int> aStack; for( int i=0; i < 10; i++ ) aStack.push(i);



                                     CSS342: Stacks and Compilers                                5
           STL Class stack                            Basic Concepts



             Example
#include <stack>
#include <iostream>
using namespace std;

int main( ) {                                  Results:
    stack<int> aStack;                         4
    int item;                                  3
                                               2
    for ( int j = 0; j < 5; j++ )              1
        aStack.push( j );                      0

    while ( !aStack.empty( ) ) {
        cout << aStack.top( ) << endl;
        aStack.pop( );
    }
}


                CSS342: Stacks and Compilers               6
                                                 Implementation




       Stack Implementation

• Array-based implementation
• Pointer-based implementation
• Linked list reuse
  – Data member
  – Inheritance


                  CSS342: Stacks and Compilers        7
                                                                      Implementation

       An Array-Based Implementation
            k       a b c         …..          g       …..
            top     0   1   2                  k             (MAX_STACK-1)


template <class Object>
class stack
{
public:
   stack();
   bool isEmpty( ) const;
   void push( const Object &newItem );
   void pop( );
   void pop( const Object &stackTop );
   const Object top( ) const;
private:
   vector<Object> theArray; //Object theArray[MAX_STACK–1]; in an ordinary array
   int top;
}




                            CSS342: Stacks and Compilers                     8
                                                                                     Implementation

      An Array-Based Implementation
       Stack( ) : top( -1), theArray( 1 ) { }


        k       a b c          …..       g        …..
        top     0   1   2                k                    theArray.Size( ) - 1



pop(Object &topItem)                    push(const Object &newItem)
 if (top < 0)                         if (top == theArray.size( ) - 1)
    throw “empty stack”;                 theArray.resize( theArray.size( ) * 2 + 1 );
 else {                               item[++top] = newItem;
    topItem = theArray[top];
    --top;
 }




                               CSS342: Stacks and Compilers                               9
                                                                    Implementation

 A Pointer-Based Implementation
topPtr
         a          b            c            ……… g               NULL
         #include<iostream>

         template<class Object>
         class Stack
         {
           public:
            Stack( ) : topPtr( NULL ) { };
            Stack( const Stack &rhs );
            ~Stack( ) { flush( ); };
            bool isEmpty( ) const;
            void push( const Object &newItem );
            const Object top( ) const;
            void pop( );
            void pop( Object &stackTop );
            void flush( );
            const Stack &operator=( const Stack &rhs );
           private:
            struct StackNode { Object item; StackNode *next; };
            StackNode *topPtr;
         };
         #include "stackPointer.cpp"


                         CSS342: Stacks and Compilers                    10
                                                                                       Implementation

             A Pointer-Based Implementation
        Stack( ) : topPtr( NULL ) { };
         topPtr
                   a             b         c            ……… g                   NULL
template<class Object>
void Stack<Object>::push( const Object &newItem )      template<class Object>
{                                                      const Object Stack<Object>::top( ) const {
  StackNode *newPtr = new StackNode;                     if ( isEmpty( ) )
  if ( newPtr == NULL )                                    throw "empty stack";
    throw "out of memory";                               return topPtr->item;
  else {                                               }
    newPtr->item = newItem;
    newPtr->next = topPtr;                             template<class Object>
    topPtr = newPtr;                                   void Stack<Object>::pop( ) {
  }                                                      if ( isEmpty( ) )
}                                                          throw "empty stack";
                                                         StackNode *oldTop = topPtr;
template<class Object>                                   topPtr = topPtr->next;
bool Stack<Object>::isEmpty( ) const {                   delete oldTop;
  return topPtr == NULL;                               }
}
                                                       template<class Object>
template<class Object>                                 void Stack<Object>::pop( Object &stackTop ) {
void Stack<Object>::flush( ) {                           stackTop = top( );
  while ( !isEmpty( ) )                                  pop( );
    pop( );                                            }
}
                                     CSS342: Stacks and Compilers                          11
                                                                Implementation

                Copy Constructor
• Stack( const Stack<Object>& rhs )
   – Implicit called upon passing, returning, and assigning an object.
• Shallow copy: C++ copies an object’s data members.
              stackTop   20           45            51   76      NULL


                 rhs.
              stackTop



• Deep copy: Java copies all traversable pointer variables.
              stackTop   20           45            51   76      NULL


                Rhs.                                             NULL
              stackTop   20           45            51   76

                         CSS342: Stacks and Compilers               12
                                                                                    Implementation

                                     Deep Copy
template<class Object>        // copy constructor
Stack<Object>::Stack( const Stack<Object> &rhs ) {
  topPtr = NULL;
  *this = rhs;
}

template<class Object>        // operator = (deep copy)
const Stack<Object> &Stack<Object>::operator=( const Stack<Object> &rhs ) {
  if ( this != &rhs ) {       // why 1           rhs.
    flush( );                 // why 2          topPtr
                                                           20          45             51
    if ( rhs.isEmpty( ) )
      return *this;
    StackNode rptr = rhs.topPtr;
    StackNode ptr = new StackNode;
    ptr->item = rptr->item;
    topPtr = ptr;                               topPtr     20          45

        for ( StackNode rptr = rptr->next; rPtr != NULL; rPtr = rPtr->next ) {
          ptr->next = new StackNode;
          ptr->next->element = rptr->element;                                    Repeat!
          ptr = ptr->next;
        }
        return *this;
    }
}



                                     CSS342: Stacks and Compilers                          13
                                                                     Implementation

         Implementation by List Reuse
     • Why not reuse the Linked List class we studied?
     • Contain a linked list instance in our stack implementation
     stack.h                                    stack.cpp
#include <iostream>         template<class Object>
#include "llist.h“          bool Stack<Object>::isEmpty( ) const {
                              return list.isEmpty( );
template<class Object>      }
class Stack {
 public:                    template<class Object>
  // the same as previous   void Stack<Object>::push( const Object &newItem ) {
 private:                     list.insert( newItem, 0 ); // insert after 0th dummy
  LList<Object> list;       }
};
                            template<class Object>
                            const Object Stack<Object>::top( ) const {
                              return list.retrieve( 1 ); // retrieve 1st list item
                            }




                            CSS342: Stacks and Compilers                 14
                                                                Implementation

 Implementation by List Reuse
                    (code continued)
template<class Object>
void Stack<Object>::pop( ) {
  if ( list.size( ) > 0 )
    list.remove( list.retrieve( 1 ) ); // remove the 1st item
}

template<class Object>
void Stack<Object>::pop( Object &stackTop ) {
  if ( list.size( ) > 0 )
    list.remove( ( stackTop = list.retrieve( 1 ) ) );
}

template<class Object>
void Stack<Object>::flush( ) {
  return list.clear( );
}

template<class Object>
const Stack<Object>& Stack<Object>::operator=( const Stack &rhs ) {
  list = rhs.list; // just reuse list’s operator=!
}
                     CSS342: Stacks and Compilers                   15
                                                                 Implementation

     Comparing Implementations
• The Array-Based Stack
   – Pros. Easy implementation
   – Cons.
       – Fixed size (if we use a fixed array)
       – Capacity or stack duplication overhead (if we use a dynamic
         array like vector)
   – Good for small objects
• The Pointer-Based Stack.
   – Pros. Dynamic size (not wasting space)           So which is the best?
   – Cons.Necessity to take care of pointers
   – Good for large objects
• Reuse of Linked List.
   – Pros.
       – Easy Implementation
       – All advantages inherent to pointer-based stack.
   – Cons. May be a bit slower.
                        CSS342: Stacks and Compilers                 16
                                                                                      Example 1

 Example 1: Balanced-Symbol Checker
   abc{defg(ijk)(l[mn])op}qr                                 abc{def})(ghij[kl]m)
      1.push    2.push 3.pop                                        1.push 2.pop
                          4.push                                             3.pop
                             5.push
                                   6.pop
                                     7.pop 8.pop
               1. {                                           1. {
               2. {(                                          2.
               3. {                                           3. empty!!
               4. {(
               5. {([
               6. {(                                          abc{(def) ghijklm
                                                                     1.push 3.pop
               7. {                                                     2.push

                                                               1. {
• Check if stack is empty in prior to a pop                    2. {(
• Check if stack is empty at the end of string                 3. {
                                                               Stack is not empty!!
                                     CSS342: Stacks and Compilers                     17
                                                                                  Example 1

       Balanced-Symbol Checker
Simplified code of textbook p411 - 419
It does not care about comments nor prints out detailed error messages.
  char getNextSymbol( ) {        // gets the next ( ) [ ] { and }
    char ch;
    do {
      if ( !cin.get( ch ) )
         return '\0'; // EOF
    } while ( ch != '(' && ch != ')' && ch != '[' &&
                 ch != ']' && ch != '{' && ch != '}' );
    return ch;
  }

  bool checkMatch( const char &openSym, const char &closeSym ) {
  // check if openSym nad closeSym matches each other

      if ( openSym == '(' && closeSym != ')' ||
           openSym == '[' && closeSym != ']' ||
           openSym == '{' && closeSym != '}' ) {
        cout << "Found " << closeSym << "; does not match " << openSym << endl;
        return false;
      }
      return true;
  }



                            CSS342: Stacks and Compilers                          18
          Balanced-Symbol Checker                                                    Example 1



bool checkBalance( ) {
                           (code continued)
  char ch, match;
  int errors = 0;
  stack<char> pendingTokens;                       // a stack
  while( ( ch = getNextSymbol( ) ) != '\0' ) {     // keep reading a new symbol till EOF
    switch( ch ) {
    case '(': case '[': case '{':                  // push an open symbol into the stack
      pendingTokens.push( ch );
      break;
    case ')': case ']': case '}':                  // has encountered a close symbol
      if ( pendingTokens.empty( ) ) {              // check if the stack is empty
          cout << "Extraneous " << ch << endl;
          return false;
      } else {
          match = pendingTokens.top( );            //   get the top (i.e., the last symbol)
          pendingTokens.pop( );                    //   on the stack
          if ( ! checkMatch( match, ch ) )         //   check this pair of open and close
            return false;                          //   symbol
      }
    }
  }
  while ( !pendingTokens.empty( ) ) {              // if the stack still has symbols
    match = pendingTokens.top( );                  // flush out all.
    pendingTokens.pop( );
    cout << "Unmatched " << match << endl;
    errors++;
  }
  return ( errors > 0 ) ? false : true;
}
                              CSS342: Stacks and Compilers                           19
                                                                         Example 2

  Example 2: Algebraic Expressions
• Infix expressions:
   – Every binary operator appears between its operands.
   – a+b
   – a + b * c, if you want to compute a + b first, then (a + b) * c
• Prefix expressions:
   – Every binary operator appears before its operands. No parentheses needed
   – a+b                => + a b
   – (a + b) * c        => * + a b c
• Postfix expressions
   – Every binary operator appears after its operands. No parentheses need
   – a+b                => a b +
   – (a + b) * c        => a b + c *       Easy to evaluate using a stack

                             CSS342: Stacks and Compilers                20
                                                                                        Example 2

  How to Evaluate a Postfix Expression
             Assumptions:         syntactically correct, no unary operations, and
                                  single digit operands
                                                                       234+*
for ( (c = cin.get( )) != ‘\n’) {
           if ( c >= ‘0’ && c <= ‘9’ )                               Operations    Stack
                       aStack.push(atoi(c));                         push 2:       2
           else {                                                    push 3:       23
                       aStack.pop(op2);                              push 4:       234
                       aStack.pop(op1);                              pop           23
                       switch (c) {                                  pop           2
                       case ‘+’: aStack.push(op1 + op2); break;      Sum of 3&4
                       case ‘-’; aStack.push(op1 – op2); break;
                                                                     push 7        27
                       ….;
                                                                     Pop
                       default: cerr << “panic!”; break;
                       }                                             Pop
           }                                                         Mult of 2&7
}                                                                    Push          14

                                      CSS342: Stacks and Compilers                      21
                                                                                               Example 2

Converting Infix to Equivalent Postfix
Abstract code:
for ( (c = cin.get( )) != ‘\n’) {
             siwtch(c) {
             case operand: postfixExp += c;   // Order of operands in both infix and postfix is the same
                             break;
                                                        Infix: a + b Postfix: a b +
                                                        the same order

           case ‘(‘:      aStack.push(‘(‘); // Simply push ‘(‘ for matching ‘)’ later
                          break;
           case operator: while(!aStack.isEmpty() && ch of aStack.getTop(ch) !=‘(‘
                                  && precedence(c) <= precedence(ch)) {
                                  posfixExp += ch;
                                  aStack.pop( );
                           }
                           aStack.push(c);

 (1)                       (2)                       (3)                     (4)
 Infix: a - b + c          Infix: a - b + c          Infix: a - b + c        Infix: a - b + c
 Postfix: a                Postfix: a                Postfix: a b            Postfix: a b -
 Stack:                    Stack: -                  Stack: -                Stack: +
                                       CSS342: Stacks and Compilers                            22
                                                                                                                    Example 2

Converting Infix to Equivalent Postfix
Abstract code (Continued):
for ( (c = cin.get( )) != ‘\n’) {
             switch(c) {
             ……               // See the previous slide

            case ‘)’:        while (ch of aStack.getTop(ch) != ‘(‘) {
                                    postfixExp += ch;
                                    aStack.pop( );
                             }
                            aStack.pop( )
                                             (1)                                        (2)
                             break;          Infix: x - (a - b +               c)       Infix: x - (a - b + c)
}          }                                  Postfix: x a b - c                        Postfix: x a b c - +
While (!aStack.isEmpty( )) {                  Stack: - ( +                              Stack: -
           aStack.pop(ch);                                “-” is put on the stack,
           postfixExp += ch;                              It is added to Postfix upon encountering “+”,
                                                          “+”is put on the stack.
}                                                         Upon a “)”, all operators before “(“ are put on Postfix
                                               (3)
                                               Infix: x - (a - b + c)
                                               Postfix: x a b c - + -
                                               Stack:
                                         CSS342: Stacks and Compilers                                               23
                                                                                               Example 2

 Converting Infix to Equivalent Postfix
int precedence( char op ) {                                         case ')':
  switch( op ) {                                                         while ( !opStack.empty( ) ) {
  case '+': return 0;                                                        stackTop = opStack.top( );
  case '-': return 0;                                                        if ( stackTop != '(' ) {
  case '*': return 1;                                                          postfixExp += stackTop;
  case '/': return 1;                                                          opStack.pop( );
  default: return 1;                                                           continue;
  }                                                                          }
}                                                                            break;
                                                                         }
string convert( const string& infix ) {                                  opStack.pop( );
  stack<char> opStack;                                                   break;
  char stackTop;                                                     default: // operand
  string postfixExp;                                                     postfixExp += c;
                                                                         break;
 for ( int i = 0; i < infix.size( ); i++ ) {                           }
   char c = infix[i];                                                }
   switch( c ) {
   case '(':                                                           while ( !opStack.empty( ) ) {
     opStack.push( c );                                                  stackTop = opStack.top( );
     break;                                                              opStack.pop( );
   case '+':                                                             postfixExp += stackTop;
   case '-':                                                           }
   case '*':
   case '/':                                                           return postfixExp;
     if ( !opStack.empty( ) ) {                                    }
         stackTop = opStack.top( );
         if ( stackTop != '(' &&
              precedence( c ) <= precedence( stackTop ) )
         {
           postfixExp += stackTop;
           opStack.pop( );
         }
     }
     opStack.push( c );
     break;
                                    CSS342: Stacks and Compilers                               24
                                                                                     Example 2

Converting Infix to Equivalent Postfix
      A – (B + C * D) / E
 Ch                  Stack                postFixExp         Remark
 A                                        A                  Postfix += A
 -                   -                    A                  Push -
 (                   -(                   A                  Push (
 B                   -(                   AB                 Postfix += B
 +                   -(+                  AB                 Push +
 C                   -(+                  AB C               Postfix += C
 *                   -(+*                 AB C               Push *     where pr(*) > pr(-)
 D                   -(+*                 AB C D             Postfix += D
 )                   -(+                  AB C D *           Pop *, Postfix += *
                     -(                   AB C D * +         Pop +, Postfix += +
                     -                    AB C D * +         Pop (
 /                   -/                   AB C D * +         Push /     where pr(/) > pr(-)
 E                   -/                   AB C D * + E       Postfix += E
                                          AB C D * + E / -   PostFix += /-
                             CSS342: Stacks and Compilers                            25
                                                                                          Example 2

A*B+C-D/(E+F)
                             Exercise
Ch              Stack             postFixExp              Remark
A                                 A                       Postfix += A
*               *                 A                       Push *
B                                 AB                      Postfix += B
                                  A B*                    Pop *, Postfix += *
+               +                 A B*                    Push +
C               +                 AB * C                  Postfix += C
                                  AB * C +                Pop +, Postfix += +
-               -                                         Push -
D               -                 AB * C + D              Postfix += D
/
           First try to solve it without D
               -/                AB * C +
                                                     the
                                          looking at Push /answer.where pr(/) > pr(-)
(               -/(               AB * C + D              Push (
E               -/(               AB * C + D E            Postfix += E
+               -/(+              AB * C + D E            Push +            where top( ) = (
F               -/(+              AB * C + D E F          Postfix += F
)               -/(               A B * C + D E F+        Pop +, Postfix += +
)               -/                A B * C + D E F+        Pop (
                -                 A B * C + D E F+/       Pop /, Postfix += /
                                  A B * C + D E F+/-      Pop -, Postfix += -
                           CSS342: Stacks and Compilers                                   26
                                                                    Calculator Design

                   Calculator Design
•       The code is located at:
    –      http://courses.washington.edu/css342/fukuda/code/stack/evaluator/
•       Three main components (in a typical language processor
        format)
    1.     Lexical analyzer
          token.h tokenizer.h, and tokenizer.cpp.h
          Read a line of characters and return tokens.
    2.     Syntax analyzer
          evaluator.h’s PREC_TABLE[] and evaluator.cpp.h’s processToken( )
          In general, analyze a structure of an arithmetic expression.
          Convert an infix expression to postfix as checking the syntax.
    3.     Evaluator
          evaluator.cpp’s binaryOp( )
          Interprets an analyzed (or postfix) expression.




                              CSS342: Stacks and Compilers                   27
                                                                                                               Calculator Design
                                 Lexical Analyzer
                                                                                        http://dinosaur.compilertools.net/lex/index.html
        1. Text Example                         2. Lab/Home Work                                            3. LEX
                                                                                          DIGIT          [0-9]
                                                                                          ID             [a-z][a-z0-9]

                 i                                           i                            %%

                                                                                          {DIGIT}+ {
getc( ) == ‘*’                          getc( ) == ‘*’
                                                                                              printf( “int = %d\n”,
                                                                          getc( )                     atoi( yytex ) );
                          getc( )
                          == ‘0’ ~’9’                ‘–’                  == ‘0’ ~’9’
                                                                 ‘>’                      {DIGIT}+”.”{DIGIT}* {
                                         MULT                                                 printf( “float = %g\n”,
                                                                                                      atof( yytex ) );
    *       –        (     val           *       –       (        >       val             }
   MULT    MINUS OPAREN                      MINUS OPAREN          GT     VALUE
                            VALUE                                                         {ID} {
                                                                                              printf( “identifier = %s”,
                                                                                                      yytext );

                                                                                          if|else|while|for|case {
                                                                                              printf( “keyword = %s”,
                                                                                                      yytext );
                                                     –       >=         >>                }
                                                UN_MINUS GE             SHIFT_R
                                                                                          From Unix shell:
                                                                                          [fukuda@home] Lex pascal.tex
                                                                                          [fukuda@home] ls
                                                                                          lex.yy.c pascal.lex
                                                                                          [fukuda@home] gcc lex.yy.c
                                              CSS342: Stacks and Compilers                                               28
                                                                    Calculator Design

                 Syntax Analyzer
• Text example and lab/home
  work                                                  A – (B + C * D) / E
   – Infix to prefix algorithm
• In general
   – Syntactic tree
                                                              –

   – Postfix: Traversing a tree from left to
     right, as printing the left, the right, and         A          /
     the parent of each node from bottom to
     root.                                                     +          E

   – Prefix: Traversing a tree from left to               B         *
     right, as printing the parent, the left,
     and the right of each node from top to
     bottom                                                    C          D

                         CSS342: Stacks and Compilers                      29
                                                                   Calculator Design
                     Syntax Analyze
• Then how can you make such a tree?
• YACC http://dinosaur.compilertools.net/yacc/index.html
  expression                          Need
           :   primary
           |   unary_expr             1. yylex( ) provided by LEX
           |   binary_expr            2. All grammar definition in parse.y( )
           ;
  primary
           :   ID
                     { $$=(int)maketree( ID, id, NULL ); }
          : VALUE
                     { $$=(int)maketree( VALUE, value, NULL ); }
           ;
  unary_expr
           : MINUS expression
                    { $$=(int)maketree( UN_MINUS, (TREE)$2, NULL ); }
           ;
  Binary_expr
           : expression STAR expression
                    { $$=(int)maketree( MULT, (TREE)$1, (TREE)$3 ); }
           | expression SLASH expression
                    { $$=(int)maketree( DIV, (TREE)$1, (TREE)$3 ); }
           ;
                          CSS342: Stacks and Compilers                30

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:2
posted:11/19/2012
language:English
pages:30