martes, 21 de febrero de 2017

analisis semántico, sintactico

Análisis semántico

Se compone de un conjunto de rutinas independientes, llamadas por los analizadores morfológico y sintáctico.
El análisis semántico utiliza como entrada el árbol sintáctico detectado por el análisis sintáctico para comprobar restricciones de tipo y otras limitaciones semánticas y preparar la generación de código.
En compiladores de un solo paso, las llamadas a las rutinas semánticas se realizan directamente desde el analizador sintáctico y son dichas rutinas las que llaman al generador de código. El instrumento más utilizado para conseguirlo es la gramática de atributos.
En compiladores de dos o más pasos, el análisis semántico se realiza independientemente de la generación de código, pasándose información a través de un archivo intermedio, que normalmente contiene información sobre el árbol sintáctico en forma linealizada (para facilitar su manejo y hacer posible su almacenamiento en memoria auxiliar).
En cualquier caso, las rutinas semánticas suelen hacer uso de una pila (la pila semántica) que contiene la información semántica asociada a los operandos (y a veces a los operadores) en forma de registros semánticos.

Las reglas semánticas vienen dadas en función de los atributos de los demás símbolos que componen la regla.
La evaluación de las reglas semánticas puede generar código, guardar información en una tabla de símbolos, emitir mensajes de error o realizar otras actividades. La traducción de la cadena de componentes léxicos es el resultado obtenido al evaluar las reglas semánticas.La evaluación de las reglas semánticas define los valores de los atributos en los nodos del árbol de análisis sintáctico para la cadena de entrada. 


Expresiones de tipos
El tipo de una construcción de un lenguaje se denotará mediante una “expresión de tipo”. De manera informal, una expresión de tipo es, o bien un tipo básico o se forma aplicando un operador llamado constructor de tipos a otras expresiones de tipos. 
Cada lenguaje de programación requerirá unas expresiones de tipos adecuadas a sus características. 
Expresiones de tipos más comunes:
• Tipos simples: Son expresiones de tipos los tipos simples del lenguaje, y algunos tipos especiales: 
 integer
 real
 char
 boolean
 void
 error

Análisis sintactico

Es la fase del analizador que se encarga de chequear el texto de entrada en base a una gramática dada. Y en caso de que el programa de entrada sea válido, suministra el árbol sintáctico que lo reconoce. En teoría, se supone que la salida del analizador sintáctico es alguna representación del árbol sintáctico que reconoce la secuencia de tokens suministrada por el analizador léxico. En la práctica, el analizador sintáctico también hace: • Acceder a la tabla de símbolos (para hacer parte del trabajo del analizador semántico). • Chequeo de tipos ( del analizador semántico). • Generar código intermedio. • Generar errores cuando se producen. En definitiva, realiza casi todas las operaciones de la compilación. Este método de trabajo da lugar a los métodos de compilación dirigidos por sintaxis.

Funciones
  • Aceptar lo que es válido sintácticamente y rechazar lo que no lo es.
  • Hacer explícito el orden jerárquico que tienen los operadores en el lenguaje de que se trate. Por ejemplo, la cadena A/B*C es interpretada como (A/B)*C en FORTRAN y comoA/(B*C) en APL.
  • Guiar el proceso de traducción (traducción dirigida por la sintaxis).

CLASIFICACIÓN:

La tarea esencial de un analizador es determinar si una determinada entrada puede ser derivada desde el símbolo inicial, usando las reglas de una gramática formal, y como hacer esto, existen esencialmente dos formas:
  • Analizador sintáctico descendente (Top-Down-Parser): un analizador puede empezar con el símbolo inicial e intentar transformarlo en la entrada, intuitivamente esto sería ir dividiendo la entrada progresivamente en partes cada vez más pequeñas, de esta forma funcionan los analizadores LL, un ejemplo es el javaCC.
  • Analizador sintáctico ascendente (Bottom-Up-Parser): un analizador puede empezar con la entrada e intentar llegar hasta el símbolo inicial, intuitivamente el analizador intenta encontrar los símbolos más pequeños y progresivamente construir la jerarquía de símbolos hasta el inicial, los analizadores LR funcionan así


lunes, 20 de febrero de 2017

Analizadores Lexico

Analizadores Léxico

concepto

El analizador léxico opera bajo petición del analizador sintáctico devolviendo un componente léxico conforme el analizador sintáctico lo va necesitando para avanzar en la gramática.Los componentes léxicos son los símbolos terminales de la gramática.
Suele implementarse como una subrutina del analizador sintáctico. Cuando recibe la orden obtén el siguiente componente léxico, el analizador léxico lee los caracteres de entrada hasta identificar el siguiente componente léxico.
Tokens:
Símbolos terminales de una gramática
o    Identificadores, palabras reservadas, operadores.
o    Varios signos pueden forman el mismo token
Atributos:

Información adicional que tiene el token, de utilidad para el análisis sintáctico y semántico.

Componentes léxicos (tokens):

unidad mínima de información que significa algo a la hora de compilar; concepto de palabra; las fases de un lenguaje constan de cadenas de componentes léxicos.

Lexema:

Una secuencia de caracteres de entrada que comprenden un solo componente léxico se llama lexema; cadena de caracteres que extrae el componente abstracto del componente léxico.

Patrón:

Descripción de la forma que han de tomarlos lexemas para ajustarse a un componente léxico.

concepto

Se encarga de buscar los componentes léxicos o palabras que componen el programa fuente, según unas reglas o patrones. La entrada del analizador léxico podemos definirla como una secuencia de caracteres.
El analizador léxico es la primera fase de un compilador. Su principal función 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 convirtiendo al analizador léxico en una subrutina o corrutina del analizador sintáctico. Recibida la orden “Dame 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




El analizador léxico tiene que dividir la secuencia de caracteres en palabras con significado propio y después convertirlo a una secuencia de terminales desde el punto de vista del analizador sintáctico, que es la entrada del analizador sintáctico. El analizador léxico reconoce las palabras en función de una gramática regular de manera que sus NO TERMINALES se convierten en los elementos de entrada de fases posteriores. En LEX, por ejemplo, esta gramática se expresa mediante expresiones regulares.



miércoles, 8 de febrero de 2017

Progrmas

#include<iostream.h>
#include<conio.h>

void main (void){
char n1='e', n2='d',n3='u',n4='a',n5='r',n6='d',n7='o';

cout<<"Tu nombre es:    "<<n1<<n2<<n3<<n4<<n5<<n6<<n7<<endl;

 getch();
}


Programa 2

#include <iostream.h>

#include <conio.h>
#include <stdlib.h>
    void main (void){

char cad[255];
int i, cont=0;

cout<<"introduzca palabra"<<endl;
cin>>cad;

for (i=0;cad[i]!='\0';i++)
cont=cont+1;


cout<<"Tu escribiste la palabra: "<<cad<<endl;
cout<<"Tu palabra tiene: "<<cont<<endl;


getch();
}

martes, 7 de febrero de 2017

Compiladores e interpretes y maquina virtual

UNIDAD 1 ARQUITECTURA DE LOS COMPILADORES E INTERPRETES

Unidad de competencia

Determina la estructura general de los compiladores e intérpretes con base en la funcionalidad de sus etapas y fases
Concepto, características, aplicabilidad y 2 ejemplos
Arquitectura de compiladores e intérpretes, máquinas virtuales

Compiladores: Un traductor que transforma textos fuente de lenguajes de alto nivel a lenguajes de bajo nivel se le denomina compilador.

--El tiempo que se necesita para traducir un lenguaje de alto nivel a lenguaje objeto se denomina tiempo de compilación.
--El tiempo que tarda en ejecutarse un programa objeto se denomina tiempo de ejecución.

La construcción de un compilador involucra la división del proceso en una serie de fases que variará con su complejidad. Generalmente estas fases se agrupan en dos tareas: el análisis del programa fuente y la síntesis del programa objeto.

*Análisis: Se trata de la comprobación de la corrección del programa fuente, e incluye las fases correspondientes al Análisis léxico (que consiste en la descomposición del programa fuente en componentes léxicos), Análisis sintáctico (agrupación de los componentes léxicos en frases gramaticales) y Análisis semántico (comprobación de la validez semántica de las sentencias aceptadas en la fase de Análisis Sintáctico).

*Síntesis: Su objetivo es la generación de la salida expresada en el lenguaje objeto y suele estar formado por una o varias combinaciones de fases de Generación de Código (normalmente se trata de código intermedio o de código objeto) y de Optimización de Código (en las que se busca obtener un código lo más eficiente posible).

TIPOS DE COMPILADORES
Esta taxonomía de los tipos de compiladores no es excluyente, por lo que puede haber compiladores que se adscriban a varias categorías:
*Compiladores cruzados: generan código para un sistema distinto del que están funcionando.
*Compiladores optimizadores: realizan cambios en el código para mejorar su eficiencia, pero manteniendo la funcionalidad del programa original.
*Compiladores de una sola pasada: generan el código máquina a partir de una única lectura del código fuente.
*Compiladores de varias pasadas: necesitan leer el código fuente varias veces antes de poder producir el código máquina.
*Compiladores JIT (Just In Time): forman parte de un intérprete y compilan partes del código según se necesitan.
Aplicabilidad
La función principal que cumple es traducir a un lenguaje mucho más sencillo y entendible por la máquina, informa al usuario si existen errores en el código fuente con el fin de ejecutar la aplicación sin problema, si existe algún error simplemente se detiene.


 
 Intérpretes
 Los intérpretes son programas que simplemente ejecutan las instrucciones que encuentran en el texto fuente. En muchos casos coexisten en memoria el programa fuente y el programa intérprete.
El encargado de hacer esto es un programa llamado intérprete. A diferencia del compilador, el intérprete de un lenguaje no produce una traducción a código máquina. El intérprete intenta realizar "al vuelo" lo que se expresa en los ficheros fuente. El intérprete contiene en su interior miles de porciones de código máquina, que combinándolas adecuadamente pueden realizar las mismas tareas que expresa una orden escrita en el lenguaje de alto nivel.
Cuando un programa es interpretado, el proceso que se sigue es el siguiente: el intérprete obtiene una instrucción del fichero fuente y la realiza inmediatamente. Para ello, ejecuta en secuencia varias de esas porciones de código máquina que comentábamos antes, y que residen en el interior del intérprete. Cuando la CPU termina la ejecución de esa secuencia, el resultado es que la CPU habrá hecho lo que la línea de código fuente expresaba.
Los programas interpretados suelen ser más lentos que los compilados debido a la necesidad de traducir el programa mientras se ejecuta, pero a cambio son más flexibles como entornos de programación y depuración (lo que se traduce, por ejemplo, en una mayor facilidad para reemplazar partes enteras del programa o añadir módulos completamente nuevos), y permiten ofrecer al programa interpretado un entorno no dependiente de la máquina donde se ejecuta el intérprete, sino del propio intérprete (lo que se conoce comúnmente como máquina virtual).
Los programas interpretes clásicos son:
BASIC
QBASIC
QUICKBASIC
VISUALBASIC
SMALLTALK
JAVA


Máquina virtual

Una Máquina Virtual de Sistema es un programa que nos permite albergar un Ordenador Ficticio dentro de un Ordenador existente, es decir, un software que simula por completo el comportamiento de un Ordenador real sin que este exista, albergado virtualmente en un ordenador físico.
Este tipo de programas nos permitirán con un solo PC disponer de múltiples Sistemas Operativos funcionando simultáneamente usando tan solo una única máquina física.
una Virtual podemos por ejemplo instalar varios PCS virtuales con distintos sistemas operativos y estudiar la forma de conectarlos en una red a través también de routers virtuales.
Otra utilidad primordial consiste en poder trabajar con aplicaciones que funcionan sobre distintos sistemas operativos al que posee el ordenador anfitrión, disponiendo de un solo Ordenador físico, esto a veces, resulta prácticamente imprescindible, cuando un ordenador con un sistema Operativo Servidor necesita trabajar con un programa que no corre sobre ese sistema servidor.
Las máquinas virtuales se usan, por lo tanto, de forma muy frecuente en el ámbito profesional y en la enseñanza, podremos, usándolas, probar y estudiar cómodamente distintos sistemas operativos, plataformas de programación, comportamiento de programas inestables etc.
Los Emuladores son un tipo de máquinas virtuales cuya única diferencia es que solo soportan un sistema, por ejemplo existen emuladores de videoconsolas, de sistemas Operativos móviles, como Android o Symbian etc. esto también puede resultar de gran utilidad.
Aunque en este artículo nos referimos principalmente a las Máquinas Virtuales de Sistema debemos saber que existe otro tipo de Máquinas Virtuales, llamadas de proceso, la diferencia entre ellas es que las segundas solo pueden ejecutar un proceso simultáneamente y su comportamiento no se distingue en la práctica de un programa convencional, aunque sí que son máquinas virtuales puesto que a diferencia de una aplicación convencional trabajan aisladas del sistema anfitrión a pesar de estar alojadas en él, además su misión no es emular un sistema operativo si no funcionar como una plataforma independiente, un ejemplo de este tipo es la Máquina Virtual de Java.
Como principal inconveniente, las Máquinas Virtuales incrementan notablemente el trabajo que soporta el Equipo Físico anfitrión, cada Sistema Operativo en funcionamiento añade una carga de procesos enorme y ante todo ocupa una gran cantidad de memoria RAM, es imprescindible, por lo tanto, disponer de un Ordenador potente y con gran cantidad de memoria si queremos hacer correr a varios SO simultáneamente.