Changeset 111 for branches/generator/URules.pas
- Timestamp:
- Aug 9, 2017, 12:09:47 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/generator/URules.pas
r110 r111 9 9 10 10 type 11 TRule = class; 12 TRules = class; 13 TGrammer = class; 14 15 TRuleItemType = (ritTerminal, ritNonTerminal); 11 16 12 17 { TRuleItem } 13 18 14 19 TRuleItem = class 15 Name: string; 20 ParentRule: TRule; 21 RuleItemType: TRuleItemType; 22 Terminal: string; 23 NonTerminalName: string; 24 NonTerminal: TRule; 25 Grammer: TGrammer; 16 26 procedure LoadFromXmlNode(Node: TDOMNode); 17 27 procedure SaveToXmlNode(Node: TDOMNode); 28 function GetBNF: string; 18 29 end; 19 30 … … 21 32 22 33 TRuleItems = class(TFPGObjectList<TRuleItem>) 34 Grammer: TGrammer; 23 35 procedure LoadFromXmlNode(Node: TDOMNode); 24 36 procedure SaveToXmlNode(Node: TDOMNode); 25 37 end; 26 38 39 TRuleType = (rtAnd, rtOr); 40 27 41 { TRule } 28 42 29 43 TRule = class 44 private 45 function GetGrammer: TGrammer; 46 procedure SetGrammer(AValue: TGrammer); 47 public 30 48 Name: string; 31 49 Items: TRuleItems; 50 RuleType: TRuleType; 51 property Grammer: TGrammer read GetGrammer write SetGrammer; 32 52 constructor Create; 33 53 destructor Destroy; override; … … 40 60 41 61 TRules = class(TFPGObjectList<TRule>) 42 FileName: string; 62 Grammer: TGrammer; 63 function FindName(Name: string): TRule; 43 64 procedure LoadFromXmlNode(Node: TDOMNode); 44 65 procedure SaveToXmlNode(Node: TDOMNode); 66 function GetBNF: string; 67 end; 68 69 { TGrammer } 70 71 TGrammer = class 72 FileName: string; 73 Rules: TRules; 45 74 procedure LoadFromXmlFile(FileName: string); 46 75 procedure SaveToXmlFile(FileName: string); 76 constructor Create; 77 destructor Destroy; override; 47 78 function GetBNF: string; 48 79 end; … … 50 81 implementation 51 82 52 { TRuleItem } 53 54 procedure TRuleItem.SaveToXmlNode(Node: TDOMNode); 55 begin 56 WriteString(Node, 'Name', Name); 57 end; 58 59 procedure TRuleItem.LoadFromXmlNode(Node: TDOMNode); 60 begin 61 Name := ReadString(Node, 'Name', ''); 62 end; 63 64 { TRuleItems } 65 66 procedure TRuleItems.SaveToXmlNode(Node: TDOMNode); 67 var 68 RuleItem: TRuleItem; 69 RuleItemNode: TDOMNode; 70 begin 71 for RuleItem in Self do begin 72 RuleItemNode := Node.OwnerDocument.CreateElement('RuleItem'); 73 RuleItem.SaveToXmlNode(RuleItemNode); 74 Node.AppendChild(RuleItemNode); 75 end; 76 end; 77 78 procedure TRuleItems.LoadFromXmlNode(Node: TDOMNode); 79 var 80 RuleItemNode: TDOMNode; 81 RuleItem: TRuleItem; 82 begin 83 RuleItemNode := Node.FirstChild; 84 while Assigned(RuleItemNode) do begin 85 if RuleItemNode.NodeName = 'RuleItem' then begin 86 RuleItem := TRuleItem.Create; 87 RuleItem.LoadFromXmlNode(RuleItemNode); 88 Add(RuleItem); 89 end; 90 RuleItemNode := RuleItemNode.NextSibling; 91 end; 92 end; 93 94 { TRule } 95 96 procedure TRule.SaveToXmlNode(Node: TDOMNode); 97 var 98 RuleItemsNode: TDOMNode; 99 begin 100 WriteString(Node, 'Name', Name); 101 102 RuleItemsNode := Node.OwnerDocument.CreateElement('RuleItems'); 103 Node.AppendChild(RuleItemsNode); 104 Items.SaveToXmlNode(RuleItemsNode); 105 end; 106 107 function TRule.GetBNF: string; 108 var 109 Item: TRuleItem; 110 begin 111 Result := Name + ' ::='; 112 for Item in Items do begin 113 Result := Result + ' ' + Item.Name; 114 end; 115 end; 116 117 constructor TRule.Create; 118 begin 119 Items := TRuleItems.Create; 120 end; 121 122 destructor TRule.Destroy; 123 begin 124 FreeAndNil(Items); 125 inherited Destroy; 126 end; 127 128 procedure TRule.LoadFromXmlNode(Node: TDOMNode); 129 var 130 ItemsNode: TDOMNode; 131 begin 132 Name := ReadString(Node, 'Name', ''); 133 134 ItemsNode := Node.FindNode('RuleItems'); 135 if Assigned(ItemsNode) then begin 136 Items.LoadFromXmlNode(ItemsNode); 137 end; 138 end; 139 140 { TRules } 141 142 procedure TRules.SaveToXmlNode(Node: TDOMNode); 143 var 144 Rule: TRule; 145 RuleNode: TDOMNode; 146 begin 147 for Rule in Self do begin 148 RuleNode := Node.OwnerDocument.CreateElement('Rule'); 149 Rule.SaveToXmlNode(RuleNode); 150 Node.AppendChild(RuleNode); 151 end; 152 end; 153 154 procedure TRules.LoadFromXmlNode(Node: TDOMNode); 155 var 156 RuleNode: TDOMNode; 157 Rule: TRule; 158 begin 159 RuleNode := Node.FirstChild; 160 while Assigned(RuleNode) do begin 161 if RuleNode.NodeName = 'Rule' then begin 162 Rule := TRule.Create; 163 Rule.LoadFromXmlNode(RuleNode); 164 Add(Rule); 165 end; 166 RuleNode := RuleNode.NextSibling; 167 end; 168 end; 169 170 procedure TRules.LoadFromXmlFile(FileName: string); 83 { TGrammer } 84 85 procedure TGrammer.LoadFromXmlFile(FileName: string); 171 86 var 172 87 Doc: TXMLDocument; 173 88 RootNode: TDOMNode; 174 89 RulesNode: TDOMNode; 90 Rule: TRule; 91 RuleItem: TRuleItem; 175 92 begin 176 93 Self.FileName := FileName; 177 Clear;94 Rules.Clear; 178 95 try 179 96 ReadXMLFile(Doc, FileName); … … 183 100 RulesNode := RootNode.FindNode('Rules'); 184 101 if Assigned(RulesNode) then begin 185 LoadFromXmlNode(RulesNode);102 Rules.LoadFromXmlNode(RulesNode); 186 103 end; 187 104 end; … … 189 106 Doc.Free; 190 107 end; 191 end; 192 193 procedure TRules.SaveToXmlFile(FileName: string); 108 109 // Update rule references 110 for Rule in Rules do 111 for RuleItem in Rule.Items do 112 if RuleItem.RuleItemType = ritNonTerminal then 113 RuleItem.NonTerminal := Rules.FindName(RuleItem.NonTerminalName); 114 end; 115 116 procedure TGrammer.SaveToXmlFile(FileName: string); 194 117 var 195 118 Doc: TXMLDocument; … … 205 128 RulesNode := Doc.CreateElement('Rules'); 206 129 RootNode.AppendChild(RulesNode); 207 SaveToXmlNode(RulesNode);130 Rules.SaveToXmlNode(RulesNode); 208 131 209 132 WriteXMLFile(Doc, FileName); … … 213 136 end; 214 137 138 constructor TGrammer.Create; 139 begin 140 Rules := TRules.Create; 141 Rules.Grammer := Self; 142 end; 143 144 destructor TGrammer.Destroy; 145 begin 146 FreeAndNil(Rules); 147 inherited Destroy; 148 end; 149 150 function TGrammer.GetBNF: string; 151 begin 152 Result := Rules.GetBNF; 153 end; 154 155 { TRuleItem } 156 157 procedure TRuleItem.SaveToXmlNode(Node: TDOMNode); 158 begin 159 WriteInteger(Node, 'Type', Integer(RuleItemType)); 160 if RuleItemType = ritTerminal then WriteString(Node, 'Terminal', Terminal) 161 else if RuleItemType = ritNonTerminal then WriteString(Node, 'NonTerminal', NonTerminal.Name) 162 end; 163 164 function TRuleItem.GetBNF: string; 165 begin 166 if RuleItemType = ritTerminal then Result := '"' + Terminal + '"' 167 else if RuleItemType = ritNonTerminal then Result := NonTerminal.Name; 168 end; 169 170 procedure TRuleItem.LoadFromXmlNode(Node: TDOMNode); 171 begin 172 RuleItemType := TRuleItemType(ReadInteger(Node, 'Type', Integer(ritTerminal))); 173 if RuleItemType = ritTerminal then Terminal := ReadString(Node, 'Terminal', '') 174 else if RuleItemType = ritNonTerminal then 175 NonTerminalName := ReadString(Node, 'NonTerminal', ''); 176 end; 177 178 { TRuleItems } 179 180 procedure TRuleItems.SaveToXmlNode(Node: TDOMNode); 181 var 182 RuleItem: TRuleItem; 183 RuleItemNode: TDOMNode; 184 begin 185 for RuleItem in Self do begin 186 RuleItemNode := Node.OwnerDocument.CreateElement('RuleItem'); 187 RuleItem.SaveToXmlNode(RuleItemNode); 188 Node.AppendChild(RuleItemNode); 189 end; 190 end; 191 192 procedure TRuleItems.LoadFromXmlNode(Node: TDOMNode); 193 var 194 RuleItemNode: TDOMNode; 195 RuleItem: TRuleItem; 196 begin 197 RuleItemNode := Node.FirstChild; 198 while Assigned(RuleItemNode) do begin 199 if RuleItemNode.NodeName = 'RuleItem' then begin 200 RuleItem := TRuleItem.Create; 201 RuleItem.Grammer := Grammer; 202 RuleItem.LoadFromXmlNode(RuleItemNode); 203 Add(RuleItem); 204 end; 205 RuleItemNode := RuleItemNode.NextSibling; 206 end; 207 end; 208 209 { TRule } 210 211 procedure TRule.SaveToXmlNode(Node: TDOMNode); 212 var 213 RuleItemsNode: TDOMNode; 214 begin 215 WriteString(Node, 'Name', Name); 216 217 RuleItemsNode := Node.OwnerDocument.CreateElement('RuleItems'); 218 Node.AppendChild(RuleItemsNode); 219 Items.SaveToXmlNode(RuleItemsNode); 220 end; 221 222 function TRule.GetBNF: string; 223 var 224 Item: TRuleItem; 225 begin 226 Result := Name + ' ::= '; 227 for Item in Items do begin 228 if Item <> Items.First then begin 229 if RuleType = rtAnd then Result := Result + ' ' 230 else if RuleType = rtOr then Result := Result + ' | '; 231 end; 232 Result := Result + Item.GetBNF; 233 end; 234 end; 235 236 function TRule.GetGrammer: TGrammer; 237 begin 238 Result := Items.Grammer; 239 end; 240 241 procedure TRule.SetGrammer(AValue: TGrammer); 242 begin 243 Items.Grammer := AValue; 244 end; 245 246 constructor TRule.Create; 247 begin 248 Items := TRuleItems.Create; 249 end; 250 251 destructor TRule.Destroy; 252 begin 253 FreeAndNil(Items); 254 inherited Destroy; 255 end; 256 257 procedure TRule.LoadFromXmlNode(Node: TDOMNode); 258 var 259 ItemsNode: TDOMNode; 260 begin 261 Name := ReadString(Node, 'Name', ''); 262 263 ItemsNode := Node.FindNode('RuleItems'); 264 if Assigned(ItemsNode) then begin 265 Items.LoadFromXmlNode(ItemsNode); 266 end; 267 end; 268 269 { TRules } 270 271 procedure TRules.SaveToXmlNode(Node: TDOMNode); 272 var 273 Rule: TRule; 274 RuleNode: TDOMNode; 275 begin 276 for Rule in Self do begin 277 RuleNode := Node.OwnerDocument.CreateElement('Rule'); 278 Rule.SaveToXmlNode(RuleNode); 279 Node.AppendChild(RuleNode); 280 end; 281 end; 282 283 function TRules.FindName(Name: string): TRule; 284 var 285 I: Integer; 286 begin 287 I := 0; 288 while (I < Count) and (Items[I].Name <> Name) do Inc(I); 289 if I < Count then Result := Items[I] 290 else Result := nil; 291 end; 292 293 procedure TRules.LoadFromXmlNode(Node: TDOMNode); 294 var 295 RuleNode: TDOMNode; 296 Rule: TRule; 297 begin 298 RuleNode := Node.FirstChild; 299 while Assigned(RuleNode) do begin 300 if RuleNode.NodeName = 'Rule' then begin 301 Rule := TRule.Create; 302 Rule.Grammer := Grammer; 303 Rule.LoadFromXmlNode(RuleNode); 304 Add(Rule); 305 end; 306 RuleNode := RuleNode.NextSibling; 307 end; 308 end; 309 215 310 function TRules.GetBNF: string; 216 311 var
Note:
See TracChangeset
for help on using the changeset viewer.