Changeset 3
- Timestamp:
- Oct 4, 2007, 1:58:38 PM (17 years ago)
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
P0.grm
r2 r3 1 p= b| '' | 'b' .1 p=bcd | '' | 'b' . -
PascalCompiler.dpr
r1 r3 1 1 program PascalCompiler; 2 3 {%File 'P0.grm'} 2 4 3 5 uses -
Program.pas
r2 r3 1 p= b| '' | 'b' .1 p=bcd | '' | 'b' . -
UMainForm.dfm
r2 r3 13 13 OldCreateOrder = False 14 14 Position = poDesigned 15 WindowState = wsMaximized 15 16 OnCreate = FormCreate 16 17 OnDestroy = FormDestroy … … 44 45 Indent = 19 45 46 TabOrder = 2 46 ExplicitWidth = 31347 ExplicitHeight = 44148 47 end 49 48 object TreeView2: TTreeView -
UMainForm.pas
r2 r3 11 11 12 12 TPathItem = record 13 public 13 14 Rule: TGrammerRule; 14 15 ItemIndex: Integer; 16 Affected: Boolean; 15 17 CharIndex: Integer; 16 18 procedure Assign(Source: TPathItem); … … 38 40 39 41 TProgramItem = class 40 private41 42 public 42 43 RuleBefore: TGrammerRule; … … 58 59 59 60 TGrammerItem = record 61 private 62 Parent: TGrammerRule; 63 Processed: Boolean; 60 64 public 61 65 ItemType: TRuleItemType; … … 70 74 TGrammerRule = class 71 75 private 72 Index: Integer;73 76 public 74 77 Name: string; 75 78 RuleType: TRuleType; 76 79 Items: array of TGrammerItem; 80 procedure ClearProcessed; 77 81 procedure AddTerminal(Character: Char; Optional, Repetition: Boolean); 78 82 procedure AddTerminalText(Text: string); … … 80 84 procedure ProcessCharacter(Character: Char); 81 85 procedure GetPossibleCharacters(Path: TGrammerPath; 82 var Characters: TPossibleCharacters; UseIndex: Integer = 0; UseCharIndex: Integer = 0);86 var Characters: TPossibleCharacters; UseIndex: Integer = 0; UseCharIndex: Integer = -1); 83 87 constructor Create; 84 88 end; … … 89 93 TopRule: TGrammerRule; 90 94 constructor Create; 95 procedure ClearProcessed; 91 96 procedure Parse(Text: string; var ParsedProgram: TProgram); 92 97 destructor Destroy; override; … … 120 125 procedure TMainForm.Button1Click(Sender: TObject); 121 126 begin 127 SourceProgram.Free; 128 SourceProgram := TProgram.Create; 122 129 Grammer.Parse(Memo1.Text, SourceProgram); 130 ShowProgramTree(SourceProgram); 123 131 end; 124 132 … … 128 136 Digit, AlphabeticCharacter, Number, AlphaNumericCharacter, 129 137 Identifier, Assignment, Expression, RuleString, Rule, RuleList, 130 AlternateOptions, OptionBlock, RepetitionBlock, GroupingBlock, 131 AlternateOptionsSubBlock, Term, AllCharacters, WhiteSpace: TGrammerRule; 138 OptionBlock, RepetitionBlock, GroupingBlock, 139 Term, AllCharacters, WhiteSpace, Concatenation, ConcatenationBlock, 140 Separation, SeparationBlock: TGrammerRule; 132 141 C: Char; 133 142 I: Integer; … … 225 234 Rules.Add(RuleString); 226 235 227 AlternateOptions := TGrammerRule.Create; 228 Expression := TGrammerRule.Create; 229 230 AlternateOptionsSubBlock := TGrammerRule.Create; 231 with AlternateOptionsSubBlock do begin 232 Name := 'AlternateOptionsSubBlock'; 233 RuleType := rtSequence; 234 AddRule(WhiteSpace, True, True); 235 AddTerminal('|', False, False); 236 AddRule(WhiteSpace, True, True); 237 AddRule(AlternateOptions, True, True); 238 end; 239 Rules.Add(AlternateOptionsSubBlock); 236 Concatenation := TGrammerRule.Create; 240 237 241 238 OptionBlock := TGrammerRule.Create; … … 245 242 AddTerminal('[', False, False); 246 243 AddRule(WhiteSpace, True, True); 247 AddRule( Expression, False, False);244 AddRule(Concatenation, False, False); 248 245 AddRule(WhiteSpace, True, True); 249 246 AddTerminal(']', False, False); … … 257 254 AddTerminal('{', False, False); 258 255 AddRule(WhiteSpace, True, True); 259 AddRule( Expression, False, False);256 AddRule(Concatenation, False, False); 260 257 AddRule(WhiteSpace, True, True); 261 258 AddTerminal('}', False, False); … … 269 266 AddTerminal('(', False, False); 270 267 AddRule(WhiteSpace, True, True); 271 AddRule( Expression, False, False);268 AddRule(Concatenation, False, False); 272 269 AddRule(WhiteSpace, True, True); 273 270 AddTerminal(')', False, False); … … 284 281 Rules.Add(Term); 285 282 286 with AlternateOptions do begin 287 Name := 'AlternateOptions'; 288 RuleType := rtSequence; 289 AddRule(Term, False, False); 290 AddRule(AlternateOptionsSubBlock, True, True); 291 end; 292 Rules.Add(AlternateOptions); 293 283 Expression := TGrammerRule.Create; 294 284 with Expression do begin 295 285 Name := 'Expression'; … … 298 288 AddRule(OptionBlock, False, False); 299 289 AddRule(GroupingBlock, False, False); 300 AddRule( AlternateOptions, False, False);290 AddRule(Term, False, False); 301 291 end; 302 292 Rules.Add(Expression); 293 294 ConcatenationBlock := TGrammerRule.Create; 295 with ConcatenationBlock do begin 296 Name := 'ConcatenationBlock'; 297 RuleType := rtSequence; 298 AddRule(WhiteSpace, False, True); 299 AddRule(Expression, False, False); 300 end; 301 Rules.Add(ConcatenationBlock); 302 303 with Concatenation do begin 304 Name := 'Concatenation'; 305 RuleType := rtSequence; 306 AddRule(Expression, False, False); 307 AddRule(ConcatenationBlock, True, True); 308 end; 309 Rules.Add(Concatenation); 310 311 SeparationBlock := TGrammerRule.Create; 312 with SeparationBlock do begin 313 Name := 'SeparationBlock'; 314 RuleType := rtSequence; 315 AddRule(WhiteSpace, True, True); 316 AddTerminal('|', False, False); 317 AddRule(WhiteSpace, True, True); 318 AddRule(Concatenation, False, False); 319 end; 320 Rules.Add(SeparationBlock); 321 322 Separation := TGrammerRule.Create; 323 with Separation do begin 324 Name := 'Separation'; 325 RuleType := rtSequence; 326 AddRule(Concatenation, False, False); 327 AddRule(SeparationBlock, True, True); 328 end; 329 Rules.Add(Separation); 303 330 304 331 Rule := TGrammerRule.Create; … … 311 338 AddTerminal('=', False, False); 312 339 AddRule(WhiteSpace, True, True); 313 AddRule( Expression, False, True);340 AddRule(Separation, False, False); 314 341 AddRule(WhiteSpace, True, True); 315 342 AddTerminal('.', False, False); … … 353 380 Items[High(Items)].Optional := Optional; 354 381 Items[High(Items)].Repetition := Repetition; 382 Items[High(Items)].Parent := Self; 355 383 end; 356 384 … … 362 390 Items[High(Items)].Optional := Optional; 363 391 Items[High(Items)].Repetition := Repetition; 392 Items[High(Items)].Parent := Self; 364 393 end; 365 394 … … 371 400 end; 372 401 402 procedure TGrammerRule.ClearProcessed; 403 var 404 I: Integer; 405 begin 406 for I := 0 to High(Items) do with Items[I] do begin 407 Processed := False; 408 end; 409 end; 410 373 411 constructor TGrammerRule.Create; 374 412 begin … … 377 415 378 416 procedure TGrammerRule.GetPossibleCharacters(Path: TGrammerPath; 379 var Characters: TPossibleCharacters; UseIndex: Integer = 0; UseCharIndex: Integer = 0); 380 var 381 I: Integer; 382 begin 383 Index := UseIndex; 417 var Characters: TPossibleCharacters; UseIndex: Integer = 0; UseCharIndex: Integer = -1); 418 var 419 I: Integer; 420 NextItemIndex, NextCharIndex: Integer; 421 NextRule: TGrammerRule; 422 TempPath: TGrammerPath; 423 begin 384 424 SetLength(Path.Items, Length(Path.Items) + 1); 385 Path.Items[High(Path.Items)].Rule := Self; 386 Path.Items[High(Path.Items)].ItemIndex := UseIndex; 387 Path.Items[High(Path.Items)].CharIndex := UseCharIndex; 425 with Path.Items[High(Path.Items)] do begin 426 Rule := Self; 427 ItemIndex := UseIndex; 428 CharIndex := UseCharIndex; 429 Affected := True; 430 end; 431 388 432 case RuleType of 389 433 rtAlternative: begin 390 for I := 0 to High(Items) do begin 391 Path.Items[High(Path.Items)].ItemIndex := I; 392 //Inc(Path.Items[High(Path.Items)].CharIndex); 393 Items[I].GetPossibleCharacters(Path, Characters); 434 if UseIndex > 0 then begin 435 // Forward generation to upper item 436 SetLength(Path.Items, Length(Path.Items) - 1); 437 with Path.Items[High(Path.Items)] do begin 438 NextItemIndex := ItemIndex; 439 NextCharIndex := CharIndex; 440 NextRule := Rule; 441 end; 442 SetLength(Path.Items, Length(Path.Items) - 1); 443 NextRule.GetPossibleCharacters(Path, Characters, NextItemIndex + 1, NextCharIndex); 444 end else begin 445 // Generate alternatives 446 for I := 0 to High(Items) do begin 447 Path.Items[High(Path.Items)].ItemIndex := I; 448 //Inc(Path.Items[High(Path.Items)].CharIndex); 449 Items[I].GetPossibleCharacters(Path, Characters); 450 end; 394 451 end; 395 452 end; 396 453 rtSequence: begin 397 Path.Items[High(Path.Items)].ItemIndex := Index; 398 //Inc(Path.Items[High(Path.Items)].CharIndex); 399 Items[Index].GetPossibleCharacters(Path, Characters); 454 TempPath.Assign(Path); 455 if UseIndex >= Length(Items) then begin 456 // Forward generation to upper item 457 SetLength(Path.Items, Length(Path.Items) - 1); 458 with Path.Items[High(Path.Items)] do begin 459 NextItemIndex := ItemIndex; 460 NextCharIndex := CharIndex; 461 NextRule := Rule; 462 end; 463 SetLength(Path.Items, Length(Path.Items) - 1); 464 NextRule.GetPossibleCharacters(Path, Characters, NextItemIndex + 1, NextCharIndex); 465 end else begin 466 Path.Items[High(Path.Items)].ItemIndex := UseIndex; 467 Items[UseIndex].GetPossibleCharacters(Path, Characters); 468 end; 469 // Check repetition 470 if (UseIndex > 0) and not Items[UseIndex - 1].Processed then 471 if Items[UseIndex - 1].Repetition then begin 472 TempPath.Items[High(TempPath.Items)].ItemIndex := UseIndex - 1; 473 Items[UseIndex - 1].GetPossibleCharacters(TempPath, Characters); 474 end; 400 475 end; 401 476 end; … … 480 555 { TGrammer } 481 556 557 procedure TGrammer.ClearProcessed; 558 var 559 I: Integer; 560 begin 561 for I := 0 to Rules.Count - 1 do with TGrammerRule(Rules[I]) do begin 562 ClearProcessed; 563 end; 564 end; 565 482 566 constructor TGrammer.Create; 483 567 begin … … 509 593 Rule := TopRule; 510 594 ItemIndex := 0; 511 CharIndex := 0;595 CharIndex := -1; 512 596 end; 513 597 … … 519 603 SetLength(Path.Items, Length(Path.Items) - 1); 520 604 SetLength(Scope.Items, 0); 605 ClearProcessed; 521 606 UseRule.GetPossibleCharacters(Path, Scope, UseIndex, UseCharIndex); 522 607 C := 0; … … 524 609 (Scope.Items[C].Character <> Text[I]) do Inc(C); 525 610 if C < Length(Scope.Items) then begin 526 ParsedProgram.Insert(Scope.Items[C].RulePath, Scope.Items[C].Character); 611 Path.Assign(Scope.Items[C].RulePath); 612 for II := 0 to Length(Path.Items) - 1 do with Path.Items[II] do begin 613 if Affected then Inc(CharIndex); 614 end; 615 ParsedProgram.Insert(Path, Scope.Items[C].Character); 616 for II := 0 to Length(Path.Items) - 1 do with Path.Items[II] do begin 617 Affected := False; 618 end; 619 //Path.Next; 527 620 end else begin 528 621 ExpectedCharacters := ''; 529 622 for II := 0 to Length(Scope.Items) - 1 do 530 623 ExpectedCharacters := ExpectedCharacters + Scope.Items[II].Character; 624 //raise Exception.Create('Parse error. Expected "' + ExpectedCharacters + '" but found "' + Text[I] + '".'); 531 625 break; 532 //raise Exception.Create('Parse error. Expected "' + ExpectedCharacters +533 //'" but found "' + Text[I] + '".');534 626 end; 535 Path.Assign(Scope.Items[C].RulePath);536 Path.Next;537 627 end; 538 628 end; … … 612 702 Found: Boolean; 613 703 PathIndex: Integer; 614 Index: Integer; 615 begin 704 NextItemIndex, NextCharIndex: Integer; 705 NextRule: TGrammerRule; 706 begin 707 Processed := True; 616 708 case ItemType of 617 709 itTerminal: begin … … 619 711 Characters.Items[High(Characters.Items)].Character := Character; 620 712 Characters.Items[High(Characters.Items)].RulePath.Assign(Path); 713 with Characters.Items[High(Characters.Items)].RulePath do begin 714 Inc(Items[High(Items)].ItemIndex); 715 end; 621 716 end; 622 717 itNonterminal: begin … … 625 720 end; 626 721 if Optional then begin 627 PathIndex := High(Path.Items); 628 Found := False; 629 while not Found and (PathIndex >= 0) do begin 630 with Path.Items[PathIndex] do begin 631 //if High(Path.Items) = PathIndex then 632 Index := ItemIndex + 1; 633 // else Index := ItemIndex; 634 635 if Index < Length(Rule.Items) then begin 636 SetLength(Path.Items, PathIndex + 1); 637 Inc(Path.Items[PathIndex].ItemIndex); 638 //Inc(Path.Items[PathIndex].CharIndex); 639 Rule.Items[Index].GetPossibleCharacters(Path, Characters); 640 Found := True; 641 end else Dec(PathIndex); 642 end; 643 end; 722 // Forward generation to upper item 723 //SetLength(Path.Items, Length(Path.Items) - 1); 724 with Path.Items[High(Path.Items)] do begin 725 NextItemIndex := ItemIndex; 726 NextCharIndex := CharIndex; 727 NextRule := Rule; 728 end; 729 SetLength(Path.Items, Length(Path.Items) - 1); 730 NextRule.GetPossibleCharacters(Path, Characters, NextItemIndex + 1, NextCharIndex); 644 731 end; 645 732 end; … … 665 752 with Items[Index] do if Rule.Items[ItemIndex].Repetition then begin 666 753 Success := True; 667 Inc(CharIndex);754 //Inc(CharIndex); 668 755 end else begin 669 756 if ((ItemIndex + 1) < Length(Rule.Items)) and (Rule.RuleType = rtSequence) then begin 670 757 Inc(ItemIndex); 671 Inc(CharIndex);758 //Inc(CharIndex); 672 759 Success := True; 673 760 end else Dec(Index); … … 684 771 ItemIndex := Source.ItemIndex; 685 772 CharIndex := Source.CharIndex; 773 Affected := Source.Affected; 686 774 end; 687 775
Note:
See TracChangeset
for help on using the changeset viewer.