Changeset 7
- Timestamp:
- Oct 12, 2007, 1:43:10 PM (17 years ago)
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
UGrammer.pas
r6 r7 4 4 5 5 uses 6 Classes, ComCtrls ;6 Classes, ComCtrls, SysUtils; 7 7 8 8 type … … 50 50 procedure DeleteEmpty; 51 51 procedure MergeNonterminal(ARule: TGrammerRule); 52 procedure Join(ARule: TGrammerRule; ItemIndex: Integer); 52 53 function MergeToTerminal: string; 53 54 constructor Create; 54 55 destructor Destroy; override; 56 procedure Assign(Source: TProgramItem); 55 57 end; 56 58 … … 65 67 TGrammerItem = record 66 68 private 69 Processed: Boolean; 67 70 Parent: TGrammerRule; 68 Processed: Boolean;69 71 public 70 72 ItemType: TRuleItemType; 71 73 Character: Char; 72 74 Rule: TGrammerRule; 75 RuleName: string; 73 76 Optional: Boolean; 74 77 Repetition: Boolean; … … 80 83 private 81 84 public 85 Ownership: TGrammerRule; 82 86 Name: string; 83 87 RuleType: TRuleType; 84 88 Items: array of TGrammerItem; 85 89 procedure ClearProcessed; 90 function Add: TGrammerItem; 86 91 procedure AddTerminal(Character: Char; Optional, Repetition: Boolean); 87 92 procedure AddTerminalText(Text: string); … … 100 105 procedure ClearProcessed; 101 106 procedure Parse(Text: string; var ParsedProgram: TProgram); 107 procedure CorrectRuleLinks; 102 108 destructor Destroy; override; 103 109 end; … … 106 112 implementation 107 113 114 uses 115 UMainForm; 116 108 117 { TGrammerRule } 118 119 function TGrammerRule.Add: TGrammerItem; 120 begin 121 SetLength(Items, Length(Items) + 1); 122 Result := Items[High(Items)]; 123 Result.Parent := Self; 124 end; 109 125 110 126 procedure TGrammerRule.AddRule(Rule: TGrammerRule; Optional, … … 147 163 constructor TGrammerRule.Create; 148 164 begin 149 165 Ownership := nil; 150 166 end; 151 167 … … 225 241 for I := 0 to Rules.Count - 1 do with TGrammerRule(Rules[I]) do begin 226 242 ClearProcessed; 243 end; 244 end; 245 246 procedure TGrammer.CorrectRuleLinks; 247 var 248 I: Integer; 249 II: Integer; 250 J: Integer; 251 begin 252 for I := 0 to Rules.Count - 1 do with TGrammerRule(Rules[I]) do begin 253 for II := 0 to Length(Items) - 1 do with Items[II] do begin 254 if (ItemType = itNonterminal) and (Rule = nil) then begin 255 J := 0; 256 while (J < Rules.Count) and (TGrammerRule(Rules[J]).Name <> RuleName) do Inc(J); 257 if J < Rules.Count then Rule := Rules[J] else 258 raise Exception.Create('Rule link correction failed on rule ' + 259 IntToStr(I) + ' item ' + IntToStr(II)); 260 end; 261 end; 227 262 end; 228 263 end; … … 294 329 ExpectedCharacters := ExpectedCharacters + Scope.Items[II].Character; 295 330 //raise Exception.Create('Parse error. Expected "' + ExpectedCharacters + '" but found "' + Text[I] + '".'); 331 MainForm.Label1.Caption := 'Parse error. Expected "' + ExpectedCharacters + '" but found "' + Text[I] + '".'; 296 332 break; 297 333 end; … … 361 397 { TProgramItem } 362 398 399 procedure TProgramItem.Assign(Source: TProgramItem); 400 begin 401 402 end; 403 363 404 constructor TProgramItem.Create; 364 405 begin … … 423 464 Items.Free; 424 465 inherited; 466 end; 467 468 procedure TProgramItem.Join(ARule: TGrammerRule; ItemIndex: Integer); 469 var 470 SubProgramItem: TProgramItem; 471 I: Integer; 472 begin 473 if (ItemType = itNonterminal) and (Rule = ARule) then begin 474 SubProgramItem := TProgramItem(Items[ItemIndex]); 475 RuleBefore := SubProgramItem.RuleBefore; 476 Rule := SubProgramItem.Rule; 477 ItemType := SubProgramItem.ItemType; 478 Value := SubProgramItem.Value; 479 Items[ItemIndex] := nil; 480 for I := 0 to Items.Count - 1 do 481 if Assigned(Items[I]) then TProgramItem(Items[I]).Free; 482 Items := SubProgramItem.Items; 483 end; 484 for I := 0 to Items.Count - 1 do 485 TProgramItem(Items[I]).Join(ARule, ItemIndex); 425 486 end; 426 487 -
UMainForm.dfm
r6 r7 21 21 PixelsPerInch = 96 22 22 TextHeight = 13 23 object Label1: TLabel 24 Left = 8 25 Top = 297 26 Width = 3 27 Height = 13 28 end 23 29 object Memo1: TMemo 24 30 Left = 8 25 31 Top = 8 26 Width = 29027 Height = 31332 Width = 346 33 Height = 283 28 34 ScrollBars = ssBoth 29 35 TabOrder = 0 … … 31 37 object Button1: TButton 32 38 Left = 304 33 Top = 839 Top = 297 34 40 Width = 50 35 41 Height = 25 … … 56 62 TabOrder = 3 57 63 end 64 object Button2: TButton 65 Left = 232 66 Top = 297 67 Width = 66 68 Height = 25 69 Caption = 'Analyze' 70 TabOrder = 4 71 OnClick = Button2Click 72 end 58 73 end -
UMainForm.pas
r6 r7 16 16 TreeView1: TTreeView; 17 17 TreeView2: TTreeView; 18 Label1: TLabel; 19 Button2: TButton; 18 20 procedure FormCreate(Sender: TObject); 19 21 procedure FormDestroy(Sender: TObject); 20 22 procedure Button1Click(Sender: TObject); 23 procedure Button2Click(Sender: TObject); 21 24 private 22 25 procedure ShowProgramNode(Node: TTreeNode; SourceProgram: TProgramItem); … … 24 27 public 25 28 Grammer: TGrammer; 29 PascalGrammer: TGrammer; 26 30 SourceProgram: TProgram; 27 31 procedure ShowProgramTree(SourceProgram: TProgram); 28 32 procedure ShowGrammerTree(Grammer: TGrammer); 33 procedure ShowGrammerRule(TreeNode: TTreeNode; ARule: TGrammerRule; 34 Attributs: string = ''); 35 procedure ProcessProgramTree; 36 function ProcessConcatenationItem(ARule: TGrammerRule; ProgramItem: TProgramItem): TGrammerItem; 37 function ProcessSeparationItem(var ARule: TGrammerRule; ProgramItem: TProgramItem): TGrammerItem; 29 38 end; 30 39 … … 46 55 DeleteNonterminal(TGrammerRule(Grammer.Rules[0])); 47 56 DeleteEmpty; 57 Join(TGrammerRule(Grammer.Rules[17]), 1); 58 Join(TGrammerRule(Grammer.Rules[15]), 0); 59 Join(TGrammerRule(Grammer.Rules[14]), 0); 48 60 end; 49 61 ShowProgramTree(SourceProgram); 62 end; 63 64 procedure TMainForm.Button2Click(Sender: TObject); 65 begin 66 ProcessProgramTree; 67 PascalGrammer.CorrectRuleLinks; 68 ShowGrammerTree(PascalGrammer); 50 69 end; 51 70 … … 62 81 SourceCode: string; 63 82 begin 83 PascalGrammer := TGrammer.Create; 84 64 85 Grammer := TGrammer.Create; 65 86 with Grammer do begin … … 303 324 begin 304 325 Memo1.Lines.SaveToFile(DefaultGrammerFileName); 305 326 PascalGrammer.Free; 306 327 Grammer.Free; 307 328 SourceProgram.Free; 308 329 end; 309 330 310 procedure TMainForm.ShowGrammerTree(Grammer: TGrammer); 311 var 312 I, II: Integer; 331 function TMainForm.ProcessConcatenationItem(ARule: TGrammerRule; ProgramItem: TProgramItem): TGrammerItem; 332 var 333 I: Integer; 334 II: Integer; 335 NewRule: TGrammerRule; 336 NewSubRule: TGrammerRule; 337 RuleItem: TGrammerItem; 338 type 339 LowerChars = 'a'..'z'; 340 begin 341 with ProgramItem do begin 342 ARule.RuleType := rtSequence; 343 for II := 0 to Items.Count - 1 do begin 344 RuleItem := ARule.Add; 345 if TProgramItem(Items[II]).Rule.Name = 'Term' then begin 346 RuleItem.ItemType := itNonterminal; 347 with TProgramItem(TProgramItem(Items[II]).Items[0]) do 348 if (Value[1] >= 'a') and (Value[1] <= 'z') then begin 349 RuleItem.ItemType := itNonterminal; 350 RuleItem.RuleName := Value; 351 RuleItem.Rule := nil; 352 end else begin 353 NewRule := TGrammerRule.Create; 354 NewRule.Ownership := ARule; 355 NewRule.Name := 'Term'; 356 NewRule.AddTerminalText(Value); 357 PascalGrammer.Rules.Add(NewRule); 358 RuleItem.Rule := NewRule; 359 RuleItem.ItemType := itNonterminal; 360 end; 361 end else if TProgramItem(Items[II]).Rule.Name = 'GroupingBlock' then begin 362 NewRule := TGrammerRule.Create; 363 NewRule.Ownership := ARule; 364 NewRule.RuleType := rtSequence; 365 NewRule.Name := 'Group'; 366 ProcessSeparationItem(NewRule, TProgramItem(Items[II]).Items[1]); 367 PascalGrammer.Rules.Add(NewRule); 368 RuleItem.ItemType := itNonterminal; 369 RuleItem.Rule := NewRule; 370 end else if TProgramItem(Items[II]).Rule.Name = 'OptionBlock' then begin 371 NewRule := TGrammerRule.Create; 372 NewRule.Ownership := ARule; 373 NewRule.RuleType := rtSequence; 374 NewRule.Name := 'Option'; 375 ProcessSeparationItem(NewRule, TProgramItem(Items[II]).Items[1]); 376 PascalGrammer.Rules.Add(NewRule); 377 RuleItem.ItemType := itNonterminal; 378 RuleItem.Optional := True; 379 RuleItem.Rule := NewRule; 380 end else if TProgramItem(Items[II]).Rule.Name = 'RepetitionBlock' then begin 381 NewRule := TGrammerRule.Create; 382 NewRule.Ownership := ARule; 383 NewRule.RuleType := rtSequence; 384 NewRule.Name := 'Repetition'; 385 ProcessSeparationItem(NewRule, TProgramItem(Items[II]).Items[1]); 386 PascalGrammer.Rules.Add(NewRule); 387 RuleItem.Repetition := True; 388 RuleItem.ItemType := itNonterminal; 389 RuleItem.Rule := NewRule; 390 end; 391 end; 392 end; 393 end; 394 395 procedure TMainForm.ProcessProgramTree; 396 var 397 I: Integer; 398 NewRule: TGrammerRule; 399 begin 400 for I := 0 to PascalGrammer.Rules.Count - 1 do 401 TGrammerRule(PascalGrammer.Rules[I]).Free; 402 PascalGrammer.Rules.Clear; 403 PascalGrammer.TopRule := nil; 404 with SourceProgram.TopItem do begin 405 with TProgramItem(Items[0]) do begin 406 for I := 0 to Items.Count - 1 do with TProgramItem(Items[I]) do begin 407 NewRule := TGrammerRule.Create; 408 with PascalGrammer do 409 if TopRule = nil then TopRule := NewRule; 410 NewRule.Name := TProgramItem(Items[0]).Value; 411 ProcessSeparationItem(NewRule, TProgramItem(Items[2])); 412 PascalGrammer.Rules.Add(NewRule); 413 end; 414 end; 415 end; 416 end; 417 418 function TMainForm.ProcessSeparationItem(var ARule: TGrammerRule; 419 ProgramItem: TProgramItem): TGrammerItem; 420 var 421 II: Integer; 422 NewSubRule: TGrammerRule; 423 RuleItem: TGrammerItem; 424 begin 425 with ProgramItem do 426 if Items.Count > 1 then begin 427 ARule.RuleType := rtAlternative; 428 for II := 0 to Items.Count - 1 do begin 429 NewSubRule := TGrammerRule.Create; 430 NewSubRule.Ownership := ARule; 431 NewSubRule.Name := ARule.Name; 432 RuleItem := ARule.Add; 433 RuleItem.ItemType := itNonterminal; 434 RuleItem.Rule := NewSubRule; 435 ProcessConcatenationItem(NewSubRule, TProgramItem(Items[II])); 436 PascalGrammer.Rules.Add(NewSubRule); 437 end; 438 end else begin 439 ProcessConcatenationItem(ARule, TProgramItem(Items[0])); 440 end; 441 end; 442 443 procedure TMainForm.ShowGrammerRule(TreeNode: TTreeNode; ARule: TGrammerRule; 444 Attributs: string = ''); 445 var 446 II: Integer; 313 447 NewTreeNode: TTreeNode; 314 Attributs: string; 315 begin 316 with Grammer, TreeView2, Items do begin 317 BeginUpdate; 318 Clear; 319 TopItem := AddChild(nil, 'Gramatika'); 320 for I := 0 to Rules.Count - 1 do with TGrammerRule(Rules[I]) do begin 448 // NewNode: TTreeNode; 449 begin 450 with TreeView2, Items, ARule do begin 321 451 case RuleType of 322 rtSequence: Attributs := '(Seq)';323 rtAlternative: Attributs := '(Alt)';452 rtSequence: Attributs := Attributs + '(Seq)'; 453 rtAlternative: Attributs := Attributs + '(Alt)'; 324 454 end; 325 NewTreeNode := AddChild(T opItem,Name + Attributs);455 NewTreeNode := AddChild(TreeNode, ARule.Name + Attributs); 326 456 for II := 0 to Length(Items) - 1 do 327 457 with Items[II] do begin … … 329 459 if Repetition then Attributs := Attributs + '(Rep)'; 330 460 case ItemType of 331 itTerminal: Attributs := Character + Attributs; 332 itNonterminal: if Assigned(Rule) then 333 Attributs := '<' + Rule.Name + '>' + Attributs; 334 else Attributs := '<?>' + Attributs; 461 itTerminal: begin 462 Attributs := Character + Attributs; 463 AddChild(NewTreeNode, Attributs); 464 end; 465 itNonterminal: begin 466 if Assigned(Rule) then begin 467 if Rule.Ownership = ARule then 468 ShowGrammerRule(NewTreeNode, Rule, Attributs) 469 else AddChild(NewTreeNode, '<' + Rule.Name + '>' + Attributs); 470 end else AddChild(NewTreeNode, '<?>' + Attributs); 471 end; 335 472 end; 336 AddChild(NewTreeNode, Attributs);337 473 end; 338 474 end; 475 end; 476 477 procedure TMainForm.ShowGrammerTree(Grammer: TGrammer); 478 var 479 I: Integer; 480 begin 481 with Grammer, TreeView2, Items do begin 482 BeginUpdate; 483 Clear; 484 TopItem := AddChild(nil, 'Gramatika'); 485 for I := 0 to Rules.Count - 1 do with TGrammerRule(Rules[I]) do 486 if Ownership = nil then ShowGrammerRule(TopItem, TGrammerRule(Rules[I])); 339 487 TopItem.Expand(False); 340 488 EndUpdate;
Note:
See TracChangeset
for help on using the changeset viewer.