Está en la página 1de 91

Lenguajes y Autómatas I.

Introducción a la Teoría de Lenguajes


Formales.
Alfabeto
Un alfabeto es cualquier conjunto finito y no vacío de elementos que denominan
símbolos y los denotará con el símbolo Ʃ.
Cadenas
Una cadena (también llamada palabra) es una secuencia finita de símbolos
pertenecientes a un alfabeto. Admitimos la existencia de una única cadena que no
tiene símbolos, la cual se denomina cadena vacía y se denota con λ.

Longitud de cadena. La longitud de cadena es el número de símbolos que


contiene. La notación empleada es la que es la que se indica en el ejemplo:

I abcb I = 4, I a + 2*b I = 5 I 000111 I = 6 I if a > b then a = b; I = 9

Una cadena vacía es la única cadena de caracteres de tamaño cero.


Cadenas
Concatenación de cadenas. La concatenación de dos cadenas u y v, escrita uv, es
"pegar" las dos cadenas para formar una nueva.

Ejemplo: Sea u = ab v = ca w = bb.

Entonces uv = abca, uw = cabb, (uv) w = abcabb, u(vw) = abcabb

El resultado de la concatenación de u, v y w es independiente del orden en que las


operaciones son ejecutadas. Matemáticamente esta propiedad es conocida como
asociatividad.
Cadenas
Universo del discurso. Es un conjunto de todas las cadenas donde podemos
formar con símbolos del alfabeto V le denominamos universo del discurso de V y
la representamos de la siguiente manera W (V). Es evidente que W(V) es un
conjunto infinito y que la cadena vacía pertenece a W(V).

Ejemplo:

Un alfabeto con una sola letra V = { a }, podemos decir que el universo del
discurso es: W(V) = { λ, a, aa, aaa, aaaa,....} y así contiene una cadenas infinitas.
Lenguajes, tipos y herramientas.
Lenguajes. Es un conjunto de cadenas, de todas las seleccionadas de un Σ*. Si Σ
es un alfabeto y L Σ*, entonces L es un lenguaje de Σ.

Observe que un lenguaje de Σ no necesita incluir cadenas con todos los símbolos
de Σ, ya que una vez que se sabe que L es un lenguaje de Σ, también sabemos que
es un lenguaje de cualquier alfabeto que sea un súper conjunto de Σ.
Lenguajes, tipos y herramientas.
La elección del término "lenguaje" puede parecer extraña, Sin embargo, los
lenguajes habituales pueden interpretarse como conjuntos de cadenas. Un
ejemplo sería el Inglés, donde la colección de las palabras correctas inglesas es
un conjunto de cadenas del alfabeto que consta de todas las letras.
Lenguajes, tipos y herramientas.
Tipos de lenguajes.

● Natural. Nosotros estamos relacionados con el concepto tradicional de


gramática que, de esta forma intuitiva, podemos considerar un conjunto de
reglas el cual nos indican que es correcto y que no lo es del lenguaje natural.
Con este fin podemos acércanos a la definición más clara y formal de la
lengua castellana.
Lenguajes, tipos y herramientas.
Tipos de lenguajes.

● Artificial. En este lenguaje aplicamos el mismo método en el cual definimos


un fragmento del lenguaje de programación. Donde pretendemos describir las
instrucciones el cual nos permite asignar un valor a una expresión ó a una
variable en un lenguaje C
Lenguajes, tipos y herramientas.
Tipos de lenguajes.

● Regular. Llamamos así a los lenguajes porque sus palabras contienen


"regularidades" o repeticiones de los mismos componentes, por ejemplo en
este lenguaje L1 = { ab, abab, ababab, abababab,...} Este ejemplo podemos
apreciar las palabras de L1 son solo repeticiones de "ab" donde se repiten
varias veces. Su regularidad consiste en las palabras que contienen "ab"
varias veces.
Estructura de un traductor
Un traductor es un programa que tiene como entrada un texto escrito en un
lenguaje (lenguaje fuente) y como salida produce un texto escrito en un lenguaje
(lenguaje objeto) que preserva el significado de origen.
Estructura de un traductor
En el proceso de traducción se identifican dos fases principales:
Estructura de un traductor
Fase de análisis:
Estructura de un traductor
Fase de Síntesis:
Fases de un compilador
Los compiladores son programas de computadora que traducen de un lenguaje a
otro. Un compilador toma como su entrada un programa escrito en lenguaje
fuente y produce un programa equivalente escrito en lenguaje objeto.

Un compilador se compone internamente de varias etapas, o fases, que realizan


operaciones lógicas.
Fases de un compilador
Fases de un compilador
Analizador léxico. Lee la secuencia de caracteres de izquierda a derecha del
programa fuente y agrupa las secuencias de caracteres en unidades con
significado propio (componentes léxicos o “tokens” en inglés).

Las palabras clave, identificadores, operadores, constantes numéricas, signos de


puntuación como separadores de sentencias, llaves, parentesis, etc. , son diversas
clasificaciones de componentes léxicos.
Fases de un compilador
Análisis sintáctico. Determina si la secuencia de componentes léxicos sigue la
sintaxis del lenguaje y obtiene la estructura jerárquica del programa en forma de
árbol, donde los nodos son las construcciones de alto nivel del lenguaje.

Se determinan las relaciones estructurales entre los componentes léxicos, esto es


semejante a realizar el análisis gramatical sobre una frase en lenguaje natural. La
estructura sintáctica la definiremos mediante las gramáticas independientes del
contexto.
Expresiones Regulares.
Definición formal de una ER.
Una expresión regular es una notación normalizada para representar lenguajes
regulares, es decir, lenguajes generados por gramáticas, las expresiones regulares
permiten describir con exactitud y sencillez cualquier lenguaje regular. Para definir
una expresión regular se pueden utilizar todos los símbolos del alfabeto Σ y
además, λ y Ø.
Diseño de una ER.
La barra inversa o contrabarra "\". La barra inversa se utiliza para escapar el siguiente carácter de la expresión de búsqueda de forma
que este adquiera un significado especial o deje de tenerlo. O sea, la barra inversa no se utiliza nunca por sí sola, sino en combinación
con otros caracteres. Al utilizarlo por ejemplo en combinación con el punto "\." este deja de tener su significado normal y se comporta
como un carácter literal.

● \t — Representa un tabulador.
● \r — Representa el "retorno de carro" o "regreso al inicio" o sea el lugar en que la línea vuelve a iniciar.
● \n — Representa la "nueva línea" el carácter por medio del cual una línea da inicio. Es necesario recordar que en Windows es
necesaria una combinación de \r\n para comenzar una nueva línea, mientras que en Unix solamente se usa \n y en Mac_OS
clásico se usa solamente \r.
● \a — Representa una "campana" o "beep" que se produce al imprimir este carácter.
● \e — Representa la tecla "Esc" o "Escape"
● \f — Representa un salto de página
● \v — Representa un tabulador vertical
● \x — Se utiliza para representar caracteres ASCII o ANSI si conoce su código. De esta forma, si se busca el símbolo de
derechos de autor y la fuente en la que se busca utiliza el conjunto de caracteres latín-1 es posible encontrarlo utilizando \xA9".
● \u — Se utiliza para representar caracteres Unicode si se conoce su código. "\u00A2" representa el símbolo de centavos. No
todos los motores de Expresiones Regulares soportan Unicode. El .Net Framework lo hace, pero el EditPad Pro no, por ejemplo.
Diseño de una ER.
● \d — Representa un dígito del 0 al 9.
● \w — Representa cualquier carácter alfanumérico.
● \s — Representa un espacio en blanco.
● \D — Representa cualquier carácter que no sea un dígito del 0 al 9.
● \W — Representa cualquier carácter no alfanumérico.
● \S — Representa cualquier carácter que no sea un espacio en blanco.
● \A — Representa el inicio de la cadena. No un carácter sino una posición.
● \Z — Representa el final de la cadena. No un carácter sino una posición.
● \b — Marca la posición de una palabra limitada por espacios en blanco, puntuación o el inicio/final
de una cadena.
● \B — Marca la posición entre dos caracteres alfanuméricos o dos no-alfanuméricos.
Diseño de una ER.
Los corchetes "[ ]".La función de los corchetes en el lenguaje de las expresiones
regulares es representar "clases de caracteres", o sea, agrupar caracteres en
grupos o clases. Son útiles cuando es necesario buscar uno de un grupo de
caracteres. Dentro de los corchetes es posible utilizar el guión "-" para especificar
rangos de caracteres.
Diseño de una ER.
La barra "|". Sirve para indicar una de varias opciones. Por ejemplo, la expresión
regular "a|e" encontrará cualquier "a" o "e" dentro del texto. La expresión regular
"este|oeste|norte|sur" permitirá encontrar cualquiera de los nombres de los puntos
cardinales. La barra se utiliza comúnmente en conjunto con otros caracteres
especiales.
Diseño de una ER.
El signo de dólar "$". Representa el final de la cadena de caracteres o el final de la
línea, si se utiliza el modo multi-línea.

No representa un carácter en especial sino una posición. Si se utiliza la expresión


regular "\.$" el motor encontrará todos los lugares donde un punto finalice la línea,
lo que es útil para avanzar entre párrafos.
Diseño de una ER.
El acento circunflejo "^". Este carácter tiene una doble funcionalidad, que difiere
cuando se utiliza individualmente y cuando se utiliza en conjunto con otros
caracteres especiales. En primer lugar su funcionalidad como carácter individual:
el carácter "^" representa el inicio de la cadena (de la misma forma que el signo de
dólar "$" representa el final de la cadena).

Por tanto, si se utiliza la expresión regular "^[a-z]" el motor encontrará todos los
párrafos que den inicio con una letra minúscula.
Diseño de una ER.
Los paréntesis "()". De forma similar que los corchetes, los paréntesis sirven para
agrupar caracteres, sin embargo existen varias diferencias fundamentales entre
los grupos establecidos por medio de corchetes y los grupos establecidos por
paréntesis:

● Los caracteres especiales conservan su significado dentro de los paréntesis.


● Los grupos establecidos con paréntesis establecen una "etiqueta" o "punto de
referencia" para el motor de búsqueda que puede ser utilizada posteriormente
como se denota más adelante.
Diseño de una ER.
● Utilizados en conjunto con la barra "|" permite hacer búsquedas opcionales.
Por ejemplo la expresión regular "al (este|oeste|norte|sur) de" permite buscar
textos que den indicaciones por medio de puntos cardinales, mientras que la
expresión regular "este|oeste|norte|sur" encontraría "este" en la palabra
"esteban", no pudiendo cumplir con este propósito.
Diseño de una ER.
El signo de interrogación "?". El signo de interrogación tiene varias funciones
dentro del lenguaje de las expresiones regulares. La primera de ellas es
especificar que una parte de la búsqueda es opcional. Por ejemplo, la expresión
regular "ob?scuridad" permite encontrar tanto "oscuridad" como "obscuridad". En
conjunto con los paréntesis redondos permite especificar que un conjunto mayor
de caracteres es opcional; por ejemplo "Nov(\.|iembre|ember)?" permite encontrar
tanto "Nov" como "Nov.", "Noviembre" y "November". Como se mencionó
anteriormente, los paréntesis nos permiten establecer un "punto de referencia"
para el motor de búsqueda.
Diseño de una ER.
Las llaves "{}". Comúnmente las llaves son caracteres literales cuando se utilizan
por separado en una expresión regular. Para que adquieran su función de
metacaracteres es necesario que encierren uno o varios números separados por
coma y que estén colocados a la derecha de otra expresión regular de la siguiente
forma: "\d{2}" Esta expresión le dice al motor de búsqueda que encuentre dos
dígitos contiguos. Utilizando esta fórmula podríamos convertir el ejemplo
"^\d\d/\d\d/\d\d\d\d$" que servía para validar un formato de fecha en
"^\d{2}/\d{2}/\d{4}$" para una mayor claridad en la lectura de la expresión.
Diseño de una ER.
Las llaves "{}". Comúnmente las llaves son caracteres literales cuando se utilizan
por separado en una expresión regular. Para que adquieran su función de
metacaracteres es necesario que encierren uno o varios números separados por
coma y que estén colocados a la derecha de otra expresión regular de la siguiente
forma: "\d{2}" Esta expresión le dice al motor de búsqueda que encuentre dos
dígitos contiguos. Utilizando esta fórmula podríamos convertir el ejemplo
"^\d\d/\d\d/\d\d\d\d$" que servía para validar un formato de fecha en
"^\d{2}/\d{2}/\d{4}$" para una mayor claridad en la lectura de la expresión.
Diseño de una ER.
El asterisco "*". El asterisco sirve para encontrar algo que se encuentra repetido 0
o más veces. Por ejemplo, utilizando la expresión "[a-zA-Z]\d*" será posible
encontrar tanto "H" como "H1", "H01", "H100" y "H1000", es decir, una letra seguida
de un número indefinido de dígitos.
Diseño de una ER.
El signo de suma "+". Se utiliza para encontrar una cadena que se encuentre
repetida una o más veces. A diferencia del asterisco, la expresión "[a-zA-Z]\d+"
encontrará "H1" pero no encontrará "H". También es posible utilizar este
metacarácter en conjunto con el signo de interrogación para limitar hasta donde
se efectúa la repetición.
Aplicaciones en problemas reales.
● Facilitar las construcciones de un compilador.
● Validar la sintaxis de un programa
● Algunos generadores lexicográficos toman como entrada una sucesión de
expresiones regulares y produce un autómata finito que reconozca cualquier
expresión ahí descritos.
● Algunos editores de texto y programas similares permiten la sustitución de
una cadena por otra cualquiera que cumpla con la expresión regular dada.
Autómatas Finitos.
Autómatas Finitos.
Definición. Un autómata finito o máquina de estado finito es un modelo
matemático de un sistema que recibe una cadena constituida por símbolos de un
alfabeto y determina si esa cadena pertenece al lenguaje que el autómata
reconoce. Éstos se definen mediante una quíntupla (E, Q, f, q0, F ) donde:

● E: alfabeto de entrada.
● Q: conjunto de estados; es conjunto finito no vacío.
● f: función de transición. f(p,a)=q
● q0 : (perteneciente a Q) estado inicial.
● F : (perteneciente a Q) conjunto de estados finales o de aceptación.
Autómatas Finitos.
Los autómatas se pueden clasificar en:

● Deterministas. Cada combinación (estado, símbolo de entrada) produce un


solo estado.
● No Deterministas. Cada combinación (estado, símbolo de entrada) produce
varios estados y además son posibles las transiciones con λ.
Autómatas Finitos.
Representación.

Los autómatas se pueden representar mediante tablas de transición o diagramas


de transición.

Tablas de transición:

● Filas encabezadas por los estados(q).


● Columnas encabezadas por los símbolos de entrada ( E).
Autómatas Finitos.
Autómatas Finitos.
Diagramas de transición:

● Nodos etiquetados por los estados(q).


● Arcos entre nodos etiquetados con (Input).
● Q0 se señala con ->.
● El estado final se señala con * o con doble circulo.
Autómatas Finitos.
Autómatas Finitos.
Ejemplo: Sea el AFD1 = ({a,b}, {p,q,r}, f, p, {q}) donde f está

definida por:

f(p,a) = q f(p,b) = r

f(q,a) = q f(q,b) = r

f(r,a) = r f(r,b) = r

escribir su tabla de transición y dibujar su diagrama de transición.


Autómatas Finitos.
E/I a b

AFD = ({a,b}, {p,q,r}, f, p, {q}) p q r

función de transición: q q r

f(p,a) = q f(p,b) = r r r r

f(q,a) = q f(q,b) = r

f(r,a) = r f(r,b) = r
Análisis Léxico.
Análisis Léxico.
Definición de analizador léxico.

El analizador léxico es una herramienta de un compilador que nos ayuda a leer los
caracteres de entrada para formar componentes y así poder identificarlos y pasar
la información a analizadores sintácticos.

Los componentes léxicos representan:

● Palabras reservadas: if, while, do etc.


● Operadores. =+-*/== > <!=.
● Constantes numéricas
● Constantes de caracteres
Componentes léxicos, patrones y
lexemas.
Componente léxico (token). Son las unidades lógicas que genera el analizador
léxico. Formar caracteres en tokens es muy parecido a formar palabras en un
lenguaje natural.

Es el conjunto de cadenas de entrada que produce como salida el mismo


componente léxico.

Cada token es una secuencia de caracteres que representa una unidad de


información en el programa fuente.

Los componentes léxicos más comunes son los siguientes:


Componentes léxicos, patrones y
lexemas.
Los componentes léxicos más comunes son los siguientes:

● Palabras clave o reservadas.


● Operadores aritméticos.
● Operadores relacionales.
● Operadores lógicos.
● Operador de asignación.
● Identificadores.
● Constantes.
● Cadenas.
Componentes léxicos, patrones y
lexemas.
Los componentes léxicos más comunes son los siguientes:

● Literales.
● Signos de puntuación.
● Librerías.
Lexema.
Representan cadenas de caracteres en el programa fuente que se pueden tratar
juntos como una unidad léxica. Un lexema es una secuencia de caracteres en el
programa fuente con la que concuerda el patrón para un componente léxico.
Patrón.
Regla que describe el conjunto de lexemas que pueden representar a un
determinado componente léxico en los programas fuente.

En otras palabras, es la descripción del componente léxico mediante una regla.


Atributos de los componentes léxicos
El analizador léxico recoge información sobre los componentes léxicos en sus
atributos asociados. Los componentes léxicos influyen en las decisiones del
análisis sintáctico y los atributos en la traducción de los componentes léxicos:

● Apuntador a la entrada de la Tabla de símbolos donde se guarda la


información sobre el componente léxico.
● El lexema para un identificador
● El número de línea en que se encontró por primera vez.
Creación de Tabla de tokens.
Errores léxicos.
Los errores léxicos se deben a descuidos del programador. En general, la
recuperación de errores léxicos es sencilla y siempre se traduce en la generación
de un error de sintaxis que será detectado más tarde por el analizador sintáctico
cuando el analizador léxico devuelve un componente léxico que el analizador
sintáctico no espera en esa posición.
Errores léxicos.
Errores léxicos típicos

Los errores léxicos se detectan cuando el analizador intenta reconocer


componentes léxicos y la cadena de caracteres de la entrada no encaja con
ningún patrón.

Son situaciones en las que usa un carácter inválido (@,$,",>,...), que no pertenece
al vocabulario del lenguaje de programación, al escribir mal un identicador,
palabra reservada u operador.
Errores léxicos.
Errores de ortografía en palabras reservadas, caracteres omitidos, adicionales o
cambiados de sitio, por ejemplo:

1. La palabra hwile en vez de while.


2. Números malformados(3.14.16).
3. Fin de archivo a mitad del codigo.
Generadores de analizadores Léxicos.
● LEX: Código generado C.
● FLEX: Código generado C++.
● ZLEX: Código generado C, soporta caracteres de 16 bits.
● JAX: Código generado JAVA, no soporta entornos esta basado en
expresiones regulares, no soporta unicode.
● JLEX: Código generado JAVA, similar a LEX.
● JFLEX: Código generado JAVA.
Aplicaciones (Caso de estudio).
Además de para construir compiladores e intérpretes, los analizadores léxicos se
pueden emplear para muchos programas “convencionales”. Los ejemplos más
claros son aquellos programas que tienen algún tipo de entrada de texto donde
hay un formato razonablemente libre en cuantos espacios y comentarios. En
estos casos es bastante engorroso controlar dónde empieza y termina cada
componente y es fácil liarse con los punteros a char. Un analizador léxico
simplifica notablemente la interfaz y si se dispone de un generador automático, el
problema se resuelve en pocas líneas de código.
Análisis Sintáctico.
Definición y clasificación de gramáticas.
Veamos algunos conceptos que nos ayuden a formular el concepto de gramática:

(Del lat. grammatĭca, y este del gr. γραμματική). f. Ciencia que estudia los
elementos de una lengua y sus combinaciones.

Arte de hablar y escribir correctamente una lengua. Estudio de una lengua regido
por el principio de que todos sus elementos mantienen entre sí relaciones
sistemáticas.

La que trata de formular una serie de reglas capaces de generar o producir todas
las oraciones posibles y aceptables de un idioma o lenguaje.
Definición y clasificación de gramáticas.
TIPO “0” O “No restringida o recursivamente enumerables”. Incluye a todas las
gramáticas formales. Estas gramáticas generan todos los lenguajes de ser
reconocidos por una máquina de Turing. Y con este lenguaje se hacen los
parser(Sintáctico) de un compilador.

CARACTERÍSTICAS: De este tipo es que del lado derecho de cada producción


puede empezar con un símbolo terminal o con un no terminal y del lado izquierdo
puedes empezar con más de un símbolo no terminal.
Definición y clasificación de gramáticas.
TIPO “1” O “Sensible al contexto”. Estos tipos de lenguajes se resuelven mediante
autómatas lineales limitados. Con este tipo se hacen los parser (analizador
sintáctico) de un compilador que transforma su entrada en un árbol de derivación.

El analizador 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.
Definición y clasificación de gramáticas.
TIPO “2” O “Libres o Independientes de contexto”. Estos tipos de lenguajes se
resuelven mediante autómatas descendentes y con este tipo de lenguaje se
programa los parser en un compilador, permiten describir la mayoría de los
lenguajes de programación, de hecho, la sintaxis de la mayoría de los lenguajes de
programación está definida mediante gramáticas libres de contexto.
Definición y clasificación de gramáticas.
TIPO “3” O “Lenguajes regulares”. Estos tipos de lenguajes se resuelven mediante
autómatas finitos y con este tipo de lenguaje se hacen los scanners. Estas
gramáticas se restringen a aquellas reglas que tienen en la parte izquierda un no
terminal, y en la parte derecha un solo terminal, posiblemente seguido de un no
terminal y también esta familia de lenguajes pueden ser obtenidas por medio de
expresiones regulares
Gramáticas Libres de Contexto (GLC).
Estas gramáticas, conocidas también como gramáticas de tipo 2 o gramáticas
independientes del contexto, son las que generan los lenguajes libres o
independientes del contexto. Los lenguajes libres del contexto son aquellos que
pueden ser reconocidos por un autómata de pila determinístico o no
determinístico.

Como toda gramática se definen mediante una cuadrupla G = (N, T, P, S), siendo

● - N es un conjunto finito de símbolos no terminales


● - T es un conjunto finito de símbolos terminales N ∩ T = ∅
● - P es un conjunto finito de producciones
● - S es el símbolo distinguido o axioma S ∉ (N ∪ T)
Árboles de derivación
Un árbol de derivación (o árbol sintáctico) es una representación gráfica de como
se deriva una forma sentencial a partir del símbolo no-terminal inicial.

Un árbol es un grafo dirigido acíclico en el cual cada nodo se conecta con un nodo
distinguido, llamado nodo raíz mediante un único camino. Un nodo n  1 se dice
descendiente de otro nodo n 2 si se puede llegar a n 1 a partir de n 1. El nodo raíz
no es descendiente de ningún nodo, y los nodos que no tienen descendientes se
denominan hojas. El resto de los nodos se denominan nodos interiores.
Árboles de derivación
Árboles de derivación
Un árbol de derivación tiene las siguientes propiedades:

1. El nodo raíz está rotulado con el símbolo distinguido (inicial) de la Gramática.


2. Cada hoja corresponde a un símbolo terminal o un símbolo no-terminal.
3. Cada nodo interior corresponde a un símbolo no-terminal.
4. Un árbol de derivación muestra gráficamente las derivaciones (sustituciones
de símbolos no terminales) que hay que llevar a cabo para llegar a una Forma
Sentencial a partir del símbolo inicial.
Árboles de derivación
Las hojas en un árbol de derivación tomadas de izquierda a derecha constituyen
una Forma Sentencial de la Gramática subyacente.
Árboles de derivación
Ejemplo: La siguiente definición BNF(notación de Backus-Naur) describe en forma
simplificada la sintaxis de una sentencia de asignación de un lenguaje tipo Pascal:

<sent_asig> ::= <var> ':=' <expresion>


<expresion> ::= <expresion> '+' <termino> | <expresion> '-' <termino> | <termino>
<termino> ::= <termino> '*' <factor> |<termino> '/' <factor> | <factor>
<factor> ::= ( <expresion> ) |<var> | <num>
<var> ::= 'A'..'Z'
<num> ::= '0'..'9'
Árboles de derivación
Un arbol de derivación correspondiente a la sentencia:

C := D - E * F
Árboles de derivación
Ejemplo: La siguiente definición BNF(notación de Backus-Naur) describe en forma
simplificada la sintaxis de una sentencia de asignación de un lenguaje tipo Pascal:

<sent_asig> ::= <var> ':=' <expresion>


<expresion> ::= <expresion> '+' <termino> | <expresion> '-' <termino> | <termino>
<termino> ::= <termino> '*' <factor> |<termino> '/' <factor> | <factor>
<factor> ::= ( <expresion> ) |<var> | <num>
<var> ::= 'A'..'Z'
<num> ::= '0'..'9'
Diagramas de sintaxis.
Un diagrama de sintaxis (también llamados diagramas de Conway) es un grafo
dirigido donde los elementos no terminales aparecen como rectángulos, y los
terminales como círculos o elipses.

Todo diagrama de sintaxis posee un origen y un destino, que no se suelen


representar explícitamente, sino que se asume que el origen se encuentra a la
izquierda del diagrama y el destino a la derecha.
Diagramas de sintaxis.
Cada arco con origen en " y destino en $ representa que el símbolo " puede ir
seguido del $ (pudiendo ser " y $ tanto terminales como no terminales).

De esta forma todos los posibles caminos desde el inicio del grafo hasta el
final,representan formas sentenciales válidas. Demostraremos que los diagramas
de sintaxis permiten representar las mismas gramáticas que la notación BNF, por
inducción sobre las operaciones básicas de BNF:
Diagramas de sintaxis.
Diagramas de sintaxis.
Diagramas de sintaxis.
Eliminación de la ambigüedad.
Una GLC es ambigua si existe una cadena w Є L(G) que tiene más de una
derivación por la izquierda o más de una derivación por la derecha o si tiene dos o
más árboles de derivación.
Eliminación de la ambigüedad.
Tipos de Ambigüedad

La ambigüedad lingüística se da cuando una palabra, un sintagma, o una oración,


es susceptible de dos o más significados o interpretaciones.

La ambigüedad puede ser sintáctica (o estructural), semántica, o pragmática.


Eliminación de la ambigüedad.
Ambigüedad Inherente: Las gramáticas que presentan este tipo de ambigüedad
no pueden utilizarse para lenguajes de programación, ya que por más
transformaciones que se realicen sobre ellas, nunca se podrá eliminar
completamente la ambigüedad que presentan.

● El lenguaje de las expresiones no es Ambiguo


● Las expresiones regulares no son ambiguas
Eliminación de la ambigüedad.
Ambigüedad Transitoria: generalmente este tipo de ambigüedad se presenta
cuando existen producciones con factores comunes; ó cuando existen
producciones que son recursivas izquierdas .
Eliminación de la ambigüedad.
Para eliminar este tipo de ambigüedad, es necesario, primero eliminar:

1. Factores comunes izquierdos inmediatos y No-inmediatos.


2. Recursividad izquierda inmediata y No-inmediata.

En sentido genérico, la ambigüedad es el atributo de cualquier concepto, idea,


declaración, presentación, o reclamación, cuyo sentido, intención, o interpretación,
definitivamente no pueden ser resueltos según una regla o un proceso resoluble
en un número finito de pasos.
Tipos de analizadores sintácticos.
Ascendente:

En el Análisis Sintáctico Ascendente se parte de las hojas y se intenta construir el


árbol hacia arriba hasta llegar al símbolo inicial de la gramática.

En un análisis top-down un parser hacer corresponder cadenas de entrada con


sus correspondientes derivaciones izquierdas.

En un análisis bottom-up un parser hace corresponder cadenas de entrada con las


inversas de las correspondientes derivaciones derechas.
Tipos de analizadores sintácticos.
Ascendente:
Tipos de analizadores sintácticos.
Ascendente:

Parten de las hojas (conjunto de tokens) para llegar a la raíz (axioma de la


gramática):

● Analizadores de procedencia de operador.


● Analizador LR(1)

Se denominan analizadores sintácticos ascendentes (botton-up) porque


pretenden construir un árbol sintáctico para una determinada cadena de entrada,
empezando por las hojas y constituyendo el árbol hasta llegar a la raíz.
Tipos de analizadores sintácticos.
Ascendente:

Un analizador sintáctico ascendente utiliza una pila explícita para realizar un


análisis sintáctico, de manera semejante como lo hace un analizador sintáctico
descendente no recursivo. La pila de análisis sintáctico contiene los tokens como
símbolos no terminales y también alguna información de estado adicional.

Los analizadores LR reconocen el lenguajes realizando dos operaciones cargar


(shift) y reducir (reduce). Lo que hace es leer los tokens de la entrada e ir
cargándolos en una pila, de forma que se puedan explorar lo n tokens que
contiene esta y ver si se corresponden con la parte derecha de alguna de las
reglas de la gramática.
Tipos de analizadores sintácticos.
Ascendente:

Los analizadores LR reconocen el lenguajes realizando dos operaciones, cargar


(shift) y reducir (reduce). Lo que hace es leer los tokens de la entrada e ir
cargándolos en una pila, de forma que se puedan explorar los n tokens que
contiene esta y ver si se corresponden con la parte derecha de alguna de las
reglas de la gramática.

Si es así se realiza un reducción, consistente en sacar de la pila esos n tokens y en


su lugar colocar el símbolo que aparezca en la parte izquierda de esa regla. En
caso contrario, se carga en la pila el siguiente token y una vez hecho esto se
vuelve a intentar una reducción.
Tipos de analizadores sintácticos.
Descendente:

En el Análisis Sintáctico Descendente se va recorriendo el árbol sintáctico desde


la raíz hasta las hojas, llegando a generar la sentencia que se está analizando. La
raíz representa el símbolo inicial de la gramática.
Tipos de analizadores sintácticos.
Descendente:
Tipos de analizadores sintácticos.
Descendente:

● Análisis sintáctico descendente:


● Partir del axioma de la gramática.
● Escoger reglas gramaticales.
● Hacer derivaciones por la izquierda.
● Procesar la entrada de izquierda a derecha.
● Obtener el árbol de análisis sintáctico o error.
Tipos de analizadores sintácticos.
Descendente:

También podría gustarte