Скачиваний:
14
Добавлен:
01.05.2014
Размер:
6.86 Кб
Скачать
// Авторы студенты группы 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