Скачиваний:
15
Добавлен:
01.05.2014
Размер:
6 Кб
Скачать
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