Sunteți pe pagina 1din 7

Universidad del Valle de Guatemala

Facultad de Ingeniería
Departamento de Ciencias de la Computación Semestre 1 de 2010
CC3006 – Diseño de Lenguajes de Programación Sección: 10
Byron Orlando Morales Sequen 08414

Tarea 2

Entrega: lunes, 15 de febrero de 2,010.

1. Considere la gramática:
S  L∣a
L  L , S∣S
1. ¿Cuáles son los terminales, los no terminales y el símbolo inicial?

Los símbolos terminales son:  ' ' ,' ' , ' a ' ,' ,' .


Los símbolos no terminales son:  ' L ' ,' S ' .
El símbolo inicial es  ' S ' .

2. Encuéntrense árboles de análisis sintáctico para las siguientes frases:
1. a , a

2. a , a , a
3. a ,a , a ,a , a
2. Construya un DFA que acepten los siguientes lenguajes sobre el alfabeto  {0, 1} :
1. Conjunto de cadenas que terminen en  00

2. Conjunto de cadenas con tres  0  consecutivos (no necesariamente al final)

3. Conjunto de cadenas que empiecen con  01

4. Conjunto de cadenas que contengan a  001  como sub­cadena

3. Escriba expresiones regulares para los lenguajes del ejercicio anterior.
1. Conjunto de cadenas que terminen en  00

0∣1∗ 00

2. Conjunto de cadenas con tres  0  consecutivos (no necesariamente al final)

0∣1∗ 000 0∣1∗


3. Conjunto de cadenas que empiecen con  01

01 0∣1∗

4. Conjunto de cadenas que contengan a  001  como sub­cadena

0∣1∗ 0010∣1∗

4. De una descripción del lenguaje que generan las siguientes expresiones regulares:
1. 0 ∗ 1∗ 000 0∣1∗

Tiene las características:
• Es infinito.
• No contiene a la cadena vacía (  ).
• Siempre contienen a la subcadena 000.
• Cada cadena del lenguje contiene a '0' cero o más veces seguido de '1', cero o más 
veces. Luego contiene a la subcadena '000'; y por último tiene a '0' o a '1' cero o 
más veces.

2. 0∣10∗ 1∗

Tiene las características:
• Es infinito.
• Contiene a la cadena vacía (  ).
• Cada cadena del lenguje contiene a '0' o '10' cero o más veces seguido de cero o 
más 1's.

5. Dadas dos expresiones regulares   r 1   y   r 2 . ¿Cómo demostraría (o refutaría) que 
L r 1 =L r 2  ?

Para   demostrar   que L r 1 =L r 2  se   necesita   que   para   cualquier   cadena   w   que 
pertenezca   a   L r 1  ,   donde w=w 1 w2 ... wn y   cada   w i pertenece   a   L r 1  ,   entonces   w  
también debería estar en  L r 2  , y por tanto cada  w i  también debería estar en  L r 2  .

Por el contrario, si encontramos al menos una cadena  r  que se encuentra en  L r 1  y que 


no se encuentra en  L r 2   entonces podemos concluír que  L r 1 ≠L r 2  .

Por   ejemplo,  en   el  lenguaje   dado  por   a∣b y  el  lenguje   dado   por   b ∗ no   continenen   las 
mismas   cadenas   ( b ∗   no   contiene   a   a ,   etc.).   Mientras   que   el   lenguaje   dado   por 
a∣ba∣b   y el lenguaje dado por   aa∣ab∣ba∣bb   si son equivalentes, ya que cada cadena 
del cualquiera de los dos lenguajes se encuentra en el otro.

6. Sea   w=xy   donde   x   y   y   son cadenas sobre un conjunto de símobolos dados. 


 q , xy =
Demuestre   que      q , x  , y   donde      es   la   función   de   transición 
extendida definida para un AFD.
Para   entender   esto  simplemente   tomamos   que   w=xy entonces   tenemos   que 
w 1 w 2 ... wn w n1 w n2 ... w nm =x 1 x 2 ... x n y 1 y 2 ... y m como   resultado   directo   de   esto   tenemos 
 q , w1 w2 ... wn = q , x =q
  , x 1 x 2 ... x n y   llamemos   p al   resultado   de  ;   luego   si 
aplicamos      al   resto   de   la   cadena   con   el   estado   p   (es   decir   aplicamos 
 p , w n1 wn2 ... w nm =
  p , y=  p , y 1 y 2 ... y m  ) obtenemos el estado final  p f . Ahora bien 
si   aplicamos      a   la   cadena   w ,   por   consiguiente   de   lo   anterior   y   de   la   forma   de   
simplemente llegaremos al estado  p f
 q , w=q
  , w1 w2 ... wn w n1 wn 2 ... w nm = p f
y como se muestra anteriormente, si se aplica    a  x  y luego a y con el estado devuelto 
por    tenemos
  q , x  , y = p
 f
p
como vemos llegamos al mismo estado  f , y por ello podemos concluír que
 q , xy =
   q , x  , y

7. Demuestre   que   para   cualquier   estado   q ,   cadena   x   y   símbolo   de   entrada   a  


tenemos que    q , ax = 
 q , a , x  , donde    es la función de transición y    es 
la función de transición extendida definida para un AFD.

Si   tomamos   el   símbolo   de   entrada   a   y   consideramos   que   x= x 1 x 2 ... x n ,   entonces 


podemos reescribir    q , ax = q
 , a x x ... x  y entonces recordamos que la función de 
1 2 n
transición extendida establece que
 q , a=q 1
 q1, x 1 =q 2
 q2, x 2= q3

 qn , x n =q n1
donde únicamente nos interesa el estado final, entonces podemos decir que tiene lógica 
 q , ax = 
decir que   q , a , x  porque nos pide que apliquemos la función de transición 
  al estado  q  junto con el primer elemento de la cadena  ax (es decir sólo a  a ) y luego 
que apliquemos la función de transición extendida    al resto de la cadena (es decir a  x ) 
con el estado dado por      y encontraríamos al estado   q n1 de la misma forma a que si 
aplicaramos de forma consecutiva a    sobre todos los caracteres de  ax .

8. Dada una especificación de componentes léxicos, explique ¿cómo a partir de dicha 
especificación   se   puede   generar   un   analizador   léxico   que   reconozca   dicha 
especificación (i.e. que reconozca cada uno de los componentes léxicos)?

Para cada componente léxico creamos un   − AFN mediante el algoritmo de Thomson. 


Luego, a cada  − AFN le aplicamos el algoritmo de  Cerradura  para generar un  AFN .  A 
cada  AFN  se le aplica el algoritmo de construcción de subconjuntos para crear un  AFD . 
Tomamos el conjunto de   AFD   creados (donde cada   AFD   representa un componente 
léxico) y creamos un único   − AFN   que los contenga a todos; ahora que tenemos un 
único   − AFN y   es   entonces   cuando   le   aplicamos   el   algoritmo   de   Cerradura  para 
generar un único  AFN . Por último, al único  AFN  que contiene a todos los componentes 
léxicos le aplicamos el algoritmo de construcción de subconjuntos para generar un único 
AFD  que es capaz de reconocer a todos los componentes léxicos del lenguaje.
9. Investigación: Complejidad Computacionas y Análisis de Algoritmos

La   complejidad   computacional   (denotada   pon   O  )   es   la   rama   de   las   ciencias   de   la 


computación que estudia de manera teórica, la optimización de los recursos requeridos 
durante la ejecución de un algoritmo para resolver un problema en cuestión (Reyes). 

El análisis se basa en dos aspectos (Reyes):
1. El tiempo: aproximar el número de pasos que se realizarán para la ejecución del 
algoritmo estudiado.
2. El   espacio:   aproximar   la   cantidad   de   memoria   utilizada   para   la   ejecución   del 
algoritmo estudiado.

Actualmente   las   computadoras   (máquinas   deterministas)   pueden   resolver   problemas 


mediante algoritmos que a lo sumo tienen complejidad polinómica (llamados clase P). Los 
argoritmos que tienen costes que sólo las máquinas no­deterministas pueden procesar 
están agrupados en la clase NP (Reyes).

La medida exacta de  la  eficiencia a veces puede  ser computada  pero  para  ello  suele 


hacer   falta   aceptar   supuestos   acerca   de   la   implementación   concreta   del   algoritmo, 
llamada modelo de computación. Un modelo de computación puede definirse en términos 
de un ordenador abstracto y/o postulando que ciertas operaciones se ejecutan en una 
unidad   de   tiempo.   Las   medidas   exactas   de   eficiencia   son   útiles   para   quienes 
verdaderamente implementan y usan algoritmos, porque tienen más precisión y así les 
permite saber cuanto tiempo pueden suponer que tomará la ejecución (Reyes).

Un   resultado   importante   en   teoría   de   la   complejidad   es   el   hecho   de   que 


independientemente de la dificultad de un programa (es decir cuántos recursos de espacio 
y tiempo necesita), siempre habrá problemas más difíciles (Reyes).

Saber si las clases P y NP son iguales es el más importante problema abierto en Ciencias 
de la Computación teórica (de hecho se ofrece un millón de dólares por ser uno de los 
problemas del milenio). Si tomamos un conjuto de problemas de clase P y le llamamos X, 
y tomamos un conjunto de problemas de clase NP y le llamamos Y; entonces si  X Y  o 
X =Y , es decir Y se puede escribir como un conjunto de soluciones de los problemas X. 
En  términos   más  simples,   Y  es   “más   sencillo”  que   X.   También  hay  que   saber  que   el 
conjunto completo más importante en NP­completo (Reyes).

En resumen, los problemas del conjunto NP­completo tienen la característica de que, si se 
llega a encontrar una solución en tiempo P para algún miembro del conjunto (cualquiera 
de los problemas de NP­completo), entonces de hecho existe una solución de tiempo P 
para todol los problemas de NP­completo (Reyes).

10. Investigación: Generadores de Analizadores Léxicos

Un analizador léxico es un módulo destinado a leer caracteres del archivo de entrada, 
donde   se  encuentra   la   cadena  a   analizar;  reconocer  subcadenas que   correspondan   a 
símbolos del lenguaje; y, retornar los tokens correspondientes y sus atributos (Hopcroft, et. 
al., 2001).
Escribir   analizadores léxicos  eficientes  a   mano   puede  resultar  una  tarea   tediosa,  para 
evitarla   se   han   creado   herramientas   de   software   que   generan   automáticamente   un 
analizador   léxico   a   partir   de   una   especificación   provista   por   el   usuario,   denominados 
generadoresde analizadores léxicos (Bavera, et. al., 2003).

Todas las herramientas para generar analizadores léxicos permiten definir la sintaxis de 
los   símbolos   mediante   expresiones   regulares,   mientras   que   sus   atributos   deben   ser 
computados luego del reconocimiento de una subcadenaque constituya un símbolo del 
lenguaje, analizándola (Bavera, et. al., 2003).

En síntesis un generador de analizadores léxicos toma un archivo en el cual se especifica 
el conjunto de reglas (expresiones regulares) que describen completamente al lenguaje 
del que se desea crear el analizador léxico y nos genera el código fuente (programa) que 
realiza la tarea del analizador léxico (Bavera, et. al., 2003).

Algunos generadores léxicos que ya existen son: 
• Lex es para C, muy utilizado en ambiente Unix
• JLex que es una implementación para Java. Además de crear un analizador léxico 
también   genera   un   analizador   sintáctico   y   semántico,   dado   el   mismo   archivo 
origen.

BIBLIOGRAFÍA: 

1. Aho, A; Lam, M.; Sethi, R; Ullman, J. Compilers – Priciples, Techniques, & Tools. 
Segunda edición. 2006. Pearson ­ Addison­Wesley, Estados Unidos de 
Norteamérica.
2. Hopcroft, J.; Motwani, R.; Ullman, J. Automata Theory, Languages, and 
Computation. Second Edition. 2001. Pearson ­ Addison­Wesley, Estados Unidos de 
Norteamérica.
3. Reyes, A. Complejidad computacional (Análisis de Algoritmos). 
http://fisiwikipedia.wikispaces.com/file/view/Complejidad+computacional.pdf 
4. Bavera, F.; Nordio, D.; Arroyo, M.; Aguirre, A. JTLex un Generador de Analizadores 
Léxicos Traductores. 2003. Universidad Nacional de Río Cuarto, Argentina.

S-ar putea să vă placă și