From: <net...@us...> - 2003-04-29 09:56:26
|
Update of /cvsroot/cpptool/rfta/src/rftaparser In directory sc8-pr-cvs1:/tmp/cvs-serv29650/src/rftaparser Modified Files: UnparsedDeclarationMutator.h UnparsedDeclarationMutator.cpp UnparsedDeclarationListMutatorTest.cpp Log Message: -- corrected "UnparsedDeclarationMutator" to be a real Mutator that can be used by MaxLODMutator Index: UnparsedDeclarationMutator.h =================================================================== RCS file: /cvsroot/cpptool/rfta/src/rftaparser/UnparsedDeclarationMutator.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** UnparsedDeclarationMutator.h 26 Apr 2003 11:06:25 -0000 1.1 --- UnparsedDeclarationMutator.h 29 Apr 2003 09:56:21 -0000 1.2 *************** *** 7,12 **** #define RFTA_UnparsedDeclarationMutator_H ! #include <rfta/parser/Parser.h> ! #include <set> namespace Refactoring --- 7,11 ---- #define RFTA_UnparsedDeclarationMutator_H ! #include <rfta/parser/Mutator.h> namespace Refactoring *************** *** 15,19 **** /// Mutate an unparsed-declaration-list into a parsed declaration-list ! class UnparsedDeclarationMutator : public Parser { public: --- 14,19 ---- /// Mutate an unparsed-declaration-list into a parsed declaration-list ! class UnparsedDeclarationMutator : public Mutator ! , public boost::noncopyable { public: *************** *** 22,88 **** * source range must not start with white spaces. */ ! UnparsedDeclarationMutator( ! ParseContext &context, ! const ASTNodePtr &node, ! const SourceASTNodePtr &sourceNode); /// Destructor. virtual ~UnparsedDeclarationMutator(); ! bool tryMutate(); ! ! private: ! ! // ! // private methods for type specifier parsing: ! // ! // ENTRY-Point: ! void parseDeclarationSpecifierList(ASTNodePtr &specifierList); ! ! // parsing of composed specifiers (e.g. "class x { ... }" ! void parseComposedSpecifier(const char * specifierStart, std::string& specifierIdent, ASTNodePtr &specifierList); ! ! /** ! * function does try to read a user defined type (it checks for a variable ! * declaration) ! * returns false in case of the end of specifier list ! */ ! bool tryParseUserDefinedType(std::string& typename_); ! ! void readNestedName(std::string& nestedname); ! void readClassOrEnumSpecifier(ASTNodePtr& specifier, std::string keyword, std::string name); ! ! // ! // private methods for declarator parsing: ! // ! // ENTRY-Point: ! void parseDeclarators(); ! void parseOperator(); ! ! bool tryReadToken(std::string& token); ! ! bool doesKeywordFollow( std::string keyword ); ! static bool tryFindNextBalanced( const char *¤t, ! const char *end, ! char opening = '<', ! char closing = '>' ); ! ! ! bool skipOverAssignmentInitializer(); ! ! void createAndAddInitializerNode( const ASTNodePtr &variableDeclNode ); ! ! void addValueNode( const ASTNodePtr& variableDeclNode, ! int start, ! int end ) const; ! void addInitializerNode( const ASTNodePtr& variableDeclNode, ! const ASTNodeType initializerType, ! int initializerStartIndex ) const; - private: - ASTNodePtr node_; - typedef std::set<std::string> KeywordSet; - KeywordSet declarationSpecifiers; - KeywordSet elaboratedSpecifiers; }; --- 22,33 ---- * source range must not start with white spaces. */ ! UnparsedDeclarationMutator(); /// Destructor. virtual ~UnparsedDeclarationMutator(); ! void mutate( const ASTNodePtr &node, ! const SourceASTNodePtr &sourceNode) const; }; Index: UnparsedDeclarationMutator.cpp =================================================================== RCS file: /cvsroot/cpptool/rfta/src/rftaparser/UnparsedDeclarationMutator.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** UnparsedDeclarationMutator.cpp 28 Apr 2003 20:37:54 -0000 1.3 --- UnparsedDeclarationMutator.cpp 29 Apr 2003 09:56:21 -0000 1.4 *************** *** 10,13 **** --- 10,14 ---- #include <rfta/parser/ParseContext.h> #include <rfta/parser/DeclarationListParser.h> + #include "DeclarationDetailsParser.h" *************** *** 16,64 **** ! UnparsedDeclarationMutator::UnparsedDeclarationMutator( ! ParseContext &context, ! const ASTNodePtr &node, ! const SourceASTNodePtr &sourceNode) ! : Parser( context, ! sourceNode->getBlankedSourceStart() + node->getRange().getStartIndex(), ! sourceNode->getBlankedSourceStart() + node->getRange().getEndIndex() ) ! , node_( node ) { - // build lookup table for specifiers: - // generel specifier: - declarationSpecifiers.insert("typedef"); - declarationSpecifiers.insert("friend"); - // storage class - declarationSpecifiers.insert("auto"); - declarationSpecifiers.insert("register"); - declarationSpecifiers.insert("static"); - declarationSpecifiers.insert("extern"); - declarationSpecifiers.insert("mutable"); - // function specifiers - declarationSpecifiers.insert("inline"); - declarationSpecifiers.insert("virtual"); - declarationSpecifiers.insert("explicit"); - // simple type specifiers - declarationSpecifiers.insert("char"); - declarationSpecifiers.insert("wchar_t"); - declarationSpecifiers.insert("bool"); - declarationSpecifiers.insert("short"); - declarationSpecifiers.insert("int"); - declarationSpecifiers.insert("long"); - declarationSpecifiers.insert("signed"); - declarationSpecifiers.insert("unsigned"); - declarationSpecifiers.insert("float"); - declarationSpecifiers.insert("double"); - declarationSpecifiers.insert("void"); - // cv-qualifier - declarationSpecifiers.insert("const"); - declarationSpecifiers.insert("volatile"); - - // build lookup table for elaborated specifiers: - elaboratedSpecifiers.insert("class"); - elaboratedSpecifiers.insert("struct"); - elaboratedSpecifiers.insert("enum"); - elaboratedSpecifiers.insert("union"); - elaboratedSpecifiers.insert("typename"); } --- 17,22 ---- ! UnparsedDeclarationMutator::UnparsedDeclarationMutator() { } *************** *** 69,909 **** - bool - UnparsedDeclarationMutator::tryMutate() - { - ASTNodePtr declarationNode = node_; - node_->mutateType( ASTNodeTypes::declaration ); - - ASTNodePtr specifierList = - createASTNode( - ASTNodeTypes::declarationSpecifierList, - declarationNode, - getCurrentIndex(), - getCurrentLength() - ); - declarationNode->setPropertyNode( - ASTNodeProperties::declarationSpecifiersProperty, - specifierList - ); - - // read the declaration specifier list and add childs to property: - parseDeclarationSpecifierList(specifierList); - - backtrackSkippingSpaces(); - specifierList->setLength(getCurrentLength()); - - skipSpaces(); - - // check if declaration has also a declarator: - if (!tryNextIs(';')) - { - // read all declarators and add childs to property: - parseDeclarators(); - } - - // return with no parsing error: - return true; - } - - /** - * function parses all declaration specifiers until the first declarator is found. - * the decision about the end of the specifier list is done in "tryParseUserDefinedType" - */ - void - UnparsedDeclarationMutator::parseDeclarationSpecifierList(ASTNodePtr &specifierList) - { - std::string identifier; - - const char * save_pointer = getCurrent(); - - while ( save_pointer = getCurrent(), tryReadNextIdentifier(identifier) ) - { - if (declarationSpecifiers.find(identifier) != declarationSpecifiers.end()) - { - // add the specifier node - ASTNodePtr specifier = - createASTNode( - ASTNodeTypes::simpleTypeSpecifier, - specifierList, - save_pointer-getStart(), - getCurrent()-save_pointer - ); - specifierList->addChild(specifier); - - skipSpaces(); - continue; - } - // check elaborated-specifiers: - else if (elaboratedSpecifiers.find(identifier) != elaboratedSpecifiers.end()) - { - skipSpaces(); - parseComposedSpecifier(save_pointer, identifier, specifierList); - skipSpaces(); - continue; - } - else - // check characters after symbol to find out if it's a userdefined type... - if (tryParseUserDefinedType(identifier)) - { - backtrackSkippingSpaces(); - // add the specifier node - ASTNodePtr specifier = - createASTNode( - ASTNodeTypes::simpleTypeSpecifier, - specifierList, - save_pointer-getStart(), - getCurrent()-save_pointer - ); - specifierList->addChild(specifier); - skipSpaces(); - continue; - } - else - { - current_ = save_pointer; - break; - } - } - } - - /** - * function tries to parse elaborated and class/enum/struct/union specifiers - * a decision about the type is found during parsing. - */ - void - UnparsedDeclarationMutator::parseComposedSpecifier(const char * specifierStart, - std::string& specifierIdent, - ASTNodePtr &specifierList) - { - // CASE 1: - // check if identifier starts with a '::') - // (definitions can not start with nested names -> this declaration is an elaborated type - // which ends after the name) - if (tryNextIs(':')) - { - if (!tryNextIs(':')) - { - throwFailure( "Expected a double colon => '::'." ); - } - skipSpaces(); - // read the full name: - std::string name("::"); - readNestedName(name); - - // add the specifier node - ASTNodePtr specifier = - createASTNode( - ASTNodeTypes::elaboratedTypeSpecifier, - specifierList, - specifierStart-getStart(), - getCurrent()-specifierStart - ); - specifierList->addChild(specifier); - - return; - // FINISH HERE - } - - // try to read the identifier that can be specifier after an elaborated type specifier - // if no identifier follows, an unnamed type is specifier (e.g. "struct { } x;") - std::string secondIdent; - if (tryReadNextIdentifier(secondIdent)) - { - skipSpaces(); - } - - // check if no identifier or the identifier is not followed by a ':' (e.g. "class x {" - if (secondIdent.empty() || !tryNextIs(':')) - { - // add the specifier node - ASTNodePtr specifier = - createASTNode( - ASTNodeTypes::classSpecifier, - specifierList, - specifierStart-getStart(), - getCurrent()-specifierStart - ); - specifierList->addChild(specifier); - - readClassOrEnumSpecifier(specifier, specifierIdent, secondIdent); - - // set real length after completed parsing - specifier->setLength(getCurrent()-specifierStart); - - return; - } - - // HERE we come only in case where the type is followed by a colon. "e.g. class x:" - // check if it is only a single colon (which means inheritance information e.g. "class x: public y ") - if (!tryNextIs(':')) - { - // yes it's - so parse the class specifier - if (specifierIdent == "class" || specifierIdent == "struct" || specifierIdent == "union") - { - - // add the specifier node - ASTNodePtr specifier = - createASTNode( - ASTNodeTypes::classSpecifier, - specifierList, - specifierStart-getStart(), - getCurrent()-specifierStart - ); - specifierList->addChild(specifier); - - // read the complete specifier: - readClassOrEnumSpecifier(specifier, specifierIdent, secondIdent); - - // set real length after completed parsing - specifier->setLength(getCurrent()-specifierStart); - - return; - // FINISH HERE (the class specifier ends here !) - } - throwFailure( "Expected a double colon => '::'." ); - } - - // HERE we come only in case of a double colon after the identifier which means: - // an elaborated type is specified: e.g. "class x::y" - skipSpaces(); - - // read the full name: - secondIdent.append("::"); - readNestedName(secondIdent); - - // add the specifier node - ASTNodePtr specifier = - createASTNode( - ASTNodeTypes::elaboratedTypeSpecifier, - specifierList, - specifierStart-getStart(), - getCurrent()-specifierStart - ); - specifierList->addChild(specifier); - // set real length after completed parsing - specifier->setLength(getCurrent()-specifierStart); - } - - bool - UnparsedDeclarationMutator::tryParseUserDefinedType(std::string& typename_) - { - // the 'typename_' might be a userdefined type or a declarator - // here we try to find out: - if (typename_ == "operator") - return false; - - // first read the fully qualified name: - skipSpaces(); - // maybe a full qualified typename (e.g. "std::string") - if (tryNextIs(':')) - { - if (!tryNextIs(':')) - { - --current_; - return false; // it's not "::" - might be the bitfield operator (e.g. "int myvar:0") - } - typename_.append("::"); - readNestedName(typename_); - skipSpaces(); - } - - // do some look ahead for the decision (store rollback position - const char * rollback = current_; - - // now check for template declaration: - if (tryNextIs('<')) // the use of a template type - { - // skip template usage: - findNextBalanced('<','>'); - skipSpaces(); - // check if it has parameter: - if (tryNextIs('(')) - if (!this->tryReadUntilNext(')')) - throwFailure("Expect a closed parameter list for this template."); - - return true; // yes, it's a user defined type ! - } - - // DO SOME LOOK AHEAD TO FIND OUT - // a possible declarator that follows: - // check existence of a next identifier, this is a sign for a userdefined type... - std::string identifier; - if (tryReadNextIdentifier(identifier)) - { - current_ = rollback; - return true; - } - - // check for a special case where the declarator starts with a '(' - // example: "int (*(*f))(int); - - if (tryNextIs('(')) // might be the declarator (e.g. "usertype (*f);" or a parameter (e.g. "int userfct()"; - { - findNextBalanced('(',')'); - } - skipSpaces(); - std::string seperators=",;=["; - bool ret = seperators.find(*current_) == std::string::npos; - - current_ = rollback; - return ret; - } - - void - UnparsedDeclarationMutator::readNestedName(std::string& nestedname) - { - std::string fullName = nestedname; - std::string nameSpecifier; - bool oneMoreLevel; - do { - oneMoreLevel = false; - if (!tryReadNextIdentifier(nameSpecifier)) - throwFailure( "Expected an identifier for elaborated type." ); - - fullName.append(nameSpecifier); - - skipSpaces(); - // check if identifier is followed by a '::' (additional level - if (tryNextIs(':')) - { - if (!tryNextIs(':')) - { - --current_; - return; // // it's not a "::" - might be the bitfield operator (e.g. "int myvar::sub :0") - } - - fullName.append("::"); - - skipSpaces(); - oneMoreLevel = true; - } - } while (oneMoreLevel); - backtrackSkippingSpaces(); - } - - void - UnparsedDeclarationMutator::readClassOrEnumSpecifier(ASTNodePtr& specifier, std::string keyword, std::string name) - { - ASTNodePtr body; - int startIndex; - - if (keyword == "class" || keyword == "struct" || keyword == "union") - { - // read over possible inheritance information - readUntilNextOf("{"); - current_++; - - body = createASTNode( - ASTNodeTypes::unparsedDeclarationList, - specifier, - startIndex = getCurrentIndex(), - getCurrentLength() - ); - specifier->setPropertyNode( ASTNodeProperties::classBodyProperty , body ); - } else - { - specifier->mutateType( ASTNodeTypes::enumSpecifier ); - expect('{'); - - body = createASTNode( - ASTNodeTypes::unparsedDeclarationList, - specifier, - startIndex = getCurrentIndex(), - getCurrentLength() - ); - specifier->setPropertyNode( ASTNodeProperties::enumBodyProperty , body ); - } - findNextBalanced('{','}'); - body->setLength(getCurrentLength() - startIndex - 1 ); // do not count the last '}' - } - - bool - UnparsedDeclarationMutator::tryFindNextBalanced( const char *¤t, - const char *end, - char opening, - char closing ) - { - int balance = 1; - while ( ++current != end ) - { - char c = *current; - if ( c == closing ) - { - --balance; - if ( balance == 0 ) - { - ++current; - return true; - } - } - else if ( c == opening ) - ++balance; - } - - return false; - } - - - bool - UnparsedDeclarationMutator::skipOverAssignmentInitializer() - { - const char *start = current_; - while ( current_ != end_ ) - { - char c = *current_; - if ( c == ';' || c == ',' ) - return current_ != (start+1); - else if ( c == '(' ) - { - if ( !tryFindNextBalanced( current_, end_, '(', ')' ) ) - return false; - } - else if ( c == '[' ) - { - if ( !tryFindNextBalanced( current_, end_, '[', ']' ) ) - return false; - } - else if ( c == '{' ) - { - if ( !tryFindNextBalanced( current_, end_, '{', '}' ) ) - return false; - } - else - ++current_; - } - - return true; - } - - void - UnparsedDeclarationMutator::parseDeclarators() - { - Tracker tracker( "UnparsedDeclarationMutator::parseDeclarators", *this ); - - int declaratorNumber = 1; - int prefixEndIndex = getCurrentIndex(); - - while ( current_ != end_ ) - { - skipSpaces(); - int declaratorStartIndex = getCurrentIndex(); - - if (doesKeywordFollow( "operator" )) - { - parseOperator(); - return; - } - - // find end of the init-declarator - bool declaratorEndReached = false; - bool functionDeclarator = false; - bool identifierFound = false; - do { - skipSpaces(); - if (tryNextIs('*')) continue; - if (tryNextIs('&')) continue; - if (tryNextIs('(')) - { - // check if this is a direct declaration of a function: - if (identifierFound) - { - functionDeclarator = true; - findNextBalanced('(',')'); - } else - { - findNextBalanced('(',')'); - readUntilNextOf(";,=("); - if (tryNextIs('(')) - { - functionDeclarator = true; - findNextBalanced('(',')'); - } - } - declaratorEndReached = true; - break; - } - if (tryNextIs('[')) - { - findNextBalanced('[',']'); - continue; - } - if (tryNextIs(';') || tryNextIs(',') || tryNextIs('=') || tryNextIs('{')) - { - declaratorEndReached = true; - --current_; - break; - } - - std::string nestedName; - if (tryNextIs(':')) - { - if (!tryNextIs(':')) - throwFailure("Did not expect a single colon at this stage."); - - nestedName = "::"; - } - - std::string identifier; - if (!tryReadNextIdentifier(identifier)) - { - throwFailure( boost::format("unexpected character: '%1%'.") % *current_ ); - } else - { - if (identifier=="const") continue; - if (identifier=="volatile") continue; - identifierFound = true; - - // read fully qualified name: - nestedName.append(identifier); - - if (tryReadNext("::")) - { - nestedName.append("::"); - readNestedName(identifier); - } - - // check for bitfield expression - if (tryNextIs(':')) - { - if (!skipOverAssignmentInitializer()) - throwFailure("Constant expression is not well formed."); - // @todo: store bit field expression - } - continue; - } - } while (hasNext() && !declaratorEndReached); - - if (!declaratorEndReached) - { - boost::format frmt( "failed to find expected declarator separator " - "for declaration %1%: ',;=({'. "); - throwFailure( frmt % declaratorNumber ); - } - - if (functionDeclarator) - { - // read the possible identifiers after function declarator: - bool found; - do { - skipSpaces(); - found=false; - if (doesKeywordFollow("const") ) { found=true; } - if (doesKeywordFollow("volatile") ) { found=true; } - } while (found); - - if (doesKeywordFollow("throw")) - { - skipSpaces(); - expect('('); - readUntilNextOf(")"); - if (*current_==')') ++current_; - } - } - ASTNodePtr - declaratorNode = createASTNode( ASTNodeTypes::unparsedDeclarator, - node_, - declaratorStartIndex, - getCurrentIndex() - declaratorStartIndex ); - // the correct length is set when the initializer is added. - node_->addChild(declaratorNode); - - // now go through initializers: - createAndAddInitializerNode(declaratorNode); - declaratorNumber++; - } - } - - - void - UnparsedDeclarationMutator::createAndAddInitializerNode( const ASTNodePtr &declaratorNode ) - { - if ( !hasNext() ) - return; - - Tracker tracker( "UnparsedDeclarationMutator::createAndAddInitializerNode", *this ); - - int initializerStartIndex = getCurrentIndex(); - int initializerValueStartIndex; - int initializerValueEndIndex; - int declaratorEndIndex; - ASTNodeType initializerType; - switch( *current_++ ) - { - case '=': - initializerType = ASTNodeTypes::assignVariableInitializerExpression; - skipSpaces(); - initializerValueStartIndex = getCurrentIndex(); - skipOverAssignmentInitializer(); /// @todo should check return value - declaratorEndIndex = getCurrentIndex(); - initializerValueEndIndex = getCurrentIndex(); - break; - case '(': - initializerType = ASTNodeTypes::constructorVariableInitializerExpression; - initializerValueStartIndex = getCurrentIndex(); - findNextBalanced( '(', ')' ); - declaratorEndIndex = getCurrentIndex(); - initializerValueEndIndex = getCurrentIndex() -1; - break; - case ';': case ',': case '{': - return; - default: - -- current_; - throwFailure( boost::format("unexpected character: '%1%'.") % *current_ ); - } - - declaratorNode->setLength( declaratorEndIndex - - declaratorNode->getStartIndex() ); - addInitializerNode( declaratorNode, - initializerType, - initializerStartIndex ); - addValueNode( declaratorNode, - initializerValueStartIndex, - initializerValueEndIndex ); - - skipSpaces(); - if ( !hasNext() ) - return; - - if ( *current_ == ';' || *current_ == ',' ) - ++current_; - else - throwFailure( boost::format("unexpected character: '%1%'.") % *current_ ); - } - void ! UnparsedDeclarationMutator::addValueNode( const ASTNodePtr& declaratorNode, ! int start, ! int end) const ! { ! ASTNodePtr initializerNode = ! declaratorNode->getProperty( ASTNodeProperties::variableInitializerProperty ); ! ASTNodePtr valueNode = ! createASTNode( ASTNodeTypes::valueExpression, ! initializerNode, ! start, ! end-start); ! initializerNode->setPropertyNode( ASTNodeProperties::valueProperty, ! valueNode ); ! } ! ! ! void ! UnparsedDeclarationMutator::addInitializerNode( const ASTNodePtr& declaratorNode, ! const ASTNodeType initializerType, ! int initializerStartIndex) const ! { ! int initializerLength = getCurrentIndex() - initializerStartIndex; ! ! ASTNodePtr initializerNode = createASTNode( initializerType, ! declaratorNode, ! initializerStartIndex, ! initializerLength ); ! declaratorNode->setPropertyNode( ASTNodeProperties::variableInitializerProperty, ! initializerNode ); ! } ! ! bool ! UnparsedDeclarationMutator::doesKeywordFollow( std::string keyword) ! { ! int idx = 0; ! const char * save = getCurrent(); ! ! std::string id; ! bool retval = tryReadNextIdentifier(id) & id == keyword; ! if (!retval) current_ = save; ! ! return retval; ! } ! ! bool ! UnparsedDeclarationMutator::tryReadToken(std::string& token) ! { ! std::string collect; ! switch(*current_++) ! { ! case '+': ! if (*current_== '=' ) ! { current_++; collect="+="; } ! else ! if (*current_== '+' ) ! { current_++; collect="++"; } ! else ! collect="+"; ! break; ! ! case '-': ! if (*current_== '=' ) ! { current_++; collect="-="; } ! else ! if (*current_== '-' ) ! { current_++; collect="--"; } ! else ! if (*current_== '>' ) ! { ! current_++; ! if (*current_== '*' ) ! { current_++; collect="->*"; } ! else ! collect="->"; ! } ! else ! collect="-"; ! break; ! ! case '*': ! if (*current_== '=' ) ! { current_++; collect="*="; } ! else ! collect="*"; ! break; ! ! case '/': ! if (*current_== '=' ) ! { current_++; collect="/="; } ! else ! collect="/"; ! break; ! ! case '^': ! if (*current_== '=' ) ! { current_++; collect="^="; } ! else ! collect="^"; ! break; ! ! case '&': ! if (*current_== '=' ) ! { current_++; collect="&="; } ! else ! if (*current_== '&' ) ! { current_++; collect="&&"; } ! else ! collect="&"; ! break; ! ! case '|': ! if (*current_== '=' ) ! { current_++; collect="|="; } ! else ! if (*current_== '|' ) ! { current_++; collect="||"; } ! else ! collect="|"; ! break; ! ! case '~': ! collect="~"; ! break; ! ! case '!': ! if (*current_== '=' ) ! { current_++; collect="!="; } ! else ! collect="!"; ! break; ! ! case '=': ! if (*current_== '=' ) ! { current_++; collect="=="; } ! else ! collect="="; ! break; ! ! case '<': ! if (*current_== '=' ) ! { current_++; collect="<="; } ! else ! if (*current_== '<' ) ! { ! current_++; ! if (*current_== '=' ) ! { ! current_++; collect="<<="; ! } ! else ! collect="<<"; ! } ! else ! collect="<"; ! break; ! ! case '>': ! if (*current_== '=' ) ! { current_++; collect=">="; } ! else ! if (*current_== '>' ) ! { ! current_++; ! if (*current_== '=' ) ! { ! current_++; collect=">>="; ! } ! else ! collect=">>"; ! } ! else ! collect=">"; ! break; ! ! case ',': ! collect=","; ! break; ! case '(': ! expect(')'); ! collect="()"; ! break; ! case '[': ! expect(']'); ! collect="[]"; ! break; ! ! default: ! --current_; ! break; ! } ! token = collect; ! return !token.empty(); ! } ! ! void ! UnparsedDeclarationMutator::parseOperator() ! { ! int declaratorStartIndex = getCurrentIndex() - strlen("operator"); ! skipSpaces(); ! ! std::string token; ! ! if (!tryReadToken(token)) ! { ! const char * begin = getCurrent(); ! if ( doesKeywordFollow("new") ) token += "new"; ! if ( doesKeywordFollow("delete") ) token += "delete"; ! if (!token.empty()) ! { ! if ( tryReadNext("[]") ) token+="[]"; ! } ! } ! // check if operator overloading has been parsed ! if (token.empty()) ! { ! // this is not the case. ! // this is 'conversion function declarator': ! ! // skip over the type-specifier and ptr-operator elements ! readUntilNextOf("("); ! } ! ! // now read parameters: (for both operator and conversion function) ! skipSpaces(); ! expect('('); ! findNextBalanced('(',')'); ! ASTNodePtr declaratorNode = createASTNode( ASTNodeTypes::unparsedDeclarator, ! node_, ! declaratorStartIndex, ! getCurrentIndex() - declaratorStartIndex ); ! node_->addChild(declaratorNode); ! skipSpaces(); } - } // namespace Refactoring --- 27,40 ---- void ! UnparsedDeclarationMutator::mutate(const ASTNodePtr &node, ! const SourceASTNodePtr &sourceNode) const ! { ! ParseContext context( sourceNode ); ! DeclarationDetailsParser detailsparser( context, ! node, ! sourceNode ); ! detailsparser.tryParse(); } } // namespace Refactoring Index: UnparsedDeclarationListMutatorTest.cpp =================================================================== RCS file: /cvsroot/cpptool/rfta/src/rftaparser/UnparsedDeclarationListMutatorTest.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** UnparsedDeclarationListMutatorTest.cpp 28 Apr 2003 20:38:28 -0000 1.2 --- UnparsedDeclarationListMutatorTest.cpp 29 Apr 2003 09:56:21 -0000 1.3 *************** *** 7,11 **** #include "stdafx.h" #include "UnparsedDeclarationListMutator.h" ! #include "UnparsedDeclarationMutator.h" #include "NamespaceParser.h" #include "KeyedString.h" --- 7,11 ---- #include "stdafx.h" #include "UnparsedDeclarationListMutator.h" ! #include "DeclarationDetailsParser.h" #include "NamespaceParser.h" #include "KeyedString.h" *************** *** 112,122 **** // do variable declaration parsing ! UnparsedDeclarationMutator mutator( context, ! classNode, ! sourceNode ); ! CppUnit::Message message( "mutator failed", "Source:\n" + source.asString() ); ! CppUnit::Asserter::failIf( !mutator.tryMutate(), message, CPPUNIT_SOURCELINE() ); --- 112,122 ---- // do variable declaration parsing ! DeclarationDetailsParser detailsparser( context, ! classNode, ! sourceNode ); ! CppUnit::Message message( "Parser failed", "Source:\n" + source.asString() ); ! CppUnit::Asserter::failIf( !detailsparser.tryParse(), message, CPPUNIT_SOURCELINE() ); |