You are on page 1of 29

Compiladores

Analizador Lxico

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Universidad Nacional Autnoma de


Mxico
Facultad de Ingeniera

Compiladores
Grupo 1

Analizador Lxico en ANSI C

ALUMNOS:
ARGUETA CORTES JAIRO I.
MENDOZA GAYTAN JOSE TRINIDAD

PROFESORA:
ING. LAURA SANDOVAL M.

Lunes 7 de Septiembre de 2009

Compiladores
Analizador Lxico

INDICE
Anlisis.. 2
Estudio preliminar..2
Planeacin.....3
Propuesta de servicios...3
Diseo.4
Expresiones regulares y autmata.4
Unin de autmatas...6
Autmata sin transiciones psilon...7
Tabla de transiciones..8
Desarrollo9
Definicin de tokens..9
Tcnicas de bsqueda e insercin.10
Implementacin.11
Ejecucin de programa lex.c.26
Explicacin....28

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Compiladores
Analizador Lxico

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Analizador lxico en ANSI C


Anlisis.
Estudio preliminar.
Objetivo: elaborar un analizador lxico en ANSI C que reconozca los componentes lxicos
pertenecientes a las clases debajo descritas.
Lista de requerimientos:
El programa deber solo utilizar instrucciones de ANSI C, independientemente de la
distribucin de C que se emplee para su elaboracin.
Las clases de los componentes lxicos validos para el analizador lxico son:
o Clase
Descripcin
o 0
constantes enteras (incluyendo octales y hexadecimales).
o 1
identificadores (segn lenguaje C).
o 2
operadores aritmticos (+,-,%,/).
o 3
operadores de asignacin (segn lenguaje C).
o El nmero de las clases es inamovible.
El analizador lxico tendr como entrada un archivo con las palabras que deber
reconocer. ste fungir como programa fuente.
Como delimitador de un componente lxico ser uno varios espacios, tabuladores o saltos
de lnea, as como el inicio de otro componente lxico.
Cuando detecte un error lxico, deber seguir el reconocimiento a partir del siguiente
smbolo valido.
El analizador deber crear la tabla de smbolos con2 campos: nombre y tipo.
Los tokens contendrn 2 campos.
o Campo1: la clase (entero de un byte).
o Campo2: el valor (de acuerdo a las sig. Tablas).
Operador de asig.
Operador valor
=
0
+=
1
-=
2
*=
3
/=
4
%=
5
|=
6
&=
7
>>=
8
<<=
9
^=
10

Operador arit.
Operador Valor
+
0
1
%
2
/
3

El valor para el token de cada identificador es la posicin dentro de la tabla de smbolos y de las
constantes enteras su valor numrico en base 10.

Compiladores
Analizador Lxico

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Como resultado, el analizador lxico deber mostrar el contenido tanto de la tabla de smbolos
como de los tokens.
Los errores que vaya encontrando el analizador lxico, los podr ir mostrando en pantalla o
escribirlos en un archivo.
El programa deber estar documentado.
Planeacin.
Se cuenta con un total de 11 das para la entrega del proyecto por lo que la organizacin quedara
de la siguiente manera:
El programa del analizador lxico se dividir en tres mdulos:
MOD I: creacin del autmata que nos definir los diferentes componentes lxicos.
MOD II: implementacin de la funcin para generar tokens.
MOD III; implementacin de la funcin para la creacin de la tabla de smbolos.
Distribucin de tiempos:
Tempo de anlisis y diseo. Tomando en cuenta los requerimientos y alcance del proyecto
se realizara en un total de 3 das.
Tiempo de desarrollo. Ser el tiempo restante antes de la entrega del proyecto en este
caso ser un total de 8 das naturales.
Asignacin de labores:
Tomando en cuenta el tiempo con el que se cuenta, as como los recurso y alcance del proyecto se
organizara de la siguiente manera:
Desarrollador1.- Argueta Cortes Jairo I. (D1)
Desarrollador2.- Mendoza Gaytn Jos T. (D2)
MOD I.- se realizara en un total de 2 das tomando en cuenta que el grado de dificultad es
bajo. Se realizara por D1 y D2
MOD II.- se asignaran 3 das para la realizacin de este modulo. Grado de dificulta de bajo
a medio. D1 y D2 MOD III.- se le asignara el tiempo restante de desarrollo en este caso un total de 3 das.
Grado de dificulta de medio a algo difcil. D1 y D2.
Propuesta de servicios.
La forma en la que se dar solucin a los requerimientos presentados ser la siguiente:
Se cuenta con un total de 11 das para la entrega del proyecto por lo que las actividades
relacionadas con el desarrollo del proyecto se tendrn que adecuar a este No. De das.
Objetivo.- Que la Ing. Laura Sandoval Montao obtenga el programa de Analizador lxico en
tiempo y forma establecidos por la misma, cumpliendo con todos y cada uno de los
requerimientos antes establecidos.
Entregables del proyecto.- se realizara la entrega de:
El anlisis, diseo y desarrollo as como la forma en la que el programa se puede implementar.

Compiladores
Analizador Lxico

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Se entregara adems el cdigo fuente del programa as como un archivo ejecutable del mismo,
esto se realizara de manera electrnica mediante el correo electrnico y de forma escrita
mediante un documento.
Diseo.
Para poder cumplir con los requerimientos especificados en el presente programa se tendr que
partir desde la creacin de las gramticas hasta la realizacin de un autmata para su posterior
programacin, veamos:
Expresiones regulares y autmatas.
Constantes enteras en C:
<entero> = <octa>|<hexa>|<deci>
<octal> = 0<digOn><digO>*
<hexa> = 0(x|X)<dighn><digh>*
<deci> = <dign><dig>*|0
<digOn> = 1||7
<digO> =0|<digOn>
<dign> =<digOn>|8|9
<dig> = 0|<dign>
<dighn> = <dign>|A|B|F|a|b|f
<digh> = 0|<dighn>
07
0
17

ii

0f

iii
X|x

19

1f

v
iv

09

vi

Compiladores
Analizador Lxico

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Identificadores segn C.
<let> = _|A|B||Z|a|b|z
<dig> = 0|1||9
<ident> = <let>(<let>|<dig>)*

II

AZ az

AZ az

09

Operadores aritmticos en C.
<opArit> = +|-|*|%|/

2
+|-|%|/

Operadores de asignacin segn C.


<signo> = +|-|*|/|%|&|||<<|>>|^
<igual> = =
<opAisg> = (<signo>| )<igual>

+-*/

%&^|
<

<

C
>
>

Compiladores
Analizador Lxico

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Unin de los autmatas.


07
0
17

ii

0f

iii
X|x

19

1f

vi

v
iv
09

II

AZ az

AZ az

JJ
09

2
+|-|%|/

=
+-*/

<

<

%&^|

C
>
>

Compiladores
Analizador Lxico

Autmata sin transiciones

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

07
0
17

ii

0f

iii
X|x

19

1f

vi

v
iv
19
09
AZ az

vii

viii

AZ az

AZ az

+|-|%|/|*
09
<
x

ix

=
+|-|%|/|*
=

xi

xii

&|^||
<

>

xiii

<
xiv
=

>
>
xv

&|^||

Compiladores
Analizador Lxico

Tablas de transiciones.

9
Mendoza Gaytn Jos Trinidad

Argueta Cortes Jairo I.

Compiladores
Analizador Lxico

10

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Desarrollo.
Definicin de la tabla de smbolos
Para trabajar con la tabla de smbolos la definimos de la siguiente manera:

Clase

TABLA DE SIMBOLOS
Nombre

Valor

Para lo cual trabajamos con una estructura en C. definida de la siguiente manera


typedef struct sim {
int ClaseS;
//Clase del Smbolo
int valorS;
//Valor del smbolo
char simbolo[20]; //Smbolo
struct sim *siguiente; //Puntero al siguiente smbolo
} tablaSimbolos;
Esta estructura nos permitir trabajar con listas ligadas, es por eso que trabajamos con
struct sim *siguiente que es un apuntador al siguiente elemento.
Este tipo de utilizacin de estructuras de datos nos permitir optimizar memoria, ya que
podramos haber utilizado una matriz multidimensional de un tamao fijo, lo que sera difcil de
modificar en su tamao aunque simplificara mas el cdigo.
Definicin de Tokens
Cada TOKEN tiene dos campos definidos de la siguiente manera (Clase, Valor)
CLASE 0
Corresponde a constantes enteras incluyendo Octales y Decimales y su valor corresponde a su
equivalente en base 10
CLASE 1
Corresponde a Identificadores y su valor corresponde a su posicin en la tabla de smbolos.
El valor de cada operador lo definimos en C de la siguiente manera
CLASE 2
//Estructura para definir Operadores arieticos {Operador, valor}
struct opAritmetico {
char operador[1]; //Operador
int valor;
//Valor
} operadorArit[4] = {{"+", 0},{"-", 1},{"%", 2},{"/", 3}};
CLASE 3

Compiladores
Analizador Lxico

11

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

//Estructura para definir Operadores de asignacin {operador,


valor}
struct opAsignacion {
char operador[3]; //Operdor
int valor;
//Valor
} operadorAsig[11] = {{"=", 0},{"+=", 1},{"-=", 2},{"*=", 3},
{"/=", 4},{"%=", 5},{"|=", 6},{"&=", 7},
{">>=", 8},{"<<=", 9},{"^=", 10}};
Tcnicas de bsqueda e insercin
La tcnica de bsqueda es lineal para nuestras listas ligadas que viene siendo la tabla de smbolos
por lo tanto cuando el autmata reconoce un Identificador, primero lo busca en la tabla de
smbolos y si este se encuentra toma el valor correspondiente en la tabla se smbolos y genera en
Token.
En caso de que el smbolo no se encuentre en la tabla, lo inserta y le asigna un valor para poder
generar el Token correspondiente.
El algoritmo est definido en C de la siguiente manera:
void buscaSimbolo(int ClaseB, char *CadenaB) {
//aux apunta al inicio de la tabla de simbolos
aux = inicioTabla;
//Bandera que indica si encontro el simbolo
int encontro = 0;
//Inicializacion de la tabla por primera vez
if(ContadorS==0)
{
insertaSimbolo(ClaseB, CadenaB);
aux = inicioTabla;
printf("( %d , %d )\n", aux->ClaseS, aux->valorS);
encontro=1;
}
//Loop que busca un simbolo en la tabla
while (encontro==0)
{
//Si encuentra el simbolo en la tabla
//imprime clase y valor correspondiente
if(strcmp(aux->simbolo,CadenaB)==0)
{
printf("( %d , %d )\n", aux->ClaseS, aux->valorS);
encontro=1;
}
//Apunta al siguiente elemento de la tabla
else
aux = aux->siguiente;
//Si no encuetra el simbolo lo inserta en la tabla
if(aux==NULL)
{

Compiladores
Analizador Lxico

12

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

insertaSimbolo(ClaseB, CadenaB);
aux = inicioTabla;
printf("( %d , %d )\n", aux->ClaseS, aux->valorS);
encontro=1;
}
}

Implementacin
Cdigo fuente
1 /*
2 * File:
lex.c
3 * Descripcion:
4
Este es una analizador LEXico escrito en ANSIC
5
que reconoce los componentes lexicos
6
perteneciente a las clases descritas en el documento
7
de especificaciones.
8
9 * Autores: Argueta Cortes Jairo I
10 *
Mendoza Gaytan Jose T.
11 *
12 * Fecha de Creacion:29/Ago/2009-4/Sep/2009
13
14 * Como utilizar lex.c
15
Desde una Terminal de Linux tecleamos:
16
1) gcc lex.c -o gcc
17
2) ./lex "[nombreArchivo]".txt
18
19 */
20
21 //Librerias a utilizar
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 //Declaracion de variables Globales
27 char car;
//Var. para almacenar caracter de archivo
28 char caracter[1]; //Var. auxiliar de caracter "car"
29 char Cadena[20];
//Var. para concatenar caracteres leidos
30 char Estado = 'A'; //Var. de estados
31 int EdoAcep = 0;
//Var. de Estadode Acep./Rec.
32 int Clase;
//Var. del tipo de clase
33 FILE *codfuente;
//Apuntador a nombre de archivo
34
35
36 //Estructura para definir Operadores arimeticos
{operador,valor}
37 struct opAritmetico {
38
char operador[1]; //Operador

Compiladores
Analizador Lxico

13

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

39
int valor;
//Valor
40 } operadorArit[4] = {{"+", 0},{"-", 1},{"%", 2},{"/", 3}};
41
42 //Estructura para definir Operadores de asignacion
{operador,valor}
43 struct opAsignacion {
44
char operador[3]; //Operdor
45
int valor;
//Valor
46 } operadorAsig[11] = {{"=", 0},{"+=", 1},{"-=", 2},{"*=", 3},
47
{"/=", 4},{"%=", 5},{"|=", 6},{"&=", 7},
48
{">>=", 8},{"<<=", 9},{"^=", 10}};
49
50 //Definicion de Tabla de simbolos
51 //Estructura para trabajar con Listas Ligadas
52 typedef struct sim {
53
int ClaseS;
//Clase del Simbolo
54
int valorS;
//Valor del simbolo
55
char simbolo[20]; //Simbolo
56
struct sim *siguiente; //Puntero al siguiente simbolo
57 } tablaSimbolos;
58
59 //Inicializacion de punteros a la tabla de Simbolos
60 tablaSimbolos *inicioTabla = NULL, *aux = NULL;
61
62 //Inicializacion del contador de simbolos en la tabla
63 int ContadorS = 0;
64
65 //Declaracion de funciones para trabajar
66 //con el automata
67
68 void automata(char);
69 void error();
70 void generaToken(int, char[]);
71 void limpiaCadena();
72
73 //Declaracion de funciones para trabajar
74 //Con la tabla de simbolos
75 tablaSimbolos *nuevoSimbolo();
76 void insertaSimbolo(int, char*);
77 void buscaSimbolo(int, char*);
78 void errorSim();
79 void imprimeTablaSimbolos();
80
81 //Metodo Main()
82 int main(int argc, char * argv[]) {
83
84
//Apertura del codigo fuente
85
codfuente = fopen(argv[1], "r");
86
87
//Verificador de apertura de archivo
88
if (codfuente == NULL) {
89
printf("Error: el fichero no puede abrirse! \n");

Compiladores
Analizador Lxico

14

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

90
printf("Velva a intentarlo \n");
91
}
92
93
//Ignorar primeros Espacios en blanco y saltos de linea
94
car = fgetc(codfuente);
95
while (car == ' ' || car == '\n') {
96
car = fgetc(codfuente);
97
}
98
printf("\nLISTA DE TOKENS \n\n");
99
//Mientras no se encuentre EOF del archivo
100
while (!feof(codfuente)) {
101
102
//Reinicializacion de Estado de Aceptacion/Rechazo.
103
if (EdoAcep == 1 && car != ' ') {
104
EdoAcep = 0;
105
}
106
107
//Ignorar Espacios en blanco y saltos de linea del
codigo fuente
108
while ((car == ' ' && EdoAcep == 1) || (car == '\n' &&
EdoAcep == 0 && Estado == 'A') || (car == ' ' && Estado == 'A')) {
109
car = fgetc(codfuente);
110
EdoAcep = 0;
111
}
112
113
//Llamada a la funcion automata
114
automata(car);
115
116
//Lectura del siguiente caracter dependiendo de su
contexto
117
if (car != ' ' && EdoAcep != 1)
118
car = fgetc(codfuente);
119
120
}
121
122
//Impresion de tabla de simbolos
123
imprimeTablaSimbolos();
124
125
//Cierre de archivo leido
126
fclose(codfuente);
127
128
return 0;
129 }
130
131 //Funcion de error, indica cuando un elemento
132 //no es reconocido por el automata
133 void error() {
134
//Mientras no se encuntre EOF
135
if(!feof(codfuente))
136
{
137
printf("%c", car);

Compiladores
Analizador Lxico

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

15

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

printf(" Error: elemento no reconocido!\n");


Estado = 'A'; //Inicializa Estado
EdoAcep = 0; //Pone en estado de no Aceptacion
limpiaCadena(); //borra el caracter leido
}
}
//Funcion limpiaCadena
void limpiaCadena() {
//Limpia cadena
int i;
for (i = 0; i <= 19; i++)
Cadena[i] =NULL;
}
//Funcion automata():
//Reconoce las cadenas definidas por
//las expresiones regulares.
void automata(char car) {
//Copia el caracter leido a caracter[0]
caracter[0] = car;
//Evalua estado actual
switch (Estado) {
case 'A':
//Evalua caracter leido
switch (car) {
case '<':
Estado = 'B';
//Concatena cadena: Cadena=Cadena+caracter
strcat(Cadena, caracter);
break;
case '>':
Estado = 'C';
strcat(Cadena, caracter);
break;
case '^':
case '|':
case '&':
Estado = 'D';
strcat(Cadena, caracter);
break;
case '=':
Estado = 'E';
strcat(Cadena, caracter);
break;

Compiladores
Analizador Lxico

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

16

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

case '+':
case '-':
case '*':
case '/':
case '%':
Estado = 'F';
strcat(Cadena, caracter);
break;
case '0':
Estado = 'G';
strcat(Cadena, caracter);
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
Estado = 'H';
strcat(Cadena, caracter);
break;
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case

'_':
'a':
'b':
'c':
'd':
'e':
'f':
'g':
'h':
'i':
'j':
'k':
'l':
'm':
'n':
'o':
'p':
'q':
'r':
's':
't':
'u':
'v':
'w':
'x':

Compiladores
Analizador Lxico

17

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

242
case 'y':
243
case 'z':
244
case 'A':
245
case 'B':
246
case 'C':
247
case 'D':
248
case 'E':
249
case 'F':
250
case 'G':
251
case 'H':
252
case 'I':
253
case 'J':
254
case 'K':
255
case 'L':
256
case 'M':
257
case 'N':
258
case 'O':
259
case 'P':
260
case 'Q':
261
case 'R':
262
case 'S':
263
case 'T':
264
case 'U':
265
case 'V':
266
case 'W':
267
case 'X':
268
case 'Y':
269
case 'Z':
270
Estado = 'I';
271
strcat(Cadena, caracter);
272
break;
273
274
default:
275
error(); //Estado de no aceptacion o
cadena no valida
276
break;
277
}
278
break;
279
case 'B':
280
switch (car) {
281
case '<':
282
Estado = 'D';
283
//Concatena cadena: Cadena=Cadena+caracter
284
strcat(Cadena, caracter);
285
break;
286
287
default:
288
error();
289
break;
290
}
291
break;
292
case 'C':

Compiladores
Analizador Lxico

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

18

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

switch (car) {
case'>':
Estado = 'D';
//Concatena cadena: Cadena=Cadena+caracter
strcat(Cadena, caracter);
break;
default:
error();
break;
}
break;
case 'D':
switch (car) {
case'=':
Estado = 'E';
//Concatena cadena: Cadena=Cadena+caracter
strcat(Cadena, caracter);
break;
default:
error();
break;
}
break;
case 'E':
Clase = 3;
//Operador de Asignacion
Estado = 'A';
EdoAcep = 1;
generaToken(Clase, Cadena);
limpiaCadena();
break;
case 'F':
switch (car) {
case'=':
Estado = 'E';
//Concatena cadena: Cadena=Cadena+caracter
strcat(Cadena, caracter);
break;
default:
Clase = 2; //Operador Aritmetico
Estado = 'A';
EdoAcep = 1;
generaToken(Clase, Cadena);
limpiaCadena();
break;
}
break;
case 'G':
switch (car) {
case'1':

Compiladores
Analizador Lxico

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396

19

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
Estado = 'J';
//Concatena cadena: Cadena=Cadena+caracter
strcat(Cadena, caracter);
break;
case'x':
case'X':
Estado = 'K';
strcat(Cadena, caracter);
break;
default:
Clase = 0; //Constante entera
Estado = 'A';
EdoAcep = 1;
generaToken(Clase, Cadena);
limpiaCadena();
break;
}
break;
case 'H':
switch (car) {
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
Estado = 'H';
//Concatena cadena: Cadena=Cadena+caracter
strcat(Cadena, caracter);
break;
default:
Clase = 0; //Constante entera
Estado = 'A';
EdoAcep = 1;
generaToken(Clase, Cadena);
limpiaCadena();
break;
}
break;
case 'I':
switch (car) {

Compiladores
Analizador Lxico

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

20

case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case

'0':
'1':
'2':
'3':
'4':
'5':
'6':
'7':
'8':
'9':
'_':
'a':
'b':
'c':
'd':
'e':
'f':
'g':
'h':
'i':
'j':
'k':
'l':
'm':
'n':
'o':
'p':
'q':
'r':
's':
't':
'u':
'v':
'w':
'x':
'y':
'z':
'A':
'B':
'C':
'D':
'E':
'F':
'G':
'H':
'I':
'J':
'K':
'L':
'M':
'N':
'O':

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Compiladores
Analizador Lxico

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

21

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
Estado = 'I';
strcat(Cadena, caracter);
break;
default:
Clase = 1; //Identificador
Estado = 'A';
EdoAcep = 1;
generaToken(Clase, Cadena);
limpiaCadena();
break;
}
break;
case 'J':
switch (car) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
Estado = 'J';
strcat(Cadena, caracter);
break;
default:
Clase = 0; //Constante entera
Estado = 'A';
EdoAcep = 1;
generaToken(Clase, Cadena);
limpiaCadena();
break;
}
break;
case 'K':
switch (car) {
case '1':
case '2':
case '3':
case '4':
case '5':

Compiladores
Analizador Lxico

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552

22

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
Estado = 'L';
//Concatena cadena: Cadena=Cadena+caracter
strcat(Cadena, caracter);
break;
default:
error();
break;
}
break;
case 'L':
switch (car) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
Estado = 'L';
strcat(Cadena, caracter);
break;

Compiladores
Analizador Lxico

23

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

553
default:
554
Clase = 0; //Constante entera
555
Estado = 'A';
556
EdoAcep = 1;
557
generaToken(Clase, Cadena);
558
limpiaCadena();
559
break;
560
}
561
break;
562
default:
563
error();
564
break;
565
}
566 }
567
568 //Funcion generaToken():
569 //Recibe como parametro el valor de la Clase
570 //y la cadena a evaluar.
571 void generaToken(int Clase, char Cadena[]) {
572
//Copia cadena
573
char *CadenaT = Cadena;
574
int ClaseT = Clase;
575
576
//Apuntador para la funcion strtol(Cadena,Apuntador,base)
577
//Permite convertir una cadena a un numero emtero
578
char *end;
579
580
581
//Evalua si es Constate Entera y calcula
582
//su valor numerico en base 10
583
if (ClaseT == 0){
584
//Convierte a numeros decimales
585
if(CadenaT[0]!='0'){
586
printf("( %d , %d )\n", ClaseT, atoi(CadenaT));
587
}
588
//Convierte a nueros Hexadecimales
589
else if(CadenaT[1]=='x' || CadenaT[1]=='X'){
590
printf("( %d , %ld )\n", ClaseT,
strtol(CadenaT,&end,16));
591
}
592
//Convierte a numeros Octales
593
else {
594
printf("( %d , %ld )\n", ClaseT,
strtol(CadenaT,&end,8));
595
}
596
}
597
//Evalua si es Identificador
598
else if(ClaseT==1) {
599
600
//Busca simbolo en la tabla
601
buscaSimbolo(ClaseT, CadenaT);

Compiladores
Analizador Lxico

24

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

602
603
}
604
//Evalua si es Operador Aritmetico
605
else if (ClaseT == 2) {
606
int valor;
607
608
//Busca en la estructura "opAritetico" el valor
609
//del operador leido
610
for (valor = 0; valor <= 3; valor++) {
611
//Compara operadores
612
if (strcmp(CadenaT, operadorArit[valor].operador)
== 0) {
613
printf("( %d , %d )\n", ClaseT, valor);
614
}
615
}
616
}
617
//Evalua si es Operador de asignacion
618
else if (ClaseT == 3) {
619
int valor;
620
//Busca en la estructura "opAsignacion" el valor
621
//del operador leido
622
for (valor = 0; valor <= 10; valor++) {
623
//Compara operadores
624
if (strcmp(CadenaT, operadorAsig[valor].operador)
== 0) {
625
printf("( %d , %d )\n", ClaseT, valor);
626
}
627
}
628
}
629 }
630
631 //Funciones para manejar TABLA de Simbolos
632
633 //Funcion que crea un nuevo simbolo
634 //Devuelve un apuntador de tipo tablasimbolos
635 tablaSimbolos *nuevoSimbolo() {
636
637
//Asigna espacio en memoria para nuevos simbolos
638
tablaSimbolos *nuevo = (tablaSimbolos *) malloc(sizeof
(tablaSimbolos));
639
640
//En caso de memoria insuficiente
641
if (!nuevo)
642
errorSim();
643
return nuevo;
644 }
645
646 //Funcion que indica memoria insuficiente
647 void errorSim() {
648
printf("Insuficiente memoria\n");
649
exit(1);

Compiladores
Analizador Lxico

650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701

25

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

}
//Funcion que inserta un nuevo simbolo en la tabla
void insertaSimbolo(int nClase, char *nCadena) {
//Define una variable del tipo tablaSimbolos
tablaSimbolos *nuevoSim = nuevoSimbolo();
//Asigna valores
nuevoSim->ClaseS = nClase;
nuevoSim->valorS = ContadorS;
strcpy(nuevoSim->simbolo, nCadena);
//nuevoSimbolo Apunta al siguiente elemento
nuevoSim->siguiente = inicioTabla;
//inicioTabla apunta al comienzo de la tabla
inicioTabla = nuevoSim;
//Incrementa contador de elementos en la tabla
ContadorS = ContadorS + 1;
}
//Funcion que busca un simbolo en la tabla.
//Recibe como parametros en valor de la clase
//y el simbolo a buscar
//Si no encuentra el simbolo, lo inserta.
//Caso contrario imprime su valor almacenado
//en la tabla.
void buscaSimbolo(int ClaseB, char *CadenaB) {
//aux apunta al inicio de la tabla de simbolos
aux = inicioTabla;
//Bandera que indica si encontro el simbolo
int encontro = 0;
//Inicializacion de la tabla por primera vez
if(ContadorS==0)
{
insertaSimbolo(ClaseB, CadenaB);
aux = inicioTabla;
printf("( %d , %d )\n", aux->ClaseS, aux->valorS);
encontro=1;
}
//Loop que busca un simbolo en la tabla
while (encontro==0)
{
//Si encuentra el simbolo en la tabla
//imprime clase y valor correspondiente

Compiladores
Analizador Lxico

26

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

702
if(strcmp(aux->simbolo,CadenaB)==0)
703
{
704
printf("( %d , %d )\n", aux->ClaseS, aux->valorS);
705
encontro=1;
706
}
707
//Apunta al siguiente elemento de la tabla
708
else
709
aux = aux->siguiente;
710
//Si no encuetra el simbolo lo inserta en la tabla
711
if(aux==NULL)
712
{
713
insertaSimbolo(ClaseB, CadenaB);
714
aux = inicioTabla;
715
printf("( %d , %d )\n", aux->ClaseS, aux->valorS);
716
encontro=1;
717
}
718
}
719 }
720
721 //Funcion que imprime la tabla se simbolos
722 void imprimeTablaSimbolos() {
723
724
//Define un apuntador de tipo tablaSimbolo
725
tablaSimbolos *aux = NULL;
726
727
//aux apunta al inicio de la tabla de simbolos
728
aux = inicioTabla;
729
730
printf("\n
TABLA DE SIMBOLOS");
731
printf("\n--------------------------");
732
printf("\n| Clase | Nombre | Valor |\n");
733
printf("--------------------------");
734
735
//Mientras aux no apunte al final de la tabla
736
while (aux != NULL) {
737
printf("\n|
%d \t %s\t\t%d|", aux->ClaseS, aux->simbolo,
aux->valorS);
738
739
//aux apunta al siguiente simbolo
740
aux = aux->siguiente;
741
}
742
743
printf("\n--------------------------\n\n");
744
745
746 }
747

Compiladores
Analizador Lxico

27

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Ejecucin de Programa lex.c


En una terminal de Linux teclear lo siguiente:
boxer@boxer-desktop:~/Escritorio$gcc lex.c o lex
boxer@boxer-desktop:~/Escritorio$./lex [nombreArchivo].txt

En [nombreArchivo] se sustituye por el nombre del archivo fuente, para nuestro caso de ejemplo
utilizamos fuente.txt
El archivo fuente.txt contiene el siguiente texto:

suma *=resul

int x1%x2

amigo@yahoo.com

suma suma
Al teclear en consola:
2009
011
boxer@boxer-desktop:~/Escritorio$gcc lex.c o lex
0xf
boxer@boxer-desktop:~/Escritorio$./lex fuente.txt
0XF

Compiladores
Analizador Lxico

28

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Observamos lo siguiente:

Analizando los resultados primero observamos una lista de TOKENS generados por el analizador
LEXico, y por ultimo observamos la tabla de smbolos generada por el analizador:

Compiladores
Analizador Lxico

29

Argueta Cortes Jairo I.


Mendoza Gaytn Jos Trinidad

Explicacin.
LISTA DE TOKENS
( 1 , 0 ) // suma Identificador Clase=1; Valor en la tabla de smbolos=0
( 3 , 3 ) // *=
Op. Asignacin Clase=3; Valor =3
( 1 , 1 ) // resul Identificador Clase=1; Valor en la tabla de smbolos=1
( 1 , 2 ) // int Identificador Clase=1; Valor en la tabla de smbolos=2
( 1 , 3 ) // x1
Identificador Clase=1; Valor en la tabla de smbolos=3
( 2 , 2 ) // %
Op. aritmtico Clase=2; Valor =2
( 1 , 4 ) // x2
Identificador Clase=1; Valor en la tabla de smbolos=4
( 1 , 5 ) // amigo Identificador Clase=1; Valor en la tabla de smbolos=5
@ Error: elemento no reconocido!
( 1 , 6 ) // yahoo Identificador Clase=1; Valor en la tabla de smbolos=6
. Error: elemento no reconocido!
( 1 , 7 ) // com Identificador Clase=1; Valor en la tabla de smbolos=7
( 1 , 0 ) // suma Identificador Clase=1; Valor en la tabla de smbolos=0
( 1 , 0 ) // suma Identificador Clase=1; Valor en la tabla de smbolos=0
( 0 , 2009 ) // 2009 Cte. Entera Clase=0; Valor en base10=2009
( 0 , 9 ) // 011 Cte. Entera Clase=0; Valor en base10=11
( 0 , 15 ) // 0xf Cte. Entera Clase=0; Valor en base10=15
( 0 , 15 ) // 0XF Cte. Entera Clase=0; Valor en base10=15
TABLA DE SIMBOLOS
-------------------------| Clase | Nombre | Valor |
-------------------------| 1
com
7|
| 1
yahoo
6|
| 1
amigo
5|
| 1
x2
4|
| 1
x1
3|
| 1
int
2|
| 1
resul
1|
| 1
suma
0|
--------------------------

boxer@boxer-desktop:~/Escritorio$

You might also like