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

Last change on this file since 531 was 531, checked in by dai_9181, 16 years ago

SourceTemplateクラスをLexicalAnalyzerクラスのインナークラスにした

File size: 12.8 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
239UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
240{
241 int i2,i3;
242 char temporary[8192];
243
244 int i=1;
245
246 Procedure::Kind kind = Procedure::Sub;
247 bool isMacro = false;
248 if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
249 if(buffer[i]==ESC_MACRO){
250 isMacro = true;
251 }
252
253 i++;
254
255 bool isCdecl = false;
256 bool isExport = false;
257 while(1){
258 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
259 isCdecl = true;
260
261 i+=2;
262 }
263 else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
264 isExport = true;
265
266 i+=2;
267 }
268 else break;
269 }
270
271 i2=0;
272 if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
273 if(!pobj_c){
274 compiler.errorMessenger.Output(126,NULL,nowLine);
275 return 0;
276 }
277
278 //オペレータの場合
279 temporary[i2++]=buffer[i++];
280 temporary[i2++]=buffer[i++];
281
282 int iCalcId;
283 if(buffer[i]=='='&&buffer[i+1]=='='){
284 iCalcId=CALC_EQUAL;
285 i3=2;
286 }
287 else if(buffer[i]=='='){
288 iCalcId=CALC_SUBSITUATION;
289 i3=1;
290 }
291 else if(buffer[i]=='('){
292 iCalcId=CALC_AS;
293 i3=0;
294 }
295 else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
296 iCalcId=CALC_ARRAY_SET;
297 i3=3;
298 }
299 else if(buffer[i]=='['&&buffer[i+1]==']'){
300 iCalcId=CALC_ARRAY_GET;
301 i3=2;
302 }
303 else{
304 iCalcId=GetCalcId(buffer+i,&i3);
305 i3++;
306 }
307 if(!iCalcId){
308 compiler.errorMessenger.Output(1,NULL,nowLine);
309 return 0;
310 }
311 temporary[i2++]=iCalcId;
312 temporary[i2]=0;
313
314 i+=i3;
315 }
316 else{
317 if(pobj_c){
318 //クラスメンバの場合、デストラクタには~が付くことを考慮
319 if(buffer[i]=='~'){
320 temporary[i2]='~';
321 i++;
322 i2++;
323 }
324 }
325
326 for(;;i++,i2++){
327 if(!IsVariableChar(buffer[i])){
328 temporary[i2]=0;
329 break;
330 }
331 temporary[i2]=buffer[i];
332 }
333
334 char parentName[VN_SIZE], memberName[VN_SIZE];
335 ReferenceKind refKind;
336 if( SplitMemberName( temporary, parentName, memberName, refKind ) )
337 {
338 if( pobj_c )
339 {
340 if( interfaceName )
341 {
342 lstrcpy( interfaceName, parentName );
343 }
344 else
345 {
346 compiler.errorMessenger.OutputFatalError();
347 return NULL;
348 }
349
350 char dummyMemberName[VN_SIZE];
351 if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
352 {
353 compiler.errorMessenger.Output(69,temporary,nowLine);
354 return NULL;
355 }
356 }
357 else
358 {
359 compiler.errorMessenger.Output(68,temporary,nowLine);
360 return NULL;
361 }
362
363 lstrcpy( temporary, memberName );
364 }
365 }
366
367 if( isMacro ){
368 //大文字に変換
369 CharUpper(temporary);
370 }
371
372 if(!pobj_c){
373 //クラスメンバ以外の場合のみ
374 //重複チェック
375
376 if(GetDeclareHash(temporary)){
377 compiler.errorMessenger.Output(15,temporary,nowLine);
378 return 0;
379 }
380 }
381
382 UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport );
383 pUserProc->SetParentClass( pobj_c );
384
385 // 親インターフェイスをセット
386 if( interfaceName && interfaceName[0] )
387 {
388 ::Interface *pTargetInterface = NULL;
389 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
390 {
391 if( pInterface->GetClass().GetName() == interfaceName )
392 {
393 pTargetInterface = pInterface;
394 break;
395 }
396 }
397 pUserProc->SetInterface( pTargetInterface );
398 }
399
400 if(isExport){
401 pUserProc->Using();
402 }
403
404 // パラメータを解析
405 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
406 pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
407
408 pUserProc->_paramStr = buffer + i;
409
410 return pUserProc;
411}
412
413void LexicalAnalyzer::CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
414{
415 extern HANDLE hHeap;
416 int i,i2,i3;
417 char temporary[8192];
418
419 // 名前空間管理
420 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
421 namespaceScopes.clear();
422
423 // Importsされた名前空間の管理
424 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
425 importedNamespaces.clear();
426
427 i=-1;
428 while(1){
429 i++;
430
431 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
432 /* Class ~ End Class
433 Interface ~ End Interface
434 を飛び越す */
435 i3=GetEndXXXCommand(source[i+1]);
436 for(i+=2,i2=0;;i++,i2++){
437 if(source[i]=='\0') break;
438 if(source[i]==1&&source[i+1]==(char)i3){
439 i++;
440 break;
441 }
442 }
443 if(source[i]=='\0') break;
444 continue;
445 }
446
447 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
448 for(i+=2,i2=0;;i2++,i++){
449 if( IsCommandDelimitation( source[i] ) ){
450 temporary[i2]=0;
451 break;
452 }
453 temporary[i2]=source[i];
454 }
455 namespaceScopes.push_back( temporary );
456
457 continue;
458 }
459 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
460 if( namespaceScopes.size() <= 0 ){
461 compiler.errorMessenger.Output(12, "End Namespace", i );
462 }
463 else{
464 namespaceScopes.pop_back();
465 }
466
467 i += 2;
468 continue;
469 }
470 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
471 for(i+=2,i2=0;;i2++,i++){
472 if( IsCommandDelimitation( source[i] ) ){
473 temporary[i2]=0;
474 break;
475 }
476 temporary[i2]=source[i];
477 }
478 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
479 {
480 compiler.errorMessenger.Output(64,temporary,cp );
481 }
482
483 continue;
484 }
485 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
486 importedNamespaces.clear();
487 continue;
488 }
489
490 if(source[i]==1&&source[i+1]==ESC_DECLARE){
491 for(i+=2,i2=0;;i2++,i++){
492 if(source[i]=='\n'){
493 temporary[i2]=0;
494 break;
495 }
496 temporary[i2]=source[i];
497 if(source[i]=='\0') break;
498 }
499 dllProcs.Add(namespaceScopes,temporary,i);
500
501 continue;
502 }
503 if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
504 char statementChar = source[i+1];
505
506 for(i2=0;;i2++,i++){
507 if(IsCommandDelimitation(source[i])){
508 temporary[i2]=0;
509 break;
510 }
511 temporary[i2]=source[i];
512 if(source[i]=='\0') break;
513 }
514
515 UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false );
516 userProcs.Insert( pUserProc, i );
517
518 /* Sub ~ End Sub
519 Function ~ End Function
520 Macro ~ End Macro
521 を飛び越す */
522 char endStatementChar = GetEndXXXCommand( statementChar );
523 for(i2=0;;i++,i2++){
524 if( source[i] == '\0' ) break;
525 if( source[i] == 1 && source[i+1] == endStatementChar ){
526 i++;
527 break;
528 }
529 }
530 if(source[i]=='\0') break;
531 continue;
532 }
533
534 //次の行
535 for(;;i++){
536 if(IsCommandDelimitation(source[i])) break;
537 }
538 if(source[i]=='\0') break;
539 }
540
541 ////////////
542 // 特殊関数
543 ////////////
544 namespaceScopes.clear();
545 importedNamespaces.clear();
546
547 compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
548 sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
549 UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false );
550 userProcs.Insert( pUserProc, i );
551}
Note: See TracBrowser for help on using the repository browser.