Changeset 6
- Timestamp:
- Oct 4, 2007, 5:13:15 PM (17 years ago)
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
PascalCompiler.dpr
r3 r6 1 1 program PascalCompiler; 2 2 3 {%File 'P0.grm'} 3 4 4 5 5 uses 6 6 Forms, 7 UMainForm in 'UMainForm.pas' {MainForm}; 7 UMainForm in 'UMainForm.pas' {MainForm}, 8 UGrammer in 'UGrammer.pas'; 8 9 9 10 {$R *.res} -
UMainForm.dfm
r3 r6 24 24 Left = 8 25 25 Top = 8 26 Width = 2 5726 Width = 290 27 27 Height = 313 28 ScrollBars = ssBoth 28 29 TabOrder = 0 29 30 end 30 31 object Button1: TButton 31 Left = 27132 Left = 304 32 33 Top = 8 33 Width = 7534 Width = 50 34 35 Height = 25 35 36 Caption = 'Parse' -
UMainForm.pas
r5 r6 5 5 uses 6 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, StdCtrls, ComCtrls ;7 Dialogs, StdCtrls, ComCtrls, UGrammer; 8 8 9 9 const … … 11 11 12 12 type 13 TGrammerRule = class;14 15 TPathItem = record16 public17 Rule: TGrammerRule;18 ItemIndex: Integer;19 Affected: Boolean;20 CharIndex: Integer;21 procedure Assign(Source: TPathItem);22 end;23 24 TGrammerPath = record25 Items: array of TPathItem;26 procedure Assign(Source: TGrammerPath);27 procedure Next;28 end;29 30 TPossibleCharacter = record31 Character: Char;32 RulePath: TGrammerPath;33 procedure Assign(Source: TPossibleCharacter);34 end;35 36 TPossibleCharacters = record37 Items: array of TPossibleCharacter;38 procedure Assign(Source: TPossibleCharacters);39 end;40 41 TRuleType = (rtSequence, rtAlternative);42 TRuleItemType = (itTerminal, itNonterminal);43 44 TProgramItem = class45 public46 RuleBefore: TGrammerRule;47 Items: TList; // of TProgramItem;48 ItemType: TRuleItemType;49 Rule: TGrammerRule;50 Value: Char;51 constructor Create;52 destructor Destroy; override;53 end;54 55 TProgram = class56 public57 TopItem: TProgramItem;58 constructor Create;59 procedure Insert(Path: TGrammerPath; Character: Char);60 destructor Destroy; override;61 end;62 63 TGrammerItem = record64 private65 Parent: TGrammerRule;66 Processed: Boolean;67 public68 ItemType: TRuleItemType;69 Character: Char;70 Rule: TGrammerRule;71 Optional: Boolean;72 Repetition: Boolean;73 procedure GetPossibleCharacters(Path: TGrammerPath; var Characters: TPossibleCharacters);74 constructor Create(ItemType: TRuleType);75 end;76 77 TGrammerRule = class78 private79 public80 Name: string;81 RuleType: TRuleType;82 Items: array of TGrammerItem;83 procedure ClearProcessed;84 procedure AddTerminal(Character: Char; Optional, Repetition: Boolean);85 procedure AddTerminalText(Text: string);86 procedure AddRule(Rule: TGrammerRule; Optional, Repetition: Boolean);87 procedure ProcessCharacter(Character: Char);88 procedure GetPossibleCharacters(Path: TGrammerPath;89 var Characters: TPossibleCharacters; UseIndex: Integer = 0; UseCharIndex: Integer = -1);90 constructor Create;91 end;92 93 TGrammer = class94 public95 Rules: TList; // of TGrammerRule;96 TopRule: TGrammerRule;97 constructor Create;98 procedure ClearProcessed;99 procedure Parse(Text: string; var ParsedProgram: TProgram);100 destructor Destroy; override;101 end;102 103 13 TMainForm = class(TForm) 104 14 Memo1: TMemo; … … 131 41 SourceProgram := TProgram.Create; 132 42 Grammer.Parse(Memo1.Text, SourceProgram); 43 with SourceProgram.TopItem do begin 44 MergeNonterminal(TGrammerRule(Grammer.Rules[7])); 45 MergeNonterminal(TGrammerRule(Grammer.Rules[9])); 46 DeleteNonterminal(TGrammerRule(Grammer.Rules[0])); 47 DeleteEmpty; 48 end; 133 49 ShowProgramTree(SourceProgram); 134 50 end; … … 138 54 LowerCaseAlphabeticCharacter, UpperCaseAlphabeticCharacter, 139 55 Digit, AlphabeticCharacter, Number, AlphaNumericCharacter, 140 Identifier, Assignment,Expression, RuleString, Rule, RuleList,56 Identifier, Expression, RuleString, Rule, RuleList, 141 57 OptionBlock, RepetitionBlock, GroupingBlock, 142 58 Term, AllCharacters, WhiteSpace, Concatenation, ConcatenationBlock, 143 Separation, SeparationBlock : TGrammerRule;59 Separation, SeparationBlock, Definition: TGrammerRule; 144 60 C: Char; 145 61 I: Integer; … … 357 273 Rules.Add(RuleList); 358 274 359 TopRule := RuleList; 275 Definition := TGrammerRule.Create; 276 with Definition do begin 277 Name := 'Definition'; 278 RuleType := rtSequence; 279 AddRule(RuleList, False, False); 280 AddRule(WhiteSpace, True, True); 281 AddTerminal('.', False, False); 282 end; 283 Rules.Add(Definition); 284 285 TopRule := Definition; 360 286 end; 361 287 … … 364 290 SourceProgram := TProgram.Create; 365 291 Memo1.Lines.LoadFromFile(DefaultGrammerFileName); 366 SourceCode := ''; ;292 SourceCode := ''; 367 293 // with Memo1.Lines do 368 294 // for I := 1 to Length(Text) do begin … … 374 300 end; 375 301 376 { TGrammerRule }377 378 procedure TGrammerRule.AddRule(Rule: TGrammerRule; Optional,379 Repetition: Boolean);380 begin381 SetLength(Items, Length(Items) + 1);382 Items[High(Items)].ItemType := itNonterminal;383 Items[High(Items)].Rule := Rule;384 Items[High(Items)].Optional := Optional;385 Items[High(Items)].Repetition := Repetition;386 Items[High(Items)].Parent := Self;387 end;388 389 procedure TGrammerRule.AddTerminal(Character: Char; Optional, Repetition: Boolean);390 begin391 SetLength(Items, Length(Items) + 1);392 Items[High(Items)].ItemType := itTerminal;393 Items[High(Items)].Character := Character;394 Items[High(Items)].Optional := Optional;395 Items[High(Items)].Repetition := Repetition;396 Items[High(Items)].Parent := Self;397 end;398 399 procedure TGrammerRule.AddTerminalText(Text: string);400 var401 I: Integer;402 begin403 for I := 1 to Length(Text) do AddTerminal(Text[I], False, False);404 end;405 406 procedure TGrammerRule.ClearProcessed;407 var408 I: Integer;409 begin410 for I := 0 to High(Items) do with Items[I] do begin411 Processed := False;412 end;413 end;414 415 constructor TGrammerRule.Create;416 begin417 418 end;419 420 procedure TGrammerRule.GetPossibleCharacters(Path: TGrammerPath;421 var Characters: TPossibleCharacters; UseIndex: Integer = 0; UseCharIndex: Integer = -1);422 var423 I: Integer;424 NextItemIndex, NextCharIndex: Integer;425 NextRule: TGrammerRule;426 TempPath: TGrammerPath;427 begin428 SetLength(Path.Items, Length(Path.Items) + 1);429 with Path.Items[High(Path.Items)] do begin430 Rule := Self;431 ItemIndex := UseIndex;432 CharIndex := UseCharIndex;433 Affected := True;434 end;435 436 case RuleType of437 rtAlternative: begin438 if UseIndex > 0 then begin439 // Forward generation to upper item440 SetLength(Path.Items, Length(Path.Items) - 1);441 with Path.Items[High(Path.Items)] do begin442 NextItemIndex := ItemIndex;443 NextCharIndex := CharIndex;444 NextRule := Rule;445 end;446 SetLength(Path.Items, Length(Path.Items) - 1);447 NextRule.GetPossibleCharacters(Path, Characters, NextItemIndex + 1, NextCharIndex);448 end else begin449 // Generate alternatives450 for I := 0 to High(Items) do begin451 Path.Items[High(Path.Items)].ItemIndex := I;452 //Inc(Path.Items[High(Path.Items)].CharIndex);453 Items[I].GetPossibleCharacters(Path, Characters);454 end;455 end;456 end;457 rtSequence: begin458 TempPath.Assign(Path);459 if UseIndex >= Length(Items) then begin460 // Forward generation to upper item461 SetLength(Path.Items, Length(Path.Items) - 1);462 with Path.Items[High(Path.Items)] do begin463 NextItemIndex := ItemIndex;464 NextCharIndex := CharIndex;465 NextRule := Rule;466 end;467 SetLength(Path.Items, Length(Path.Items) - 1);468 NextRule.GetPossibleCharacters(Path, Characters, NextItemIndex + 1, NextCharIndex);469 end else begin470 Path.Items[High(Path.Items)].ItemIndex := UseIndex;471 Items[UseIndex].GetPossibleCharacters(Path, Characters);472 end;473 // Check repetition474 if (UseIndex > 0) and not Items[UseIndex - 1].Processed then475 if Items[UseIndex - 1].Repetition then begin476 TempPath.Items[High(TempPath.Items)].ItemIndex := UseIndex - 1;477 Items[UseIndex - 1].GetPossibleCharacters(TempPath, Characters);478 end;479 end;480 end;481 end;482 483 procedure TGrammerRule.ProcessCharacter(Character: Char);484 begin485 end;486 487 302 procedure TMainForm.FormDestroy(Sender: TObject); 488 303 begin … … 497 312 I, II: Integer; 498 313 NewTreeNode: TTreeNode; 499 NewTreeNode2: TTreeNode;500 314 Attributs: string; 501 315 begin … … 520 334 else Attributs := '<?>' + Attributs; 521 335 end; 522 NewTreeNode2 :=AddChild(NewTreeNode, Attributs);336 AddChild(NewTreeNode, Attributs); 523 337 end; 524 338 end; … … 541 355 else TreeView1.Items.AddChild(TreeNode, 'x'); 542 356 end else begin 543 Tree Node := TreeView1.Items.AddChild(Node, SourceProgram.Value);357 TreeView1.Items.AddChild(Node, SourceProgram.Value); 544 358 end; 545 359 end; … … 557 371 end; 558 372 559 { TGrammer }560 561 procedure TGrammer.ClearProcessed;562 var563 I: Integer;564 begin565 for I := 0 to Rules.Count - 1 do with TGrammerRule(Rules[I]) do begin566 ClearProcessed;567 end;568 end;569 570 constructor TGrammer.Create;571 begin572 Rules := TList.Create;573 end;574 575 destructor TGrammer.Destroy;576 var577 I: Integer;578 begin579 for I := 0 to Rules.Count - 1 do TGrammerRule(Rules[I]).Free;580 Rules.Free;581 inherited;582 end;583 584 procedure TGrammer.Parse(Text: string; var ParsedProgram: TProgram);585 var586 Path: TGrammerPath;587 I, II: Integer;588 C: Integer;589 Scope: TPossibleCharacters;590 UseIndex: Integer;591 UseCharIndex: Integer;592 UseRule: TGrammerRule;593 ExpectedCharacters: string;594 Level: Integer;595 begin596 SetLength(Path.Items, Length(Path.Items) + 1);597 with Path.Items[High(Path.Items)] do begin598 Rule := TopRule;599 ItemIndex := 0;600 CharIndex := -1;601 end;602 603 for I := 1 to Length(Text) do begin604 if (Text[I] <> #13) and (Text[I] <> #10) then begin605 UseIndex := Path.Items[High(Path.Items)].ItemIndex;606 UseCharIndex := Path.Items[High(Path.Items)].CharIndex;607 UseRule := Path.Items[High(Path.Items)].Rule;608 SetLength(Path.Items, Length(Path.Items) - 1);609 SetLength(Scope.Items, 0);610 ClearProcessed;611 UseRule.GetPossibleCharacters(Path, Scope, UseIndex, UseCharIndex);612 C := Length(Scope.Items);613 Level := 0; //High(Integer);614 for II := High(Scope.Items) downto 0 do begin615 if (Scope.Items[II].Character = Text[I]) and (Level < Length(Scope.Items[II].RulePath.Items))616 then begin617 C := II;618 Level := Length(Scope.Items[II].RulePath.Items);619 end;620 end;621 if C < Length(Scope.Items) then begin622 Path.Assign(Scope.Items[C].RulePath);623 for II := 0 to Length(Path.Items) - 1 do with Path.Items[II] do begin624 if Affected then Inc(CharIndex);625 end;626 ParsedProgram.Insert(Path, Scope.Items[C].Character);627 for II := 0 to Length(Path.Items) - 1 do with Path.Items[II] do begin628 Affected := False;629 end;630 //Path.Next;631 end else begin632 ExpectedCharacters := '';633 for II := 0 to Length(Scope.Items) - 1 do634 ExpectedCharacters := ExpectedCharacters + Scope.Items[II].Character;635 //raise Exception.Create('Parse error. Expected "' + ExpectedCharacters + '" but found "' + Text[I] + '".');636 break;637 end;638 end;639 end;640 641 end;642 643 { TProgram }644 645 constructor TProgram.Create;646 begin647 TopItem := TProgramItem.Create;648 end;649 650 destructor TProgram.Destroy;651 begin652 TopItem.Free;653 inherited;654 end;655 656 procedure TProgram.Insert(Path: TGrammerPath; Character: Char);657 var658 I: Integer;659 SelectedProgramItem: TProgramItem;660 begin661 SelectedProgramItem := TopItem;662 for I := 0 to High(Path.Items) do with Path.Items[I] do begin663 SelectedProgramItem.ItemType := itNonterminal;664 if not Assigned(SelectedProgramItem.Rule) then SelectedProgramItem.Rule := Rule;665 if SelectedProgramItem.Rule = Rule then begin666 // if (Rule.RuleType = rtSequence) or (SelectedProgramItem.Rule = SelectedProgramItem.RuleBefore) then begin667 if SelectedProgramItem.Items.Count < (CharIndex + 1) then668 SelectedProgramItem.Items.Count := CharIndex + 1;669 if not Assigned(SelectedProgramItem.Items[CharIndex]) then670 SelectedProgramItem.Items[CharIndex] := TProgramItem.Create;671 SelectedProgramItem := TProgramItem(SelectedProgramItem.Items[CharIndex]);672 (* end else begin673 SelectedProgramItem.Items.Count := SelectedProgramItem.Items.Count + 1;674 if not Assigned(SelectedProgramItem.Items[SelectedProgramItem.Items.Count - 1]) then675 SelectedProgramItem.Items[SelectedProgramItem.Items.Count - 1] := TProgramItem.Create;676 SelectedProgramItem := TProgramItem(SelectedProgramItem.Items[SelectedProgramItem.Items.Count - 1]);677 end;678 *)679 end;680 end;681 with SelectedProgramItem do begin682 ItemType := itTerminal;683 Value := Character;684 end;685 end;686 687 { TProgramItem }688 689 constructor TProgramItem.Create;690 begin691 Items := TList.Create;692 end;693 694 destructor TProgramItem.Destroy;695 var696 I: Integer;697 begin698 for I := 0 to Items.Count - 1 do TProgramItem(Items[I]).Free;699 Items.Free;700 inherited;701 end;702 703 { TGrammerItem }704 705 constructor TGrammerItem.Create(ItemType: TRuleType);706 begin707 Rule := nil;708 end;709 710 procedure TGrammerItem.GetPossibleCharacters(Path: TGrammerPath;711 var Characters: TPossibleCharacters);712 var713 Found: Boolean;714 PathIndex: Integer;715 NextItemIndex, NextCharIndex: Integer;716 NextRule: TGrammerRule;717 begin718 Processed := True;719 case ItemType of720 itTerminal: begin721 SetLength(Characters.Items, Length(Characters.Items) + 1);722 Characters.Items[High(Characters.Items)].Character := Character;723 Characters.Items[High(Characters.Items)].RulePath.Assign(Path);724 with Characters.Items[High(Characters.Items)].RulePath do begin725 Inc(Items[High(Items)].ItemIndex);726 end;727 end;728 itNonterminal: begin729 Rule.GetPossibleCharacters(Path, Characters);730 end;731 end;732 if Optional then begin733 // Forward generation to upper item734 //SetLength(Path.Items, Length(Path.Items) - 1);735 with Path.Items[High(Path.Items)] do begin736 NextItemIndex := ItemIndex;737 NextCharIndex := CharIndex;738 NextRule := Rule;739 end;740 SetLength(Path.Items, Length(Path.Items) - 1);741 NextRule.GetPossibleCharacters(Path, Characters, NextItemIndex + 1, NextCharIndex);742 end;743 end;744 745 { TGrammerPath }746 747 procedure TGrammerPath.Assign(Source: TGrammerPath);748 var749 I: Integer;750 begin751 SetLength(Items, Length(Source.Items));752 for I := 0 to High(Items) do Items[I].Assign(Source.Items[I]);753 end;754 755 procedure TGrammerPath.Next;756 var757 Index: Integer;758 Success: Boolean;759 begin760 Success := False;761 Index := High(Items);762 while not Success and (Index >= 0) do begin763 with Items[Index] do if Rule.Items[ItemIndex].Repetition then begin764 Success := True;765 //Inc(CharIndex);766 end else begin767 if ((ItemIndex + 1) < Length(Rule.Items)) and (Rule.RuleType = rtSequence) then begin768 Inc(ItemIndex);769 //Inc(CharIndex);770 Success := True;771 end else Dec(Index);772 end;773 end;774 SetLength(Items, Index + 1);775 end;776 777 { TPathItem }778 779 procedure TPathItem.Assign(Source: TPathItem);780 begin781 Rule := Source.Rule;782 ItemIndex := Source.ItemIndex;783 CharIndex := Source.CharIndex;784 Affected := Source.Affected;785 end;786 787 { TPossibleCharacter }788 789 procedure TPossibleCharacter.Assign(Source: TPossibleCharacter);790 begin791 Character := Source.Character;792 RulePath.Assign(Source.RulePath);793 end;794 795 { TPossibleCharacters }796 797 procedure TPossibleCharacters.Assign(Source: TPossibleCharacters);798 var799 I: Integer;800 begin801 SetLength(Items, Length(Source.Items));802 for I := 0 to High(Items) do Items[I].Assign(Source.Items[I]);803 end;804 805 373 end.
Note:
See TracChangeset
for help on using the changeset viewer.