Monografias.com > Uncategorized
Descargar Imprimir Comentar Ver trabajos relacionados

Guía básica de Bison y Flex (página 2)



Partes: 1, 2

Declaraciones del Bison

Como se mencionó anteriormente, en esta parte se
declaran los símbolos que se utilizan en gramática y además se definen los
tipos de los valores
semánticos.

Los no terminales se declaran si es necesario asociarle
un valor
semántico.

Ejemplo de declaración de Tokens:

%token NUM /* Se declara un token que tiene asociado el
tipo de datos por
defecto*/

Para crear varios tipos se utiliza

%union {

int itype; /* Definimos un tipo entero que se llama
itype*/

double dtype; /* Definimos un tipo double que se llama
dtype*/

}

Con esta especificación de tipos cuando
declaramos un Token tenemos que especificarle el tipo que tiene
asociado.

%token <itype> TK_INT /* Se declara un Token
literal entero*/

%token <dtype> TK_DOUBLE /* Se declara un token
literal real*/

Precedencia de
los operadores

Se utiliza %left, %right o %nonassoc para especificar la
asociatividad de los operadores, la prioridad se establece por el
orden de aparición en la declaración.

Para declarar un Token de esta forma se trabaja con la
misma sintaxis que para declarar un Token de la forma %token
visto anteriormente.

Ejemplo:

%right '='

%left '-' '+'

%left '*' '/'

%left NEG /* Negación, menos unario */

%right '^' /* Potencia
*/

En este ejemplo definimos que el de menor precedencia es
el operador de asignación y se define que es asociativo
por la derecha, le siguen los operadores de adición y
substracción que tienen la misma precedencia entre ellos,
mayor que la asignación y son asociativos por la
izquierda, así sucesivamente, y por último se
define que el de mayor precedencia es el operador de
potenciación.

Declaración
de no terminales

La misma sintaxis que con %token pero utilizando
%type

Ejemplo:

%type <itype> exp

Donde itype se tiene que haber creado en %union como
vimos anteriormente.

Resumen de las declaraciones del Bison

%skeleton "lalr1.cc": Esta directiva es necesaria
para compilar el proyecto para
C++, la función es
crear los ficheros:

  1. 'position.hh'
  2. 'location.hh' (Estos dos primeros ficheros son
    utilizados para la localización y posición de los
    tokens en el fichero fuente)
  3. 'stack.hh' (Pila auxiliar utilizada por el
    parser)
  4. 'file.hh'
  5. 'file.cc' (Declaración e implementación
    de la clase
    parser, 'file' es el nombre del fichero de salida)

%define "parser_class_name" "name": Cambia el
nombre por defecto de los ficheros 'output.hh' y 'output.cc' por
el definido en "name".

%defines: Se utiliza para especificarle al Bison
que cree el fichero "file.hh", por defecto solo se crea
"file.cc".

%error-verbose: esta directiva se utiliza para
habilitar la muestra de
mensajes de error (%debug habilita el traceo durante el proceso de
parsing)

%parse-param{argument_declaration}: Declara un
parámetro adicional que yylex acepta.

%lex-param {argument_declaration}: Declara un
parámetro adicional que yylex acepta.

%locations: Cuando es usada, el parser habilita
la búsqueda de localizaciones, dos clases auxiliares
definen una posición (un puntero a un archivo) y una
localización (un rango compuesto por un par de
posiciones).

%initial-action: Corre el código
del usuario antes de parsear.

@$: es el conjunto para el rango desde @1 hasta
@n, de una regla con n componentes.

%destructor { delete $$; } "identificador":
Habilita la liberación de memoria durante
el proceso de recuperación de errores.

Introducción
al Flex:

El Flex define las reglas de reconocimiento de
símbolos (Tokens) a partir de expresiones
regulares. Cuando un Token es reconocido por uno de estos
patrones de agrupamiento se le define una acción,
por lo general esta acción es devolver el Tipo y el valor
(lexema).

El Flex cuando se utiliza combinado con el Bison,
utiliza las definiciones de los Tokens realizadas en el Bison
para la
comunicación entre ellos,

Los ficheros del Flex para C++ utilizan por convenio la
extensión ‘.ll’. La sintaxis de un fichero en
flex es la siguiente:

… definiciones …

%%

… reglas…

%%

… subrutinas …

Expresiones Regulares

Caracteres Especiales

Explicación

.

Reconoce todos los caracteres excepto los cambios
de línea

n

Cambio de línea

*

Repite cero o muchas veces

+

Repite una o muchas veces

?

Repite cero o una vez

^

Define el inicio de la expresión

$

Define el final de la expresión

|

Operador OR

""

Define una cadena, dentro se tienen que escapar
los caracteres especiales del C para que se puedan
reconocer, ejemplo: n t …

[]

Agrupa un rango de caracteres de los cuales se
puede seleccionar uno solo en cada momento.

()

Agrupa expresiones regulares.

{}

Expande los tokens o reconoce determinada cadena
que se repitan según el rango que se especifique
entre las llaves

Ejemplos:

abc abc

abc* ab abc abcc abccc …

abc+ abc abcc abccc …

a(bc)+ abc abcbc abcbcbc …

a(bc)? a abc

[abc] Uno entre: a, b, c

[a-z] Una letra en el rango de la a-z

[a-z] Uno entre: a, -, z (Escaparon el menos porque
tiene un significado diferente (El de establecer el rango
cuando esta entre dos valores del
mismo tipo))

[-az] Uno entre: -, a, z

[A-Za-z0-9]+ Al menos un carácter alfanumérico.

[ tn]+ Espacios en blanco.

[^ab] Cualquier carácter excepto: a, b (Porque
^ está al inicio)

[a^b] Uno entre: a, ^, b

[a|b] Uno entre: a, |, b

a|b Uno entre: a, b

{letra}+ si se definió el Token letra, entonces
a partir de esta nueva definición se pueden definir
palabras

a{1,5} reconoce las cadenas donde se repita la 'a' de
1 a 5 veces

Partes del Fichero

Se había mostrado las partes de un fichero en
Flex:

… definiciones …

%%

… reglas…

%%

… subrutinas …

Las definiciones y las subrutinas no son obligatorias,
en las reglas siempre hay que definir al menos una, y siempre
después de ‘%%’ aunque no existan definiciones
y si no existen subrutinas no es necesario poner el último
‘%%’.

Definiciones

En esta parte si una línea comienza con un
espacio en blanco o con un tabulador el contenido de esa
línea se copia exactamente en el fichero de código
C++ que se genera.

Las directivas que se vayan a utilizar en el programa se
colocan entre ‘%{‘ y ‘}%’

Todo lo que se coloque en la primera columna de esta
sección y que no este entre ‘%{‘ y
‘}%’ se tomará como una regla de
sustitución de cadenas de la forma:

nombre patrón

Esto se utiliza para definir los Tokens que se desean
reconocer, por ejemplo:

digito [1-9]

letra [a-zA-Z]

numero {digito}+

palabra {letra}+

blanco [ t]+

rep a{1,5}

Reglas

Las reglas están formadas por un reconocimiento
de un Token y una acción asociada a este reconocimiento,
si no se define ninguna acción no se hace nada cuando se
reconoce dicho Token.

Si aparecen cadenas que no se reconocen por ninguno de
los tokens estas se imprimen como aparecen. Una solución
para que esto no pase es poner una regla que sea '.' que reconoce
cualquier carácter excepto un cambio de
línea, pudiéndole asociar otro comportamiento
como devolver un Token de error léxico, etc.

Las reglas se pueden realizar a partir de lo que se
definió anteriormente, un ejemplo de esto:

{blanco} ;

Esta regla define que no se haga nada al aparecer un
espacio en blanco o un tabulador

{rep} printf("%d", yyleng);

Esta regla define que cada vez que se encuentre una
cadena compuesta por 'a' entre 1 y 5 repeticiones, imprima la
longitud de dicha cadena.

{palabra} printf("%s",yytext);

Cada vez que se encuentre alguna palabra, esta se
imprime en pantalla, si entre dos palabras hay un espacio en
blanco, este no se imprime (por la primera regla)

{numero} printf("n");

Cada vez que se encuentre algún número
imprime en pantalla un cambio de línea.

Cuando las reglas son complejas podemos definirlas entre
llaves y escribirlas en varias líneas.

Subrutinas

Se implementan funciones que
serán copiadas para el fichero con el código en C++
exactamente como se implementan en esta
sección.

 

Datos de los autores:

Daynel Marmol Lacal

Lic. en Ciencias de la
Computación

Profesor de programación

Universidad de las Ciencias Informáticas
(UCI)

Cuidad de La Habana, Cuba

Leansy Alfonso Pérez

Ing. Informático

Profesor de Programación

Universidad de las Ciencias Informáticas
(UCI)

Cuidad de La Habana, Cuba

Categoría del trabajo:
Programación

Partes: 1, 2
 Página anterior Volver al principio del trabajoPágina siguiente 

Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

Categorias
Newsletter