Está en la página 1de 8

Proyecto de Compilador

INTEGRANTES:

* Karim Ghonem Camacho


* David Hurtado
* Oscar Claros

DOCENTE: ING. EGUEZ, CARLOS

GRUPO: A

MATERIA: COMPILADORES

Santa Cruz, Bolivia


2019
1. Introducción

1.1. Analizador Léxico

Un analizador léxico es el componente encargado de identificar los tokens válidos en un código de


entrada y emitir errores de ser necesario, crearemos un analizador léxico basado en expresiones
regulares capaz de detectar números, cadenas, comentarios, operadores, identificadores y palabras
reservadas.

El analizador léxico deberá informar de cada token encontrado, en que linea y columna exactamente fue
extraído el token, ademas del indice del token, el tipo y el lexema que lo representa.

1.2. Objetivo
Es la primera etapa de un compilador, cuyo principal objetivo consiste en leer los caracteres de entrada
y elaborar como salida una secuencia de componentes léxicos que utiliza el analizador sintáctico para
hacer el análisis. Esta interacción, suele aplicarse, para convertir al analizador léxico en una subrutina o
rutina básica de entrada del analizador sintáctico. Recibida la orden “obtener el siguiente componente
léxico” del Analizador Sintáctico, el Analizador Léxico lee los caracteres de entrada hasta que pueda
identificar el siguiente componente léxico.

1.3. Estrategia de desarrollo

1.4. Uso de Expresiones regulares

Para construir el analizador léxico utilizaremos la clase Flex que implementa el motor de expresiones
regulares FlexEngine, este nos permitirá buscar modelos de caracteres o patrones que representan
nuestros tokens admitidos por el analizador léxico, Flex creara el AFN (Autómata Finito No Determinista)
correspondiente a la expresión regular que creemos.

Para especificar los modelos de caracteres admitidos necesitamos conocer el lenguaje de expresiones
regulares.

1.5. Analizador Léxico Basado en Expresiones Regulares

Reglas de Expresiones Regulares para token de Contexto simple:


# Listas para tokens
palabras_reservadas = {
    'if': 'IF',
    'while': 'WHILE',
    'else': 'ELSE',
    'int': 'INT',
    'for': 'FOR',
    'end': 'END',
}

signo = {
    '+': 'SUMA',
    '-': 'RESTA',
    '*': 'MULT',
    '/': 'DIV',
    '=': 'IGUAL',
    ';': 'PUNTOCOMA',
    ':': 'DOSPUNTOS',
    '(': 'PARIZQ',
    ')': 'PARDER',
    '{':'LLAIZQ',
    '}':'LLADER',
    '[':'CORIZQ',
    ']':'CORDER',
    '<':'MENORQUE',
    '>':'MAYORQUE',
    '<=':'MENORIGUAL',
    '>=':'MAYORIGUAL',
    r'!=':'DISTINTO',
    r'"':'COMDOB',
    '&&': 'AND',
    '<>': 'OR',
    '||': 'NOT'
}

tokens = [
    'IDENTIFICADOR',
    'SIGNO',
    'NUMERO',
    'CADENA',
] + list(palabras_reservadas.values()) + list(signo.values())
2. Analizador Sintáctico
Un analizador sintáctico (o parser) es una de las partes de un compilador que transforma su entrada en
un árbol de derivación.

El análisis sintáctico convierte el texto de entrada en otras estructuras (comúnmente árboles), que son
más útiles para el posterior análisis y capturan la jerarquía implícita de la entrada. Un analizador léxico
crea tokens de una secuencia de caracteres de entrada y son estos tokens los que son procesados por el
analizador sintáctico para construir la estructura de datos, por ejemplo un árbol de análisis o árboles de
sintaxis abstracta.

El análisis sintáctico también es un estado inicial del análisis de frases de lenguaje natural. Es usado para
generar diagramas de lenguajes que usan flexión gramatical, como los idiomas romances o el latín. Los
lenguajes habitualmente reconocidos por los analizadores sintácticos son los lenguajes libres de
contexto. Cabe notar que existe una justificación formal que establece que los lenguajes libres de
contexto son aquellos reconocibles por un autómata de pila, de modo que todo analizador sintáctico
que reconozca un lenguaje libre de contexto es equivalente en capacidad computacional a un autómata
de pila.

Los analizadores sintácticos fueron extensivamente estudiados durante los años 70 del siglo XX,
detectándose numerosos patrones de funcionamiento en ellos, cosa que permitió la creación de
programas generadores de analizadores sintáticos a partir de una especificación de la sintaxis del
lenguaje en forma Backus-Naur por ejemplo, tales como yacc, GNU bison y javaCC.

2.1 Objetivos
Como se explicó anteriormente es la primera etapa de un compilador para esto se plantearon los
siguientes objetivos:

 Buscar componentes léxicos según los pragmas


 Reconocer los símbolos terminales, no terminales, reglas de producción y axioma inicial
 Definir la entrada de caracteres en tokens, lexemas.
 Definir las reglas de gramática libre de contexto.
 Realizar la tabla de transiciones.

2.2 Alcance
Como se definió previamente en esta etapa solo podrá reconocer de un código fuente una secuencia de
caracteres y poder producir una salida compuesta de tokens( componentes léxicos) o símbolos además
de a través de la tabla realizar el análisis sintáctico.
2.3 Identificación de lenguaje fuente
El lenguaje fuente a analizar Python.

2.4 Identificación de lenguaje de construcción


El lenguaje en el que se realizó el analizador es el Python.

Fue seleccionado por sus propiedades de lenguaje además de que se tiene un conocimiento amplio en
este lenguaje que es superior a cualquier otro lenguaje hablando personalmente.

2.5 Estrategia de desarrollo


2.6 Uso de librerías YACC
Para el análisis sintáctico hacemos uso de la herramienta YACC (Yet Another Compiler
Compiler). El cual nos permite definir las reglas sintácticas para su posterior análisis, además
que esta herramienta realiza el análisis semántico de forma paralela

2.7 Analizador Sintáctico


2.2.1 Declaracion terminales
Rule 0 S' -> statement
Rule 1 statement -> NAME EQUALS expression
Rule 2 statement -> expression
Rule 3 expression -> expression PLUS expression
Rule 4 expression -> expression MINUS expression
Rule 5 expression -> expression TIMES expression
Rule 6 expression -> expression DIVIDE expression
Rule 7 expression -> MINUS expression
Rule 8 expression -> LPAREN expression RPAREN
Rule 9 expression -> NUMBER
Rule 10 expression -> NAME

2.2.8 Conclusión
Se realizó con éxito un analizador léxico y sintáctico, el cual puede definir los diferentes tipos de datos
dado un código fuente obtenido por un archivo .txt y nos da el resultado en otro archivo .txt con todo el
análisis correspondiente.
3. Analizador Semantico
La fase de análisis semántico revisa el programa fuente para tratar de encontrar errores semánticos y
reúne la información sobre los tipos para la fase posterior de generación de código. En ella se utiliza la
estructura jerárquica determinada por la fase de análisis sintáctico para identificar los operadores y
operandos de expresiones y proposiciones.

Un componente importante del análisis semántico es la verificación de tipos. Aquí, el compilador verifica
si cada operador tiene operandos permitidos por la especificación del lenguaje fuente. Por ejemplo, las
definiciones de muchos lenguajes de programación requieren que el compilador indique un error cada
vez que se use un número real como índice de una matriz. Sin embargo, la especificación del lenguaje
puede imponer restricciones a los operandos, por ejemplo, cuando un operador aritmético binario se
aplica a un número entero y a un número real.3 Revisa que los arreglos tengan definido el tamaño
correcto.

3.1. Tabla de funciones


4. def p_expresion_operaciones(t):
5.     '''
6.     expresion  : expresion SUMA expresion
7.                | expresion RESTA expresion
8.                | expresion MULT expresion
9.                | expresion DIV expresion
10.    '''
11.

12.    verificador= True
13.    if(isinstance(t[1],int)):
14.        if(isinstance(t[3],int)):
15.            pass
16.        elif(isinstance(t[3],float)):
17.            pass
18.        elif(isinstance(t[3],str)):
19.            print("Error combinacion de entero con string no valido")
20.            verificador=False
21.    elif(isinstance(t[1],float)):
22.        if(isinstance(t[3],int)):
23.            pass
24.        elif(isinstance(t[3],float)):
25.            pass
26.        elif(isinstance(t[3],str)):
27.            print("Error combinacion de flotante con string no valido")
28.            verificador=False
29.    elif(isinstance(t[1],str)):
30.        if(isinstance(t[3],int)):
31.            print("Error comb str y int no valideishon")
32.            verificador=False
33.        elif(isinstance(t[3],float)):
34.            print("Error combinacion de string con flotante no valido")
35.            verificador=False
36.        elif(isinstance(t[3],str)):
37.            pass
38.    else:
39.        verificador=False
40.        print("Permutacion no Valida")
41.

42.    if(verificador):
43.        if t[2] == '+':
44.            t[0] = t[1] + t[3]
45.        elif t[2] == '-':
46.            t[0] = t[1] - t[3]
47.        elif t[2] == '*':
48.            t[0] = t[1] * t[3]
49.        elif t[2] == '/':
50.            t[0] = t[1] / t[3]
51.        elif t[2] == '%':
52.            t[0] = t[1] % t[3]
53.        elif t[2] == '**':
54.            i = t[3]
55.            t[0] = t[1]
56.            while i > 1:
57.                t[0] *= t[1]
58.                i -= 1

Anexos

● Motivos por lo cual mi compilador no traduce y es un interpretador

■ Debe tener instalado y configurado Python 3.7.4

■ Descargar la herramienta PLY

■ Este compilador no puede traducir; por que tenemos una retracción de la

herramienta por que no se puede seguir a la herramienta de recursión


Viéndolo como un árbol el parser como un des compositor de las parte

libera un punto en ves de tener el nombre de la variable tendrás

directamente el valor y si lo pones en la parte inferior del arbol para obtener

nombre de la variable no se puede subir la solución es ponerlo en la punta

pero uno se limita a que no puede tener nombre de la variable

También podría gustarte