| 1 | unit UMainForm;
|
|---|
| 2 |
|
|---|
| 3 | {$MODE Delphi}
|
|---|
| 4 |
|
|---|
| 5 | interface
|
|---|
| 6 |
|
|---|
| 7 | uses
|
|---|
| 8 | LCLIntf, SysUtils, Classes, Graphics, Controls, Forms,
|
|---|
| 9 | Dialogs, StdCtrls, ComCtrls, LResources, UGrammer, UProgram;
|
|---|
| 10 |
|
|---|
| 11 | const
|
|---|
| 12 | DefaultGrammerFileName: string = '../../grammer/test.grm';
|
|---|
| 13 | DefaultPascalFileName: string = '../../pascal/test.pas';
|
|---|
| 14 |
|
|---|
| 15 | type
|
|---|
| 16 | TMainForm = class(TForm)
|
|---|
| 17 | Memo1: TMemo;
|
|---|
| 18 | Button1: TButton;
|
|---|
| 19 | TreeView1: TTreeView;
|
|---|
| 20 | TreeView2: TTreeView;
|
|---|
| 21 | Button2: TButton;
|
|---|
| 22 | Memo2: TMemo;
|
|---|
| 23 | Button3: TButton;
|
|---|
| 24 | StatusBar1: TStatusBar;
|
|---|
| 25 | Button4: TButton;
|
|---|
| 26 | procedure FormCreate(Sender: TObject);
|
|---|
| 27 | procedure FormDestroy(Sender: TObject);
|
|---|
| 28 | procedure Button1Click(Sender: TObject);
|
|---|
| 29 | procedure Button2Click(Sender: TObject);
|
|---|
| 30 | procedure Button3Click(Sender: TObject);
|
|---|
| 31 | procedure Button4Click(Sender: TObject);
|
|---|
| 32 | private
|
|---|
| 33 | procedure ShowProgramNode(Node: TTreeNode; SourceProgram: TProgramItem);
|
|---|
| 34 | public
|
|---|
| 35 | Grammer: TGrammer;
|
|---|
| 36 | PascalGrammer: TGrammer;
|
|---|
| 37 | SourceProgram: TProgram;
|
|---|
| 38 | PascalProgram: TProgram;
|
|---|
| 39 | procedure ShowProgramTree(SourceProgram: TProgram);
|
|---|
| 40 | procedure ShowGrammerTree(Grammer: TGrammer);
|
|---|
| 41 | procedure ShowGrammerRule(TreeNode: TTreeNode; ARule: TGrammerRule;
|
|---|
| 42 | Attributs: string = '');
|
|---|
| 43 | procedure ProcessProgramTree;
|
|---|
| 44 | function ProcessConcatenationItem(ARule: TGrammerRule; ProgramItem: TProgramItem): TGrammerItem;
|
|---|
| 45 | function ProcessSeparationItem(var ARule: TGrammerRule; ProgramItem: TProgramItem): TGrammerItem;
|
|---|
| 46 | end;
|
|---|
| 47 |
|
|---|
| 48 | var
|
|---|
| 49 | MainForm: TMainForm;
|
|---|
| 50 |
|
|---|
| 51 |
|
|---|
| 52 | implementation
|
|---|
| 53 |
|
|---|
| 54 | procedure TMainForm.Button1Click(Sender: TObject);
|
|---|
| 55 | begin
|
|---|
| 56 | SourceProgram.Free;
|
|---|
| 57 | SourceProgram := TProgram.Create;
|
|---|
| 58 | SourceProgram.Parse(Grammer, Memo1.Text);
|
|---|
| 59 | ShowProgramTree(SourceProgram);
|
|---|
| 60 | end;
|
|---|
| 61 |
|
|---|
| 62 | procedure TMainForm.Button2Click(Sender: TObject);
|
|---|
| 63 | begin
|
|---|
| 64 | ProcessProgramTree;
|
|---|
| 65 | PascalGrammer.CorrectRuleLinks;
|
|---|
| 66 | ShowGrammerTree(PascalGrammer);
|
|---|
| 67 | end;
|
|---|
| 68 |
|
|---|
| 69 | procedure TMainForm.Button3Click(Sender: TObject);
|
|---|
| 70 | begin
|
|---|
| 71 | PascalProgram.Free;
|
|---|
| 72 | PascalProgram := TProgram.Create;
|
|---|
| 73 | PascalProgram.Parse(PascalGrammer, Memo2.Text);
|
|---|
| 74 | with PascalProgram.TopItem, PascalGrammer do begin
|
|---|
| 75 | // MergeNonterminal(TGrammerRule(Rules[7]));
|
|---|
| 76 | // MergeNonterminal(TGrammerRule(Rules[9]));
|
|---|
| 77 | // DeleteNonterminal(TGrammerRule(Rules[0]));
|
|---|
| 78 | // DeleteEmpty;
|
|---|
| 79 | // Join(TGrammerRule(Rules[17]), 1);
|
|---|
| 80 | // Join(TGrammerRule(Rules[15]), 0);
|
|---|
| 81 | // Join(TGrammerRule(Rules[14]), 0);
|
|---|
| 82 | end;
|
|---|
| 83 | ShowProgramTree(PascalProgram);
|
|---|
| 84 | end;
|
|---|
| 85 |
|
|---|
| 86 | procedure TMainForm.Button4Click(Sender: TObject);
|
|---|
| 87 | begin
|
|---|
| 88 | with SourceProgram.TopItem do begin
|
|---|
| 89 | MergeNonterminal(Grammer.Rules[7]);
|
|---|
| 90 | MergeNonterminal(Grammer.Rules[9]);
|
|---|
| 91 | DeleteNonterminal(Grammer.Rules[0]);
|
|---|
| 92 | DeleteEmpty;
|
|---|
| 93 | Join(Grammer.Rules[17], 1);
|
|---|
| 94 | Join(Grammer.Rules[15], 0);
|
|---|
| 95 | Join(Grammer.Rules[14], 0);
|
|---|
| 96 | end;
|
|---|
| 97 | ShowProgramTree(SourceProgram);
|
|---|
| 98 | end;
|
|---|
| 99 |
|
|---|
| 100 | procedure TMainForm.FormCreate(Sender: TObject);
|
|---|
| 101 | var
|
|---|
| 102 | LowerCaseAlphabeticCharacter, UpperCaseAlphabeticCharacter,
|
|---|
| 103 | Digit, AlphabeticCharacter, Number, AlphaNumericCharacter,
|
|---|
| 104 | Identifier, Expression, RuleString, Rule, RuleList,
|
|---|
| 105 | OptionBlock, RepetitionBlock, GroupingBlock,
|
|---|
| 106 | Term, AllCharacters, WhiteSpace, Concatenation, ConcatenationBlock,
|
|---|
| 107 | Separation, SeparationBlock, Definition: TGrammerRule;
|
|---|
| 108 | C: Char;
|
|---|
| 109 | I: Integer;
|
|---|
| 110 | begin
|
|---|
| 111 | PascalGrammer := TGrammer.Create;
|
|---|
| 112 |
|
|---|
| 113 | Grammer := TGrammer.Create;
|
|---|
| 114 | with Grammer do begin
|
|---|
| 115 | WhiteSpace := TGrammerRule.Create;
|
|---|
| 116 | with WhiteSpace do begin
|
|---|
| 117 | Name := 'WhiteSpace';
|
|---|
| 118 | Token := True;
|
|---|
| 119 | RuleType := rtAlternative;
|
|---|
| 120 | AddTerminal(' ', False, False);
|
|---|
| 121 | AddTerminal(#10, False, False);
|
|---|
| 122 | AddTerminal(#13, False, False);
|
|---|
| 123 | end;
|
|---|
| 124 | Rules.Add(WhiteSpace);
|
|---|
| 125 |
|
|---|
| 126 | LowerCaseAlphabeticCharacter := TGrammerRule.Create;
|
|---|
| 127 | with LowerCaseAlphabeticCharacter do begin
|
|---|
| 128 | Name := 'LowerCaseAlphabeticCharacter';
|
|---|
| 129 | RuleType := rtAlternative;
|
|---|
| 130 | for C := 'a' to 'z' do AddTerminal(C, False, False);
|
|---|
| 131 | end;
|
|---|
| 132 | Rules.Add(LowerCaseAlphabeticCharacter);
|
|---|
| 133 |
|
|---|
| 134 | UpperCaseAlphabeticCharacter := TGrammerRule.Create;
|
|---|
| 135 | with UpperCaseAlphabeticCharacter do begin
|
|---|
| 136 | Name := 'UpperCaseAlphabeticCharacter';
|
|---|
| 137 | RuleType := rtAlternative;
|
|---|
| 138 | for C := 'A' to 'Z' do AddTerminal(C, False, False);
|
|---|
| 139 | end;
|
|---|
| 140 | Rules.Add(UpperCaseAlphabeticCharacter);
|
|---|
| 141 |
|
|---|
| 142 | AlphabeticCharacter := TGrammerRule.Create;
|
|---|
| 143 | with AlphabeticCharacter do begin
|
|---|
| 144 | Name := 'AlphabeticCharacter';
|
|---|
| 145 | RuleType := rtAlternative;
|
|---|
| 146 | AddRule(LowerCaseAlphabeticCharacter, False, False);
|
|---|
| 147 | AddRule(UpperCaseAlphabeticCharacter, False, False);
|
|---|
| 148 | end;
|
|---|
| 149 | Rules.Add(AlphabeticCharacter);
|
|---|
| 150 |
|
|---|
| 151 | Digit := TGrammerRule.Create;
|
|---|
| 152 | with Digit do begin
|
|---|
| 153 | Name := 'Digit';
|
|---|
| 154 | RuleType := rtAlternative;
|
|---|
| 155 | for C := '0' to '9' do AddTerminal(C, False, False);
|
|---|
| 156 | end;
|
|---|
| 157 | Rules.Add(Digit);
|
|---|
| 158 |
|
|---|
| 159 | Number := TGrammerRule.Create;
|
|---|
| 160 | with Number do begin
|
|---|
| 161 | Name := 'Number';
|
|---|
| 162 | Token := True;
|
|---|
| 163 | RuleType := rtSequence;
|
|---|
| 164 | AddTerminal('-', True, False);
|
|---|
| 165 | AddRule(Digit, False, True);
|
|---|
| 166 | end;
|
|---|
| 167 | Rules.Add(Number);
|
|---|
| 168 |
|
|---|
| 169 | AlphaNumericCharacter := TGrammerRule.Create;
|
|---|
| 170 | with AlphaNumericCharacter do begin
|
|---|
| 171 | Name := 'AlphaNumericCharacter';
|
|---|
| 172 | RuleType := rtAlternative;
|
|---|
| 173 | AddRule(Digit, False, False);
|
|---|
| 174 | AddRule(AlphabeticCharacter, False, False);
|
|---|
| 175 | AddTerminal('_', False, False);
|
|---|
| 176 | end;
|
|---|
| 177 | Rules.Add(AlphaNumericCharacter);
|
|---|
| 178 |
|
|---|
| 179 | Identifier := TGrammerRule.Create;
|
|---|
| 180 | with Identifier do begin
|
|---|
| 181 | Name := 'Identifier';
|
|---|
| 182 | Token := True;
|
|---|
| 183 | RuleType := rtSequence;
|
|---|
| 184 | AddRule(AlphabeticCharacter, False, False);
|
|---|
| 185 | AddRule(AlphaNumericCharacter, True, True);
|
|---|
| 186 | end;
|
|---|
| 187 | Rules.Add(Identifier);
|
|---|
| 188 |
|
|---|
| 189 | AllCharacters := TGrammerRule.Create;
|
|---|
| 190 | with AllCharacters do begin
|
|---|
| 191 | Name := 'AllCharacters';
|
|---|
| 192 | RuleType := rtAlternative;
|
|---|
| 193 | for I := 32 to 38 do AddTerminal(Chr(I), False, False);
|
|---|
| 194 | for I := 40 to 125 do AddTerminal(Chr(I), False, False);
|
|---|
| 195 | end;
|
|---|
| 196 | Rules.Add(AllCharacters);
|
|---|
| 197 |
|
|---|
| 198 | RuleString := TGrammerRule.Create;
|
|---|
| 199 | with RuleString do begin
|
|---|
| 200 | Name := 'String';
|
|---|
| 201 | Token := True;
|
|---|
| 202 | RuleType := rtSequence;
|
|---|
| 203 | AddTerminal('''', False, False);
|
|---|
| 204 | AddRule(AllCharacters, True, True);
|
|---|
| 205 | AddTerminal('''', False, False);
|
|---|
| 206 | end;
|
|---|
| 207 | Rules.Add(RuleString);
|
|---|
| 208 |
|
|---|
| 209 | Concatenation := TGrammerRule.Create;
|
|---|
| 210 | Separation := TGrammerRule.Create;
|
|---|
| 211 |
|
|---|
| 212 | OptionBlock := TGrammerRule.Create;
|
|---|
| 213 | with OptionBlock do begin
|
|---|
| 214 | Name := 'OptionBlock';
|
|---|
| 215 | RuleType := rtSequence;
|
|---|
| 216 | AddTerminal('[', False, False);
|
|---|
| 217 | AddRule(WhiteSpace, True, True);
|
|---|
| 218 | AddRule(Separation, False, False);
|
|---|
| 219 | AddRule(WhiteSpace, True, True);
|
|---|
| 220 | AddTerminal(']', False, False);
|
|---|
| 221 | end;
|
|---|
| 222 | Rules.Add(OptionBlock);
|
|---|
| 223 |
|
|---|
| 224 | RepetitionBlock := TGrammerRule.Create;
|
|---|
| 225 | with RepetitionBlock do begin
|
|---|
| 226 | Name := 'RepetitionBlock';
|
|---|
| 227 | RuleType := rtSequence;
|
|---|
| 228 | AddTerminal('{', False, False);
|
|---|
| 229 | AddRule(WhiteSpace, True, True);
|
|---|
| 230 | AddRule(Separation, False, False);
|
|---|
| 231 | AddRule(WhiteSpace, True, True);
|
|---|
| 232 | AddTerminal('}', False, False);
|
|---|
| 233 | end;
|
|---|
| 234 | Rules.Add(RepetitionBlock);
|
|---|
| 235 |
|
|---|
| 236 | GroupingBlock := TGrammerRule.Create;
|
|---|
| 237 | with GroupingBlock do begin
|
|---|
| 238 | Name := 'GroupingBlock';
|
|---|
| 239 | RuleType := rtSequence;
|
|---|
| 240 | AddTerminal('(', False, False);
|
|---|
| 241 | AddRule(WhiteSpace, True, True);
|
|---|
| 242 | AddRule(Separation, False, False);
|
|---|
| 243 | AddRule(WhiteSpace, True, True);
|
|---|
| 244 | AddTerminal(')', False, False);
|
|---|
| 245 | end;
|
|---|
| 246 | Rules.Add(GroupingBlock);
|
|---|
| 247 |
|
|---|
| 248 | Term := TGrammerRule.Create;
|
|---|
| 249 | with Term do begin
|
|---|
| 250 | Name := 'Term';
|
|---|
| 251 | RuleType := rtAlternative;
|
|---|
| 252 | AddRule(Identifier, False, False);
|
|---|
| 253 | AddRule(RuleString, False, False);
|
|---|
| 254 | end;
|
|---|
| 255 | Rules.Add(Term);
|
|---|
| 256 |
|
|---|
| 257 | Expression := TGrammerRule.Create;
|
|---|
| 258 | with Expression do begin
|
|---|
| 259 | Name := 'Expression';
|
|---|
| 260 | RuleType := rtAlternative;
|
|---|
| 261 | AddRule(RepetitionBlock, False, False);
|
|---|
| 262 | AddRule(OptionBlock, False, False);
|
|---|
| 263 | AddRule(GroupingBlock, False, False);
|
|---|
| 264 | AddRule(Term, False, False);
|
|---|
| 265 | end;
|
|---|
| 266 | Rules.Add(Expression);
|
|---|
| 267 |
|
|---|
| 268 | ConcatenationBlock := TGrammerRule.Create;
|
|---|
| 269 | with ConcatenationBlock do begin
|
|---|
| 270 | Name := 'ConcatenationBlock';
|
|---|
| 271 | RuleType := rtSequence;
|
|---|
| 272 | AddRule(Expression, False, False);
|
|---|
| 273 | AddRule(WhiteSpace, True, True);
|
|---|
| 274 | end;
|
|---|
| 275 | Rules.Add(ConcatenationBlock);
|
|---|
| 276 |
|
|---|
| 277 | with Concatenation do begin
|
|---|
| 278 | Name := 'Concatenation';
|
|---|
| 279 | RuleType := rtSequence;
|
|---|
| 280 | AddRule(Expression, False, False);
|
|---|
| 281 | AddRule(WhiteSpace, True, True);
|
|---|
| 282 | AddRule(ConcatenationBlock, True, True);
|
|---|
| 283 | end;
|
|---|
| 284 | Rules.Add(Concatenation);
|
|---|
| 285 |
|
|---|
| 286 | SeparationBlock := TGrammerRule.Create;
|
|---|
| 287 | with SeparationBlock do begin
|
|---|
| 288 | Name := 'SeparationBlock';
|
|---|
| 289 | RuleType := rtSequence;
|
|---|
| 290 | //AddRule(WhiteSpace, True, True);
|
|---|
| 291 | AddTerminal('|', False, False);
|
|---|
| 292 | AddRule(WhiteSpace, True, True);
|
|---|
| 293 | AddRule(Concatenation, False, False);
|
|---|
| 294 | end;
|
|---|
| 295 | Rules.Add(SeparationBlock);
|
|---|
| 296 |
|
|---|
| 297 | with Separation do begin
|
|---|
| 298 | Name := 'Separation';
|
|---|
| 299 | RuleType := rtSequence;
|
|---|
| 300 | AddRule(Concatenation, False, False);
|
|---|
| 301 | //AddRule(WhiteSpace, True, True);
|
|---|
| 302 | AddRule(SeparationBlock, True, True);
|
|---|
| 303 | end;
|
|---|
| 304 | Rules.Add(Separation);
|
|---|
| 305 |
|
|---|
| 306 | Rule := TGrammerRule.Create;
|
|---|
| 307 | with Rule do begin
|
|---|
| 308 | Name := 'Rule';
|
|---|
| 309 | RuleType := rtSequence;
|
|---|
| 310 | AddRule(WhiteSpace, True, True);
|
|---|
| 311 | AddRule(Identifier, False, False);
|
|---|
| 312 | AddRule(WhiteSpace, True, True);
|
|---|
| 313 | AddTerminal('=', False, False);
|
|---|
| 314 | AddRule(WhiteSpace, True, True);
|
|---|
| 315 | AddRule(Separation, False, False);
|
|---|
| 316 | //AddRule(WhiteSpace, True, True);
|
|---|
| 317 | AddTerminal('.', False, False);
|
|---|
| 318 | AddRule(WhiteSpace, True, True);
|
|---|
| 319 | end;
|
|---|
| 320 | Rules.Add(Rule);
|
|---|
| 321 |
|
|---|
| 322 | RuleList := TGrammerRule.Create;
|
|---|
| 323 | with RuleList do begin
|
|---|
| 324 | Name := 'RuleList';
|
|---|
| 325 | RuleType := rtSequence;
|
|---|
| 326 | AddRule(Rule, False, True);
|
|---|
| 327 | end;
|
|---|
| 328 | Rules.Add(RuleList);
|
|---|
| 329 |
|
|---|
| 330 | Definition := TGrammerRule.Create;
|
|---|
| 331 | with Definition do begin
|
|---|
| 332 | Name := 'Definition';
|
|---|
| 333 | RuleType := rtSequence;
|
|---|
| 334 | AddRule(RuleList, False, False);
|
|---|
| 335 | AddRule(WhiteSpace, True, True);
|
|---|
| 336 | AddTerminal('.', False, False);
|
|---|
| 337 | end;
|
|---|
| 338 | Rules.Add(Definition);
|
|---|
| 339 |
|
|---|
| 340 | TopRule := Definition;
|
|---|
| 341 | end;
|
|---|
| 342 |
|
|---|
| 343 | ShowGrammerTree(Grammer);
|
|---|
| 344 |
|
|---|
| 345 | SourceProgram := TProgram.Create;
|
|---|
| 346 | Memo1.Lines.LoadFromFile(DefaultGrammerFileName);
|
|---|
| 347 | Memo2.Lines.LoadFromFile(DefaultPascalFileName);
|
|---|
| 348 | // with Memo1.Lines do
|
|---|
| 349 | // for I := 1 to Length(Text) do begin
|
|---|
| 350 | // if (Text[I] <> ' ') and (Text[I] <> #10) and (Text[I] <> #13) then SourceCode := SourceCode + Text[I];
|
|---|
| 351 | // end;
|
|---|
| 352 |
|
|---|
| 353 | //Grammer.Parse(Memo1.Text, SourceProgram);
|
|---|
| 354 | //ShowProgramTree(SourceProgram);
|
|---|
| 355 | end;
|
|---|
| 356 |
|
|---|
| 357 | procedure TMainForm.FormDestroy(Sender: TObject);
|
|---|
| 358 | begin
|
|---|
| 359 | Memo1.Lines.SaveToFile(DefaultGrammerFileName);
|
|---|
| 360 | Memo2.Lines.SaveToFile(DefaultPascalFileName);
|
|---|
| 361 | PascalGrammer.Free;
|
|---|
| 362 | Grammer.Free;
|
|---|
| 363 | SourceProgram.Free;
|
|---|
| 364 | end;
|
|---|
| 365 |
|
|---|
| 366 | function TMainForm.ProcessConcatenationItem(ARule: TGrammerRule; ProgramItem: TProgramItem): TGrammerItem;
|
|---|
| 367 | var
|
|---|
| 368 | II: Integer;
|
|---|
| 369 | NewRule: TGrammerRule;
|
|---|
| 370 | RuleItem: TGrammerItem;
|
|---|
| 371 | begin
|
|---|
| 372 | with ProgramItem do begin
|
|---|
| 373 | ARule.RuleType := rtSequence;
|
|---|
| 374 | for II := 0 to Items.Count - 1 do begin
|
|---|
| 375 | RuleItem := ARule.Add;
|
|---|
| 376 | if TProgramItem(Items[II]).Rule.Name = 'Term' then begin
|
|---|
| 377 | RuleItem.ItemType := itNonterminal;
|
|---|
| 378 | with TProgramItem(TProgramItem(Items[II]).Items[0]) do
|
|---|
| 379 | if (Value[1] >= 'a') and (Value[1] <= 'z') then begin
|
|---|
| 380 | RuleItem.ItemType := itNonterminal;
|
|---|
| 381 | RuleItem.RuleName := Value;
|
|---|
| 382 | RuleItem.Rule := nil;
|
|---|
| 383 | end else if Value = 'NAME' then begin
|
|---|
| 384 | RuleItem.Rule := TGrammerRule(PascalGrammer.Rules[7]);
|
|---|
| 385 | end else if Value = 'NUMBER' then begin
|
|---|
| 386 | RuleItem.Rule := TGrammerRule(PascalGrammer.Rules[5]);
|
|---|
| 387 | end else if (Length(Value) > 1) and (Value[1] = '''') and
|
|---|
| 388 | (Value[Length(Value)] = '''') then begin
|
|---|
| 389 | if Length(Value) > 3 then begin
|
|---|
| 390 | NewRule := TGrammerRule.Create;
|
|---|
| 391 | NewRule.Parent := ARule;
|
|---|
| 392 | NewRule.Name := 'Term';
|
|---|
| 393 | NewRule.AddTerminalText(Copy(Value, 2, Length(Value) - 2));
|
|---|
| 394 | PascalGrammer.Rules.Add(NewRule);
|
|---|
| 395 | RuleItem.Rule := NewRule;
|
|---|
| 396 | RuleItem.ItemType := itNonterminal;
|
|---|
| 397 | end else if Length(Value) = 3 then begin
|
|---|
| 398 | RuleItem.ItemType := itTerminal;
|
|---|
| 399 | RuleItem.Character := Value[2]
|
|---|
| 400 | end;
|
|---|
| 401 | end else begin
|
|---|
| 402 | NewRule := TGrammerRule.Create;
|
|---|
| 403 | NewRule.PArent := ARule;
|
|---|
| 404 | NewRule.Name := 'Term';
|
|---|
| 405 | NewRule.AddTerminalText(Value);
|
|---|
| 406 | PascalGrammer.Rules.Add(NewRule);
|
|---|
| 407 | RuleItem.Rule := NewRule;
|
|---|
| 408 | RuleItem.ItemType := itNonterminal;
|
|---|
| 409 | end;
|
|---|
| 410 | end else if TProgramItem(Items[II]).Rule.Name = 'GroupingBlock' then begin
|
|---|
| 411 | NewRule := TGrammerRule.Create;
|
|---|
| 412 | NewRule.Parent := ARule;
|
|---|
| 413 | NewRule.RuleType := rtSequence;
|
|---|
| 414 | NewRule.Name := 'Group';
|
|---|
| 415 | ProcessSeparationItem(NewRule, Items[II].Items[1]);
|
|---|
| 416 | PascalGrammer.Rules.Add(NewRule);
|
|---|
| 417 | RuleItem.ItemType := itNonterminal;
|
|---|
| 418 | RuleItem.Rule := NewRule;
|
|---|
| 419 | end else if TProgramItem(Items[II]).Rule.Name = 'OptionBlock' then begin
|
|---|
| 420 | NewRule := TGrammerRule.Create;
|
|---|
| 421 | NewRule.Parent := ARule;
|
|---|
| 422 | NewRule.RuleType := rtSequence;
|
|---|
| 423 | NewRule.Name := 'Option';
|
|---|
| 424 | ProcessSeparationItem(NewRule, Items[II].Items[1]);
|
|---|
| 425 | PascalGrammer.Rules.Add(NewRule);
|
|---|
| 426 | RuleItem.ItemType := itNonterminal;
|
|---|
| 427 | RuleItem.Optional := True;
|
|---|
| 428 | RuleItem.Rule := NewRule;
|
|---|
| 429 | end else if Items[II].Rule.Name = 'RepetitionBlock' then begin
|
|---|
| 430 | NewRule := TGrammerRule.Create;
|
|---|
| 431 | NewRule.Parent := ARule;
|
|---|
| 432 | NewRule.RuleType := rtSequence;
|
|---|
| 433 | NewRule.Name := 'Repetition';
|
|---|
| 434 | ProcessSeparationItem(NewRule, Items[II].Items[1]);
|
|---|
| 435 | PascalGrammer.Rules.Add(NewRule);
|
|---|
| 436 | RuleItem.Repetition := True;
|
|---|
| 437 | RuleItem.Optional := True;
|
|---|
| 438 | RuleItem.ItemType := itNonterminal;
|
|---|
| 439 | RuleItem.Rule := NewRule;
|
|---|
| 440 | end;
|
|---|
| 441 | end;
|
|---|
| 442 | end;
|
|---|
| 443 | end;
|
|---|
| 444 |
|
|---|
| 445 | procedure TMainForm.ProcessProgramTree;
|
|---|
| 446 | var
|
|---|
| 447 | I: Integer;
|
|---|
| 448 | NewRule: TGrammerRule;
|
|---|
| 449 | WhiteSpace, LowerCaseAlphabeticCharacter, UpperCaseAlphabeticCharacter,
|
|---|
| 450 | AlphabeticCharacter, Digit, Number, AlphaNumericCharacter,
|
|---|
| 451 | Identifier: TGrammerRule;
|
|---|
| 452 | C: Char;
|
|---|
| 453 | begin
|
|---|
| 454 | for I := 0 to PascalGrammer.Rules.Count - 1 do
|
|---|
| 455 | PascalGrammer.Rules[I].Free;
|
|---|
| 456 | PascalGrammer.Rules.Clear;
|
|---|
| 457 | with PascalGrammer do begin
|
|---|
| 458 | WhiteSpace := TGrammerRule.Create;
|
|---|
| 459 | with WhiteSpace do begin
|
|---|
| 460 | Name := 'WhiteSpace';
|
|---|
| 461 | RuleType := rtAlternative;
|
|---|
| 462 | AddTerminal(' ', False, False);
|
|---|
| 463 | AddTerminal(#10, False, False);
|
|---|
| 464 | AddTerminal(#13, False, False);
|
|---|
| 465 | end;
|
|---|
| 466 | Rules.Add(WhiteSpace);
|
|---|
| 467 |
|
|---|
| 468 | LowerCaseAlphabeticCharacter := TGrammerRule.Create;
|
|---|
| 469 | with LowerCaseAlphabeticCharacter do begin
|
|---|
| 470 | Name := 'LowerCaseAlphabeticCharacter';
|
|---|
| 471 | RuleType := rtAlternative;
|
|---|
| 472 | for C := 'a' to 'z' do AddTerminal(C, False, False);
|
|---|
| 473 | end;
|
|---|
| 474 | Rules.Add(LowerCaseAlphabeticCharacter);
|
|---|
| 475 |
|
|---|
| 476 | UpperCaseAlphabeticCharacter := TGrammerRule.Create;
|
|---|
| 477 | with UpperCaseAlphabeticCharacter do begin
|
|---|
| 478 | Name := 'UpperCaseAlphabeticCharacter';
|
|---|
| 479 | RuleType := rtAlternative;
|
|---|
| 480 | for C := 'A' to 'Z' do AddTerminal(C, False, False);
|
|---|
| 481 | end;
|
|---|
| 482 | Rules.Add(UpperCaseAlphabeticCharacter);
|
|---|
| 483 |
|
|---|
| 484 | AlphabeticCharacter := TGrammerRule.Create;
|
|---|
| 485 | with AlphabeticCharacter do begin
|
|---|
| 486 | Name := 'AlphabeticCharacter';
|
|---|
| 487 | RuleType := rtAlternative;
|
|---|
| 488 | AddRule(LowerCaseAlphabeticCharacter, False, False);
|
|---|
| 489 | AddRule(UpperCaseAlphabeticCharacter, False, False);
|
|---|
| 490 | end;
|
|---|
| 491 | Rules.Add(AlphabeticCharacter);
|
|---|
| 492 |
|
|---|
| 493 | Digit := TGrammerRule.Create;
|
|---|
| 494 | with Digit do begin
|
|---|
| 495 | Name := 'Digit';
|
|---|
| 496 | RuleType := rtAlternative;
|
|---|
| 497 | for C := '0' to '9' do AddTerminal(C, False, False);
|
|---|
| 498 | end;
|
|---|
| 499 | Rules.Add(Digit);
|
|---|
| 500 |
|
|---|
| 501 | Number := TGrammerRule.Create;
|
|---|
| 502 | with Number do begin
|
|---|
| 503 | Name := 'Number';
|
|---|
| 504 | RuleType := rtSequence;
|
|---|
| 505 | AddTerminal('-', True, False);
|
|---|
| 506 | AddRule(Digit, False, True);
|
|---|
| 507 | end;
|
|---|
| 508 | Rules.Add(Number);
|
|---|
| 509 |
|
|---|
| 510 | AlphaNumericCharacter := TGrammerRule.Create;
|
|---|
| 511 | with AlphaNumericCharacter do begin
|
|---|
| 512 | Name := 'AlphaNumericCharacter';
|
|---|
| 513 | RuleType := rtAlternative;
|
|---|
| 514 | AddRule(Digit, False, False);
|
|---|
| 515 | AddRule(AlphabeticCharacter, False, False);
|
|---|
| 516 | AddTerminal('_', False, False);
|
|---|
| 517 | end;
|
|---|
| 518 | Rules.Add(AlphaNumericCharacter);
|
|---|
| 519 |
|
|---|
| 520 | Identifier := TGrammerRule.Create;
|
|---|
| 521 | with Identifier do begin
|
|---|
| 522 | Name := 'Identifier';
|
|---|
| 523 | RuleType := rtSequence;
|
|---|
| 524 | AddRule(AlphabeticCharacter, False, False);
|
|---|
| 525 | AddRule(AlphaNumericCharacter, True, True);
|
|---|
| 526 | end;
|
|---|
| 527 | Rules.Add(Identifier);
|
|---|
| 528 | end;
|
|---|
| 529 |
|
|---|
| 530 | PascalGrammer.TopRule := nil;
|
|---|
| 531 | with SourceProgram.TopItem do begin
|
|---|
| 532 | with Items[0] do begin
|
|---|
| 533 | for I := 0 to Items.Count - 1 do with Items[I] do begin
|
|---|
| 534 | NewRule := TGrammerRule.Create;
|
|---|
| 535 | with PascalGrammer do
|
|---|
| 536 | if TopRule = nil then TopRule := NewRule;
|
|---|
| 537 | NewRule.Name := Items[0].Value;
|
|---|
| 538 | ProcessSeparationItem(NewRule, Items[2]);
|
|---|
| 539 | PascalGrammer.Rules.Add(NewRule);
|
|---|
| 540 | end;
|
|---|
| 541 | end;
|
|---|
| 542 | end;
|
|---|
| 543 | end;
|
|---|
| 544 |
|
|---|
| 545 | function TMainForm.ProcessSeparationItem(var ARule: TGrammerRule;
|
|---|
| 546 | ProgramItem: TProgramItem): TGrammerItem;
|
|---|
| 547 | var
|
|---|
| 548 | II: Integer;
|
|---|
| 549 | NewSubRule: TGrammerRule;
|
|---|
| 550 | RuleItem: TGrammerItem;
|
|---|
| 551 | begin
|
|---|
| 552 | with ProgramItem do
|
|---|
| 553 | if Items.Count > 1 then begin
|
|---|
| 554 | ARule.RuleType := rtAlternative;
|
|---|
| 555 | for II := 0 to Items.Count - 1 do begin
|
|---|
| 556 | NewSubRule := TGrammerRule.Create;
|
|---|
| 557 | NewSubRule.Parent := ARule;
|
|---|
| 558 | NewSubRule.Name := ARule.Name;
|
|---|
| 559 | RuleItem := ARule.Add;
|
|---|
| 560 | RuleItem.ItemType := itNonterminal;
|
|---|
| 561 | RuleItem.Rule := NewSubRule;
|
|---|
| 562 | ProcessConcatenationItem(NewSubRule, Items[II]);
|
|---|
| 563 | PascalGrammer.Rules.Add(NewSubRule);
|
|---|
| 564 | end;
|
|---|
| 565 | end else begin
|
|---|
| 566 | ProcessConcatenationItem(ARule, Items[0]);
|
|---|
| 567 | end;
|
|---|
| 568 | end;
|
|---|
| 569 |
|
|---|
| 570 | procedure TMainForm.ShowGrammerRule(TreeNode: TTreeNode; ARule: TGrammerRule;
|
|---|
| 571 | Attributs: string = '');
|
|---|
| 572 | var
|
|---|
| 573 | II: Integer;
|
|---|
| 574 | NewTreeNode: TTreeNode;
|
|---|
| 575 | // NewNode: TTreeNode;
|
|---|
| 576 | begin
|
|---|
| 577 | with TreeView2, Items, ARule do begin
|
|---|
| 578 | case RuleType of
|
|---|
| 579 | rtSequence: Attributs := Attributs + '(Seq)';
|
|---|
| 580 | rtAlternative: Attributs := Attributs + '(Alt)';
|
|---|
| 581 | end;
|
|---|
| 582 | NewTreeNode := AddChild(TreeNode, ARule.Name + Attributs);
|
|---|
| 583 | for II := 0 to Items.Count - 1 do
|
|---|
| 584 | with Items[II] do begin
|
|---|
| 585 | if Optional then Attributs := '(Opt)' else Attributs := '';
|
|---|
| 586 | if Repetition then Attributs := Attributs + '(Rep)';
|
|---|
| 587 | case ItemType of
|
|---|
| 588 | itTerminal: begin
|
|---|
| 589 | Attributs := Character + Attributs;
|
|---|
| 590 | AddChild(NewTreeNode, Attributs);
|
|---|
| 591 | end;
|
|---|
| 592 | itNonterminal: begin
|
|---|
| 593 | if Assigned(Rule) then begin
|
|---|
| 594 | if Rule.Parent = ARule then
|
|---|
| 595 | ShowGrammerRule(NewTreeNode, Rule, Attributs)
|
|---|
| 596 | else AddChild(NewTreeNode, '<' + Rule.Name + '>' + Attributs);
|
|---|
| 597 | end else AddChild(NewTreeNode, '<?>' + Attributs);
|
|---|
| 598 | end;
|
|---|
| 599 | end;
|
|---|
| 600 | end;
|
|---|
| 601 | end;
|
|---|
| 602 | end;
|
|---|
| 603 |
|
|---|
| 604 | procedure TMainForm.ShowGrammerTree(Grammer: TGrammer);
|
|---|
| 605 | var
|
|---|
| 606 | I: Integer;
|
|---|
| 607 | begin
|
|---|
| 608 | with Grammer, TreeView2, Items do begin
|
|---|
| 609 | BeginUpdate;
|
|---|
| 610 | Clear;
|
|---|
| 611 | TopItem := AddChild(nil, 'Gramatika');
|
|---|
| 612 | for I := 0 to Rules.Count - 1 do with TGrammerRule(Rules[I]) do
|
|---|
| 613 | if not Assigned(Parent) then ShowGrammerRule(TopItem, TGrammerRule(Rules[I]));
|
|---|
| 614 | TopItem.Expand(False);
|
|---|
| 615 | EndUpdate;
|
|---|
| 616 | end;
|
|---|
| 617 | end;
|
|---|
| 618 |
|
|---|
| 619 | procedure TMainForm.ShowProgramNode(Node: TTreeNode; SourceProgram: TProgramItem);
|
|---|
| 620 | var
|
|---|
| 621 | TreeNode: TTreeNode;
|
|---|
| 622 | I: Integer;
|
|---|
| 623 | begin
|
|---|
| 624 | if SourceProgram.ItemType = itNonterminal then begin
|
|---|
| 625 | TreeNode := TreeView1.Items.AddChild(Node, SourceProgram.Rule.Name);
|
|---|
| 626 | for I := 0 to SourceProgram.Items.Count - 1 do
|
|---|
| 627 | if Assigned(SourceProgram.Items[I]) then
|
|---|
| 628 | //TreeView1.Items.AddChild(TreeNode, IntToStr(I))
|
|---|
| 629 | ShowProgramNode(TreeNode, SourceProgram.Items[I])
|
|---|
| 630 | else TreeView1.Items.AddChild(TreeNode, 'x');
|
|---|
| 631 | end else begin
|
|---|
| 632 | TreeView1.Items.AddChild(Node, SourceProgram.Value);
|
|---|
| 633 | end;
|
|---|
| 634 | end;
|
|---|
| 635 |
|
|---|
| 636 | procedure TMainForm.ShowProgramTree(SourceProgram: TProgram);
|
|---|
| 637 | begin
|
|---|
| 638 | with TreeView1, Items do begin
|
|---|
| 639 | BeginUpdate;
|
|---|
| 640 | Clear;
|
|---|
| 641 | TopItem := AddChild(nil, 'Program');
|
|---|
| 642 | ShowProgramNode(TopItem, SourceProgram.TopItem);
|
|---|
| 643 | TopItem.Expand(True);
|
|---|
| 644 | EndUpdate;
|
|---|
| 645 | end;
|
|---|
| 646 | end;
|
|---|
| 647 |
|
|---|
| 648 | initialization
|
|---|
| 649 | {$i UMainForm.lrs}
|
|---|
| 650 |
|
|---|
| 651 | end.
|
|---|