Monday, February 23, 2015

Metodos y arreglos Codigo 3D

Parametros y llamadas de metodos (Ejemplos)

Utilizando ya el concepto de Stack(pila) como arreglo dinamico para llevar el control de la ejecucion del codigo 3D, desarrollaremos ejemplo de metodos por valor y por referencia donde el primero envia el dato del la variable o bien el numero, en cambio el segundo envia una posicion en la pila
para que sea accedida directamente entonces lo cambio se vean  reflejados asi se realizen en otros metodos que tenga los parametros por referencia.

El siguiente codigo no conoce el concepto de objeto y es estructurado por lo tanto esto
se refleja en el movimiento entre ambitos, se utilizan parametros de tipo entero.

Atributos por valor

Procedure Uno (Z, h int)
var I,J,K : integer
{
J = K + Z * H
}
Procedure Dos
var A,B,C,D: integer
{
A = B * 34 + K
call uno(A,34)
}

Codigo 3D:

Proc Dos
{
t1 = ptr + 0
...
t6 = ptr + 0
t7 = pila[t6]
t8 = ptr + 4
pila[t8]= t7
t9 = ptr + 4
pila[t9] = 34
ptr = ptr + 4
call uno
ptr = ptr - 4
}
proc Uno
{
t1 = ptr + 3
t2 = ptr + 4
t3 = pila[t2]
t4 = ptr + 0
t5 = pila[t4]
t6 = ptr + 1
t7 = pila[t6]
t8 = t5 * t7
t9 = t3 + t8
pila[t1]=t9
}

Atributos por Referencia

Se utiliza el mismo codigo anterior pero en este caso se cambio a parametros referencia los siguientes parametros:

Procedure Uno(var int z, var h int)

tambien la llamado al metodo se cambio de la siguiente manera:

Procedure Dos
{
...
call uno (A,D)
}

Codigo 3D:

Proc Dos
{
...
t6 = ptr  + 0
t7 = ptr + 4
pila[t7] = t6
t8 = ptr + 3
t9 = ptr + 5
pila[t9] = t8
ptr =ptr + 4
call uno
ptr = ptr - 4
}

Proc Uno
{
t1 = ptr + 3
t2 = ptr + 4
t3 = pila[t2]
t4 = ptr + 0
t5 = pila[t4]//se accesa ala pos del parametro y si obtiene la inf que es una pos
t6 = pila[t5]//se obtiene el dato que estaba en la pos de la  inf anterior
t7 = ptr + 1
t8 = pila[t7]
t9 = pila[t8]
t10 = t6 * t9
t11 = t3 + t10
pila[t1] = t11
}

Arreglos Utilizando pila y heap (Ejemplo)

Todo tipo de dato no primitivo se almacena en el heap sea este de una variable local o global.
Se asume que el arreglo tiene valores desde 0 a hasta el numero tamaño-1 donde: MAT[10,10]

MAT[X,Y] = 15

Codigo 3D:

t1 = ptrh + 2//punt del heap mas la pos obtenida de tabla de simbolos
t2 = ptr + 0
t3 = pila[t2]
t4 = ptr + 1
t5 = pila[t4]
t6 = t5 - 1
t7 = t6 * 10
t8 = t7 + t3
t9 = t1 + t8//se suma el punt de inicio del arreglo mas la pos
heap[t9] = 15 //en esa posicion en el heap se ingresa el valor

Tuesday, February 10, 2015

Codigo 3 Direcciones Ejemplos

CODIGO 3 DIRECCIONES (Ejemplos Basicos Resueltos)

Ejemplo:

Genera el codigo intermedio de :  (a * b + h) - j * k + 1
                                                            Reutilizacion de temporales 
t1 = a * b                                                  t1= a * b 
t2 = t1 + h                                                t2 = t1 + h
t3 = j * k                                                  t1 = t1 - t2
t4 = t2 - t3                                                t1 = t1 + 1 
t5 = t4 + 1

Genera el codigo intermedio de : a + b * (c + d) * (f + k ) * d 

                                                            Reutilizacion de temporales 
t1 = c + d                                                  t1= c + d
t2 = t1 * b                                                 t1 = t1 * b
t3 = f  + k                                                  t2 = f  + k
t4 = t2 * t3                                                t1 = t1 * t2 
t5 = t4 * d                                                 t1 = t1 * d
t6 = a + t5                                                 t1 = a + t1

Escriba el codigo de 3 direcciones de:  a > b OR b <  k + h AND f * b + d == z OR NOT k>f
t1 = a > b
t2 = k + h
t3 = b < t2
t4 = f  * b
t5 = t4 + d
t6 = t5 == z
t7 = t3 AND t6
t8 = t1 OR t7 
t9 = k > f
t10 = NOT t9
t11 = t8 OR t10 

Hacer el codigo 3 direcciones de la expresion : a > b + h OR b == d teniendo la restriccion de que los operadores realaciones no se puede escribir directamente (t1= t2 >b)

t1 = b + h
if  a > t1 the goto l1
goto l2

l1:

t2 =1
goto l3

l2: 

t2=0

l3:
if b ==d then goto l4
goto l5

l4: 

t3= 1
goto l5

l5:

t3 =0

l6:

t4= t2 or t3 

Corto Circuito


 Es ejecutar el codigo de manera  tal que si estamos evaluando un operador logico AND y la primera operacion es falsa el resultado sera falso. De igual manera si es OR si la primera es comparacion es verdadera entonces es verdadera. Esto segun las propiedades logicas del operador.

OR

Ejemplo:

Generar codigo de 3 direcciones de la entrada: a > b OR b < f OR d == k

if a > b then goto l1
goto l2

l2: 

if b < f then goto l3 
goto l4

l4: 

if d == k then goto l5
goto l6

l1, l3, l5:

t1=1
goto l7

l3, l4, l6:

t1=0

l7:


AND

Ejemplo:

Generar codigo de 3 direcciones de la entrada: a > b AND b < f AND d == k

if a > b then goto l1
goto l2

l1: 

if b < f then goto l3 
goto l4

l3: 

if d == k then goto l5
goto l6

l5:

t1=1
goto l7

l2, l4, l6:

t1=0

l7:


XOR

Generar codigo 3D para la entrada: a XOR b

if a then goto l1
goto l2

l2:

if b then goto l3
goto l4

l1:

if b then goto l5
goto l6

l3,l6:

goto l7

l5,l4:

l7:



NOT ( ! )

Es la negacion de cualquier expresion de tipo booleana, si esta era falsa sera entonces verdadera.


Ejemplo:


Generar codigo de 3D para la siguiente codicion : NOT (a < 5 AND b == 20)

if a < 5 then goto l1
goto l2 
l1:
if b == 20 then goto l3
goto l4
l2,l4:
t1 = 0
goto l5
l3:
t1 = 1
l5:

EJEMPLOS MEZCLADOS

Generar codigo de 3 direcciones para la entrada: a > b AND b > f OR  d == k


Codigo 3D:

if a > b then goto l1
goto l2

l1:
if b > f then got l3
goto l4

l2,l4:

if d ==k then goto l5
goto l6

l3, l5:

t1=1
goto l7

l6 :

t1 = 0

l7:

Generar codigo de 3 Direcciones de la siguiente entrada: (a > b OR  b < f ) AND d == k 

if a > b then goto l1
goto l2

l2: 

if b < f then goto l3
goto

l1,l3:
if d == k then goto l5
goto l6

l5: 

t1 =1
goto l7

l4, l6:

t1 = 0

l7:



REPEAT 

Entrada :  repeat { Sentencias } until cond
Linicio:
            < codigo sentencias >
            < codigo condicion >
Lf:
goto Linicio
Lv:
WHILE 
Entrada: while cond Do { Sentencias }
Linicio:
                 < codigo condicion>
Lv:
                  < codigo sentencias>
Lf:
-------------------------------------------------------------------------------------------------------------
Entrada : Do { Sentencias } while cond
goto Lsent
Lcond:
               < codigo condicion >
Lv:
Lsent:
               < Codigo sentencias >
               goto Lcond
Lf:
--------------------------------------------------------------------------------------------------------------
Escriba el codigo en 3 Direcciones:
if a > b and k > f 
{

while a > b do
{
a = a + b
if a == b 
b = b - 1
}else{ 
break
}
b= b + 1
}
while a + b * 2 > f + k 
{
a = b + f * k
break
}
break
}
}else{
a = a + b
}
Codigo 3D:



if a > b then goto l1
goto l2
l1: 
if k > f then goto l3
goto l4
l3:
l5:
if a > b then goto l7
goto l8
l7:
t1 = a + b
a = t1
if a == b then goto l9
goto l10
l9:
t2 = b -1 
b = t2
goto l11
l10:
goto l6
l11:
t3 = b + 1
b = t3
l12:
t4 = b * 2
t5 = a + t4
t6 = f + k
if t5 > t6 then goto l4
goto l5
l14:
t7 = f  * k
t8 = b + t7
a = t8
goto l13
goto l12
l15:
l13:
goto l6
goto l5
l8:
l6:
goto l16
l2, l4:
t9 = a + b
a = t9
l16:
Break's: l6,l3


SWITCH
Entrada:

Switch(E)
{
  val1: sentencias 1
  val2: sentencias 2
  .
  .
  .
   valn: sentencias n
}

Codigo 3D:

< codigo E >

   if Eval != val 1 then goto l1
        < codigo sentencia 1>
       goto Lsalida

l1:
   if Eval != val2 then goto l2
       < codigo sentencia 2 >
       goto Lsalida

l2:
.
.
.
   if Eval != valn then goto ln
       < codigo sentencia n >
       goto Lsalida
ln:

Lsalida:

Sunday, February 8, 2015

Examenes Compiladores

EXAMENES COMPILADORES 2 FIUSAC

Por aqui dejare parciales y finales que tengo, muy viejos y otros recientes espero les sirvan, si resuelven unos 5 para cada parcial, iran a divertirse al examen.

Primer Parcial










Segundo Parcial



Tercer Parcial




Primer,Segundo y Tercer Parcial



Examen Final


Arreglos Codigo 3 Direcciones

ARREGLOS EN CODIGO 3D

Para el siguiente arreglo: ARR[4 (filas), 5 (columnas)]. Asumiendo que tenemos informacion en las primeras 2 filas de la forma (Donde el par de numeros corresponde a fila,columna(11= fila 1, columna 1): {{11, 12,13,14,15},{21,22,23,24,25}}. 
Para poder representar este arreglo de mas de 1 dimension en codigo 3D vamos a realizar Mapeo Lexicografico un tema que la mayoria maneja.  

EL mapeo convertiria el arreglo anterior en:

Acceso por filas: {11,12,13,14,15,16,17,18,21,22,23,24,25}

Acceso por columnas: {11,21,31,41,12,22,32,42}
Ejemplo:

MAT[x,y] = 10 para MAT[1..10,1..3]. 10 filas, 3 columnas.

Acceso por Filas

formulaPos = ( x - 1)* tamCol + y

t1= x - 1
t2 = t1 * 3
t3 = t2 + y
MAT[T3] = 10

Acceso por Columnas

formulaPos = (y -1)* tamfila + x

t1 = y - 1
t2 = t1 * 10
t3 = t2 + x
MAT[t3] = 10

Formula Acceso por filas consecutivas:  x + (y-1)tam1 + (z-1)*tam2*tam1
Formula Acceso por columnas consecutivas:  (x-1)* tam1 + y + (z-1)* tam2*tam1

Otra Propuesta:

Formula Acceso por filas consecutivas : (x * tam1 + y) * tam2 + z

 
Escribir el codigo de 3 Direcciones de el la siguiente asignacion: 
ARR[x,y,z] = ARR[ARR[a,b,c],y,z]   Donde ARR[1..10,1..7,1..3] utilizando acceso por Columnas

Propuesta 1:
t1= x - 1
t2 = t1 * 10
t3 = t2 + y
t4 = z -1
t5 = t4 * 30
t6 = t3 + t5
t7 = a - 1
t8= t7 * 10 
t9 = t8 + b
t10 = c - 1
t11 = t10 * 3
t12 = t11 + t9 
t13 = ARR[t12]
t14 = t13 - 1
t15 = t14 * 10 
t16 = t15 + y 
t17 = z - 1
t18 = t17 * 30
t19 = t16+ t18
t20 = ARR[t19]
ARR[t6] = t20

Otra propuesta(la encontre en un cuaderno de un companiero aun no la entiendo):

t1 = x - 1
t2 = t1 * 7
t3 = t2 * 3
t4 = y - 1
t5 = t4 * 3
t6 = t3 + t5
t7 = t6 + z
t8  = a - 1
t9 = t8 * 7
t10 = t9 * 3
t11 = b - 1
t12 = t11 * 3
t13 = t10 + t12
t14 = t12 + c
t15 = t14 - 1
t16 = t15 * 7
t17 = t16 * 3
t18 = y - 1
t19 = t18 * 3
t20 = t17 + t19
t21 = t20 + z
t22 = ARR[t21]
ARR[t7] = t22 

Si aun no entiendes puedes ver el siguiente blog donde explican de manera detallada los arreglos en 3 dimensiones : Arreglos

Saturday, February 7, 2015

Codigo 3 Direcciones

CODIGO 3 DIRECCIONES

Tabla de Simbolos


Existen tablas de simbolos como colores en el mundo, pero es necesario tener un estandar y entonces las columnas basicas necesarias son explicadas en este documento. Es importante guardar en la tabla de simbolos los atributos necesarios. Puedes usar mas de 1 pasada para llenar tu tabla de simbolos. Una excelente tabla de simbolos te simplificara de gran manera la generacion de codigo 3D.




Stack y Heap

La utilizacion de estos dos vectores de tipo entero es primordial al ejecutar el codigo 3D, Aqui se maneja el cambio de ambito( llamada de metodos), manejo de objetos(Heap), instancias de los mismos. En la clase teorica puede que nunca se utilizen pero se utilizan en los proyectos de laboratorio.




Metodos


Los metodos son subrutinas  muy parecidas a las subrutias del codigo ensamblador que al final es codigo de 3 Direcciones. La ejecucion de los metodos es manejada principalmente en el Stack con la ayuda de punteros descrits en el documentos, el stack es una estructura dinamica durante la ejecucion del codigo.






Objetos 

La abstraccion de los objetos es un poco dificil de entender, pero es muy importante saber el algoritmo correcto y eficiente para poder transformar a 3d cualquier tipo de codigo actual,ya que la mayoria de programacion es orientada a objetos.





Si te es dificil entender puedes consultar un ejemplo publique aca : Link

Metodos y Clases


Cuando creamos una clase, esta podria ser traducible a codigo 3D con todos sus atributos asi sea una clase extendida, o bien tenga atributos importados, los metodos de clases importadas o extendidas tambien deben ser traducidos de manera correcta. Entonces como se maneja este tipo de casos:



Nota: Los documentos publicados no son de mi autoria, fueron redactados por el auxiliar de catedra para los alumnos.

Ejercicio

Ejercicio completo incluye codigo 3D y optimizacion  de codigo.

A. Generar su representacion intermedia usando codigo de 3 dimensiones.
B. Señalar sus bloques basiCos y construir el diagrama de flujo.


       
int A[200];

int B[100];

suma = 0;

for(i =0 ; j =100 ; i <100; i++,j--_
{

    if((A[j*2]+B[i] > 350 )
    {
      k =0;
      while(k<i)
     {
        B[i] = B[i] +A[k*2];
        k++;
     }
   }
   suma = suma + B[i];
}
final = (suma -100)      
 

Friday, February 6, 2015

Optimizacion de Codigo 3D(Teoria)

OPTIMIZACION DE CODIGO 

La optimizacion de codigo reduce redundancias y codigo demas, al quitar este codigo no se modifica el flujo del programa, pero se optimiza el tiempo de compilacion y ejecucion del mismo.

 

GRAFO ACICLICO DIRIGIDO

Al optimizar podemos utilizar el algoritmo de construccion de GDA, Se presentan los pasos y los casos para construirlo, ademas un ejemplo de como funciona.



Ejemplo:

       
int[100] a;

void quicksort(int m,n) {
         int i,j; int v,x;
         if (n <= m) return;
         i = m - 1; j = n;
         v = a[n];
         while(1)
         {
                do i = i + 1
               while (a[i] < v);
               do j = j - 1             
               while (a[j] > v);
               if (i >= j) break;
               x = a[i];
               a[i] = a[j];
               a[j] := x;
        }
       x = a[i];
       a[i] = a[n];
       a[n] := x;
       quicksort(m, j);
       quicksort(i + 1, n);
}      
 



Manejo Objetos Codigo 3D

Codigo 3D Objetos


Ya que en clase dificilmente den la parte de objetos y sea el axuliar(es) el encargado, este documento puede servirles. A continuacion un ejemplo creado por el auxiliar de catedra de ese semestre. Es lo mas Entendible que encontre con respecto al manejo de objetos.


Manejo de Objetos.pdf

Thursday, February 5, 2015

Ejemplos Gramaticas

Gramaticas

Ejercicios de Gramaticas que encontre en un mi cuaderno y en un  blog, casi siempre se ven los mismos ejercicios y practicar es lo IMPORTANTE aqui.(si existe algun error porfavor comentarlo).
via : Fuente

Problema 1

Gramatica  descendente que utiliza atributos sintetizados y heredados, para sumar y multiplicar. Retorna el valor de la operacion

S ->E {write("El resultado es: ", E.val); }

E ->  T { Eh.val = T.val; } E' { E.val = E'.val; }
 
E' -> + T {E'1h.val = E'h.val + T.val; } E' { E'.val = E'1.val;}
          | ɛ {E's.val = E'h.val;}

T -> F {T'h.val = F.val; } T' {T.val = T'.val;} 

T' -> * F {T'1h.val = T'h.val;} T'{ T'.val = T'1.val;}
          | ɛ {T's.val = T'h.val;}

 F ->  ( E )  {F.val = E.val; }
          | num   { F.val = val(num); }


Problema 2

Escriba una definicion dirigida por la sintaxis para una gramatica que reconoce expresiones aritmeticas en notacion postfijo, de tal manera que genere la misma expresion pero en notacion prefijo e infijo.

S ->E {write(“prefijo: “, E.pre); write(“infijo:”, E.inf); }

 E ->  E E +  { E.pre = concat(‘+’, E1.pre, E2.pre); E.inf = concat(E1.inf, ‘+’,
          E2.inf); }
       | E E  {E.pre = concat(‘’,E1.pre, E2.pre); E.inf = concat(E1.inf, ‘’,E2.inf); }
       | E E * { E.pre = concat(‘*’, E1.pre, E2.pre); E.inf = concat(E1.inf, ‘*’, E2.inf); }
       | E E /  { E.pre = concat(‘/’, E1.pre, E2.pre); E.inf = concat(E1.inf, ‘/’, E2.inf); }
       | ( E )   { E.pre = E1.pre; E.inf = E1.inf; }
       | num   { E.pre = num; E.inf = num; }




Problema 3

Para la siguiente gramatica que reconoce expresiones regulares, escriba una definición dirigida por la sintaxis que genere el arbol de la expresion y que al final pueda indicar cuantas hojas fueron creadas, y ademas que muestre la misma expresion regular sin parentesis redundantes.

Precedencia en expresiones regulares:
*=1
.=2
|=3

S -> E
E: -> E E {  E.ptr=crear_Nodo(‘|’,E1.ptr,E2.ptr);
                    E.cad=concat(E1.cad,’|’,E2.cad);
                    E.pre=1;
              }
E -> E
 . E{ E.ptr=crear_Nodo(‘.’,E1.ptr,E2.ptr);
                 if (E1.pre<2) Then E1.cad=concat(‘(‘, E1.cad, ‘)’);
                 if (E2.pre<2) Then E2.cad=concat(‘(‘, E2.cad, ‘)’);
                 E.cad=concat (E1,’.’,E2);
                 E.pre=2;
            }
E -> E * E{   E.ptr=crear_Nodo(‘*’,E1.ptr,E2.ptr);
                   if (E1.pre<3) Then E1.cad=concat(‘(‘, E1.cad, ‘)’);
                   if (E2.pre<3) Then E2.cad=concat(‘(‘, E2.cad, ‘)’);
                   E.cad=concat (E1,’*’,E2);
                   E.pre=3;
             }
E -> ){   E.ptr=E1.ptr;
                  E.cad=E1.cad;
                  E.pre=E1.pre;
             }
E:-> id { E.ptr=Nodo_Hoja(id);
             E.cad=id;
             E.pre=4;
         }
E -> num { E.ptr=Nodo_Hoja(num);
                 E.cad=num;
                 E.pre=4;
              }

Problema 4

Escriba una gramatica que reconozca numeros binarios de la forma 101.101 teniendo como componente lexico el 0 y el 1, escriba una definicion dirigida por la sintaxis que calcule el valor correspondiente en decimal. 
Ejemplos: 1.1 en decimal equivale a 1.5, 10.10 en decimal equivale a 2.5, 11.11 en decimal equivale a 3.75, 101.101 en decimal equivale a 5.625.

Problema resuelto utilizando Atributos Heredados:

S -> {L1.ladoh = 1; }L .{L2.ladoh = 0; } L { write (L1.val +”.”+ L2.val); }
       |L { write (L1.val ); }
L -> {L1.lado = L.lado }L B {
                                                 L.base = L1.base*2;
                                                 if (L.lado==1)
                                                      L.val = L1.val*2+B.val;
                                                 else
                                                      L.val = L1.val+B.val / L.base;
                                             }
L -> {B1.lado = L.lado }B {
                                            L.base =2
                                            if (L.lado==1){
                                                L.val = B.val;
                                           }else{
                                                L.val =B.val / 2;
                                        }}
B  ->  0 { B.val=0;}
        | 1 { B.val=1;}

Cadenas de Entrada de prueba:

101.101 = 101 = 2^2 + 0^1 + 2^0 = 4 + 0 + 1 = 5
0.101 = 1*1/2 + 0*1/4 + 1*1/8 = 0.625

Problema resuelto utilizando Atributos Sintetizados:

S ->   L L { write (L1.val1 +”.”+ L2.val2); }
         | L { write (L1.val1 ); }
L -> L B {
                 L.base = L1.base*2;
                 L.val1 = L1.val1*2+B.val;
                 L.val2 = L1.val2+B.val / L.base;
              }
L -> B {
               L.base =2;
               L.val1 = B.val;
               L.val2 =B.val / 2;
}
B ->   0 { B.val=0; }
       | 1 { B.val=1; }

Problema 5

Escriba una definicion dirigida por la sintaxis donde unicamente utilice atributos sintetizados, para una gramatica que reconozca la declaracion de variables de acuerdo a la siguiente sintaxis: [tipo] Lista de identificadores: la que consta de un tipo (integer o char), seguido de una lista de identificadores y a partir de ello obtener la salida: Tipo:identificador, para cada identificador. Asuma que utiliza un analizador de sintaxis ascendente. Ejemplo:

Cadena de entrada: integer [a,b,c]

Salida: a:integer
b:integer
c:integer

S -> L ‘]’
L -> L ,id{
                   write(id,’:’,L1.tipo);
                   L.tipo=L1.tipo;
               }
       |’integer’ ‘[‘ id{
                             write(id,’:’,’integer’ );
                             L.tipo=’integer’;
                        }
        |’char’ ‘[‘ id{
                        write(id,’:’,’char’ );
                        L.tipo=char;
                     }

Problema 6

Escriba una definicion dirigida por la sintaxis que reconozca el mismo lenguaje y genere la misma salida del tema anterior (Problema 5), pero asuma que el analizador de sintaxis es descendente. 

S -> L ]

L -> TIPO [ id { write(id,’:’,Tipo.tipo); Lh’.tipo=TIPO.tipo} L{L.tipo=Ls’.tipo; }

L’ -> , id { (id,’:’,Lh’.tipo); Lh’.tipo=L’.tipo } L’ { L’.tipo= Ls’.tipo; }  
        | epsilon{Ls’.tipo=Lh’.tipo; }

TIPO -> char { TIPO.tipo=char;}
              |int { TIPO.tipo=int;}

Problema 7

Las siguientes reglas definen la traduccion de una palabra en ingles al seudolatin:
  • Si la palabra comienza con una cadena no vacia de consonantes, desplegar la cadena inicial de         consonantes al final de la palagra y añadir el sufico AY, por ejemplo: PROBLEM se compierte en OBLEMPRAY
  •  Si la palabra comienza con una vocal, añadir el sufico YAY, por ejemplo: OWL se convierte en OWLYAY
  •  U depues de Q es una consonante
  •  Y al inicio de una palabra es una vocal si no va seguida de una vocal
  •  Las palabras de una sola letra no se modifican
TERMINALES

C= todas las letras consonantes excepto la letra Y 
V=letras vocales
UQ = uq 
Y = y

S -> L

L -> LCo    L { write(L.cad, LCo.cad,’AY’) } 
//Lista de consonantes seguido de lista de cualquier letra
      |LVo    L  { write(LVo.cad, L.cad, ‘YAY’) } 
//Lista de vocales seguido de lista de cualquier letra
        |Y    LCo  L  {write(L.cad, LCo.cad,Y, ’AY’) }
// letra Y seguido de lista de consonantes seguido de lista de cualquier letra
       |Y    LVo   L  {write(write(L.cad,Y, ’AY’) ) }
//Letra Y seguidoLista de vocales seguido de lista de cualquier letra

LCo -> LCo   C  {LCo.cad=LCo1.cad+C } //LCo es lista de consonantes menos la letra Y
            |LCo  UQ  {LCo.cad=LCo1.cad+UQ }
            |LCo   Y  {LCo.cad=LCo1.cad+Y }
            |C { LCo.cad=C }
            |UQ  { LCo.cad=UQ }

LVo -> LVo V   { LVo.cad=LVo1.cad+V} / /LVo es lista de vocales
           | V { LVo.cad=V }

L -> L C   { L.cad=concat(L.cad+C) } // Es lista de cualquier cosa
       |L V  { L.cad=concat(L.cad+V) }
       |UQ  { L.cad=uq }
       |Y     { L.cad=y }

Problema 8

Para una gramatica que reconozca de expresiones aritmeticas escriba un esquema de traduccion que permita evaluar las expresiones y muestre el valor final asumiendo que el operador “+” tiene mayor precedencia que el operador “*”.

S -> E       {write(“El valor es: ”, E1.val) ;}
E -> E T  {E.val=E1.val*T.val ;}
      | T       {E.val=T.val ;}
T -> T F  {T.val=T1.val+F.val ;}
      |F       {T.val=F.val ;}
F -> (E)    {F.val=E.val ;}
      |num   {F.val=num ;}

Problema 9

Escriba una definición dirigida por la sintaxis para una gramática que reconozca la declaración de variables de acuerdo a la sintaxis del lenguaje pascal, la que consta de una lista de identificadores seguida de un tipo de dato (integer o char) y a partir de ello obtener la siguiente salida: (solo debe usar atributos sintetizados). 
ejemplo:
Cadena entrada: a,b,c: integer; Salida: 
   a->integer
   b->integer
   c->integer

Total de variables declaradas: 3

Dec  -> ListaDec{ print(ListaDec.cad)}

ListaDec -> id , ListaDec{ ListaDec.tipo=ListaDec1.tipo;
                                         ListaDec.cad=concat(Id, '>',ListaDec1.tipo, ',' ListaDec.cad);
                                      }
                  | id : TIPO { ListaDec.tipo=TIPO.tipo ListaDec.cad=concat(id, '>', TIPO.tipo); }

TIPO  -> ’char’ { TIPO.tipo=’char’; }
              | ’int’   { TIPO.tipo=’integer’; }

Solucion propuesta por el ingeniero:

S -> X
X -> {L.tipo=TIPO.tipo} L ‘:’ TIPO
L ->  L , id{ write(id,L1.tipo); }
       |id  { write(id,L.tipo); }
TIPO -> ’char’{ TIPO.tipo=’char’; }
            |’int’{ TIPO.tipo=’int’;}

Lo que dice el ingeniero es que es la solucion correcta pero no se puede implementar, todos los atributos sintetizados son por la izquierda, los atributos heredados no siempre van a ser por la izquierda.

Problema 10

Para una gramática que reconoce expresiones aritméticas, con los operadores de + y *, escriba una definición dirigida por la sintaxis para un analizador de sintaxis ascendente, que transforme la expresión de entrada, como se muestra en los ejemplos siguientes:

Entrada: 1, Salida : 1
Entrada : 1 + 2+3, Salida : SUM ( 1,2,3)
Entrada : 1 + 2 * 3, Salida : SUM ( 1, MUL ( 2,3))
Entrada: 1 + 2 +3*4 *3+5 +6, Salida: SUM ( 1, 2, MUL (3, 4, 3), 5, 6)
Entrada: (1+ 2+3) * 4 * ( 3 + 5+ 6), Salida : MUL ( SUM (1, 2, 3) , 4, SUM (3, 5, 6))
Entrada (2 + 3) * 4 * ( 3 + 5), Salida : MUL ( SUM (2, 3), 4 , SUM (3, 5))

S -> E { if(E.op=1) write(‘sum(‘,E.op’)’);
             if(E.op=2) write(‘mul(‘,E.op’)’);
           }
E -> E E{ if(E1.op!=1 and E1.op!=0){
                     E1.cad=concat(‘mul(‘ , E1.cad, ’)’); }
                if(E2.op!=1 and E2.op!=0){
                     E2.cad=concat(‘mul(‘ , E2.cad, ’)’); 
                     E.cad=concat(E1.cad, ‘ , ’ , E2.cad);
                     E.op=1; }
               }
        |E E  { if(E1.op!=2 and E1.op!=0){
                       E1.cad=concat(‘sum(‘ , E1.cad, ’)’); }
                  if(E2.op!=2 and E2.op!=0){
                       E2.cad=concat(‘sum(‘ , E2.cad, ’)’);
                       E.cad=concat(E1.cad, ‘ , ’ , E2.cad);
                       E.op=2; }
                  }
        |(E)      {E.cad=E1.cad; E.op=E1.op;}
        |num    {E.cad=NUM.cad; E.op=0;}

Otra posible solucion:

S -> E{ write(E1.op,’(‘,E1.cad,’)’); }
E -> E E{
          if(E1.op==”” || E1.op==”sum”){
               E.cad=concat(E1.cad,’,’);
          }else{
               E.cad=concat(E1.op,’(‘,E1.cad,’)’);
          }
          if(E2.op==”” || E2.op==”sum”){
               E.cad=concat(E.cad,E2.cad,’,’);
          }else{
               E.cad=concat(E.cad,E2.op,’(‘,E2.cad,’)’);
          }
     }
      | E E {
        if(E1.op==”” || E1.op==”mul”){
             E.cad=concat(E1.cad,’,’);
        }else{
             E.cad=concat(E1.op,’(‘,E1.cad,’)’);
        }
        if(E2.op==”” || E2.op==”mul”){
             E.cad=concat(E.cad,E2.cad,’,’);
        }else{
             E.cad=concat(E.cad,E2.op,’(‘,E2.cad,’)’);
        }
}
|num{
        E.op=””;
        E.cad=num;
}