00001 // This file is part of jdl_parser. 00002 // 00003 // jdl_parser is free software: you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation, either version 3 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // jdl_parser is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with jdl_parser. If not, see <http://www.gnu.org/licenses/>. 00015 00016 // Copyright Simone Pellegrini 2007-2008; e-mail: motonacciu@gmail.com 00017 00018 #ifndef PARSER_STACK_HPP_ 00019 #define PARSER_STACK_HPP_ 00020 00021 #include "defs.hpp" 00022 00023 namespace jdl{ 00024 00025 template <class T> 00026 class parser_stack{ 00027 vector<T> operand_stack; 00028 vector<int> index_stack; 00029 00030 void check_invariant() const; 00031 public: 00032 parser_stack(){ index_stack.push_back(0); } 00033 00034 void push(T val, bool new_activation = false); 00035 00036 void new_ar(){ index_stack.push_back(0); } 00037 00038 vector<T>& pop(); 00039 00040 size_t size() const { return operand_stack.size(); } 00041 00042 T top() const { return operand_stack.back(); } 00043 00044 void clear(){ 00045 // for(size_t i=0; i<operand_stack.size(); i++) 00046 // delete operand_stack[i]; 00047 operand_stack.clear(); 00048 index_stack.clear(); 00049 } 00050 00051 void print(ostream& out) const; 00052 00053 ~parser_stack(){ 00054 // for(size_t i=0; i<operand_stack.size(); i++) 00055 // delete operand_stack[i]; 00056 } 00057 }; 00058 00059 template <class T> 00060 inline void parser_stack<T>::check_invariant() const { 00061 assert(((size_t)accumulate(index_stack.begin(),index_stack.end(),0)) == operand_stack.size()); 00062 } 00063 00064 template <class T> 00065 inline vector<T>& parser_stack<T>::pop(){ 00066 int size = index_stack.back(); 00067 index_stack.pop_back(); 00068 vector<T>* v = new vector<T>(); 00069 for(int i=0; i<size; i++){ 00070 v->push_back(operand_stack.back()); 00071 operand_stack.pop_back(); 00072 } 00073 check_invariant(); 00074 return *v; 00075 } 00076 00077 template <class T> 00078 inline void parser_stack<T>::push(T val, bool new_activation){ 00079 if(new_activation || index_stack.empty()) 00080 index_stack.push_back(0); 00081 operand_stack.push_back(val); 00082 index_stack.back()++; 00083 check_invariant(); 00084 } 00085 00086 template <class T> 00087 inline void parser_stack<T>::print(ostream& out) const { 00088 out << "Stack size: " << size() << endl; 00089 out << "Activation records: " << endl; 00090 out << "\tStack:" << endl; 00091 //vector<T>::iterator iterator = operand_stack.begin(); 00092 // while(it != operand_stack.end()) 00093 // cout << "\t\t" << *(it++) << endl; 00094 00095 for(size_t i=0; i<operand_stack.size(); i++) 00096 out << "\t\t" << operand_stack[i] << endl; 00097 out << endl << "\n\tIndexes: " << endl; 00098 vector<int>::const_iterator it2 = index_stack.begin(); 00099 while(it2 != index_stack.end()) 00100 out << "\t\t" << *(it2++) << endl; 00101 } 00102 00103 } 00104 #endif /*PARSER_STACK_HPP_*/