/* Compilador del Lenguaje Micro (Fischer) */ #include <stdio.h> #include <string.h> #include <ctype.h>

Documentos relacionados
/**********************Prototipos de ciones************************/ TOKEN scanner(); int columna(int c);

DEFINICIÓN FORMAL DE UN AFP

Diagrama de transiciones del autómata. Tabla de transiciones

Estructuras de Datos Declaraciones Tipos de Datos

Algoritmo, Estructuras y Programación I Ing. Marglorie Colina

Sintaxis de C Ing. Jose Maria Sola Dr. Oscar Ricardo Bruno

Tema 05: Elementos de un programa en C

Analizador Léxico en ANSI C

Tipos de Datos en C. Palabras reservadas en C

Introducción a la Programación

Elementos de un programa en C

Variables. Una variable no es más que un nombre simbólico que identifica una dirección de memoria: vs.

domingo, 24 de agosto de :28 a.m.

Algoritmos y Estructuras de Datos Ingeniería en Informática, Curso 2º SEMINARIO DE C Sesión 1

8- LEX-Expresiones regulares

Descripción de un Programa

Introducción al lenguaje C

Lenguaje de Programación: C++ ARCHIVOS I/O

Programación Estructurada

Lenguaje C. República Bolivariana de Venezuela Fundación Misión Sucre Aldea Fray Pedro de Agreda Introducción a la Programación III

COMPILADORES ANALIZADOR SINTÁCTICO

Programación estructurada (Introducción a lenguaje C)

Práctica 1: Intérprete de mandatos. Sistemas Operativos Área de Arquitectura y Tecnología de Computadores

Fundamentos de programación

Tema 5 Tabla de Símbolos

Lenguaje C Elementos de un Programa. Ing. Hugo Fdo. Velasco Peña Universidad Nacional 2006

Todo programa en 'C' consta de una o más funciones, una de las cuales se llama main.

PROGRAMACION ESTRUCTURADA: Tema 1. El lenguaje de programación C

Lección 2 Introducción al lenguaje C

Se guardan en archivos con extencion c y los cabezales con extension h

TEMA 2. EL LENGUAJE C. ELEMENTOS BÁSICOS

Laboratorio de Arquitectura de Redes. Introducción al lenguaje C

Lenguaje de programación C. Introducción

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Uso avanzado de punteros

Archivos & Cadenas CURSO DE PROGRAMACIÓN EN C. Centro de Investigación y de Estudios Avanzados del IPN. CINVESTAV - Tamaulipas.

Introducción al Lenguaje de Programación C

Universidad Autónoma del Estado de México 2016, Año del 60 Aniversario de la Universidad Autónoma del Estado de México

Programación I Funciones

PRÁCTICA. Apellidos, Nombre: Calificación:

Tema 13: Apuntadores en C

Programación Básica Estructuras de Datos y Funciones en C

Uso Pseudocódigo Diagrama de flujo Codificación

Introducción a C. Grupo de Sistemas y Comunicaciones. Febrero 2008 C 1. Programación imperativa estructurada.

UNIDAD 1. Algoritmo se define como un conjunto de instrucciones que la computadora debe seguir para resolver un problema.

Programación En Lenguaje C

7.3. Estructura de un programa

INTRODUCCIÓN AL LENGUAJE C

Funciones Definición de función

Universidad de Pamplona Materia: Programación 1 Docente: Ing. Lusbin Raúl Vargas LENGUAJE C ESTRUCTURA DE UN PROGRAMA EN C

Estructuras de Datos Estáticas. Diseñar y programar en lenguaje C soluciones utilizando estructuras de datos estáticas

Teoría de Autómatas y Lenguajes Formales Práctica 4

Introducción al lenguaje C

Elementos léxicos del lenguaje de programación C

INTRODUCCIÓN AL LENGUAJE C++

Examen Principios de Programación Febrero 2012

LENGUAJE. Tema 2 Elementos de un programa

Analizador Léxico. Programación II Margarita Álvarez. Analizador Léxico - Funciones

ANEXO XVII DE LA RESOLUCION N

Es un lenguaje estructurado, tiene una abundante cantidad de operadores y tipos de datos.

UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA FACULTAD DE CIENCIAS PRACTICA DE PROCESOS HERRAMIENTAS

Taller de Sistemas Operativos Introducción

Introducción a los generadores de analizadores léxicos y sintácticos FLEX y BISON: Implementación de una pequeña calculadora

Archivos en lenguaje C

Ejercicios de la sesión 4 de C resueltos

Tema 2: Análisis léxico

Curso de Introducción a C en Plan 9

EDITRAN/TR. Windows/Unix. Manual de referencia

PROGRAMACION / Clave: 11214

Tema ADQUISICIÓN Y TRATAMIENTO DE DATOS. Departamento de Ciencias de la Computación e IA. Subprogramas en C

LENGUAJE. Tema 1 - Introducción

Codificación en C. Como pasar de Pseudocódigo a C (con pequeños trucos de C++)

TEORÍA. definition TAG. PROPERTIES ID expr EXTENDS ID FIN_TAG. DELAYED : expr

Por ejemplo, para declarar un arreglo de enteros llamado a con diez elementos se hace de la siguiente forma:

Listas. Rafael Palacios May/2005

UTN FRBA Algoritmos y Estructura de Datos Examen Final 18/07/2014. Apellido y nombre: Legajo: Cursó con Prof:

Estructura de datos y Programación

Programación en C. Algoritmo y Estructura de Datos. Ing. M. Laura López. Programación en C

Variables. Una variable no es más que un nombre simbólico que identifica una dirección de memoria: vs.

Estructura Selectiva Múltiple

OBJETIVOS. Explicar el manejo de archivos de texto. Explicar el manejo de archivos binarios. Desarrollar programas que usen archivos.

Fundamentos de Programación 2017-I

Punteros. Programación en C 1

Introducción a C# y la plataforma.net. Pablo Zaidenvoren 2013

Programación. Test Autoevaluación Tema 3

Unidad III Análisis Léxico. M.C. Juan Carlos Olivares Rojas

Tema 5. Análisis semántico

Introducción a Lenguaje C. Jornadas de Octubre 2009 Grupo de Usuarios de Linux Universidad Carlos III Tania Pérez

Objetivos Que el estudiante logre conocer, comprender y manejar conceptos y técnicas vinculados con el Analizador Léxico, para lo cual debe:

Módulo. = Asignación = = Comp. de igualdad!= Com. de desigualdad <= Comp. menor o igual >= Comp. mayor o igual AND lógico OR lógica.

08 Análisis léxico IV

TEMA 4. ESTRUCTURAS DE CONTROL

Cuales son los tipos de instrucciones que se utilizan en la programación?

Unidad II Fundamentos de C++ M.C. Juan Carlos Olivares Rojas

Realizar el ejercicio anterior utilizando Punteros

Lección 3 Sentencias de control

UTN FRBA Algoritmos y Estructura de Datos Examen Final 13/02/2015. Apellido y nombre: Legajo: Cursó con Prof:

TEÓRICO. 3 Curso de I.T. Informática de Sistemas. Examen de Traductores, Intérpretes y Compiladores. Convocatoria ordinaria de Junio de 2006 er

Java. Introducción a la Programación Orientada a Objetos

Ejercicio Sockets Suma Resta. Descripción

Transcripción:

1 /* Compilador del Lenguaje Micro (Fischer) */ #include <stdio.h> #include <string.h> #include <ctype.h> #define NUMESTADOS 15 #define NUMCOLS 13 #define TAMLEX 32+1 #define TAMNOM 20+1 /******************Declaraciones Globales*************************/ FILE * in; typedef enum INICIO, FIN, LEER, ESCRIBIR, ID, CONSTANTE, PARENIZQUIERDO, PARENDERECHO, PUNTOYCOMA, COMA, ASIGNACION, SUMA, RESTA, FDT, ERRORLEXICO TOKEN; typedef struct char identifi[tamlex]; TOKEN t; /* t=0, 1, 2, 3 Palabra Reservada, t=id=4 Identificador (ver enum) */ RegTS; RegTS TS[1000] = "inicio", INICIO, "fin", FIN, "leer", LEER, "escribir", ESCRIBIR, "$", 99 ; typedef struct TOKEN clase; char nombre[tamlex]; int valor; REG_EXPRESION; char buffer[tamlex]; TOKEN tokenactual; int flagtoken = 0; /**********************Prototipos de Funciones************************/ TOKEN scanner(); // el scanner int columna(int c); int estadofinal(int e); void Objetivo(void); // del PAS void Programa(void); void ListaSentencias(void); void Sentencia(void); void ListaIdentificadores(void); void Identificador(REG_EXPRESION * presul); void ListaExpresiones(void); void Expresion(REG_EXPRESION * presul); void Primaria(REG_EXPRESION * presul); void OperadorAditivo(char * presul); REG_EXPRESION ProcesarCte(void); REG_EXPRESION ProcesarId(void);

2 char * ProcesarOp(void); void Leer(REG_EXPRESION in); void Escribir(REG_EXPRESION out); REG_EXPRESION GenInfijo(REG_EXPRESION e1, char * op, REG_EXPRESION e2); void Match(TOKEN t); TOKEN ProximoToken(); void ErrorLexico(); void ErrorSintactico(); void Generar(char * co, char * a, char * b, char * c); char * Extraer(REG_EXPRESION * preg); int Buscar(char * id, RegTS * TS, TOKEN * t); void Colocar(char * id, RegTS * TS); void Chequear(char * s); void Comenzar(void); void Terminar(void); void Asignar(REG_EXPRESION izq, REG_EXPRESION der); /***************************Programa Principal************************/ int main(int argc, char * argv[]) TOKEN tok; char nomarchi[tamnom]; int l; /***************************Se abre el Archivo Fuente******************/ // verifica errores posibles if ( argc == 1 ) printf("debe ingresar el nombre del archivo fuente (en lenguaje Micro) en la linea de comandos\n"); return -1; // no puso nombre de archivo fuente if ( argc!= 2 ) printf("numero incorrecto de argumentos\n"); return -1; //los argumentos deben ser 2 strcpy(nomarchi, argv[1]); l = strlen(nomarchi); if ( l > TAMNOM ) printf("nombre incorrecto del Archivo Fuente\n"); return -1; // requiere para compilar un archivo de extensión.m archivo.m if ( nomarchi[l-1]!= 'm' nomarchi[l-2]!= '.' ) printf("nombre incorrecto del Archivo Fuente\n"); return -1; if ( (in = fopen(nomarchi, "r") ) == NULL ) printf("no se pudo abrir archivo fuente\n"); return -1;//no pudo abrir archivo /*************************Inicio Compilacion***************************/ Objetivo(); /**************************Se cierra el Archivo Fuente******************/ fclose(in); return 0;

3 /**********Procedimientos de Analisis Sintactico (PAS) *****************/ /**********Procedimientos de Analisis Sintactico (PAS) *****************/ void Objetivo(void) /* <objetivo> -> <programa> FDT #terminar */ Programa(); Match(FDT); Terminar(); void Programa(void) /* <programa> -> #comenzar INICIO <listasentencias> FIN */ Comenzar();//de inicio semántico en caso de corresponder Match(INICIO); ListaSentencias(); Match(FIN); void ListaSentencias(void) /* <listasentencias> -> <sentencia> <sentencia> */ Sentencia(); while ( 1 ) // se repite hasta que retorna al no encontrar sentencia <sentencia> switch ( ProximoToken() ) case ID : case LEER : case ESCRIBIR : Sentencia(); break; default : return; //si no es sentencia termina la funcion // fin del switch // fin del while // fin funcion

4 void Sentencia(void) TOKEN tok = ProximoToken(); REG_EXPRESION izq, der; //typedef struct TOKEN clase; char nombre[tamlex]; int valor; REG_EXPRESION; switch ( tok ) case ID : /* <sentencia> -> ID := <expresion> #asignar ; */ Identificador(&izq); Match(ASIGNACION); Expresion(&der); Asignar(izq, der); //genera instrucción de asignacion Match(PUNTOYCOMA); break; case LEER : /* <sentencia> -> LEER ( <listaidentificadores> ) */ Match(LEER); Match(PARENIZQUIERDO); ListaIdentificadores(); Match(PARENDERECHO); Match(PUNTOYCOMA); break; case ESCRIBIR : /* <sentencia> -> ESCRIBIR ( <listaexpresiones> ) */ Match(ESCRIBIR); Match(PARENIZQUIERDO); ListaExpresiones(); Match(PARENDERECHO); Match(PUNTOYCOMA); break; default : return; void ListaIdentificadores(void) /* <listaidentificadores> -> <identificador> #leer_id COMA <identificador> #leer_id */ TOKEN t; REG_EXPRESION reg; Identificador(&reg); Leer(reg); for ( t = ProximoToken(); t == COMA; t = ProximoToken() ) Match(COMA); Identificador(&reg); Leer(reg);

5 void Identificador(REG_EXPRESION * presul) /* <identificador> -> ID #procesar_id */ Match(ID); *presul = ProcesarId();//rutina semantica void ListaExpresiones(void) /* <listaexpresiones> -> <expresion> #escribir_exp COMA <expresion> #escribir_exp */ TOKEN t; REG_EXPRESION reg; Expresion(&reg); Escribir(reg); for ( t = ProximoToken(); t == COMA; t = ProximoToken() ) Match(COMA); Expresion(&reg); Escribir(reg); void Expresion(REG_EXPRESION * presul) /* <expresion> -> <primaria> <operadoraditivo> <primaria> #gen_infijo */ REG_EXPRESION operandoizq, operandoder; char op[tamlex]; TOKEN t; Primaria(&operandoIzq); for ( t = ProximoToken(); t == SUMA t == RESTA; t = ProximoToken() ) OperadorAditivo(op); Primaria(&operandoDer); operandoizq = GenInfijo(operandoIzq, op, operandoder); *presul = operandoizq; void Primaria(REG_EXPRESION * presul) TOKEN tok = ProximoToken(); switch ( tok ) case ID : /* <primaria> -> <identificador> */ Identificador(presul); break; case CONSTANTE : /* <primaria> -> CONSTANTE #procesar_cte */ Match(CONSTANTE); *presul = ProcesarCte(); break; case PARENIZQUIERDO : /* <primaria> -> PARENIZQUIERDO <expresion> PARENDERECHO Match(PARENIZQUIERDO); Expresion(presul); Match(PARENDERECHO); break; default : return;

void OperadorAditivo(char * presul) /* <operadoraditivo> -> SUMA #procesar_op RESTA #procesar_op */ TOKEN t = ProximoToken(); if ( t == SUMA t == RESTA ) Match(t); strcpy(presul, ProcesarOp()); else ErrorSintactico(t); 6

7 /**********************Rutinas Semanticas******************************/ REG_EXPRESION ProcesarCte(void) /* Convierte cadena que representa numero a entero y construye un registro semantico */ REG_EXPRESION reg; reg.clase = CONSTANTE; strcpy(reg.nombre, buffer); sscanf(buffer, "%d", &reg.valor); return reg; REG_EXPRESION ProcesarId(void) /* Declara ID y construye el correspondiente registro semantico */ REG_EXPRESION reg; Chequear(buffer); //function auxiliar reg.clase = ID; strcpy(reg.nombre, buffer); return reg; char * ProcesarOp(void) /* Declara OP y construye el correspondiente registro semantico */ return buffer; void Leer(REG_EXPRESION in) /* Genera la instruccion para leer */ Generar("Read", in.nombre, "Entera", ""); void Escribir(REG_EXPRESION out) /* Genera la instruccion para escribir */ Generar("Write", Extraer(&out), "Entera", "");

REG_EXPRESION GenInfijo(REG_EXPRESION e1, char * op, REG_EXPRESION e2) /* Genera la instruccion para una operacion infija y construye un registro semantico con el resultado */ REG_EXPRESION reg; static unsigned int numtemp = 1; char cadtemp[tamlex] ="Temp&"; char cadnum[tamlex]; char cadop[tamlex]; if ( op[0] == '-' ) strcpy(cadop, "Restar"); if ( op[0] == '+' ) strcpy(cadop, "Sumar"); sprintf(cadnum, "%d", numtemp); numtemp++; strcat(cadtemp, cadnum); if ( e1.clase == ID) Chequear(Extraer(&e1)); if ( e2.clase == ID) Chequear(Extraer(&e2)); Chequear(cadTemp); Generar(cadOp, Extraer(&e1), Extraer(&e2), cadtemp); strcpy(reg.nombre, cadtemp); return reg; 8

9 /***************Funciones Auxiliares**********************************/ void Match(TOKEN t) if (!(t == ProximoToken()) ) ErrorSintactico(); flagtoken = 0; TOKEN ProximoToken() if (!flagtoken ) tokenactual = scanner(); if ( tokenactual == ERRORLEXICO ) ErrorLexico(); flagtoken = 1; if ( tokenactual == ID ) Buscar(buffer, TS, &tokenactual); return tokenactual; void ErrorLexico() printf("error Lexico\n"); void ErrorSintactico() printf("error Sintactico\n"); void Generar(char * co, char * a, char * b, char * c) /* Produce la salida de la instruccion para la MV por stdout */ printf("%s %s%c%s%c%s\n", co, a, ',', b, ',', c); char * Extraer(REG_EXPRESION * preg) /* Retorna la cadena del registro semantico */ return preg->nombre;

10 int Buscar(char * id, RegTS * TS, TOKEN * t) /* Determina si un identificador esta en la TS */ int i = 0; while ( strcmp("$", TS[i].identifi) ) if (!strcmp(id, TS[i].identifi) ) *t = TS[i].t; return 1; i++; return 0; void Colocar(char * id, RegTS * TS) /* Agrega un identificador a la TS */ int i = 4; while ( strcmp("$", TS[i].identifi) ) i++; if ( i < 999 ) strcpy(ts[i].identifi, id ); TS[i].t = ID; strcpy(ts[++i].identifi, "$" );

11 void Chequear(char * s) /* Si la cadena No esta en la Tabla de Simbolos la agrega, y si es el nombre de una variable genera la instruccion */ TOKEN t; if (!Buscar(s, TS, &t) ) Colocar(s, TS); Generar("Declara", s, "Entera", ""); void Comenzar(void) /* Inicializaciones Semanticas */ void Terminar(void) /* Genera la instruccion para terminar la ejecucion del programa */ Generar("Detiene", "", "", ""); void Asignar(REG_EXPRESION izq, REG_EXPRESION der) /* Genera la instruccion para la asignacion */ Generar("Almacena", Extraer(&der), izq.nombre, ""); /**************************Scanner************************************/ TOKEN scanner() int tabla[numestados][numcols] = L D + - ( ), ; : = EOF OTRO 0 1, 3, 5, 6, 7, 8, 9, 10, 11, 14, 13, 0, 14, 1 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ID 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 3 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 CTE 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 5 + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 6-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7 ( 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 8 ) 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 10 ; 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 11 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 14, 14, 14, 12 ASIG 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13 fdt 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 Err 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 ; int car; int col;

12 int estado = 0; int i = 0; do car = fgetc(in); col = columna(car); estado = tabla[estado][col]; if ( col!= 11 ) //si es espacio no lo agrega al buffer buffer[i] = car; i++; while (!estadofinal(estado) &&!(estado == 14) ); buffer[i] = '\0'; //complete la cadena switch ( estado ) case 2 : if ( col!= 11 ) //si el carácter espureo no es blanco ungetc(car, in); // lo retorna al flujo buffer[i-1] = '\0'; return ID; case 4 : if ( col!= 11 ) ungetc(car, in); buffer[i-1] = '\0'; return CONSTANTE; case 5 : return SUMA; case 6 : return RESTA; case 7 : return PARENIZQUIERDO; case 8 : return PARENDERECHO; case 9 : return COMA; case 10 : return PUNTOYCOMA; case 12 : return ASIGNACION; case 13 : return FDT; case 14 : return ERRORLEXICO; return 0; int estadofinal(int e) if ( e == 0 e == 1 e == 3 e == 11 e == 14 ) return 0; return 1;

int columna(int c) if ( isalpha(c) ) return 0; if ( isdigit(c) ) return 1; if ( c == '+' ) return 2; if ( c == '-' ) return 3; if ( c == '(' ) return 4; if ( c == ')' ) return 5; if ( c == ',' ) return 6; if ( c == ';' ) return 7; if ( c == ':' ) return 8; if ( c == '=' ) return 9; if ( c == EOF ) return 10; if ( isspace(c) ) return 11; return 12; /*************Fin Scanner**********************************************/ 13