Sei sulla pagina 1di 15

1:

2: /* UESPI / Cincia da Computao


3: * Projeto e Teoria de Linguagens I
4: * Prof. Mrcio Igo
5: *
6: * Arquivo fonte libAnalex.h
7: *
8: * Conjunto de funes que implementam o "back-end" do analisador lxico, em es
9: * pecial o AFD reconhecedor da linguagem especificada.
10: *
11: * ++++ Dependncia: Existe a necessidade de um TAD para montagem da tabela de
12: * smbolos.
13: *
14: * (C) 2011 | Gnesis Ribeiro Leite, Cristiano Neri
15: *
16: */
17:
18: /* Bibliotecas importadas */
19: #include <ctype.h>
20: #include <stdio.h>
21: #include "libTAD.h"
22:
23: /* CONSTANTES */
24: #define RESWORDSIZE 25
25: #define LINESIZE 200
26: #define SINGLEQUOTES 39
27: #define DOUBLEQUOTES 34
28:
29: /*******************************************************************************
30: NOME: verLastLine()
31:
32: DESCRIO
33: Verifica se a ltima linha do cdigo-fonte foi deixada em branco.
34:
35: PARMETROS
36: FILE *sc : Ponteiro para o cdigo-fonte.
37:
38: RETORNO
39: Retorna 0, caso a ltima linha esteja em branco, ou 1 em caso contrrio.
40: ********************************************************************************
41: int verLastLine ( FILE *sc )
42: {
43: char line[ LINESIZE ]; /* Para armazenar o buffer das linhas */
44:
45: /* Percorre o cdigo-fonte at o fim, copiando cada linha */
46: while (!feof(sc)) // Enquanto o no chegar ao fim do arquivo -> True
47: fgets( line, ( LINESIZE -2 ), sc );
48:
49: /* Rebobinando o cdigo-fonte */
50: rewind( sc );
51:
52: /* Verifica se a ltima linha est em branco */
53: if ( strlen( line ) <= 1 ) return 0; //Se o comprimento da linha for menor ou igual
54: //a 1(espao) -> considera vazia.
55: else return 1;
56: } /* verLastLine */
57:
58: /*******************************************************************************
59: NOME: cleanItem()
60:
61: DESCRIO
62: Limpa um item, colocando seus valores padres.
63:
64: PARMETROS
65: Item *item : Ponteiro para o item a ser limpo.
66:
67: RETORNO
68: Retorna o item limpo em *item.
69: ********************************************************************************
70: void cleanItem ( Item *item )
71: {
72: strcpy( item -> token, "\0" );
73: strcpy( item -> class, "\0" );
74:
75: item -> value = 0;
76:
77: item -> coOrdinate.line = 0;
78: item -> coOrdinate.column = 0;
79: } /* cleanItem */
80:
81: /*******************************************************************************
82: NOME: action1()
83:
84: DESCRIO
85: Realiza uma seqncia de aes a serem tomadas, que se repetem no autmato.
86:
87: PARMETROS
88: Queue *queue : A tabela onde o item ser inserido.
89: Item *item : O item auxiliar utilizado pelo analisador lxico.
90: char *tkn : O valor para o nome do token.
91: char *cls : O valor para a classe do token.
92: long val : O valor do item.
93: unsigned short int y : A linha do token no cdigo-fonte.
94: unsigned char x : A coluna do token no cdigo-fonte.
95: char *sta : Para alterar o estado do autmato para o primeiro.
96:
97: RETORNO
98: -
99: ********************************************************************************
100: void action1 ( Queue *queue, Item *item, char *tkn, char *cls, long val,
101: unsigned short int y, unsigned char x, char *sta )
102: {
103: strcpy( item -> token, tkn ); /* Ajustando o nome e a classe do token */
104: strcpy( item -> class, cls );
105:
106: item -> value = val; /* Ajustando o valor */
107:
108: item -> coOrdinate.line = y; /* Ajustando as coordenadas no codigo-fonte */
109: item -> coOrdinate.column = x;
110:
111: /* Gravando o token na tabela*/
112: enqueue( queue, item );
113:
114: /* Limpando o item... */
115: cleanItem( item );
116:
117: /* Voltando ao estado 1 do automato */
118: *sta = 1;
119: } /* action1 */
120:
121: /*******************************************************************************
122: NOME: concat()
123:
124: DESCRIO
125: Concatena um caractere no final de uma String.
126:
127: PARMETROS
128: char *str : Um ponteiro para a String.
129: char ch : O caractere a ser concatenado.
130:
131: RETORNO
132: ch concatenado na ltima posio da String apontada por *str.
133: ********************************************************************************
134: void concat ( char *str, char ch ) {
135: register int i = strlen( str ); /* Armazena o tamanho atual da String */
136:
137: *( str + i ) = ch; /* Adicionando o caractere no fim da String */
138: *( str + ( i + 1 ) ) = '\0'; /* Marcando o novo final da String */
139: } /* concat */
140:
141: /*******************************************************************************
142: NOME: isHex()
143:
144: DESCRIO
145: Verifica se um caractere vlido para a notao hexadecimal [0..9] ou [a..F]
146:
147: PARMETROS
148: char c : O caracter a ser avaliado.
149:
150: RETORNO
151: Retorna 1 em caso positivo ou 0 em caso negativo.
152: ********************************************************************************
153: char isHex ( char c )
154: {
155: return ( ( isdigit( c ) ) || ( c == 'a') || ( c == 'A') || ( c == 'b') ||
156: ( c == 'B') || ( c == 'c') || ( c == 'C') || ( c == 'd') || ( c == 'D') ||
157: ( c == 'e') || ( c == 'E') || ( c == 'f') || ( c == 'F') );
158: } /* isHex */
159:
160: /*******************************************************************************
161: NOME: isLetter()
162:
163: DESCRIO
164: Verifica se um caractere uma letra ou underscore '_'.
165:
166: PARMETROS
167: char c : O caracter a ser avaliado.
168:
169: RETORNO
170: Retorna 1 em caso positivo ou 0 em caso negativo.
171: ********************************************************************************
172: char isLetter ( char c )
173: {
174: return ( ( isalpha( c ) ) || ( c == '_' ) );
175: } /* isLetter */
176:
177: /*******************************************************************************
178: NOME: toLowerCase()
179:
180: DESCRIO
181: Converte todos os caracteres de uma String para letras minsculas.
182:
183: PARMETROS
184: const char *str1 : Um ponteiro para a String de origem.
185: char *str2 : Um ponteiro para a String de destino.
186:
187: RETORNO
188: *str2 tem seu valor alterado para a representao em letras minsculas de str
189: ********************************************************************************
190: void toLowerCase ( const char *str1, char *str2 )
191: {
192: register int i = 0; /* Para varrer *str1 */
193:
194: *( str2 + 0 ) = '\0'; /* Limpando *str2 */
195:
196: /* Varrendo *str1 e criando *str2 */
197: for (; i < strlen( str1 ); i++ )
198: *( str2 + i ) = tolower( *( str1 + i ) );
199:
200: *( str2 + i ) = '\0'; /* Adicionando o caractere nulo no final de *str2 */
201: } /* toLowerCase */
202:
203: /*******************************************************************************
204: NOME: isInQueue()
205:
206: DESCRIO
207: Verifica se um token est na fila.
208:
209: PARMETROS
210: Queue *queue : O ponteiro para a fila.
211: char *tkn : O ponteiro para o token a ser analisado.
212:
213: RETORNO
214: Retorna -1 caso no haja ocorrncia de *tkn em *queue, ou o valor de *tkn na
215: fila em caso contrrio.
216: ********************************************************************************
217: long isInQueue ( Queue *queue, char *tkn )
218: {
219: /* Para armazenar os tokens em minusculo - Para grarantir que NAO eh sen-
220: sivel ao caso. */
221: char strAux1[ ITEMTOKENSIZE ], strAux2[ ITEMTOKENSIZE ];
222:
223: toLowerCase( tkn, strAux2 ); /* Convertendo o token passado para minusculo */
224:
225: /* Verificando se a fila estah vazia */
226: if ( ! queueEmpty( queue ) ){
227: /* Ponteiro para varrer a fila */
228: Pointer aux = queue -> front -> next;
229:
230: /* Roda enquanto nao atingir o fim da fila ou nao encontrar o token */
231: while ( aux != NULL ) {
232: /* Convertendo o token da posicao para minusculo */
233: toLowerCase( aux -> item.token, strAux1 );
234:
235: /* Verificando se o token jah foi gravado. Caso tenha sido, retorna-
236: se o seu valor. */
237: if ( ! strcmp( strAux1, strAux2 ) )
238: return ( aux -> item.value ); /* Retornando o valor do token */
239:
240: aux = aux -> next; /* Incrementando o ponteiro */
241: } /* while */
242:
243: return -1; /* Item nao encontrado */
244: }
245: else
246: /* Fila vazia */
247: return -1;
248: } /* isInQueue */
249:
250: /*******************************************************************************
251: NOME: getTokenClass()
252:
253: DESCRIO
254: Obtm a classe de um determinado token, a partir de seu nmero de identifica
255: o.
256:
257: PARMETROS
258: int index : O nmero de identificao do token.
259: char *class : A classe que ser retornada.
260:
261: RETORNO
262: Retorna a classe do token *class - de extrema que index corresponda SEMPRE a
263: uma posio vlida.
264: ********************************************************************************
265: void getTokenClass ( int index, char *class )
266: {
267: /* Matriz que guarda a lista com o nome de cada classe */
268: /* OBS.: Ao ser adicionado ou exluido algum item, deve-se atualizar o
269: primeiro indice da matriz. */
270: char TOKENCLASSES[][ ITEMCLASSSIZE ] = {
271: /*00*/"comando de classe geral",
272: /*01*/"comando de desvio de fluxo de execuo",
273: /*02*/"comando de iterao",
274: /*03*/"comando de manipulao de objetos",
275: /*04*/"comando de manipulao de registros",
276: /*05*/"comando de seleo",
277: /*06*/"comando relativo unidades",
278: /*07*/"constante numrica",
279: /*08*/"declarao de variveis",
280: /*09*/"delimitador",
281: /*10*/"delimitador de bloco de comandos",
282: /*11*/"delimitador de comando",
283: /*12*/"delimitador de comentrios",
284: /*13*/"delimitador de parmetros",
285: /*14*/"id",
286: /*15*/"identificador de anulao de operador",
287: /*16*/"identificador de caractere ASCII",
288: /*17*/"identificador de nmero hexadecimal",
289: /*18*/"indicador de faixa de valores",
290: /*19*/"manipulao de ponteiros",
291: /*20*/"operador aritmtico",
292: /*21*/"operador de atribuio",
293: /*22*/"operador booleano",
294: /*23*/"operador lgico",
295: /*24*/"operador relacional",
296: /*25*/"programao de baixo nvel",
297:
298: /*26*/"caractere invlido",
299: /*27*/"identificador invlido"
300: };
301:
302: /* Copia a classe do token para a variavel de retorno */
303: strcpy( class, *( TOKENCLASSES + index ) );
304: } /* getTokenClass */
305:
306: /*******************************************************************************
307: NOME: isResWord()
308:
309: DESCRIO
310: Verifica se um token , ou no, uma palavra reservada da linguagem.
311:
312: PARMETROS
313: const char *token : Ponteiro para o token a ser avaliado.
314: char *cToken : Caso seja uma palavra reservada, retorna a classe. Caso contr
315: rio, retorna uma string nula.
316:
317: RETORNO
318: Retorna 1 se o token for uma palavra reservada ou 0 em caso contrario.
319: ********************************************************************************
320: char isResWord ( const char *token, char *cToken ) {
321: /* Matriz que guarda a lista de palavras reservadas */
322: char RESERVEDWORDS[][ RESWORDSIZE ] = {
323: /* Delimitadores de bloco de comandos [ 0-1 ] */
324: "begin","end",
325:
326: /* Declaracao de variaveis [ 2-18 ] */
327: "var","string","function","procedure","const","type","array","record",
328: "set","file","uses","program","unit","label","packed","library",
329: "exports",
330:
331: /* Comandos de iteracao [ 19-24 ] */
332: "for","to","downto","repeat","until","while",
333:
334: /* Comandos de selecao [ 25-28 ] */
335: "if","then","else","case",
336:
337: /* Operadores booleanos [ 29-32 ] */
338: "not","and","or","xor",
339:
340: /* Operadores aritmeticos [ 33-34 ] */
341: "mod","div",
342:
343: /* Operador relacional [ 35 ] */
344: "in",
345:
346: /* Operadores logicos [ 36-37 ] */
347: "shl","shr",
348:
349: /* Manipulacao de ponteiros [ 38 ] */
350: "nil",
351:
352: /* Comandos de classes diversas [ 39-40 ] */
353: "of","do",
354:
355: /* Comandos usados em unidades [ 41-42 ] */
356: "implementation","interface",
357:
358: /* Comando de manipulacao de registros [ 43 ] */
359: "with",
360:
361: /* Comando de desvio de fluxo execucao [ 44 ] */
362: "goto",
363:
364: /* Comandos de manipulacao de objetos [ 45-48 ] */
365: "constructor","destructor","inherited","object",
366:
367: /* Programacao de baixo nivel [ 49-50 ] */
368: "asm","inline"
369: };
370:
371: register char i; /* Variavel de controle da iteracao */
372:
373: /* Para armazenar a representacao do token em minusculo */
374: char auxStr[ ITEMTOKENSIZE ];
375:
376: /* Gerando a representacao em minusculo do token */
377: /* GARANTE QUE A ANALISE NAO SERAH SENSIVEL AO CASO */
378: toLowerCase( token, auxStr );
379:
380: *( cToken + 0 ) = '\0'; /* Anulando a classe do token */
381:
382: /* Varrendo a matriz de palavras reservadas para verificar se
383: o token faz parte dela. Caso faca, a sua classe eh de-
384: finida. */
385: for ( i = 0; i <= 50; i++ )
386:
387: /* Testando se eh palavra reservada*/
388: if ( ! strcmp( auxStr, *( RESERVEDWORDS + i ) ) ) {
389:
390: /* Definindo a classe da palavra reservada */
391: switch ( i ) {
392: case 0: case 1:
393: getTokenClass( 10, cToken );
394:
395: break;
396:
397: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9:
398: case 10: case 11: case 12: case 13: case 14: case 15:
399: case 16: case 17: case 18:
400: getTokenClass( 8, cToken );
401:
402: break;
403:
404: case 19: case 20: case 21: case 22: case 23: case 24:
405: getTokenClass( 2, cToken );
406:
407: break;
408:
409: case 25: case 26: case 27: case 28:
410: getTokenClass( 5, cToken );
411:
412: break;
413:
414: case 29: case 30: case 31: case 32:
415: getTokenClass( 22, cToken );
416:
417: break;
418:
419: case 33: case 34:
420: getTokenClass( 20, cToken );
421:
422: break;
423:
424: case 35:
425: getTokenClass( 24, cToken );
426:
427: break;
428:
429: case 36: case 37:
430: getTokenClass( 23, cToken );
431:
432: break;
433:
434: case 38:
435: getTokenClass( 19, cToken );
436:
437: break;
438:
439: case 39: case 40:
440: getTokenClass( 0, cToken );
441:
442: break;
443:
444: case 41: case 42:
445: getTokenClass( 6, cToken );
446:
447: break;
448:
449: case 43:
450: getTokenClass( 4, cToken );
451:
452: break;
453:
454: case 44:
455: getTokenClass( 1, cToken );
456:
457: break;
458:
459: case 45: case 46: case 47: case 48:
460: getTokenClass( 3, cToken );
461:
462: break;
463:
464: case 49: case 50:
465: getTokenClass( 25, cToken );
466:
467: break;
468: } /* switch */
469:
470: return 1; /* Eh palavra reservada */
471: } /* if */
472:
473: return 0; /* Nao eh palavra reservada */
474: } /* isResWord */
475:
476: /*******************************************************************************
477: NOME: lexicalScanner()
478:
479: DESCRIO
480: Esta a funcao que realizar a anlise lxica. a principal funo desta bi
481: blioteca.
482:
483: PARMETROS
484: FILE *sCode : O ponteiro para o arquivo com o cdigo-fonte.
485: Queue *sTable : Ponteiro para a tabela de smbolos.
486: Queue *tTable : Ponteiro para a tabela de tokens que nao fazem parte da tabel
487: de smbolos -tabela de tokens.
488: Queue *eTable : Ponteiro para a tabela de erros, que armazena os tokens invl
489: dos.
490:
491: RETORNO
492: Retorna 0 caso a anlise no tenha produzido erro;
493: -1 caso o erro tenha sido na manipulao do arquivo;
494: 1 caso haja um erro lxico no cdigo-fonte.
495: ********************************************************************************
496: int lexicalScanner ( FILE *sCode, Queue *sTable, Queue *tTable, Queue *eTable )
497: {
498: char chRead, /* O ultimo caractere lido */
499: state = 1, /* O estado em que se encontra o analisador lexico */
500: atualLine[ LINESIZE ], /* Armazena a ultima linha lida do arquivo */
501: ret = 0; /* O retorno da funcao */
502:
503: /* Armazena o valor mais alto de um item da tabela de simbolos */
504: long maxValue = 0;
505:
506: /* Informacoes de posicionamento no arquivo - linha x coluna */
507: CoOrdinate cFile;
508:
509: /* Informacoes dos tokens */
510: Item item;
511:
512: /* Armazena o comprimento da linha, para evitar calculos repetidos */
513: int lineSize;
514:
515: /* Inicializando variaveis */
516: /* Inicializando as coordenadas do arquivo */
517: cFile.line = 0;
518:
519: /* Inicializando os valores do item */
520: strcpy( item.token, "\0" );
521: strcpy( item.class, "\0" );
522: item.value = 0;
523: item.coOrdinate.line = 0;
524: item.coOrdinate.column = 0;
525:
526: /* Laco que varre o arquivo do inicio ao fim, em linhas */
527: while ( ! feof( sCode ) ) {
528: /* Lendo a linha atual do arquivo com o codigo-fonte e
529: armazenando-a em atualLine. */
530: fgets( atualLine, ( LINESIZE -2 ), sCode );
531:
532: lineSize = strlen( atualLine ); /* Obtendo o comprimento da linha */
533:
534: /* Laco que varre a linha atual */
535: for ( cFile.column = 0; cFile.column < lineSize; cFile.column++ ) {
536: /* Lendo o caractere da String atualLine e o armazenando em chLido */
537: chRead = *( atualLine + cFile.column );
538:
539: /* A acao a ser tomada depende do estado em que o algoritmo
540: se encontra e do caractere lido. */
541: switch ( state ) {
542: case 1: /* Estado inicial */
543: if ( isspace( chRead ) ) { /* Consome espacos */
544: ++cFile.column; /* Avancando a coluna */
545:
546: /* Roda ateh o fim da linha ou enquanto ler espacos */
547: while ( ( cFile.column < lineSize ) &&
548: ( isspace( *( atualLine + cFile.column ) ) ) )
549: ++cFile.column;
550:
551: /* Caso nao seja o fim da linha, um caractere jah
552: foi lido, portando deve ser relido */
553: if ( cFile.column < lineSize )
554: --cFile.column;
555: }
556:
557: /* Encontrado ; */
558: else if ( chRead == ';' ) {
559: /* Concatenando o caractere encontrado no token */
560: concat( item.token, chRead );
561:
562: /* Armazenando as coordenadas do token no codigo-fonte */
563: item.coOrdinate.line = cFile.line;
564: item.coOrdinate.column = cFile.column;
565:
566: /* Voltando a coluna, para nao perder caracteres */
567: --cFile.column;
568:
569: /* Alterando o estado */
570: state = 2;
571: }
572:
573: /* Inicio de identificador encontrado */
574: else if ( isLetter( chRead ) ) {
575: /* Concatenando o caractere encontrado no token */
576: concat( item.token, chRead );
577:
578: /* Armazenando as coordenadas do token no codigo-fonte */
579: item.coOrdinate.line = cFile.line;
580: item.coOrdinate.column = cFile.column;
581:
582: /* Alterando o estado */
583: state = 3;
584: }
585:
586: /* Inicio de numero encontrado */
587: else if ( isdigit( chRead ) ) {
588: /* Concatenando o caractere encontrado no token */
589: concat( item.token, chRead );
590:
591: /* Armazenando as coordenadas do token no codigo-fonte */
592: item.coOrdinate.line = cFile.line;
593: item.coOrdinate.column = cFile.column;
594:
595: /* Alterando o estado */
596: state = 4;
597: }
598:
599: /* Encontrado . */
600: else if ( chRead == '.' ) {
601: /* Concatenando o caractere encontrado no token */
602: concat( item.token, chRead );
603:
604: /* Armazenando as coordenadas do token no codigo-fonte */
605: item.coOrdinate.line = cFile.line;
606: item.coOrdinate.column = cFile.column;
607:
608: /* Alterando o estado */
609: state = 11;
610: }
611:
612: /* Encontrado = */
613: else if ( chRead == '=' ) {
614: /* Concatenando o caractere encontrado no token */
615: concat( item.token, chRead );
616:
617: /* Armazenando as coordenadas do token no codigo-fonte */
618: item.coOrdinate.line = cFile.line;
619: item.coOrdinate.column = cFile.column;
620:
621: /* Voltando a coluna, para nao perder caracteres */
622: --cFile.column;
623:
624: /* Alterando o estado */
625: state = 13;
626: }
627:
628: /* Encontrado < */
629: else if ( chRead == '<' ) {
630: /* Concatenando o caractere encontrado no token */
631: concat( item.token, chRead );
632:
633: /* Armazenando as coordenadas do token no codigo-fonte */
634: item.coOrdinate.line = cFile.line;
635: item.coOrdinate.column = cFile.column;
636:
637: /* Alterando o estado */
638: state = 14;
639: }
640:
641: /* Encontrado > */
642: else if ( chRead == '>' ) {
643: /* Concatenando o caractere encontrado no token */
644: concat( item.token, chRead );
645:
646: /* Armazenando as coordenadas do token no codigo-fonte */
647: item.coOrdinate.line = cFile.line;
648: item.coOrdinate.column = cFile.column;
649:
650: /* Alterando o estado */
651: state = 17;
652: }
653:
654: /* Encontrado : */
655: else if ( chRead == ':' ) {
656: /* Concatenando o caractere encontrado no token */
657: concat( item.token, chRead );
658:
659: /* Armazenando as coordenadas do token no codigo-fonte */
660: item.coOrdinate.line = cFile.line;
661: item.coOrdinate.column = cFile.column;
662:
663: /* Alterando o estado */
664: state = 19;
665: }
666:
667: /* Encontrado ; */
668: else if ( chRead == ',' ) {
669: /* Concatenando o caractere encontrado no token */
670: concat( item.token, chRead );
671:
672: /* Armazenando as coordenadas do token no codigo-fonte */
673: item.coOrdinate.line = cFile.line;
674: item.coOrdinate.column = cFile.column;
675:
676: /* Voltando a coluna, para nao perder caracteres */
677: --cFile.column;
678:
679: /* Alterando o estado */
680: state = 21;
681: }
682:
683: /* Encontrado ' */
684: else if ( chRead == '\'' ) {
685: /* Completando informacoes sobre o token */
686: strcpy( item.token, "\'" );
687: getTokenClass( 9, item.class );
688: item.value = -1;
689: item.coOrdinate.line = cFile.line;
690: item.coOrdinate.column = cFile.column;
691:
692: /* Gravando o token na fila */
693: enqueue( tTable, &item );
694:
695: /* Limpando o item */
696: cleanItem( &item );
697:
698: /* Alterando o estado */
699: state = 22;
700: }
701:
702: /* Encontrado " */
703: else if ( chRead == '\"' ) {
704: /* Completando informacoes sobre o token */
705: strcpy( item.token, "\"" );
706: getTokenClass( 9, item.class );
707: item.value = -1;
708: item.coOrdinate.line = cFile.line;
709: item.coOrdinate.column = cFile.column;
710:
711: /* Gravando o token na fila */
712: enqueue( tTable, &item );
713:
714: /* Limpando o item */
715: cleanItem( &item );
716:
717: /* Alterando o estado */
718: state = 24;
719: }
720:
721: /* Encontrado +,-,* ou / */
722: else if ( ( chRead == '+' ) || ( chRead == '-' ) ||
723: ( chRead == '*' ) || ( chRead == '/' ) ) {
724: /* Concatenando o caractere encontrado no token */
725: concat( item.token, chRead );
726:
727: /* Armazenando as coordenadas do token no codigo-fonte */
728: item.coOrdinate.line = cFile.line;
729: item.coOrdinate.column = cFile.column;
730:
731: /* Voltando a coluna, para nao perder caracteres */
732: --cFile.column;
733:
734: /* Alterando o estado */
735: state = 26;
736: }
737:
738: /* Encontrado ( */
739: else if ( chRead == '(' ) {
740: /* Concatenando o caractere encontrado no token */
741: concat( item.token, chRead );
742:
743: /* Armazenando as coordenadas do token no codigo-fonte */
744: item.coOrdinate.line = cFile.line;
745: item.coOrdinate.column = cFile.column;
746:
747: /* Alterando o estado */
748: state = 27;
749: }
750:
751: /* Encontrado [,] ou ) */
752: else if ( ( chRead == '[' ) || ( chRead == ']' ) ||
753: ( chRead == ')' ) ) {
754: /* Concatenando o caractere encontrado no token */
755: concat( item.token, chRead );
756:
757: /* Armazenando as coordenadas do token no codigo-fonte */
758: item.coOrdinate.line = cFile.line;
759: item.coOrdinate.column = cFile.column;
760:
761: /* Voltando a coluna, para nao perder caracteres */
762: --cFile.column;
763:
764: /* Alterando o estado */
765: state = 31;
766: }
767:
768: /* Encontrado { */
769: else if ( chRead == '{' ) {
770: /* Completando informacoes sobre o token */
771: strcpy( item.token, "{" );
772: getTokenClass( 12, item.class );
773: item.value = -1;
774: item.coOrdinate.line = cFile.line;
775: item.coOrdinate.column = cFile.column;
776:
777: /* Gravando o token na fila */
778: enqueue( tTable, &item );
779:
780: /* Limpando o item */
781: cleanItem( &item );
782:
783: /* Alterando o estado */
784: state = 32;
785: }
786:
787: /* Encontrado # */
788: else if ( chRead == '#' ) {
789: /* Concatenando o caractere encontrado no token */
790: concat( item.token, chRead );
791:
792: /* Armazenando as coordenadas do token no codigo-fonte */
793: item.coOrdinate.line = cFile.line;
794: item.coOrdinate.column = cFile.column;
795:
796: /* Voltando a coluna, para nao perder caracteres */
797: --cFile.column;
798:
799: /* Alterando o estado */
800: state = 34;
801: }
802:
803: /* Encontrado @ ou ^ */
804: else if ( ( chRead == '@' ) || ( chRead == '^' ) ) {
805: /* Concatenando o caractere encontrado no token */
806: concat( item.token, chRead );
807:
808: /* Armazenando as coordenadas do token no codigo-fonte */
809: item.coOrdinate.line = cFile.line;
810: item.coOrdinate.column = cFile.column;
811:
812: /* Voltando a coluna, para nao perder caracteres */
813: --cFile.column;
814:
815: /* Alterando o estado */
816: state = 35;
817: }
818:
819: /* Encontrado & */
820: else if ( chRead == '&' ) {
821: /* Concatenando o caractere encontrado no token */
822: concat( item.token, chRead );
823:
824: /* Armazenando as coordenadas do token no codigo-fonte */
825: item.coOrdinate.line = cFile.line;
826: item.coOrdinate.column = cFile.column;
827:
828: /* Voltando a coluna, para nao perder caracteres */
829: --cFile.column;
830:
831: /* Alterando o estado */
832: state = 36;
833: }
834:
835: /* Encontrado $ */
836: else if ( chRead == '$' ) {
837: /* Concatenando o caractere encontrado no token */
838: concat( item.token, chRead );
839:
840: /* Armazenando as coordenadas do token no codigo-fonte */
841: item.coOrdinate.line = cFile.line;
842: item.coOrdinate.column = cFile.column;
843:
844: /* Alterando o estado */
845: state = 37;
846: }
847:
848: /* Caractere nao reconhecido encontrado */
849: else {
850: /* Concatenando o caractere encontrado no token */
851: concat( item.token, chRead );
852:
853: /* Armazenando as coordenadas do token no codigo-fonte */
854: item.coOrdinate.line = cFile.line;
855: item.coOrdinate.column = cFile.column;
856:
857: /* Voltando a coluna, para nao perder caracteres */
858: --cFile.column;
859:
860: /* Alterando o estado */
861: state = 39;
862: }
863: break;
864:
865: case 2: /* Estado final - ; */
866: /* Completando as informacoes sobre o token */
867: getTokenClass( 11 ,item.class );
868:
869: /* Realizando a acao padrao */
870: action1( tTable, &item, item.token, item.class, -1,
871: item.coOrdinate.line, item.coOrdinate.column, &state );
872: break;
873:
874: case 3: /* Estado final - identificadores */
875: if ( ( isLetter( chRead ) ) || ( isdigit( chRead ) ) )
876: /* Concatenando o caractere lido no token */
877: concat( item.token, chRead );
878:
879: else {
880: /* Verificando se o token eh uma palavra reservada */
881: if ( isResWord( item.token, item.class ) ) {
882: /* Eh uma palavra reservada */
883:
884: /* Realizando a acao padrao */
885: action1( tTable, &item, item.token, item.class,
886: -1, item.coOrdinate.line, item.coOrdinate.column,
887: &state );
888: }
889: else {
890: /* NAO eh uma palavra reservada */
891:
892: /* Verificando se o identificador jah foi gravado */
893: long saved = isInQueue( sTable, item.token );
894:
895: if ( saved == -1 ) { /* NAO foi gravado */
896: /* Completando informacoes sobre o token */
897: getTokenClass( 14, item.class );
898: item.value = maxValue;
899:
900: /* Inserindo na tabela de simbolos */
901: enqueue( sTable, &item );
902:
903: /* Incrementando o valor maximo */
904: ++maxValue;
905: }
906: else { /* Jah foi gravado */
907: /* Completando informacoes sobre o token */
908: getTokenClass( 14, item.class );
909: item.value = saved;
910:
911: /* Inserindo na tabela de simbolos */
912: enqueue( sTable, &item );
913: }
914: } /* else */
915:
916: /* Voltando a coluna, para nao perder caracteres */
917: --cFile.column;
918:
919: /* Limpando o item lido */
920: cleanItem( &item );
921:
922: /* Alterando o estado */
923: state = 1;
924: } /* else */
925: break;
926:
927: case 4: /* Estado final - numeros inteiros */
928: if ( isdigit( chRead ) ) /* Digito lido */
929: /* Concatenando o caractere lido no token */
930: concat( item.token, chRead );
931:
932: else if ( chRead == '.' ) { /* Ponto lido */
933: /* Concatenando o caractere lido no token */
934: concat( item.token, chRead );
935:
936: /* Alterando o estado */
937: state = 5;
938: }
939:
940: else if ( isalpha( chRead ) ) { /* Letra lida */
941: /* Letras validas */
942: if ( ( chRead == 'e' ) || ( chRead == 'E' ) ) {
943: /* Concatenando o caractere lido no token */
944: concat( item.token, chRead );
945:
946: /* Alterando o estado */
947: state = 7;
948: }
949: else { /* ERRO */
950: /* Concatenando o caractere lido no token */
951: concat( item.token, chRead );
952:
953: /* Alterando o estado */
954: state = 10;
955: }
956: } /* else if */
957:
958: else { /* Numero totalmente lido */
959: /* Completando as informacoes sobre o token */
960: getTokenClass( 7, item.class );
961:
962: /* Realizando a acao padrao */
963: action1( tTable, &item, item.token, item.class, -1,
964: item.coOrdinate.line, item.coOrdinate.column, &state );
965:
966: /* Voltando a coluna, para nao perder caracteres */
967: --cFile.column;
968: } /* else */
969: break;
970:
971: case 5: /* Lendo numero . */
972: if ( isdigit( chRead ) ) { /* Digito lido */
973: /* Concatenando o caractere lido no token */
974: concat( item.token, chRead );
975:
976: /* Alterando o estado */
977: state = 6;
978: }
979: else if ( chRead == '.' ) { /* Encontrado .. */
980: /* Removendo o ultimo caractere do token - . */
981: *( item.token + ( strlen( item.token ) -1 ) ) = '\0';
982:
983: /* Completando as informacoes sobre o token */
984: getTokenClass( 7, item.class );
985:
986: /* Realizando a acao padrao */
987: action1( tTable, &item, item.token, item.class, -1,
988: item.coOrdinate.line, item.coOrdinate.column, &state );
989:
990: /* Adicionando o ponto retirado no token e o ponto lido */
991: strcpy( item.token, ".." );
992:
993: /* Ajustando as coordenadas do token */
994: item.coOrdinate.line = cFile.line;
995: item.coOrdinate.column = cFile.column - 1;
996:
997: /* Voltando a coluna, para nao perder caracteres */
998: --cFile.column;
999:
1000: /* Indo para o estado do token .. */
1001: state = 12;
1002: }
1003:
1004: /* Numero ponto letra : ERRO */
1005: else if ( isLetter( chRead ) ) {
1006: /* Concatenando o caractere lido no token */
1007: concat( item.token, chRead );
1008:
1009: /* Alterando o estado */
1010: state = 10;
1011: }
1012:
1013: else { /* Erro */
1014: /* Completando as informacoes sobre o token */
1015: getTokenClass( 27, item.class );
1016:
1017: /* Realizando a acao padrao */
1018: action1( eTable, &item, item.token, item.class, -1,
1019: item.coOrdinate.line, item.coOrdinate.column, &state );
1020:
1021: /* Garantindo retorno de erro */
1022: ret = 1;
1023:
1024: /* Voltando a coluna, para nao perder caracteres */
1025: --cFile.column;
1026: }
1027: break;
1028:
1029: case 6: /* Estado final - numeros reais */
1030: if ( isdigit( chRead ) ) /* Digito lido */
1031: /* Concatenando o caractere lido no token */
1032: concat( item.token, chRead );
1033:
1034: else if ( isLetter( chRead ) ) { /* Letra lida */
1035: /* Letras validas */
1036: if ( ( chRead == 'e' ) || ( chRead == 'E' ) ) {
1037: /* Concatenando o caractere lido no token */
1038: concat( item.token, chRead );
1039:
1040: /* Alterando o estado */
1041: state = 7;
1042: }
1043: else { /* ERRO */
1044: /* Concatenando o caractere lido no token */
1045: concat( item.token, chRead );
1046:
1047: /* Alterando o estado */
1048: state = 10;
1049: }
1050: } /* else if */
1051:
1052: else {
1053: /* Completando as informacoes sobre o token */
1054: getTokenClass( 7, item.class );
1055:
1056: /* Realizando a acao padrao */
1057: action1( tTable, &item, item.token, item.class, -1,
1058: item.coOrdinate.line, item.coOrdinate.column, &state );
1059:
1060: /* Voltando a coluna, para nao perder caracteres */
1061: --cFile.column;
1062: }
1063: break;
1064:
1065: case 7: /* Estado final - numero em notacao E */
1066: if ( isdigit( chRead ) ) { /* Digito lido */
1067: /* Concatenando o caractere lido no token */
1068: concat( item.token, chRead );
1069:
1070: /* Alterando o estado */
1071: state = 9;
1072: }
1073:
1074: /* Sinal lido */
1075: else if ( ( chRead == '+' ) || ( chRead == '-' ) ) {
1076: /* Concatenando o caractere lido no token */
1077: concat( item.token, chRead );
1078:
1079: /* Alterando o estado */
1080: state = 8;
1081: }
1082:
1083: else if ( isLetter( chRead ) ) { /* Letra lida */
1084: /* Concatenando o caractere lido no token */
1085: concat( item.token, chRead );
1086:
1087: /* Alterando o estado */
1088: state = 10;
1089: }
1090:
1091: else { /* ERRO */
1092: /* Completando as informacoes sobre o token */
1093: getTokenClass( 27, item.class );
1094:
1095: /* Realizando a acao padrao */
1096: action1( eTable, &item, item.token, item.class, -1,
1097: item.coOrdinate.line, item.coOrdinate.column, &state );
1098:
1099: /* Voltando a coluna, para nao perder caracteres */
1100: --cFile.column;
1101: }
1102: break;
1103:
1104: case 8: /* Estado final - numeros em notacao E com sinal */
1105: if ( isdigit( chRead ) ) {
1106: /* Concatenando o caractere lido no token */
1107: concat( item.token, chRead );
1108:
1109: /* Alterando o estado */
1110: state = 9;
1111: }
1112:
1113: else if ( isLetter( chRead ) ) { /* Letra lida */
1114: /* Concatenando o caractere lido no token */
1115: concat( item.token, chRead );
1116:
1117: /* Alterando o estado */
1118: state = 10;
1119: }
1120:
1121: else {
1122: /* Completando as informacoes sobre o token */
1123: getTokenClass( 27, item.class );
1124:
1125: /* Realizando a acao padrao */
1126: action1( tTable, &item, item.token, item.class, -1,
1127: item.coOrdinate.line, item.coOrdinate.column, &state );
1128:
1129: /* Voltando a coluna, para nao perder caracteres */
1130: --cFile.column;
1131: } /* else */
1132: break;
1133:
1134: case 9: /* Estado final - numeros em notacao E */
1135: if ( isdigit( chRead ) )
1136: /* Concatenando o caractere lido no token */
1137: concat( item.token, chRead );
1138:
1139: else if ( isLetter( chRead ) ) { /* Letra lida */
1140: /* Concatenando o caractere lido no token */
1141: concat( item.token, chRead );
1142:
1143: /* Alterando o estado */
1144: state = 10;
1145: }
1146:
1147: else { /* Numero totalmente lido */
1148: /* Completando as informacoes sobre o token */
1149: getTokenClass( 7, item.class );
1150:
1151: /* Realizando a acao padrao */
1152: action1( tTable, &item, item.token, item.class, -1,
1153: item.coOrdinate.line, item.coOrdinate.column, &state );
1154:
1155: /* Voltando a coluna, para nao perder caracteres */
1156: --cFile.column;
1157: }
1158: break;
1159:
1160: case 10: /* Estado final - numero seguido de letra - ERRO */
1161: if ( ( isLetter( chRead ) ) || ( isdigit( chRead ) ) ) {
1162: /* Concatenando o caractere lido no token */
1163: concat( item.token, chRead );
1164: }
1165: else {
1166: /* Completando as informacoes sobre o token */
1167: getTokenClass( 27, item.class );
1168:
1169: /* Realizando a acao padrao */
1170: action1( eTable, &item, item.token, item.class, -1,
1171: item.coOrdinate.line, item.coOrdinate.column, &state );
1172:
1173: /* Voltando a coluna, para nao perder caracteres */
1174: --cFile.column;
1175:
1176: /* Retornando erro */
1177: ret = 1;
1178: }
1179: break;
1180:
1181: case 11: /* Estado final - . */
1182: if ( chRead == '.' ) { /* .. lido */
1183: /* Concatenando o caractere lido no token */
1184: concat( item.token, chRead );
1185:
1186: /* Alterando o estado */
1187: state = 12;
1188: }
1189: else {
1190: /* Completando as informacoes sobre o token */
1191: getTokenClass( 9, item.class );
1192:
1193: /* Realizando a acao padrao */
1194: action1( tTable, &item, item.token, item.class, -1,
1195: item.coOrdinate.line, item.coOrdinate.column, &state );
1196:
1197: /* Voltando a coluna, para nao perder caracteres */
1198: --cFile.column;
1199: }
1200: break;
1201:
1202: case 12: /* Estado final - .. */
1203: /* Completando as informacoes sobre o token */
1204: getTokenClass( 18, item.class );
1205:
1206: /* Realizando a acao padrao */
1207: action1( tTable, &item, item.token, item.class, -1,
1208: item.coOrdinate.line, item.coOrdinate.column, &state );
1209: break;
1210:
1211: case 13: /* Estado final - = */
1212: /* Completando as informacoes sobre o token */
1213: getTokenClass( 24, item.class );
1214:
1215: /* Realizando a acao padrao */
1216: action1( tTable, &item, item.token, item.class, -1,
1217: item.coOrdinate.line, item.coOrdinate.column, &state );
1218: break;
1219:
1220: case 14: /* Estado final - < */
1221: if ( chRead == '=' ) { /* Lido <= */
1222: /* Concatenando o caractere lido no token */
1223: concat( item.token, chRead );
1224:
1225: /* Voltando a coluna, para nao perder caracteres */
1226: --cFile.column;
1227:
1228: /* Alterando o estado */
1229: state = 15;
1230: }
1231: else if ( chRead == '>' ) { /* Lido <> */
1232: /* Concatenando o caractere lido no token */
1233: concat( item.token, chRead );
1234:
1235: /* Voltando a coluna, para nao perder caracteres */
1236: --cFile.column;
1237:
1238: /* Alterando o estado */
1239: state = 16;
1240: }
1241: else { /* Lido < */
1242: /* Completando as informacoes sobre o token */
1243: getTokenClass( 24, item.class );
1244:
1245: /* Realizando a acao padrao */
1246: action1( tTable, &item, item.token, item.class, -1,
1247: item.coOrdinate.line, item.coOrdinate.column, &state );
1248:
1249: /* Voltando a coluna, para nao perder caracteres */
1250: --cFile.column;
1251: }
1252: break;
1253:
1254: case 15: /* Estado final - <= */
1255: /* Completando as informacoes sobre o token */
1256: getTokenClass( 24, item.class );
1257:
1258: /* Realizando a acao padrao */
1259: action1( tTable, &item, item.token, item.class, -1,
1260: item.coOrdinate.line, item.coOrdinate.column, &state );
1261: break;
1262:
1263: case 16: /* Estado final - <> */
1264: /* Completando as informacoes sobre o token */
1265: getTokenClass( 24, item.class );
1266:
1267: /* Realizando a acao padrao */
1268: action1( tTable, &item, item.token, item.class, -1,
1269: item.coOrdinate.line, item.coOrdinate.column, &state );
1270: break;
1271:
1272: case 17: /* Estado final - > */
1273: if ( chRead == '=' ) {
1274: /* Concatenando o caractere lido no token */
1275: concat( item.token, chRead );
1276:
1277: /* Voltando a coluna, para nao perder caracteres */
1278: --cFile.column;
1279:
1280: /* Alterando o estado */
1281: state = 18;
1282: }
1283: else { /* Lido > */
1284: /* Completando as informacoes sobre o token */
1285: getTokenClass( 24, item.class );
1286:
1287: /* Realizando a acao padrao */
1288: action1( tTable, &item, item.token, item.class, -1,
1289: item.coOrdinate.line, item.coOrdinate.column, &state );
1290:
1291: /* Voltando a coluna, para nao perder caracteres */
1292: --cFile.column;
1293: }
1294: break;
1295:
1296: case 18: /* Estado final - >= */
1297: /* Completando as informacoes sobre o token */
1298: getTokenClass( 24, item.class );
1299:
1300: /* Realizando a acao padrao */
1301: action1( tTable, &item, item.token, item.class, -1,
1302: item.coOrdinate.line, item.coOrdinate.column, &state );
1303: break;
1304:
1305: case 19: /* Estado final - : */
1306: if ( chRead == '=' ) { /* Lido := */
1307: /* Concatenando o caractere lido no token */
1308: concat( item.token, chRead );
1309:
1310: /* Voltando a coluna, para nao perder caracteres */
1311: --cFile.column;
1312:
1313: /* Alterando o estado */
1314: state = 20;
1315: }
1316: else { /* Lido : */
1317: /* Completando as informacoes sobre o token */
1318: getTokenClass( 9, item.class );
1319:
1320: /* Realizando a acao padrao */
1321: action1( tTable, &item, item.token, item.class, -1,
1322: item.coOrdinate.line, item.coOrdinate.column, &state );
1323:
1324: /* Voltando a coluna, para nao perder caracteres */
1325: --cFile.column;
1326: }
1327: break;
1328:
1329: case 20: /* Estado final - := */
1330: /* Completando as informacoes sobre o token */
1331: getTokenClass( 21, item.class );
1332:
1333: /* Realizando a acao padrao */
1334: action1( tTable, &item, item.token, item.class, -1,
1335: item.coOrdinate.line, item.coOrdinate.column, &state );
1336: break;
1337:
1338: case 21: /* Estado final - , */
1339: /* Completando as informacoes sobre o token */
1340: getTokenClass( 9, item.class );
1341:
1342: /* Realizando a acao padrao */
1343: action1( tTable, &item, item.token, item.class, -1,
1344: item.coOrdinate.line, item.coOrdinate.column, &state );
1345: break;
1346:
1347: case 22: /* Dentro de ' */
1348: if ( chRead != '\'' ) { /* Consome a constante literal */
1349: ++cFile.column; /* Avancando a coluna */
1350:
1351: /* Roda ateh o fim da linha ou
1352: ateh o fim da constante */
1353: while ( ( cFile.column < lineSize ) &&
1354: ( *( atualLine + cFile.column ) != '\'' ) )
1355: ++cFile.column;
1356:
1357: /* Caso nao seja o fim da linha, o fim
1358: do comentario foi encontrado. */
1359: if ( cFile.column < lineSize ) {
1360: /* Concatenando o caractere lido no token */
1361: concat( item.token, *( atualLine + cFile.column ) );
1362:
1363: /* Ajustando as coordenadas */
1364: item.coOrdinate.line = cFile.line;
1365: item.coOrdinate.column = cFile.column;
1366:
1367: /* Voltando a coluna, para nao perder caracteres */
1368: --cFile.column;
1369:
1370: /* Alterando o estado */
1371: state = 23;
1372: } /* if */
1373: }
1374:
1375: else { /* Lido ' */
1376: /* Concatenando o caractere lido no token */
1377: concat( item.token, chRead );
1378:
1379: /* Ajustando as coordenadas */
1380: item.coOrdinate.line = cFile.line;
1381: item.coOrdinate.column = cFile.column;
1382:
1383: /* Voltando a coluna, para nao perder caracteres */
1384: --cFile.column;
1385:
1386: /* Alterando o estado */
1387: state = 23;
1388: }
1389: break;
1390:
1391: case 23: /* Estado final - ' */
1392: /* Completando as informacoes sobre o token */
1393: getTokenClass( 9, item.class );
1394:
1395: /* Realizando a acao padrao */
1396: action1( tTable, &item, item.token, item.class, -1,
1397: item.coOrdinate.line, item.coOrdinate.column, &state );
1398: break;
1399:
1400: case 24: /* Dentro de " */
1401: if ( chRead != '\"' ) { /* Consome a constante literal */
1402: ++cFile.column; /* Avancando a coluna */
1403:
1404: /* Roda ateh o fim da linha ou
1405: ateh o fim da constante */
1406: while ( ( cFile.column < lineSize ) &&
1407: ( *( atualLine + cFile.column ) != '\"' ) )
1408: ++cFile.column;
1409:
1410: /* Caso nao seja o fim da linha, o fim
1411: do comentario foi encontrado. */
1412: if ( cFile.column < lineSize ) {
1413: /* Concatenando o caractere lido no token */
1414: concat( item.token, *( atualLine + cFile.column ) );
1415:
1416: /* Ajustando as coordenadas */
1417: item.coOrdinate.line = cFile.line;
1418: item.coOrdinate.column = cFile.column;
1419:
1420: /* Voltando a coluna, para nao perder caracteres */
1421: --cFile.column;
1422:
1423: /* Alterando o estado */
1424: state = 25;
1425: } /* if */
1426: }
1427:
1428: else { /* Lido ' */
1429: /* Concatenando o caractere lido no token */
1430: concat( item.token, chRead );
1431:
1432: /* Ajustando as coordenadas */
1433: item.coOrdinate.line = cFile.line;
1434: item.coOrdinate.column = cFile.column;
1435:
1436: /* Voltando a coluna, para nao perder caracteres */
1437: --cFile.column;
1438:
1439: /* Alterando o estado */
1440: state = 25;
1441: }
1442: break;
1443:
1444: case 25: /* Estado final - " */
1445: /* Completando as informacoes sobre o token */
1446: getTokenClass( 9, item.class );
1447:
1448:
1449: action1( tTable, &item, item.token, item.class, -1,
1450: item.coOrdinate.line, item.coOrdinate.column, &state );
1451: break;
1452:
1453: case 26: /* Estado final - +-* / */
1454: /* Completando as informacoes sobre o token */
1455: getTokenClass( 20, item.class );
1456:
1457: /* Realizando a acao padrao */
1458: action1( tTable, &item, item.token, item.class, -1,
1459: item.coOrdinate.line, item.coOrdinate.column, &state );
1460: break;
1461:
1462: case 27: /* Estado final - ( */
1463: if ( chRead != '*' ) { /* Lido ( */
1464: /* Completando as informacoes sobre o token */
1465: getTokenClass( 13, item.class );
1466:
1467: /* Realizando a acao padrao */
1468: action1( tTable, &item, item.token, item.class, -1,
1469: item.coOrdinate.line, item.coOrdinate.column, &state );
1470:
1471: /* Voltando a coluna, para nao perder caracteres */
1472: --cFile.column;
1473: }
1474: else { /* Lido (* */
1475: /* Concatenando o caractere lido no token */
1476: concat( item.token, chRead );
1477:
1478: /* Completando as informacoes sobre o token */
1479: getTokenClass( 12, item.class );
1480: item.value = -1;
1481:
1482: /* Gravando o token */
1483: enqueue( tTable, &item );
1484:
1485: /* Limpando o item */
1486: cleanItem( &item );
1487:
1488: /* Alterando o estado */
1489: state = 28;
1490: } /* else */
1491: break;
1492:
1493: case 28: /* Dentro de (* */
1494: if ( chRead != '*' ) { /* Consome comentarios */
1495: ++cFile.column; /* Avancando a coluna */
1496:
1497: /* Roda ateh o fim da linha ou
1498: ateh o fim do comentario */
1499: while ( ( cFile.column < lineSize ) &&
1500: ( *( atualLine + cFile.column ) != '*' ) )
1501: ++cFile.column;
1502:
1503: /* Caso nao seja o fim da linha, o fim
1504: do comentario foi encontrado. */
1505: if ( cFile.column < lineSize ) {
1506: /* Concatenando o caractere lido no token */
1507: concat( item.token, *( atualLine + cFile.column ) );
1508:
1509: /* Alterando o estado */
1510: state = 29;
1511: } /* if */
1512: }
1513:
1514: else { /* Possivel fim de comentario encontrado */
1515: /* Concatenando o caractere lido no token */
1516: concat( item.token, chRead );
1517:
1518: /* Alterando o estado */
1519: state = 29;
1520: }
1521: break;
1522:
1523: case 29: /* Lido * dentro de (* */
1524: if ( chRead == ')' ) { /* Fim de comentario encontrado */
1525: /* Concatenando o caractere lido no token */
1526: concat( item.token, chRead );
1527:
1528: /* Ajustando as coordenadas */
1529: item.coOrdinate.line = cFile.line;
1530: item.coOrdinate.column = cFile.column - 1;
1531:
1532: /* Voltando a coluna, para nao perder caracteres */
1533: --cFile.column;
1534:
1535: /* Alterando o estado */
1536: state = 30;
1537: }
1538:
1539: else if ( chRead == '*' ) ; /* Consome *s */
1540:
1541: else { /* Nao eh fim de comentario */
1542: /* Limpando o token */
1543: strcpy( item.token, "" );
1544:
1545: /* Alterando o estado */
1546: state = 28;
1547: }
1548: break;
1549:
1550: case 30: /* Estado final - *) */
1551: /* Completando as informacoes sobre o token */
1552: getTokenClass( 12, item.class );
1553:
1554: /* Realizando a acao padrao */
1555: action1( tTable, &item, item.token, item.class, -1,
1556: item.coOrdinate.line, item.coOrdinate.column, &state );
1557: break;
1558:
1559: case 31: /* Estado final - []) */
1560: /* Completando as informacoes sobre o token */
1561: getTokenClass( 13, item.class );
1562:
1563: /* Realizando a acao padrao */
1564: action1( tTable, &item, item.token, item.class, -1,
1565: item.coOrdinate.line, item.coOrdinate.column, &state );
1566: break;
1567:
1568: case 32: /* Dentro de { */
1569: if ( chRead != '}' ) { /* Consome comentarios */
1570: ++cFile.column; /* Avancando a coluna */
1571:
1572: /* Roda ateh o fim da linha ou
1573: ateh o fim do comentario */
1574: while ( ( cFile.column < lineSize ) &&
1575: ( *( atualLine + cFile.column ) != '}' ) )
1576: ++cFile.column;
1577:
1578: /* Caso nao seja o fim da linha, o fim
1579: do comentario foi encontrado. */
1580: if ( cFile.column < lineSize ) {
1581: /* Concatenando o caractere lido no token */
1582: concat( item.token, *( atualLine + cFile.column ) );
1583:
1584: /* Ajustando as coordenadas */
1585: item.coOrdinate.line = cFile.line;
1586: item.coOrdinate.column = cFile.column;
1587:
1588: /* Voltando a coluna, para nao perder caracteres */
1589: --cFile.column;
1590:
1591: /* Alterando o estado */
1592: state = 33;
1593: } /* if */
1594: }
1595:
1596: else { /* Fim de comentario encontrado */
1597: /* Concatenando o caractere lido no token */
1598: concat( item.token, chRead );
1599:
1600: /* Ajustando as coordenadas */
1601: item.coOrdinate.line = cFile.line;
1602: item.coOrdinate.column = cFile.column;
1603:
1604: /* Voltando a coluna, para nao perder caracteres */
1605: --cFile.column;
1606:
1607: /* Alterando o estado */
1608: state = 33;
1609: }
1610: break;
1611:
1612: case 33: /* Estado final - } */
1613: /* Completando as informacoes sobre o token */
1614: getTokenClass( 12, item.class );
1615:
1616: /* Realizando a acao padrao */
1617: action1( tTable, &item, item.token, item.class, -1,
1618: item.coOrdinate.line, item.coOrdinate.column, &state );
1619: break;
1620:
1621: case 34: /* Estado final - # */
1622: /* Completando as informacoes sobre o token */
1623: getTokenClass( 16, item.class );
1624:
1625: /* Realizando a acao padrao */
1626: action1( tTable, &item, item.token, item.class, -1,
1627: item.coOrdinate.line, item.coOrdinate.column, &state );
1628: break;
1629:
1630: case 35: /* Estado final - @^ */
1631: /* Completando as informacoes sobre o token */
1632: getTokenClass( 19, item.class );
1633:
1634: /* Realizando a acao padrao */
1635: action1( tTable, &item, item.token, item.class, -1,
1636: item.coOrdinate.line, item.coOrdinate.column, &state );
1637: break;
1638:
1639: case 36: /* Estado final - & */
1640: /* Completando as informacoes sobre o token */
1641: getTokenClass( 15, item.class );
1642:
1643: /* Realizando a acao padrao */
1644: action1( tTable, &item, item.token, item.class, -1,
1645: item.coOrdinate.line, item.coOrdinate.column, &state );
1646: break;
1647:
1648: case 37: /* Estado final - $ */
1649: if ( isHex( chRead ) ) { /* Constante hexadecimal encontrada */
1650: /* Grava-se o $ e inicia a leitura da constante */
1651: /* Completando as informacoes sobre o token */
1652: getTokenClass( 17, item.class );
1653: item.value = -1;
1654:
1655: /* Gravando o item */
1656: enqueue( tTable, &item );
1657:
1658: /* Limpando o item */
1659: cleanItem( &item );
1660:
1661: /* Ajustando as coordenadas */
1662: item.coOrdinate.line = cFile.line;
1663: item.coOrdinate.column = cFile.column;
1664:
1665: /* Concatenando o caractere lido no token */
1666: concat( item.token, chRead );
1667:
1668: /* Alterando o estado */
1669: state = 38;
1670: }
1671: else {
1672: /* Completando as informacoes sobre o token */
1673: getTokenClass( 15, item.class );
1674:
1675: /* Realizando a acao padrao */
1676: action1( tTable, &item, item.token, item.class, -1,
1677: item.coOrdinate.line, item.coOrdinate.column, &state );
1678: }
1679: break;
1680:
1681: case 38: /* Estado final - [0..9][a..F] */
1682: if ( isHex( chRead ) ) /* Lendo a constate hexadecimal */
1683: /* Concatenando o caractere lido no token */
1684: concat( item.token, chRead );
1685:
1686: else if ( isLetter( chRead ) ) { /* ERRO */
1687: /* Concatenando o caractere lido no token */
1688: concat( item.token, chRead );
1689:
1690: /* Alterando o estado */
1691: state = 10;
1692: }
1693:
1694: else { /* Constante hexadecimal lida */
1695: /* Completando as informacoes sobre o token */
1696: getTokenClass( 15, item.class );
1697:
1698: /* Realizando a acao padrao */
1699: action1( tTable, &item, item.token, item.class, -1,
1700: item.coOrdinate.line, item.coOrdinate.column, &state );
1701:
1702: /* Voltando a coluna, para nao perder caracteres */
1703: --cFile.column;
1704: }
1705: break;
1706:
1707: case 39: /* Estado final - Caractere desconhecido */
1708: /* Completando as informacoes sobre o token */
1709: getTokenClass( 26, item.class );
1710:
1711: /* Realizando a acao padrao */
1712: action1( eTable, &item, item.token, item.class, -1,
1713: item.coOrdinate.line, item.coOrdinate.column, &state );
1714: break;
1715:
1716: default:
1717: /* Forcando a saida do laco for */
1718: cFile.column = lineSize;
1719:
1720: /* Retornando erro */
1721: ret = -1;
1722: break;
1723: } /* switch*/
1724: } /* for */
1725:
1726: /* Incrementando a linha atual */
1727: ++cFile.line;
1728: } /* while */
1729:
1730: /* Rebobinando o codigo-fonte */
1731: rewind( sCode );
1732:
1733: /* Retornando o resultado da analise lexica */
1734: /* -1 - Erro na manipulacao do arquivo. */
1735: /* 0 - Nao foram encontrados erros. */
1736: /* 1 - Erro lexico encontrado. */
1737: return ret;
1738: } /* lexicalAnalysis */
1739:

Potrebbero piacerti anche