Você está na página 1de 7

1º Projeto Analisador LÉXICO de um compilador de Redes de Petri

FONTE Léxico Sintático Semântico OBJ

A linguagem de entrada ( FONTE )

A representação gráfica (grafo) de uma rede genérica é mostrada a seguir.

Uma descrição em forma de texto do grafo da rede, poderia ser a lista de todas as transições com suas etapas de entrada e de
saída. Uma transição genérica Tj com p etapas de entradas e q-p etapas de saída seria representada assim:

E1 Tj EP+1

Ep Eq

Tj :
E1 / E2 / . . . / Ep ;
EP+1 / EP+2 / . . . / Eq .

1 de 7
A linguagem de saída ( OBJETO )

Os diagramas "ladder" são uma representação que imita os diagramas dos painéis de relês do passado. Embora alguns CP's
possam ser programados em uma espécie de Assembly, para os elementos básicos (contatos, bobinas e “flags”) isso não passa de
uma representação mnemônica do mesmo diagrama, tanto que permitem a passagem de uma forma para a outra e vice-versa.

A seguir, um exemplo ilustra a utilização dos elementos básicos na representação gráfica da linguagem de contatos, e à direita,
uma forma mnemônica equivalente.

130

Projeto do Analisador léxico


Para facilitar a documentação da rede de Petri, vamos permitir que a linguagem de entrada admita comentários que iniciam em
qualquer posição da linha com "//" e se estendem até o final da linha. O reconhecedor também se incumbe de eliminar
comentários, brancos e mudanças de linha para a fase sintática.

Os terminais da linguagem serão o conjunto { ponto, dois pontos, ponto-e-vírgula, barra inclinada e os identificadores de etapa e
de transição }. A entrada do programa é um arquivo tipo texto com um texto qualquer, A saída é um arquivo texto com uma lista
dos terminais: símbolos (SBL), identificadores de etapa (IDE) e identificadores de transição (IDT). Os sinais de pontuação e
demais caracteres isolados encontrados no texto são classificados como símbolos (SBL).

O autômato abaixo deve ser realizado na forma de um diagrama de estados, tal como no projeto #1. A cada transição deve haver
um conjunto de ações capazes de compor os terminais da linguagem ou descartar caracteres quando for o caso de caracteres
brancos e/ou comentários. O léxico deve ser uma função ("procedure") que será chamada pelo analisador sintático (projeto #3)
cada vez que este precisar de um átomo ("token").

não é fim de
6 barra 7 linha( NL )
8

outros ( SBL )

( SBL ) barra ( )

brancos

( SBL )
( IDT ) ( SBL ) ( IDE )
E
T

número 5 número número


número 4 2 3
2 de 7
EXEMPLO

IDT T1
// fonte com texto qualquer
SBL :
IDE E1
SBL ;
// transicao #1 IDE E2
SBL .

IDT T2
T1 :
SBL :
E1 ; IDE E2
SBL /
E2 . IDE E5
SBL ;
IDE E3
// transicao #2 SBL /
IDE E4
SBL .

T2 : SBL O
SBL b
E2 / E5;
Léxico SBL s
E3/E4 . SBL 2
SBL 1
// fim SBL 3

IDE E1234567890
// Outros casos
SBL E
SBL 7

Obs 213 SBL @


SBL #
E1234567890 // COMENTARIO
SBL $
E 7 SBL %
SBL ^
@#$%^& *()+ SBL &
SBL *
SBL (
SBL )
SBL +

3
A título de ilustração, fornecemos abaixo um "código" de um Léxico hipotético:

A .. Z A .. Z
4 2 0 .. 9

outros

brancos
* 7 1

/

* todos
/

todos 6 * 5 3
todos

function S = flex2 ( void )

global OUT Posicao Arquivo

E = 1; T = 0; VAR = [];
[C_lido,T] = le_car2([]);

while (1)

if strcmp(C_lido,'ù')
S = ['SB ' C_lido];
break
end

if ( E==1 & T==4 ),


Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=1;
elseif ( E==1 & T==2 ),
VAR = [ C_lido ];
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=2;
elseif ( E==1 & T==3 ),
VAR = [ C_lido ];
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=3;
elseif ( E==1 & ~(T==2|T==3|T==4|T ==6) ),
VAR = [ C_lido ];
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=4;

elseif ( E==2 & (T==1|T==2) ),


VAR = [ VAR C_lido ];
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=2;

4
elseif ( E==2 & ~(T==1|T==2) ),
S = ['ID ' VAR];
VAR = ['ID ' VAR];
escreve2( VAR ); % SÓ LOOK_AHEAD
break
E=1;
elseif ( E==3 & ~(T==3) ),
VAR = [ VAR C_lido ];
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=3;
elseif ( E==3 & T==3 ),
S = ['TE ' VAR C_lido ];
VAR = ['TE ' VAR C_lido ];
escreve2( VAR );
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
break
E=1;
elseif ( E==4 ),
S = ['SB ' VAR ];
VAR = ['SB ' VAR ];
escreve2( VAR ); % SÓ LOOK_AHEAD
break
E=1;
% subrede para comentarios

elseif ( E==1 & T==6 ),


VAR = [ C_lido ];
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=5;
elseif ( E==5 & ~(T==7) ),
S = ['SB ' '/' ];
VAR = ['SB ' '/' ];
escreve2( VAR ); % SÓ LOOK_AHEAD
break
E=1;
elseif ( E==5 & T==7 ),
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=6;
elseif ( E==6 & ~(T==7) ),
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=6;
elseif ( E==6 & T==7 ),
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=7;
elseif ( E==7 & T==7 ),
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=7;
elseif ( E==7 & ~(T==7|T==6) ),
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=6;
elseif ( E==7 & T==6 ),
Posicao = Posicao + 1;
[C_lido,T] = le_car2([]);
E=1;
end

end

5
Rotinas auxiliares do analisador léxico

function Info = escreve2( String_Escrever )

global OUT Posicao Arquivo


fprintf( OUT,'%s\n', String_Escrever );

function [Caracter, Transicoes] = le_car2( void )

global OUT Posicao Arquivo


Caracter = Arquivo(Posicao);

if ( Caracter >= '0' ) & ( Caracter <= '9' )


Transicoes = 1; % Numero T(1)

elseif ( (Caracter >= 'A') & (Caracter <= 'Z') | ...


(Caracter >= 'a') & (Caracter <= 'z') )
Transicoes = 2; % Letra T(2)

elseif ( Caracter == '"' )


Transicoes = 3; % Aspas T(3)

elseif ( abs(Caracter) == 13 | ... % Newline T(4)


abs(Caracter) == 10 | ... % Return
abs(Caracter) == 32 | ... % Branco
abs(Caracter) == 9 ) % Tab
Transicoes = 4;

elseif ( Caracter == '/' )


Transicoes = 6; % Barra T(6)

elseif ( Caracter == '*' )


Transicoes = 7; % Estrela T(7)

else
Transicoes = 5; % Outros Simbolos T(5)

end

function Arquivo = le_arq2( FID )

j = 0;

while feof(FID) ~= 1, % enquanto nao e finalde arquivo


S = fgets(FID); % o tamanho se S é da linha
for i = 1:max(size(S));
j = j + 1;
Arquivo(j) = S(i);
end
end

Arquivo(j+1) = ' '; % espaço


Arquivo(j+2) = 'ù'; % marca final de arquivo <ALT>+151

6
Teste do Analisador léxico

% MAIN PROGRAM 

global OUT Posicao Arquivo

IN = fopen('c:\fonte.txt','r');
OUT = fopen('c:\token.txt','w');

Arquivo = le_arq2( IN );
Posicao = 1; i = 1;

i, S = flex2([]),pause % flex2([]) é a chamada da função LÉXICO

while (S ~= 'ù' )

i = i + 1;
i, S = flex2([]),pause % exibe o token formado e o numero da linha

end

fclose( 'all' );

O analisador LÉXICO ( função flex ) e a estrutura do compilador

Você também pode gostar