Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Apndice 3
20-01-2010
La produccin: ASB::=AsB define que S puede ser reemplazado por s, siempre que ocurra entre A y B; por lo cual es sensible al contexto. El uso de la recursin al definir producciones, permite generar un infinito nmero de sentencias a partir de un nmero finito de producciones. S::=aA A::=b|cA La categora A, est definida en trminos de s misma. En el ejemplo, los smbolos terminales se representan con minsculas, los no terminales con maysculas. A partir de S, se generan: ab, acb, accb, acccb, ..
20-01-2010
Introduccin a analizadores lxicos S accb aA accb A ccb cA ccb A cb cA cb A b b b Inicio. Se lee a Se reemplaza S. Se reconoce a. Se acepta a. Se lee c Se reemplaza A. Se reconoce c. Se acepta c. Se lee c. Se reemplaza A. Se reconoce c. Se acepta c. Se lee b. Se reemplaza A. Se reconoce b. Se acepta la frase como correcta.
Figura A3.1. Anlisis sin volver atrs. No es necesario volver atrs, y el anlisis est basado en la lectura de un smbolo terminal por adelantado. Para que esto sea posible, los smbolos iniciales de smbolos no terminales alternativos que figuran a la derecha en las producciones, deben ser diferentes. El siguiente ejemplo ilustra reglas que no cumplen el principio anterior. Ya que A y B (smbolos no terminales alternativos en S), tienen iguales smbolos iniciales, ambos son x. S::=A|B A::=xA|y B::=xB|z Si se desea analizar la secuencia xxxz, se tendr la dificultad que no es posible discernir (slo leyendo el primer smbolo por adelantado) si S debe ser reemplazado por A o por B. Si se eligiera al azar, reemplazar S por A, luego de unos pasos el anlisis falla, y se debera volver atrs, e intentar reemplazar por B, en lugar de A, y volver a intentar. Las reglas: S::=C|xS C::=y|z Son equivalentes a las anteriores y cumplen el principio anterior. En variadas construcciones de los lenguajes se acepta smbolos opcionales. Es decir la alternativa entre un smbolo terminal y una secuencia nula de smbolos. Ejemplo de esto es la asignacin: x= +a; el smbolo + es opcional. Sea nula la secuencia nula. Entonces las reglas: S::=Ax A::=x|nula Si se desea reconocer x, si luego de reemplazar S por Ax, se intenta reemplazar A por x el anlisis falla, se logra xx en la derivacin. Con lo cual puede reconocerse el primer x, y luego al
20-01-2010
intentar leer el prximo, como no quedan smbolos no terminales que leer y queda pendiente un x que derivar, se concluye que el anlisis fall. Lo que se debi realizar era reemplazar A por nula. Para evitar la vuelta atrs en el reconocimiento, se impone una regla adicional para las producciones que generen la secuencia nula: Para una secuencia A que genera la secuencia nula, los smbolos iniciales que genera A deben se disjuntos con los smbolos que siguen a cualquier secuencia generada por A. En el ejemplo anterior, S dice que la sentencia A tiene a x como smbolo siguiente. Y la produccin que define A, indica que el primer smbolo que puede generar A es tambin x. Como los iniciales generados por A son iguales a los siguientes a A, se viola la regla anterior. La repeticin de construcciones, que tambin es muy frecuente en los lenguajes, suele definirse empleando recursin. Por ejemplo la repeticin de una o ms veces del elemento B, puede anotarse: A::= B|AB Pero el primero de B y el primero de AB no es el vaco, y no cumple la primera de las reglas. Si se cambia la definicin de A por: A::=nula|AB A genera: nula, B, BB, BBB, y se tendr que el primero de A y el siguiente a A sern B, violando la segunda regla. Lo cual permite visualizar que no puede emplearse recursin por la izquierda. La recursin por la derecha, cumple las reglas anteriores: A::=nula|BA Esta ltima produccin tambin genera la repeticin de cero, una o ms veces del elemento B. La frecuencia de construcciones repetitivas que generen la secuencia nula lleva a definir los siguiente metasmbolos: A::={B} Que genera: nula, B, BB, BBB, Esta definicin slo simplifica la notacin, pero an es preciso revisar que se cumpla la segunda regla, para emplear algoritmos basados en leer un smbolo por adelantado y sin volver atrs.
20-01-2010
Figura A3.2. Smbolo terminal. Corresponde a un reconocimiento del smbolo terminal x, en la produccin de la que forma parte, y al avanzar en la lectura del siguiente smbolo en la secuencia de entrada. Es importante asociar estos grafos a elementos de un lenguaje de programacin que implementar el reconocedor sintctico basado en diagramas. Para el elemento terminal, puede traducirse: if (ch== x) ch=lee(stream); else error(n); Donde stream es el descriptor del archivo que contiene el texto que ser analizado. La funcin lee, trae el siguiente carcter. En este nivel los caracteres individuales del texto se consideran smbolos terminales. La funcin de error, debera generar un mensaje asociado a la deteccin de una sentencia mal formada. Smbolo no terminal.
B
Figura A3.3. Smbolo no terminal. Cuando aparece este diagrama en una produccin, corresponde a la activacin de un reconocedor del smbolo no terminal B. En el reconocedor, se activa una invocacin al procedimiento reconocedor de B. B( ); Alternativa. La produccin: A::=B1|B2||Bn Se representa:
20-01-2010
B1 A B2 Bn
Figura A3.4. Alternativa. En el reconocedor, puede implementarse, mediante la sentencia switch. switch (ch){ case L1: B1(); break; case L2: B2(); break; . case Ln: Bn(); break; } Donde los Li seran los conjuntos de los smbolos iniciales de los Bi. Es preferible describir la alternativa, explicitando el primer smbolo:
b1 A b2 B1 B2
bn
Bn
Figura A3.5. Alternativa, con primer smbolo explcito. switch (ch){ case b1: {ch=lee(stream); B1(); break;} case b2: {ch=lee(stream); B2(); break;} . case bn: {ch=lee(stream); Bn(); break;} } Concatenacin. La produccin: A::=B1B2Bn Se representa:
20-01-2010
Figura A3.6. Concatenacin. En el reconocedor: {B1( ); B2( );Bn( );} Repeticin. La produccin: A::={B} Se representa:
A B
Figura A3.7. Repeticin. En el reconocedor, se implementa: while( esta_en(L, ch) ) B( ); Donde la funcin esta_en retorna verdadero si ch pertenece al conjunto L de los primeros caracteres generados por B. Es preferible, representar, el forma explcita el primer carcter:
A B b
Figura A3.8. Repeticin, con primer smbolo explcito. De este modo el reconocedor se implementa: while( ch==b) {ch=lee(stream); B( );} La repeticin, de a lo menos una vez, puede implementarse con una sentencia while. Cada uno de los bloques anteriores puede ser reemplazado por alguna de las construcciones anteriores. Por ejemplo: la repeticin puede ser una serie de acciones concatenadas.
20-01-2010
8 Resumen.
Para una gramtica dada, pueden construirse grafos sintcticos a partir de las producciones descritas en BNF, y viceversa. Y de stas derivar el cdigo del reconocedor. Los grafos deben cumplir las siguientes dos reglas, para que se puedan recorrer leyendo un smbolo por adelantado y sin volver atrs. Los primeros smbolos en las alternativas deben ser diferentes. De tal forma que la bifurcacin solo pueda escogerse observando el siguiente smbolo de esa rama. Si un grafo reconocedor de una sentencia A, puede generar la secuencia nula, debe rotularse con todos los smbolos que puedan seguir a A. Ya que ingresar al lazo puede afectar el reconocimiento de lo que viene a continuacin. Una vez definido el lenguaje a reconocer, mediante sus grafos, debe verificarse el cumplimiento de las dos reglas anteriores. Un sistema de grafos que cumplan las reglas anteriores se denomina determinista y puede ser recorrido sin volver atrs y solo leyendo un smbolo por adelantado. Esta restriccin no es una limitante en los casos prcticos.
Figura A3.9. Grafo del reconocedor. El grafo permite revisar el cumplimiento de las dos reglas. La bifurcacin tiene interseccin vaca de los primeros elementos de cada rama: { ( } { x } =
20-01-2010
La produccin que genera la secuencia nula tiene interseccin vaca del primer elemento de la repeticin y del smbolo que sigue a esa repeticin: { + } { ) } = El siguiente programa implementa un reconocedor, para sentencias que cumplan la sintaxis descrita por el grafo. Lo ms importante es notar que el cdigo para el reconocedor de sentencias A, puede ser escrito a partir del diagrama anterior. Cada conjunto de reglas da origen a un programa determinado. Se han agregado las funciones que abren y leen el archivo con el texto que ser analizado, para ilustrar los detalles del entorno. Se da trmino a las sentencias del archivo con un asterisco, en la primera posicin de una lnea. Cada vez que termina el anlisis de una sentencia avisa si la encontr correcta. Se emplea una variable global ch, para disminuir el nmero de argumentos. Se destaca que debe leerse un smbolo por adelantado, antes de invocar al reconocedor. Si el descriptor del archivo se deja como variable global, pueden disminuirse an ms los argumentos de las funciones, simplificndolas. #include <stdio.h> void error(int e) { printf("Error %d\n", e);} char lee(FILE *stream) { return( fgetc(stream)); } char ch='\0'; void A(FILE *stream) { if (ch=='x') ch=lee(stream); else if (ch=='(' ) { ch=lee(stream); A(stream); while(ch=='+') {ch=lee(stream); A(stream);} if ( ch==')' ) ch=lee(stream); else error(1); } else error(2); } /* Analiza archivo de texto */ int parser(void) { FILE *stream; if ((stream = fopen("inparser.txt", "r")) == NULL) { fprintf(stderr, "No pudo abrir archivo de entrada.\n"); return 1; Profesor Leopoldo Silva Bijit 20-01-2010
10 }
/* lee hasta encontrar el final del stream */ while(!feof(stream)) { ch=lee(stream); if(ch=='*') break; //lee ch por adelantado. A(stream); printf("%s\n","ok"); } printf("%s\n","fin"); fclose(stream); return 0; } int main(void) { parser(); return 0; }
20-01-2010
Introduccin a analizadores lxicos char simbolo='\0'; int nl=1; //contador de lneas int nc=0; //contador de caracteres en la lnea. FILE *stream; void error(int tipo) { putchar('\n');printf("(%d,%d): ",nl, nc+1); switch (tipo) { case 1: printf("%s\n", "Esperaba smbolo no terminal");break; case 2: printf("%s\n", "Esperaba signo igual"); break; case 3: printf("%s\n", "Esperaba cierre parntesis"); break; case 4: printf("%s\n", "Esperaba abre parntesis"); break; case 5: printf("%s\n", "Esperaba punto"); break; } } void getch(void) { if(!feof(stream)) { simbolo = fgetc(stream); nc++; if(smbolo == '\n') {nl++; nc=0;} putchar(simbolo); //eco en salida estndard } } void getsimbolo(void) { getch(); while(isspace(simbolo)) getch(); //descarta blancos } //factor ::= <smbolo terminal> | <smbolo no terminal> | ( <expresin> ) void factor(void) { if (isalpha(simbolo) ) getsimbolo(); else if (simbolo == '(' ) { getsimbolo(); expresion(); if(smbolo == ')' ) getsimbolo(); else error(3); } else error(4); }
11
20-01-2010
12
// trmino ::= <factor> { <factor> } void termino(void) { factor(); while( (isalpha(simbolo)) || (smbolo == '(' ) ) factor(); } Notar que la repeticin de factor es precedida por la revisin de los primeros caracteres de factor: es decir que sea un smbolo terminal o no terminal o el comienzo de una expresin, que debe comenzar por parntesis abierto. //expresin ::= <trmino> {, <termino>} void expresion(void) { termino(); while(smbolo == ',') {getsimbolo(); termino();} } // produccin ::= <smbolo no terminal> = <expresin> . void produccion() { if(isupper(simbolo)) getsimbolo(); else error(1); if (smbolo == '=') getsimbolo(); else error(2); expresion(); if (simbolo != '.') error(5); } /* Lectura de archivo de texto */ int bnfparser(void) { /* Abre stream para lectura, en modo texto. */ if ((stream = fopen("bnfparser.txt", "r")) == NULL) { fprintf(stderr, "No pudo abrir archivo de entrada.\n"); return 1; } /* lee hasta encontrar el final del stream */ while(!feof(stream)) { getsimbolo(); if(simbolo=='*') break; produccion(); } printf("%s numero de lineas =%d\n","fin de archivo", nl); fclose(stream); /* close stream */ return 0; }
20-01-2010
Introduccin a analizadores lxicos int main(void) { bnfparser(); return 0; } Para el siguiente archivo de entrada: A = C. B=x,A. B=x,A,B,CC=x(B,D. D=(A). * Se genera la siguiente salida: A = C. B=x,A. B=x,A,B,C(3,10): Esperaba punto C=x(B,D. (4,8): Esperaba cierre parntesis D=(A). *fin de archivo nmero de lneas =5
13
14
letra; luego se siguen almacenado los caracteres del identificador (crculo 1) hasta que llegue un carcter no alfanumrico, en que se vuelve a esperar identificadores. Si lo nico que se desea es extraer los identificadores, si no llega una letra cuando se espera una, puede descartrsela y continuar el anlisis.
Si es letra Si es espacio Si es alfanumrico
0 No es letra
Si no es alfanumrico
Figura A3.10. Estados de reconocedor de identificador. Asumiendo que se tiene una lnea almacenada en buffer, la siguiente funcin forma en el string id, el identificador. La estructura del cdigo est basada en el diagrama anterior, y en las funciones cuyos prototipos se encuentran en ctype.h #define LARGOLINEA 80 #define Esperando_letra 0 #define Almacenando_id 1 getword(char *buffer, int nl) { char id[LARGOLINEA]; int i, j, estado; for(i=0, estado=0, j=0; i<strlen(buffer); i++) { switch (estado){ case Esperando_letra: if (isspace(buffer[i]) ) continue; else if (isalpha(buffer[i])) { estado=Almacenando_id; id[j]=buffer[i]; j++; } else ; //No es letra. Descarta char.
20-01-2010
Introduccin a analizadores lxicos break; case Almacenando_id: if (isalnum(buffer[i])) {id[j]=buffer[i]; j++;} //forma id else if(!isalnum(buffer[i])) { estado = Esperando_letra; id[j]='\0'; //termina string j=0; //reset posicin //printf("%s %d\n", id, nl); //muestra los identificadores y la lnea // Aqu debera hacerse algo con el identificador root=insert(id, root, nl); //Ejemplo: lo inserta en rbol } break; } } }
15
20-01-2010
16
Es #
Si es espacio
alfanum Si es alfanumrico
Figura A3.11. Estados de reconocedor de definiciones. La funcin puede escribirse, basndose en el diagrama: FILE *streami,*streamo; char ch; #define p() putc(ch,streamo); #define g() ch=getc(streami) void parser(void) { char word[LARGOID]; char equiv[LARGOID]; int j, state; pcelda p; for(state=0, j=0;!feof(streami);g()) { switch (state){ case EsperaID: if (isspace(ch) ) { p(); continue;} else if (isalpha(ch)) {state=GetId; word[j++]=ch;} else if(ch=='#'){state=BuscaDefine; j=0;} else p(); //se traga hasta final de lnea break; case GetId: if (isalnum(ch)) {word[j++]=ch;} else { if(!isalnum(ch)) Profesor Leopoldo Silva Bijit 20-01-2010
Introduccin a analizadores lxicos {state=EsperaID; word[j]='\0'; j=0; //printf("%s\n",word); if( (p=buscar(word))!=NULL ) //busca identificador { //printf("%s -> %s\n", p->definicion, p->equivalencia); fprintf(streamo, p->equivalencia); //lo reeemplaza } else fprintf(streamo,word); } p(); } break; case BuscaDefine: if (isalnum(ch)) {word[j++]=ch;} else if(!isalnum(ch)) {word[j]='\0';j=0; if (strcmp(word,"define")==0) { state=EsperaDef; //printf("pre=%s\n",word); } else {state=EsperaID; putc('#', streamo); fprintf(streamo,word);p();} } break; case EsperaDef: if (isspace(ch) ) continue; else if (isalpha(ch)) {state=GetDef; word[j++]=ch;} break; case GetDef: if (isalnum(ch)) {word[j++]=ch;} else if(!isalnum(ch)) {state=EsperaEquiv; word[j]='\0'; j=0; //printf("Definicin =%s\n",word); } break; case EsperaEquiv: if (isspace(ch) ) continue; else if (isgraph(ch)) {state=GetEquiv; equiv[j++]=ch;} break; case GetEquiv: if (isgraph(ch)) {equiv[j++]=ch;} else if(!isgraph(ch)) { state=EsperaID; equiv[j]='\0';j=0; //printf("insertar valor equivalente en tabla=%s\n", equiv); // Aqu debera insertar la palabra word y su equivalencia. if( (p=buscar(word))!=NULL ) descarte(word); //permite redefinicin inserte(word, equiv); Profesor Leopoldo Silva Bijit 20-01-2010
17
18 } break; } } } El siguiente segmento, abre los archivos de entrada y salida. int procesa_archivos(void) { /* Abre stream para lectura, en modo texto. */ if ((streami = fopen("input6.c", "r")) == NULL) { fprintf(stderr, "No pudo abrir archivo de entrada.\n"); return 1; } /* Abre stream para escritura, en modo texto. */ if ((streamo = fopen("output6.c", "w")) == NULL) { fprintf(stderr, "No pudo abrir archivo de salida.\n"); return 1; } /* lee hasta encontrar el final del stream */ while(!feof(streami)) { g(); //lee uno por adelantado if(!feof(streami)) { parser(); //putchar(ch); } else break; } fclose(streami); /* close stream */ fclose(streamo); return 0; } int main(void) { makenull(); procesa_archivos(); return 0; }
20-01-2010
19
Tambin es preciso poder extraer resultados, para posterior anlisis, escribindolos en un archivo. Escritura de archivos de texto, con estructura de lneas. Consideremos primero la escritura de archivos de texto con formato. Esto puede lograrse con un editor, siguiendo ciertas convenciones para separar los elementos de datos. Es recomendable ingresar por lneas, y en cada lnea separar los tems mediante espacios o tabs. Es importante saber el nmero y tipos de datos de los tems de cada lnea, ya que debe confeccionarse un string de formato con dicha estructura. En caso de escritura de un archivo, mediante un programa, tambin debe tenerse en cuenta la estructura de la lnea. Veamos un ejemplo. Se tiene un entero y un carcter por lnea, que configuran un dato con la siguiente estructura: struct mystruct { int i; char ch; }; La confeccin con un editor, podra generar el siguiente texto, donde los espacios previos al nmero pueden ser reemplazados por varios espacios o tabs. La separacin entre el nmero y el carcter debe ser un espacio o un tab. Luego pueden existir varios espacios o tabs, seguidos de un retorno. 11 a 22 b 333 c 4d 5e Escritura de archivo, desde un programa. La manipulacin de archivos, requiere la invocacin a funciones de <stdio.h>, para abrir, cerrar, leer o escribir en el archivo. El siguiente segmento abre para escritura el archivo testwr.txt, que debe estar ubicado en el mismo directorio que el programa ejecutable; en caso de otra ubicacin, es preciso preceder el nombre con el sendero de la ruta. El modo w establece modo escritura, es decir sobreescribe si el archivo existe, y lo crea en caso contrario. La variable que permite manipular un archivo es de tipo FILE, y se la define segn: Profesor Leopoldo Silva Bijit 20-01-2010
if ((stream = fopen("testwr.txt", "w")) == NULL) { fprintf(stderr, "No puede abrir archivo de salida.\n"); return 1; } El stream o flujo de salida stderr suele ser la pantalla. La siguiente instruccin escribe en el stream 4 caracteres por lnea, ms el terminador de lnea, eol; que suele ser uno o dos caracteres. La estructura de la lnea: dd<sp>c<eol>. fprintf(stream, "%2d %c\n", s.i, s.ch); Una vez completada la escritura de todas las lneas, se cierra el archivo, mediante: fclose(stream); Lectura de archivos de texto con estructura de lneas. Se incluye un programa para leer el archivo, ya sea generado con un editor o por un programa, mediante la funcin fscanf. Se ha usado la funcin feof, para determinar si se lleg al final del archivo. La accin que se realiza con los datos es simplemente desplegar en la pantalla, los datos formateados. /* Ejemplo con streams. Lectura de archivo de texto formateado */ #include <stdio.h> //El archivo testwr.txt debe estar estructurado en lneas. //Cada lnea debe estar formateada segn: <sep>entero<sep>char<eol> //Donde <sep> pueden ser espacios o tabs. //El entero debe ser de dos dgitos, si en el string de formato del fscanf figura como %2d. FILE *stream; int main(void) { int jj; char cc; /* Abre stream para lectura, en modo texto. */ if ((stream = fopen("testwr.txt", "r")) == NULL){ fprintf(stderr, "No pudo abrir archivo de entrada.\n"); return 1; } /* lee hasta encontrar el final del stream */ Profesor Leopoldo Silva Bijit 20-01-2010
21
for(;;) { fscanf(stream, "%d %c", &jj, &cc); //lee variables segn su tipo y estructura de lnea. if(feof(stream)) break; printf("%d %c\n", jj, cc); //slo muestra las lneas del archivo } fclose(stream); /* close stream */ return 0; } Si se intenta leer ms all del fin de archivo la funcin feof, retorna verdadero. Llenar un arreglo a partir de un archivo. El siguiente ejemplo llena un arreglo de estructuras. /* Ejemplo con streams. Con datos de archivo se escribe un arreglo */ #include <stdio.h> //El archivo testwr.txt debe estar estructurado en lineas. //Cada linea debe estar formateada segn: <sep>entero<sep>char<eol> //Donde <sep> pueden ser espacios o tabs. //El entero debe ser de dos dgitos, si en el string de formato del fscanf figura como %2d. struct mystruct { int i; char ch; }; #define ITEMS 20 struct mystruct arr[ITEMS]; FILE *stream; int main(void) { int i, jj; char cc; /* Abre stream para lectura, en modo texto. */ if ((stream = fopen("testwr.txt", "r")) == NULL) { fprintf(stderr, "No pudo abrir archivo de entrada.\n"); return 1; } for(i=0; i< ITEMS; i++) { fscanf(stream, "%d %c", &jj, &cc); //lee variables segn tipo. if(feof(stream)) break; arr[i].i=jj; arr[i].ch=cc; //llena items del arreglo } Profesor Leopoldo Silva Bijit 20-01-2010
for(i=0;i< ITEMS;i++) { printf("%d %c\n", arr[i].i, arr[i].ch);// muestra el arreglo } return 0; } Escritura y lectura de archivos binarios. El siguiente ejemplo, ilustra la escritura y lectura de archivos binarios, no de texto. Se emplean ahora las funciones: fwrite, fseek y fread. * Ejemplo con streams. Escritura y luego lectura de archivo binario */ #include <stdio.h> struct mystruct { int i; char ch; }; int main(void) { FILE *stream; struct mystruct s; int j; /* sobreescribe y lo abre para escritura o lectura en modo binario */ if ((stream = fopen("TEST.bin", "w+b")) == NULL) { fprintf(stderr, "No se puede crear archivo de salida.\n"); return 1; } for(j=0;j<20;j++) { s.i = j; s.ch = 'A'+j; fwrite(&s, sizeof(s), 1, stream); /* write struct s to file */ } /* seek to the beginning of the file */ fseek(stream, SEEK_SET, 0); /* lee y despliega los datos */ Profesor Leopoldo Silva Bijit 20-01-2010
Introduccin a analizadores lxicos for(j=0; j<20;j++) { fread(&s, sizeof(s), 1, stream); printf("%d %c\n", s.i, s.ch); } fclose(stream); /* close file */ return 0; }
23
El archivo TEST.bin, no puede ser visualizado con un editor de texto. Para su interpretacin debe usarse un editor binario. Compilacin y ejecucin en ambiente UNIX. Para programas sencillos, como los ilustrados, puede generarse el ejecutable en ambiente UNIX, mediante el comando: make <nombre de archivo c, sin extensin> Esto crea un ejecutable de igual nombre al programa en C. Para su ejecucin basta escribir su nombre. Escritura y lectura de archivos por lneas. #define LARGOLINEA 80 //mximo largo de lnea igual a 80 caracteres char buffer[LARGOLINEA]; int lee_archivo(void) { FILE *stream; /* Abre stream para lectura, en modo texto. */ if ((stream = fopen("input.txt", "r")) == NULL) { fprintf(stderr, "No pudo abrir archivo de entrada.\n"); return 1; } while(!feof(stream)) /* lee hasta encontrar el final del stream */ { fgets(buffer, LARGOLINEA, stream); //carga buffer if(!feof(stream)) { // Aqu debera procesarse la lnea //printf("%s ", buffer); //muestra las lneas del archivo de entrada } else break; } fclose(stream); /* close stream */ return 0; Profesor Leopoldo Silva Bijit 20-01-2010
24 } int escribe_archivo(void) { FILE *stream; /* Abre stream para escritura, en modo texto. */ if ((stream = fopen("output.txt", "w")) == NULL) { fprintf(stderr, "No pudo crear archivo de salida.\n"); return 1; } // Aqu debera escribirse el el archivo.. //fputs(buffer, stream); imprime lnea //fprintf(stream, "%d\t", 5); salida formateada // fputc('\n', stream); salida caracteres fclose(stream); /* close stream */ return 0; }
Referencias.
Niklaus Wirth, Algorithms + Data Structures = Programs, Prentice-Hall 1975.
20-01-2010
25
ndice general.
APNDICE 3 .............................................................................................................................................. 1 INTRODUCCIN A LA ESTRUCTURA Y OPERACIN DE ANALIZADORES LXICOS. ...... 1 A3.1. ESTRUCTURA DE UN LENGUAJE DE PROGRAMACIN. ...................................................................... 1 A3.2. ANALIZADOR LXICO. (PARSER) ..................................................................................................... 2 A3.3. REGLAS DE ANLISIS. ..................................................................................................................... 4 Smbolo terminal. ................................................................................................................................ 5 Smbolo no terminal. ........................................................................................................................... 5 Alternativa. .......................................................................................................................................... 5 Concatenacin..................................................................................................................................... 6 Repeticin. ........................................................................................................................................... 7 Resumen. ............................................................................................................................................. 8 EJEMPLO A3.1. RECONOCEDOR SIMPLE. ................................................................................................... 8 EJEMPLO A3.2. PARSER BNF. ............................................................................................................... 10 EJEMPLO A3.3. RECONOCEDOR DE IDENTIFICADOR. .............................................................................. 13 EJEMPLO A3.4. RECONOCEDOR DE UNA DEFINICIN. ............................................................................ 15 A3.4. MANIPULACIN DE ARCHIVOS EN C. ............................................................................................. 18 Escritura de archivos de texto, con estructura de lneas. .................................................................. 19 Escritura de archivo, desde un programa. ........................................................................................ 19 Lectura de archivos de texto con estructura de lneas. ..................................................................... 20 Llenar un arreglo a partir de un archivo. ......................................................................................... 21 Escritura y lectura de archivos binarios. .......................................................................................... 22 Compilacin y ejecucin en ambiente UNIX. .................................................................................... 23 Escritura y lectura de archivos por lneas. ....................................................................................... 23 REFERENCIAS. ........................................................................................................................................ 24 NDICE GENERAL. ................................................................................................................................... 25 NDICE DE FIGURAS................................................................................................................................. 25
ndice de figuras.
FIGURA A3.1. ANLISIS SIN VOLVER ATRS. ................................................................................................ 3 FIGURA A3.2. SMBOLO TERMINAL. .............................................................................................................. 5 FIGURA A3.3. SMBOLO NO TERMINAL. ........................................................................................................ 5 FIGURA A3.4. ALTERNATIVA. ....................................................................................................................... 6 FIGURA A3.5. ALTERNATIVA, CON PRIMER SMBOLO EXPLCITO. ................................................................. 6 FIGURA A3.6. CONCATENACIN. .................................................................................................................. 7 FIGURA A3.7. REPETICIN............................................................................................................................ 7 FIGURA A3.8. REPETICIN, CON PRIMER SMBOLO EXPLCITO. ..................................................................... 7 FIGURA A3.9. GRAFO DEL RECONOCEDOR. ................................................................................................... 8 FIGURA A3.10. ESTADOS DE RECONOCEDOR DE IDENTIFICADOR. ............................................................... 14 FIGURA A3.11. ESTADOS DE RECONOCEDOR DE DEFINICIONES................................................................... 16
20-01-2010