Capítulo 3: Gramáticas en JavaCC

          Las grámaticas en JavaCC son propiamente funciones, que tienen el trabajo de leer los tokens, y analizarlos gramaticalmente. Estas funciones leen (dependiendo de un parámetro que es pasado a JavaCC y de acuerdo al código de Java) un archivo o una línea escrita en ese momento, pero esto lo veremos en el siguiente capítulo. Ahora lo que nos interesa es saber como se expresan las Gramáticas en JavaCC.

          A continuación veremos la forma en la que se expresa una Gramática:

Tipo Nombre (Parámetros):
{
   Bloque de Variables
}
{
   Producción
}

          Como una función, tipo es uno de los tipos de variables de Java que pueden ser regresados, si en la gramática el tipo es void no regresará nada, en otro caso, la gramática deberá contener al menos un return. También, nombre es un id que sigue las reglas de Java. En parámetros se colocan parámetros si se creen necesarios, con el mismo formato que Java, en el bloque de variables se definen los tipos de variable, los tipos de variable pueden ser tanto de Java como de JavaCC (más sobre esto en el siguiente capítulo). Para acabar, en la parte de producción se pone la producción de la gramática.

          Ahora si recordamos el capítulo 1, recordaremos que las gramáticas utilizan ciertos símbolos, bueno, pues aquí les pondre los equivalentes de cada símbolo:

 

Simbolo de Gramática
Función
Equivalente en JavaCC
ID

Nombre de no terminal, da el nombre de un no terminal

Nombre de función o llamada a función

 

| Or

|
::=

Produce

 

El segundo bloque de llaves en la función de la gramática.

<E.R.>

Utilización de una expresión regular (terminal)

 

<Nombre de la E.R.> o "E.R."

 

" "

Terminales o símbolos constantes

 

 

En JavaCC no existen estos, si se utiliza una palabra entre " " se infiere que ya fue declarada como E.R. y la busca si no lo encuentra lo tomará como un token de algun tipo ya definido.

Símbolo de nada

 

 

En JavaCC € no existe, así que mediante los mismos simbolos que vimos y definimos en las E.R.'s, se llega a producir €; No existe forma de colocar € directamente en una gramática, sin embargo existe la posbilidad de represntar el caso en el que no encuentre lo que busca.

( )

Agrupación

 

( )

 

 

Repetición


Tanto en gramáticas como en JavaCC la repetición, no es más que una llamada recursiva a la función (gramática)

          Ahora con estos símbolos procedemos a crear la producción; la producción también tiene un formato específico, y este es:

Producción
{
   Que hace si encuentra esta...
}
| Otra Producción
{
   Que hace si encuentra esta...
}
   ·
   ·
   ·

          Producción y Otra Producción no es más que una regla gramatical (en un momento lo veremos), sólo que Otra Producción es opcional pues una gramática puede estar formada por una sola producción, después de la producción se define que pasa si la encuentra, por lo regular se hace un return para regresar algún valor específico. Es importante que se note que cada producción va separada por un or "|" y que cada vez que se define una producción se debe de indicar que pasa si encuentra esa producción, excepto si las dos o más producciones deben de regresar el mismo valor, pues basta con agrupar y colocar los or necesarios (más sobre esto en un momento). JavaCC compila con WARNINGS, pero hay un problema, Java NO, entonces si JavaCC manda WARNINGS es mejor componer los errorer que intentar correr eso en Java, de todas formas Java mandará error.

 

          Definición de Reglas Gramáticales.

          La forma en que JavaCC reconoce las reglas gramáticales, no está muy lejos de lo que se ve en autómatas o en teoría de la computación; pues sólo se deberá colocar como se quieren encontrar los componentes léxicos (E.R.'s). Veamos algunos ejemplos:

<write>"("<cadena>")"";"

Esta regla gramatical acepta la instrucción write, nótese que los paréntesis y el punto y coma están entre comillas, esto es válido, si y solo si, se definió una E.R. que aceptara "(" una que aceptara ")" y una que aceptara ";".

<if>condicion( )<then>

Esta regla gramatical acepta if seguido de una condición, la cual es otra gramática, y seguido de then. Aquí es importante que se note cómo se hace la llamada a otra gramática
<for>asignacion( )(<to>|<downto>)<do>

Aquí vemos como con la agrupación podemos elegir entre to o downto. Esto mismo se puede hacer con toda la función, veamos el siguiente ejemplo
(<id><asignacion><numero>";" | <id>";") Como vemos son dos producciónes diferentes, sin embargo es posible que se requiera mandar el mismo resultado cuando se encuentre éste.

 

          Ya para finalizar el capítulo veremos como se juntan todos los conocimientos aquí adquiridos:

String Write( ):
{
}
{
   <write>"("<cadena>")"";"
     {
        return "encontre la sentencia write";
     }
}

Gramática sencilla de la sentencia write, regresa una cadena que dice "encontré la sentencia write".

String Write2( ):{}
{
   <write>"("Contenido( )")"";"
     {
        return "encontre la sentencia write";
     }
}

void Contenido( ):{}
{
   (<cadena>|<id>)
     {
        return;
     }
   |{
       return;
    }
}

En esta Gramática notamos cómo es que se definen dos o mas gramáticas, haciendo uso de los conocimientos de Java, podemos decir que el orden en el que aparezcan las gramáticas(desde el punto de vista que son funciones) no importa.

También, notamos un |{return;} bueno este es nuestro equivalente al €, no es precisamente €, significa si existe otra cosa que no sea <cadena> ó <id> regresa. El uso de este "Truco" puede ser perjudicial, puesto que si lo notan, ahí nos dice que esta gramática acepta cualquier cosa dentro de los paréntesis, cosa que está mal.

Se preguntarán ¿para qué nos enseña algo que está mal? es simple, para que ustedes no cometan el mismo error que yo cometí. Ahora les diré cual es el código correcto de contenido para forzarlo a aceptar €

          void contenido( ):{}
          {
             (<cadena>|<id>)?
               {
                   return;
                }
          }


^_^ Ahora sí, esta gramática acepta €. De no llegar a un return, esta gramática mandaria un error, el manejo de errores se tratará en el capítulo 5.

 

                      

 

Hosted by www.Geocities.ws

1