unit umbrInic;

interface

function inicVarsTradutor (nomeArq: string): boolean;
procedure libMemTradutor;

const
   TRACO = ^A;

type
   pt_regras = ^ forma_regra;

   forma_regra = record                { Forma da entrada do vetor REGRAS }
                    contexto_a_esquerda : string[5];
                    contexto            : string[5];
                    contexto_a_direita  : string[5];
                    fonemas             : string[20];
                    prox                : pt_regras;
                 end;

var
   regras  : array [#0..#255] of pt_regras;   { ponteiros para listas de regras }

implementation


{--------------------------------------------------------}
{            extrai campos de uma regra lida
{--------------------------------------------------------}

procedure extraiCampos (var linha: string; var regra: forma_regra);
var
   pos: integer;

label 1, 2, 3, 4;

begin
    with regra do
       begin
          contexto_a_esquerda := '';
          for pos := 1 to length (linha) do
             if linha[pos] = '(' then
                 goto 1
             else
                 contexto_a_esquerda := contexto_a_esquerda + linha[pos];
          pos := 9999;

      1:
          contexto := '';
          for pos := pos+1 to length (linha) do
             if linha[pos] = ')' then
                 goto 2
             else
                 contexto := contexto + linha[pos];
          pos := 9999;

      2:
          contexto_a_direita := '';
          for pos := pos+1 to length (linha) do
             if linha[pos] = '=' then
                 goto 3
             else
                 contexto_a_direita := contexto_a_direita + linha[pos];
          pos := 9999;

      3:
          fonemas := '';
          for pos := pos+1 to length (linha) do
             if linha[pos] = '|' then
                 goto 4
             else
                 fonemas := fonemas + linha[pos];

      4:
          prox := nil;
      end;
end;

{--------------------------------------------------------}
{                   le arquivo de regras
{--------------------------------------------------------}

function inicVarsTradutor (nomeArq: string): boolean;
var
   ind_regra : char;                   { Ind p/ a entrada corrente de REGRS }
   regra : forma_regra;                { Regra lida }
   pt_aux,                             { Ponteiro auxiliar }
   novo_reg : pt_regras;               { Regra auxiliar }
   arq_regras: text;                   { Arquivo de regras }
   linha: string;                      { Linha lida do arquivo }

label fim;

begin
   inicVarsTradutor := false;

   for ind_regra := #0 to #255 do
      regras[ind_regra] := nil;

   assign (arq_regras, nomeArq);
   {$i-} reset (arq_regras); {$i+}
   if ioresult <> 0 then
       exit;

   while not eof (arq_regras) do
      begin
         readln (arq_regras, linha);
         if (linha = '') or (linha[1] = ';') then continue;

         extraiCampos (linha, regra);

         new (novo_reg);
         with novo_reg^ do
            begin
               contexto_a_esquerda := regra.contexto_a_esquerda;
               contexto            := regra.contexto;
               contexto_a_direita  := regra.contexto_a_direita;
               fonemas             := regra.fonemas;
               prox                := NIL;
            end;

         ind_regra := regra.contexto[1];
         if regras [ind_regra] = NIL then
             regras [ind_regra] := novo_reg
         else
             begin
                 pt_aux := regras[ind_regra];
                 while pt_aux^.prox <> NIL do
                     pt_aux := pt_aux^.prox;
                 pt_aux^.prox := novo_reg;
            end;
      end;

fim:
   close (arq_regras);
   inicVarsTradutor := true;
end;

{--------------------------------------------------------}
{               libera memoria do tradutor
{--------------------------------------------------------}

procedure libMemTradutor;
var
    preg, prox : pt_regras;
    ind_regra: char;

begin
    for ind_regra := ' ' to '_' do
        begin
            preg := regras [ind_regra];
            while preg <> NIL do
                begin
                    prox := preg^.prox;
                    dispose (preg);
                    preg := prox;
                end;
            regras [ind_regra] := NIL;
        end;
end;

end.
