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