Скачиваний:
13
Добавлен:
01.05.2014
Размер:
4.62 Кб
Скачать
// Авторы студенты группы 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.28 Кб12Udm_First.dcu
  • #
    01.05.2014290 б12Udm_First.dfm
  • #
    01.05.20146.33 Кб13Udm_First.pas
  • #
    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