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


unit Udm_Grammar;


{=}INTERFACE


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


type Tdm_Grammar = class(TDataModule)
published
    //--------------------------------------------------------------------------
    xml_Grammar: TXMLDocument;
    //--------------------------------------------------------------------------
private
    //--------------------------------------------------------------------------
    function  GetNumByName( i_Section: IXMLNode; i_Name: string ): integer;
    function  ValidateType( i_Section: IXMLNode; i_Type: string ): boolean;
    function  ValidateProd: boolean;
    procedure FillGrammar;
    //--------------------------------------------------------------------------
public
    //--------------------------------------------------------------------------
    node_Term:    IXMLNode;
    node_NTerm:   IXMLNode;
    node_Prod:    IXMLNode;
    //--------------------------------------------------------------------------
    procedure LoadGrammar( i_Path: string );
    function  GetSymbolDesc( i_Symbol: IXMLNode ): string;
    //--------------------------------------------------------------------------
end;


var dm_Grammar: Tdm_Grammar;


{=}IMPLEMENTATION


uses Ufrm_Main;


{$R *.dfm}




(*
    В секции i_Section ищется узел-потомок, имеющий аттрибут 'NAME',
    равный i_Name. В случае отсутствия такого узла, возвращается -1.
*)

function Tdm_Grammar.GetNumByName( i_Section: IXMLNode; i_Name: string ): integer;
var I: integer;
begin
   Result := -1;
   for I := 0 to i_Section.ChildNodes.Count - 1 do
      if (i_Section.ChildNodes[I].Attributes['NAME'] = i_Name) then Result := I;
end;


(*
    Проверяет все элементы секции i_Section на предмет соответствия атрибута
    TYPE равному i_Type.
*)

function Tdm_Grammar.ValidateType( i_Section: IXMLNode; i_Type: string ): boolean;
var I: integer;
begin
   Result := TRUE;
   for I := 0 to i_Section.ChildNodes.Count - 1 do
      Result := Result and (i_Section.ChildNodes[I].Attributes['TYPE'] = i_Type);
end;


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

function Tdm_Grammar.ValidateProd: boolean;
var pNum,lNum: integer; CurProd, LocNode: IXMLNode;
begin
   Result := TRUE;
   for pNum := 0 to node_Prod.ChildNodes.Count - 1 do
   begin
      CurProd := node_Prod.ChildNodes[pNum];
      Result := Result and (Self.GetNumByName(node_NTerm, CurProd.Attributes['START']) > -1);
      for lNum := 0 to CurProd.ChildNodes.Count - 1 do
      begin
         if CurProd.ChildNodes[lNum].Attributes['TYPE'] = 'term' then LocNode := node_Term
                                                                 else LocNode := node_NTerm;
         Result := Result and (Self.GetNumByName(LocNode, CurProd.ChildNodes[lNum].Attributes['NAME']) > -1)
      end;
   end;
end;


(*
    Построение пополненной грамматике по исходной. Добавляется самый начальный
    символ и цепное правило, которое выводит из него всю грамматику
*)
procedure Tdm_Grammar.FillGrammar;
var StartSym: IXMLNode; StartRule: IXMLNode; StartRef: IXMLNode; SymName: string;
begin
   StartSym := node_NTerm.AddChild( 'SYMBOL' , 0 );
   StartSym.Attributes['TYPE'] := 'nterm';
   StartSym.Attributes['NAME'] := 'START';

   SymName := node_Prod.ChildNodes[0].Attributes['START'];

   StartRule := node_Prod.AddChild( 'PRODUCTION' , 0);
   StartRule.Attributes['START'] := 'START';

   StartRef := StartRule.AddChild( 'SYMBOL' );
   StartRef.Attributes['TYPE'] := 'nterm';
   StartRef.Attributes['NAME'] := SymName;
end;



//ИНТЕРФЕЙС
//Загрузить грамматику из файла, выполняет проверку и подготавливает её к анализу
procedure Tdm_Grammar.LoadGrammar( i_Path: string );
begin
   frm_Main.Log('      Проверка грамматики...', clGreen);

   //загрузка грамматики
   xml_Grammar.LoadFromFile( i_Path );
   node_Term  := xml_Grammar.DocumentElement.ChildNodes[0];
   node_NTerm := xml_Grammar.DocumentElement.ChildNodes[1];
   node_Prod  := xml_Grammar.DocumentElement.ChildNodes[2];

   //множество терминальных символов
   if not Self.ValidateType( node_Term, 'term') then
      frm_Main.Log('[ОШИБКА] В множестве терминальных символов обнаружены нетерминалы', clRed);

   // множество нетерминальных символов
   if not Self.ValidateType( node_NTerm, 'nterm') then
      frm_Main.Log('[ОШИБКА] В множестве нетерминальных символов обнаружены терминалы', clRed);
   if not Self.GetNumByName(node_NTerm, 'START') = -1 then
      frm_Main.Log('[ОШИБКА] В множестве нетерминальных символов обнаружен символ "START"', clRed);

   //множество порождающих правил
   if not Self.ValidateProd then
      frm_Main.Log('[ОШИБКА] В порождающих правилах обнаружены необъявленные символы', clRed);

   //Построение пополненной грамматики
   Self.FillGrammar;

   frm_Main.Log(' ', clBlack);

   end;



//Получить строковое представление символа, переданного в виде узла xml
function  Tdm_Grammar.GetSymbolDesc( i_Symbol: IXMLNode ): string;
begin
   Result := i_Symbol.Attributes['TYPE'] + '_' + i_Symbol.Attributes['NAME'];
end;


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