Changeset 50 for branches/DelphiToC/Analyze/UPascalParser.pas
- Timestamp:
- Aug 9, 2010, 3:05:26 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/DelphiToC/Analyze/UPascalParser.pas
r49 r50 10 10 11 11 type 12 TOnErrorMessage = procedure 12 TOnErrorMessage = procedure(Text: string; Position: TPoint) of object; 13 13 14 14 TTokenType = (ttNone, ttIdentifier, ttConstantNumber, ttConstantString, … … 24 24 FNextToken: string; 25 25 FNextTokenType: TTokenType; 26 PreviousChar: Char;27 CurrentChar: Char;26 PreviousChar: char; 27 CurrentChar: char; 28 28 procedure ErrorMessage(const Text: string; const Arguments: array of const); 29 29 public 30 CodeStreamPosition: Integer;30 CodeStreamPosition: integer; 31 31 CodePosition: TPoint; 32 32 SourceCodeText: TStringList; 33 function IsAlphanumeric(Character: Char): Boolean;33 function IsAlphanumeric(Character: char): boolean; 34 34 procedure GetNextToken; 35 35 function ReadCode: string; 36 36 procedure Expect(Code: string); 37 function IsWhiteSpace(Character: Char): Boolean;38 function IsAlphabetic(Character: Char): Boolean;39 function IsIdentificator(Text: string): Boolean;40 function IsKeyword(Text: string): Boolean;41 function IsOperator(Text: string): Boolean;37 function IsWhiteSpace(Character: char): boolean; 38 function IsAlphabetic(Character: char): boolean; 39 function IsIdentificator(Text: string): boolean; 40 function IsKeyword(Text: string): boolean; 41 function IsOperator(Text: string): boolean; 42 42 procedure Log(Text: string); 43 43 property OnErrorMessage: TOnErrorMessage read FOnErrorMessage write FOnErrorMessage; … … 55 55 procedure ParseProgram(SourceCode: TModule); 56 56 procedure ParseAll(SourceCode: TProgram); 57 procedure ParseCommonBlock(SourceCode: TCommonBlock; EndSymbol: Char = ';');57 procedure ParseCommonBlock(SourceCode: TCommonBlock; EndSymbol: char = ';'); 58 58 function ParseCommand(SourceCode: TCommonBlock): TCommand; 59 59 procedure ParseBeginEnd(SourceCode: TBeginEnd); 60 60 procedure ParseFunctionList(SourceCode: TFunctionList); 61 61 procedure ParseIfThenElse(SourceCode: TIfThenElse); 62 procedure ParseForToDo(SourceCode: TForToDo); 62 63 procedure ParseVariableList(SourceCode: TVariableList); 63 64 procedure ParseVariable(SourceCode: TVariable); … … 78 79 STypeNotDefined = 'Type "%s" not defined.'; 79 80 SEndOfDataReached = 'Parser reached to end of input data.'; 81 SUndefinedVariable = 'Undefined variable.'; 80 82 81 83 … … 91 93 begin 92 94 Log('Expected: ' + Code + ' Readed: ' + FNextToken); 93 if FNextToken <> Code then begin 95 if FNextToken <> Code then 96 begin 94 97 ErrorMessage(SExpectedButFound, [Code, FNextToken]); 95 98 … … 101 104 end; 102 105 103 function TBaseParser.IsAlphabetic(Character: Char): Boolean;106 function TBaseParser.IsAlphabetic(Character: char): boolean; 104 107 begin 105 108 Result := (Character in ['a'..'z']) or (Character in ['A'..'Z']); 106 109 end; 107 110 108 function TBaseParser.IsAlphanumeric(Character: Char): Boolean;111 function TBaseParser.IsAlphanumeric(Character: char): boolean; 109 112 begin 110 113 Result := IsAlphabetic(Character) or (Character in ['0'..'9']); 111 114 end; 112 115 113 function TBaseParser.IsKeyword(Text: string): Boolean;114 var 115 I: Integer;116 function TBaseParser.IsKeyword(Text: string): boolean; 117 var 118 I: integer; 116 119 begin 117 120 Result := False; … … 121 124 end; 122 125 123 function TBaseParser.IsOperator(Text: string): Boolean;124 var 125 I: Integer;126 function TBaseParser.IsOperator(Text: string): boolean; 127 var 128 I: integer; 126 129 begin 127 130 Result := False; … … 131 134 end; 132 135 133 function TBaseParser.IsIdentificator(Text: string): Boolean;134 var 135 I: Integer;136 function TBaseParser.IsIdentificator(Text: string): boolean; 137 var 138 I: integer; 136 139 begin 137 140 Result := True; 138 if Length(Text) = 0 then Result := False; 139 if IsKeyWord(Text) then Result := False; 141 if Length(Text) = 0 then 142 Result := False; 143 if IsKeyWord(Text) then 144 Result := False; 140 145 if Length(Text) > 0 then 141 146 if not (Text[1] in ['a'..'z', 'A'..'Z', '%', '_']) then … … 146 151 end; 147 152 148 function TBaseParser.IsWhiteSpace(Character: Char): Boolean;153 function TBaseParser.IsWhiteSpace(Character: char): boolean; 149 154 begin 150 155 Result := (Character = ' ') or (Character = #13) or (Character = #10); … … 160 165 if FileExistsUTF8(LogFileName) { *Converted from FileExists* } then 161 166 LogFile := TFileStream.Create(LogFileName, fmOpenWrite) 162 else LogFile := TFileStream.Create(LogFileName, fmCreate); 163 if Length(Text) > 0 then begin 167 else 168 LogFile := TFileStream.Create(LogFileName, fmCreate); 169 if Length(Text) > 0 then 170 begin 164 171 LogFile.Write(Text[1], Length(Text)); 165 172 LogFile.Write(#13#10, 2); … … 183 190 procedure TBaseParser.GetNextToken; 184 191 var 185 I: Integer;186 II: Integer;187 J: Integer;192 I: integer; 193 II: integer; 194 J: integer; 188 195 const 189 SpecChar: set of char = [';', '.', ',', ':', '(', ')', '[', ']', '+', '-', '/', '*', 190 '^', '=', '<' , '>' , '@']; 191 DoubleSpecChar : array[0..6] of string = (':=', '..', '<=', '>=', '<>', '+=', '-='); 192 begin 193 FNextToken := ''; 194 FNextTokenType := ttNone; 195 with SourceCodeText do 196 while True do begin 197 if CodeStreamPosition < Length(Text) then begin 196 SpecChar: set of char = [';', '.', ',', ':', '(', ')', '[', ']', 197 '+', '-', '/', '*', '^', '=', '<', '>', '@']; 198 DoubleSpecChar: array[0..6] of string = (':=', '..', '<=', '>=', '<>', '+=', '-='); 199 begin 200 FNextToken := ''; 201 FNextTokenType := ttNone; 202 with SourceCodeText do 203 while True do 204 begin 205 if CodeStreamPosition < Length(Text) then 206 begin 198 207 CurrentChar := Text[CodeStreamPosition]; 199 end else begin 208 end 209 else 210 begin 200 211 FNextToken := ''; 201 212 FNextTokenType := ttEndOfFile; … … 203 214 end; 204 215 205 if FNextTokenType = ttNone then begin 206 if IsWhiteSpace(CurrentChar) then FNextTokenType := ttWhiteSpace 207 else 208 if CurrentChar = '{' then begin 216 if FNextTokenType = ttNone then 217 begin 218 if IsWhiteSpace(CurrentChar) then 219 FNextTokenType := ttWhiteSpace 220 else 221 if CurrentChar = '{' then 222 begin 209 223 FNextTokenType := ttBlockComment1; 210 end else 211 if CurrentChar = '''' then begin 224 end 225 else 226 if CurrentChar = '''' then 227 begin 212 228 FNextTokenType := ttConstantString; 213 end else 214 if CurrentChar in SpecChar then begin 229 end 230 else 231 if CurrentChar in SpecChar then 232 begin 215 233 FNextTokenType := ttOperator; 216 234 FNextToken := FNextToken + CurrentChar; 217 end else 218 if IsAlphanumeric(CurrentChar) then begin 235 end 236 else 237 if IsAlphanumeric(CurrentChar) then 238 begin 219 239 FNextTokenType := ttIdentifier; 220 240 FNextToken := FNextToken + CurrentChar; 221 end else FNextTokenType := ttUnknown; 222 end else 223 if FNextTokenType = ttLineComment then begin 241 end 242 else 243 FNextTokenType := ttUnknown; 244 end 245 else 246 if FNextTokenType = ttLineComment then 247 begin 224 248 if (CurrentChar = #13) or (CurrentChar = #10) then 225 249 FNextTokenType := ttNone; 226 end else 227 if FNextTokenType = ttBlockComment1 then begin 250 end 251 else 252 if FNextTokenType = ttBlockComment1 then 253 begin 228 254 if (CurrentChar = '}') then 229 255 FNextTokenType := ttNone; 230 end else 231 if FNextTokenType = ttBlockComment2 then begin 256 end 257 else 258 if FNextTokenType = ttBlockComment2 then 259 begin 232 260 if (PreviousChar = '*') and (CurrentChar = ')') then 233 261 FNextTokenType := ttNone; 234 end else 235 if FNextTokenType = ttConstantString then begin 262 end 263 else 264 if FNextTokenType = ttConstantString then 265 begin 236 266 if (CurrentChar = '''') and (PreviousChar = '''') then 237 Break else 267 Break 268 else 238 269 FNextToken := FNextToken + CurrentChar; 239 end else 240 if FNextTokenType = ttOperator then begin 241 if (CurrentChar = '*') and (PreviousChar = '(') then begin 270 end 271 else 272 if FNextTokenType = ttOperator then 273 begin 274 if (CurrentChar = '*') and (PreviousChar = '(') then 275 begin 242 276 FNextToken := ''; 243 277 FNextTokenType := ttBlockComment2; 244 end else 245 if (CurrentChar = '/') and (PreviousChar = '/') then begin 278 end 279 else 280 if (CurrentChar = '/') and (PreviousChar = '/') then 281 begin 246 282 FNextToken := ''; 247 283 FNextTokenType := ttLineComment; 248 end else 284 end 285 else 249 286 if not (CurrentChar in SpecChar) then 250 Break else begin 251 J := 0; 252 while (J < Length(DoubleSpecChar)) and ((PreviousChar + CurrentChar) <> DoubleSpecChar[J]) do Inc(J); 253 if J < Length(DoubleSpecChar) then 254 FNextToken := FNextToken + CurrentChar else Break; 255 end; 256 end else 257 if FNextTokenType = ttIdentifier then begin 287 Break 288 else 289 begin 290 J := 0; 291 while (J < Length(DoubleSpecChar)) and 292 ((PreviousChar + CurrentChar) <> DoubleSpecChar[J]) do 293 Inc(J); 294 if J < Length(DoubleSpecChar) then 295 FNextToken := FNextToken + CurrentChar 296 else 297 Break; 298 end; 299 end 300 else 301 if FNextTokenType = ttIdentifier then 302 begin 258 303 if not IsAlphanumeric(CurrentChar) then 259 Break else 304 Break 305 else 260 306 FNextToken := FNextToken + CurrentChar; 261 307 end … … 263 309 FNextTokenType := ttNone; 264 310 265 if FNextTokenType <> ttNone then begin 311 if FNextTokenType <> ttNone then 312 begin 266 313 // Update cursor position 267 314 Inc(CodePosition.X); 268 if (CurrentChar = #13) then begin 315 if (CurrentChar = #13) then 316 begin 269 317 CodePosition.X := 1; 270 318 Inc(CodePosition.Y); … … 288 336 procedure TPascalParser.ParseWhileDo(SourceCode: TWhileDo); 289 337 begin 290 with SourceCode do begin 338 with SourceCode do 339 begin 291 340 Expect('while'); 292 341 Condition.CommonBlock := CommonBlock; … … 306 355 Method: TFunction; 307 356 Constant: TConstant; 308 // Brackets: Integer;357 // Brackets: Integer; 309 358 Expressions: TExpressionList; 310 I: Integer;311 II: Integer;359 I: integer; 360 II: integer; 312 361 begin 313 362 Expressions := TExpressionList.Create; 314 363 Expressions.Add(TExpression.Create); 315 with SourceCode do begin 316 while ((FNextToken <> ';') and (FNextToken <> ',') and (not IsKeyWord(FNextToken))) and 317 not (((FNextToken = ')') or (FNextToken = ']'))) do begin 318 Identifier := ReadCode; 319 if Identifier = '(' then begin 320 // Subexpression 321 with TExpression(Expressions.Last) do begin 364 with SourceCode do 365 begin 366 while ((FNextToken <> ';') and (FNextToken <> ',') and 367 (not IsKeyWord(FNextToken))) and not 368 (((FNextToken = ')') or (FNextToken = ']'))) do 369 begin 370 Identifier := ReadCode; 371 if Identifier = '(' then 372 begin 373 // Subexpression 374 with TExpression(Expressions.Last) do 375 begin 376 SubItems[1] := TExpression.Create; 377 ParseExpression(TExpression(SubItems[1])); 378 end; 379 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do 380 begin 381 CommonBlock := SourceCode.CommonBlock; 382 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 383 end; 384 Expect(')'); 385 end 386 else 387 if IsOperator(Identifier) then 388 begin 389 // Operator 390 TExpression(Expressions.Last).OperatorName := Identifier; 391 TExpression(Expressions.Last).NodeType := ntOperator; 392 end 393 else 394 if IsIdentificator(Identifier) then 395 begin 396 // Reference to identificator 397 NewVariable := CommonBlock.Variables.Search(Identifier); 398 if Assigned(NewVariable) then 399 begin 400 // Referenced variable 401 with TExpression(Expressions.Last) do 402 begin 322 403 SubItems[1] := TExpression.Create; 323 ParseExpression(TExpression(SubItems[1])); 404 TExpression(SubItems[1]).NodeType := ntVariable; 405 TExpression(SubItems[1]).Variable := NewVariable; 324 406 end; 325 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 407 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do 408 begin 326 409 CommonBlock := SourceCode.CommonBlock; 327 410 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 328 411 end; 329 Expect(')'); 330 end else 331 if IsOperator(Identifier) then begin 332 // Operator 333 TExpression(Expressions.Last).OperatorName := Identifier; 334 TExpression(Expressions.Last).NodeType := ntOperator; 335 end else 336 if IsIdentificator(Identifier) then begin 337 // Reference to identificator 338 NewVariable := CommonBlock.Variables.Search(Identifier); 339 if Assigned(NewVariable) then begin 340 // Referenced variable 341 with TExpression(Expressions.Last) do begin 412 end 413 else 414 begin 415 Method := CommonBlock.Functions.Search(Identifier); 416 if Assigned(Method) then 417 begin 418 // Referenced method 419 with TExpression(Expressions.Last) do 420 begin 342 421 SubItems[1] := TExpression.Create; 343 TExpression(SubItems[1]).NodeType := ntVariable; 344 TExpression(SubItems[1]).Variable := NewVariable; 345 end; 346 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 347 CommonBlock := SourceCode.CommonBlock; 348 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 349 end; 350 end else begin 351 Method := CommonBlock.Functions.Search(Identifier); 352 if Assigned(Method) then begin 353 // Referenced method 354 with TExpression(Expressions.Last) do begin 355 SubItems[1] := TExpression.Create; 356 if FNextToken = '(' then // Method with parameters 357 with TExpression(SubItems[1]) do begin 422 if FNextToken = '(' then // Method with parameters 423 with TExpression(SubItems[1]) do 424 begin 358 425 Expect('('); 359 426 NewExpression := TExpression.Create; … … 361 428 ParseExpression(NewExpression); 362 429 SubItems.Add(NewExpression); 363 while FNextToken = ',' do begin 430 while FNextToken = ',' do 431 begin 364 432 Expect(','); 365 433 NewExpression := TExpression.Create; … … 370 438 Expect(')'); 371 439 end; 372 TExpression(SubItems[1]).NodeType := ntFunction; 373 TExpression(SubItems[1]).Method := Method; 440 TExpression(SubItems[1]).NodeType := ntFunction; 441 TExpression(SubItems[1]).Method := Method; 442 end; 443 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do 444 begin 445 CommonBlock := SourceCode.CommonBlock; 446 SubItems[0] := 447 TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 448 end; 449 end 450 else 451 begin 452 Constant := CommonBlock.Constants.Search(Identifier); 453 if Assigned(Constant) then 454 begin 455 // Referenced constant 456 with TExpression(Expressions.Last) do 457 begin 458 SubItems[1] := TExpression.Create; 459 TExpression(SubItems[1]).NodeType := ntConstant; 460 TExpression(SubItems[1]).Value := Constant.Value; 374 461 end; 375 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 462 with TExpression(Expressions.Items[Expressions.Add( 463 TExpression.Create)]) do 464 begin 376 465 CommonBlock := SourceCode.CommonBlock; 377 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 466 SubItems[0] := 467 TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 378 468 end; 379 end else begin 380 Constant := CommonBlock.Constants.Search(Identifier); 381 if Assigned(Constant) then begin 382 // Referenced constant 383 with TExpression(Expressions.Last) do begin 384 SubItems[1] := TExpression.Create; 385 TExpression(SubItems[1]).NodeType := ntConstant; 386 TExpression(SubItems[1]).Value := Constant.Value; 387 end; 388 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 389 CommonBlock := SourceCode.CommonBlock; 390 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 391 end; 392 end else begin 393 ErrorMessage(SUnknownIdentifier, [Identifier]); 394 end; 469 end 470 else 471 begin 472 ErrorMessage(SUnknownIdentifier, [Identifier]); 395 473 end; 396 474 end; 397 end else 398 begin 399 // Constant value 400 with TExpression(Expressions.Last) do begin 401 SubItems[1] := TExpression.Create; 402 TExpression(SubItems[1]).CommonBlock := SourceCode.CommonBlock; 403 TExpression(SubItems[1]).NodeType := ntConstant; 404 405 if Identifier[1] = '''' then begin 406 TExpression(SubItems[1]).Value := Identifier; 407 //SetLength(TExpression(SubItems[1]).Value, Length(Identifier)); 408 //for I := 1 to Length(Identifier) do 409 // TExpression(SubItems[1]).Value[I - 1] := Byte(Identifier[I]); 410 end else begin 411 TExpression(SubItems[1]).Value := Identifier; 412 end; 475 end; 476 end 477 else 478 begin 479 // Constant value 480 with TExpression(Expressions.Last) do 481 begin 482 SubItems[1] := TExpression.Create; 483 TExpression(SubItems[1]).CommonBlock := SourceCode.CommonBlock; 484 TExpression(SubItems[1]).NodeType := ntConstant; 485 486 if Identifier[1] = '''' then 487 begin 488 TExpression(SubItems[1]).Value := Identifier; 489 //SetLength(TExpression(SubItems[1]).Value, Length(Identifier)); 490 //for I := 1 to Length(Identifier) do 491 // TExpression(SubItems[1]).Value[I - 1] := Byte(Identifier[I]); 492 end 493 else 494 begin 495 TExpression(SubItems[1]).Value := Identifier; 413 496 end; 414 //ShowMessage(IntToStr(Expressions.Count)); 415 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do begin 416 CommonBlock := SourceCode.CommonBlock; 417 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 418 end; 419 end; 497 end; 498 //ShowMessage(IntToStr(Expressions.Count)); 499 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do 500 begin 501 CommonBlock := SourceCode.CommonBlock; 502 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1]; 503 end; 504 end; 420 505 end; 421 506 422 507 // Build expression tree 423 for II := 0 to High(Operators) do begin 508 for II := 0 to High(Operators) do 509 begin 424 510 I := 1; 425 while (I < Expressions.Count - 1) do begin 511 while (I < Expressions.Count - 1) do 512 begin 426 513 if not TExpression(Expressions[I]).Associated and 427 (TExpression(Expressions[I]).OperatorName = Operators[II]) then begin 428 TExpression(Expressions[I]).Associated := True; 429 TExpression(Expressions[I - 1]).SubItems[1] := Expressions[I]; 430 TExpression(Expressions[I + 1]).SubItems[0] := Expressions[I]; 431 //Expressions.Delete(I); 432 end else Inc(I); 514 (TExpression(Expressions[I]).OperatorName = Operators[II]) then 515 begin 516 TExpression(Expressions[I]).Associated := True; 517 TExpression(Expressions[I - 1]).SubItems[1] := Expressions[I]; 518 TExpression(Expressions[I + 1]).SubItems[0] := Expressions[I]; 519 //Expressions.Delete(I); 520 end 521 else 522 Inc(I); 433 523 end; 434 524 end; … … 450 540 First: TOperation; 451 541 Second: TOperation; 452 StartIndex: Integer;542 StartIndex: integer; 453 543 LoopVariable: TVariable; 454 544 IdentName: string; … … 456 546 begin 457 547 begin 458 if FNextToken = 'begin' then begin 548 if FNextToken = 'begin' then 549 begin 459 550 Result := TBeginEnd.Create; 460 551 TBeginEnd(Result).CommonBlock := SourceCode; … … 462 553 // + ' ' + IntToStr(Integer(Result))); 463 554 ParseBeginEnd(TBeginEnd(Result)); 464 end else 465 if FNextToken = 'if' then begin 555 end 556 else 557 if FNextToken = 'if' then 558 begin 466 559 Result := TIfThenElse.Create; 467 560 TIfThenElse(Result).CommonBlock := SourceCode; 468 561 ParseIfThenElse(TIfThenElse(Result)); 469 end else 470 if FNextToken = 'while' then begin 562 end 563 else 564 if FNextToken = 'while' then 565 begin 471 566 Result := TWhileDo.Create; 472 567 TWhileDo(Result).CommonBlock := SourceCode; 473 568 ParseWhileDo(TWhileDo(Result)); 474 end else 475 if IsIdentificator(FNextToken) then begin 476 if Assigned(SourceCode.Variables.Search(FNextToken)) then begin 569 end 570 else 571 if FNextToken = 'for' then 572 begin 573 Result := TForToDo.Create; 574 TForToDo(Result).CommonBlock := SourceCode; 575 ParseForToDo(TForToDo(Result)); 576 end 577 else 578 if IsIdentificator(FNextToken) then 579 begin 580 if Assigned(SourceCode.Variables.Search(FNextToken)) then 581 begin 477 582 // Variable assignment 478 583 Result := TAssignment.Create; … … 484 589 TAssignment(Result).Source.CommonBlock := SourceCode; 485 590 ParseExpression(TAssignment(Result).Source); 486 end else 487 if Assigned(SourceCode.Functions.Search(FNextToken)) then begin 591 end 592 else 593 if Assigned(SourceCode.Functions.Search(FNextToken)) then 594 begin 488 595 // Function call 489 596 FunctionName := ReadCode; … … 491 598 TFunctionCall(Result).CommonBlock := SourceCode; 492 599 TFunctionCall(Result).FunctionRef := SourceCode.Functions.Search(FunctionName); 493 if FNextToken = '(' then begin 600 if FNextToken = '(' then 601 begin 494 602 Expect('('); 495 with TFunctionCall(Result) do begin 603 with TFunctionCall(Result) do 604 begin 496 605 ParameterExpression.Add(TExpression.Create); 497 606 TExpression(ParameterExpression.Last).CommonBlock := SourceCode; … … 500 609 Expect(')'); 501 610 end; 502 end else begin 611 end 612 else 613 begin 503 614 Result := nil; 504 615 ErrorMessage(SUnknownIdentifier, [ReadCode]); 505 616 end; 506 end else 617 end 618 else 507 619 if FNextToken = ';' then 508 else begin 620 else 621 begin 509 622 Result := nil; 510 623 ErrorMessage(SIllegalExpression, [ReadCode]); … … 521 634 else if FNextToken = 'unit' then 522 635 ParseUnit(SourceCode) 523 else ParseProgram(SourceCode); 636 else 637 ParseProgram(SourceCode); 524 638 end; 525 639 … … 528 642 Identifier: string; 529 643 begin 530 with SourceCode do begin 531 if FNextToken = 'program' then begin 644 with SourceCode do 645 begin 646 if FNextToken = 'program' then 647 begin 532 648 Expect('program'); 533 649 Name := ReadCode; 534 650 ModuleType := mdProgram; 535 651 Expect(';'); 536 end else Name := ''; 652 end 653 else 654 Name := ''; 537 655 538 656 // Uses section … … 547 665 begin 548 666 Expect('unit'); 549 with TModule(ProgramCode.Modules[0]) do begin 667 with TModule(ProgramCode.Modules[0]) do 668 begin 550 669 Name := ReadCode; 551 670 ModuleType := mdUnit; … … 560 679 procedure TPascalParser.ParseAll(SourceCode: TProgram); 561 680 var 562 I: Integer; 563 begin 564 with SourceCode do begin 681 I: integer; 682 begin 683 with SourceCode do 684 begin 565 685 for I := 0 to Modules.Count - 1 do 566 686 ParseModule(TModule(Modules[I])); … … 570 690 { TParserCommonBlock } 571 691 572 procedure TPascalParser.ParseCommonBlock(SourceCode: TCommonBlock; EndSymbol: Char = ';'); 573 begin 574 with SourceCode do begin 575 while FNextToken <> EndSymbol do begin 692 procedure TPascalParser.ParseCommonBlock(SourceCode: TCommonBlock; 693 EndSymbol: char = ';'); 694 begin 695 with SourceCode do 696 begin 697 while FNextToken <> EndSymbol do 698 begin 576 699 if FNextToken = 'var' then 577 700 ParseVariableList(Variables) … … 584 707 else if FNextToken = 'function' then 585 708 ParseFunctionList(Functions) 586 else begin 709 else 710 begin 587 711 ParseBeginEnd(Code); 588 712 Break; … … 600 724 begin 601 725 //ShowMessage(IntToStr(Integer(SourceCode)) + ' ' + IntToStr(Integer(SourceCode.CommonBlock))); 602 with SourceCode do begin 726 with SourceCode do 727 begin 603 728 Expect('begin'); 604 while (FNextToken <> 'end') and (FNextTokenType <> ttEndOfFile) do begin 729 while (FNextToken <> 'end') and (FNextTokenType <> ttEndOfFile) do 730 begin 605 731 NewCommand := ParseCommand(CommonBlock); 606 if Assigned(NewCommand) then Commands.Add(NewCommand); 732 if Assigned(NewCommand) then 733 Commands.Add(NewCommand); 607 734 //ShowMessage(NextCode); 608 if FNextToken = ';' then ReadCode; 735 if FNextToken = ';' then 736 ReadCode; 609 737 end; 610 738 Expect('end'); … … 621 749 VariableName: string; 622 750 Variable: TParameter; 623 I: Integer;751 I: integer; 624 752 begin 625 753 Identifiers := TStringList.Create; 626 with SourceCode do begin 627 with TFunction(Items[Add(TFunction.Create)]) do begin 754 with SourceCode do 755 begin 756 with TFunction(Items[Add(TFunction.Create)]) do 757 begin 628 758 Parent := SourceCode.Parent; 629 if FNextToken = 'procedure' then begin 759 if FNextToken = 'procedure' then 760 begin 630 761 Expect('procedure'); 631 762 HaveResult := False; 632 end else begin 763 end 764 else 765 begin 633 766 Expect('function'); 634 767 HaveResult := True; … … 636 769 Name := ReadCode; 637 770 638 if FNextToken = '(' then begin 771 if FNextToken = '(' then 772 begin 639 773 Expect('('); 640 while FNextToken <> ')' do begin 641 // while IsIdentificator(NextCode) do begin 642 with TParameterList(Parameters) do begin 774 while FNextToken <> ')' do 775 begin 776 // while IsIdentificator(NextCode) do begin 777 with TParameterList(Parameters) do 778 begin 643 779 VariableName := ReadCode; 644 780 Variable := Search(VariableName); 645 if not Assigned(Variable) then begin 781 if not Assigned(Variable) then 782 begin 646 783 Identifiers.Add(VariableName); 647 while FNextToken = ',' do begin 784 while FNextToken = ',' do 785 begin 648 786 Expect(','); 649 787 Identifiers.Add(ReadCode); 650 788 end; 651 end else ErrorMessage(SRedefineIdentifier, [VariableName]); 789 end 790 else 791 ErrorMessage(SRedefineIdentifier, [VariableName]); 652 792 Expect(':'); 653 793 TypeName := ReadCode; 654 794 NewValueType := Parent.Types.Search(TypeName); 655 if not Assigned(NewValueType) then ErrorMessage(STypeNotDefined, [TypeName]) 656 else for I := 0 to Identifiers.Count - 1 do 657 with TParameter(Items[Add(TParameter.Create)]) do begin 795 if not Assigned(NewValueType) then 796 ErrorMessage(STypeNotDefined, [TypeName]) 797 else 798 for I := 0 to Identifiers.Count - 1 do 799 with TParameter(Items[Add(TParameter.Create)]) do 800 begin 658 801 Name := Identifiers[I]; 659 802 ValueType := NewValueType; … … 664 807 665 808 // Parse function result type 666 if HaveResult then begin 809 if HaveResult then 810 begin 667 811 Expect(':'); 668 812 TypeName := ReadCode; 669 813 NewValueType := Parent.Types.Search(TypeName); 670 if not Assigned(NewValueType) then ErrorMessage(STypeNotDefined, [TypeName]) 671 else begin 672 ResultType := NewValueType; 673 with TVariable(Parent.Variables.Items[Parent.Variables.Add(TVariable.Create)]) do begin 674 Name := 'Result'; 675 ValueType := NewValueType; 676 end; 814 if not Assigned(NewValueType) then 815 ErrorMessage(STypeNotDefined, [TypeName]) 816 else 817 begin 818 ResultType := NewValueType; 819 with TVariable(Parent.Variables.Items[Parent.Variables.Add( 820 TVariable.Create)]) do 821 begin 822 Name := 'Result'; 823 ValueType := NewValueType; 677 824 end; 825 end; 678 826 end; 679 827 end; … … 689 837 procedure TPascalParser.ParseIfThenElse(SourceCode: TIfThenElse); 690 838 begin 691 with Sourcecode do begin 839 with Sourcecode do 840 begin 692 841 Expect('if'); 693 842 Condition.CommonBlock := CommonBlock; … … 695 844 Expect('then'); 696 845 Command := ParseCommand(CommonBlock); 697 if FNextToken = 'else' then begin 846 if FNextToken = 'else' then 847 begin 698 848 Expect('else'); 699 849 ElseCommand := ParseCommand(CommonBlock); 700 850 end; 851 end; 852 end; 853 854 procedure TPascalParser.ParseForToDo(SourceCode: TForToDo); 855 var 856 VariableName: string; 857 begin 858 with SourceCode do 859 begin 860 Expect('for'); 861 VariableName := ReadCode; 862 ControlVariable := SourceCode.CommonBlock.Variables.Search(VariableName); 863 if not Assigned(ControlVariable) then 864 ErrorMessage(SUndefinedVariable, [VariableName]); 865 Expect(':='); 866 Start.CommonBlock := CommonBlock; 867 ParseExpression(Start); 868 Expect('to'); 869 Stop.CommonBlock := CommonBlock; 870 ParseExpression(Stop); 871 Expect('do'); 872 Command := ParseCommand(CommonBlock); 701 873 end; 702 874 end; … … 711 883 VariableName: string; 712 884 Variable: TVariable; 713 I: Integer;885 I: integer; 714 886 begin 715 887 Identifiers := TStringList.Create; 716 with SourceCode do begin 888 with SourceCode do 889 begin 717 890 Expect('var'); 718 while IsIdentificator(FNextToken) do begin 891 while IsIdentificator(FNextToken) do 892 begin 719 893 Identifiers.Clear; 720 894 VariableName := ReadCode; 721 895 Variable := Search(VariableName); 722 if not Assigned(Variable) then begin 896 if not Assigned(Variable) then 897 begin 723 898 Identifiers.Add(VariableName); 724 while FNextToken = ',' do begin 899 while FNextToken = ',' do 900 begin 725 901 Expect(','); 726 902 Identifiers.Add(ReadCode); 727 903 end; 728 end else ErrorMessage(SRedefineIdentifier, [VariableName]); 904 end 905 else 906 ErrorMessage(SRedefineIdentifier, [VariableName]); 729 907 Expect(':'); 730 908 TypeName := ReadCode; 731 909 NewValueType := Parent.Types.Search(TypeName); 732 if NewValueType = nil then ErrorMessage(STypeNotDefined, [TypeName]) 733 else for I := 0 to Identifiers.Count - 1 do 734 with TVariable(Items[Add(TVariable.Create)]) do begin 910 if NewValueType = nil then 911 ErrorMessage(STypeNotDefined, [TypeName]) 912 else 913 for I := 0 to Identifiers.Count - 1 do 914 with TVariable(Items[Add(TVariable.Create)]) do 915 begin 735 916 Name := Identifiers[I]; 736 917 ValueType := NewValueType; … … 746 927 procedure TPascalParser.ParseVariable(SourceCode: TVariable); 747 928 begin 748 with SourceCode do begin 929 with SourceCode do 930 begin 749 931 Name := FNextToken; 750 932 Expect(':='); … … 762 944 ConstantName: string; 763 945 Constant: TConstant; 764 I: Integer;946 I: integer; 765 947 ConstantValue: string; 766 948 begin 767 949 Identifiers := TStringList.Create; 768 with SourceCode do begin 950 with SourceCode do 951 begin 769 952 Expect('const'); 770 while IsIdentificator(FNextToken) do begin 953 while IsIdentificator(FNextToken) do 954 begin 771 955 ConstantName := ReadCode; 772 956 Constant := Search(ConstantName); 773 if not Assigned(Constant) then begin 957 if not Assigned(Constant) then 958 begin 774 959 Identifiers.Add(ConstantName); 775 while FNextToken = ',' do begin 960 while FNextToken = ',' do 961 begin 776 962 Expect(','); 777 963 Identifiers.Add(ReadCode); 778 964 end; 779 end else ErrorMessage(SRedefineIdentifier, [ConstantName]); 965 end 966 else 967 ErrorMessage(SRedefineIdentifier, [ConstantName]); 780 968 Expect(':'); 781 969 TypeName := ReadCode; … … 785 973 Expect(';'); 786 974 787 if NewValueType = nil then ErrorMessage(STypeNotDefined, [TypeName]) 788 else for I := 0 to Identifiers.Count - 1 do 789 with TConstant(Items[Add(TConstant.Create)]) do begin 975 if NewValueType = nil then 976 ErrorMessage(STypeNotDefined, [TypeName]) 977 else 978 for I := 0 to Identifiers.Count - 1 do 979 with TConstant(Items[Add(TConstant.Create)]) do 980 begin 790 981 Name := Identifiers[I]; 791 982 ValueType := NewValueType; … … 801 992 procedure TPascalParser.ParseTypeList(SourceCode: TTypeList); 802 993 begin 803 with SourceCode do begin 994 with SourceCode do 995 begin 804 996 Expect('type'); 805 997 while IsIdentificator(FNextToken) do 806 with TType(Items[Add(TType.Create)]) do begin 998 with TType(Items[Add(TType.Create)]) do 999 begin 807 1000 Parent := SourceCode; 808 1001 ParseType(TType(Items[Count - 1])); … … 815 1008 procedure TPascalParser.ParseType(SourceCode: TType); 816 1009 begin 817 with SourceCode do begin 1010 with SourceCode do 1011 begin 818 1012 Name := FNextToken; 819 1013 Expect('='); … … 829 1023 begin 830 1024 Expect('uses'); 831 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do begin 1025 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do 1026 begin 832 1027 Name := ReadCode; 833 1028 end; 834 while FNextToken = ',' do begin 1029 while FNextToken = ',' do 1030 begin 835 1031 Expect(','); 836 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do begin 1032 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do 1033 begin 837 1034 Name := ReadCode; 838 1035 end; … … 842 1039 843 1040 end. 1041
Note:
See TracChangeset
for help on using the changeset viewer.