Скачиваний:
14
Добавлен:
01.05.2014
Размер:
7 Кб
Скачать
//  Авторы студенты группы 2382: Щербинская О. Ю., Мирошникова Н. Л.,  Костыгова Д. М.

unit Udm_Vpod;


{=}INTERFACE


uses SysUtils, Classes, xmldom, XMLIntf, msxmldom, XMLDoc, Graphics;


type Tdm_Vpod = class(TDataModule)
    //--------------------------------------------------------------------------
    xml_Vpod: TXMLDocument;
    //--------------------------------------------------------------------------
private
    procedure MarkGrammarItems;
    function  AddToVpod( i_Root: IXMLNode; i_Item: IXMLNode ): IXMLNode;
    function  AlreadyHasItem( i_Root: IXMLNode; i_Item: IXMLNode ): boolean;
    procedure AddStartableItems( i_Root: IXMLNode; i_Item: IXMLNode );
    procedure ResolveVpodRelation;
    procedure ResolveMagazineEnd;
public
    procedure BuildVpodRelation;
    function  GetItemNum  ( i_Item: IXMLNode ): integer;
    function  GetItemDesc ( i_Item: IXMLNode ): string;
end;


var dm_Vpod: Tdm_Vpod;


{=}IMPLEMENTATION

uses Ufrm_Main, Udm_Grammar;


{$R *.dfm}

{===============================================================================
    ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ МОДУЛЯ
===============================================================================}

(*
    Размечает правила входной грамматики, определяя в них грамматические
    вхождения
    При этом изменяется содержимое dm_Grammar.xml_Grammar
*)

procedure tdm_Vpod.MarkGrammarItems;
var nProd, nSym: integer; ProdNode,SymNode: IXMLNode;
begin
   for nProd := 0 to dm_Grammar.node_Prod.ChildNodes.Count - 1 do
   begin
      ProdNode := dm_Grammar.node_Prod.ChildNodes[nProd];

      for nSym := 0 to ProdNode.ChildNodes.Count - 1 do
      begin
         SymNode := ProdNode.ChildNodes[nSym];

         SymNode.Attributes['PRODNUM']  :=  IntToStr( nProd );
         SymNode.Attributes['POSNUM']   :=  IntToStr( nSym );
      end;
   end;
end;


(*
    Добавляет в документ xml_Vpod копию узла i_Item и подвешивает её к
    корню i_Root ( i_Root принадлежит xml_Vpod )
*)

function tdm_Vpod.AddToVpod( i_Root: IXMLNode; i_Item: IXMLNode ): IXMLNode;
var NewItem: IXMLNode;
begin
   NewItem := i_Root.AddChild('LR_ITEM');

   NewItem.Attributes['TYPE']     :=  i_Item.Attributes['TYPE'];
   NewItem.Attributes['NAME']     :=  i_Item.Attributes['NAME'];
   NewItem.Attributes['PRODNUM']  :=  i_Item.Attributes['PRODNUM'];
   NewItem.Attributes['POSNUM']   :=  i_Item.Attributes['POSNUM'];

   Result := NewItem;
end;


(*
     Проверяет, содержит ли корень i_Root потомков с аттрибутами, эквивалентными
     грамматическому вхождению i_Item
*)

function tdm_Vpod.AlreadyHasItem( i_Root: IXMLNode; i_Item: IXMLNode ): boolean;
var cNum: integer;  ChildNode: IXMLNode;
begin
   Result := FALSE;
   for cNum := 0 to i_Root.ChildNodes.Count - 1 do
   begin
      ChildNode := i_Root.ChildNodes[cNum];
      Result := ( ChildNode.Attributes['TYPE']    =  i_Item.Attributes['TYPE']    ) and
                ( ChildNode.Attributes['NAME']    =  i_Item.Attributes['NAME']    ) and
                ( ChildNode.Attributes['PRODNUM'] =  i_Item.Attributes['PRODNUM'] ) and
                ( ChildNode.Attributes['POSNUM']  =  i_Item.Attributes['POSNUM']  );
      if Result then Exit;
   end;
end;


(*
    Добавляет к корню i_Root все грамматические вхождения, которыми могут
    начинаться цепочки, выводимые из вхождения i_Item
*)

procedure tdm_Vpod.AddStartableItems( i_Root: IXMLNode; i_Item: IXMLNode );
var nProd: integer;  ProdNode: IXMLNode;
begin
   if Self.AlreadyHasItem( i_Root, i_Item ) then Exit;

   Self.AddToVpod( i_Root, i_Item );

   if ( i_Item.Attributes['TYPE'] = 'term' ) then Exit;

   for nProd := 0 to dm_Grammar.node_Prod.ChildNodes.Count - 1 do
   begin
      ProdNode := dm_Grammar.node_Prod.ChildNodes[nProd];

      if ( ProdNode.Attributes['START'] <> i_Item.Attributes['NAME'] ) then continue;
      if ( ProdNode.ChildNodes.Count = 0) then continue;

      Self.AddStartableItems( i_Root, ProdNode.ChildNodes[0] );
   end;
end;


(*
    Определение отношения впод для всех грамматических вхождений
*)

procedure Tdm_Vpod.ResolveVpodRelation;
var nProd,nSym: integer; ProdNode,SymNode,NewItem: IXMLNode;
begin
   xml_Vpod.LoadFromFile( frm_Main.GetTemplatePath + '\Template.xml' );

   for nProd := 0 to dm_Grammar.node_Prod.ChildNodes.Count - 1 do
   begin
      ProdNode := dm_Grammar.node_Prod.ChildNodes[nProd];

      for nSym := 0 to ProdNode.ChildNodes.Count - 1 do
      begin
         SymNode := ProdNode.ChildNodes[nSym];
         NewItem := Self.AddToVpod( xml_Vpod.DocumentElement, SymNode );

         if ( nSym <> ProdNode.ChildNodes.Count - 1 ) then
            Self.AddStartableItems( NewItem, ProdNode.ChildNodes[nSym + 1] );
      end;
   end;
end;


(*
    Добавляет к грамматическим вхождениям маркер дна магазина и
    определяет для него отношение ВПОД
*)

procedure Tdm_Vpod.ResolveMagazineEnd;
var NewItem: IXMLNode;
begin
   NewItem := xml_Vpod.DocumentElement.AddChild('LR_ITEM',0);

   NewItem.Attributes['TYPE']     :=  'sys';
   NewItem.Attributes['NAME']     :=  'EOF';
   NewItem.Attributes['PRODNUM']  :=  'x';
   NewItem.Attributes['POSNUM']   :=  'x';

   Self.AddStartableItems( NewItem, dm_Grammar.node_Prod.ChildNodes[0].ChildNodes[0] );
end;



//ИНТЕРФЕЙС




//определить отношения "Входит под" для входной грамматики
procedure Tdm_Vpod.BuildVpodRelation;
begin
   frm_Main.Log('Отношения OBLOW', clBlack);

   //Разметка множества порождающих правил грамматики
   Self.MarkGrammarItems;

   //Построение множества OBLOWграмматических вхождений
   Self.ResolveVpodRelation;

   //Построение множества OBLOW маркера дна магазина
   Self.ResolveMagazineEnd;


   end;


(*
    по узлу, содержащему грамматическое вхождение
    узнать его номер в репозитории вхождений
*)
function  Tdm_Vpod.GetItemNum( i_Item: IXMLNode ): integer;
var nItem: integer;  ItemNode: IXMLNode;
begin
   Result := -1;
   for nItem := 0 to xml_Vpod.DocumentElement.ChildNodes.Count - 1 do
   begin
      ItemNode := xml_Vpod.DocumentElement.ChildNodes[nItem];
      if ( ItemNode.Attributes['NAME']    = i_Item.Attributes['NAME']    ) and
         ( ItemNode.Attributes['TYPE']    = i_Item.Attributes['TYPE']    ) and
         ( ItemNode.Attributes['PRODNUM'] = i_Item.Attributes['PRODNUM'] ) and
         ( ItemNode.Attributes['POSNUM']  = i_Item.Attributes['POSNUM']  ) then
         Result := nItem;
   end;
end;



//Получить строковое представление грамматического вхождения
function  Tdm_Vpod.GetItemDesc ( i_Item: IXMLNode ): string;
begin
   Result := dm_Grammar.GetSymbolDesc( i_Item ) +
             '(' + i_Item.Attributes['PRODNUM'] + ',' + i_Item.Attributes['POSNUM'] + ')';
end;


end.
Соседние файлы в папке SLR_Grammar