⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cjparser.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            // 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 + -