Análise Léxica

(O Texto desta página ainda não foi revisado, portanto, deve ser usado com cautela)


Conceitos Auxiliares

 
Token Lexema Padrão
id Valor,x,y,calcula,... letra.(legra|digito)*
if if if
relacao < <= >= < ou <= ou >=
num 123  10.342E20 Ver Gramática Abaixo

Problema da Buferização: Leitura em dispositivos de bloco.

Expressões Regulares com Simplificações: (Exemplo)

digito -> [0-9]   /* 0 | 1 | ... | 9 */
digitos -> digito+   /* digito digito* */
fracao_opc -> (. digitos)?  /* . digitos | \empty */
expoe_opc -> (E (+ | -)? digitos)?
num -> digitos fracao_opc expoe_opc

letra -> [A-Za-z]
id -> letra.(letra|digito)*

delim -> branco | tab | newline
ws -> delim*

Padrões de Tokens para um subconjunto do Pascal

 
Token Valor Atrib. Padrão
id apont. tab. id (acima)
num param? num (acima)
oprel LT <
oprel LE <=
...
if - if (tab. simb)
then - " "
ws Nao Retorna ws (acima)

Diagramas de Transição

Operadores Relacionais:

[0] --- < --- (1) --- = ----- ((2))  return(relop,LE)
|                     \--- > ----- ((3))                    NE
|                      \-- outro -- ((4))                   LT
\----- = ---- ((5)) return(relop,EQ)
 \---- > ----- (6) --- = ----- ((7)) return(relop,GE)
                      \----- outro --((8)) return(relop,GT)

Identificadores e Palavras-Chaves

[9]---- letra --- (10) ----- outro --- ((11))  return( obter_token() , instalar_id() )
                           ^    |
                         Letra ou Digito

Numeros

....

Espaços ...

[28] --- delim --- (29)------ outro --- ((30))
                             ^       |
                             delim

Implementação Direta de Diagramas de Transição

int estado = 0, partida = 0;
int valor_lexico; /* Retornar 2o componente do token */

int falhar()
{
    apontador_adiante = inicio_de_token;
   switch(partida)
  {
     case 0; partida = 9; break;
     9 - 12
    12 - 20
    20 - 25
    25 recuperar_erro() break
    default: ...
  }
  return(partida);
}

token proximo_token()
{
     while(1)
    {
         switch(estado) /* Cuidado com iniac. de estado */
        {
             case 0: ...
             case 1:
             ...
             case 9: c = proximo_char();
                        if( isletter(c)) estado = 10;
                        else estado = falhar();
                        break; /* sai do switch */
             case 10: ...
        }
    }
}

Implementação Usando Lex
%{
        #include "global.h"  /* Definir aqui simbolos para Tokens: ID, NUM,... */
}%

/* definições regulares */

delim           [ \t\n]
ws              {delim}+
letra            [A-Za-z]
digito          [0-9]
id               {letra} ({letra} | {digito})*
numero      {digito}+ (\. {digito}+)? (E[+\-]? {digito}+)?

%%

{ws}          {  /* nenhuma acao */ }
if                {return(IF)}
then           {return(THEN)}
else            {return(ELSE)}
{id}           {yylval = instalar_id(); return(ID);}
{numero}  {yylval = instalar_num(); return(NUM);}
"<"            {yylval=LT; return(OPREL)}
"<="          {yylval=LE; return(OPREL)}
...

%%

void instalar_id()
{  ...
}

void instalar_num()
{  ...
}