source: branches/Analyzátor gramatiky/UProgram.pas

Last change on this file was 32, checked in by george, 15 years ago
  • Průběžné uložení.
File size: 6.3 KB
Line 
1unit UProgram;
2
3{$MODE Delphi}
4
5interface
6
7uses
8 Classes, ComCtrls, SysUtils, UGrammer, fgl;
9
10type
11 TProgramItem = class;
12
13 TProgramItemList = specialize TFPGObjectList<TProgramItem>;
14
15 TProgramItem = class
16 public
17 RuleBefore: TGrammerRule;
18 Items: TProgramItemList;
19 ItemType: TRuleItemType;
20 Rule: TGrammerRule;
21 Value: string;
22 procedure Delete;
23 procedure DeleteItem(Index: Integer);
24 procedure DeleteNonterminal(ARule: TGrammerRule);
25 procedure DeleteEmpty;
26 procedure MergeNonterminal(ARule: TGrammerRule);
27 procedure Join(ARule: TGrammerRule; ItemIndex: Integer);
28 function MergeToTerminal: string;
29 constructor Create;
30 destructor Destroy; override;
31 procedure Assign(Source: TProgramItem);
32 end;
33
34 TProgram = class
35 public
36 TopItem: TProgramItem;
37 constructor Create;
38 procedure Insert(Path: TGrammerPath; Character: Char);
39 procedure Parse(Grammer: TGrammer; Tokens: TStringList);
40 destructor Destroy; override;
41 end;
42
43implementation
44
45{ TProgram }
46
47constructor TProgram.Create;
48begin
49 TopItem := TProgramItem.Create;
50end;
51
52destructor TProgram.Destroy;
53begin
54 TopItem.Free;
55 inherited;
56end;
57
58procedure TProgram.Insert(Path: TGrammerPath; Character: Char);
59var
60 I: Integer;
61 SelectedProgramItem: TProgramItem;
62begin
63 SelectedProgramItem := TopItem;
64 for I := 0 to Path.Items.Count - 1 do
65 with Path.Items[I] do begin
66 SelectedProgramItem.ItemType := itNonterminal;
67 if not Assigned(SelectedProgramItem.Rule) then SelectedProgramItem.Rule := Rule;
68 if SelectedProgramItem.Rule = Rule then begin
69// if (Rule.RuleType = rtSequence) or (SelectedProgramItem.Rule = SelectedProgramItem.RuleBefore) then begin
70 if SelectedProgramItem.Items.Count < (CharIndex + 1) then
71 SelectedProgramItem.Items.Count := CharIndex + 1;
72 if not Assigned(SelectedProgramItem.Items[CharIndex]) then
73 SelectedProgramItem.Items[CharIndex] := TProgramItem.Create;
74 SelectedProgramItem := SelectedProgramItem.Items[CharIndex];
75(* end else begin
76 SelectedProgramItem.Items.Count := SelectedProgramItem.Items.Count + 1;
77 if not Assigned(SelectedProgramItem.Items[SelectedProgramItem.Items.Count - 1]) then
78 SelectedProgramItem.Items[SelectedProgramItem.Items.Count - 1] := TProgramItem.Create;
79 SelectedProgramItem := TProgramItem(SelectedProgramItem.Items[SelectedProgramItem.Items.Count - 1]);
80 end;
81*)
82 end;
83 end;
84 with SelectedProgramItem do begin
85 ItemType := itTerminal;
86 Value := Character;
87 end;
88end;
89
90procedure TProgram.Parse(Grammer: TGrammer; Tokens: TStringList);
91var
92 Path: TGrammerPath;
93 I, II: Integer;
94 UseIndex: Integer;
95 UseCharIndex: Integer;
96 UseRule: TGrammerRule;
97 Level: array of Integer;
98begin
99 Path := TGrammerPath.Create;
100 with Path.Items[Path.Items.Add(TPathItem.Create)] do begin
101 Rule := Grammer.TopRule;
102 ItemIndex := 0;
103 CharIndex := -1;
104 end;
105
106 for I := 0 to Tokens.Count - 1 do begin
107 UseIndex := Path.Items[Path.Items.Count - 1].ItemIndex;
108 UseCharIndex := Path.Items[Path.Items.Count - 1].CharIndex;
109 UseRule := Path.Items[Path.Items.Count - 1].Rule;
110 Path.Items.Delete(Path.Items.Count - 1);
111 Grammer.ClearProcessed;
112 if UseRule.Check(Path, Tokens[I], UseIndex, UseCharIndex) then
113 begin
114
115 end else begin
116 //raise Exception.Create('Parse error. Expected "' + Tokens[I] + '" but found "' + Text[I] + '".');
117 //MainForm.StatusBar1.SimpleText := 'Parse error. Expected "' + ExpectedCharacters + '" but found "' + Text[I] + '".';
118 break;
119 end;
120 end;
121 Path.Destroy;
122end;
123
124procedure TProgramItem.MergeNonterminal(ARule: TGrammerRule);
125var
126 I: Integer;
127begin
128 for I := 0 to Items.Count - 1 do
129 with Items[I] do begin
130 if ItemType = itNonterminal then begin
131 if Rule.Name = ARule.Name then begin
132 ItemType := itTerminal;
133 Value := MergeToTerminal;
134 end else MergeNonterminal(ARule);
135 end;
136 end;
137end;
138
139{ TProgramItem }
140
141procedure TProgramItem.Assign(Source: TProgramItem);
142begin
143
144end;
145
146constructor TProgramItem.Create;
147begin
148 Items := TProgramItemList.Create;
149end;
150
151procedure TProgramItem.Delete;
152var
153 I: Integer;
154begin
155 for I := 0 to Items.Count - 1 do
156 with Items[I] do begin
157 if ItemType = itNonterminal then Delete;
158 end;
159end;
160
161procedure TProgramItem.DeleteEmpty;
162var
163 I: Integer;
164begin
165 I := 0;
166 while I < Items.Count do
167 with Items[I] do begin
168 if ItemType = itNonterminal then begin
169 if Items.Count = 0 then begin
170 Self.DeleteItem(I);
171 end else begin
172 DeleteEmpty;
173 Inc(I);
174 end;
175 end else Inc(I);
176 end;
177end;
178
179procedure TProgramItem.DeleteItem(Index: Integer);
180begin
181 if Items[Index].ItemType = itNonterminal then
182 Items[Index].Delete;
183 Items.Delete(Index);
184end;
185
186procedure TProgramItem.DeleteNonterminal(ARule: TGrammerRule);
187var
188 I: Integer;
189begin
190 I := 0;
191 while I < Items.Count do
192 with Items[I] do begin
193 if ItemType = itNonterminal then begin
194 if Rule.Name = ARule.Name then begin
195 Self.DeleteItem(I);
196 end else begin
197 DeleteNonterminal(ARule);
198 Inc(I);
199 end;
200 end else Inc(I);
201 end;
202end;
203
204destructor TProgramItem.Destroy;
205begin
206 Items.Destroy;
207 inherited;
208end;
209
210procedure TProgramItem.Join(ARule: TGrammerRule; ItemIndex: Integer);
211var
212 SubProgramItem: TProgramItem;
213 I: Integer;
214begin
215 if (ItemType = itNonterminal) and (Rule = ARule) then begin
216 SubProgramItem := Items[ItemIndex];
217 RuleBefore := SubProgramItem.RuleBefore;
218 Rule := SubProgramItem.Rule;
219 ItemType := SubProgramItem.ItemType;
220 Value := SubProgramItem.Value;
221 Items[ItemIndex] := nil;
222 for I := 0 to Items.Count - 1 do
223 if Assigned(Items[I]) then Items[I].Free;
224 Items := SubProgramItem.Items;
225 end;
226 for I := 0 to Items.Count - 1 do
227 Items[I].Join(ARule, ItemIndex);
228end;
229
230function TProgramItem.MergeToTerminal: string;
231var
232 I: Integer;
233begin
234 Result := '';
235 for I := 0 to Items.Count - 1 do
236 with Items[I] do begin
237 if ItemType = itTerminal then Result := Result + Value
238 else Result := Result + MergeToTerminal;
239 end;
240end;
241
242end.
Note: See TracBrowser for help on using the repository browser.