From: <net...@us...> - 2003-05-13 08:02:20
|
Update of /cvsroot/cpptool/rfta/src/rftaparser In directory sc8-pr-cvs1:/tmp/cvs-serv22324/src/rftaparser Modified Files: DeclarationDetailsParserTest.cpp DeclarationDetailsParser.h DeclarationDetailsParser.cpp Log Message: -- corrected detection of declarations and added tests for this Index: DeclarationDetailsParserTest.cpp =================================================================== RCS file: /cvsroot/cpptool/rfta/src/rftaparser/DeclarationDetailsParserTest.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** DeclarationDetailsParserTest.cpp 13 May 2003 06:44:33 -0000 1.2 --- DeclarationDetailsParserTest.cpp 13 May 2003 08:02:16 -0000 1.3 *************** *** 133,144 **** DeclarationDetailsParserTest::testParserPass() { /* from the c++ 'bible' */ ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(*e)(int(3));" ); ! ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(f)[4];" ); ! //ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(a);" ); ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "myint (*f)(int) const;" ); ! //ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(a)=4;" ); ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(*b)();" ); ! //ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(x),y,z=7;" ); /* --- 133,145 ---- DeclarationDetailsParserTest::testParserPass() { + ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "mytype v;" ); /* from the c++ 'bible' */ ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(*e)(int(3));" ); ! ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(f)[4];" ); ! ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(a);" ); ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "myint (*f)(int) const;" ); ! ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(a)=4;" ); ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(*b)();" ); ! ASSERT_DETAILS_PARSER_PASS( DeclarationDetailsParser, "T(x),y,z=7;" ); /* Index: DeclarationDetailsParser.h =================================================================== RCS file: /cvsroot/cpptool/rfta/src/rftaparser/DeclarationDetailsParser.h,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** DeclarationDetailsParser.h 10 May 2003 13:10:10 -0000 1.5 --- DeclarationDetailsParser.h 13 May 2003 08:02:16 -0000 1.6 *************** *** 78,81 **** --- 78,82 ---- // ENTRY-Point: bool parseDeclarators(); + bool tryParseSingleDeclarator(); // parser has to stay at the character after the operator keyword... Index: DeclarationDetailsParser.cpp =================================================================== RCS file: /cvsroot/cpptool/rfta/src/rftaparser/DeclarationDetailsParser.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** DeclarationDetailsParser.cpp 13 May 2003 06:44:33 -0000 1.10 --- DeclarationDetailsParser.cpp 13 May 2003 08:02:16 -0000 1.11 *************** *** 407,411 **** // 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)) --- 407,412 ---- // DO SOME LOOK AHEAD TO FIND OUT // a possible declarator that follows: ! // check existence of a next identifier ! // example: "mytype myfct(...)"; std::string identifier; if (tryReadNextIdentifier(identifier)) *************** *** 418,427 **** // example: "mytype (*(*f))(int) const;" // or : "mytype (*f)[4]; ! ! bool maybeBracedDeclarator = false; ! if (tryNextIs('(')) // might be the declarator (e.g. "usertype (*f);" or a parameter (e.g. "int userfct()"; ! { ! findNextBalanced('(',')'); ! maybeBracedDeclarator = true; } // check the characters follow the braces: --- 419,436 ---- // example: "mytype (*(*f))(int) const;" // or : "mytype (*f)[4]; ! // might be a function call too -- see 'tryParseSingleDeclarator' how this is detected ! ! if (*current_ == '(') ! { ! const char * lookahead = current_; ! // might be ! // a declarator (e.g. "T (*f);" or ! // a parameter (e.g. "T (10)"; ! if (tryParseSingleDeclarator()) ! { ! current_ = lookahead; ! return true; ! } else ! return false; } // check the characters follow the braces: *************** *** 439,450 **** std::string seperators=",;=["; - // if braces did occure after the 'identifier' only the following symbols garantee - // a userdefined type (example: "mytype (...)[4]" versus "myfct(...);") - if (maybeBracedDeclarator) - seperators=",;="; bool ret = seperators.find(*current_) == std::string::npos; current_ = rollback; return ret; } --- 448,597 ---- std::string seperators=",;=["; bool ret = seperators.find(*current_) == std::string::npos; current_ = rollback; return ret; + } + + /** + * function does try to read a declarator definition. + */ + bool + DeclarationDetailsParser::tryParseSingleDeclarator() + { + const char * rollback = current_; + int braceLevel = 0; + int identifierCount=0; + + skipSpaces(); + if (*current_ == '(') + { + braceLevel++; + ++current_; + } + + skipSpaces(); + do + { + skipSpaces(); + if (*current_>='0' && *current_<='9') + { + // not a declarator + current_ = rollback; + return false; + } + if (*current_==',' || *current_==';' || *current_=='=') + { + break; + } + // check for an identifier starting at current position: + std::string identifier; + if (tryReadNextIdentifier(identifier)) + { + identifierCount++; + if (identifierCount==1) + continue; + else + break; + } + switch (*current_) + { + + case '*': + case '&': + current_++; + continue; + + case '(': + braceLevel++; + current_++; + continue; + + case ')': + braceLevel--; + current_++; + continue; + + case '[': + current_++; + findNextBalanced('[',']'); + continue; + + default: + // not a declarator + current_ = rollback; + return false; + } + } while (hasNext() && braceLevel!=0); + + // first check for balancing of braces: + if (braceLevel!=0) + { + // not a declarator + current_ = rollback; + return false; + } + skipSpaces(); + + if (identifierCount==0) + { + // check for an identifier starting at current position: + std::string identifier; + if (tryReadNextIdentifier(identifier)) + { + identifierCount++; + } + } + + // the following loop skips over the symbols that are attached on the right hand side of a + // declarator: + // [ ... ] array declarator + // const / throw function declarator + bool doContinue; + do { + doContinue = false; + + std::string identifier; + if (tryReadNextIdentifier(identifier)) + { + if (identifier!="const" && identifier!="throw") + { + // not a declarator + current_ = rollback; + return false; + } + if (identifier=="throw") + { + skipSpaces(); + expect('('); + findNextBalanced('(',')'); + skipSpaces(); + } + doContinue = true; + } + if (*current_=='[') + { + ++current_; + findNextBalanced('[',']'); + skipSpaces(); + doContinue = true; + } + if (*current_=='(') + { + ++current_; + findNextBalanced('(',')'); + skipSpaces(); + doContinue = true; + } + } while (doContinue); + + // check the symbols that can appear after a declarator: + if (*current_==',' || *current_==';' || *current_=='=') + { + return true; + } + // not a declarator + current_ = rollback; + return false; } |