📄 cjparser.cpp
字号:
// expressions like "int = 5" are ignored, // since name for paramters is required if ( blocksSkipped == 3 ) { if ( *cur == ')' ) { ++cur; break; } else continue; } pPar->m_InitVal = wxString( blocks[nameBlock], blockSizes[nameBlock] ); nameBlock = nameBlock - 2; // skip '=' token and default value block typeBlock = nameBlock - 1; } // attach comments about the parameter AttachComments( *pPar, blocks[nameBlock] ); // retrieve argument name pPar->m_Name = wxString( blocks[nameBlock], blockSizes[nameBlock] ); // retreive argument type size_t len = blockSizes[ typeBlock ]; len = size_t ( (blocks[ typeBlock ] + len) - blocks[ 0 ] ); pPar->m_Type = wxString( blocks[0], len ); arrange_indirection_tokens_between( pPar->m_Type, pPar->m_Name ); if ( *cur == ')' ) { ++cur; break; } ++cur; // skip comma get_next_token(cur); } while(1); // skip possible whitespace between ')' and following "const" while ( isspace(*cur) ) cur++; // check if it was really a function not a macro, // if so, than it should be terminated with semicolon ';' // or opening implemenetaton bracket '{' char* tok = cur; int tmpLnNo; store_line_no( tmpLnNo ); bool result = true; do { if ( *tok == '{' || *tok == ';' ) { restore_line_no(tmpLnNo); break; } // check for unexpected tokens if ( *tok == '=' || *tok == '0' ) { skip_token(tok); if ( !get_next_token(tok) ) return false; continue; } if ( *tok == '}' ) return false; // if initialization list found if ( *tok == ':' ) { restore_line_no(tmpLnNo); break; } if ( cmp_tokens_fast( tok, "const", 5 ) ) { ((spOperation*)mpCurCtx)->mIsConstant = true; skip_token(tok); if ( !get_next_token(tok) ) return false; continue; } if ( CheckVisibilty( tok ) ) return false; // if next context found if ( is_keyword( tok ) ) return false; skip_token(tok); if ( !get_next_token(tok) ) return false; } while(1); return result;}void CJSourceParser::ParseMemberVar( char*& cur ){ MMemberListT& members = mpCurCtx->GetMembers(); bool firstMember = true; wxString type; // jump to the end of statement // and start collecting same-type varibles // back-to-front towards the type identifier skip_statement( cur ); char* savedPos = cur; int tmpLnNo; store_line_no( tmpLnNo ); --cur; // rewind back to ';' do { spAttribute* pAttr = new spAttribute(); // FOR NOW:: line not is not exact, if member declaration is multiline pAttr->mSrcLineNo = get_line_no(); mpCurCtx->AddMember( pAttr ); pAttr->mVisibility = mCurVis; pAttr->mIsConstant = 0; if ( firstMember ) { firstMember = 0; } skip_token_back( cur ); // attach comments about the attribute AttachComments( *pAttr, cur ); pAttr->m_Name = get_token_str( cur ); // guessing that this going to be variable type skip_next_token_back( cur ); skip_token_back( cur ); pAttr->m_Type = get_token_str( cur ); // if comma, than variable list continues // otherwise the variable type reached - stop if ( *cur == _T('=') ) { // yes, we've mistaken, it was not a identifier, // but it's default value pAttr->m_InitVal = pAttr->m_Name; // skip default value and '=' symbol skip_next_token_back( cur ); skip_token_back( cur ); pAttr->m_Name = get_token_str( cur ); skip_next_token_back( cur ); skip_token_back( cur ); } if ( *cur != ',' ) { type = get_token_str( cur ); break; } } while(1); size_t first = 0; // set up types for all collected (same-type) attributes; while ( first != members.size() - 1 ) { spAttribute* pAttr = members[first++]->CastToAttribute(); if ( !pAttr ) continue; if ( pAttr->m_Type.empty() ) pAttr->m_Type = type; pAttr->mVisibility = mCurVis; if ( !pAttr->m_Name.empty() ) arrange_indirection_tokens_between( pAttr->m_Type, pAttr->m_Name ); } cur = savedPos; restore_line_no( tmpLnNo ); clear_commets_queue();}void CJSourceParser::SkipFunction( char*& cur ){ while ( *cur != '(' && cur < _gSrcEnd ) { if (*cur == 10 ) ++_gLineNo; ++cur; } skip_next_token_back( cur ); // go back and skip function identifier skip_token_back( cur ); // go back and skip return type skip_block( cur ); // now, go ahead and skip whole declaration SkipFunctionBody( cur );}void CJSourceParser::SkipFunctionBody( char*& cur ){ // FIXME:: check for comments and quoted stirngs here bool hasDefinition = false; while( *cur != '{' && *cur != ';' ) { if (*cur == 10 ) ++_gLineNo; ++cur; } if ( *cur == ';' ) { ++cur; } else { hasDefinition = true; skip_scope_block( cur ); // skip the whole imp. } if ( mpCurCtx->GetType() == SP_CTX_OPERATION ) { spOperation& op = *((spOperation*)mpCurCtx); int curOfs = int ( cur - _gSrcStart ); op.mContextLength = curOfs - mpCurCtx->mSrcOffset; op.mHasDefinition = hasDefinition; // separate scope resolution token from the name of operation for( size_t i = 0; i != op.m_Name.length(); ++i ) { if ( op.m_Name[i] == ':' && op.m_Name[i+1] == ':' ) { wxString unscoped( op.m_Name, i+2, op.m_Name.length() - ( i + 2 ) ); op.mScope = wxString( op.m_Name, 0, i ); op.m_Name = unscoped; break; } } }}bool CJSourceParser::CheckVisibilty( char*& cur ){ size_t len = get_token_len( cur ); if ( cmp_tokens_fast( cur, "public:", len ) ) { mCurVis = SP_VIS_PUBLIC; return true; } if ( cmp_tokens_fast( cur, "protected:", len ) ) { mCurVis = SP_VIS_PROTECTED; return true; } if ( cmp_tokens_fast( cur, "private:", len ) ) { mCurVis = SP_VIS_PRIVATE; return true; } return false;}void CJSourceParser::AddClassNode( char*& cur ){ char* ctxStart = cur; wxString classkeyword = get_token_str( cur ); skip_token( cur ); // skip 'class' keyword if ( !get_next_token( cur ) ) return; // in C++ if ( *cur == ':' ) { skip_token( cur ); get_next_token( cur ); } // by default all class members are private mCurVis = SP_VIS_PRIVATE; spClass* pClass = new spClass(); if ( classkeyword == "class" ) pClass->mClassSubType = SP_CLTYPE_CLASS; else if ( classkeyword == "struct" ) { pClass->mClassSubType = SP_CLTYPE_STRUCTURE; mCurVis = SP_VIS_PUBLIC; } else if ( classkeyword == "union" ) { pClass->mClassSubType = SP_CLTYPE_UNION; mCurVis = SP_VIS_PUBLIC; } else if ( classkeyword == "interface" ) pClass->mClassSubType = SP_CLTYPE_INTERFACE; else { pClass->mClassSubType = SP_CLTYPE_INVALID; wxFAIL_MSG("unknown class keyword"); } mpCurCtx->AddMember( pClass ); // attach comments about the class AttachComments( *pClass, cur ); pClass->mSrcLineNo = get_line_no(); pClass->mSrcOffset = int( ctxStart - _gSrcStart ); char* nameTok = cur; pClass->m_Name = get_token_str( cur ); bool isDerived = 0; // DANGER-MACROS:: do { skip_token( cur ); if ( !get_next_token( cur ) ) return; if ( *cur == ':' ) { isDerived = 1; char* tok = cur; int tmpLn; store_line_no( tmpLn ); skip_next_token_back( tok ); skip_token_back( tok ); restore_line_no( tmpLn ); // class name should precend ':' colon, thus // the one which was captured before was // proablty something else (like __dllexport MyClass : ... ) if ( nameTok != tok ) { pClass->m_Name = get_token_str( tok ); } } if ( *cur == '{' ) break; if ( *cur == ',' ) continue; size_t len = get_token_len( cur ); // skip neglectable C++ modifieres if ( cmp_tokens_fast( cur, "public", len ) ) continue; if ( cmp_tokens_fast( cur, "protected", len ) ) continue; if ( cmp_tokens_fast( cur, "private", len ) ) continue; if ( cmp_tokens_fast( cur, "virtual", len ) ) continue; // skip neglectable JAVA modifieres if ( cmp_tokens_fast( cur, "extends", len ) ) { isDerived = 1; continue; } if ( cmp_tokens_fast( cur, "implements", len ) ) { isDerived = 1; continue; } // all we need to know is superclass or interface char* tok = cur; int tmpLn; store_line_no( tmpLn ); skip_token(tok); get_next_token(tok); restore_line_no( tmpLn ); if ( *tok != ':' && *cur != ':' ) pClass->m_SuperClassNames.push_back( wxString( cur, len ) ); } while(1); if ( !isDerived ) { int tmpLn; store_line_no( tmpLn ); while ( pClass->m_SuperClassNames.size() ) pClass->m_SuperClassNames.erase( &pClass->m_SuperClassNames[0] ); char* tok = cur; // some non-obviouse token was following "class" keyword - // we've confused it with class name - thus now we're reverting this mistake skip_next_token_back( tok ); skip_token_back( tok ); pClass->m_Name = get_token_str( tok ); restore_line_no( tmpLn ); } ++cur; // skip opening curly brace pClass->mHeaderLength = ( cur - ctxStart ); // now, enter the class context mpCurCtx = pClass; clear_commets_queue();}void CJSourceParser::AddEnumNode( wxChar*& cur ){ // now the cursor is at "enum" keyword wxChar* start = cur; spEnumeration* pEnum = new spEnumeration(); mpCurCtx->AddMember( pEnum ); pEnum->mSrcLineNo = get_line_no(); AttachComments( *pEnum, cur ); skip_token( cur ); if ( !get_next_token( cur ) ) return; // check if enumeration has got it's identifier if ( *cur != '{' ) { pEnum->m_Name = get_token_str( cur ); } if ( !skip_imp_block( cur ) ) return; get_string_between( start, cur, &pEnum->m_EnumContent ); if ( get_next_token(cur) ) { // check if the identifier if after the {...} block if ( *cur != ';' ) pEnum->m_Name = get_token_str( cur ); } clear_commets_queue();}void CJSourceParser::AddTypeDefNode( wxChar*& cur ){ // now the cursor at the token next to "typedef" keyword if ( !get_next_token(cur) ) return; wxChar* start = cur; spTypeDef* pTDef = new spTypeDef(); mpCurCtx->AddMember( pTDef ); pTDef->mSrcLineNo = get_line_no(); AttachComments( *pTDef, cur ); skip_statement( cur ); int tmpLnNo; store_line_no( tmpLnNo ); wxChar* tok = cur-1; skip_next_token_back( tok ); wxChar* nameEnd = tok; skip_token_back( tok ); wxChar* nameStart = tok; skip_next_token_back( tok ); wxChar* typeEnd = tok; // check if it's function prototype if ( *nameStart == ')' ) { typeEnd = nameStart+1; // skip argument list while ( *nameStart != '(' ) --nameStart; // skip to function type definition while ( *nameStart != ')' ) --nameStart; skip_next_token_back( nameStart ); nameEnd = nameStart; skip_token_back( nameStart ); if ( *nameStart == '*' ) ++nameStart; } get_string_between( start, typeEnd, &pTDef->m_OriginalType ); get_string_between( nameStart, nameEnd, &pTDef->m_Name ); clear_commets_queue(); restore_line_no( tmpLnNo );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -