NestedWord.hpp

Go to the documentation of this file.
00001 #ifndef wali_nwa_NESTED_WORD_HPP
00002 #define wali_nwa_NESTED_WORD_HPP
00003 
00004 #include "wali/Countable.hpp"
00005 #include "opennwa/NwaFwd.hpp"
00006 #include <vector>
00007 #include <algorithm>
00008 
00009 namespace opennwa
00010 {
00011     /// This class represents a single nested word.
00012     ///
00013     /// The word can be unbalanced left or unbalanced right, even
00014     /// though our NWAs do not have support for unbalanced-right
00015     /// words.
00016     ///
00017     /// The representation used by this class is closer to that of a
00018     /// word in a visibly-pushdown language. It holds the linear
00019     /// contents of a word, but does not store the nesting relation
00020     /// explicitly. Instead, each position in the word is annotated
00021     /// with whether it is an internal, call, or return position. The
00022     /// nesting relation is induced by the matchings between calls and
00023     /// returns.
00024     class NestedWord : public wali::Countable
00025     {
00026     public:
00027       /// Each position in the nested word has a symbol and a type.
00028       ///
00029       struct Position
00030       {
00031         /// The type of a position: either a call position, internal
00032         /// position, or return position.
00033         enum Type {
00034           CallType, InternalType, ReturnType
00035         };
00036         
00037         /// The symbol at this position
00038         ///
00039         Symbol symbol;
00040 
00041         /// The type (call/internal/return) of this position
00042         ///
00043         Type type;
00044         
00045         /// Constructs a Position object with the given symbol and
00046         /// type
00047         Position(Symbol sym, Type ty) : symbol(sym), type(ty) {}
00048 
00049         /// Returns whether two positions are equal
00050         ///
00051         bool operator==(Position const & p) const
00052         {
00053           return symbol == p.symbol && type == p.type;
00054         }
00055       };
00056       
00057     private:
00058       std::vector<Position> word;
00059       
00060     public:
00061       /// An iterator to allow traversal through the word. (Don't
00062       /// depend on this concrete type specifically, but I guarantee
00063       /// it will be a random access iterator.)
00064       typedef std::vector<Position>::const_iterator const_iterator;
00065       
00066       /// Appends the position 'p' (symbol & type) to the end of this
00067       /// nested word
00068       void append(Position p)
00069       {
00070         word.push_back(p);
00071       }
00072 
00073 
00074       /// Appends the given symbol to the end of this nested word in a
00075       /// call position.
00076       void appendCall(Symbol sym)     { append(Position(sym, Position::CallType)); }
00077       /// Appends the given symbol to the end of this nested word in an
00078       /// internal position.
00079       void appendInternal(Symbol sym) { append(Position(sym, Position::InternalType)); }
00080       /// Appends the given symbol to the end of this nested word in a
00081       /// return position.
00082       void appendReturn(Symbol sym)   { append(Position(sym, Position::ReturnType)); }
00083 
00084 
00085       /// Returns an iterator to the first position in this nested
00086       /// word.
00087       const_iterator begin() const
00088       {
00089         return word.begin();
00090       }
00091       
00092       /// Returns an iterator to one position past the end of this
00093       /// nested word.
00094       const_iterator end() const
00095       {
00096         return word.end();
00097       }
00098 
00099       ///
00100       /// Returns the number of positions in this nested word
00101       size_t size() const
00102       {
00103         return word.size();
00104       }
00105 
00106       ///
00107       /// Returns whether the two nested words are equal
00108       bool operator==(NestedWord const & other) const
00109       {
00110         if (word.size() != other.word.size()) {
00111           return false;
00112         }
00113         else {
00114           return std::equal(word.begin(), word.end(), other.word.begin());
00115         }
00116       }
00117 
00118       ///
00119       /// Returns whether two nested words are unequal
00120       bool operator!=(NestedWord const & other) const
00121       {
00122         return !(*this == other);
00123       }
00124       
00125     };
00126 
00127 
00128     typedef ref_ptr<NestedWord> NestedWordRefPtr;
00129 }
00130 
00131 
00132 // Yo, Emacs!
00133 // Local Variables:
00134 //   c-file-style: "ellemtel"
00135 //   c-basic-offset: 2
00136 // End:
00137 
00138 #endif