Скачиваний:
14
Добавлен:
01.05.2014
Размер:
6.33 Кб
Скачать
unit Umsc_GenCode;


{=}INTERFACE

procedure GenCode;

{=}IMPLEMENTATION


uses SysUtils, Graphics, xmldom, XMLIntf, msxmldom, XMLDoc,
Ufrm_Main, Udm_Grammar, Udm_Goto, Udm_Action;


function IsTerm( i_Goto: IXMLNode ): string;
begin
if i_Goto.Attributes['TYPE'] = 'term' then Result := 'true' else Result := 'false';
end;


function ToAction( i_Act: IXMLNode ): string;
begin
if i_Act.Attributes['ACTION'] = 'ACCEPT' then Result := '-2'
else if i_Act.Attributes['ACTION'] = 'SHIFT' then Result := '-1'
else Result := i_Act.Attributes['DATA'];
end;


procedure GenCode;
var Fout: text; FName: string; nSym, nSub: integer; SymNode, SubNode: IXMLNode;
FCount, GCount: integer;
begin
FName := ChangeFileExt( ExtractFileName(dm_Grammar.xml_Grammar.FileName), '' );

//===========================================================================

frm_Main.Log( 'Создание pascal.cpp', clGreen );

AssignFile( Fout, FName + '.cpp'); Rewrite( Fout );

writeln(Fout, '// File generated by SLR(1)-Grammer for grammar ' + FName);

writeln(Fout, '');
writeln(Fout, '// Including external dependecies');
writeln(Fout, '');

writeln(Fout, '#include "StdAfx.h"');
writeln(Fout, '#include "' + FName + '.h"');

writeln(Fout, '');
writeln(Fout, '// Terminals information for grammar automaton');
writeln(Fout, '');

writeln(Fout, 'ENUM_TOKENS ' + FName + '_Terms [] = {');
for nSym := 0 to dm_Grammar.node_Term.ChildNodes.Count - 1 do
begin
SymNode := dm_Grammar.node_Term.ChildNodes[nSym];
if nSym <> 0 then writeln(Fout,',');
write(Fout, SymNode.Attributes['NAME'] );
end;
writeln(Fout, '');
writeln(Fout, '};');

writeln(Fout, '');
writeln(Fout, '// Productions information for grammar automaton');
writeln(Fout, '');

writeln(Fout, 'RuleInfo ' + FName + '_Rules [] = {');
for nSym := 0 to dm_Grammar.node_Prod.ChildNodes.Count - 1 do
begin
SymNode := dm_Grammar.node_Prod.ChildNodes[nSym];
if nSym <> 0 then writeln(Fout,',');
write(Fout, '{ ' + SymNode.Attributes['START'] + ', ' + IntToStr( SymNode.ChildNodes.Count ) + ' }' );
end;
writeln(Fout, '');
writeln(Fout, '};');

writeln(Fout, '');
writeln(Fout, '// Goto table for grammar automaton');
writeln(Fout, '');

GCount := 0;
writeln(Fout, 'GInfo ' + FName + '_Goto [] = {');
for nSym := 0 to dm_Goto.xml_States.DocumentElement.ChildNodes.Count - 1 do
begin
SymNode := dm_Goto.xml_States.DocumentElement.ChildNodes[nSym];
for nSub := 0 to SymNode.ChildNodes.Count - 1 do
begin
SubNode := SymNode.ChildNodes[nSub];
if not((nSub = 0) and (nSym = 0)) then writeln(Fout,',');
write(Fout, '{ ' + SymNode.Attributes['NAME'] + ', ' +
IsTerm(SubNode) + ', ' + SubNode.Attributes['NAME'] + ', ' +
SubNode.Attributes['STNAME'] + ' }');
inc(GCount);
end;
end;
writeln(Fout, '');
writeln(Fout, '};');

writeln(Fout, '');
writeln(Fout, '// Action table for grammar automaton');
writeln(Fout, '');

FCount := 0;
writeln(Fout, 'FInfo ' + FName + '_Action [] = {');
for nSym := 0 to dm_Action.xml_Action.DocumentElement.ChildNodes.Count - 1 do
begin
SymNode := dm_Action.xml_Action.DocumentElement.ChildNodes[nSym];
for nSub := 0 to SymNode.ChildNodes.Count - 1 do
begin
SubNode := SymNode.ChildNodes[nSub];

if not((nSub = 0) and (nSym = 0)) then writeln(Fout,',');

write(Fout, '{ ' + SymNode.Attributes['NAME'] + ', ' +
SubNode.Attributes['NAME'] + ', ' + ToAction( SubNode ) + ' }');
inc(FCount);
end;
end;
writeln(Fout, '');
writeln(Fout, '};');

CloseFile( Fout );

//===========================================================================

frm_Main.Log( 'Создание pascal.h', clGreen );

AssignFile( Fout, FName + '.h'); Rewrite( Fout );

writeln(Fout, '// File generated by SLR(1)-Grammar for grammar ' + FName);

writeln(Fout, '');
writeln(Fout, '#include "SyntaxAn.h"');
writeln(Fout, '#include "Tokens.h"');

writeln(Fout, '');
writeln(Fout, '#define ' + FName + '_RulesCount ' + IntToStr( dm_Grammar.node_Prod.ChildNodes.Count ));
writeln(Fout, '#define ' + FName + '_FCount ' + IntToStr( FCount ));
writeln(Fout, '#define ' + FName + '_GCount ' + IntToStr( GCount ));

writeln(Fout, '');
writeln(Fout, '// Defining symbolics for nonterminals');
writeln(Fout, '');

for nSym := 0 to dm_Grammar.node_NTerm.ChildNodes.Count - 1 do
begin
SymNode := dm_Grammar.node_NTerm.ChildNodes[nSym];
writeln(Fout, '#define ' + SymNode.Attributes['NAME'] + ' ' + IntToStr(nSym));
end;

writeln(Fout, '');
writeln(Fout, '// Defining symbolics for automaton states');
writeln(Fout, '');

for nSym := 0 to dm_Goto.xml_States.DocumentElement.ChildNodes.Count - 1 do
begin
SymNode := dm_Goto.xml_States.DocumentElement.ChildNodes[nSym];
writeln(Fout, '#define ' + SymNode.Attributes['NAME'] +' ' + IntToStr(nSym));
end;

writeln(Fout, '');
writeln(Fout, '// Defining symbolics for grammar productions');
writeln(Fout, '');

for nSym := 0 to dm_Grammar.node_Prod.ChildNodes.Count - 1 do
begin
SymNode := dm_Grammar.node_Prod.ChildNodes[nSym];
write(Fout,'#define _' + SymNode.Attributes['START'] + '__');
for nSub := 0 to SymNode.ChildNodes.Count - 1 do
begin
SubNode := SymNode.ChildNodes[nSub];
write(Fout, {SubNode.Attributes['TYPE'] + }SubNode.Attributes['NAME'] + '_');
end;
writeln(Fout, ' ' + IntToStr(nSym));
end;


writeln(Fout, '');
writeln(Fout, '// Defining external links');
writeln(Fout, '');

writeln(Fout, 'extern ENUM_TOKENS ' + FName + '_Terms[];');
writeln(Fout, 'extern RuleInfo ' + FName + '_Rules[];');
writeln(Fout, 'extern GInfo ' + FName + '_Goto[];');
writeln(Fout, 'extern FInfo ' + FName + '_Action[];');

CloseFile( Fout );


//===========================================================================
end;

end.
Соседние файлы в папке SLR_Grammar