From: Baptiste L. <bl...@us...> - 2004-08-07 15:52:33
|
Update of /cvsroot/cpptool/CppParser/include/rfta/cppparser In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9448/include/rfta/cppparser Added Files: autolink.h config.h conststring.h cppparser.h cppparserfacade.h cppparsersettings.h forwards.h node.h nodeprocessor.h token.h Log Message: * made a library out of the c++ parser (cppparser) * exposed the c++ parser to python (pycppparser) * migrating refactoring framework to python (pyrfta) --- NEW FILE: config.h --- #ifndef RFTA_CPPPARSER_CONFIG_H_INCLUDED # define RFTA_CPPPARSER_CONFIG_H_INCLUDED # include <boost/config.hpp> //# define CPPUT_THREAD_SAFE //# define CPPUT_USE_WIN32_THREAD //# define CPPUT_USE_PTHREAD_THREAD // untested //# define CPPUT_USE_BOOST_ATOMIC_COUNTER //# define CPPUT_USE_BOOST_SHARED_PTR # define CPPUT_BOOST_FRIENDLY //# define CPPUT_DLL_SUPPORT //# define CPPUT_USE_WIN32_DLL // LoadLibrary //# define CPPUT_USE_DL_DLL // dlopen //# define CPPUT_USE_SHL_DLL // shl_open //# define CPPUT_USE_BEOS_DLL // compiler specific stuffs... /////////////////////////////////////////////////////////////////////////// # if _MSC_VER <= 1200 // VC++ 6 or before # pragma warning( disable : 4786 ) // ident trunc to '255' chars in debug info # define CPPUT_STD_VECTOR_ITERATOR_IS_POINTER 1 # define CPPUT_HAS_FUNCTION_TEMPLATE_ORDERING 0 # define CPPUT_HAS_TEMPLATE_PARTIAL_SPECIALIZATION 0 # endif # if _MSC_VER <= 1300 // VC++ 7.0 or before // VC++ 7.0 does have deduced typename, but their behavior is not consistent with // VC++ 7.1. Since it is not required to compile, we just pretend it's not available. # define CPPUT_NO_DEDUCED_TYPENAME # endif # if _MSC_VER >= 1310 // VC++ 7.1 # define CPPUT_HAS_FUNCTION_TEMPLATE_ORDERING 1 # define CPPUT_HAS_TEMPLATE_PARTIAL_SPECIALIZATION 1 # pragma warning( disable : 4800 ) // forcing value to bool performance warning # pragma warning( disable : 4018 ) // '<' signed/unsigned mismatch # endif // define CPPUT_DLL_BUILD when building rfta parser dll. # ifdef RFTA_CPPPARSER_DLL_BUILD # define RFTA_CPPARSER_API __declspec(dllexport) # else # define RFTA_CPPARSER_API __declspec(dllimport) # endif // Auto-link feature, define symbol CPPUT_NO_AUTO_LINK to disable # ifndef RFTA_CPPPARSER_DLL_BUILD # define CPPUT_LIB_NAME "rfta_cppparser" # include <rfta/cppparser/autolink.h> # undef CPPUT_LIB_NAME # endif #endif // RFTA_CPPPARSER_CONFIG_H_INCLUDED --- NEW FILE: cppparser.h --- #ifndef PARSER_CPPARSER_H_INCLUDED # define PARSER_CPPARSER_H_INCLUDED # include <rfta/cppparser/node.h> # include <string> namespace Parser { class GrammarBuilder; namespace CppParser { extern TokenType RFTA_CPPARSER_API tkSpaces; extern TokenType RFTA_CPPARSER_API tkIdentifier; extern TokenType RFTA_CPPARSER_API tkString; extern TokenType RFTA_CPPARSER_API tkCharacter; extern TokenType RFTA_CPPARSER_API tkInteger; extern TokenType RFTA_CPPARSER_API tkFloat; extern TokenType RFTA_CPPARSER_API tkCppComment; extern TokenType RFTA_CPPARSER_API tkCComment; extern TokenType RFTA_CPPARSER_API tkPreprocessorDirective; extern TokenType RFTA_CPPARSER_API tkError; extern TokenType RFTA_CPPARSER_API tkSymbol; void RFTA_CPPARSER_API tokenize( const std::string &input, Tokens &tokens ); void RFTA_CPPARSER_API preprocess( const std::string &input, Tokens &tokens ); void RFTA_CPPARSER_API setUpGrammarBuilder( GrammarBuilder &builder ); } // namespace CppParser } // namespace Parser #endif // PARSER_CPPARSER_H_INCLUDED --- NEW FILE: cppparsersettings.h --- #ifndef PARSER_CPPPARSERSETTINGS_H_INCLUDED # define PARSER_CPPPARSERSETTINGS_H_INCLUDED # include <rfta/cppparser/config.h> # include <string> namespace Parser { class RFTA_CPPARSER_API CppParserSettings { public: virtual ~CppParserSettings() { } virtual std::string grammarPath() const =0; }; } // namespace Parser #endif // PARSER_CPPPARSERSETTINGS_H_INCLUDED --- NEW FILE: nodeprocessor.h --- #ifndef TEST_NODEPROCESSOR_H_INCLUDED # define TEST_NODEPROCESSOR_H_INCLUDED # include <rfta/cppparser/config.h> # include <cpput/enumerator.h> # include <boost/shared_ptr.hpp> # include <map> # include <set> # include <string> enum NodeSpecificationTypes { nsNone = 0, nsHasBraceValue = 1, nsHasBraceValues = nsHasBraceValue << 1, nsHasBraceNodeValue = nsHasBraceValues << 1, nsHasColonValue = nsHasBraceNodeValue << 1, nsHasColonNodeValue = nsHasColonValue << 1, nsHasColonEnumerationValue = nsHasColonNodeValue << 1, nsHasColonStringListValue = nsHasColonEnumerationValue << 1, nsHasChildren = nsHasColonStringListValue << 1 }; // class NodeSpecification // /////////////////////////////////////////////////////////////// class RFTA_CPPARSER_API NodeSpecification { public: typedef unsigned int Features; NodeSpecification(); NodeSpecification( const std::string &specificationName, const std::string &inputName, Features features ); const std::string &specificationName() const; const std::string &inputName() const; bool hasBraceValue() const; bool hasBraceValues() const; bool hasBraceNodeValue() const; bool hasColonValue() const; bool hasColonNodeValue() const; bool hasColonEnumerationValue() const; bool hasColonStringListValue() const; bool hasChildren() const; void addEnumerationValue( const std::string &value ); void addChild( const std::string &specificationName ); void addMandatoryChild( const std::string &specificationName ); void getAllEnumerationValue( std::set<std::string> &enumeration ) const; void getAllPossibleChildren( std::set<std::string> &children ) const; bool isAcceptableChild( const std::string &specificationName ) const; private: typedef std::set<std::string> Children; Children children_; Children mandatoryChildren_; std::set<std::string> enumerationValues_; std::string specificationName_; std::string inputName_; Features features_; }; typedef boost::shared_ptr<NodeSpecification> NodeSpecificationPtr; // class Node // /////////////////////////////////////////////////////////////// class Node; typedef boost::shared_ptr<Node> NodePtr; class RFTA_CPPARSER_API Node { public: typedef CppUT::Enumerator<NodePtr> NodeEnumerator; typedef CppUT::Enumerator<std::string> ValueEnumerator; virtual ~Node(); virtual unsigned int line() const = 0; virtual unsigned int column() const = 0; virtual const std::string &inputName() const = 0; virtual const std::string &specificationName() const = 0; virtual std::string braceValue() const = 0; virtual CppUT::Enumerator<std::string> braceValues() const = 0; virtual NodePtr braceNodeValue() const = 0; virtual CppUT::Enumerator<NodePtr> braceNodeValues() const = 0; virtual std::string colonValue() const = 0; virtual CppUT::Enumerator<std::string> colonValues() const =0; virtual NodePtr colonNodeValue() const =0; virtual CppUT::Enumerator<NodePtr> colonNodeValues() const =0; virtual bool hasChild( const std::string &inputName ) const =0; virtual NodePtr child( const std::string &inputName ) const =0; virtual CppUT::Enumerator<NodePtr> children() const = 0; }; // class Node // /////////////////////////////////////////////////////////////// class NodeImpl : public Node { public: NodeImpl( const NodeSpecificationPtr &specification, unsigned int line, unsigned int column ); const NodeSpecification &specification() const; void addBraceValue( const std::string &value ); void addBraceValue( const NodePtr &node ); void addColonValue( const std::string &value ); void addColonValue( const NodePtr &node ); void addChild( const NodePtr &node ); public: // overridden from Node unsigned int line() const; unsigned int column() const; const std::string &inputName() const; const std::string &specificationName() const; std::string braceValue() const; CppUT::Enumerator<std::string> braceValues() const; NodePtr braceNodeValue() const; CppUT::Enumerator<NodePtr> braceNodeValues() const; std::string colonValue() const; CppUT::Enumerator<std::string> colonValues() const; NodePtr colonNodeValue() const; CppUT::Enumerator<NodePtr> colonNodeValues() const; bool hasChild( const std::string &inputName ) const; NodePtr child( const std::string &inputName ) const; CppUT::Enumerator<NodePtr> children() const; private: NodeSpecificationPtr specification_; std::deque<std::string> braceValues_; std::deque<NodePtr> braceNodeValues_; std::deque<std::string> colonValues_; std::deque<NodePtr> colonNodeValues_; std::multimap<std::string, NodePtr> children_; unsigned int line_; unsigned int column_; }; typedef boost::shared_ptr<NodeImpl> NodeImplPtr; // class NodeProcessorError // /////////////////////////////////////////////////////////////////// struct RFTA_CPPARSER_API NodeProcessorError : public std::runtime_error { NodeProcessorError( const std::string &message ) : std::runtime_error( message ) { } }; // class NodeProcessor // /////////////////////////////////////////////////////////////// class RFTA_CPPARSER_API NodeProcessor { public: NodeProcessor(); void recordSpecfication( const NodeSpecification &specification ); void setRootSpecification( const std::string &rootSpecificationName ); void checkSpecifications(); NodePtr parseNodeTree( const std::string &nodeTree, unsigned int startLine ); private: struct Token { enum TokenType // update typeName() when changed { tokenIdentifier = 0, tokenOpenRoundBrace, tokenCloseRoundBrace, tokenOpenCurlyBrace, tokenCloseCurlyBrace, tokenColon, tokenComma, tokenError }; Token( const std::string &text, TokenType type, unsigned int line, unsigned int column ) : text_( text ) , type_( type ) , line_( line ) , column_( column ) { } static std::string typeName( TokenType type ); std::string text_; TokenType type_; unsigned int line_; unsigned int column_; }; typedef std::deque<Token> Tokens; void tokenize( const std::string &declarations, unsigned int startLine ); static bool isIdFirstLetter( char c ); static bool isIdOtherLetter( char c ); NodeImplPtr expectNode( const NodeSpecification &specification ); /// Checks that the node meet its specification requirements void checkNodeRequirements( const NodeImplPtr &node, const Token &start ) const; void checkNodeColonEnumerationConstraint( const NodeImplPtr &node, const Token &start ) const; void parseNodeBraceValues( const NodeImplPtr &node ); void parseNodeBraceNodeValue( const NodeImplPtr &node ); void parseNodeColonValue( const NodeImplPtr &node ); void parseNodeColonNodeValue( const NodeImplPtr &node ); void parseNodeChildren( const NodeImplPtr &node ); void syntaxError( const Token &token, const std::string &message ) const; void syntaxError( const std::string &message ) const; bool hasMoreTokens() const; bool expectMoreTokens( const Token &errorLocation, const std::string &message ) const; const Token &expectToken( Token::TokenType type, const std::string &message = "" ); bool isAheadTokenType( Token::TokenType type ) const; void nextToken(); typedef std::map<std::string,NodeSpecificationPtr> NodeSpecifications; NodeSpecifications specifications_; typedef std::deque<std::string> SpecificationNames; typedef std::map<std::string,SpecificationNames> ParseNamesToSpecificationNames; ParseNamesToSpecificationNames parseNamesToSpecificationNames_; int tokenIndex_; Tokens tokens_; std::string rootSpecificationName_; }; #endif // TEST_NODEPROCESSOR_H_INCLUDED --- NEW FILE: token.h --- #ifndef PARSER_TOKEN_H_INCLUDED # define PARSER_TOKEN_H_INCLUDED # include <rfta/cppparser/conststring.h> # include <map> # include <sstream> # include <vector> namespace Parser { typedef unsigned int BufferId; class RFTA_CPPARSER_API TokenLocation { public: TokenLocation() : startPos_(-1) , endPos_(-1) , bufferId_(-1) { } TokenLocation( unsigned int startPos, unsigned int endPos, BufferId bufferId ) : startPos_( startPos ) , endPos_( endPos ) , bufferId_( bufferId ) { } bool isValid() const { return startPos_ != -1 && endPos_ != -1; } bool operator ==( const TokenLocation &other ) const { return startPos_ == other.startPos_ && endPos_ == other.endPos_ && bufferId_ == other.bufferId_; } bool operator !=( const TokenLocation &other ) const { return !( *this == other ); } unsigned int length() const { return endPos_ - startPos_; } unsigned int startPos_; unsigned int endPos_; BufferId bufferId_; }; class RFTA_CPPARSER_API TokenType { public: enum { idShift = 16 }; TokenType() { } TokenType( unsigned int type ) : type_( type ) { } TokenType( TokenType category, unsigned int id ) : type_( category.type_ | id ) { } bool operator ==( TokenType other ) const; bool operator !=( TokenType other ) const; bool operator <( TokenType other ) const; unsigned int id() const; bool isSilent() const; TokenType category() const; TokenType nextCategory() const; unsigned int hash() const; void setSilent(); private: enum { tokenIdMask = 0xffff0000, tokenCategoryMask = 0xfff, tokenCategoryIncrement = 0x1, tokenSilentMask = 0x8000000 }; unsigned int type_; }; class RFTA_CPPARSER_API TokenIdManager { public: static unsigned int get( const ConstString &text ); static std::string str( TokenType type ); private: static TokenIdManager &instance(); typedef std::map<ConstString,unsigned int> TokenIds; TokenIds ids_; typedef std::map<unsigned int,std::string> IdTexts; IdTexts texts_; }; enum DefaultTokenType { invalidTokenType = -1, endStream = 0, symbol, lastUsedTokenType }; class RFTA_CPPARSER_API TokenTypeManager { public: TokenTypeManager(); static TokenTypeManager &instance(); TokenType add( const ConstString &name, bool isSilent = false ); ConstString typeName( TokenType type ) const; private: void set( TokenType id, const ConstString &name ); typedef std::map<ConstString,TokenType> Types; Types types_; typedef std::map<TokenType,ConstString> Names; Names names_; ConstString unknownName_; TokenType last_; }; inline ConstString RFTA_CPPARSER_API tokenTypeName( TokenType type ) { return TokenTypeManager::instance().typeName( type ); } class RFTA_CPPARSER_API Token { public: Token( const ConstString &text, TokenType tokenType, TokenLocation location = TokenLocation() ); const ConstString &text() const; const TokenLocation &location() const; TokenType type() const; TokenType category() const; bool isSilent() const; ConstString typeName() const; unsigned int hash() const; bool operator ==( const Token &other ) const; bool operator !=( const Token &other ) const; std::string str() const; private: ConstString text_; TokenLocation location_; TokenType tokenType_; }; typedef std::vector<Token> Tokens; // Inline functions // ////////////////////////////////////////// inline bool TokenType::operator ==( TokenType other ) const { return type_ == other.type_; } inline bool TokenType::operator !=( TokenType other ) const { return type_ != other.type_; } inline bool TokenType::operator <( TokenType other ) const { return type_ < other.type_; } inline unsigned int TokenType::id() const { return type_ & tokenIdMask; } inline bool TokenType::isSilent() const { return (type_ & tokenSilentMask) != 0; } inline void TokenType::setSilent() { type_ |= tokenSilentMask; } inline TokenType TokenType::category() const { return TokenType( type_ & ~tokenIdMask ); } inline TokenType TokenType::nextCategory() const { return category().type_ + tokenCategoryIncrement; } inline unsigned int TokenType::hash() const { return type_; } inline unsigned int TokenIdManager::get( const ConstString &text ) { TokenIds::iterator it = instance().ids_.find( text ); if ( it == instance().ids_.end() ) { unsigned int id = (instance().ids_.size()+1) << TokenType::idShift; instance().ids_.insert( TokenIds::value_type( text, id ) ); instance().texts_.insert( IdTexts::value_type( id, text.str() ) ); return id; } return it->second; } inline std::string TokenIdManager::str( TokenType type ) { if ( instance().texts_.count(type.id()) == 0) return "<unknown>"; return instance().texts_.find(type.id())->second; } inline TokenIdManager & TokenIdManager::instance() { static TokenIdManager manager; return manager; } inline TokenTypeManager::TokenTypeManager() : last_( lastUsedTokenType ) , unknownName_( "?" ) { set( endStream, "end_stream" ); set( symbol, "symbol" ); } inline TokenTypeManager & TokenTypeManager::instance() { static TokenTypeManager manager; return manager; } inline TokenType TokenTypeManager::add( const ConstString &name, bool isSilent ) { Types::iterator it = types_.find( name ); if ( it == types_.end() ) { TokenType type = last_; if ( isSilent ) { type.setSilent(); set( last_, "__silent__." + name.str() ); } else set( last_, name ); last_ = last_.nextCategory(); return type; } return it->second; } inline ConstString TokenTypeManager::typeName( TokenType type ) const { Names::const_iterator it = names_.find( type.category() ); if ( it == names_.end() ) return unknownName_; if ( type.isSilent() ) return it->second.str().substr( 11 ); // "__silent__." return it->second; } inline void TokenTypeManager::set( TokenType id, const ConstString &name ) { types_[name] = id; names_[id] = name; } inline Token::Token( const ConstString &text, TokenType tokenType, TokenLocation location ) : text_( text ) , tokenType_( tokenType ) , location_( location ) { if ( tokenType.category() == TokenType(symbol) && tokenType.id() == 0 ) tokenType_ = TokenType( tokenType.category(), TokenIdManager::get( text ) ); } inline const ConstString & Token::text() const { return text_; } inline const TokenLocation & Token::location() const { return location_; } inline TokenType Token::type() const { return tokenType_; } inline TokenType Token::category() const { return tokenType_.category(); } inline bool Token::isSilent() const { return tokenType_.isSilent(); } inline ConstString Token::typeName() const { return tokenTypeName( tokenType_ ); } inline unsigned int Token::hash() const { return (tokenType_.hash() << 17) + text_.hash(); } inline bool Token::operator ==( const Token &other ) const { return text_ == other.text_ && tokenType_ == other.tokenType_ && location_ == other.location_; } inline bool Token::operator !=( const Token &other ) const { return !( *this == other ); } inline std::string Token::str() const { std::ostringstream os; os << "Token(" << tokenTypeName(tokenType_).str() << ", " << location_.startPos_ << "-" << location_.endPos_ << " = '" << text_.str() << "')"; return os.str(); } } // namespace Parser #endif // PARSER_TOKEN_H_INCLUDED --- NEW FILE: node.h --- #ifndef PARSER_NODE_H_INCLUDED # define PARSER_NODE_H_INCLUDED # include <boost/intrusive_ptr.hpp> # include <rfta/cppparser/token.h> # include <stack> # include <stdexcept> namespace Parser { class Node; typedef boost::intrusive_ptr<Node> NodePtr; } // namespace Parser namespace boost { void RFTA_CPPARSER_API intrusive_ptr_add_ref( Parser::Node *); void RFTA_CPPARSER_API intrusive_ptr_release( Parser::Node *); } // namespace boost namespace Parser { typedef std::vector<NodePtr> Nodes; class RFTA_CPPARSER_API NodeVisitor { public: virtual ~NodeVisitor() { } virtual void visitNode( Node &node ) = 0; }; class RFTA_CPPARSER_API NodeEnumerator { public: NodeEnumerator( const NodePtr ¤t ) : current_( current ) { } bool hasNext() const { return current_; } Node &next(); NodePtr nextPtr(); private: NodePtr current_; }; class RFTA_CPPARSER_API DepthFirstEnumerator { public: DepthFirstEnumerator( const NodePtr ¤t ) : current_( current.get() ) { } bool hasNext() const; bool hasPrevious() const; Node &next(); Node &previous(); private: std::stack<Node *> parents_; Node *current_; }; class RFTA_CPPARSER_API Node { public: friend void boost::intrusive_ptr_add_ref( Node *); friend void boost::intrusive_ptr_release( Node *); // Node name is really a node type Node( const ConstString &name, const Nodes &children = Nodes() ) : parent_( 0 ) , previousSibling_( 0 ) , name_( name ) , token_( "", invalidTokenType ) , count_( 0 ) { for ( int index =0; index < children.size(); ++index ) appendChild( children.at( index ) ); } Node( const Token &token ) : parent_( 0 ) , previousSibling_( 0 ) , name_( token.typeName() ) , token_( token ) { } virtual ~Node() { } void setParent( Node *parent ) { parent_ = parent; } NodePtr getPreviousSibling() const { return previousSibling_; } const NodePtr &getNextSibling() const { return nextSibling_; } void unparent() { parent_ = 0; } Node *parent() const { return parent_; } NodeEnumerator enumChildren() const { return NodeEnumerator( firstChild_ ); } void setName( const ConstString &name ) { name_ = name; } const ConstString &name() const { return name_; } virtual bool accept( NodeVisitor &visitor ) { visitor.visitNode( *this ); return true; } NodePtr thisPtr() const; NodePtr childAt( std::size_t index ) const; NodePtr getLastChild() const; bool hasChildren() const; int getChildCount() const; std::string treeStr( int margin = 0, int indentLevel = 0 ); std::string str() const; void appendChild( const NodePtr &child ); void prependChild( const NodePtr &child ); NodePtr removeFromParent(); void insertSiblingAfter( const NodePtr &newNextSibling ); // token functions const Token &token() const { return token_; } void setToken( const Token &token ) { token_ = token; } const ConstString &text() const { return token_.text(); } unsigned int textLength() const { return text().length(); } TokenType type() const { return token_.type(); } TokenType category() const { return token_.category(); } bool hasValidToken() const { return token_.type() != invalidTokenType; } ConstString typeName() const { return token_.typeName(); } const TokenLocation &location() const { return token_.location(); } private: void setNextSibling( const NodePtr &nextSibling ); void setFirstChild( const NodePtr &firstChild ); virtual std::string nodeHeaderStr() const; Node( const Node &other ); void operator=( const Node &other ); private: Token token_; ConstString name_; Node *parent_; NodePtr firstChild_; Node *previousSibling_; NodePtr nextSibling_; long count_; // reference count for intrusive_ptr }; inline NodePtr RFTA_CPPARSER_API makeCompositeNode( const ConstString &name ) { return NodePtr( new Node( name ) ); } inline NodePtr RFTA_CPPARSER_API makeNode( const ConstString &name ) { return makeCompositeNode( name ); } inline NodePtr RFTA_CPPARSER_API makeTokenNode( const Token &token ) { return NodePtr( new Node( token ) ); } } // namespace Parser #endif // PARSER_NODE_H_INCLUDED --- NEW FILE: cppparserfacade.h --- #ifndef PARSER_CPPPARSERFACADE_H_INCLUDED # define PARSER_CPPPARSERFACADE_H_INCLUDED # include <rfta/cppparser/forwards.h> # include <rfta/cppparser/cppparsersettings.h> # include <stdexcept> namespace Parser { class RFTA_CPPARSER_API CppParserFacade { public: CppParserFacade( const CppParserSettings &settings ); // clearly not final api, will need filename & 'file provider' for preprocessing NodePtr parse( const std::string &input ); private: const CppParserSettings &settings_; boost::shared_ptr<GrammarBuilder> builder_; MatcherPtr translationUnitMatcher_; }; class RFTA_CPPARSER_API CppParserFacadeError : public std::runtime_error { public: CppParserFacadeError( const std::string &message ) : std::runtime_error( message ) { } }; } // namespace Parser #endif // PARSER_CPPPARSERFACADE_H_INCLUDED --- NEW FILE: conststring.h --- #ifndef PARSER_CONSTSTRING_H_INCLUDED # define PARSER_CONSTSTRING_H_INCLUDED # include <rfta/cppparser/config.h> # include <algorithm> # include <string> namespace Parser { class RFTA_CPPARSER_API ConstString { public: typedef const char *const_iterator; typedef char value_type; ConstString( const std::string &s ) : buffer_( 0 ) { const char *begin = s.c_str(); const char *end = begin + s.length(); initialize( begin, end ); } ConstString( const char *cstring = "" ) : buffer_( 0 ) { const char *end = cstring; while ( *end != 0 ) ++end; initialize( cstring, end ); } ConstString( const char *begin, const char *end ) : buffer_( 0 ) { initialize( begin, end ); } ConstString( const ConstString &other ) : buffer_( 0 ) { initializeBuffer( other.buffer_, other.buffer_ + other.length_ ); checksum_ = other.checksum_; } ~ConstString() { delete [] const_cast<char *>(buffer_); } ConstString &operator =( const ConstString &other ) { ConstString tmp( other ); std::swap( buffer_, tmp.buffer_ ); std::swap( checksum_, tmp.checksum_ ); std::swap( length_, tmp.length_ ); return *this; } const char *begin() const { return buffer_; } const char *end() const { return buffer_ + length_; } unsigned int length() const { return length_; } unsigned int hash() const { return checksum_; } const char *c_str() const { return buffer_; } std::string str() const { return buffer_; } char operator[]( int index ) const { return buffer_[index]; } bool operator ==( const ConstString &other ) const { if ( checksum_ != other.checksum_ || length_ != other.length_ ) return false; const char *end = buffer_+length_; return std::mismatch( buffer_, end, other.buffer_ ).first == end; } bool operator !=( const ConstString &other ) const { return !( *this == other ); } bool operator <( const ConstString &other ) const { return strcmp( buffer_, other.buffer_ ) < 0; } bool operator >( const ConstString &other ) const { return !( *this < other ); } private: void initialize( const char *begin, const char *end ) { initializeBuffer( begin, end ); computeChecksum(); } void initializeBuffer( const char *begin, const char *end ) { length_ = unsigned int(end - begin); char *buffer = new char[end-begin+1]; std::copy( begin, end, buffer ); buffer[length_] = 0; buffer_ = buffer; } void computeChecksum() { const char *begin = this->begin(); const char *end = this->end(); unsigned int checksum = length_ * 0x03010515; while ( begin != end ) { unsigned int c( *begin++ ); checksum ^= checksum * 0x02005001 + c; } checksum_ = checksum; } unsigned int length_; unsigned int checksum_; const char *buffer_; }; } // namespace Parser #endif // PARSER_CONSTSTRING_H_INCLUDED --- NEW FILE: forwards.h --- #ifndef PARSER_FORWARDS_H_INCLUDED # define PARSER_FORWARDS_H_INCLUDED # include <rfta/cppparser/config.h> # include <boost/intrusive_ptr.hpp> # include <boost/shared_ptr.hpp> namespace Parser { class GrammarBuilder; class Matcher; typedef boost::shared_ptr<Matcher> MatcherPtr; class Node; typedef boost::intrusive_ptr<Node> NodePtr; } // namespace Parser #endif // PARSER_FORWARDS_H_INCLUDED --- NEW FILE: autolink.h --- // No gards, this header can be included multiple time // Generic header to automatically link against a specified library // The library name prefix must be defined in CPPUT_LIB_NAME. // CPPUT_LIB_NAME will be undefined after including this header. // The full library name is build according to the followin rules: // (0) CPPUT_LIB_NAME: library name prefix (lut,...) // (a) TOOLSET: vc6, vc7, bcb4, bcb5, bcb6 // (b) THREADING: m(multithreaded), s(single threaded) // (c) DEBUG MODE: r(release), d(debug) // (d) LINKAGE: s(static), d(dynamic) // FULLNAME: 0_a_bcd.lib #if !defined(CPPUT_LIB_NAME) # error Macro CPPUT_LIB_NAME should be defined. You should not include this header directly. #endif // Select compiler #if defined(_MSC_VER) && (_MSC_VER == 1200) // VC6 # define CPPUT_LIB_TOOLSET "vc6" #elif defined(_MSC_VER) && (_MSC_VER >= 1300) //VC7 (.NET 2002) # define CPPUT_LIB_TOOLSET "vc7" #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) // CBuilder 6 # define CPPUT_LIB_TOOLSET "bcb6" #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) # define CPPUT_LIB_TOOLSET "bcb5" #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x540) # define CPPUT_LIB_TOOLSET "bcb4" #endif // Select threading #if defined(_MT) || defined(__MT__) # define CPPUT_LIB_THREADING "m" #else # define CPPUT_LIB_THREADING "s" #endif // Select debug mode #if defined(_DEBUG) # define CPPUT_LIB_DEBUG_MODE "d" #else # define CPPUT_LIB_DEBUG_MODE "r" #endif // Select linkage #if defined(CPPUT_STATIC_LINK) # define CPPUT_LIB_LINKAGE "s" #else # define CPPUT_LIB_LINKAGE "d" #endif // Automatic link #if defined(CPPUT_LIB_TOOLSET) && \ defined(CPPUT_LIB_THREADING) && \ defined(CPPUT_LIB_LINKAGE) && \ defined(CPPUT_LIB_DEBUG_MODE) # define CPPUT_LIB_FULL_NAME \ CPPUT_LIB_NAME "_" CPPUT_LIB_TOOLSET "_" CPPUT_LIB_THREADING CPPUT_LIB_DEBUG_MODE \ CPPUT_LIB_LINKAGE ".lib" # pragma comment(lib,CPPUT_LIB_FULL_NAME) #endif #undef CPPUT_LIB_TOOLSET #undef CPPUT_LIB_THREADING #undef CPPUT_LIB_LINKAGE #undef CPPUT_LIB_DEBUG_MODE #undef CPPUT_LIB_FULL_NAME #undef CPPUT_LIB_NAME |