Dair
Dair

Reputation: 16240

Trouble getting simple flex example to work

I am trying to follow this tutorial, and I am currently stuck on the first snippet of code:

%{
#include <iostream>
using namespace std;
#define YY_DECL extern "C" int yylex()
%}
%%
[ \t\n]         ;
[0-9]+\.[0-9]+  { cout << "Found a floating-point number:" << yytext << endl; }
[0-9]+          { cout << "Found an integer:" << yytext << endl; }
[a-zA-Z0-9]+    { cout << "Found a string: " << yytext << endl; }
%%
main() {
    // lex through the input:
    yylex();
}

Which first gave me an error because of the lack of return type for main so changed the code to this:

%{
#include <iostream>
using namespace std;
#define YY_DECL extern "C" int yylex()
%}
%%
[ \t\n]         ;
[0-9]+\.[0-9]+  { cout << "Found a floating-point number:" << yytext << endl; }
[0-9]+          { cout << "Found an integer:" << yytext << endl; }
[a-zA-Z0-9]+    { cout << "Found a string: " << yytext << endl; }
%%
int main() {
    // lex through the input:
    yylex();
    return 0;
}

Running:

flex snazzle.l

works fine, but when I do the next step:

g++ lex.yy.c -lfl -o snazzle

It says:

clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated ld: library not found for -lfl clang: error: linker command failed with exit code 1 (use -v to see invocation)

What is going on? I am using flex 2.5.35 Apple(flex-31), if it matters... Thanks.

Upvotes: 0

Views: 814

Answers (2)

chandan kharbanda
chandan kharbanda

Reputation: 199

I faced the same problem.

Here is the solution :

1. Using lex.yy.cc instead of lex.yy.c as output file.

flex -o lex.yy.cc snazzle.l
  1. Using ll flag instead of lf1

    g++ lex.yy.cc -ll -o snazzle

Upvotes: 0

rici
rici

Reputation: 241721

clang is complaining that the filename is lex.yy.c but you are compiling it with "g++" (how that gets to be clang++, I don't know, but it will be something to do with the toolchain Apple distributes; it's probably a symlink.) Doing that is, as the warning says, deprecated. None of that has anything to do with flex. You can tell flex that you want to output a c++ file:

flex -o lex.yy.cc snazzle.l

Although personally, I'd name the output file something snazzlier, like snazzle.lex.cc. Whatever you name it, it should end with .cc to mark it as a C++ file. Or you can use .cpp or .cxx or .c++ or some other extensions I don't remember.

The second error is telling you that the flex library, -lfl, isn't installed, or at least it isn't installed in any of the standard places. Rather than try to find that library, I'd personally just add

%option noyywrap

to your flex input. Put it just before the fist %% line. That tells flex that there is no yywrap function, which in turns means that when the input file reaches EOF, it's really an EOF. yywrap is called when the input hits EOF, and it is allowed to change input files and return 0, indicating that the lex operation should continue. Obviously you don't need the feature for this tutorial -- it is only very occasionally useful, in general -- and the fl library includes a definition of yywrap which does precisely this:

int yywrap() { return 1; }

You could add that to your file instead, but it's just as easy to add the noyywrap option, in which case the generated lexer won't need a yywrap function at all.

Upvotes: 2

Related Questions