Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Курсовая работа2 / SLR_Grammar / Udm_Follow
.pas // Авторы студенты группы 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.
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