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 ----
|