5

How can I use a scanner I've written using Flex as part of a program I'm designing? Specifically, within a c++ class as a method of the class, and from a separate file with just a main method to perform testing.

I don't wish to use the %option c++, but will compile with g++.

To answer the problem of how to test the scanner from a separate file's main I attempted with the following code:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

extern "C" {
    extern int yylex();
}

extern FILE* yyin;

int main(int argc, char *argv[]) {
    if (argc > 1)
        yyin = fopen(argv[1], "r");
    yylex();
    return 0;
}

I compile like so:

flex mylexer.l++
g++ lex.mylexer.C myDriver.C -o myLexer

I get:

undefined reference to yyin

undefined reference to yylex

What is the correct way to compile/setup the driver file? Thank you for reading and contributing anything!

rici
  • 234,347
  • 28
  • 237
  • 341
mcorley
  • 767
  • 12
  • 21
  • Why are you using a `.l++` file if you don't actually want to make a C++ lexer? I thought any file ending in `+` for flex generates the C++ lexer by default (but it's been many years since I've looked at it so I could be wrong). – JUST MY correct OPINION Apr 02 '11 at 07:51

4 Answers4

8

The simplist example I have is:

mylex.l

%option noyywrap

%%

:       return ':';

%%

main.cpp

#include <stdio.h>
#include <iostream>

extern "C"
{
    extern int yylex(void);
    extern FILE*   yyin;
}

int main()
{
    yyin    = fopen("plop", "r");
    std::cout << yylex() << "\n";
}

Then to build:

> flex -o mylex.c mylex.l
> gcc -c mylex.c
> g++ -c main.cpp
> g++ main.o mylex.o

Notice the gcc to compile the mylex.c
If you compile mylex.c with g++ it will be compiled as C++ (not C) and your extern "C" declarations in main would be wrong. Thus you need to compile the mylex.c and main.cpp with different compilers then link them together in separate steps.

Version 2:

Alternatively you can compile the flex code as C++ and remove the extern "C" from main.

main.cpp

#include <stdio.h>
#include <iostream>

extern int yylex(void);
extern FILE*   yyin;

int main()
{
    yyin    = fopen("plop", "r");
    std::cout << yylex() << "\n";
}

Now Build like this:

> flex -o mylex.c mylex.l
> g++ -c mylex.c
> g++ -c main.cpp
> g++ main.o mylex.o

Notice this time I used g++ to compile mylex.c (which you could call mylex.cpp now).

Now that you are using the same compiler it can be a one liner:

> flex -o mylex.c mylex.l
> g++ mylex.c main.cpp
Martin York
  • 257,169
  • 86
  • 333
  • 562
2

You have to link the flex library with your programm, that is, you have to add -lfl to your g++compiler invocation.

flex mylexer.l++
g++ lex.mylexer.C myDriver.C -o myLexer -lfl
Martin York
  • 257,169
  • 86
  • 333
  • 562
flolo
  • 15,148
  • 4
  • 32
  • 57
0

You need to include the file generated by flex on your g++ command line -- both yyin and yylex are defined there. If lex.mylexer.C is supposed to be that file, its possible that you're getting a flex error you're ignoring, or otherwise not running flex properly to generate the file -- check it to make sure that it actually contains the flex output and isn't an empty file.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
-2

Check out boost Spirit

xcramps
  • 1,203
  • 1
  • 9
  • 9