Manual Flex y Bison Con Qt

13
UNIVERSIDAD DE SANCARLOS DE GUATEMALA Organización de lenguajes y Compiladores 1 Creado por: José Manuel González Alvarez Manual Flex y Bison con Qt Primeros pasos

description

UNIVERSIDAD DE SANCARLOS DE GUATEMALAOrganización de lenguajes y Compiladores 1Manual Flex y Bison con QtPrimeros pasosCreado por: José Manuel González AlvarezINTRODUCCIONEl siguiente manual presenta una introducción de cómo utilizar conjuntamente Bison Flex y Qt, se presenta una introducción ambas herramientas, después se explica la instalación de las misma sobre el sistema operativo Linux, y se concluye con un ejemplo practico para observar como se utilizan juntas estas herramientas.

Transcript of Manual Flex y Bison Con Qt

Page 1: Manual Flex y Bison Con Qt

UNIVERSIDAD DE SANCARLOS DE GUATEMALA

Organización de lenguajes y Compiladores 1

Creado por: José Manuel González

Alvarez

Manual Flex y Bison con Qt Primeros pasos

Page 2: Manual Flex y Bison Con Qt

INTRODUCCION

El siguiente manual presenta una introducción de cómo utilizar conjuntamente

Bison Flex y Qt, se presenta una introducción ambas herramientas, después se explica

la instalación de las misma sobre el sistema operativo Linux, y se concluye con un

ejemplo practico para observar como se utilizan juntas estas herramientas.

Notas del Autor

Este manual solo es una inicialización a esta tecnología así que no se

profundiza, tanto en la sintaxis de la herramienta y se supone un conocimiento mínimo

del lector.

El objetivo primordial, es despertar el interés del lector hacia eta tecnología y

que le sirva como una guía inicial, para uso.

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/

A continuación se presenta una instalación desde el sistema operativo Linux utilizando la

distribución Ubuntu.

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.

Page 3: Manual Flex y Bison Con Qt

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.

Page 4: Manual Flex y Bison Con Qt

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/.

A continuación se presenta una instalación desde el sistema operativo Linux utilizando la

distribución Ubuntu.

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.

Page 5: Manual Flex y Bison Con Qt

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;}

Para declarar un terminal

%token<Tipodato> id; ejemplo %token<Str> nEntero;

Grammar rules:

En esta area se localizan la reglas gramaticales que regiran a nuestro analizador

Sintaxis general;

Noterminal: reglas

Ejemplo:

RESULTADO: RESULTADO Nmas RESULTADO

También se pueden colocar acciones

RESULTADO: RESULTADO Nmas RESULTADO{/*código c. */}

Utilizar Bison y Flex en Qt

La mejor manera de aprender esto es con un ejemplo, así que realizaremos una calculadora

con operaciones básicas suma, resta multiplicación y división, usando Qt, bison y flex.

Objetivo: Aprender a usar flex y bison con qt atraves de un ejemplo sencillo.

Page 6: Manual Flex y Bison Con Qt

Aprender a usar QFileDialog de Qt, para cargar archivos a bison y ejecutar de ahí.

Descripción general del ejemplo: Se carga un archivo de entrada con una cadena de operaciones aritméticas ejemplo: “5+5*4”,

este se presenta en un caja de texto, después se da clic en el botón calcular y en una caja de

texto diferente, se presenta los resultados, también se puede cambiar los datos en la caja de

texto y darle a calcular automáticamente guarda los cambios y hace los cálculos.

Interfaz del programa.

Cargando el archivo:

Creando ejemplo paso a paso:

Crear el proyecto en qt

Page 7: Manual Flex y Bison Con Qt

Creando los archivos de analizador léxico y sintactico:

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.

Nuestro archivo léxico se llama scan.l y el sintactio parser.y

Page 8: Manual Flex y Bison Con Qt

En anexos se coloco el código de el analizador sintatico y lexico.

Compilando los archivos scan y parser. Abra un terminal sitúes en la carpeta donde esta situado sus archivos.

Para bison escribes lo siguiente:

Bison –o parser.cpp --defines=parser.h parse.y –v

Como se muestra en la imagen.

Para flex: Flex –header –file=scanner.h –o scanner.cpp scan.l

Page 9: Manual Flex y Bison Con Qt

Para una lista completa de las opciones sobre flex y bison, escribe en consola, flex --help o bison –help

Añadiendo los archivos:

Ahora das clic derecho sobre la carpeta source y Header, selecciona la opción add Existing,

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.

Ahora en tu principal agrega lo siguiente en nuestro caso se llama inicio.

Este metodo agrega el archivo que se analizara extern int yyrestart(FILE* archivo); Este método hace el analisis extern int yyparse(); Este metodo agrega nuestro editor donde se mostraran los resultados extern void setEditor(QTextEdit* editor); Este metodo agrega nuestro editor donde se mostraran los errores extern void setTexEdit(QTextEdit* edit1);

Page 10: Manual Flex y Bison Con Qt

Nota: los dos primeros métodos siempre se deben agregar los otros fueron creados por mí

para imprimir el resultado del análisis.

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; } abre un archivo, recibe como parámetro el nombre del archivo, Este método es llamado a pulsar el botón abrir de la aplicación. void inicio::on_pushButton_clicked() { nameFile=QFileDialog::getOpenFileName(this,tr("abrir"),tr("/home/jose/Escritorio"),tr("Archivo 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.

Page 11: Manual Flex y Bison Con Qt

//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; } void ImprimirError(QString val) {salida->append(val); } %} 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));} %%

Page 12: Manual Flex y Bison Con Qt

Archivo parser.y: %{ #include "scanner.h" #include <iostream> #include <QString> #include <QTextEdit> #include <QList> extern int yylineno; extern char *yytext; extern void ImprimirError(QString val); extern void setEditor(QTextEdit* editor); QTextEdit* edit; void imprimir(QString val) { edit->setText(val); } void setEditor(QTextEdit* editor) { edit=editor; } int yyerror(const char* mens) { ImprimirError(QString("Error Sintactico en Fila: %1, en %2").arg(yylineno).arg(yytext)); return 0; } %} %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 %left Nmas Nmenos %left Npor Ndiv

Page 13: Manual Flex y Bison Con Qt

%% INICIO: RESULTADO {imprimir("Resultado: "+QString::number($<STR2>1))} ; RESULTADO: RESULTADO Nmas RESULTADO {$<STR2>$ = $<STR2>1+$<STR2>3} | RESULTADO Nmenos RESULTADO {$<STR2>$ = $<STR2>1-$<STR2>3} | RESULTADO Npor RESULTADO{$<STR2>$ = $<STR2>1*$<STR2>3} | RESULTADO Ndiv RESULTADO {$<STR2>$ = $<STR2>1/$<STR2>3} | Nparen RESULTADO Ncparen {$<STR2>$ = $<STR2>2} | Nent {$<STR2>$ = $<STR2>1} | Nfloat {$<STR2>$ = $<STR2>1}; %%