Vous êtes sur la page 1sur 18

Dada la gramtica regular (Tipo-3) iniciada en clase, la cual define al analizador lexicogrfico de nuestro lenguaje uami, concluya de tal

manera que el analizador lexicogrfico indique a las siguientes palabras o grupos de palabras, conforme se estipula a continuacin: 1.- Incluir en la regla de produccin que reconoce a los espacios en blanco (<eb>) la opcin que permita desechar (brincarse) a los comentarios residentes en todo programa fuente, los cuales inician con el { localizndose en cualquier posicin de una lnea de instruccin; y concluyen hasta el fin de lnea (\n). 2.- modificar a LAS REGLAS DE PRODUCCION NECESARIAS PARA INCLUIR AL GUION BAJO (_) COMO CARACTER VALIDO PARA los identificadores. 3.- Que reconozca a los lexemas de dos caracteres (operadores log, y relacionales). 4.- Que identifique a los lexemas de un solo carcter como se indica a continuacin (operadores log, y relacionales). 5.- Debe reconocer a las cadenas delimitadas entre comillas (). 6.- El analizador lexicogrfico deber regresar (indicar) el carcter que no caiga en ninguno de los grupos de cadenas, conforme al conjunto de reglas de produccin que lo definen. 7.- el compilador uami ser uno que se ejecute por comando de lnea. Todo el programa fuente expresado en el lenguaje uami se guardara en un archivo ASCII, con extensin fte; y ser proporcionado su nombre al compilador al momento de compilar; ejemplo: c:\> uami factorial.fte 8.- recuerde que debe codificar y compilar cada uno de los dems archivos fuente que conforman a nuestro compilador uami final, tales como: uami.c, global.h, init.c, symbol.c, adems del propio lxico 9.- por el momento, el archivo fuente uami.c contendr por ahora el cdigo necesario para iniciar el ambiente de compilacin (tal como cargar a la tabla de smbolos con las palabras reservadas, etc.); adems de que utilizara en ciclo (loop) para invocar al analizador lexicogrfico (lxico), para analizar as todo un programa fuente de usuario. 10.- Se deber generar un archivo ASCII en disco duro, el cual tendr el mismo nombre del programa fuente de usuario (archivo con extensin fte), pero que terminara con la extensin .tal, en el cual se guardara cada una de las tulpas (VALOR, TIPO) que el analizador lexicogrfico encuentre en tal programa fuente. Cada tupla debe utilizar solo una lnea del archivo tal.

11.- Se deber generar un archivo ASCII en disco duro, el cual tendr el mismo nombre que el nombre del programa fuente de usuario (archivo con extensin fte), pero que terminara con la extensin err, en el cual se guardara, por el momento, una copia fiel del programa de usuario. 12.13.- Proporcione la definicin completa de la Gramtica tipo-3 (gramtica regular), la cual define al Analizador Lexicogrfico. No olvide incluir el alfabeto, ni ninguna de las tulpas (conjuntos) de tal Gramtica-Regular.

A.Lex: G3=(V,T,P,S) Dado suma(uami)={cdigo ASCII de los caracteres disponibles en el teclado de PC} V={<alex>,<eb>,<delim>,<digito>,<num_ent>,<letra>,<id>,<op_arit>,<op_log_am_pp>,<op_rel_as_ad>} T={Todos los nombres de variables de longitud arbitraria que inicien con letra o digito, las 18 palabras reservadas (program, begin, end, if, then, else,...), +, -, *, /} U %, >, >=, ==, <, <=, <>, !=, &&, ||, {El cdigo ASCII que representa a cada uno de los caracteres disponibles en el teclado de una computadora digital}. P: <eb> <delim>+ <delim> b | \t | \n <digito> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 <num_ent> <digito>+ <num_flo> ( . | <digito>+) <letra> a | | z | A | | Z <id> <letra>(<letra> | <digito>)* <op_arit> + | - | * | / | % <op_log_am_pp> & ( & | & ) | | (| | |)

<op_rel_as_ad> > | ( = | = ) | < ( = | > | = A >) | ( ! | = )( = | =) <alex> <eb> | <num_ent> | <id> | <op_art> | <op_log_am_pp> | <op_rel_as_ad> <eof> EOF S={<alex>}

/**** init.c **********************************************/ #include "global.h" struct entry keywords[] = { "program", PROGRAM,

"if", IF, "then", THEN, "else", ELSE, "do", DO, "while", WHILE, "begin", BEGIN, "end", END, "print", PRINT, "read", READ, "halt", HALT, "dump", DUMP, "div", DIV, "mod", MOD, "repeat", REPEAT, "until",UNTIL, "for", FOR, "to", TO, 0, 0 }; void init () /* loads keywords into symtable */ { struct entry *p; for (p = keywords; p->token; p++) insert(p->lexptr, p->token); } /**** symbol.c ***********************************************/

#include "global.h" //RUTINAS DE LA TABLA DE SIMBOLOS #define STRMAX 999

#define SYMMAX 100 static struct entry symtable[SYMMAX]; // RECORDAR: struct entry ESTA EN EL ARCHIVO "global.h". ESTO ES UNA DEFINICION DE LA TABLA DE SIMBOLOS. int lastentry = 0; /*last used position in symtable (ULTIMA POSICION USADA EN LA TABLA DE SYMTABLE) */ int lookup(char *s) /* returns position of entry for s (DEVUELVE LA POSICION DE LA ENTRADA DE S) */ //lookup=BUSQUEDA { int p; for (p = lastentry; p > 0; p = p - 1){ if (strcmp(symtable[p].lexptr, s) == 0) // CADA UNO ES UN APUNTADOR A UNA CADENA (symtable[p].lexptr) Y (S) return p; } return 0; } char * store(char *s) { static char lexemes[STRMAX]; //ALMACENAMIENTO PRIVADO, PARA ALMACENAR LA CADENA int firstchar; /* next free entry in lexemes (PROXIMA ENTRADA LIBRE EN LEXEMAS)*/ static int lastchar = -1; /* last used entry in lexemes (ULTIMA ENTRADA UTILIZADA EN LEXEMAS)*/ firstchar = ++lastchar; lastchar += strlen(s); //NO CONSIDERA A '\0' COMO UN CARACTER AL SACAR LA LONGITUD... strlen=nos da la longitid de uan cadena if (lastchar >= STRMAX) error("lexemes array ..."); strcpy(&lexemes[firstchar], s); //COPIA UNA CADENA DE CARACTERES EN ESTE CASO DE s SE COPIA A &lexemes[firstchar] return &lexemes[firstchar]; } int insert(char *s, int * tok) /*returns position of entry for s (DEVUELVE LA POSICION DE ENTRADA DE s) */ { if (++lastentry >= SYMMAX)

error("symbol table full"); symtable[lastentry].token = tok; // token=MUESTRA symtable[lastentry].lexptr = store(s); //store=ALMACENAR return lastentry; } void puttoken(int i, int newtoken) { symtable[i].token=newtoken; } int gettoken(int i) //obtiene la muestra { return symtable[i].token; } char* getsym(i) int i; { return (symtable[i].lexptr); } void printsyms() { if (lastentry) { int i; printf("\n\n Symbol Table Contents\n Name Value\n"); for (i=1; i<=lastentry; i++) printf("%10.10s %6d\n", getsym(i), gettoken(i) ); } }

/****** a_lex ******************************/ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include "global.h" #define blanco ' ' #define tabulador '\t' #define salto_linea '\n' int lineno = 1; int lookup(char *); int insert(char * , int ); int gettoken( int ); int alex(){ int i=0; char c; c = fgetc(pf); char valor_id[20], tokenvalcad[100]; int posicin; /*******************************************RECONOCIMIENTO DE METAPALABRAS**********************/ while(c == blanco || c == tabulador || c == salto_linea || c == '{'){ if(c == '{'){ //LECTURA DE COMENTARIOS do{ c = fgetc(pf); }while(c != '\n'); }

if(c == '\n') lineno++; c = getc(pf); } /****************************************** FIN DE ARCHIVO *************************************************/ if(c == EOF ) return DONE; /*******************************************RECONOCIMIENTO DE CANTIDADES NUMERICAS****************************/ if(c == '.'){ char aux1[10]; i=0; aux1[i] = c; c = fgetc(pf); i++; while(isdigit(c)){ aux1[i] = c; c = fgetc(pf); i++; } aux1[i] = '\0'; strcpy(tokenvalf,aux1); ungetc(c,pf); return NUM_FLT; } if(isdigit(c)){ char aux[10]; i=0; ungetc(c,pf); c = fgetc(pf); //RECONOCIMIENTO DE FLOTANTES QUE INICIAN CON PUNTO DECIMAL

//lectura de los digitos siguientes al punto decimal

//RECONOCIMIENTO DE FLOTANTES Y ENTEROS

aux[i] = c; i++; while(isdigit(c)){ //ciclo para determinar o descartar un punto decimal c = fgetc(pf); aux[i] = c; i++; } if( c == '.'){ //SE RECONOCE LOS FLOTANTES CON EL PUNTO DECIMAL EN CUALQUIR LUGAR EXEPTO AL INICIO c = fgetc(pf); aux[i]=c; i++; c=fgetc(pf); while(isdigit(c)){ //se leen los sigientes digitos despues del punto decimal aux[i]=c; i++; c=fgetc(pf); } aux[i]='\0'; strcpy(tokenvalf,aux); //se copia la cadena del numero flotante en tokenvalef ungetc(c,pf); return NUM_FLT; }else{ tokenval = atoi(aux); // se hace una conversion de cadena a numero entero ungetc(c,pf); return NUM_ENT; } } /****************************************RECONOCIMIENTO DE ID's*************************************/ if(isalpha(c)){ i = 0; while(isalnum(c) || c == '_'){

valor_id[i]=c; c=fgetc(pf); i++; } fflush(stdin); //limpiesa de arreglo valor_id[i] = '\0'; ungetc(c, pf); posicin = lookup(valor_id); //se busca la posicin de la palabra en caso de existir en la tabla de smbolos if(posicin == 0) posicin = insert(valor_id, ID); //se inserta una nueva palabra en la tabla de smbolos tokenval = posicion; return (gettoken(posicion)); } /**************************************RECONOCIMIENTO DE OPERADORES LOGIGOS*************************/ if(c == '<' || c == '>' || c == '!' || c == '='){ if(c == '<'){ //lectura de caracteres <, <= tokenval = LT; c = fgetc(pf); if(c == '=') tokenval = LE; } else{ if(c == '!'){ //lectura de caracter != c = fgetc(pf); if(c == '=') tokenval = NE; } else{ if(c == '>'){ //lectura de caracteres >, >= tokenval = GT; c = fgetc(pf); if(c == '=')

tokenval = GE; } else{ if(c == '='){ //lectura de caracteres =, == tokenval = NONE; c = fgetc(pf); if(c == '=') tokenval = EQ; else return BECOMES; } } } } return RELOP; } /*******************************RECONOCIMIENTO DE OPERADORES RELACIONALES*********************************/ if(c == '|' || c == '&'){ //lectura de caracteres &&, || if(c == '|'){ c = fgetc(pf); if(c == '|'){ tokenval = OR; return ADDOP; }else error("error de compilacin"); //manda un error en caso de encontrar otra cosa que no se a un || } if(c == '&'){ c = fgetc(pf); if(c == '&'){ tokenval = AND; return MULOP;

}else error("error de compilacin"); } } /******************************RECONOCIMIENTO DE OPERADORES ARITMETICOS*********************************/ switch(c){ case '+' : tokenval = PLUS; return ADDOP; break; case '-' : tokenval = MINUS; return ADDOP; break; case '*' : tokenval = TIMES; return MULOP; break; case '/' : tokenval = DIV; return MULOP; break; case '%' : tokenval = MOD; return MULOP; break; } /*************************************RECONOCIMIENTO DE CADENAS***************************/ if(c == '"'){ int aux1; //cadena auxiliar para guardar cada uno de los caracteres que estan dentro de las comillas i = 0; //manda un error en caso de encontrar otra cosa que no se a un &&

tokenvalcad[i] = c; c = fgetc(pf); while(c != '"'){ if(c != EOF){ tokenvalcad[i] = c; c = fgetc(pf); i++; }else return error("error de compilacin"); } tokenvalcad[i] = EOS; aux1=lookup(tokenvalcad); if (aux1==0) aux1=insert(tokenvalcad,STRING); //Insertando en tabla de smbolos tokenval=aux1; return STRING; } tokenval = NONE; //VALOR DEL FIN DE ARCHIVO return (toascii(c)); //RECONOCIMIENTO DE TODO EL MUMDO } #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include "global.h" int main(int argc, char *argv[]){ int t=0; char caracter; FILE* tulpas, *copia;

char* v = "pruebas.tpl"; /*********************************CREACION DEL ARCHIVO .err *************************/ char w[10]; strcpy(w,argv[1]); while( w[t] != '.') t++; if( w[t] == '.' ){ t++; if(w[t] == 'f' ){ t++; if( w[t] == 't'){ t++; if( w[t] == 'e'){ t++; if( w[t] == '\0'){ t = t-3; w[t] = 'e'; t++; w[t] = 'r'; t++; w[t] = 'r'; }else{ printf("Este archivo no puede ser leido\n"); return 0; } }else{ printf("Este archivo no puede ser leido\n"); return 0; } }else{ printf("Este archivo no puede ser leido\n"); return 0; } }else{ printf("Este archivo no puede ser leido\n"); return 0;

} } if( w[t] == '\0'){ printf("Este archivo no puede ser leido\n"); return 0; } pf = fopen(argv[1], "r"); tuplas = fopen(v, "w"); init(); /******************************** IMPRESION DE TUPLAS EN ARCHIVO .TPL **********/ while((t = alex()) != DONE){ if (((t > 255 && t < 276) && t != 262 && t != 260) || t == 502 || t == 503) fprintf(tuplas,"(%s,%d)\n",getsym(tokenval),t); else { if(t == 276) fprintf(tuplas, "(%s, %d)\n",tokenvalf,t); else fprintf (tuplas, "(%d, %d)\n",tokenval,t); } } fprintf(tuplas, "(%d,%d)", tokenval, t); close(pf); fclose(tulpas); /********************************** COPIA DE ARCHIVO FUENTE *******************/ pf = fopen(argv[1], "r"); copia = fopen(w, "w"); do{ caracter = fgetc(pf);

fputc(caracter, copia); }while(caracter != EOF); close(pf); fclose(copia); printsyms(); //impresion de tabla de smbolos printf("\nSE HA CREADO LA COPIA DEL ARCHIVO FUENTE\n\n"); return 0; }

/**** global.h #include<stdio.h> #include<ctype.h> #include<stdlib.h> #define NONE #define EOS

*********************************************/ /* load i/o routines */ /* load character test routines (RUTINAS DE CARGA DE PRUEBA DE CARACTER) */ -1 '\0'

/* lexical tokens */ #define PROGRAM 256 #define BEGIN 257 #define END 258 #define DONE 259 #define BECOMES #define ID #define NUM_ENT #define STRING #define IF 264 #define THEN 265

260 261 262 263

#define #define #define DO #define #define #define #define #define #define #define #define

ELSE 266 WHILE 268 PRINT269 DUMP270 HALT 271 REPEAT UNTIL FOR TO NUM_FLT

267

272 273 274 275 276

/* lexical tokens and values for operations (MUESTRA LOS LEXICOS Y VALORES PARA OPERACIONES) */ #define RELOP 300 #define LT 301 #define LE 302 #define EQ 303 #define GE 304 #define GT 305 #define NE 306 #define ADDOP 400 #define PLUS 401 #define MINUS 402 #define OR 403 #define MULOP 500 #define TIMES 501 #define DIV 502 #define MOD 503 #define AND 504 /* symbols used by the emitter (SIMBOLOS UTILIZADOS POR EL EMISOR) */ #define LVALUE 901 #define RVALUE 902

#define PUSH 903 #define ASSIGN #define READ #define WRITE #define LABEL #define GOTO #define GOTRUE #define GOFALSE char tokenvalf[10]; int tokenval; FILE* pf;

904 905 906 907 908 909 910

struct entry { char *lexptr; int token; };

Vous aimerez peut-être aussi