Скачиваний:
14
Добавлен:
01.05.2014
Размер:
8 Кб
Скачать
//  Авторы студенты группы 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 Кб13Udm_Follow.dcu
  • #
    01.05.2014191 б13Udm_Follow.dfm
  • #
    01.05.20145 Кб14Udm_Follow.pas
  • #
    01.05.201410 Кб13Udm_Goto.dcu
  • #
    01.05.2014283 б13Udm_Goto.dfm
  • #
    01.05.20148 Кб14Udm_Goto.pas
  • #
    01.05.20147 Кб13Udm_Grammar.dcu
  • #
    01.05.2014195 б13Udm_Grammar.dfm
  • #
    01.05.20145 Кб15Udm_Grammar.pas
  • #
    01.05.20149 Кб13Udm_Vpod.dcu
  • #
    01.05.2014186 б13Udm_Vpod.dfm