Professional Documents
Culture Documents
Flex
Que es:
Flex es una herramienta para generar analizadores léxicos: programas que reconocen
patrones en un texto. Flex lee los ficheros de entrada dados, o la entrada estándar si no se le
ha indicado ningún nombre de fichero, con la descripción de un escáner a generar. La
descripción se encuentra en forma de parejas de expresiones regulares y código C,
denominadas reglas. Flex genera como salida un fichero fuente en C.
Instalación:
Puede descargar los paquetes de instalación de la siguiente dirección.
http://flex.sourceforge.net/
Primero abra el repositorio (Sistema -> Administración -> Gestor de paquetes Synaptic) y
escriba en el buscador flex, marque el paquete flex como se ve en la imagen.
De clic en aplicar y espere a que termine la instalación. Después abra un terminal y escriba flex
– V le tiene que salir algo parecido a la imagen, listo tiene instalado Flex.
Bison
Que es:
Bison es un generador de analizadores sintácticos propósito general a partir de una
gramática libre de contexto clasificada como LALR (1) este analizador es generado en
código c.
Los analizadores generados por Bison pueden ser utilizados para construir lenguajes
desde pequeños lenguajes como los utilizados en calculadoras de Escritorio, hasta
lenguajes complejos de programación.
Instalación:
Puede descargar los paquetes de instalación de Bison de la siguiente dirección
http://www.gnu.org/software/bison/.
Primero abra el repositorio (Sistema -> Administración -> Gestor de paquetes Synaptic) y
escriba en el buscador bison, marque el paquete bison como se ve en la imagen.
De clic en aplicar y espere a que termine la instalación. Después abra un terminal y escriba
bison - -version le tiene que salir algo parecido a la imagen, listo tiene instalado bison.
Descripción del archivo de entrada:
Estructura general de un archivo bison.
%{
Prólogo
%}
Bison declarations
%%
Grammar rules
%%
Epílogo
Prologo:
En esta área van los include y métodos que el programador considere conveniente escribir,
todo en esto en el lenguaje c.
Bison declarations:
Aquí se incluye las opciones que da bison, como la declaración de terminales y no terminales
que usara en la gramatica.
Si se requiere usar un tipo de dato para los terminales y no terminales se usa esta opción
donde se declara, los tipos que se requiera %union{tipodato id;…así sucesivamente} ejemplo
%union{int Str;}
Grammar rules:
En esta area se localizan la reglas gramaticales que regiran a nuestro analizador
Sintaxis general;
Noterminal: reglas
Ejemplo:
Objetivo:
Aprender a usar flex y bison con qt atraves de un ejemplo sencillo.
Aprender a usar QFileDialog de Qt, para cargar archivos a bison y ejecutar de ahí.
Cargando el archivo:
Se da clic derecho sobre el proyecto y en add new, saldrá un cuadro de dialogo como el de la
imagen de abajo se da clic en choose se coloca el nombre y listo.
Para flex:
Flex –header –file=scanner.h –o scanner.cpp scan.l
Para una lista completa de las opciones sobre flex y bison, escribe en consola, flex --help o
bison –help
Vas a tu carpeta donde generaste tus archivos bison y flex, en nuestro caso fue la misma
carpeta de proyecto, te recomiendo que lo hagas ahí. Seleccionas el archivo, el .h es para la
carpeta Header y el .cpp es para la carpeta Sources. Has lo mismo para los cuatro archivos dos
.cpp y dos .h cada par corresponde a tu analizador léxico y sintáctico.
ANEXO
Les dejo el código de el archivo sca.l, parse.y respectivamente, así como parte de código que
considero interesante.
Guarda un archivo, recibe como parámetro el nombre del archivo,
El contenido que se gurdara lo extrae de la caja de texto
bool inicio::saveFile( QString fileName)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
return false;
}
QTextStream out(&file);
#ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
out << ui->pantalla->toPlainText();//guardando contenido
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
return true;
}
void inicio::on_pushButton_clicked()
{
nameFile=QFileDialog::getOpenFileName(this,tr("abrir"),tr("/home/jose/Escritorio"),tr("Archiv
o de texto (*.txt)"));
QString file= nameFile;
if(!file.isNull()){
ui->pantalla->setText("");
QFile archivo(file);
if (!archivo.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&archivo);
while (!in.atEnd()) {
QString line = in.readLine();
ui->pantalla->append(line);
}
}
}
Este método llama al analizador.
void inicio::on_bcalcular_clicked()
{ setEditor(ui->textEdit); //se agrega el editor donde se dan los resultados
setTexEdit(ui->textEdit); //se agrega el editor donde se mostran los errores
//en nuestro caso es el mismo editor.
//la variable nameFile tiene guardado el nombre del documento analizar, que se abrió con el
QFileDialog, el método toLati1().contsData(), retorna un *char, para compatibilidad con el
método fopen
FILE* input = fopen(nameFile.toLatin1().constData(), "r" );
if (input!=NULL){
saveFile(nameFile);
yyrestart(input);
yyparse();
}
}
Archivo scan.l:
%option noyywrap
%option yylineno
%{
#include "parser.h"
#include <iostream>
#include <QString>
#include <QTextEdit>
QTextEdit* salida;
extern void setTexEdit(QTextEdit* edit1);
void setTexEdit(QTextEdit* edit1)
{
salida= edit1;
}
blanco1 [\t\n]*
digito [0-9]
Numero_Entero {digito}+
Numero_Decimal {digito}+"."{digito}+
%%
{blanco1} {/*Se ignoran los blancos*/}
[+] {return (Nmas); }
[-] {return (Nmenos); }
[*] {return (Npor); }
\/ {return (Ndiv); }
[(] {return (Nparen); }
[)] {return (Ncparen); }
{Numero_Entero} {return (Nent); }
{Numero_Decimal} {return (Nfloat); }
. {ImprimirError(QString("Error Lexico en Fila: %1 en
%2").arg(yylineno).arg(yytext));}
%%
Archivo parser.y:
%{
#include "scanner.h"
#include <iostream>
#include <QString>
#include <QTextEdit>
#include <QList>
%}
%union{
double STR2;
}
%token<STR2> Nmas
%token<STR2> Nmenos
%token<STR2> Npor
%token<STR2> Ndiv
%token<STR2> Nparen
%token<STR2> Ncparen
%token<STR2> Nent
%token<STR2> Nfloat
%type<STR2> RESULTADO