Ignore:
Timestamp:
Apr 30, 2008, 8:04:04 PM (16 years ago)
Author:
dai_9181
Message:

幾つかの構文解析系の処理をLexicalAnalyzerに実装し直した

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer.cpp

    r508 r511  
    6767    return FullNameToSymbol( fullName.c_str() );
    6868}
     69
     70void LexicalAnalyzer::CollectClassesForNameOnly( const char *source, Classes &classes )
     71{
     72    int i, i2;
     73    char temporary[VN_SIZE];
     74
     75    // 名前空間管理
     76    NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
     77    namespaceScopes.clear();
     78
     79    // Importsされた名前空間の管理
     80    NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
     81    importedNamespaces.clear();
     82
     83    for(i=0;;i++){
     84        if(source[i]=='\0') break;
     85
     86        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
     87            for(i+=2,i2=0;;i2++,i++){
     88                if( IsCommandDelimitation( source[i] ) ){
     89                    temporary[i2]=0;
     90                    break;
     91                }
     92                temporary[i2]=source[i];
     93            }
     94            namespaceScopes.push_back( temporary );
     95
     96            continue;
     97        }
     98        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
     99            if( namespaceScopes.size() <= 0 ){
     100                compiler.errorMessenger.Output(12, "End Namespace", i );
     101            }
     102            else{
     103                namespaceScopes.pop_back();
     104            }
     105
     106            i += 2;
     107            continue;
     108        }
     109        else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
     110            for(i+=2,i2=0;;i2++,i++){
     111                if( IsCommandDelimitation( source[i] ) ){
     112                    temporary[i2]=0;
     113                    break;
     114                }
     115                temporary[i2]=source[i];
     116            }
     117            if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
     118            {
     119                compiler.errorMessenger.Output(64,temporary,i );
     120            }
     121
     122            continue;
     123        }
     124        else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
     125            importedNamespaces.clear();
     126            continue;
     127        }
     128
     129        if(source[i]==1&&(
     130            source[i+1]==ESC_CLASS||
     131            source[i+1]==ESC_TYPE||
     132            source[i+1]==ESC_INTERFACE
     133            ))
     134        {
     135            int nowLine = i;
     136            i += 2;
     137
     138            Type blittableType;
     139            if(memicmp(source+i,"Align(",6)==0){
     140                //アラインメント修飾子
     141                i+=6;
     142                i=JumpStringInPare(source,i)+1;
     143            }
     144            else if( memicmp( source + i, "Blittable(", 10 ) == 0 ){
     145                // Blittable修飾子
     146                i+=10;
     147                i+=GetStringInPare_RemovePare(temporary,source+i)+1;
     148                compiler.StringToType( temporary, blittableType );
     149            }
     150
     151            bool isEnum = false;
     152            bool isDelegate = false;
     153            if( source[i] == 1 && source[i+1] == ESC_ENUM ){
     154                // 列挙型の場合
     155                isEnum = true;
     156
     157                i += 2;
     158            }
     159            else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
     160            {
     161                // デリゲートの場合
     162                isDelegate = true;
     163
     164                i += 2;
     165            }
     166
     167            for(i2=0;;i++,i2++){
     168                if(!IsVariableChar(source[i])){
     169                    temporary[i2]=0;
     170                    break;
     171                }
     172                temporary[i2]=source[i];
     173            }
     174
     175            //クラスを追加
     176            CClass *pClass = classes.Add(namespaceScopes, importedNamespaces, temporary,nowLine);
     177            if( pClass ){
     178                if( source[nowLine+1] == ESC_CLASS ){
     179                    if( isEnum )
     180                    {
     181                        pClass->SetClassType( CClass::Enum );
     182                    }
     183                    else if( isDelegate )
     184                    {
     185                        pClass->SetClassType( CClass::Delegate );
     186                    }
     187                    else{
     188                        pClass->SetClassType( CClass::Class );
     189                    }
     190                }
     191                else if( source[nowLine+1] == ESC_INTERFACE ){
     192                    pClass->SetClassType( CClass::Interface );
     193                }
     194                else{
     195                    pClass->SetClassType( CClass::Structure );
     196                }
     197            }
     198
     199            // Blittable型の場合
     200            if( !blittableType.IsNull() ){
     201                pClass->SetBlittableType( blittableType );
     202
     203                // Blittable型として登録
     204                compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
     205            }
     206        }
     207    }
     208}
     209
     210UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
     211{
     212    int i2,i3;
     213    char temporary[8192];
     214
     215    int i=1;
     216
     217    Procedure::Kind kind = Procedure::Sub;
     218    bool isMacro = false;
     219    if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
     220    if(buffer[i]==ESC_MACRO){
     221        isMacro = true;
     222    }
     223
     224    i++;
     225
     226    bool isCdecl = false;
     227    bool isExport = false;
     228    while(1){
     229        if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
     230            isCdecl = true;
     231
     232            i+=2;
     233        }
     234        else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
     235            isExport = true;
     236
     237            i+=2;
     238        }
     239        else break;
     240    }
     241
     242    i2=0;
     243    if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
     244        if(!pobj_c){
     245            compiler.errorMessenger.Output(126,NULL,nowLine);
     246            return 0;
     247        }
     248
     249        //オペレータの場合
     250        temporary[i2++]=buffer[i++];
     251        temporary[i2++]=buffer[i++];
     252
     253        int iCalcId;
     254        if(buffer[i]=='='&&buffer[i+1]=='='){
     255            iCalcId=CALC_EQUAL;
     256            i3=2;
     257        }
     258        else if(buffer[i]=='='){
     259            iCalcId=CALC_SUBSITUATION;
     260            i3=1;
     261        }
     262        else if(buffer[i]=='('){
     263            iCalcId=CALC_AS;
     264            i3=0;
     265        }
     266        else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
     267            iCalcId=CALC_ARRAY_SET;
     268            i3=3;
     269        }
     270        else if(buffer[i]=='['&&buffer[i+1]==']'){
     271            iCalcId=CALC_ARRAY_GET;
     272            i3=2;
     273        }
     274        else{
     275            iCalcId=GetCalcId(buffer+i,&i3);
     276            i3++;
     277        }
     278        if(!iCalcId){
     279            compiler.errorMessenger.Output(1,NULL,nowLine);
     280            return 0;
     281        }
     282        temporary[i2++]=iCalcId;
     283        temporary[i2]=0;
     284
     285        i+=i3;
     286    }
     287    else{
     288        if(pobj_c){
     289            //クラスメンバの場合、デストラクタには~が付くことを考慮
     290            if(buffer[i]=='~'){
     291                temporary[i2]='~';
     292                i++;
     293                i2++;
     294            }
     295        }
     296
     297        for(;;i++,i2++){
     298            if(!IsVariableChar(buffer[i])){
     299                temporary[i2]=0;
     300                break;
     301            }
     302            temporary[i2]=buffer[i];
     303        }
     304
     305        char parentName[VN_SIZE], memberName[VN_SIZE];
     306        ReferenceKind refKind;
     307        if( SplitMemberName( temporary, parentName, memberName, refKind ) )
     308        {
     309            if( pobj_c )
     310            {
     311                if( interfaceName )
     312                {
     313                    lstrcpy( interfaceName, parentName );
     314                }
     315                else
     316                {
     317                    compiler.errorMessenger.OutputFatalError();
     318                    return NULL;
     319                }
     320
     321                char dummyMemberName[VN_SIZE];
     322                if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
     323                {
     324                    compiler.errorMessenger.Output(69,temporary,nowLine);
     325                    return NULL;
     326                }
     327            }
     328            else
     329            {
     330                compiler.errorMessenger.Output(68,temporary,nowLine);
     331                return NULL;
     332            }
     333
     334            lstrcpy( temporary, memberName );
     335        }
     336    }
     337
     338    if( isMacro ){
     339        //大文字に変換
     340        CharUpper(temporary);
     341    }
     342
     343    if(!pobj_c){
     344        //クラスメンバ以外の場合のみ
     345        //重複チェック
     346
     347        if(GetDeclareHash(temporary)){
     348            compiler.errorMessenger.Output(15,temporary,nowLine);
     349            return 0;
     350        }
     351    }
     352
     353    UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport );
     354    pUserProc->SetParentClass( pobj_c );
     355
     356    // 親インターフェイスをセット
     357    if( interfaceName && interfaceName[0] )
     358    {
     359        ::Interface *pTargetInterface = NULL;
     360        BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
     361        {
     362            if( pInterface->GetClass().GetName() == interfaceName )
     363            {
     364                pTargetInterface = pInterface;
     365                break;
     366            }
     367        }
     368        pUserProc->SetInterface( pTargetInterface );
     369    }
     370
     371    if(isExport){
     372        pUserProc->Using();
     373    }
     374
     375    // パラメータを解析
     376    // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
     377    pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
     378
     379    pUserProc->_paramStr = buffer + i;
     380
     381    return pUserProc;
     382}
     383
     384void LexicalAnalyzer::CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
     385{
     386    extern HANDLE hHeap;
     387    int i,i2,i3;
     388    char temporary[8192];
     389
     390    // 名前空間管理
     391    NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
     392    namespaceScopes.clear();
     393
     394    // Importsされた名前空間の管理
     395    NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
     396    importedNamespaces.clear();
     397
     398    i=-1;
     399    while(1){
     400        i++;
     401
     402        if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
     403            /*  Class ~ End Class
     404                Interface ~ End Interface
     405                を飛び越す           */
     406            i3=GetEndXXXCommand(source[i+1]);
     407            for(i+=2,i2=0;;i++,i2++){
     408                if(source[i]=='\0') break;
     409                if(source[i]==1&&source[i+1]==(char)i3){
     410                    i++;
     411                    break;
     412                }
     413            }
     414            if(source[i]=='\0') break;
     415            continue;
     416        }
     417
     418        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
     419            for(i+=2,i2=0;;i2++,i++){
     420                if( IsCommandDelimitation( source[i] ) ){
     421                    temporary[i2]=0;
     422                    break;
     423                }
     424                temporary[i2]=source[i];
     425            }
     426            namespaceScopes.push_back( temporary );
     427
     428            continue;
     429        }
     430        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
     431            if( namespaceScopes.size() <= 0 ){
     432                compiler.errorMessenger.Output(12, "End Namespace", i );
     433            }
     434            else{
     435                namespaceScopes.pop_back();
     436            }
     437
     438            i += 2;
     439            continue;
     440        }
     441        else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
     442            for(i+=2,i2=0;;i2++,i++){
     443                if( IsCommandDelimitation( source[i] ) ){
     444                    temporary[i2]=0;
     445                    break;
     446                }
     447                temporary[i2]=source[i];
     448            }
     449            if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
     450            {
     451                compiler.errorMessenger.Output(64,temporary,cp );
     452            }
     453
     454            continue;
     455        }
     456        else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
     457            importedNamespaces.clear();
     458            continue;
     459        }
     460
     461        if(source[i]==1&&source[i+1]==ESC_DECLARE){
     462            for(i+=2,i2=0;;i2++,i++){
     463                if(source[i]=='\n'){
     464                    temporary[i2]=0;
     465                    break;
     466                }
     467                temporary[i2]=source[i];
     468                if(source[i]=='\0') break;
     469            }
     470            dllProcs.Add(namespaceScopes,temporary,i);
     471
     472            continue;
     473        }
     474        if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
     475            char statementChar = source[i+1];
     476
     477            for(i2=0;;i2++,i++){
     478                if(IsCommandDelimitation(source[i])){
     479                    temporary[i2]=0;
     480                    break;
     481                }
     482                temporary[i2]=source[i];
     483                if(source[i]=='\0') break;
     484            }
     485
     486            UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false );
     487            userProcs.Insert( pUserProc, i );
     488
     489            /*  Sub ~ End Sub
     490                Function ~ End Function
     491                Macro ~ End Macro
     492                を飛び越す           */
     493            char endStatementChar = GetEndXXXCommand( statementChar );
     494            for(i2=0;;i++,i2++){
     495                if( source[i] == '\0' ) break;
     496                if( source[i] == 1 && source[i+1] == endStatementChar ){
     497                    i++;
     498                    break;
     499                }
     500            }
     501            if(source[i]=='\0') break;
     502            continue;
     503        }
     504
     505        //次の行
     506        for(;;i++){
     507            if(IsCommandDelimitation(source[i])) break;
     508        }
     509        if(source[i]=='\0') break;
     510    }
     511
     512    ////////////
     513    // 特殊関数
     514    ////////////
     515    namespaceScopes.clear();
     516    importedNamespaces.clear();
     517
     518    compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
     519    sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
     520    UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false );
     521    userProcs.Insert( pUserProc, i );
     522}
Note: See TracChangeset for help on using the changeset viewer.