Update of /cvsroot/cpptool/rfta/src/rftaparser In directory sc8-pr-cvs1:/tmp/cvs-serv17247/src/rftaparser Modified Files: DeclarationDetailsParser.h DeclarationDetailsParser.cpp Added Files: DeclarationDetailsParserTest.h DeclarationDetailsParserTest.cpp Log Message: -- extensions and test for parsing declarations in compound statement context (preparation to replace 'variabledeclmutator') --- NEW FILE: DeclarationDetailsParserTest.h --- // ////////////////////////////////////////////////////////////////////////// // Header file DeclarationDetailsParserTest.h for class DeclarationDetailsParserTest // (c)Copyright 2003, Andre Baresel. // Created: 2003/05/09 // ////////////////////////////////////////////////////////////////////////// #ifndef RFTA_DeclarationDetailsParserTest_H #define RFTA_DeclarationDetailsParserTest_H #include "ParserTesting.h" namespace Refactoring { /// Unit tests for CompoundStatementParserTest class DeclarationDetailsParserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( DeclarationDetailsParserTest ); CPPUNIT_TEST( testTemplateFuntionFollowedByDecl ); CPPUNIT_TEST_SUITE_END(); public: /*! Constructs a DeclarationDetailsParserTest object. */ DeclarationDetailsParserTest(); /// Destructor. virtual ~DeclarationDetailsParserTest(); void setUp(); void tearDown(); void testTemplateFuntionFollowedByDecl(); private: /// Prevents the use of the copy constructor. DeclarationDetailsParserTest( const DeclarationDetailsParserTest &other ); /// Prevents the use of the copy operator. void operator =( const DeclarationDetailsParserTest &other ); private: }; // Inlines methods for DeclarationDetailsParserTest: // ------------------------------------------------ } // namespace Refactoring #endif // RFTA_DeclarationDetailsParserTest_H --- NEW FILE: DeclarationDetailsParserTest.cpp --- // ////////////////////////////////////////////////////////////////////////// // Implementation file DeclarationDetailsParserTest.cpp for class DeclarationDetailsParserTest // (c)Copyright 2003, Andre Baresel. // Created: 2003/04/10 // ////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "DeclarationDetailsParserTest.h" #include <rfta/parser/ASTNodes.h> #include "DeclarationDetailsParser.h" #include "KeyedString.h" namespace Refactoring { RFTAPARSER_TEST_SUITE_REGISTRATION( DeclarationDetailsParserTest ); template<typename ParserType> void checkParserFail( const std::string &source, const CppUnit::SourceLine &sourceLine, Refactoring::Testing::Identity<ParserType> ) { SourceASTNodePtr sourceNode = SourceASTNode::create( source, source ); ParseContext context( sourceNode ); ASTNodePtr compound = ASTNode::create( ASTNodeTypes::compoundStatement, sourceNode, 0, source.length(), sourceNode ); ASTNodePtr decl = ASTNode::create( ASTNodeTypes::declarationOrExpression, compound, 0, source.length(), sourceNode ); context.addNode( decl ); ParserType parser( context, decl, sourceNode ); CppUnit::Message message( "parsing did not fail", std::string( "using parser: " ) + typeid(ParserType).name(), "Source:\n" + source ); CppUnit::Asserter::failIf( parser.tryParse(), message, sourceLine ); } #define ASSERT_PARSER_FAIL( ParserType, source )\ Refactoring::checkParserFail<ParserType>( source, \ CPPUNIT_SOURCELINE(), \ Refactoring::Testing::Identity<ParserType>() ) DeclarationDetailsParserTest::DeclarationDetailsParserTest() : CppUnit::TestFixture() { } DeclarationDetailsParserTest::~DeclarationDetailsParserTest() { } void DeclarationDetailsParserTest::setUp() { } void DeclarationDetailsParserTest::tearDown() { } void DeclarationDetailsParserTest::testTemplateFuntionFollowedByDecl() { ASSERT_PARSER_FAIL( DeclarationDetailsParser, "call_fct(10);" ); ASSERT_PARSER_FAIL( DeclarationDetailsParser, "sizeof SomeType;" ); ASSERT_PARSER_FAIL( DeclarationDetailsParser, "new SomeObject;" ); ASSERT_PARSER_FAIL( DeclarationDetailsParser, "x = x + 3;" ); ASSERT_PARSER_FAIL( DeclarationDetailsParser, "name.id = name.length() > 10 ? 1 : 2;" ); } } // namespace Refactoring Index: DeclarationDetailsParser.h =================================================================== RCS file: /cvsroot/cpptool/rfta/src/rftaparser/DeclarationDetailsParser.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** DeclarationDetailsParser.h 4 May 2003 06:56:47 -0000 1.4 --- DeclarationDetailsParser.h 10 May 2003 13:10:10 -0000 1.5 *************** *** 38,42 **** // // ENTRY-Point: ! void parseDeclarationSpecifierList(ASTNodePtr &specifierList); // parsing of composed specifiers (e.g. "class x { ... }" --- 38,42 ---- // // ENTRY-Point: ! bool parseDeclarationSpecifierList(ASTNodePtr &specifierList); // parsing of composed specifiers (e.g. "class x { ... }" *************** *** 77,81 **** // // ENTRY-Point: ! void parseDeclarators(); // parser has to stay at the character after the operator keyword... --- 77,81 ---- // // ENTRY-Point: ! bool parseDeclarators(); // parser has to stay at the character after the operator keyword... *************** *** 93,97 **** bool skipOverAssignmentInitializer(); ! void createAndAddInitializerNode( const ASTNodePtr &variableDeclNode ); void addValueNode( const ASTNodePtr& variableDeclNode, --- 93,97 ---- bool skipOverAssignmentInitializer(); ! bool createAndAddInitializerNode( const ASTNodePtr &variableDeclNode ); void addValueNode( const ASTNodePtr& variableDeclNode, *************** *** 110,113 **** --- 110,114 ---- KeywordSet declarationSpecifiers; KeywordSet elaboratedSpecifiers; + KeywordSet statementKeywords; }; Index: DeclarationDetailsParser.cpp =================================================================== RCS file: /cvsroot/cpptool/rfta/src/rftaparser/DeclarationDetailsParser.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** DeclarationDetailsParser.cpp 4 May 2003 06:56:47 -0000 1.8 --- DeclarationDetailsParser.cpp 10 May 2003 13:10:10 -0000 1.9 *************** *** 63,66 **** --- 63,83 ---- elaboratedSpecifiers.insert("union"); elaboratedSpecifiers.insert("typename"); + + // statement key words: + statementKeywords.insert( "break" ); + statementKeywords.insert( "case" ); + statementKeywords.insert( "continue" ); + statementKeywords.insert( "default" ); + statementKeywords.insert( "do" ); + statementKeywords.insert( "if" ); + statementKeywords.insert( "return" ); + statementKeywords.insert( "while" ); + statementKeywords.insert( "for" ); + statementKeywords.insert( "switch" ); + statementKeywords.insert( "try" ); + + statementKeywords.insert( "sizeof" ); + statementKeywords.insert( "new" ); + statementKeywords.insert( "delete" ); } *************** *** 71,77 **** bool DeclarationDetailsParser::tryParse() ! { ASTNodePtr declarationNode = node_; node_->mutateType( ASTNodeTypes::declaration ); --- 88,102 ---- + /** + * tries to parse declaration. This does not work + * for template definition and function-implementation (these are detected in 'DeclarationParser')! + */ bool DeclarationDetailsParser::tryParse() ! { ! // @todo: reverse mutation changes in the case of a parsing failure in ! // 'parseDeclarationSpecifierList' ! // 'parseDeclarators' ! ASTNodePtr declarationNode = node_; node_->mutateType( ASTNodeTypes::declaration ); *************** *** 101,109 **** { // read all declarators and add childs to property: ! parseDeclarators(); } ! // return with no parsing error: ! return true; } --- 126,145 ---- { // read all declarators and add childs to property: ! if (!parseDeclarators()) ! return false; // @todo: restore node type to 'unparsed' / 'unknown' ! } ! ! // this check does detect wrong declarations in compound statement context ! ASTNodePtr helpnode = boost::make_shared(node_->getParentNode()); ! if ( !(!helpnode) && helpnode->getType() == ASTNodeTypes::compoundStatement ) ! { ! // check if any specifier did appear ! if (specifierList->getChildCount() == 0) ! return false; // this is not a declaration } + ! // returns true only in case of reaching the final ';' ! return *(current_-1)==';'; } *************** *** 112,116 **** * the decision about the end of the specifier list is done in "tryParseUserDefinedType" */ ! void DeclarationDetailsParser::parseDeclarationSpecifierList(ASTNodePtr &specifierList) { --- 148,152 ---- * the decision about the end of the specifier list is done in "tryParseUserDefinedType" */ ! bool DeclarationDetailsParser::parseDeclarationSpecifierList(ASTNodePtr &specifierList) { *************** *** 122,125 **** --- 158,166 ---- while ( save_pointer = getCurrent(),lastIndex=getCurrentIndex(), tryReadNextIdentifier(identifier) ) { + if (statementKeywords.find(identifier) != statementKeywords.end()) + { // statement keywords cannot be specifiers... + current_ = save_pointer; + break; + } if (declarationSpecifiers.find(identifier) != declarationSpecifiers.end()) { *************** *** 168,171 **** --- 209,213 ---- } } + return true; } *************** *** 534,538 **** } ! void DeclarationDetailsParser::parseDeclarators() { --- 576,580 ---- } ! bool DeclarationDetailsParser::parseDeclarators() { *************** *** 594,598 **** { if (!tryNextIs(':')) ! throwFailure("Did not expect a single colon at this stage."); nestedName = "::"; --- 636,643 ---- { if (!tryNextIs(':')) ! { ! // Did not expect a single colon at this stage.... ! return false; ! } nestedName = "::"; *************** *** 606,610 **** std::string identifier; if (!tryReadNextIdentifier(identifier)) ! throwFailure( boost::format("unexpected character: '%1%'.") % *current_ ); if (identifier=="const") --- 651,658 ---- std::string identifier; if (!tryReadNextIdentifier(identifier)) ! { ! // unexpected character: '*current_' ! return false; ! } if (identifier=="const") *************** *** 628,632 **** { parseOperator(declaratorStartIndex); ! return; } --- 676,681 ---- { parseOperator(declaratorStartIndex); ! declaratorEndReached = true; ! break; } *************** *** 635,649 **** { 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 ); } --- 684,698 ---- { if (!skipOverAssignmentInitializer()) ! // failure: Constant expression is not well formed ! return false; ! // @todo: store bit field expression ! } } while (hasNext() && !declaratorEndReached); if (!declaratorEndReached) { ! // failed to find expected declarator separator for declaration 'declaratorNumber' ! return false; } *************** *** 676,690 **** // now go through initializers: ! createAndAddInitializerNode(declaratorNode); declaratorNumber++; } } ! void DeclarationDetailsParser::createAndAddInitializerNode( const ASTNodePtr &declaratorNode ) { if ( !hasNext() ) ! return; Tracker tracker( "DeclarationDetailsParser::createAndAddInitializerNode", *this ); --- 725,743 ---- // now go through initializers: ! if (!createAndAddInitializerNode(declaratorNode)) ! // error in parsing initializer ! return false; ! declaratorNumber++; } + return true; } ! bool DeclarationDetailsParser::createAndAddInitializerNode( const ASTNodePtr &declaratorNode ) { if ( !hasNext() ) ! return true; // simply no intializer Tracker tracker( "DeclarationDetailsParser::createAndAddInitializerNode", *this ); *************** *** 713,720 **** break; case ';': case ',': case '{': ! return; default: -- current_; ! throwFailure( boost::format("unexpected character: '%1%'.") % *current_ ); } --- 766,774 ---- break; case ';': case ',': case '{': ! return true; // end of initializer default: -- current_; ! // unexpected character: '*current_' ! return false; } *************** *** 729,739 **** skipSpaces(); - if ( !hasNext() ) - return; ! if ( *current_ == ';' || *current_ == ',' ) ! ++current_; else ! throwFailure( boost::format("unexpected character: '%1%'.") % *current_ ); } --- 783,794 ---- skipSpaces(); ! if ( !hasNext() || (*current_ != ';' && *current_ != ',') ) ! return false; // expected the final character of the initializer (';' or ',') else ! { ! ++current_; ! return true; ! } } *************** *** 965,976 **** findNextBalanced('(',')'); readUntilNextOf("{;=,"); - backtrackSkippingSpaces(); - - ASTNodePtr declaratorNode = createASTNode( ASTNodeTypes::unparsedDeclarator, - node_, - declaratorStartIndex, - getCurrentIndex() - declaratorStartIndex ); - node_->addChild(declaratorNode); - skipSpaces(); } --- 1020,1023 ---- |