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;
}

No comments:

Post a Comment