
Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Курсовая работа2 / SLR_Grammar / Udm_Vpod
.pas // Авторы студенты группы 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.
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