Archive for the 'Uncategorized' Category

20
May
10

Flex+Bison+Qt4 2

Bueno, hoy quiero extender un poco lo que es el uso de flex y bison en Qt4, gracias a la petición de un lector. En esta ocasión lo que se quiere es poder conocer el valor semántico de un identificador, ejemplo:

int variableEntera;

Con código anterior ademas de saber que es una variable, queremos saber cual es su nombre, en este caso “variableEntera”.

Así como el primer artículo, he investigado bastante para encontrar la mejor manera de hacer eso, pero no hay mucha info, así que lo que les propongo me lo invente según lo que pude observar a la hora de estar trabajando con estas herramientas.

Proyecto de de ejemplo: QtFlexBison2.tar.gz

En el archivo scanner.l estan las reglas del analizador léxico. Para generar el código en C++ ejecutamos lo siguiente en la carpeta donde esta el archivo:

flex -d -o scanner.cc scanner.l

Ese comando nos crea el archivo scanner.cc.

En el archivo parser.y estan las reglas del analizador sintactico y semantico. Para generar el código C++ ejecutamos lo siguiente en la carpeta donde esta el archivo:

bison++ -d -hparser.h -o parser.cc parser.y

Ese comando nos crear dos archivos: parser.cc y parser.h

Ahora abrimos el archivo QtFlexBison.pro con Qt Creator y lo compilamos.

Explicación:

El programa consiste en poder reconocer un grupo de variables en un grupo especifico, no tiene nada que ver con algún lenguaje, solo me lo invente para ejemplificar el caso.

La estructura del texto es el siguiente:

principal

{

grupo:nombre

{

var:uno

var:dos

}

grupo:otro_grupo

{

var:tres

var:cuatro

var:cinco

var:seis

}

}

Tenemos 2 grupos, cada uno con sus variables. El programa es capaz de recorrer el texto, saber cuales son los grupos y que variables tienen. Las salida del programa es el siguiente:

grupo: nombre

variable: ‘uno’

variable: ‘dos’

grupo: otro_grupo

variable: ‘tres’

variable: ‘cuatro’

variable: ‘cinco’

variable: ‘seis’

Con esto podemos saber el nombre del grupo y que variables tiene con su respectivo nombre.

Las reglas semánticas se encuentran en el archivo parser.y, en ella se encuentra la manera de poder obtener el nombre del identificador. Algo que quiero resaltar es la manera que se van cumpliendo las reglas, si no se entiende eso no podemos ir obteniendo los valores. En este ejemplo el orden en que se cumplen las reglas es el siguiente:

(Las reglas tienen qDebug() para que se vea el orden en que se cumplieron las reglas)

identificador:  “nombre”     //se encontro el nombre del grupo uno
identificador:  “uno”           //se encontro el nombre de la primera variable
variable: identificador         //se cumplio la regla de variable
identificador:  “dos”           //se encontro el nombre de la segunda variable
variable: identificador         //se cumplio la regla de variable para la segunda
variables: variable               //se cumplio la regla de variables en conjunto
variable variable
grupo                         //se cumple la regla de grupo ( hasta ahora se cumplió esta regla y su nombre fue lo primero que se obtuvo arriba )
identificador:  “otro_grupo”  //se encontro el nombre del grupo dos
identificador:  “tres”
variable: identificador
identificador:  “cuatro”     //se encontro el nombre de la cuarta variable
variable: identificador       //se cumplio la regla de variable para la cuarta
identificador:  “cinco”
variable: identificador
identificador:  “seis”
variable: identificador
variables: variable
variable variable
variable variable
variable variable
grupo                 //se cumple la regla de grupo 2 ( hasta ahora se cumplió esta regla y su nombre fue lo primero que se obtuvo después de terminar el primer grupo )
grupos: grupo
grupo grupo
regla principal      //se cumple la regla principal, se cumple hasta que todo lo demás se haya cumplido

Si se dan cuenta primero encontramos el nombre del grupo o variable y hasta después se cumple la regla que le pertenece, eso hace que tengamos que guardar el nombre en algún lado hasta que se cumpla la regla. Para ese fin use un pila, en la que se ingresan los identificadores y cuando se vayan cumpliendo reglas se van sacando. ejemplo:

Imaginemos

grupo: uno{

var: variable_uno

var: variable_dos

}

La pila se llena asi:

se encuentra el nombre del grupo: uno                                  pila:    uno

se encuentra el nombre del la var1:  variable_uno                           uno

pila:    variable_uno

se cumple la regla de variable: se saca de la pila                   pila:    uno

se encuentra el nombre del la var2:  variable_dos                  uno

pila:    variable_dos

se cumple la regla de variable 2: se saca de la pila          pila:    uno

se cumple la regla de grupo: se saca de la pila            pila:

Como se puede ver se tiene que estar guardando el nombre de los elementos que queremos hasta que se cumpla con la regla que le corresponde.

Es la manera que encontrado para hacer esto, si alguien tiene una mejor manera de hacerlo que nos haga el favor de compartirlo para que aprendamos todos.

Espero que les sirva. =)

12
Jun
09

Flex+Bison+Qt4

Bueno, hoy quiero compartir algo con todos, como trabajar con flex y bison en Qt4. Tenia un proyecto en la universidad, investigue e investigue y no encontre casi nada de información acerca de este tema, encontraba muchos ejemplos comunes del uso de flex y bison pero no como usarlo con Qt4. Encontre algunas cositas como QLALR pero me dio hueva estudiarlo asi que mejor le entre solo a flex y bison. Encontré otros que primero creaban el ejecutable del analizador y luego con un QProcess usaban ese ejecutable, pero no me gusto, creo que es mejor generar el código de los analizadores y luego integrarlos con el proyecto de Qt4, asi que eso vamos a hacer.

Antes que nada quiero decirles que no es la gran cosa el ejemplo, ni se si será la mejor manera de hacerlo, pero me funciono muy bien.

En este ejemplo haremos una calculadora, en el código se muestra como trabajar con archivos para mandarselo como parametro al parser y un objeto Acciones que sirve de intermediario por asi decirlo entre el proyecto Qt4 y el parser. Este no es un turorial de flex y bison asi que solo me voy a limitar en la union con Qt4. Estoy utilizando flex 2.5.35 y bison++ 1.21-8 en GNU/Linux.

Proyecto de ejemplo: prueba_qt4_flex_bison.tar.gz

En el archivo scanner.l estan las reglas del analizador léxico. Para generar el código en C++ ejecutamos lo siguiente en la carpeta donde esta el archivo:

flex -d -o scanner.cc scanner.l

Ese comando nos crea el archivo scanner.cc.

En el archivo parser.y estan las reglas del analizador sintactico y semantico. Para generar el código C++ ejecutamos lo siguiente en la carpeta donde esta el archivo:

bison++ -d -hparser.h -o parser.cc parser.y

Ese comando nos crear dos archivos: parser.cc y parser.h

Ahora abrimos el archivo prueba_qt4_flex_bison.pro con Qt Creator y lo compilamos.

Ya con eso tenemos una sencilla calculadora, ahora solo falta probarla: escribir “2+3*4“, tiene que salir 14

Si se necesita tambien para Windows, pues, el mismo código generado por flex y bison funciona. No se porque el código que genera flex para DOS/Windows no compila, tampoco he tenido tiempo para investigarlo asi que simplemete copie FlexLexer.h que esta en /usr/include y lo pegue en la carpeta de las cabeceras de mingw32, con eso compila nitido en Windows y nuestro programa es multiplataforma.

Espero que les sirva. =)




CGSOL 2008

Publicidad CGSOL 2008