PDA

View Full Version : Flex, Bison and qmake



Hydragyrum
7th September 2006, 23:03
Good afternoon,

I've got the lex/yacc files for a parser written, and I know that they work, as I tested them separately, and I need to integrate these into a Qt4 project. that part's fine if I use qmake to generate the makefile, and then hack the makefile to make the damned thing compile properly.

The problem I'm having is that qmake changes the filenames of the outputs, as well as the default prefixes for most of the lex/yacc stuff (such as the yylex() function, and yylval for example...), and I'd like it to not do that. I'd like to be able to go through qmake so that I don't have to hack at the makefile in order to make it work again.

anyways, here's the project file I'm using for this parser, using a small quick and dirty test class I wrote.



TEMPLATE = app
TARGET +=
DEPENDPATH += .
INCLUDEPATH += .

# Input
HEADERS += parse.h parser.y.h parseTest.h
LEXSOURCES += parser.l
YACCSOURCES += parser.y
SOURCES += main.cpp parseTest.cpp

# Flex/bison specifics

QMAKE_LEX = flex
QMAKE_YACC = bison

QMAKE_YACCFLAGS = -d -o y.tab.c
QMAKE_YACC_HEADER =
QMAKE_YACC_SOURCE =


This will generate a makefile that assumes you already know what kind of mangling qmake will do to your filenames (which I didn't, and I would prefer to not have to rewrite the code to make it work)

Basically, these are the offending lines in the makefile that I don't want to be like that.



parser_yacc.cpp: parser.y
$(YACC) $(YACCFLAGS) -p parser -b parser parser.y
-$(DEL_FILE) parser_yacc.cpp parser_yacc.h
-$(MOVE) parser.tab.h parser_yacc.h
-$(MOVE) parser.tab.c parser_yacc.cpp

parser_yacc.h: parser_yacc.cpp

parser_lex.cpp: parser.l
$(LEX) $(LEXFLAGS) -Pparser parser.l
-$(DEL_FILE) parser_lex.cpp
-$(MOVE) lex.parser.c parser_lex.cpp



I do not want the -Pparser flag in the lex lines, nor the -p and -b tags in the yacc lines. I also want the makefile to contain the standard default lex.yy.c output for the lex output, and y.tab.h and y.tab.cpp as the yacc output, since I use C++ code for the parser, although the lexer contains only C code, and can probably run through g++ anyways.

So to recap, I need a way to get qmake to not touch the filenames of the lex and yacc (or in this case, flex and bison) output, and to recognize that it hasn't touched the filenames in order to create the proper targets in the makefile for lex.yy.c (or lex.yy.cpp), y.tab.h, and y.tab.cpp

I've spent the past day on this problem, scouring google, and trying as many different things as I could find. Hacking the makefile each time is an unacceptable solution, I need something that you could add to the project file itself, or at least something scriptable.

Thanks.

wysota
8th September 2006, 00:07
I have a quick solution for you. Tell qmake to treat your lex and bison files with a "custom compiler". Take a look at our wiki (the "undocumented qmake" article) and qmake docs to see how to tell qmake about a custom compiler. Then you'll be able to simply tell qmake what exact commands to execute.

A proper solution would be difficult to obtain as qmake assumes you might have more than one lex and yacc parser and modifies the symbols using yacc and lex interfaces to avoid name clashes, so if you don't use them the way qmake wants you to, it might be a bit difficult to adapt. Of course a semi-proper solution is to override some qmake variables which are responsible for all those modifications.

Hydragyrum
8th September 2006, 01:36
I had a feeling it'll be something like that...

I've tried poking around a bit with it, but couldn't get it to work, It would appear in the makefile, but not under the "all" target...

I'll try it some more tomorrow, as I am not currently at work now :) If there's any other documentation on that feature it would be great to know.

Thanks.

wysota
8th September 2006, 09:08
Try something like this (not tested):

FLEXINPUTS = parser.l
flex_c.output = lex.yy.c
flex_c.input = FLEXINPUTS # it has to be done using a variable
flex_c.commands = flex parser.l

Hydragyrum
8th September 2006, 15:41
for some reason, that wasn't working too well yesterday when I tried poking at it, but works now...

For the interested, my full qmake project file, at least for this testing app is as follows



################################################## ####################
# Automatically generated by qmake (2.00a) Thu Sep 7 15:54:07 2006
################################################## ####################

TEMPLATE = app
TARGET +=
DEPENDPATH += .
INCLUDEPATH += .

# Input
HEADERS += parse.h parser.y.h parseTest.h
#LEXSOURCES += parser.l
#YACCSOURCES += parser.y
SOURCES += main.cpp parseTest.cpp

# Flex/bison specifics

#QMAKE_LEX = flex
#QMAKE_YACC = bison

#QMAKE_YACCFLAGS = -d -o y.tab.c
#QMAKE_YACC_HEADER =
#QMAKE_YACC_SOURCE =

FLEXSOURCES = parser.l
BISONSOURCES = parser.y

flex.commands = flex ${QMAKE_FILE_IN}
flex.input = FLEXSOURCES
flex.output = lex.yy.c
flex.variable_out = SOURCES
flex.depends = y.tab.h
flex.name = flex
QMAKE_EXTRA_COMPILERS += flex

bison.commands = bison -d -t -y ${QMAKE_FILE_IN} && mv y.tab.c y.tab.cpp
bison.input = BISONSOURCES
bison.output = y.tab.cpp
bison.variable_out = SOURCES
bison.name = bison
QMAKE_EXTRA_COMPILERS += bison

bisonheader.commands = @true
bisonheader.input = BISONSOURCES
bisonheader.output = y.tab.h
bisonheader.variable_out = HEADERS
bisonheader.name = bison header
bisonheader.depends = y.tab.cpp
QMAKE_EXTRA_COMPILERS += bisonheader



I'll have to add windows and linux-specific definitions for the move command in the bison.commands, but apart from that it works fairly nicely.

Still I'm not sure why it wasn't working yesterday..but's that's not important.

kerloi
2nd May 2011, 16:52
Hi all,
I know it is a very old thread but I used it to implement my bison/flex parser with Qt, at least I tried.

I wrote a .pro file:


# Flex/bison specifics
FLEXSOURCES = VHDLParser.l
BISONSOURCES = VHDLParser.y

#flex definition
flex.name = Flex
flex.input = FLEXSOURCES
flex.output = ${QMAKE_FILE_BASE}.cpp
flex.commands = flex -i -o${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
#flex.CONFIG += target_predeps
flex.variable_out = SOURCES
QMAKE_EXTRA_COMPILERS += flex

#bison definition
bison.name = Bison
bison.input = BISONSOURCES
bison.output = ${QMAKE_FILE_BASE}.cpp
bison.commands = bison -d -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
bison.clean = position.hh stack.hh location.hh VHDLParser.hpp
bison.CONFIG += target_predeps
bison.variable_out = SOURCES
QMAKE_EXTRA_COMPILERS += bison

OTHER_FILES += \
$$BISONSOURCES \
$$FLEXSOURCES

But when I build my project, the flex compiler simply doesn't start. I can clearly see bison running in the console but not flex.
Of course, when comes the time to link every object files, it doesn't work beceause yylex() is missing ...

Please tell me what's wrong with this .pro.