Changeset 3 for trunk/Compiler/Analyze/UPascalParser.pas
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:ignore
set to
lib
-
Property svn:ignore
set to
-
trunk/Compiler
-
Property svn:ignore
set to
lib
-
Property svn:ignore
set to
-
trunk/Compiler/Analyze/UPascalParser.pas
r2 r3 18 18 public 19 19 function ParseFile(Name: string): Boolean; 20 procedure ParseWhileDo(SourceCode: TWhileDo);20 function ParseWhileDo(var WhileDo: TWhileDo; SourceCode: TCommonBlock): Boolean; 21 21 procedure ParseExpression(SourceCode: TExpression); 22 22 function ParseRightValue(SourceCode: TExpression): TObject; 23 23 function ParseFunctionCall(SourceCode: TExpression): TObject; 24 procedure ParseUses(SourceCode: TUsedModuleList; AExported: Boolean);24 function ParseUses(SourceCode: TUsedModuleList; AExported: Boolean): Boolean; 25 25 function ParseModule(ProgramCode: TProgram): TModule; 26 procedure ParseUnit(SourceCode: TModuleUnit);27 procedure ParseUnitInterface(SourceCode: TModuleUnit);28 procedure ParseUnitImplementation(SourceCode: TModuleUnit);26 function ParseUnit(var SourceCode: TModuleUnit; ProgramCode: TProgram): Boolean; 27 function ParseUnitInterface(SourceCode: TModuleUnit): Boolean; 28 function ParseUnitImplementation(SourceCode: TModuleUnit): Boolean; 29 29 procedure ParseProgram(SourceCode: TModuleProgram); 30 30 procedure ParseCommonBlock(SourceCode: TCommonBlock; EndSymbol: char = ';'; … … 32 32 procedure ParseCommonBlockInterface(SourceCode: TCommonBlock); 33 33 function ParseCommand(SourceCode: TCommonBlock): TCommand; 34 procedure ParseBeginEnd(SourceCode: TBeginEnd);34 function ParseBeginEnd(var BeginEnd: TBeginEnd; SourceCode: TCommonBlock): Boolean; 35 35 function ParseFunctionList(SourceCode: TFunctionList; Exported: Boolean = False): Boolean; 36 36 procedure ParseFunctionParameters(SourceCode: TFunction; ValidateParams: Boolean = False); 37 procedure ParseIfThenElse(SourceCode: TIfThenElse);38 procedure ParseForToDo(SourceCode: TForToDo);37 function ParseIfThenElse(var IfThenElse: TIfThenElse; SourceCode: TCommonBlock): Boolean; 38 function ParseForToDo(var ForToDo: TForToDo; SourceCode: TCommonBlock): Boolean; 39 39 function ParseVariableList(SourceCode: TVariableList; Exported: Boolean = False): Boolean; 40 40 procedure ParseVariable(SourceCode: TVariableList; Exported: Boolean = False); … … 107 107 end; 108 108 109 procedure TPascalParser.ParseWhileDo(SourceCode: TWhileDo); 110 begin 111 with SourceCode do 112 begin 109 function TPascalParser.ParseWhileDo(var WhileDo: TWhileDo; SourceCode: TCommonBlock): Boolean; 110 begin 111 if NextToken = 'while' then begin 113 112 Expect('while'); 114 Condition.CommonBlock := CommonBlock; 115 ParseExpression(Condition); 116 Expect('do'); 117 Command := ParseCommand(CommonBlock); 118 end; 113 WhileDo := TWhileDo.Create; 114 WhileDo.CommonBlock := SourceCode; 115 with WhileDo do begin 116 Condition.CommonBlock := CommonBlock; 117 ParseExpression(Condition); 118 Expect('do'); 119 Command := ParseCommand(CommonBlock); 120 end; 121 Result := True; 122 end else Result := False; 119 123 end; 120 124 … … 311 315 begin 312 316 begin 313 if NextToken = 'begin' then begin 314 Result := TBeginEnd.Create; 315 TBeginEnd(Result).CommonBlock := SourceCode; 316 //ShowMessage(IntToStr(Integer(SourceCode)) 317 // + ' ' + IntToStr(Integer(Result))); 318 ParseBeginEnd(TBeginEnd(Result)); 319 end else 320 if NextToken = 'if' then begin 321 Result := TIfThenElse.Create; 322 TIfThenElse(Result).CommonBlock := SourceCode; 323 ParseIfThenElse(TIfThenElse(Result)); 324 end else 325 if NextToken = 'while' then begin 326 Result := TWhileDo.Create; 327 TWhileDo(Result).CommonBlock := SourceCode; 328 ParseWhileDo(TWhileDo(Result)); 329 end else 330 if NextToken = 'for' then begin 331 Result := TForToDo.Create; 332 TForToDo(Result).CommonBlock := SourceCode; 333 ParseForToDo(TForToDo(Result)); 334 end else 317 if not ParseBeginEnd(TBeginEnd(Result), SourceCode) then 318 if not ParseIfThenElse(TIfThenElse(Result), SourceCode) then 319 if not ParseWhileDo(TWhileDo(Result), SourceCode) then 320 if not ParseForToDo(TForToDo(Result), SourceCode) then 335 321 if IsIdentificator(NextToken) then begin 336 322 if Assigned(SourceCode.Variables.Search(NextToken)) then begin … … 381 367 begin 382 368 Self.ProgramCode := ProgramCode; 383 if NextToken = 'unit' then begin 384 Result := TModuleUnit.Create; 385 Result.ParentProgram := ProgramCode; 386 ParseUnit(TModuleUnit(Result)); 387 end else 388 if NextToken = 'program' then begin 369 if not ParseUnit(TModuleUnit(Result), ProgramCode) then begin 389 370 Result := TModuleProgram.Create; 390 371 Result.ParentProgram := ProgramCode; … … 414 395 end; 415 396 416 procedure TPascalParser.ParseUnit(SourceCode: TModuleUnit);397 function TPascalParser.ParseUnit(var SourceCode: TModuleUnit; ProgramCode: TProgram): Boolean; 417 398 var 418 399 NewModule: TModule; 419 400 begin 420 Expect('unit'); 421 with Sourcecode do begin 422 Name := ReadToken; 423 end; 424 Expect(';'); 425 426 ParseUnitInterface(SourceCode); 427 if NextToken = 'implementation' then 428 ParseUnitImplementation(SourceCode); 429 430 SourceCode.ParentProgram.Modules.Add(SourceCode); 431 432 if NextToken = 'initialization' then begin 433 Expect('initialization'); 434 end; 435 if NextToken = 'finalization' then begin 436 Expect('finalization'); 437 end; 438 end; 439 440 procedure TPascalParser.ParseUnitInterface(SourceCode: TModuleUnit); 441 begin 442 Expect('interface'); 443 // Uses section 444 if NextToken = 'uses' then 401 if NextToken = 'unit' then begin 402 SourceCode := TModuleUnit.Create; 403 SourceCode.ParentProgram := ProgramCode; 404 Expect('unit'); 405 with Sourcecode do begin 406 Name := ReadToken; 407 end; 408 Expect(';'); 409 410 if not ParseUnitInterface(SourceCode) then 411 ErrorMessage(SExpectedButFound, ['interface', NextToken]); 412 413 if not ParseUnitImplementation(SourceCode) then 414 ErrorMessage(SExpectedButFound, ['implementation', NextToken]); 415 416 SourceCode.ParentProgram.Modules.Add(SourceCode); 417 418 if NextToken = 'initialization' then begin 419 Expect('initialization'); 420 end; 421 if NextToken = 'finalization' then begin 422 Expect('finalization'); 423 end; 424 Result := True; 425 end else Result := False; 426 end; 427 428 function TPascalParser.ParseUnitInterface(SourceCode: TModuleUnit): Boolean; 429 begin 430 if NextToken = 'interface' then begin 431 Expect('interface'); 432 // Uses section 445 433 ParseUses(SourceCode.UsedModules, True); 446 434 447 ParseCommonBlockInterface(SourceCode.Body); 448 end; 449 450 procedure TPascalParser.ParseUnitImplementation(SourceCode: TModuleUnit); 451 begin 452 Expect('implementation'); 453 454 // Uses section 455 if NextToken = 'uses' then 456 ParseUses(SourceCode.UsedModules, False); 457 458 ParseCommonBlock(SourceCode.Body, '.', False); 435 ParseCommonBlockInterface(SourceCode.Body); 436 Result := True; 437 end else Result := False; 438 end; 439 440 function TPascalParser.ParseUnitImplementation(SourceCode: TModuleUnit): Boolean; 441 begin 442 if NextToken = 'implementation' then begin 443 Expect('implementation'); 444 445 // Uses section 446 if NextToken = 'uses' then 447 ParseUses(SourceCode.UsedModules, False); 448 449 ParseCommonBlock(SourceCode.Body, '.', False); 450 Result := True; 451 end else Result := False; 459 452 end; 460 453 … … 471 464 if not ParseFunctionList(Functions) then begin 472 465 if WithBody then 473 ParseBeginEnd(Code); 466 if not ParseBeginEnd(Code, SourceCode) then 467 ErrorMessage(SExpectedButFound, ['begin', NextToken]); 474 468 Break; 475 469 end; … … 496 490 { TParserBeginEnd } 497 491 498 procedure TPascalParser.ParseBeginEnd(SourceCode: TBeginEnd);492 function TPascalParser.ParseBeginEnd(var BeginEnd: TBeginEnd; SourceCode: TCommonBlock): Boolean; 499 493 var 500 494 NewCommand: TCommand; 501 495 begin 502 //ShowMessage(IntToStr(Integer(SourceCode)) + ' ' + IntToStr(Integer(SourceCode.CommonBlock)));503 with SourceCode do504 begin505 Expect('begin');506 w hile (NextToken <> 'end') and (NextTokenType <> ttEndOfFile)do496 if NextToken = 'begin' then begin 497 //ShowMessage(IntToStr(Integer(SourceCode)) + ' ' + IntToStr(Integer(SourceCode.CommonBlock))); 498 BeginEnd := TBeginEnd.Create; 499 TBeginEnd(BeginEnd).CommonBlock := SourceCode; 500 with BeginEnd do 507 501 begin 508 NewCommand := ParseCommand(CommonBlock); 509 if Assigned(NewCommand) then 510 Commands.Add(NewCommand); 511 //ShowMessage(NextCode); 512 if NextToken = ';' then 513 ReadToken; 514 end; 515 Expect('end'); 516 end; 502 Expect('begin'); 503 while (NextToken <> 'end') and (NextTokenType <> ttEndOfFile) do 504 begin 505 NewCommand := ParseCommand(CommonBlock); 506 if Assigned(NewCommand) then 507 Commands.Add(NewCommand); 508 //ShowMessage(NextCode); 509 if NextToken = ';' then 510 ReadToken; 511 end; 512 Expect('end'); 513 end; 514 Result := True; 515 end else Result := False; 517 516 end; 518 517 … … 680 679 { TParserIfThenElse } 681 680 682 procedure TPascalParser.ParseIfThenElse(SourceCode: TIfThenElse); 683 begin 684 with SourceCode do begin 685 Expect('if'); 686 Condition.CommonBlock := CommonBlock; 687 ParseExpression(Condition); 688 Expect('then'); 689 Command := ParseCommand(CommonBlock); 690 if NextToken = 'else' then 691 begin 692 Expect('else'); 693 ElseCommand := ParseCommand(CommonBlock); 694 end; 695 end; 696 end; 697 698 procedure TPascalParser.ParseForToDo(SourceCode: TForToDo); 681 function TPascalParser.ParseIfThenElse(var IfThenElse: TIfThenElse; SourceCode: TCommonBlock): Boolean; 682 begin 683 if NextToken = 'if' then begin 684 IfThenElse := TIfThenElse.Create; 685 IfThenElse.CommonBlock := SourceCode; 686 with IfThenElse do begin 687 Expect('if'); 688 Condition.CommonBlock := CommonBlock; 689 ParseExpression(Condition); 690 Expect('then'); 691 Command := ParseCommand(CommonBlock); 692 if NextToken = 'else' then 693 begin 694 Expect('else'); 695 ElseCommand := ParseCommand(CommonBlock); 696 end; 697 end; 698 Result := True; 699 end else Result := False; 700 end; 701 702 function TPascalParser.ParseForToDo(var ForToDo: TForToDo; SourceCode: TCommonBlock): Boolean; 699 703 var 700 704 VariableName: string; 701 705 begin 702 with SourceCode do 703 begin 704 Expect('for'); 705 VariableName := ReadToken; 706 ControlVariable := SourceCode.CommonBlock.Variables.Search(VariableName); 707 if not Assigned(ControlVariable) then 708 ErrorMessage(SUndefinedVariable, [VariableName], -1); 709 Expect(':='); 710 Start.CommonBlock := CommonBlock; 711 ParseExpression(Start); 712 Expect('to'); 713 Stop.CommonBlock := CommonBlock; 714 ParseExpression(Stop); 715 Expect('do'); 716 Command := ParseCommand(CommonBlock); 717 end; 706 if NextToken = 'for' then begin 707 ForToDo := TForToDo.Create; 708 ForToDo.CommonBlock := SourceCode; 709 with ForToDo do begin 710 Expect('for'); 711 VariableName := ReadToken; 712 ControlVariable := ForToDo.CommonBlock.Variables.Search(VariableName); 713 if not Assigned(ControlVariable) then 714 ErrorMessage(SUndefinedVariable, [VariableName], -1); 715 Expect(':='); 716 Start.CommonBlock := CommonBlock; 717 ParseExpression(Start); 718 Expect('to'); 719 Stop.CommonBlock := CommonBlock; 720 ParseExpression(Stop); 721 Expect('do'); 722 Command := ParseCommand(CommonBlock); 723 end; 724 Result := True; 725 end else Result := False; 718 726 end; 719 727 … … 1128 1136 { TParserUsedModuleList } 1129 1137 1130 procedure TPascalParser.ParseUses(SourceCode: TUsedModuleList; AExported: Boolean = False);1138 function TPascalParser.ParseUses(SourceCode: TUsedModuleList; AExported: Boolean = False): Boolean; 1131 1139 var 1132 1140 NewUsedModule: TUsedModule; 1133 1141 begin 1134 Expect('uses'); 1135 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do 1136 begin 1137 Name := ReadToken; 1138 if NextToken = 'in' then begin 1139 Expect('in'); 1140 Location := ReadToken; 1141 end else Location := Name + '.pas'; 1142 Module := SourceCode.ParentModule.ParentProgram.Modules.Search(Name); 1143 if not Assigned(Module) then begin 1144 if ParseFile(Name) then begin 1145 Module := SourceCode.ParentModule.ParentProgram.Modules.Search(Name); 1146 Exported := AExported; 1147 end else begin 1148 ErrorMessage(SUnitNotFound, [Name], -2); 1149 SourceCode.Delete(SourceCode.Count - 1); 1150 end; 1151 end; 1152 end; 1153 while NextToken = ',' do begin 1154 Expect(','); 1155 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do 1156 begin 1142 if NextToken = 'uses' then begin 1143 Expect('uses'); 1144 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do begin 1157 1145 Name := ReadToken; 1158 1146 if NextToken = 'in' then begin … … 1162 1150 Module := SourceCode.ParentModule.ParentProgram.Modules.Search(Name); 1163 1151 if not Assigned(Module) then begin 1164 if not ParseFile(Name) then begin 1152 if ParseFile(Name) then begin 1153 Module := SourceCode.ParentModule.ParentProgram.Modules.Search(Name); 1154 Exported := AExported; 1155 end else begin 1165 1156 ErrorMessage(SUnitNotFound, [Name], -2); 1166 1157 SourceCode.Delete(SourceCode.Count - 1); … … 1168 1159 end; 1169 1160 end; 1170 end; 1171 Expect(';'); 1161 while NextToken = ',' do begin 1162 Expect(','); 1163 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do 1164 begin 1165 Name := ReadToken; 1166 if NextToken = 'in' then begin 1167 Expect('in'); 1168 Location := ReadToken; 1169 end else Location := Name + '.pas'; 1170 Module := SourceCode.ParentModule.ParentProgram.Modules.Search(Name); 1171 if not Assigned(Module) then begin 1172 if not ParseFile(Name) then begin 1173 ErrorMessage(SUnitNotFound, [Name], -2); 1174 SourceCode.Delete(SourceCode.Count - 1); 1175 end; 1176 end; 1177 end; 1178 end; 1179 Expect(';'); 1180 Result := True; 1181 end else Result := False; 1172 1182 end; 1173 1183
Note:
See TracChangeset
for help on using the changeset viewer.