flex icon indicating copy to clipboard operation
flex copied to clipboard

linker errors with generated C++ code

Open lano1106 opened this issue 5 years ago • 1 comments

I also reported the issue on the devel mailing list. I guess that it would be trivial to fix and I could even do it myself!

I just wanted to report the issue here as well for tracking and discussion purposes:

Guys,

your work is absolutely amazing!

I always wanted to be able to call class methods from inside flex rules actions.

I have just being able to do it but I did stumble into very minor issues that I wanted to report...

I could even possibly contribute to the resolution if you tell me that they are valid issues.

So here is what I am doing with what.

I'm using the ArchLinux build of flex 2.6.4. cmdline to build my lexer:

flex -+ -v --prefix=cursym --yyclass=cursymFlexLexer -B -- outfile=lex.cursym.cpp --header-file=lex.cursym.h cursym.l

a) I create a derived class from yyFlexLexer (that I rename cursymFlexLexer). b) I redefine YY_DECL to let flex write my derived class yylex() method.

By doing that, this allows me to call any methods from my derived class from inside the flex rules actions! It is very powerful because then, I can inherit from this derived class and override some of these methods to change the lexer behavior.

It works like a charm but I did stumble on 2 small linker issues

  1. Multiple yyFlexLexer::yylex() definition (it is defined in the flex generated files)

My yyFlexLexer derived class declaration is in a distinct header file. It is because I need its declaration in the lexer TU and from at least another location so that I can either instantiate the derived class or inherit from it and actually use it.

Fix: I changed yyFlexLexer::yylex() to be inline in the (flex generated header file) and it fixed this issue:

#include <FlexLexer.h> inline int yyFlexLexer::yylex() { LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" ); return 0; }

I guess that it wouldn't hurt neither to define it to be inline in the lex.yy.cc file as well...

  1. Linker complains that yyFlexLexer::yywrap() is not defined.

I have no idea why it isn't generated... but I just added it at the bottom of my l file and the linker has been happy with the fix:

// No idea why I need to define it myself.. int yyFlexLexer::yywrap() { return 1; }

lano1106 avatar Dec 08 '19 19:12 lano1106

Some more improvements in the situation.

I still think that a function declaration shouldn't be in the generated header file. I insisted having it because I was worried that with all the defines fest, I would get a different result than if I was directly including <FlexLexer.h> directly.

I decided to give it a try. I dropped the header file generation and have done the following in the derived class header file:

#ifndef yyFlexLexer #define yyFlexLexer cursymFlexLexer #include <FlexLexer.h> #endif

When it is included from the lex.yy.cc file, the inclusion is skipped. In any other context, it is included and problem #1 is gone.

Concerning the problem #2, the missing yywrap definition. I did realize that I forgot to link with libfl.

I give that a try. No it doesn't work. It makes situation even worse. I have the following ouput when I link against libfl:

g++ -pthread -L../clickbank/base -o test_currency_util lex.cursym.o test_currency_util.o currency_util.o -lbase -lfl /usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../lib/libfl.so: undefined reference to `yylex' collect2: error: ld returned 1 exit status

lano1106 avatar Dec 08 '19 22:12 lano1106