source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/LexicalAnalyzer.cpp @ 544

Last change on this file since 544 was 544, checked in by dai_9181, 15 years ago

CollectTypeDefsメソッドからbasbufを排除。

File size: 16.9 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5LexicalAnalyzer::SourceTemplate::SourceTemplate( const std::string &filePath )
6{
7    Jenga::Common::File file = Jenga::Common::File( GetApplicationBaseFullPath( filePath ) );
8    source = file.Read();
9}
10std::string LexicalAnalyzer::SourceTemplate::GetResult( const std::map<std::string,std::string> &values )
11{
12    std::string result = source;
13
14    std::map<std::string,std::string>::const_iterator it = values.begin();
15    while( it != values.end() )
16    {
17        while( true )
18        {
19            std::string::size_type index = result.find( it->first );
20            if( index == std::string::npos )
21            {
22                break;
23            }
24
25            result = result.substr( 0, index ) + it->second + result.substr( index + it->first.length() );
26        }
27        it++;
28    }
29
30    return result;
31}
32
33
34bool LexicalAnalyzer::CollectNamespaces( const char *source, NamespaceScopesCollection &namespaceScopesCollection )
35{
36    int i, i2;
37    char temporary[1024];
38
39    bool isSuccessful = true;
40
41    // 名前空間管理
42    NamespaceScopes namespaceScopes;
43
44    for(i=0;;i++){
45        if(source[i]=='\0') break;
46
47        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
48            for(i+=2,i2=0;;i2++,i++){
49                if( IsCommandDelimitation( source[i] ) ){
50                    temporary[i2]=0;
51                    break;
52                }
53                temporary[i2]=source[i];
54            }
55            namespaceScopes.push_back( temporary );
56
57            if( !namespaceScopesCollection.IsExist( namespaceScopes ) ){
58                namespaceScopesCollection.push_back( namespaceScopes );
59            }
60
61            continue;
62        }
63        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
64            if( namespaceScopes.size() <= 0 ){
65                compiler.errorMessenger.Output( 12, "End Namespace", i );
66                isSuccessful = false;
67            }
68            else{
69                namespaceScopes.pop_back();
70            }
71
72            i += 2;
73            continue;
74        }
75    }
76
77    if( namespaceScopes.size() > 0 ){
78        compiler.errorMessenger.Output( 63, NULL, cp );
79        isSuccessful = false;
80    }
81
82    return isSuccessful;
83}
84
85Symbol LexicalAnalyzer::FullNameToSymbol( const char *fullName )
86{
87    char areaName[VN_SIZE] = "";        //オブジェクト変数
88    char nestName[VN_SIZE] = "";        //入れ子メンバ
89    bool isNest = SplitMemberName( fullName, areaName, nestName );
90
91    return Symbol( NamespaceScopes( areaName ), nestName );
92}
93
94Symbol LexicalAnalyzer::FullNameToSymbol( const std::string &fullName )
95{
96    return FullNameToSymbol( fullName.c_str() );
97}
98
99void LexicalAnalyzer::CollectClassesForNameOnly( const char *source, Classes &classes )
100{
101    int i, i2;
102    char temporary[VN_SIZE];
103
104    // 名前空間管理
105    NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
106    namespaceScopes.clear();
107
108    // Importsされた名前空間の管理
109    NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
110    importedNamespaces.clear();
111
112    for(i=0;;i++){
113        if(source[i]=='\0') break;
114
115        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
116            for(i+=2,i2=0;;i2++,i++){
117                if( IsCommandDelimitation( source[i] ) ){
118                    temporary[i2]=0;
119                    break;
120                }
121                temporary[i2]=source[i];
122            }
123            namespaceScopes.push_back( temporary );
124
125            continue;
126        }
127        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
128            if( namespaceScopes.size() <= 0 ){
129                compiler.errorMessenger.Output(12, "End Namespace", i );
130            }
131            else{
132                namespaceScopes.pop_back();
133            }
134
135            i += 2;
136            continue;
137        }
138        else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
139            for(i+=2,i2=0;;i2++,i++){
140                if( IsCommandDelimitation( source[i] ) ){
141                    temporary[i2]=0;
142                    break;
143                }
144                temporary[i2]=source[i];
145            }
146            if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
147            {
148                compiler.errorMessenger.Output(64,temporary,i );
149            }
150
151            continue;
152        }
153        else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
154            importedNamespaces.clear();
155            continue;
156        }
157
158        if(source[i]==1&&(
159            source[i+1]==ESC_CLASS||
160            source[i+1]==ESC_TYPE||
161            source[i+1]==ESC_INTERFACE
162            ))
163        {
164            int nowLine = i;
165            i += 2;
166
167            Type blittableType;
168            if(memicmp(source+i,"Align(",6)==0){
169                //アラインメント修飾子
170                i+=6;
171                i=JumpStringInPare(source,i)+1;
172            }
173            else if( memicmp( source + i, "Blittable(", 10 ) == 0 ){
174                // Blittable修飾子
175                i+=10;
176                i+=GetStringInPare_RemovePare(temporary,source+i)+1;
177                compiler.StringToType( temporary, blittableType );
178            }
179
180            bool isEnum = false;
181            bool isDelegate = false;
182            if( source[i] == 1 && source[i+1] == ESC_ENUM ){
183                // 列挙型の場合
184                isEnum = true;
185
186                i += 2;
187            }
188            else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
189            {
190                // デリゲートの場合
191                isDelegate = true;
192
193                i += 2;
194            }
195
196            for(i2=0;;i++,i2++){
197                if(!IsVariableChar(source[i])){
198                    temporary[i2]=0;
199                    break;
200                }
201                temporary[i2]=source[i];
202            }
203
204            //クラスを追加
205            CClass *pClass = classes.Add(namespaceScopes, importedNamespaces, temporary,nowLine);
206            if( pClass ){
207                if( source[nowLine+1] == ESC_CLASS ){
208                    if( isEnum )
209                    {
210                        pClass->SetClassType( CClass::Enum );
211                    }
212                    else if( isDelegate )
213                    {
214                        pClass->SetClassType( CClass::Delegate );
215                    }
216                    else{
217                        pClass->SetClassType( CClass::Class );
218                    }
219                }
220                else if( source[nowLine+1] == ESC_INTERFACE ){
221                    pClass->SetClassType( CClass::Interface );
222                }
223                else{
224                    pClass->SetClassType( CClass::Structure );
225                }
226            }
227
228            // Blittable型の場合
229            if( !blittableType.IsNull() ){
230                pClass->SetBlittableType( blittableType );
231
232                // Blittable型として登録
233                compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
234            }
235        }
236    }
237}
238
239void LexicalAnalyzer::AddTypeDef( TypeDefCollection &typeDefs, const NamespaceScopes &namespaceScopes, const std::string &expression, int nowLine )
240{
241    int i;
242    char temporary[VN_SIZE];
243
244    for(i=0;;i++){
245        if(expression[i]=='='||expression[i]=='\0'){
246            temporary[i]=0;
247            break;
248        }
249        temporary[i]=expression[i];
250    }
251
252    if(expression[i]!='='){
253        compiler.errorMessenger.Output(10,"TypeDef",nowLine);
254        return;
255    }
256
257    const char *pTemp=expression.c_str()+i+1;
258
259    //識別文字のエラーチェック(新しい型)
260    i=0;
261    for(;;i++){
262        if(temporary[i]=='\0') break;
263        if( !( IsVariableChar( temporary[i], true) ) ){
264            compiler.errorMessenger.Output(10,"TypeDef",nowLine);
265            return;
266        }
267    }
268
269    //識別文字のエラーチェック(コピー元の型)
270    if(pTemp[0]=='*'&&pTemp[1]==1&&(pTemp[2]==ESC_FUNCTION||pTemp[2]==ESC_SUB)){
271        //関数ポインタ
272        if(pTemp[3]!='('){
273            compiler.errorMessenger.Output(10,"TypeDef",nowLine);
274            return;
275        }
276    }
277    else{
278        i=0;
279        while(pTemp[i]=='*') i++;
280        for(;;i++){
281            if(pTemp[i]=='\0') break;
282            if( !( IsVariableChar( pTemp[i], true) ) )
283            {
284                compiler.errorMessenger.Output(10,"TypeDef",nowLine);
285                return;
286            }
287        }
288    }
289
290    //識別子が重複している場合はエラーにする
291    if(lstrcmp(temporary,pTemp)==0){
292        compiler.errorMessenger.Output(1,NULL,nowLine);
293        return;
294    }
295
296
297
298    //////////////////////////
299    // TypeDef情報を追加
300    //////////////////////////
301
302    Type baseType;
303    if( !compiler.StringToType( pTemp, baseType ) )
304    {
305        compiler.errorMessenger.Output(3, pTemp, nowLine );
306        return;
307    }
308
309    typeDefs.push_back(
310        TypeDef(
311            namespaceScopes,
312            temporary,
313            pTemp,
314            baseType
315        )
316    );
317}
318void LexicalAnalyzer::CollectTypeDefs( const char *source, TypeDefCollection &typeDefs )
319{
320    // 名前空間管理
321    NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
322    namespaceScopes.clear();
323
324    // Importsされた名前空間の管理
325    NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
326    importedNamespaces.clear();
327
328    int i=-1, i2;
329    char temporary[VN_SIZE];
330    while(1){
331
332        i++;
333
334        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
335            for(i+=2,i2=0;;i2++,i++){
336                if( IsCommandDelimitation( source[i] ) ){
337                    temporary[i2]=0;
338                    break;
339                }
340                temporary[i2]=source[i];
341            }
342            namespaceScopes.push_back( temporary );
343
344            continue;
345        }
346        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
347            if( namespaceScopes.size() <= 0 ){
348                compiler.errorMessenger.Output(12, "End Namespace", i );
349            }
350            else{
351                namespaceScopes.pop_back();
352            }
353
354            i += 2;
355            continue;
356        }
357        else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
358            for(i+=2,i2=0;;i2++,i++){
359                if( IsCommandDelimitation( source[i] ) ){
360                    temporary[i2]=0;
361                    break;
362                }
363                temporary[i2]=source[i];
364            }
365            if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
366            {
367                compiler.errorMessenger.Output(64,temporary,i );
368            }
369
370            continue;
371        }
372        else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
373            importedNamespaces.clear();
374            continue;
375        }
376
377        if( source[i]==1 ){
378            char temporary[VN_SIZE];
379            if(source[i+1]==ESC_TYPEDEF){
380                int i2 = 0;
381                for(i+=2;;i2++,i++){
382                    if(source[i]=='\n'){
383                        temporary[i2]=0;
384                        break;
385                    }
386                    temporary[i2]=source[i];
387                    if(source[i]=='\0') break;
388                }
389                AddTypeDef( typeDefs, namespaceScopes, temporary, i );
390
391                continue;
392            }
393            else if( source[i+1] == ESC_CONST && source[i+2] == 1 && source[i+3] == ESC_ENUM ){
394                int i2 = 0;
395                for(i+=4;;i2++,i++){
396                    if(!IsVariableChar(source[i])){
397                        temporary[i2]=0;
398                        break;
399                    }
400                    temporary[i2]=source[i];
401                    if(source[i]=='\0') break;
402                }
403
404                Type baseType;
405                if( !compiler.StringToType( "Long", baseType ) )
406                {
407                    throw;
408                }
409
410                typeDefs.push_back(
411                    TypeDef(
412                        namespaceScopes,
413                        temporary,
414                        "Long",
415                        baseType
416                    )
417                );
418            }
419        }
420
421        //次の行
422        for(;;i++){
423            if(IsCommandDelimitation(source[i])) break;
424        }
425        if(source[i]=='\0') break;
426    }
427}
428
429UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
430{
431    int i2,i3;
432    char temporary[8192];
433
434    int i=1;
435
436    Procedure::Kind kind = Procedure::Sub;
437    bool isMacro = false;
438    if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
439    if(buffer[i]==ESC_MACRO){
440        isMacro = true;
441    }
442
443    i++;
444
445    bool isCdecl = false;
446    bool isExport = false;
447    while(1){
448        if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
449            isCdecl = true;
450
451            i+=2;
452        }
453        else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
454            isExport = true;
455
456            i+=2;
457        }
458        else break;
459    }
460
461    i2=0;
462    if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
463        if(!pobj_c){
464            compiler.errorMessenger.Output(126,NULL,nowLine);
465            return 0;
466        }
467
468        //オペレータの場合
469        temporary[i2++]=buffer[i++];
470        temporary[i2++]=buffer[i++];
471
472        int iCalcId;
473        if(buffer[i]=='='&&buffer[i+1]=='='){
474            iCalcId=CALC_EQUAL;
475            i3=2;
476        }
477        else if(buffer[i]=='='){
478            iCalcId=CALC_SUBSITUATION;
479            i3=1;
480        }
481        else if(buffer[i]=='('){
482            iCalcId=CALC_AS;
483            i3=0;
484        }
485        else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
486            iCalcId=CALC_ARRAY_SET;
487            i3=3;
488        }
489        else if(buffer[i]=='['&&buffer[i+1]==']'){
490            iCalcId=CALC_ARRAY_GET;
491            i3=2;
492        }
493        else{
494            iCalcId=GetCalcId(buffer+i,&i3);
495            i3++;
496        }
497        if(!iCalcId){
498            compiler.errorMessenger.Output(1,NULL,nowLine);
499            return 0;
500        }
501        temporary[i2++]=iCalcId;
502        temporary[i2]=0;
503
504        i+=i3;
505    }
506    else{
507        if(pobj_c){
508            //クラスメンバの場合、デストラクタには~が付くことを考慮
509            if(buffer[i]=='~'){
510                temporary[i2]='~';
511                i++;
512                i2++;
513            }
514        }
515
516        for(;;i++,i2++){
517            if(!IsVariableChar(buffer[i])){
518                temporary[i2]=0;
519                break;
520            }
521            temporary[i2]=buffer[i];
522        }
523
524        char parentName[VN_SIZE], memberName[VN_SIZE];
525        ReferenceKind refKind;
526        if( SplitMemberName( temporary, parentName, memberName, refKind ) )
527        {
528            if( pobj_c )
529            {
530                if( interfaceName )
531                {
532                    lstrcpy( interfaceName, parentName );
533                }
534                else
535                {
536                    compiler.errorMessenger.OutputFatalError();
537                    return NULL;
538                }
539
540                char dummyMemberName[VN_SIZE];
541                if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
542                {
543                    compiler.errorMessenger.Output(69,temporary,nowLine);
544                    return NULL;
545                }
546            }
547            else
548            {
549                compiler.errorMessenger.Output(68,temporary,nowLine);
550                return NULL;
551            }
552
553            lstrcpy( temporary, memberName );
554        }
555    }
556
557    if( isMacro ){
558        //大文字に変換
559        CharUpper(temporary);
560    }
561
562    if(!pobj_c){
563        //クラスメンバ以外の場合のみ
564        //重複チェック
565
566        if(GetDeclareHash(temporary)){
567            compiler.errorMessenger.Output(15,temporary,nowLine);
568            return 0;
569        }
570    }
571
572    UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport );
573    pUserProc->SetParentClass( pobj_c );
574
575    // 親インターフェイスをセット
576    if( interfaceName && interfaceName[0] )
577    {
578        ::Interface *pTargetInterface = NULL;
579        BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
580        {
581            if( pInterface->GetClass().GetName() == interfaceName )
582            {
583                pTargetInterface = pInterface;
584                break;
585            }
586        }
587        pUserProc->SetInterface( pTargetInterface );
588    }
589
590    if(isExport){
591        pUserProc->Using();
592    }
593
594    // パラメータを解析
595    // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
596    pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
597
598    pUserProc->_paramStr = buffer + i;
599
600    return pUserProc;
601}
602
603void LexicalAnalyzer::CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
604{
605    extern HANDLE hHeap;
606    int i,i2,i3;
607    char temporary[8192];
608
609    // 名前空間管理
610    NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
611    namespaceScopes.clear();
612
613    // Importsされた名前空間の管理
614    NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
615    importedNamespaces.clear();
616
617    i=-1;
618    while(1){
619        i++;
620
621        if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
622            /*  Class ~ End Class
623                Interface ~ End Interface
624                を飛び越す           */
625            i3=GetEndXXXCommand(source[i+1]);
626            for(i+=2,i2=0;;i++,i2++){
627                if(source[i]=='\0') break;
628                if(source[i]==1&&source[i+1]==(char)i3){
629                    i++;
630                    break;
631                }
632            }
633            if(source[i]=='\0') break;
634            continue;
635        }
636
637        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
638            for(i+=2,i2=0;;i2++,i++){
639                if( IsCommandDelimitation( source[i] ) ){
640                    temporary[i2]=0;
641                    break;
642                }
643                temporary[i2]=source[i];
644            }
645            namespaceScopes.push_back( temporary );
646
647            continue;
648        }
649        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
650            if( namespaceScopes.size() <= 0 ){
651                compiler.errorMessenger.Output(12, "End Namespace", i );
652            }
653            else{
654                namespaceScopes.pop_back();
655            }
656
657            i += 2;
658            continue;
659        }
660        else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
661            for(i+=2,i2=0;;i2++,i++){
662                if( IsCommandDelimitation( source[i] ) ){
663                    temporary[i2]=0;
664                    break;
665                }
666                temporary[i2]=source[i];
667            }
668            if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
669            {
670                compiler.errorMessenger.Output(64,temporary,cp );
671            }
672
673            continue;
674        }
675        else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
676            importedNamespaces.clear();
677            continue;
678        }
679
680        if(source[i]==1&&source[i+1]==ESC_DECLARE){
681            for(i+=2,i2=0;;i2++,i++){
682                if(source[i]=='\n'){
683                    temporary[i2]=0;
684                    break;
685                }
686                temporary[i2]=source[i];
687                if(source[i]=='\0') break;
688            }
689            dllProcs.Add(namespaceScopes,temporary,i);
690
691            continue;
692        }
693        if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
694            char statementChar = source[i+1];
695
696            for(i2=0;;i2++,i++){
697                if(IsCommandDelimitation(source[i])){
698                    temporary[i2]=0;
699                    break;
700                }
701                temporary[i2]=source[i];
702                if(source[i]=='\0') break;
703            }
704
705            UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false );
706            userProcs.Insert( pUserProc, i );
707
708            /*  Sub ~ End Sub
709                Function ~ End Function
710                Macro ~ End Macro
711                を飛び越す           */
712            char endStatementChar = GetEndXXXCommand( statementChar );
713            for(i2=0;;i++,i2++){
714                if( source[i] == '\0' ) break;
715                if( source[i] == 1 && source[i+1] == endStatementChar ){
716                    i++;
717                    break;
718                }
719            }
720            if(source[i]=='\0') break;
721            continue;
722        }
723
724        //次の行
725        for(;;i++){
726            if(IsCommandDelimitation(source[i])) break;
727        }
728        if(source[i]=='\0') break;
729    }
730
731    ////////////
732    // 特殊関数
733    ////////////
734    namespaceScopes.clear();
735    importedNamespaces.clear();
736
737    compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
738    sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
739    UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false );
740    userProcs.Insert( pUserProc, i );
741}
Note: See TracBrowser for help on using the repository browser.