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

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

幾つかの構文解析系の処理をLexicalAnalyzerに実装し直した

File size: 12.0 KB
Line 
1#include "stdafx.h"
2
3using namespace ActiveBasic::Compiler;
4
5bool LexicalAnalyzer::CollectNamespaces( const char *source, NamespaceScopesCollection &namespaceScopesCollection )
6{
7 int i, i2;
8 char temporary[1024];
9
10 bool isSuccessful = true;
11
12 // 名前空間管理
13 NamespaceScopes namespaceScopes;
14
15 for(i=0;;i++){
16 if(source[i]=='\0') break;
17
18 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
19 for(i+=2,i2=0;;i2++,i++){
20 if( IsCommandDelimitation( source[i] ) ){
21 temporary[i2]=0;
22 break;
23 }
24 temporary[i2]=source[i];
25 }
26 namespaceScopes.push_back( temporary );
27
28 if( !namespaceScopesCollection.IsExist( namespaceScopes ) ){
29 namespaceScopesCollection.push_back( namespaceScopes );
30 }
31
32 continue;
33 }
34 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
35 if( namespaceScopes.size() <= 0 ){
36 compiler.errorMessenger.Output( 12, "End Namespace", i );
37 isSuccessful = false;
38 }
39 else{
40 namespaceScopes.pop_back();
41 }
42
43 i += 2;
44 continue;
45 }
46 }
47
48 if( namespaceScopes.size() > 0 ){
49 compiler.errorMessenger.Output( 63, NULL, cp );
50 isSuccessful = false;
51 }
52
53 return isSuccessful;
54}
55
56Symbol LexicalAnalyzer::FullNameToSymbol( const char *fullName )
57{
58 char areaName[VN_SIZE] = ""; //オブジェクト変数
59 char nestName[VN_SIZE] = ""; //入れ子メンバ
60 bool isNest = SplitMemberName( fullName, areaName, nestName );
61
62 return Symbol( NamespaceScopes( areaName ), nestName );
63}
64
65Symbol LexicalAnalyzer::FullNameToSymbol( const std::string &fullName )
66{
67 return FullNameToSymbol( fullName.c_str() );
68}
69
70void LexicalAnalyzer::CollectClassesForNameOnly( const char *source, Classes &classes )
71{
72 int i, i2;
73 char temporary[VN_SIZE];
74
75 // 名前空間管理
76 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
77 namespaceScopes.clear();
78
79 // Importsされた名前空間の管理
80 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
81 importedNamespaces.clear();
82
83 for(i=0;;i++){
84 if(source[i]=='\0') break;
85
86 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
87 for(i+=2,i2=0;;i2++,i++){
88 if( IsCommandDelimitation( source[i] ) ){
89 temporary[i2]=0;
90 break;
91 }
92 temporary[i2]=source[i];
93 }
94 namespaceScopes.push_back( temporary );
95
96 continue;
97 }
98 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
99 if( namespaceScopes.size() <= 0 ){
100 compiler.errorMessenger.Output(12, "End Namespace", i );
101 }
102 else{
103 namespaceScopes.pop_back();
104 }
105
106 i += 2;
107 continue;
108 }
109 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
110 for(i+=2,i2=0;;i2++,i++){
111 if( IsCommandDelimitation( source[i] ) ){
112 temporary[i2]=0;
113 break;
114 }
115 temporary[i2]=source[i];
116 }
117 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
118 {
119 compiler.errorMessenger.Output(64,temporary,i );
120 }
121
122 continue;
123 }
124 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
125 importedNamespaces.clear();
126 continue;
127 }
128
129 if(source[i]==1&&(
130 source[i+1]==ESC_CLASS||
131 source[i+1]==ESC_TYPE||
132 source[i+1]==ESC_INTERFACE
133 ))
134 {
135 int nowLine = i;
136 i += 2;
137
138 Type blittableType;
139 if(memicmp(source+i,"Align(",6)==0){
140 //アラインメント修飾子
141 i+=6;
142 i=JumpStringInPare(source,i)+1;
143 }
144 else if( memicmp( source + i, "Blittable(", 10 ) == 0 ){
145 // Blittable修飾子
146 i+=10;
147 i+=GetStringInPare_RemovePare(temporary,source+i)+1;
148 compiler.StringToType( temporary, blittableType );
149 }
150
151 bool isEnum = false;
152 bool isDelegate = false;
153 if( source[i] == 1 && source[i+1] == ESC_ENUM ){
154 // 列挙型の場合
155 isEnum = true;
156
157 i += 2;
158 }
159 else if( source[i] == 1 && source[i+1] == ESC_DELEGATE )
160 {
161 // デリゲートの場合
162 isDelegate = true;
163
164 i += 2;
165 }
166
167 for(i2=0;;i++,i2++){
168 if(!IsVariableChar(source[i])){
169 temporary[i2]=0;
170 break;
171 }
172 temporary[i2]=source[i];
173 }
174
175 //クラスを追加
176 CClass *pClass = classes.Add(namespaceScopes, importedNamespaces, temporary,nowLine);
177 if( pClass ){
178 if( source[nowLine+1] == ESC_CLASS ){
179 if( isEnum )
180 {
181 pClass->SetClassType( CClass::Enum );
182 }
183 else if( isDelegate )
184 {
185 pClass->SetClassType( CClass::Delegate );
186 }
187 else{
188 pClass->SetClassType( CClass::Class );
189 }
190 }
191 else if( source[nowLine+1] == ESC_INTERFACE ){
192 pClass->SetClassType( CClass::Interface );
193 }
194 else{
195 pClass->SetClassType( CClass::Structure );
196 }
197 }
198
199 // Blittable型の場合
200 if( !blittableType.IsNull() ){
201 pClass->SetBlittableType( blittableType );
202
203 // Blittable型として登録
204 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) );
205 }
206 }
207 }
208}
209
210UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName )
211{
212 int i2,i3;
213 char temporary[8192];
214
215 int i=1;
216
217 Procedure::Kind kind = Procedure::Sub;
218 bool isMacro = false;
219 if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function;
220 if(buffer[i]==ESC_MACRO){
221 isMacro = true;
222 }
223
224 i++;
225
226 bool isCdecl = false;
227 bool isExport = false;
228 while(1){
229 if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){
230 isCdecl = true;
231
232 i+=2;
233 }
234 else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){
235 isExport = true;
236
237 i+=2;
238 }
239 else break;
240 }
241
242 i2=0;
243 if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){
244 if(!pobj_c){
245 compiler.errorMessenger.Output(126,NULL,nowLine);
246 return 0;
247 }
248
249 //オペレータの場合
250 temporary[i2++]=buffer[i++];
251 temporary[i2++]=buffer[i++];
252
253 int iCalcId;
254 if(buffer[i]=='='&&buffer[i+1]=='='){
255 iCalcId=CALC_EQUAL;
256 i3=2;
257 }
258 else if(buffer[i]=='='){
259 iCalcId=CALC_SUBSITUATION;
260 i3=1;
261 }
262 else if(buffer[i]=='('){
263 iCalcId=CALC_AS;
264 i3=0;
265 }
266 else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){
267 iCalcId=CALC_ARRAY_SET;
268 i3=3;
269 }
270 else if(buffer[i]=='['&&buffer[i+1]==']'){
271 iCalcId=CALC_ARRAY_GET;
272 i3=2;
273 }
274 else{
275 iCalcId=GetCalcId(buffer+i,&i3);
276 i3++;
277 }
278 if(!iCalcId){
279 compiler.errorMessenger.Output(1,NULL,nowLine);
280 return 0;
281 }
282 temporary[i2++]=iCalcId;
283 temporary[i2]=0;
284
285 i+=i3;
286 }
287 else{
288 if(pobj_c){
289 //クラスメンバの場合、デストラクタには~が付くことを考慮
290 if(buffer[i]=='~'){
291 temporary[i2]='~';
292 i++;
293 i2++;
294 }
295 }
296
297 for(;;i++,i2++){
298 if(!IsVariableChar(buffer[i])){
299 temporary[i2]=0;
300 break;
301 }
302 temporary[i2]=buffer[i];
303 }
304
305 char parentName[VN_SIZE], memberName[VN_SIZE];
306 ReferenceKind refKind;
307 if( SplitMemberName( temporary, parentName, memberName, refKind ) )
308 {
309 if( pobj_c )
310 {
311 if( interfaceName )
312 {
313 lstrcpy( interfaceName, parentName );
314 }
315 else
316 {
317 compiler.errorMessenger.OutputFatalError();
318 return NULL;
319 }
320
321 char dummyMemberName[VN_SIZE];
322 if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) )
323 {
324 compiler.errorMessenger.Output(69,temporary,nowLine);
325 return NULL;
326 }
327 }
328 else
329 {
330 compiler.errorMessenger.Output(68,temporary,nowLine);
331 return NULL;
332 }
333
334 lstrcpy( temporary, memberName );
335 }
336 }
337
338 if( isMacro ){
339 //大文字に変換
340 CharUpper(temporary);
341 }
342
343 if(!pobj_c){
344 //クラスメンバ以外の場合のみ
345 //重複チェック
346
347 if(GetDeclareHash(temporary)){
348 compiler.errorMessenger.Output(15,temporary,nowLine);
349 return 0;
350 }
351 }
352
353 UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport );
354 pUserProc->SetParentClass( pobj_c );
355
356 // 親インターフェイスをセット
357 if( interfaceName && interfaceName[0] )
358 {
359 ::Interface *pTargetInterface = NULL;
360 BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() )
361 {
362 if( pInterface->GetClass().GetName() == interfaceName )
363 {
364 pTargetInterface = pInterface;
365 break;
366 }
367 }
368 pUserProc->SetInterface( pTargetInterface );
369 }
370
371 if(isExport){
372 pUserProc->Using();
373 }
374
375 // パラメータを解析
376 // ※第1パラメータにに指定するデータの例:"( s As String ) As String"
377 pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic );
378
379 pUserProc->_paramStr = buffer + i;
380
381 return pUserProc;
382}
383
384void LexicalAnalyzer::CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs )
385{
386 extern HANDLE hHeap;
387 int i,i2,i3;
388 char temporary[8192];
389
390 // 名前空間管理
391 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes();
392 namespaceScopes.clear();
393
394 // Importsされた名前空間の管理
395 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces();
396 importedNamespaces.clear();
397
398 i=-1;
399 while(1){
400 i++;
401
402 if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){
403 /* Class ~ End Class
404 Interface ~ End Interface
405 を飛び越す */
406 i3=GetEndXXXCommand(source[i+1]);
407 for(i+=2,i2=0;;i++,i2++){
408 if(source[i]=='\0') break;
409 if(source[i]==1&&source[i+1]==(char)i3){
410 i++;
411 break;
412 }
413 }
414 if(source[i]=='\0') break;
415 continue;
416 }
417
418 if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){
419 for(i+=2,i2=0;;i2++,i++){
420 if( IsCommandDelimitation( source[i] ) ){
421 temporary[i2]=0;
422 break;
423 }
424 temporary[i2]=source[i];
425 }
426 namespaceScopes.push_back( temporary );
427
428 continue;
429 }
430 else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){
431 if( namespaceScopes.size() <= 0 ){
432 compiler.errorMessenger.Output(12, "End Namespace", i );
433 }
434 else{
435 namespaceScopes.pop_back();
436 }
437
438 i += 2;
439 continue;
440 }
441 else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){
442 for(i+=2,i2=0;;i2++,i++){
443 if( IsCommandDelimitation( source[i] ) ){
444 temporary[i2]=0;
445 break;
446 }
447 temporary[i2]=source[i];
448 }
449 if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) )
450 {
451 compiler.errorMessenger.Output(64,temporary,cp );
452 }
453
454 continue;
455 }
456 else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){
457 importedNamespaces.clear();
458 continue;
459 }
460
461 if(source[i]==1&&source[i+1]==ESC_DECLARE){
462 for(i+=2,i2=0;;i2++,i++){
463 if(source[i]=='\n'){
464 temporary[i2]=0;
465 break;
466 }
467 temporary[i2]=source[i];
468 if(source[i]=='\0') break;
469 }
470 dllProcs.Add(namespaceScopes,temporary,i);
471
472 continue;
473 }
474 if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){
475 char statementChar = source[i+1];
476
477 for(i2=0;;i2++,i++){
478 if(IsCommandDelimitation(source[i])){
479 temporary[i2]=0;
480 break;
481 }
482 temporary[i2]=source[i];
483 if(source[i]=='\0') break;
484 }
485
486 UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false );
487 userProcs.Insert( pUserProc, i );
488
489 /* Sub ~ End Sub
490 Function ~ End Function
491 Macro ~ End Macro
492 を飛び越す */
493 char endStatementChar = GetEndXXXCommand( statementChar );
494 for(i2=0;;i++,i2++){
495 if( source[i] == '\0' ) break;
496 if( source[i] == 1 && source[i+1] == endStatementChar ){
497 i++;
498 break;
499 }
500 }
501 if(source[i]=='\0') break;
502 continue;
503 }
504
505 //次の行
506 for(;;i++){
507 if(IsCommandDelimitation(source[i])) break;
508 }
509 if(source[i]=='\0') break;
510 }
511
512 ////////////
513 // 特殊関数
514 ////////////
515 namespaceScopes.clear();
516 importedNamespaces.clear();
517
518 compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName();
519 sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str());
520 UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false );
521 userProcs.Insert( pUserProc, i );
522}
Note: See TracBrowser for help on using the repository browser.