Changeset 20 for branches/DelphiToC/UPascalParser.pas
- Timestamp:
- Sep 8, 2009, 2:01:55 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/DelphiToC/UPascalParser.pas
r19 r20 8 8 9 9 type 10 TPascalParser = class; 11 10 12 TOnErrorMessage = procedure (Text: string) of object; 13 14 TParserCommand = class(TCommand) 15 procedure Parse(Parser: TPascalParser); 16 end; 17 18 TParserWhileDo = class(TWhileDo) 19 procedure Parse(Parser: TPascalParser); 20 end; 21 22 TParserExpression = class(TExpression) 23 procedure Parse(Parser: TPascalParser); 24 end; 25 26 11 27 12 28 TPascalParser = class … … 32 48 procedure ParseModuleProgram(Module: TModule); 33 49 procedure ParseFunction(FunctionList: TFunctionList); 50 procedure ParseFunctionParameterList(ParameterList: TParameterList); 34 51 procedure ParseVariableList(VariableList: TVariableList); 35 52 procedure ParseVariable(Variable: TVariable); … … 40 57 procedure ParseCommonBlockDefinitions(CommonBlock: TCommonBlock; EndSymbol: string = ';'); 41 58 function ParseCommonBlockExpression(CommonBlock: TCommonBlock): TExpression; 42 procedure ParseCommonBlockProgramCode(CommonBlock: TCommonBlock); 43 procedure ParseCommonBlockOperation(CommonBlock: TCommonBlock); 59 function ParseCommand(CommonBlock: TCommonBlock): TCommand; 60 procedure ParseBeginEnd(CommonBlock: TCommonBlock; Command: TBeginEnd); 61 procedure ParseIfThenElse(CommonBlock: TCommonBlock; Command: TIfThenElse); 62 procedure ParseWhileDo(CommonBlock: TCommonBlock; Command: TWhileDo); 44 63 procedure Log(Text: string); 45 64 property OnErrorMessage: TOnErrorMessage read FOnErrorMessage write FOnErrorMessage; … … 206 225 207 226 procedure TPascalParser.ParseFunction(FunctionList: TFunctionList); 208 begin 227 var 228 Identifiers: TStringList; 229 NewValueType: TType; 230 TypeName: string; 231 VariableName: string; 232 Variable: TParameter; 233 I: Integer; 234 begin 235 Identifiers := TStringList.Create; 209 236 with FunctionList do begin 210 237 with TFunction(Items[Add(TFunction.Create)]) do begin 238 Parent := FunctionList.Parent; 211 239 Expect('procedure'); 212 240 Name := ReadCode; 213 Expect(';'); 214 ParseCommonBlockDefinitions(Items[Count - 1]); 215 end; 241 if NextCode = '(' then begin 242 Expect('('); 243 while NextCode <> ')' do begin 244 // while IsIdentificator(NextCode) do begin 245 with TParameterList(Parameters) do begin 246 VariableName := ReadCode; 247 Variable := Search(VariableName); 248 if not Assigned(Variable) then begin 249 Identifiers.Add(VariableName); 250 while NextCode = ',' do begin 251 Expect(','); 252 Identifiers.Add(ReadCode); 253 end; 254 end else ErrorMessage('Pøedefinování existující promìnné.'); 255 Expect(':'); 256 TypeName := ReadCode; 257 NewValueType := Parent.Types.Search(TypeName); 258 if not Assigned(NewValueType) then ErrorMessage('Typ ' + TypeName + ' nebyl definován.') 259 else for I := 0 to Identifiers.Count - 1 do 260 with TParameter(Items[Add(TParameter.Create)]) do begin 261 Name := Identifiers[I]; 262 ValueType := NewValueType; 263 end; 264 end; 265 end; 266 Expect(')'); 267 end; 268 end; 269 Expect(';'); 270 ParseCommonBlockDefinitions(TFunction(Items[Count - 1])); 271 end; 272 Identifiers.Destroy; 273 end; 274 275 procedure TPascalParser.ParseFunctionParameterList( 276 ParameterList: TParameterList); 277 begin 278 279 end; 280 281 procedure TPascalParser.ParseIfThenElse(CommonBlock: TCommonBlock; Command: TIfThenElse); 282 begin 283 Expect('if'); 284 Expect('than'); 285 if NextCode = 'else' then begin 286 Expect('else'); 216 287 end; 217 288 end; … … 229 300 Name := 'main'; 230 301 with TType(Types[Types.Add(TType.Create)]) do begin 302 Name := 'void'; 303 Size := 0; 304 UsedType := nil; 305 end; 306 with TType(Types[Types.Add(TType.Create)]) do begin 231 307 Name := 'byte'; 232 308 Size := 1; 233 309 UsedType := nil; 310 end; 311 with TFunction(Methods[Methods.Add(TFunction.Create)]) do begin 312 Name := 'exit'; 313 ResultType := TModule(Modules[0]).Types[0]; 234 314 end; 235 315 end; … … 318 398 end; 319 399 400 procedure TPascalParser.ParseBeginEnd(CommonBlock: TCommonBlock; Command: TBeginEnd); 401 var 402 NewCommand: TCommand; 403 begin 404 with Command do begin 405 Expect('begin'); 406 while NextCode <> 'end' do begin 407 NewCommand := ParseCommand(CommonBlock); 408 if Assigned(NewCommand) then Commands.Add(NewCommand); 409 //ShowMessage(NextCode); 410 if NextCode = ';' then ReadCode; 411 end; 412 Expect('end'); 413 end; 414 end; 415 320 416 procedure TPascalParser.ParseCommonBlockDefinitions(CommonBlock: TCommonBlock; EndSymbol: string = ';'); 321 417 begin … … 327 423 else if NextCode = 'procedure' then ParseFunction(Methods) 328 424 else begin 329 Parse CommonBlockProgramCode(CommonBlock);425 ParseBeginEnd(CommonBlock, Code); 330 426 Break; 331 427 end; … … 335 431 end; 336 432 337 function TPascalParser.ParseCommonBlockExpression(CommonBlock: TCommonBlock): TExpression; 433 function TPascalParser.ParseCommand(CommonBlock: TCommonBlock): TCommand; 434 var 435 Identifier: string; 436 Variable: TVariable; 437 Method: TFunction; 438 First: TOperation; 439 Second: TOperation; 440 StartIndex: Integer; 441 LoopVariable: TVariable; 442 IdentName: string; 443 begin 444 if NextCode = 'begin' then begin 445 Result := TBeginEnd.Create; 446 ParseBeginEnd(CommonBlock, TBeginEnd(Result)); 447 end else 448 if NextCode = 'if' then begin 449 Result := TIfThenElse.Create; 450 ParseIfThenElse(CommonBlock, TIfThenElse(Result)); 451 end else 452 if NextCode = 'while' then begin 453 Result := TWhileDo.Create; 454 ParseWhileDo(CommonBlock, TWhileDo(Result)); 455 end else 456 if IsIdentificator(NextCode) then begin 457 if Assigned(CommonBlock.Variables.Search(NextCode)) then begin 458 Result := TAssignment.Create; 459 IdentName := ReadCode; 460 TAssignment(Result).Target := CommonBlock.Variables.Search(IdentName); 461 Expect(':='); 462 TAssignment(Result).Source := ParseCommonBlockExpression(CommonBlock); 463 end else 464 if Assigned(CommonBlock.Methods.Search(NextCode)) then begin 465 Result := TMethodCall.Create; 466 // ParseMetVariable(TMethodCall(Result).Target); 467 end; 468 end; 469 470 (* begin 471 Expect('if'); 472 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 473 Instruction := inConditionalJump; 474 ExpressionTree := ParseCommonBlockExpression(CommonBlock); 475 Negative := True; 476 end; 477 First := Operations[Operations.Count - 1]; 478 Expect('then'); 479 ParseCommonBlockOperation(CommonBlock); 480 if NextCode = 'else' then begin 481 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 482 Instruction := inJump; 483 end; 484 Second := Operations[Operations.Count - 1]; 485 First.GotoAddress := Operations.Count; 486 Expect('else'); 487 ParseCommonBlockOperation(CommonBlock); 488 Second.GotoAddress := Operations.Count; 489 end else First.GotoAddress := Operations.Count; 490 end 491 else if NextCode = 'repeat' then begin 492 Expect('repeat'); 493 StartIndex := Operations.Count; 494 ParseCommonBlockOperation(CommonBlock); 495 Expect('until'); 496 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 497 Instruction := inConditionalJump; 498 ExpressionTree := ParseCommonBlockExpression(CommonBlock); 499 GotoAddress := StartIndex; 500 end; 501 end 502 else if NextCode = 'while' then begin 503 Expect('while'); 504 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 505 Instruction := inConditionalJump; 506 ExpressionTree := ParseCommonBlockExpression(CommonBlock); 507 end; 508 First := Operations[Operations.Count - 1]; 509 StartIndex := Operations.Count - 1; 510 Expect('do'); 511 ParseCommonBlockOperation(CommonBlock); 512 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 513 Instruction := inJump; 514 GotoAddress := StartIndex; 515 end; 516 First.GotoAddress := Operations.Count; 517 end 518 else if NextCode = 'for' then begin 519 Expect('for'); 520 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 521 Instruction := inExpressionEvaluation; 522 ExpressionTree := ParseCommonBlockExpression(CommonBlock); 523 if (ExpressionTree.NodeType <> ntOperator) and 524 (ExpressionTree.OperatorName <> ':=') then ErrorMessage('Expected assigment in for loop'); 525 if TExpression(TExpression(ExpressionTree).SubItems[0]).NodeType <> ntVariable then 526 ErrorMessage('Index in FOR loop have to be variable'); 527 LoopVaraible := TExpression(TExpression(ExpressionTree).SubItems[0]).Variable; 528 end; 529 Expect('to'); 530 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 531 Instruction := inExpressionEvaluation; 532 ExpressionTree := TExpression.Create; 533 with ExpressionTree do begin 534 NodeType := ntOperator; 535 OperatorName := '='; 536 SubItems[0] := TExpression.Create; 537 with TExpression(SubItems[0]) do begin 538 NodeType := ntVariable; 539 Variable := LoopVaraible; 540 end; 541 SubItems[1] := ParseCommonBlockExpression(CommonBlock); 542 end; 543 Negative := True; 544 end; 545 First := Operations[Operations.Count - 1]; 546 StartIndex := Operations.Count - 1; 547 Expect('do'); 548 ParseCommonBlockOperation(CommonBlock); 549 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 550 Instruction := inExpressionEvaluation; 551 ExpressionTree := TExpression.Create; 552 with ExpressionTree do begin 553 NodeType := ntOperator; 554 OperatorName := ':='; 555 SubItems[0] := TExpression.Create; 556 with TExpression(SubItems[0]) do begin 557 NodeType := ntVariable; 558 Variable := LoopVaraible; 559 end; 560 SubItems[1] := TExpression.Create; 561 with TExpression(SubItems[1]) do begin 562 NodeType := ntOperator; 563 OperatorName := '+'; 564 SubItems[0] := TExpression.Create; 565 with TExpression(SubItems[0]) do begin 566 NodeType := ntVariable; 567 Variable := LoopVaraible; 568 end; 569 SubItems[1] := TExpression.Create; 570 with TExpression(SubItems[1]) do begin 571 NodeType := ntConstant; 572 //SetLength(Value, 1); 573 //Value[0] := 1; 574 Value := 1; 575 end; 576 end; 577 end; 578 end; 579 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 580 Instruction := inJump; 581 GotoAddress := StartIndex; 582 end; 583 First.GotoAddress := Operations.Count; 584 end 585 else begin 586 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin 587 Instruction := inExpressionEvaluation; 588 ExpressionTree := ParseCommonBlockExpression(CommonBlock); 589 end; 590 end; 591 *) 592 end; 593 594 procedure TPascalParser.ParseTypeList(TypeList: TTypeList); 595 begin 596 with TypeList do begin 597 Expect('type'); 598 while IsIdentificator(NextCode) do 599 with TType(Items[Add(TType.Create)]) do begin 600 Parent := TypeList; 601 ParseType(TType(Items[Count - 1])); 602 end; 603 end; 604 end; 605 606 procedure TPascalParser.ParseVariableList(VariableList: TVariableList); 607 var 608 Identifiers: TStringList; 609 NewValueType: TType; 610 TypeName: string; 611 VariableName: string; 612 Variable: TVariable; 613 I: Integer; 614 begin 615 Identifiers := TStringList.Create; 616 with VariableList do begin 617 Expect('var'); 618 while IsIdentificator(NextCode) do begin 619 VariableName := ReadCode; 620 Variable := Search(VariableName); 621 if not Assigned(Variable) then begin 622 Identifiers.Add(VariableName); 623 while NextCode = ',' do begin 624 Expect(','); 625 Identifiers.Add(ReadCode); 626 end; 627 end else ErrorMessage('Pøedefinování existující promìnné.'); 628 Expect(':'); 629 TypeName := ReadCode; 630 NewValueType := Parent.Types.Search(TypeName); 631 if NewValueType = nil then ErrorMessage('Typ ' + TypeName + ' nebyl definován.') 632 else for I := 0 to Identifiers.Count - 1 do 633 with TVariable(Items[Add(TVariable.Create)]) do begin 634 Name := Identifiers[I]; 635 ValueType := NewValueType; 636 end; 637 Expect(';'); 638 end; 639 end; 640 Identifiers.Destroy; 641 end; 642 643 procedure TPascalParser.ParseWhileDo(CommonBlock: TCommonBlock; Command: TWhileDo); 644 begin 645 end; 646 647 procedure TPascalParser.ParseVariable(Variable: TVariable); 648 begin 649 with Variable do begin 650 Name := NextCode; 651 Expect(':='); 652 653 end; 654 end; 655 656 procedure TPascalParser.ParseType(AType: TType); 657 begin 658 with AType do begin 659 Name := NextCode; 660 Expect('='); 661 UsedType := Parent.Search(NextCode); 662 end; 663 end; 664 665 { TParserWhileDo } 666 667 procedure TParserWhileDo.Parse(Parser: TPascalParser); 668 begin 669 with Parser do begin 670 Expect('while'); 671 TParserExpression(Condition).Parse(Parser); 672 Expect('do'); 673 TParserCommand(Command).Parse(Parser); 674 end; 675 end; 676 677 { TExpression } 678 679 procedure TParserExpression.Parse(Parser: TPascalParser); 338 680 var 339 681 Identifier: string; … … 455 797 end; 456 798 457 procedure TPascalParser.ParseCommonBlockOperation(CommonBlock: TCommonBlock);458 var459 Identifier: string;460 Variable: TVariable;461 Method: TFunction;462 First: TOperation;463 Second: TOperation;464 StartIndex: Integer;465 LoopVaraible: TVariable;466 begin467 with CommonBlock do begin468 if NextCode = 'begin' then ParseCommonBlockProgramCode(CommonBlock)469 else if NextCode = 'if' then begin470 Expect('if');471 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin472 Instruction := inConditionalJump;473 ExpressionTree := ParseCommonBlockExpression(CommonBlock);474 Negative := True;475 end;476 First := Operations[Operations.Count - 1];477 Expect('then');478 ParseCommonBlockOperation(CommonBlock);479 if NextCode = 'else' then begin480 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin481 Instruction := inJump;482 end;483 Second := Operations[Operations.Count - 1];484 First.GotoAddress := Operations.Count;485 Expect('else');486 ParseCommonBlockOperation(CommonBlock);487 Second.GotoAddress := Operations.Count;488 end else First.GotoAddress := Operations.Count;489 end490 else if NextCode = 'repeat' then begin491 Expect('repeat');492 StartIndex := Operations.Count;493 ParseCommonBlockOperation(CommonBlock);494 Expect('until');495 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin496 Instruction := inConditionalJump;497 ExpressionTree := ParseCommonBlockExpression(CommonBlock);498 GotoAddress := StartIndex;499 end;500 end501 else if NextCode = 'while' then begin502 Expect('while');503 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin504 Instruction := inConditionalJump;505 ExpressionTree := ParseCommonBlockExpression(CommonBlock);506 end;507 First := Operations[Operations.Count - 1];508 StartIndex := Operations.Count - 1;509 Expect('do');510 ParseCommonBlockOperation(CommonBlock);511 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin512 Instruction := inJump;513 GotoAddress := StartIndex;514 end;515 First.GotoAddress := Operations.Count;516 end517 else if NextCode = 'for' then begin518 Expect('for');519 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin520 Instruction := inExpressionEvaluation;521 ExpressionTree := ParseCommonBlockExpression(CommonBlock);522 if (ExpressionTree.NodeType <> ntOperator) and523 (ExpressionTree.OperatorName <> ':=') then ErrorMessage('Expected assigment in for loop');524 if TExpression(TExpression(ExpressionTree).SubItems[0]).NodeType <> ntVariable then525 ErrorMessage('Index in FOR loop have to be variable');526 LoopVaraible := TExpression(TExpression(ExpressionTree).SubItems[0]).Variable;527 end;528 Expect('to');529 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin530 Instruction := inExpressionEvaluation;531 ExpressionTree := TExpression.Create;532 with ExpressionTree do begin533 NodeType := ntOperator;534 OperatorName := '=';535 SubItems[0] := TExpression.Create;536 with TExpression(SubItems[0]) do begin537 NodeType := ntVariable;538 Variable := LoopVaraible;539 end;540 SubItems[1] := ParseCommonBlockExpression(CommonBlock);541 end;542 Negative := True;543 end;544 First := Operations[Operations.Count - 1];545 StartIndex := Operations.Count - 1;546 Expect('do');547 ParseCommonBlockOperation(CommonBlock);548 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin549 Instruction := inExpressionEvaluation;550 ExpressionTree := TExpression.Create;551 with ExpressionTree do begin552 NodeType := ntOperator;553 OperatorName := ':=';554 SubItems[0] := TExpression.Create;555 with TExpression(SubItems[0]) do begin556 NodeType := ntVariable;557 Variable := LoopVaraible;558 end;559 SubItems[1] := TExpression.Create;560 with TExpression(SubItems[1]) do begin561 NodeType := ntOperator;562 OperatorName := '+';563 SubItems[0] := TExpression.Create;564 with TExpression(SubItems[0]) do begin565 NodeType := ntVariable;566 Variable := LoopVaraible;567 end;568 SubItems[1] := TExpression.Create;569 with TExpression(SubItems[1]) do begin570 NodeType := ntConstant;571 //SetLength(Value, 1);572 //Value[0] := 1;573 Value := 1;574 end;575 end;576 end;577 end;578 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin579 Instruction := inJump;580 GotoAddress := StartIndex;581 end;582 First.GotoAddress := Operations.Count;583 end584 else begin585 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin586 Instruction := inExpressionEvaluation;587 ExpressionTree := ParseCommonBlockExpression(CommonBlock);588 end;589 end;590 end;591 end;592 593 procedure TPascalParser.ParseCommonBlockProgramCode(CommonBlock: TCommonBlock);594 begin595 with CommonBlock do begin596 Expect('begin');597 while NextCode <> 'end' do begin598 ParseCommonBlockOperation(CommonBlock);599 Expect(';');600 end;601 Expect('end');602 with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin603 Instruction := inReturn;604 end;605 CheckReferences;606 end;607 end;608 609 procedure TPascalParser.ParseTypeList(TypeList: TTypeList);610 begin611 with TypeList do begin612 Expect('type');613 while IsIdentificator(NextCode) do614 with TType(Items[Add(TType.Create)]) do begin615 Parent := TypeList;616 ParseType(TType(Items[Count - 1]));617 end;618 end;619 end;620 621 procedure TPascalParser.ParseVariableList(VariableList: TVariableList);622 var623 Identifiers: TStringList;624 NewValueType: TType;625 TypeName: string;626 VariableName: string;627 Variable: TVariable;628 I: Integer;629 begin630 Identifiers := TStringList.Create;631 with VariableList do begin632 Expect('var');633 while IsIdentificator(NextCode) do begin634 VariableName := ReadCode;635 Variable := Search(VariableName);636 if not Assigned(Variable) then begin637 Identifiers.Add(VariableName);638 while NextCode = ',' do begin639 Expect(',');640 Identifiers.Add(ReadCode);641 end;642 end else ErrorMessage('Pøedefinování existující promìnné.');643 Expect(':');644 TypeName := ReadCode;645 NewValueType := Parent.Types.Search(TypeName);646 if NewValueType = nil then ErrorMessage('Typ ' + TypeName + ' nebyl definován.')647 else for I := 0 to Identifiers.Count - 1 do648 with TVariable(Items[Add(TVariable.Create)]) do begin649 Name := Identifiers[I];650 ValueType := NewValueType;651 end;652 Expect(';');653 end;654 end;655 Identifiers.Destroy;656 end;657 658 procedure TPascalParser.ParseVariable(Variable: TVariable);659 begin660 end;661 662 procedure TPascalParser.ParseType(AType: TType);663 begin664 with AType do begin665 Name := NextCode;666 Expect('=');667 UsedType := Parent.Search(NextCode);668 end;669 end;670 671 799 end.
Note:
See TracChangeset
for help on using the changeset viewer.