Nombre Completo
Cleto Martín Angelina
La siguiente receta explica como construir un analizador léxico con Flex y un analizador sintáctico con Bison, utilizando C++. Además, incluye un pequeño Makefile para el enlazado de todos los archivos y un ejemplo mínimo de uso.
<span>option c++ %option noyywrap </span>{ #include <sstream> #include <cstdlib> #include "parser.h" using namespace std; <span>} <span class="caps">DIGIT</span> [0-9] DIGIT1 [1-9] </span>% {DIGIT1}{DIGIT}* { cout << "Lexer: " << yytext << endl; return Parser::NUMBER; } . { return Parser::UNKNOWN; } <<<span class="caps">EOF</span>>> { yyterminate(); } %%
Es importante ver que el analizador sintáctico (“Parser”) ya conoce los tokens, por lo que el analizador léxico no tiene más que devolver el token encontrado.
<span>name Parser %define <span class="caps">LSP</span>_NEEDED %define <span class="caps">MEMBERS</span> \ virtual ~Parser() {} \ private: \ yyFlexLexer lexer; %define <span class="caps">LEX</span>_BODY {return lexer.yylex();} %define <span class="caps">ERROR</span>_BODY {cerr << "error encountered at line: "<<lexer.lineno()<<" last word parsed:"<<lexer.YYText()<<"\n";} %header{ #include < ostream > #include < fstream > #include < FlexLexer.h > using namespace std; </span>} <span>union { int i_type; } %token <span class="caps">UNKNOWN</span> %token < i_type > <span class="caps">NUMBER</span> %type < i_type > number %start number </span>% number : <span class="caps">NUMBER</span> { $$ = atoi(lexer.YYText()); cout << "Parser value " << $$ << endl;} ; %%
#include "parser.h" #include < iostream > using namespace std; int main(int argc, char ** argv) { Parser parser; parser.yyparse(); return 0; }
all: test
parser.cc: parser.y
bison++ -d -hparser.h -o $@ $<
scanner.cc: scanner.l
flex++ -d -o$@ $<
test: parser.o scanner.o test.o
g++ -o $@ test.o parser.o scanner.o
clean:
$(RM) *~ *# test *.o *.h
$(RM) parser.cc scanner.cc
Comentarios
Muy sencillito
Me ha entrado envidia y voy a realizar yo la receta usando JFlex y CUP.
error: redefinición de 'class yyFlexLexer'
En primer lugar dar las gracias por este tutorial, me ha venido muy bien para migrar mi Flex/Bison de C a C++
En segundo lugar, quisiera hacer una pequeña aportación:
- Es posible que al compilar os arroje este ERROR:
-En mi caso se ha dado utilizando KUbuntu 8.04(64bits) y resulta que es un bug: http://bugs.kde.org/show_bug.cgi?id=67277
-El PROBLEMA es que internamente se hacen varios "includes" a la librería "FlexLexer.h" y no se han definido bien las etiquetas "ifdefined...", por lo que se redefine la clase "yyFlexLexer"
-La SOLUCIÓN más sencilla consiste en insertar la línea:
#undef yyFlexLexerjusto antes de la linea:
#include <FlexLexer.h>en nuestro fichero ".l"
Un saludo!