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

unit Udm_Goto;


{=}INTERFACE


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


type Tdm_Goto = class(TDataModule)
published
//--------------------------------------------------------------------------
xml_States: TXMLDocument;
xml_Voc: TXMLDocument;
//--------------------------------------------------------------------------
private
//---------------------------------------------------------------------------
m_StateCount: integer;
//---------------------------------------------------------------------------
procedure BuildGeneralVocabulary;
function AddState( i_Code: string ): IXMLNode;
function GetState( i_Code: string ): integer;
function ResolveTransition( i_State, i_VocSym: IXMLNode ): string;
procedure AddTransition( i_State, i_VocSym: IXMLNode; i_Code: string );
procedure BuildInitialState;
procedure BuildReachables( i_State: IXMLNode );
//---------------------------------------------------------------------------
public
//---------------------------------------------------------------------------
procedure BuildGotoFunction;
function GetStateDesc( i_State: IXMLNode ): string;
function GetTransDesc( i_Trans: IXMLNode ): string;
function IsGotoDefined( i_State: IXMLNode; i_NTermName: string): boolean;
//---------------------------------------------------------------------------
end;


var dm_Goto: Tdm_Goto;


{================================================================}IMPLEMENTATION

uses Udm_Grammar, Udm_Vpod, Ufrm_Main, Umsc_StrSetUtils;


{$R *.dfm}


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


(*
Процедура строит обобщённый словарь грамматики, в который включает
сначала все нетерминалы, а затем - все терминалы
символ START включать не следует
*)

procedure Tdm_Goto.BuildGeneralVocabulary;
var nSym: integer; AddNode: IXMLNode;
begin
xml_Voc.LoadFromFile( frm_Main.GetTemplatePath + '\Template.xml' );
for nSym := 1 to dm_Grammar.node_NTerm.ChildNodes.Count - 1 do
begin
AddNode := dm_Grammar.node_NTerm.ChildNodes[nSym].CloneNode(FALSE);
xml_Voc.DocumentElement.ChildNodes.Add( AddNode );
end;
for nSym := 0 to dm_Grammar.node_Term.ChildNodes.Count - 1 do
begin
AddNode := dm_Grammar.node_Term.ChildNodes[nSym].CloneNode(FALSE);
xml_Voc.DocumentElement.ChildNodes.Add( AddNode );
end;
end;


(*
Добавляет к множеству состояний очередное состояние. Совокупность грамматических
вхождений, соответствующих состоянию, шифруется в i_Code
*)

function Tdm_Goto.AddState( i_Code: string ): IXMLNode;
var StateNode: IXMLNode;
begin
StateNode := xml_States.DocumentElement.AddChild('STATE');
StateNode.Attributes['NAME'] := 'STATE_' + IntToStr(m_StateCount);
StateNode.Attributes['CODE'] := i_Code;

inc(m_StateCount);
Result := StateNode;
end;


(*
Сканирует множество определённых состояний, пытаясь найти среди них код,
равный i_Code;
*)

function Tdm_Goto.GetState( i_Code: string ): integer;
var nState: integer;
begin
Result := -1;
for nState := 0 to xml_States.DocumentElement.ChildNodes.Count - 1 do
if xml_States.DocumentElement.ChildNodes[nState].Attributes['CODE'] = i_Code then Result := nState;
end;


(*
По текущему состоянию i_State
(представленному кодом) и символу обобщённого словаря нужно узнать
код состояния, в которое перейдёт автомат по этому символу
*)

function Tdm_Goto.ResolveTransition( i_State, i_VocSym: IXMLNode ): string;
var ParseCode, Buffer: string; nItem, nVpod: integer;
ParseSym: TStrSetIterator; VpodItem: IXMLNode;
begin
InitStrSet( Buffer );
ParseCode := i_State.Attributes['CODE'];
InitStrSetIterator( ParseSym );

while HasMoreElements( ParseCode, ParseSym ) do
begin
nItem := GetNextElement( ParseCode, ParseSym );

for nVpod := 0 to dm_Vpod.xml_Vpod.DocumentElement.ChildNodes[nItem].ChildNodes.Count - 1 do
begin
VpodItem := dm_Vpod.xml_Vpod.DocumentElement.ChildNodes[nItem].ChildNodes[nVpod];

if ( VpodItem.Attributes['TYPE'] = i_VocSym.Attributes['TYPE'] ) and
( VpodItem.Attributes['NAME'] = i_VocSym.Attributes['NAME'] ) then
Umsc_StrSetUtils.AddElement( Buffer, dm_Vpod.GetItemNum( VpodItem ) );
end;
end;
Result := Buffer;
end;


(*
Добавляет в состояние i_State переход по символу i_VocSym в состояние,
обозначенное кодом i_Code
*)

procedure Tdm_Goto.AddTransition( i_State, i_VocSym: IXMLNode; i_Code: string );
var TranNode: IXMLNode;
begin
TranNode := i_State.AddChild( 'TRANSITION' );
TranNode.Attributes['TYPE'] := i_VocSym.Attributes['TYPE'];
TranNode.Attributes['NAME'] := i_VocSym.Attributes['NAME'];
TranNode.Attributes['STNAME'] := i_Code;
end;


(*
Прооцедура формирует начальное состояние из символа конца магазина
*)

procedure Tdm_Goto.BuildInitialState;
var InitSet: string;
begin
xml_States.LoadFromFile( frm_Main.GetTemplatePath + '\Template.xml' );

m_StateCount := 0;

InitStrSet( InitSet );
AddElement( InitSet, 0 );
Self.AddState( InitSet );
end;


(*
рурсивно строит таблицу переходов управляющего автомата
Надо её только вызвать для начального состояния.
*)

procedure Tdm_Goto.BuildReachables( i_State: IXMLNode );
var nVoc,nStat: integer; VocNode: IXMLNode; Code,Name: string; NewState: IXMLNode;
begin
for nVoc := 0 to xml_Voc.DocumentElement.ChildNodes.Count - 1 do
begin
VocNode := xml_Voc.DocumentElement.ChildNodes[nVoc];

Code := ResolveTransition( i_State, VocNode );
if ( IsEmpty( Code ) ) then Continue;

NewState := NIL;
nStat := Self.GetState(Code);
if ( nStat = -1 ) then
begin
NewState := AddState(Code);
nStat := m_StateCount - 1;
end;

Name := 'STATE_' + IntToStr(nStat);
Self.AddTransition( i_State, VocNode, Name );

if ( NewState <> NIL ) then Self.BuildReachables( NewState );
end;
end;



//ИНТЕРФЕЙС


// построение функции свёртки


procedure Tdm_Goto.BuildGotoFunction;
begin
try

//Построение обобщённого словаря грамматики
Self.BuildGeneralVocabulary;

//Формирование начального состояния автомата
Self.BuildInitialState;

//Поиск достижимых состояний автомата
Self.BuildReachables( xml_States.DocumentElement.ChildNodes[0] );
frm_Main.Log( '', clBlack );
except
frm_Main.Log( '[ОШИБКА] Обнаружена ошибка', clRed );
end;
end;


(*
Возвращает строковое представление состояния, однако не распарсивает
его грамматические вхождения
*)

function Tdm_Goto.GetStateDesc( i_State: IXMLNode ): string;
begin
Result := i_State.Attributes['NAME'];
end;


(*
Возвращает строковое представление перехода состояния по символу словаря
*)

function Tdm_Goto.GetTransDesc( i_Trans: IXMLNode ): string;
begin
Result := dm_Grammar.GetSymbolDesc( i_Trans ) + '(' + i_Trans.Attributes['STNAME'] + ')';
end;


(*
Проверяет для заданного состояния: определен ли на нём переход по нетерминалу
с именем i_NTermName. Это нужно при построении функции действий
*)

function Tdm_Goto.IsGotoDefined( i_State: IXMLNode; i_NTermName: string): boolean;
var nGoto: integer; GotoNode: IXMLNode;
begin
Result := FALSE;
for nGoto := 0 to i_State.ChildNodes.Count - 1 do
begin
GotoNode := i_State.ChildNodes[nGoto];
if ( GotoNode.Attributes['TYPE'] = 'nterm' ) and
( GotoNode.Attributes['NAME'] = i_NTermName ) then
Result := TRUE;
end;
end;

end.
Соседние файлы в папке SLR_Grammar
  • #
    01.05.20147.27 Кб12Udm_Follow.dcu
  • #
    01.05.2014191 б12Udm_Follow.dfm
  • #
    01.05.20144.62 Кб13Udm_Follow.pas
  • #
    01.05.20149.93 Кб12Udm_Goto.dcu
  • #
    01.05.2014283 б12Udm_Goto.dfm
  • #
    01.05.20148.06 Кб13Udm_Goto.pas
  • #
    01.05.20147.32 Кб12Udm_Grammar.dcu
  • #
    01.05.2014195 б12Udm_Grammar.dfm
  • #
    01.05.20145.32 Кб14Udm_Grammar.pas
  • #
    01.05.20149.05 Кб12Udm_Vpod.dcu
  • #
    01.05.2014186 б12Udm_Vpod.dfm