Thursday 15 March 2012

Using Flex with Qt

I've got a large project to work on which will require quite a bit of parsing / scanning of files so I've decided to teach myself flex and bison. So far I've read the first chapter of the excellent book Flex and Bison and the first example is as follows
/* from the flex and bison book do a word count */

%{
int chars=0;
int words=0;
int lines=0;
%}

%%

[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n    { chars++; lines++; }
.     { chars++; }

%%
int main(int argc, char **argv)
{
  yylex();
  printf("Word count %8d %8d %8d\n",lines,words,chars);
  return 0;
}

To build and compile this we use the following command line
flex -o wc.c wc.l
gcc -o WordCount wc.c -lfl
This works fine, but as I use QtCreator as my ide I really want to configure Qt to do this all for me. QtCreator does have some limited lex and yacc support however I really wanted to use flex and bison, so need to add my own compiler to the qmake build system via the Qt project. To do this we use the QMAKE_EXTRA_COMPILERS flag in the project and build our own compile chain, the following extract shows how this works
# the is the name of the exe we want
TARGET=WordCount
# this is the source fed to the flex syste
FLEXSOURCES+=wc.l
# we then add this to the other files for editing
OTHER_FILES+=$$FLEXSOURCES

###########################################################################################
# now we are going to create a Qt compiler ojbect for the EXTRA_COMPILERS FLAG
# this basically has a number of attributes which we need to set as outlined below
###########################################################################################
# this flag list the sources we wish to input to this custom compiler, in this case listed above
# in the FLEXSOURCES variable
flex.input = FLEXSOURCES
# now we need to say what files to output, for flex we want to create the .c
flex.output = ${QMAKE_FILE_BASE}.c
# this is the actual compile command we wish to call in this case it wil be
# flex -o (output).c input.l
flex.commands = flex  -o ${QMAKE_FILE_IN_BASE}.c ${QMAKE_FILE_IN}
# once this compiler has been run we need to add the output files to the linker stage in this case
# as we are generating .c files we just add it to the SOURCES variable and it will be compiled
flex.variable_out = SOURCES
# this flag ensures that the extra compiler is run before the main c one (as we need to have the .c files
# generated by flex before we use the gcc compiler)
flex.CONFIG += target_predeps
# this tells the make clean command what files to remove
flex.clean =  ${QMAKE_FILE_IN_BASE}.c
# this is just the name of the extra compiler used in the make file (make flex for example)
flex.name = flex
# finally add this to the qmake project so it will have the makefile generated
QMAKE_EXTRA_COMPILERS += flex
# we need the fl lib for flex
LIBS+=-lfl
# tell qt we usign gcc
QMAKE_LINK=gcc
# this just cleans out some things for mac
CONFIG += console
CONFIG -= app_bundle

And that is about it, now I've got to read the rest of the book, but at least it makes the coding easier!

1 comment: