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


{=}INTERFACE


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


type Tdm_Follow = class(TDataModule)
published
   xml_Follow: TXMLDocument;
private
   m_Modified: boolean;
   procedure InitFollowRelation;
   function  GetFirstSet( i_ProdNum: integer; i_StartSym: integer ): string;
   procedure GenerateFollowRelation;
public
   procedure BuildFollowRelation;
   function  GetFollowCode( i_NTermName: string ): string;
end;


var dm_Follow: Tdm_Follow;


{=}IMPLEMENTATION

uses Umsc_StrSetUtils, Ufrm_Main, Udm_Grammar, Udm_First;


{$R *.dfm}


//    Инициализация множеств СЛЕД для всех нетерминалов
procedure Tdm_Follow.InitFollowRelation;
var nNterm: integer;  AddNode,NTermNode: IXMLNode;  InitSet: string;
begin
   xml_Follow.LoadFromFile( frm_Main.GetTemplatePath + '\Template.xml' );

   InitStrSet( InitSet );

   for nNTerm := 1 to dm_Grammar.node_NTerm.ChildNodes.Count - 1 do
   begin
      NTermNode := dm_Grammar.node_NTerm.ChildNodes[nNterm];

      AddNode := xml_Follow.DocumentElement.AddChild('SYMBOL');
      AddNode.Attributes['NAME'] := NTermNode.Attributes['NAME'];
      AddNode.Attributes['TYPE'] := NTermNode.Attributes['TYPE'];
      AddNode.Attributes['CODE'] := InitSet;
   end;

   AddElement(InitSet,0);
   xml_Follow.DocumentElement.ChildNodes[0].Attributes['CODE'] := InitSet;
end;


(*
  Возвращает множество ПЕРВ от цепочки, начиная от символа "i_StartSym"
  части правила "i_ProdNum", и заканчивая концом цепочки
*)
function  Tdm_Follow.GetFirstSet( i_ProdNum: integer; i_StartSym: integer ): string;
var nSym: integer;  ProdNode, SymNode: IXMLNode;  Buffer: string;
begin
   ProdNode := dm_Grammar.node_Prod.ChildNodes[ i_ProdNum ];
   nSym := i_StartSym;

   InitStrSet( Buffer );

   while ( nSym < ProdNode.ChildNodes.Count ) do
   begin
      SymNode := ProdNode.ChildNodes[nSym];

      if ( SymNode.Attributes['TYPE'] = 'term' ) then
      begin
         AddElement( Buffer, dm_First.getXTermIndex(SymNode) );
         Break;
      end;

      MergeSet( Buffer, dm_First.GetCurrentRelation( dm_First.xml_First.DocumentElement, SymNode.Attributes['NAME'] ) );
      if not HasElement( Buffer, 0 ) then break;

      RemElement( Buffer, 0 );
      inc(nSym);
   end;

   if nSym = ProdNode.ChildNodes.Count then AddElement( Buffer, 0 );

   Result := Buffer;
end;


//построение множества СЛЕД нетерминалов
procedure Tdm_Follow.GenerateFollowRelation;
var nSym, nProd: integer;   SymNode,ProdNode: IXMLNode;
    LastInRule:  boolean;   MergeClient, RuleStart: string;
begin
   m_Modified := TRUE;
   while m_Modified do
   begin
      m_Modified := FALSE;

      for nProd := 1 to dm_Grammar.node_Prod.ChildNodes.Count - 1 do
      begin
         ProdNode   :=  dm_Grammar.node_Prod.ChildNodes[nProd];
         RuleStart  :=  ProdNode.Attributes['START'];

         if ProdNode.ChildNodes.Count = 0 then continue;

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

            if SymNode.Attributes['TYPE'] = 'term' then continue;

            MergeClient := GetFirstSet( nProd, nSym + 1 );
            LastInRule  := RemElement( MergeClient, 0 );

            m_Modified := dm_First.MergeToRelation( xml_Follow.DocumentElement, SymNode.Attributes['NAME'], MergeClient ) or m_Modified;
            if LastInRule then m_Modified := dm_First.MergeToRelation( xml_Follow.DocumentElement, SymNode.Attributes['NAME'], dm_First.GetCurrentRelation( xml_Follow.DocumentElement, RuleStart) ) or m_Modified;
         end;
      end;
   end;

end;



//    ИНТЕРФЕЙС
procedure Tdm_Follow.BuildFollowRelation;
begin
   try
      Self.InitFollowRelation;

      frm_Main.Log( 'Отношения FOLLOW', clBlack );
      Self.GenerateFollowRelation;
      frm_Main.Log( '', clBlack );
   except
      frm_Main.Log( '[ОШИБКА] Обнаружена  ошибка', clRed );
   end;
end;



//По имени нетерминала возвращает его множество СЛЕД
function  Tdm_Follow.GetFollowCode( i_NTermName: string ): string;
var nNterm: integer;  NTermNode: IXMLNode;
begin
   Result := '.';
   for nNterm := 0 to Self.xml_Follow.DocumentElement.ChildNodes.Count - 1 do
   begin
      NTermNode := Self.xml_Follow.DocumentElement.ChildNodes[nNterm];
      if NTermNode.Attributes['NAME'] = i_NTermName then Result := NTermNode.Attributes['CODE'];
   end;
end;


end.
Соседние файлы в папке SLR_Grammar
  • #
    01.05.20148 Кб13Udm_First.dcu
  • #
    01.05.2014290 б13Udm_First.dfm
  • #
    01.05.20146 Кб14Udm_First.pas
  • #
    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