Changeset 7


Ignore:
Timestamp:
Oct 12, 2007, 1:43:10 PM (17 years ago)
Author:
george
Message:

Tvorba gramatiky pascalu

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • UGrammer.pas

    r6 r7  
    44
    55uses
    6   Classes, ComCtrls;
     6  Classes, ComCtrls, SysUtils;
    77
    88type
     
    5050    procedure DeleteEmpty;
    5151    procedure MergeNonterminal(ARule: TGrammerRule);
     52    procedure Join(ARule: TGrammerRule; ItemIndex: Integer);
    5253    function MergeToTerminal: string;
    5354    constructor Create;
    5455    destructor Destroy; override;
     56    procedure Assign(Source: TProgramItem);
    5557  end;
    5658
     
    6567  TGrammerItem = record
    6668  private
     69    Processed: Boolean;
    6770    Parent: TGrammerRule;
    68     Processed: Boolean;
    6971  public
    7072    ItemType: TRuleItemType;
    7173    Character: Char;
    7274    Rule: TGrammerRule;
     75    RuleName: string;
    7376    Optional: Boolean;
    7477    Repetition: Boolean;
     
    8083  private
    8184  public
     85    Ownership: TGrammerRule;
    8286    Name: string;
    8387    RuleType: TRuleType;
    8488    Items: array of TGrammerItem;
    8589    procedure ClearProcessed;
     90    function Add: TGrammerItem;
    8691    procedure AddTerminal(Character: Char; Optional, Repetition: Boolean);
    8792    procedure AddTerminalText(Text: string);
     
    100105    procedure ClearProcessed;
    101106    procedure Parse(Text: string; var ParsedProgram: TProgram);
     107    procedure CorrectRuleLinks;
    102108    destructor Destroy; override;
    103109  end;
     
    106112implementation
    107113
     114uses
     115  UMainForm;
     116
    108117{ TGrammerRule }
     118
     119function TGrammerRule.Add: TGrammerItem;
     120begin
     121  SetLength(Items, Length(Items) + 1);
     122  Result := Items[High(Items)];
     123  Result.Parent := Self;
     124end;
    109125
    110126procedure TGrammerRule.AddRule(Rule: TGrammerRule; Optional,
     
    147163constructor TGrammerRule.Create;
    148164begin
    149 
     165  Ownership := nil;
    150166end;
    151167
     
    225241  for I := 0 to Rules.Count - 1 do with TGrammerRule(Rules[I]) do begin
    226242    ClearProcessed;
     243  end;
     244end;
     245
     246procedure TGrammer.CorrectRuleLinks;
     247var
     248  I: Integer;
     249  II: Integer;
     250  J: Integer;
     251begin
     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;
    227262  end;
    228263end;
     
    294329          ExpectedCharacters := ExpectedCharacters + Scope.Items[II].Character;
    295330        //raise Exception.Create('Parse error. Expected "' + ExpectedCharacters + '" but found "' + Text[I] + '".');
     331        MainForm.Label1.Caption := 'Parse error. Expected "' + ExpectedCharacters + '" but found "' + Text[I] + '".';
    296332        break;
    297333      end;
     
    361397{ TProgramItem }
    362398
     399procedure TProgramItem.Assign(Source: TProgramItem);
     400begin
     401 
     402end;
     403
    363404constructor TProgramItem.Create;
    364405begin
     
    423464  Items.Free;
    424465  inherited;
     466end;
     467
     468procedure TProgramItem.Join(ARule: TGrammerRule; ItemIndex: Integer);
     469var
     470  SubProgramItem: TProgramItem;
     471  I: Integer;
     472begin
     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);
    425486end;
    426487
  • UMainForm.dfm

    r6 r7  
    2121  PixelsPerInch = 96
    2222  TextHeight = 13
     23  object Label1: TLabel
     24    Left = 8
     25    Top = 297
     26    Width = 3
     27    Height = 13
     28  end
    2329  object Memo1: TMemo
    2430    Left = 8
    2531    Top = 8
    26     Width = 290
    27     Height = 313
     32    Width = 346
     33    Height = 283
    2834    ScrollBars = ssBoth
    2935    TabOrder = 0
     
    3137  object Button1: TButton
    3238    Left = 304
    33     Top = 8
     39    Top = 297
    3440    Width = 50
    3541    Height = 25
     
    5662    TabOrder = 3
    5763  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
    5873end
  • UMainForm.pas

    r6 r7  
    1616    TreeView1: TTreeView;
    1717    TreeView2: TTreeView;
     18    Label1: TLabel;
     19    Button2: TButton;
    1820    procedure FormCreate(Sender: TObject);
    1921    procedure FormDestroy(Sender: TObject);
    2022    procedure Button1Click(Sender: TObject);
     23    procedure Button2Click(Sender: TObject);
    2124  private
    2225    procedure ShowProgramNode(Node: TTreeNode; SourceProgram: TProgramItem);
     
    2427  public
    2528    Grammer: TGrammer;
     29    PascalGrammer: TGrammer;
    2630    SourceProgram: TProgram;
    2731    procedure ShowProgramTree(SourceProgram: TProgram);
    2832    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;
    2938  end;
    3039
     
    4655    DeleteNonterminal(TGrammerRule(Grammer.Rules[0]));
    4756    DeleteEmpty;
     57    Join(TGrammerRule(Grammer.Rules[17]), 1);
     58    Join(TGrammerRule(Grammer.Rules[15]), 0);
     59    Join(TGrammerRule(Grammer.Rules[14]), 0);
    4860  end;
    4961  ShowProgramTree(SourceProgram);
     62end;
     63
     64procedure TMainForm.Button2Click(Sender: TObject);
     65begin
     66  ProcessProgramTree;
     67  PascalGrammer.CorrectRuleLinks;
     68  ShowGrammerTree(PascalGrammer);
    5069end;
    5170
     
    6281  SourceCode: string;
    6382begin
     83  PascalGrammer := TGrammer.Create;
     84
    6485  Grammer := TGrammer.Create;
    6586  with Grammer do begin
     
    303324begin
    304325  Memo1.Lines.SaveToFile(DefaultGrammerFileName);
    305 
     326  PascalGrammer.Free;
    306327  Grammer.Free;
    307328  SourceProgram.Free;
    308329end;
    309330
    310 procedure TMainForm.ShowGrammerTree(Grammer: TGrammer);
    311 var
    312   I, II: Integer;
     331function TMainForm.ProcessConcatenationItem(ARule: TGrammerRule; ProgramItem: TProgramItem): TGrammerItem;
     332var
     333  I: Integer;
     334  II: Integer;
     335  NewRule: TGrammerRule;
     336  NewSubRule: TGrammerRule;
     337  RuleItem: TGrammerItem;
     338type
     339  LowerChars = 'a'..'z';
     340begin
     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;
     393end;
     394
     395procedure TMainForm.ProcessProgramTree;
     396var
     397  I: Integer;
     398  NewRule: TGrammerRule;
     399begin
     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;
     416end;
     417
     418function TMainForm.ProcessSeparationItem(var ARule: TGrammerRule;
     419  ProgramItem: TProgramItem): TGrammerItem;
     420var
     421  II: Integer;
     422  NewSubRule: TGrammerRule;
     423  RuleItem: TGrammerItem;
     424begin
     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;
     441end;
     442
     443procedure TMainForm.ShowGrammerRule(TreeNode: TTreeNode; ARule: TGrammerRule;
     444  Attributs: string = '');
     445var
     446  II: Integer;
    313447  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;
     449begin
     450  with TreeView2, Items, ARule do begin
    321451      case RuleType of
    322         rtSequence: Attributs := '(Seq)';
    323         rtAlternative: Attributs := '(Alt)';
     452        rtSequence: Attributs := Attributs + '(Seq)';
     453        rtAlternative: Attributs := Attributs + '(Alt)';
    324454      end;
    325       NewTreeNode := AddChild(TopItem, Name + Attributs);
     455      NewTreeNode := AddChild(TreeNode, ARule.Name + Attributs);
    326456      for II := 0 to Length(Items) - 1 do
    327457      with Items[II] do begin
     
    329459        if Repetition then Attributs := Attributs + '(Rep)';
    330460        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;
    335472        end;
    336         AddChild(NewTreeNode, Attributs);
    337473      end;
    338474    end;
     475end;
     476
     477procedure TMainForm.ShowGrammerTree(Grammer: TGrammer);
     478var
     479  I: Integer;
     480begin
     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]));
    339487    TopItem.Expand(False);
    340488    EndUpdate;
Note: See TracChangeset for help on using the changeset viewer.