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, 16 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.