Inicio / Wikis / Tutoriales / Manual de Bison - Archivos de Gramatica de Bison (III)

Manual de Bison - Archivos de Gramatica de Bison (III)

(3 opiniones)
Tutorial creado por
14 de Febrero de 2006
Lenguaje C

Declaraciones de Bison


La sección de declaraciones de Bison de una gramática de Bison define los símbolos utilizados en la formulación de la gramática y los tipos de datos de los valores semánticos. See section Símbolos, Terminales y No Terminales.

Todos los nombres de tipos de tokens (pero no los tokens de caracter literal simple tal como '+' y '*') se deben declarar. Los símbolos no terminales deben ser declarados si necesita especificar el tipo de dato a utilizar para los valores semánticos (see section Más de Un Tipo de Valor).

La primera regla en el fichero también especifica el símbolo de arranque, por defecto. Si desea que otro símbolo sea el símbolo de arranque, lo debe declarar explícitamente (see section Lenguajes y Gramáticas independientes del Contexto).

Nombres de Tipo de Token


La forma básica de declarar un nombre de tipo de token (símbolo terminal) es como sigue:

%token nombre

Bison convertirá esto es una directiva #define en el analizador, así que la función yylex (si está en este fichero) puede utilizar el nombre nombre para representar el código de este tipo de token.

De forma alternativa, puede utilizar %left, %right, o %nonassoc en lugar de %token, si desea especificar la precedencia. See section Precedencia de Operadores.

Puede especificar explícitamente el código numérico para un token añadiendo un valor entero en el campo que sigue inmediatamente al nombre del token:

%token NUM 300

Es generalmente lo mejor, sin embargo, permitir a Bison elegir los códigos numéricos para todos los tipos de tokens. Bison automáticamente seleccionará los códigos que no provoquen conflictos unos con otros o con caracteres ASCII.

En el caso de que el tipo de la pila sea una union, debe aumentar %token u otra declaración de tokens para incluir la opción de tipo de datos delimitado por ángulos (see section Más de Un Tipo de Valor).

Por ejemplo:

%union { /* define el tipo de la pila */
double val;
symrec *tptr;
}
%token <val> NUM /* define el token NUM y su tipo */

Puede asociar un token de cadena literal con un nombre de tipo de token escribiendo la cadena literal al final de la declaración %type que declare el nombre. Por ejemplo:

%token arrow "=>"

Por ejemplo, una gramática para el lenguaje C podría especificar estos nombres con los tokens de cadena literal equivalente:

%token <operator> OR "||"
%token <operator> LE 134 "<="
%left OR "<="

Una vez que iguale la cadena literal y el nombre del token, puede utilizarlo indistintamente en ulteriores declaraciones en reglas gramaticales. La función yylex puede utilizar el nombre del token o la cadena literal para obtener el número de código del tipo de token (see section Convención de Llamada para ##yylex##).

Precedencia de Operadores


Use las declaraciones %left, %right o %nonassoc para declarar un token y especificar su precedencia y asociatividad, todo a la vez. Estas se llaman declaraciones de precedencia. See section Precedencia de Operadores, para información general a cerca de la precedencia de operadores.

La sintaxis de una declaración de precedencia es la misma que la de %token: bien

%left símbolos...

o

%left <tipo> símbolos...

Y realmente cualquiera de estas declaraciones sirve para los mismos propósitos que %token. Pero además, estos especifican la asociatividad y precedencia relativa para todos los símbolos:

  • La asociatividad de un operador op determina cómo se anidan los repetidos usos de un operador: si `x op y op z' se analiza agrupando x con y primero o agrupando y con z primero. %left especifica asociatividad por la izquierda (agrupando x con y primero) y %right especifica asociatividad por la derecha (agrupando y con z primero). %nonassoc especifica no asociatividad, que significa que `x op y op z' se considera como un error de sintaxis.
  • La precedencia de un operador determina cómo se anida con otros operadores. Todos los tokens declarados en una sola declaración de precedencia tienen la misma precedencia y se anidan conjuntamente de acuerdo a su asociatividad. Cuando dos tokens declarados asocian declaraciones de diferente precedencia, la última en ser declarada tiene la mayor precedencia y es agrupada en primer lugar.

La Colección de Tipos de Valores


La declaración %union especifica la colección completa de posibles tipos de datos para los valores semánticos. La palabra clave %union viene seguida de un par de llaves conteniendo lo mismo que va dentro de una union en C.

Por ejemplo:

%union {
double val;
symrec *tptr;
}

Esto dice que los dos tipos de alternativas son double y symrec *. Se les ha dado los nombres val y tptr; estos nombres se utilizan en las declaraciones de %token y %type para tomar uno de estos tipos para un símbolo terminal o no terminal (see section Símbolos No Terminales).

Note que, a diferencia de hacer una declaración de una union en C, no se escribe un punto y coma después de la llave que cierra.

Símbolos No Terminales


Cuando utilice %union para especificar varios tipos de valores, debe declarar el tipo de valor de cada símbolo no terminal para los valores que se utilicen. Esto se hace con una declaración %type, como esta:

%type <tipo> noterminal...

Aquí noterminal es el nombre de un símbolo no terminal, y tipo es el nombre dado en la %union a la alternativa que desee (see section La Colección de Tipos de Valores). Puede dar cualquier número de símbolos no terminales en la misma declaración %type, si tienen el mismo tipo de valor. Utilice espacios para separar los nombres de los símbolos.

Puede también declarar el tipo de valor de un símbolo terminal. Para hacer esto, utilice la misma construcción <tipo> en una declaración para el símbolo terminal. Todos las clases de declaraciones de tipos permiten <tipo>.

Suprimiendo Advertencias de Conflictos


Bison normalmente avisa si hay algún conflicto en la gramática (see section Conflictos de Desplazamiento/Reducción), pero la mayoría de las gramáticas reales tienen confictos desplazamiento/reducción inofensivos que se resuelven de una manera predecible y serían muy difíciles de eliminar. Es deseable suprimir los avisos a cerca de estos conflictos a menos que el número de conflictos cambie. Puede hacer esto con la declaración %expect.

La declaración tiene este aspecto:

%expect n

Aquí n es un entero decimal. La declaración dice que no deben haber avisos si hay n conflictos de desplazamiento/reducción y ningún conflicto reducción/reducción. Los avisos usuales se dan si hay más o menos conflictos, o si hay algún conflicto reducción/reducción.

En general, el uso de %expect implica estos pasos:

  • Compilar su gramática sin %expect. Utilice la opción `-v' para obtener una lista amplia de dónde ocurrieron los conflictos. Bison también imprimirá el número de conflictos.
  • Comprobar cada uno de los conflictos para estar seguro de que la resolución por defecto de Bison es lo que realmente quiere. Si no, reescriba la gramática y vuelva al principio.
  • Añada una declaración %expect, copiando el número n a partir del número que imprime Bison.

Ahora Bison dejará de molestarle con los conflictos que ha comprobado, pero le avisará de nuevo si cambia el resultado de la gramática con conflictos adicionales.

El Símbolo de Arranque


Bison asume por defecto que el símbolo de arranque para la gramática es el primer no terminal que se encuentra en la sección de especificación de la gramática. El programador podría anular esta restricción con la declaración %start así:

%start símbolo

Un Analizador Puro (Reentrante)


Un programa reentrante es aquel que no cambia en el curso de la ejecución; en otras palabras, consiste enteramente de código puro (de sólo lectura). La reentrancia es importante siempre que la ejecución asíncrona sea posible; por ejemplo, un programa no reentrante podría no ser seguro al ser llamado desde un gestor de señales. En sistemas con múltiples hilos de control, un programa no reentrante debe ser llamado únicamente dentro de interbloqueos.

Normalmente, Bison genera un analizador que no es reentrante. Esto es apropiado para la mayoria de los casos, y permite la compatibilidad con YACC. (Los interfaces estandares de YACC son inherentemente no reentrantes, porque utilizan variables asignadas estáticamente para la comunicación con yylex, incluyendo yylval y yylloc.)

Por otra parte, puede generar un analizador puro, reentrante. La declaración de Bison %pure_parser dice que desea que el analizador sea reentrante. Esta aparece así:

%pure_parser

El resultado es que las variables de comunicación yylval y yylloc se convierten en variables locales en yyparse, y se utiliza una convención de llamada diferente para la función del analizador léxico yylex. See section Convenciones de Llamada para Analizadores Puros, para los detalles a cerca de esto. La variable yynerrs también se convierte en local en yyparse (see section La Función de Informe de Errores ##yyerror##). La convención para llamar a yyparse no cambia.

Que el analizador sea o no puro no depende de las reglas gramaticales. Puede generar indistintamente un analizador puro o un analizador no reentrante a partir de cualquier gramática válida.

Sumario de Declaraciones de Bison


Aquí hay un sumario de todas las declaraciones de Bison:

%union Declara la colección de tipos de datos que los valores semánticos pueden poseer (see section La Colección de Tipos de Valores). %token Declara un símbolo terminal (nombre de tipo de token) sin precedencia o asociatividad especificada (see section Nombres de Tipo de Token). %right Declara un símbolo terminal (nombre de tipo de token) que es asociativo por la derecha (see section Precedencia de Operadores). %left Declara un símbolo terminal (nombre de tipo de token) que es asociativo por la izquierda. (see section Precedencia de Operadores). %nonassoc Declara un símbolo terminal (nombre de tipo de token) que es no asociativo (utilizándolo de una forma que sería asociativo es un error de sintaxis) (see section Precedencia de Operadores). %type Declara el tipo de valor semántico para un símbolo no terminal. (see section Símbolos No Terminales). %start Especifica el símbolo de arranque de la gramática (see section El Símbolo de Arranque). %expect Declara el número esperado de conflictos desplazamiento-reducción (see section Suprimiendo Advertencias de Conflictos). %pure_parser Solicita un programa de análisis puro (reentrante) (see section Un Analizador Puro (Reentrante)). %no_lines No genera ningún comando #line del proprocesador en el fichero del analizador. Normalmente Bison escribe estos comandos en el archivo del analizador de manera que el compilador de C y los depuradores asociarán los errores y el código objeto con su archivo fuente (el archivo de la gramática). Esta directiva provoca que asocien los errores con el archivo del analizador, tratándolo como un archivo fuente independiente por derecho propio. %raw El archivo de salida `nombre.h' normalmente define los tokens con los números de token compatible con Yacc. Si se especifica esta opción, se utilizarán los números internos de Bison en su lugar. (Los números compatibles con Yacc comienzan en 257 excepto para los tokens de caracter simple; Bison asigna números de token secuencialmente para todos los tokens comenzando por 3.) %token_table Genera un array de nombres de tokens en el archivo del analizador. El nombre del array es yytname; yytname[i] es el nombre del token cuyo número de código de token interno de Bison es i. Los primeros tres elementos de yytname son siempre "$", "error", e "$illegal"; después de estos vienen los símbolos definidos en el archivo de la gramática. Para tokens de caracter literal y tokens de cadena literal, el nombre en la tabla incluye los caracteres entre comillas simples o dobles: por ejemplo, "'+'" es un literal de caracter simple y "\"<=\## es un token de cadena literal. Todos los caracteres del token de cadena literal aparecen textualmente en la cadena encontrada en la tabla; incluso los caracteres de comillas-dobles no son traducidos. Por ejemplo, si el token consiste de tres caracteres `*"*', su cadena en ##yytname## contiene `"*"*"'. (En C, eso se escribiría como ##"\"*\"*\). Cuando especifique %token_table, Bison también generará definiciones para las macros YYNTOKENS, YYNNTS, y YYNRULES y YYNSTATES; YYNTOKENS El número de token más alto, más uno. YYNNTS El número de símbolos no terminales. YYNRULES El número de reglas gramaticales, YYNSTATES El número de estados del analizador (see section Estados del Analizador).

Múltiples Analizadores en el Mismo Programa


La mayoría de los programa que usan Bison analizan sólo un lenguaje y por lo tanto contienen sólo un analizador de Bison. Pero , ¿qué pasa si desea analizar más de un lenguaje con el mismo programa? Entonces necesita evitar un conflicto de nombres entre diferentes definiciones de yyparse, yylval, etc.

La manera más fácil de hacer esto es utilizar la opción `-p prefijo' (see section Invocando a Bison). Esta renombra las funciones de interfaz y variables del analizador de Bison para comenzar con prefijo en lugar de `yy'. Puede utilizarlo para darle a cada analizador nombres diferentes que no provoquen conflicto.

La lista precisa de símbolos renombrados es yyparse, yylex, yyerror, yynerrs, yylval, yychar e yydebug. Por ejemplo, si utiliza `-p c', los nombres se convierten em cparse, clex, etc.

El resto de las variables y macros asociadas con Bison no se renombran. Estas otras no son globales. Por ejemplo, YYSTYPE no se renombra, pero definirla de diferente forma en analizadores diferentes no provoca confusión (see section Tipos de Datos para Valores Semánticos).

La opción `-p' funciona añadiendo definiciones de macros al comienzo del archivo fuente del analizador, definiendo yyparse como prefijoparse, etc. Esto sustituye efectivamente un nombre por el otro en todo el fichero del analizador.
Valora este capítulo: (3 opiniones)
Autor y licencia de 'Manual de Bison - Archivos de Gramatica de Bison (III)'
Charles Donnelly y Richard Stallman Extraído de: http://es.tldp.org/Manuales-LuCAS/BISON/bison-es-1.27.html GNU Free Documentation License
Licencia GNU Free Documentation License: http://www.es.gnu.org/licencias/fdles.html
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.

Opiniona sobre 'Manual de Bison - Archivos de Gramatica de Bison (III)' (3)

Tu nombre debe tener tres caracteres como mínimo.
Es necesario que te des de alta con una cuenta de correo válida.
Es necesario que te des de alta con una cuenta de correo válida.
El contenido del título de tu opinión debe tener tres caracteres como mínimo.
Es obligatorio que selecciones una valoración del recurso.
El contenido del comentario de tu opinión debe tener tres caracteres como mínimo.

Opina sobre este tutorial



* Valoración:
* Nombre:
* Correo electrónico:
* Título:
* Comentario:

Wikis relacionados con 'Manual de Bison - Archivos de Gramatica de Bison (III)'

Bison es un generador de analizadores sintácticos de propósito general que convierte una descripción gramatical... Más »
Los sistemas cluster hace años que fueron diseñados, la computación paralela y distribuida no es... Más »
Manual Compacto para nuevos usuarios.
El presente texto es una versión ampliada de la conferencia impartida en el ciclo organizado... Más »
Algunos fragmentos de la obra De la Guerra de Karl von Clusewitz. Un manual de... Más »
¿Estás seguro de que deseas eliminar este capítulo?