1 / 30

CSS342: Stacks and Compilers

CSS342: Stacks and Compilers. Professor: Munehiro Fukuda. 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). Basic Concepts. abcc ddde ef.

marcos
Télécharger la présentation

CSS342: Stacks and Compilers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CSS342: Stacks and Compilers Professor: Munehiro Fukuda CSS342: Stacks and Compilers

  2. 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

  3. Basic Concepts abcc ddde ef Concepts of Stack push pop • Stack of cafeteria dishes • Inherently unfair in day-by-day situations • Useful problem-solving techniques in Computer Science • Using a backspace key to correct typos • Checking for balanced braces push push push push a b c c pop a b c c push push push push a b c d d d e pop pop pop a b c d d d e push push a b c d e f CSS342: Stacks and Compilers

  4. Basic Concepts Stack Specification template<class Object> class stack { public: stack(); bool empty() const; void push( const Object&newItem ); void pop( ); void pop( Object &stackTop ); // not in STL const Object top( ) const; } push to the top pop (): remove from the top a pop(stacktop): remove and get the top item 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

  5. Basic Concepts STL Class stack CSS342: Stacks and Compilers

  6. Basic Concepts STL Class stackExample #include <stack> #include <iostream> using namespace std; int main( ) { stack<int> aStack; int item; for ( int j = 0; j < 5; j++ ) aStack.push( j ); while ( !aStack.empty( ) ) { cout << aStack.top( ) << endl; aStack.pop( ); } } Results: 4 3 2 1 0 CSS342: Stacks and Compilers

  7. Implementation Stack Implementation • Array-based implementation • Pointer-based implementation • Linked list reuse • Data member • Inheritance CSS342: Stacks and Compilers

  8. 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

  9. Implementation k a b c ….. g ….. top 0 1 2 k theArray.Size( ) - 1 An Array-Based Implementation Stack( ) : top( -1), theArray( 1 ) { } push(const Object &newItem) pop(Object &topItem) if (top < 0) throw “empty stack”; else { topItem= theArray[top]; --top; } if (top == theArray.size( ) - 1) theArray.resize( theArray.size( ) * 2 + 1 ); item[++top] = newItem; CSS342: Stacks and Compilers

  10. Implementation topPtr ……… NULL a b c g A Pointer-Based Implementation #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

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

  12. Implementation stackTop stackTop 20 45 51 45 20 76 76 20 45 51 76 51 Copy Constructor • Stack( const Stack<Object>& rhs ) • Implicit calledupon passing, returning, and assigning an object. • Shallow copy: C++ copies an object’s data members. • Deep copy: Java copies all traversable pointer variables. NULL rhs. stackTop NULL Rhs. stackTop NULL CSS342: Stacks and Compilers

  13. 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 flush( ); // why 2 if ( rhs.isEmpty( ) ) return *this; StackNode rptr = rhs.topPtr; StackNode ptr = new StackNode; ptr->item = rptr->item; topPtr = ptr; for ( StackNode rptr = rptr->next; rPtr != NULL; rPtr = rPtr->next ) { ptr->next = new StackNode; ptr->next->element = rptr->element; ptr = ptr->next; } return *this; } } rhs. topPtr 20 45 51 topPtr 20 45 Repeat! CSS342: Stacks and Compilers

  14. 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> #include "llist.h“ template<class Object> class Stack { public: // the same as previous private: LList<Object> list; }; template<class Object> bool Stack<Object>::isEmpty( ) const { return list.isEmpty( ); } template<class Object> void Stack<Object>::push( const Object &newItem ) { list.insert( newItem, 0 ); // insert after 0th dummy } template<class Object> const Object Stack<Object>::top( ) const { return list.retrieve( 1 ); // retrieve 1st list item } CSS342: Stacks and Compilers

  15. 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

  16. 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) • 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. So which is the best? CSS342: Stacks and Compilers

  17. 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 • Check if stack is empty in prior to a pop • Check if stack is empty at the end of string 4.push 3.pop 5.push 6.pop 7.pop 8.pop 1. { 2. {( 3. { 4. {( 5. {([ 6. {( 7. { 1. { 2. 3. empty!! abc{(def) ghijklm 1.push 3.pop 2.push 1. { 2. {( 3. { Stack is not empty!! CSS342: Stacks and Compilers

  18. 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

  19. Example 1 Balanced-Symbol Checker(code continued) bool checkBalance( ) { 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

  20. 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 Example 2 Example 2: Algebraic Expressions CSS342: Stacks and Compilers

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

  22. Converting Infix to Equivalent Postfix Example 2 Infix: a + b Postfix: a b + the same order 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; 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) Infix: a - b + c Postfix: a Stack: (2) Infix: a - b + c Postfix: a Stack: - (3) Infix: a - b + c Postfix: a b Stack: - (4) Infix: a - b + c Postfix: a b - Stack: + CSS342: Stacks and Compilers

  23. 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( ) break; } } While (!aStack.isEmpty( )) { aStack.pop(ch); postfixExp += ch; } (1) Infix: x - (a - b + c) Postfix: x a b - c Stack: - ( + (2) Infix: x - (a - b + c) Postfix: x a b c - + Stack: - “-” is put on the stack, 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

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

  25. Example 2 Converting Infix to Equivalent Postfix A – (B + C * D) / E CSS342: Stacks and Compilers

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

  27. 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) • Lexical analyzer token.h tokenizer.h, and tokenizer.cpp.h Read a line of characters and return tokens. • 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. • Evaluator evaluator.cpp’s binaryOp( ) Interprets an analyzed (or postfix) expression. CSS342: Stacks and Compilers

  28. 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] %% {DIGIT}+ { printf( “int = %d\n”, atoi( yytex ) ); {DIGIT}+”.”{DIGIT}* { printf( “float = %g\n”, atof( yytex ) ); } {ID} { printf( “identifier = %s”, yytext ); if|else|while|for|case { printf( “keyword = %s”, yytext ); } From Unix shell: [fukuda@home] Lex pascal.tex [fukuda@home] ls lex.yy.c pascal.lex [fukuda@home] gcc lex.yy.c i i getc( ) == ‘*’ getc( ) == ‘*’ getc( ) == ‘0’ ~’9’ getc( ) == ‘0’ ~’9’ ‘–’ ‘>’ MULT * – ( val * – ( > val MULT MINUS OPAREN MINUS OPAREN GT VALUE VALUE – >= >> UN_MINUS GE SHIFT_R CSS342: Stacks and Compilers

  29. Calculator Design Syntax Analyzer A – (B + C * D) / E • Text example and lab/home work • Infix to prefix algorithm • In general • Syntactic tree • Postfix:Traversing a tree from left to right, as printing the left, the right, and the parent of each node from bottom to root. • Prefix:Traversing a tree from left to right, as printing the parent, the left, and the right of each node from top to bottom – A / + E B * C D CSS342: Stacks and Compilers

  30. Calculator Design Syntax Analyze expression : primary | unary_expr | binary_expr ; 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 ); } ; • Need • yylex( ) provided by LEX • All grammar definition in parse.y( ) • Then how can you make such a tree? • YACC http://dinosaur.compilertools.net/yacc/index.html CSS342: Stacks and Compilers

More Related