Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use the flex lexical scanner generator as part of my program?

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!

like image 237
mcorley Avatar asked Apr 02 '11 07:04

mcorley


People also ask

How does flex scanner work?

flex is a tool for generating scanners: programs which recognize lexical patterns in text. flex reads the given input files (or its standard input if no file names are given) for a description of the scanner to generate. The description is in the form of pairs of regular expressions and C code, called rules .

What is lexical analyzer generator?

Flex (fast lexical analyzer generator) is a free and open-source software alternative to lex. It is a computer program that generates lexical analyzers (also known as "scanners" or "lexers").

What is the structure of the Flex program?

A flex program consists of three parts: the definition section, the rules section, and the user subroutines. The parts are separated by lines consisting of two percent signs. The first two parts are required, although a part may be empty. The third part and the preceding %% line may be omitted.


2 Answers

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
like image 175
Martin York Avatar answered Oct 05 '22 18:10

Martin York


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
like image 20
flolo Avatar answered Oct 05 '22 16:10

flolo