Anda di halaman 1dari 5

Construo de um analisador lxico e um sinttico

Implementao em C

#include <stdio.h>
#include <string.h>
typedef struct
{
int COD;
char VALOR[50];
} TOKEN;
int delta (int q, char ch)
{
int M[19][15] =
{ { 12, 13, 14, 15,

1, -2, -2,

4, 10,

7, 10, 10, 10,

0, -2 },

{ -1, -1, -1, -1,

1, -1,

2, -1, -1, -1, -1, -1, -1, -1, -2 },

{ -3, -3, -3, -3,

3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3 },

{ -1, -1, -1, -1,

3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2 },

{ -1, -1, -1, -1, 10, 11, -1, 10,

5, 10, 10, 10, 10, -1, -2 },

{ -1, -1, -1, -1, 10, 11, -1, 10, 10,

6, 10, 10, 10, -1, -2 },

{ -1, -1, -1, -1, 10, 11, -1, 10, 10, 10, 10, 10, 10, -1, -2 },
{ -1, -1, -1, -1, 10, 11, -1, 10, 10, 10,

8, 10, 10, -1, -2 },

{ -1, -1, -1, -1, 10, 11, -1, 10, 10, 10, 10,

9, 10, -1, -2 },

{ -1, -1, -1, -1, 10, 11, -1, 10, 10, 10, 10, 10, 10, -1, -2 },
{ -1, -1, -1, -1, 10, 11, -1, 10, 10, 10, 10, 10, 10, -1, -2 },
{ -3, -3, -3, -3, 10, -3, -3, 10, 10, 10, 10, 10, 10, -3, -3 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2 },
{

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0 },

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0 },

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0,

0 }

};

switch (ch)
{
case '+' : return M[q][0]; break;
case '-' : return M[q][1]; break;
case '*' : return M[q][2]; break;
case '/' : return M[q][3]; break;
case '_' : return M[q][5]; break;
case '.' : return M[q][6]; break;
case 'm' : return M[q][7]; break;
case 'o' : return M[q][8]; break;
1

Construo de um analisador lxico e um sinttico

Implementao em C

case 'd' : return M[q][9]; break;


case 'i' : return M[q][10]; break;
case 'v' : return M[q][11]; break;
case ' ' : return M[q][13]; break;
case '\t': return M[q][13]; break;
case '\n': return M[q][13]; break;
default:
if (ch >= '0' && ch <= '9')

// digitos

return M[q][4];
else if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')

// outras letras

return M[q][12];
else
return M[q][14];

// outros caracteres

}
} // delta
int AnalisadorLexico (TOKEN *TOK, int *tam_TOK)
{
char ch, st[50];
int

k, q_ant=0, q_act=0, tam_st = 0;

FILE *f;
f = fopen("ENT_1.txt", "r"); if (f == NULL)
return 0;
*tam_TOK = 0;
ch = fgetc(f);
while (ch != EOF)
{
for (k = 0; k < 50; k++)
st[k] = '\0';
tam_st = 0; q_act = 0;
do {
q_ant = q_act; q_act = delta(q_ant, ch);
if (q_act > 0)
{
st[tam_st] = ch;
tam_st++;
ch = fgetc(f);
}
} while (q_act > 0 && ch != EOF);

Construo de um analisador lxico e um sinttico

Implementao em C

// reconhecer o padro identificado entre os tokens da gramtica


switch (q_ant)
{
case 1 : TOK[*tam_TOK].COD = 0; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
// retirar o ltimo carcter do padro identificado
case 2 : TOK[*tam_TOK].COD = 0; st[tam_st-1] = '\0'; strcpy(TOK[*tam_TOK].VALOR, st);
(*tam_TOK)++; break;
case 3 : TOK[*tam_TOK].COD = 0; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 4 : TOK[*tam_TOK].COD = 1; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 5 : TOK[*tam_TOK].COD = 1; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 7 : TOK[*tam_TOK].COD = 1; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 8 : TOK[*tam_TOK].COD = 1; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 10 : TOK[*tam_TOK].COD = 1; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
// retirar o ltimo carcter do padro identificado
case 11 : TOK[*tam_TOK].COD = 1; st[tam_st-1] = '\0'; strcpy(TOK[*tam_TOK].VALOR, st);
(*tam_TOK)++; break;
case 12 : TOK[*tam_TOK].COD = 2; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 13 : TOK[*tam_TOK].COD = 3; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 14 : TOK[*tam_TOK].COD = 4; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 15 : TOK[*tam_TOK].COD = 5; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 9 : TOK[*tam_TOK].COD = 6; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
case 6 : TOK[*tam_TOK].COD = 7; strcpy(TOK[*tam_TOK].VALOR, st); (*tam_TOK)++; break;
} // While
if (ch == EOF)
break;
switch (q_act)
{
case 0 : ch = fgetc(f); break; // leu um separador : branco, tab ou new line
case -1 : break; // leu um carcter que inicial de um token (separador)
// leu um carcter invlido ou no inicial de um token (separador)
case -2 : printf("ERRO: caracter invalido ou fora do contexto!! -- %c\n", ch); ch = fgetc(f);
// leu carcter invlido ou no inicial de token (separador); retirar ultimo carcter do padro identificado

case -3 : printf("ERRO: caracter invalido ou fora do contexto. Retirar ultimo caracter do padrao!!\n ");
}
} // while
fclose(f);
return 1;
}
3

Construo de um analisador lxico e um sinttico

Implementao em C

int AnalisadorSintatico (TOKEN *TOK, int tam)


{
int Prod[11][3] = { {-1, -1, -1}, {11, 10, 10}, {11, 10, 10}, { 0, -1, -1}, { 1, -1, -1}, { 2, -1, -1},
{ 3, -1, -1}, { 4, -1, -1}, { 5, -1, -1}, { 6, -1, -1}, { 7, -1, -1} };
int Oraculo[12][9] = {

int

{ 0, -1, -1, -1, -1, -1, -1, -1, -1},

{-1, 0, -1, -1, -1, -1, -1, -1, -1},

{-1, -1, 0, -1, -1, -1, -1, -1, -1},

{-1, -1, -1, 0, -1, -1, -1, -1, -1},

{-1, -1, -1, -1, 0, -1, -1, -1, -1},

{-1, -1, -1, -1, -1, 0, -1, -1, -1},

{-1, -1, -1, -1, -1, -1, 0, -1, -1},

{-1, -1, -1, -1, -1, -1, -1, 0, -1},

{-1, -1, -1, -1, -1, -1, -1, -1, -2},

{-1, -1, 1, 1, 1, 1, 1, 1, -1},

{ 3, 4, 2, 2, 2, 2, 2, 2, -1},

{-1, -1, 5, 6, 7, 8, 9, 10, -1} };

Z[20], topo = 0, lookhead, k, accao, j;

TOK[tam].COD = 8;
TOK[tam].VALOR[0] = '$';
tam++;
printf("Topo(Z) -- lookhead -- accao \n");
Z[0] = 8;

// Push(Z, $)

Z[1] = 9;

// Push(Z, S)

topo = 1;
k = 0;
lookhead = TOK[k].COD;
do
{
accao = Oraculo[Z[topo]][lookhead];
printf(" %d

--

%d

-- %d \n", Z[topo], lookhead, accao);

switch (accao)
{
case -2 : break;

// Aceitacao

case -1 : break;

// ERRO

case 0 :

// Pop(Z)

topo--;

lookhead = TOK[++k].COD;

// Da_Simbolo

break;
default:
topo--;

// Pop(Z);

for (j = 2; j >= 0; j--)


if (Prod[accao][j] >= 0)
Z[++topo] = Prod[accao][j];

// Push(Z, Yi)

break;
}
} while (accao >= 0);
return accao;
}
4

Construo de um analisador lxico e um sinttico

Implementao em C

int main ()
{
int

k, tam_TOK;

TOKEN TOK[100];
if (AnalisadorLexico(TOK, &tam_TOK) != 1)
return(0);
printf("\n\nLISTA DE TOKEN (%d) : \n\n", tam_TOK);
for (k = 0; k < tam_TOK; k++)
{
switch (TOK[k].COD)
{
case 0 : printf("NUM -> "); break;
case 1 : printf(" ID -> "); break;
case 2 : printf(" +

-> "); break;

case 3 : printf(" -

-> "); break;

case 4 : printf(" *

-> "); break;

case 5 : printf(" /

-> "); break;

case 6 : printf("div -> "); break;


case 7 : printf("mod -> "); break;
}
printf("%s - %d\n", TOK[k].VALOR, TOK[k].COD);
}
printf("\n");
if (AnalisadorSintatico(TOK, tam_TOK) == -1)
printf("ERRO: Sequencia de tokens nao aceite.\n");
else
printf("Sequencia de tokens aceite.\n");
return 1;
} // main

Anda mungkin juga menyukai