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

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

CollectTypeDefsメソッドをLexicalAnalyzerクラスに移動した。

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        extern char *basbuf;
332
333        i++;
334
335        if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){
336            for(i+=2,i2=0;;i2++,i++){
337                if( IsCommandDelimitation( basbuf[i] ) ){
338                    temporary[i2]=0;
339                    break;
340                }
341                temporary[i2]=basbuf[i];
342            }
343            namespaceScopes.push_back( temporary );
344
345            continue;
346        }
347        else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){
348            if( namespaceScopes.size() <= 0 ){
349                compiler.errorMessenger.Output(12, "End Namespace", i );
350            }
351            else{
352                namespaceScopes.pop_back();
353            }
354
355            i += 2;
356            continue;
357        }
358        else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){
359            for(i+=2,i2=0;;i2++,i++){
360                if( IsCommandDelimitation( basbuf[i] ) ){
361                    temporary[i2]=0;
362                    break;
363                }
364                temporary[i2]=basbuf[i];
365            }
366            if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
367            {
368                compiler.errorMessenger.Output(64,temporary,i );
369            }
370
371            continue;
372        }
373        else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
374            importedNamespaces.clear();
375            continue;
376        }
377
378        if( basbuf[i]==1 ){
379            char temporary[VN_SIZE];
380            if(basbuf[i+1]==ESC_TYPEDEF){
381                int i2 = 0;
382                for(i+=2;;i2++,i++){
383                    if(basbuf[i]=='\n'){
384                        temporary[i2]=0;
385                        break;
386                    }
387                    temporary[i2]=basbuf[i];
388                    if(basbuf[i]=='\0') break;
389                }
390                AddTypeDef( typeDefs, namespaceScopes, temporary, i );
391
392                continue;
393            }
394            else if( basbuf[i+1] == ESC_CONST && basbuf[i+2] == 1 && basbuf[i+3] == ESC_ENUM ){
395                int i2 = 0;
396                for(i+=4;;i2++,i++){
397                    if(!IsVariableChar(basbuf[i])){
398                        temporary[i2]=0;
399                        break;
400                    }
401                    temporary[i2]=basbuf[i];
402                    if(basbuf[i]=='\0') break;
403                }
404
405                Type baseType;
406                if( !compiler.StringToType( "Long", baseType ) )
407                {
408                    throw;
409                }
410
411                typeDefs.push_back(
412                    TypeDef(
413                        namespaceScopes,
414                        temporary,
415                        "Long",
416                        baseType
417                    )
418                );
419            }
420        }
421
422        //次の行
423        for(;;i++){
424            if(IsCommandDelimitation(basbuf[i])) break;
425        }
426        if(basbuf[i]=='\0') break;
427    }
428}
429
430UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
431{
432    int i2,i3;
433    char temporary[8192];
434
435    int i=1;
436
437    Procedure::Kind kind = Procedure::Sub;
438    bool isMacro = false;
439    if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
440    if(buffer[i]==ESC_MACRO){
441        isMacro = true;
442    }
443
444    i++;
445
446    bool isCdecl = false;
447    bool isExport = false;
448    while(1){
449        if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
450            isCdecl = true;
451
452            i+=2;
453        }
454        else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
455            isExport = true;
456
457            i+=2;
458        }
459        else break;
460    }
461
462    i2=0;
463    if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
464        if(!pobj_c){
465            compiler.errorMessenger.Output(126,NULL,nowLine);
466            return 0;
467        }
468
469        //オペレータの場合
470        temporary[i2++]=buffer[i++];
471        temporary[i2++]=buffer[i++];
472
473        int iCalcId;
474        if(buffer[i]=='='&&buffer[i+1]=='='){
475            iCalcId=CALC_EQUAL;
476            i3=2;
477        }
478        else if(buffer[i]=='='){
479            iCalcId=CALC_SUBSITUATION;
480            i3=1;
481        }
482        else if(buffer[i]=='('){
483            iCalcId=CALC_AS;
484            i3=0;
485        }
486        else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
487            iCalcId=CALC_ARRAY_SET;
488            i3=3;
489        }
490        else if(buffer[i]=='['&&buffer[i+1]==']'){
491            iCalcId=CALC_ARRAY_GET;
492            i3=2;
493        }
494        else{
495            iCalcId=GetCalcId(buffer+i,&i3);
496            i3++;
497        }
498        if(!iCalcId){
499            compiler.errorMessenger.Output(1,NULL,nowLine);
500            return 0;
501        }
502        temporary[i2++]=iCalcId;
503        temporary[i2]=0;
504
505        i+=i3;
506    }
507    else{
508        if(pobj_c){
509            //クラスメンバの場合、デストラクタには~が付くことを考慮
510            if(buffer[i]=='~'){
511                temporary[i2]='~';
512                i++;
513                i2++;
514            }
515        }
516
517        for(;;i++,i2++){
518            if(!IsVariableChar(buffer[i])){
519                temporary[i2]=0;
520                break;
521            }
522            temporary[i2]=buffer[i];
523        }
524
525        char parentName[VN_SIZE], memberName[VN_SIZE];
526        ReferenceKind refKind;
527        if( SplitMemberName( temporary, parentName, memberName, refKind ) )
528        {
529            if( pobj_c )
530            {
531                if( interfaceName )
532                {
533                    lstrcpy( interfaceName, parentName );
534                }
535                else
536                {
537                    compiler.errorMessenger.OutputFatalError();
538                    return NULL;
539                }
540
541                char dummyMemberName[VN_SIZE];
542                if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
543                {
544                    compiler.errorMessenger.Output(69,temporary,nowLine);
545                    return NULL;
546                }
547            }
548            else
549            {
550                compiler.errorMessenger.Output(68,temporary,nowLine);
551                return NULL;
552            }
553
554            lstrcpy( temporary, memberName );
555        }
556    }
557
558    if( isMacro ){
559        //大文字に変換
560        CharUpper(temporary);
561    }
562
563    if(!pobj_c){
564        //クラスメンバ以外の場合のみ
565        //重複チェック
566
567        if(GetDeclareHash(temporary)){
568            compiler.errorMessenger.Output(15,temporary,nowLine);
569            return 0;
570        }
571    }
572
573    UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport );
574    pUserProc->SetParentClass( pobj_c );
575
576    // 親インターフェイスをセット
577    if( interfaceName && interfaceName[0] )
578    {
579        ::Interface *pTargetInterface = NULL;
580        BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
581        {
582            if( pInterface->GetClass().GetName() == interfaceName )
583            {
584                pTargetInterface = pInterface;
585                break;
586            }
587        }
588        pUserProc->SetInterface( pTargetInterface );
589    }
590
591    if(isExport){
592        pUserProc->Using();
593    }
594
595    // パラメータを解析
596    // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
597    pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
598
599    pUserProc->_paramStr = buffer + i;
600
601    return pUserProc;
602}
603
604void LexicalAnalyzer::CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
605{
606    extern HANDLE hHeap;
607    int i,i2,i3;
608    char temporary[8192];
609
610    // 名前空間管理
611    NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
612    namespaceScopes.clear();
613
614    // Importsされた名前空間の管理
615    NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
616    importedNamespaces.clear();
617
618    i=-1;
619    while(1){
620        i++;
621
622        if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
623            /*  Class ~ End Class
624                Interface ~ End Interface
625                を飛び越す           */
626            i3=GetEndXXXCommand(source[i+1]);
627            for(i+=2,i2=0;;i++,i2++){
628                if(source[i]=='\0') break;
629                if(source[i]==1&&source[i+1]==(char)i3){
630                    i++;
631                    break;
632                }
633            }
634            if(source[i]=='\0') break;
635            continue;
636        }
637
638        if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
639            for(i+=2,i2=0;;i2++,i++){
640                if( IsCommandDelimitation( source[i] ) ){
641                    temporary[i2]=0;
642                    break;
643                }
644                temporary[i2]=source[i];
645            }
646            namespaceScopes.push_back( temporary );
647
648            continue;
649        }
650        else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
651            if( namespaceScopes.size() <= 0 ){
652                compiler.errorMessenger.Output(12, "End Namespace", i );
653            }
654            else{
655                namespaceScopes.pop_back();
656            }
657
658            i += 2;
659            continue;
660        }
661        else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
662            for(i+=2,i2=0;;i2++,i++){
663                if( IsCommandDelimitation( source[i] ) ){
664                    temporary[i2]=0;
665                    break;
666                }
667                temporary[i2]=source[i];
668            }
669            if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
670            {
671                compiler.errorMessenger.Output(64,temporary,cp );
672            }
673
674            continue;
675        }
676        else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
677            importedNamespaces.clear();
678            continue;
679        }
680
681        if(source[i]==1&&source[i+1]==ESC_DECLARE){
682            for(i+=2,i2=0;;i2++,i++){
683                if(source[i]=='\n'){
684                    temporary[i2]=0;
685                    break;
686                }
687                temporary[i2]=source[i];
688                if(source[i]=='\0') break;
689            }
690            dllProcs.Add(namespaceScopes,temporary,i);
691
692            continue;
693        }
694        if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
695            char statementChar = source[i+1];
696
697            for(i2=0;;i2++,i++){
698                if(IsCommandDelimitation(source[i])){
699                    temporary[i2]=0;
700                    break;
701                }
702                temporary[i2]=source[i];
703                if(source[i]=='\0') break;
704            }
705
706            UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false );
707            userProcs.Insert( pUserProc, i );
708
709            /*  Sub ~ End Sub
710                Function ~ End Function
711                Macro ~ End Macro
712                を飛び越す           */
713            char endStatementChar = GetEndXXXCommand( statementChar );
714            for(i2=0;;i++,i2++){
715                if( source[i] == '\0' ) break;
716                if( source[i] == 1 && source[i+1] == endStatementChar ){
717                    i++;
718                    break;
719                }
720            }
721            if(source[i]=='\0') break;
722            continue;
723        }
724
725        //次の行
726        for(;;i++){
727            if(IsCommandDelimitation(source[i])) break;
728        }
729        if(source[i]=='\0') break;
730    }
731
732    ////////////
733    // 特殊関数
734    ////////////
735    namespaceScopes.clear();
736    importedNamespaces.clear();
737
738    compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
739    sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
740    UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false );
741    userProcs.Insert( pUserProc, i );
742}
Note: See TracBrowser for help on using the repository browser.