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

📄 cjparser.cpp

📁 wxGTK 是 wxWidgets 的 linux GTK+ (>2.2.3)版本。wxWidgets 是一个跨平台的 GUI 框架
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// "reversed" versions of skip_token() and get_next_token()static inline void skip_token_back( char*& cur ){    // FIXME:: now, when moving backwards, neither strings nor    //         comment blocks are checked    --cur; // skip to the trailing character    if ( *cur == ',' ||         *cur == ')' ||         *cur == '('       )       return;    for( ; cur < _gSrcEnd ; --cur )    {        switch ( *cur )        {            case ' ' : break;            case '\t': break;            case 13  : break;            case 10  : break;            case ',' : break;            case '(' : break;            default : continue;        };        break;    }    ++cur; // get to the leading character of the token}static inline void skip_next_token_back( char*& cur ){    --cur; // skip leading character of the current token    if ( *cur == ',' ||         *cur == ')' ||         *cur == '('       )    {       ++cur;       return;    }    for( ; cur < _gSrcEnd; --cur )    {        switch ( *cur )        {            case ' ' : continue;            case '\t': continue;            case 13  : continue;            case 10  : continue;            case ',' : continue;            case '(' : continue;            default : break;        };        break;    }    ++cur; // position after the trailing charcter of the prev token}static wxString get_token_str( char* cur ){    return wxString( cur, get_token_len( cur ) );}// skips token or whole expression which may have// nested  expressions between '(' ')' brackets.//// Upon return, the cursor points to the terminating bracket ')',//// Return value is the size of the blockstatic size_t skip_block( char*& cur ){    size_t level = 0; // nesting level    char* start = cur;    // NOTE:: assumed that block not necessarely starts    //        with bracket rightaway    if ( *cur == '(' )    {        ++level;    }    do    {        skip_token( cur );        char* savedPos = cur;        int tmpLnNo;        store_line_no( tmpLnNo );        get_next_token( cur );        if ( cur >= _gSrcEnd ) return 0;        if ( *cur == '(' )        {            ++level;        }        else        if ( *cur == ')' )        {            if ( level == 0 )            {                cur = savedPos;                restore_line_no( tmpLnNo );                return size_t(cur-start);            }            --level;            if ( level == 0 )            {                ++cur;                // QUICK-HACK::to easily handle function prototypes ,                // it works, besause theoretically there should                // be no cast-expressions in non-implementation                // scope (e.g. "time( (long*)(ptr+1) )" should not                // appear in the declarations, thus it is most likelly                // for the ")(" fragment to be within a function                // prototype in the declarations scope                if ( *cur == '(' )                {                    ++level;                    continue;                }                else return size_t(cur-start);            }        }        else        {            if ( level == 0 )            {                cur = savedPos;                restore_line_no( tmpLnNo );                return size_t(cur-start);            }        }    } while(1);}// returns 0, if end of source reachedstatic inline bool skip_imp_block( char*& cur ){    while( *cur != '{' && cur < _gSrcEnd )    {        skip_token( cur );        if ( !get_next_token( cur ) ) return false;    }    while( *cur != '}' && cur < _gSrcEnd )    {        skip_token( cur );        if ( !get_next_token( cur ) ) return false;    }    ++cur;    return true;}static bool is_class_token( char*& cur ){    // FIXME:: the below mess should be cleaned in it's entirely    if ( *cur == 'i' )        if ( *(cur+1) == 'n' )            return cmp_tokens_fast( cur, "interface", 9 );    if ( *cur == 'c' )        if ( *(cur+1) == 'l' )            return cmp_tokens_fast( cur, "class", 5 );    if ( *cur == 's' )        if ( *(cur+1) == 't' )            return cmp_tokens_fast( cur, "struct", 6 );    if ( *cur == 'u' )        if ( *(cur+1) == 'n' )            return cmp_tokens_fast( cur, "union", 5 );    return false;}inline static bool is_forward_decl( char* cur ){    do    {        switch( *cur )        {            case ':' : return false;            case '{' : return false;            case '(' : return false;            case ';' : return true;            default : break;        };        ++cur;    } while (cur < _gSrcEnd); // prevent running out of bounds    return false;}inline static bool is_function( char* cur, bool& isAMacro ){    isAMacro = false;    int tmpLnNo;    store_line_no( tmpLnNo );    // NOTE:: comments and quoted strings are not checked here    // first,check for "single-line hanginging macros" like:    // ___UNICODE    //    char* eol = cur;    skip_to_eol( eol );    skip_token( cur );    get_next_token( cur );    if ( cur > eol )    {        isAMacro = true;        restore_line_no( tmpLnNo );        return true;    }    // it's not a macro, go to the begining of arg. list    do    {        // if bracket found, it's a function or a begining        // of some macro        if ( *cur == '(' )        {            restore_line_no( tmpLnNo );            return true;        }        // end of statement found without any brackets in it        // - it cannot be a function        if ( *cur == ';' )        {            restore_line_no( tmpLnNo );            return false;        }        ++cur;    } while( cur < _gSrcEnd);    isAMacro = 1;    restore_line_no( tmpLnNo );    return false;}// upon return the cursor is positioned after the// terminating curly bracestatic inline void skip_scope_block( char*& cur ){    size_t level = 0;    for( ; cur < _gSrcEnd ; ++cur )        switch( *cur )        {            case '/' : skip_comments( cur );                       --cur;                       continue;            case '"' : skip_quoted_string( cur );                       --cur;                       continue;            case '{' : ++level;                       continue;            case '}'  :--level;                       if ( level == 0 )                       {                           ++cur; // skip final closing curly brace                           return;                       }            case 10 : ++_gLineNo; continue;            default : continue;        };}// moves tokens like '*' '**', '***', '&' from the name// to the typestatic void arrange_indirection_tokens_between( wxString& type,                                                wxString& identifier ){    // TBD:: FIXME:: return value of operators !    while ( identifier[0u] == _T('*') ||            identifier[0u] == _T('&')          )    {        type += identifier[0u];        identifier.erase(0,1);        if ( !identifier.length() ) return;    }}// the only function where multi-lang keyword map is accessedstatic bool is_keyword( char* cur ){    size_t len = get_token_len( cur );    // put a terminating zero after the given token    char tmp = *(cur + len);    *(cur+len) = '\0';    KeywordMapT::iterator i;    i = __gMultiLangMap.find( cur );    // restore original character suppresed by terminating zero    *(cur + len) = tmp;    return i == __gMultiLangMap.end() ? false : true;}static inline void get_string_between( wxChar* start, wxChar* end,                                       wxString* pStr ){    char saved = *end;    *end  = _T('\0');    *pStr = start;    *end  = saved;}static wxChar* set_comment_text( wxString& text, wxChar* start ){    wxChar* end = start;    // to avoid poluting the queue with this comment    _gLastSuppresedComment = start;    skip_comments( end );    if ( *(end-1) == _T('/') )        end -= 2;    start += 2;    // skip multiple leading '/''s or '*''s    while( *start == _T('/') && start < end ) ++start;    while( *start == _T('*') && start < end ) ++start;    get_string_between( start, end, &text );    return end;}/***** Implementation for class CJSourceParser *****/CJSourceParser::CJSourceParser( bool collectCommnets, bool collectMacros )    : mpStart(0),      mpEnd(0),      mpCurCtx( 0 ),      mCommentsOn( collectCommnets ),      mMacrosOn  ( collectMacros ){    check_keyword_map();}spFile* CJSourceParser::Parse( char* start, char* end ){    // set up state variables    mCurVis       = SP_VIS_PRIVATE;    spFile* pTopCtx = new spFile();    mpCurCtx        = pTopCtx;    mIsVirtual    = 0;    mIsTemplate   = 0;    mNestingLevel = 0;    m_cur = start;    mpStart = start;    mpEnd   = end;    _gSrcEnd   = mpEnd; // let all the C-functions "smell" the end of file    _gSrcStart = start;    _gLineNo   = 0;    clear_commets_queue();    // main parsing loop    do    {        if ( !get_next_token( m_cur ) )            // end of source reached            return pTopCtx;        if ( memcmp( m_cur, "ScriptSection( const string&",                     strlen( "ScriptSection( const string&" )                   ) == 0            )        {            // int o = 0;            // ++o;        }        switch (*m_cur)        {            case '#' :                {                    AddMacroNode( m_cur );                    continue;                }            case ':' :                {                    skip_token( m_cur );                    continue;                }            case ';' :                {                    skip_token( m_cur );                    continue;                }            case ')' :                {                    skip_token( m_cur );                    continue;                }            case '=' :                {                    skip_token( m_cur );                    continue;                }            default: break;        }        // 'const' is a part of the return type, not a keyword here        if ( strncmp(m_cur, "const", 5) != 0 && is_keyword( m_cur ) )        {            // parses, token, if token identifies            // the container context (e.g. class/namespace)            // the corresponding context object is created            // and set as current context            ParseKeyword( m_cur );            continue;        }        if ( *m_cur >= _T('0') && *m_cur <= _T('9') )        {            skip_token( m_cur );            continue;        }        if ( *m_cur == _T('}') )        {            if ( mCurCtxType != SP_CTX_CLASS )            {                // FOR NOW:: disable the below assertion                // DBG:: unexpected closing-bracket found                //ASSERT(0);                skip_token( m_cur ); // just skip it                continue;            }            if ( mpCurCtx->GetType() == SP_CTX_CLASS )            {                int curOfs = ( (m_cur+1) - _gSrcStart );                mpCurCtx->mContextLength = ( curOfs - mpCurCtx->mSrcOffset );            }            --mNestingLevel;            // terminate operation/class/namespace context            // TBD:: check if it's really this type of context            wxASSERT( mpCurCtx );            mpCurCtx = mpCurCtx->GetOutterContext();            wxASSERT( mpCurCtx );            if ( mNestingLevel == 0 )            {                mCurCtxType = SP_CTX_FILE;                // not-nested class delclaration finished,                // rest template flag in any case                mIsTemplate = 0;            }            skip_token( m_cur );            continue;        }        bool isAMacro = false;        if ( is_function( m_cur, isAMacro ) )        {            if ( isAMacro )            {                skip_token( m_cur );                continue;            }            char* savedPos = m_cur;            int tmpLnNo;            store_line_no( tmpLnNo );            wxUnusedVar( tmpLnNo );            isAMacro = false;            if ( !ParseNameAndRetVal( m_cur, isAMacro ) )            {                if ( !isAMacro )                {                    m_cur = savedPos;                    SkipFunction( m_cur );                }                continue;            }            if ( !ParseArguments( m_cur ) )            {                // failure while parsing arguments,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -