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.
%option c++ %option noyywrap %{ #include <sstream> #include <cstdlib> #include "parser.h" using namespace std; %} DIGIT [0-9] DIGIT1 [1-9] %% {DIGIT1}{DIGIT}* { cout << "Lexer: " << yytext << endl; return Parser::NUMBER; } . { return Parser::UNKNOWN; } <<EOF>> { 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.
%name Parser %define LSP_NEEDED %define MEMBERS \ virtual ~Parser() {} \ private: \ yyFlexLexer lexer; %define LEX_BODY {return lexer.yylex();} %define ERROR_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; %} %union { int i_type; } %token UNKNOWN %token < i_type > NUMBER %type < i_type > number %start number %% number : NUMBER { $$ = 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
Comments
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!
Flex
Escribí un artículo hace algún tiempo que me gustaría compartir con ustedes: http://rolandopalermo.blogspot.com/2009/12/como-configurar-flex-en-windo...
Espero que les sea de utilidad, saludos.