Ignore:
Timestamp:
Dec 27, 2017, 6:05:11 PM (7 years ago)
Author:
chronos
Message:
  • Added: Lookup tables can be defined and their usage set from grammer rules.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/generator/UGrammer.pas

    r136 r137  
    1313  TGrammer = class;
    1414  TRuleItems = class;
     15  TLookupTable = class;
    1516
    1617  TRuleItemType = (ritTerminal, ritNonTerminal, ritSubItems, ritTerminalRange);
    1718  TGrammerNotation = (gnBnf, gnEbnf);
     19  TLookupTableAction = (taCreate, taReference);
    1820
    1921  { TRuleItem }
     
    3739    NonTerminal: TRule;
    3840    SubItems: TRuleItems;
     41    LookupTableUsed: Boolean;
     42    LookupTable: TLookupTable;
     43    LookupTableName: string;
     44    LookupTableAction: TLookupTableAction;
    3945    function GetCharLength: Integer;
    4046    procedure LoadFromXmlNode(Node: TDOMNode);
     
    115121  end;
    116122
     123  TLookupTableItem = class
     124    Name: string;
     125  end;
     126
     127  { TLookupTable }
     128
     129  TLookupTable = class
     130    Name: string;
     131    Grammer: TGrammer;
     132    Items: TFPGObjectList<TLookupTableItem>;
     133    procedure LoadFromXmlNode(Node: TDOMNode);
     134    procedure SaveToXmlNode(Node: TDOMNode);
     135    constructor Create;
     136    destructor Destroy; override;
     137  end;
     138
     139  { TLookupTables }
     140
     141  TLookupTables = class(TFPGObjectList<TLookupTable>)
     142    Grammer: TGrammer;
     143    function FindName(Name: string): TLookupTable;
     144    procedure LoadFromXmlNode(Node: TDOMNode);
     145    procedure SaveToXmlNode(Node: TDOMNode);
     146  end;
     147
    117148  { TGrammer }
    118149
     
    128159    FileName: string;
    129160    Rules: TRules;
     161    LookupTables: TLookupTables;
    130162    TopRule: TRule;
    131163    WhiteSpaceRule: TRule;
     
    151183implementation
    152184
     185{ TLookupTables }
     186
     187function TLookupTables.FindName(Name: string): TLookupTable;
     188var
     189  I: Integer;
     190begin
     191  I := 0;
     192  while (I < Count) and (Items[I].Name <> Name) do Inc(I);
     193  if I < Count then Result := Items[I]
     194    else Result := nil;
     195end;
     196
     197procedure TLookupTables.LoadFromXmlNode(Node: TDOMNode);
     198var
     199  RuleNode: TDOMNode;
     200  LookupTable: TLookupTable;
     201begin
     202  RuleNode := Node.FirstChild;
     203  while Assigned(RuleNode) do begin
     204    if RuleNode.NodeName = 'LookupTable' then begin
     205      LookupTable := TLookupTable.Create;
     206      LookupTable.Grammer := Grammer;
     207      LookupTable.LoadFromXmlNode(RuleNode);
     208      Add(LookupTable);
     209    end;
     210    RuleNode := RuleNode.NextSibling;
     211  end;
     212end;
     213
     214procedure TLookupTables.SaveToXmlNode(Node: TDOMNode);
     215var
     216  LookupTable: TLookupTable;
     217  RuleNode: TDOMNode;
     218begin
     219  for LookupTable in Self do begin
     220    RuleNode := Node.OwnerDocument.CreateElement('LookupTable');
     221    LookupTable.SaveToXmlNode(RuleNode);
     222    Node.AppendChild(RuleNode);
     223  end;
     224end;
     225
     226{ TLookupTable }
     227
     228procedure TLookupTable.LoadFromXmlNode(Node: TDOMNode);
     229begin
     230  Name := ReadString(Node, 'Name', '');
     231end;
     232
     233procedure TLookupTable.SaveToXmlNode(Node: TDOMNode);
     234begin
     235  WriteString(Node, 'Name', Name);
     236end;
     237
     238constructor TLookupTable.Create;
     239begin
     240  Items := TFPGObjectList<TLookupTableItem>.Create;
     241end;
     242
     243destructor TLookupTable.Destroy;
     244begin
     245  FreeAndNil(Items);
     246  inherited Destroy;
     247end;
     248
    153249{ TGrammer }
    154250
     
    188284        Rules.LoadFromXmlNode(RulesNode);
    189285      end;
     286      RulesNode := RootNode.FindNode('LookupTables');
     287      if Assigned(RulesNode) then begin
     288        LookupTables.LoadFromXmlNode(RulesNode);
     289      end;
    190290
    191291      TopRule := Rules.FindName(ReadString(RootNode, 'TopRule', ''));
     
    217317    Rules.SaveToXmlNode(RulesNode);
    218318
     319    RulesNode := Doc.CreateElement('LookupTables');
     320    RootNode.AppendChild(RulesNode);
     321    LookupTables.SaveToXmlNode(RulesNode);
     322
    219323    if Assigned(TopRule) then
    220324      WriteString(RootNode, 'TopRule', TopRule.Name);
     
    239343  Rules := TRules.Create;
    240344  Rules.Grammer := Self;
     345  LookupTables := TLookupTables.Create;
     346  LookupTables.Grammer := Self;
    241347end;
    242348
     
    244350begin
    245351  DoDestroy;
     352  FreeAndNil(LookupTables);
    246353  FreeAndNil(Rules);
    247354  inherited Destroy;
     
    297404    end;
    298405  end;
     406  WriteBoolean(Node, 'LookupTableUsed', LookupTableUsed);
     407  WriteString(Node, 'LookupTable', LookupTableName);
     408  WriteInteger(Node, 'LookupTableAction', Integer(LookupTableAction));
    299409end;
    300410
     
    407517    end;
    408518  end;
     519  LookupTableUsed := ReadBoolean(Node, 'LookupTableUsed', False);
     520  LookupTableName := ReadString(Node, 'LookupTable', '');
     521  LookupTableAction := TLookupTableAction(ReadInteger(Node, 'LookupTableAction', 0));
    409522end;
    410523
     
    430543  RuleItem: TRuleItem;
    431544begin
    432   for RuleItem in Self do
     545  for RuleItem in Self do begin
    433546    case RuleItem.RuleItemType of
    434547      ritNonTerminal: RuleItem.NonTerminal := Grammer.Rules.FindName(RuleItem.NonTerminalName);
    435548      ritSubItems: RuleItem.SubItems.UpdateRuleReference;
    436549    end;
     550    RuleItem.LookupTable := Grammer.LookupTables.FindName(RuleItem.LookupTableName);
     551  end;
    437552end;
    438553
Note: See TracChangeset for help on using the changeset viewer.