Скачиваний:
14
Добавлен:
01.05.2014
Размер:
5.32 Кб
Скачать
// Авторы студенты группы 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.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
  • #
    01.05.20146.86 Кб13Udm_Vpod.pas
  • #
    01.05.20147.29 Кб12Ufrm_Main.dcu
  • #
    01.05.20141.82 Кб12Ufrm_Main.dfm