Abdullah Diab’s Blog

Binding NetBeans with Flex

In my faculty – Informatics Engineering, Damascus University -, in the 4th year of Software Engineering Department, we have to build a compiler :shock:.

I like using NetBeans for developing applications, it supports lots of languages and tools; like C, C++, Java, Python, Ruby and more. The compiler would be implemented in C++.

The first two phases of implementing a compiler are: building a lexer (tokenizer) and building a parser. The lexer is implemented using GNU Flex while the parser is implemented using GNU Bison.

The Problem

The first problem I faced when starting the project was to tell NetBeans how to handle the lex file:

The lex file must be passed to the flex tool to generate a C++ code file.

The second problem was that when the code file is generated it contains errors:

#ifdef __cplusplus

#include <stdlib.h>
class istream;
#include <unistd.h>

When using building the file you’ll find that it contains errors regarding the usage of istream. (You might not face this problem, then you’re a lucky programmer).

The first problem: Binding NetBeans with Flex

From NetBeans –> Projects Side Tab –> right click on the lex file –> Properties:

Categories –> General:

  • Uncheck “Excluded From Build”.

  • Select “Custom Build Tool” in the Tool drop down list.

Categories –> Custom Build Step:

  • Enter in the Command Line field: flex lex.l Assuming that your lex file is called lex.l

  • Enter in the Outputs field: lex.yy.cc

  • Enter in the Description: Running Flex …

Press Ok.

Now when you compile the solution your lex file will be passed the the flex tool.

The second problem: Fixing the error

When I started fixing the error, I was doing it by hand, but I got bored of the process so I wrote a small Python script to do this for me:

Assuming that the output file of the lex file is called lex.yy.cc:

f = open('lex.yy.cc')
lines = f.readlines()
i = 0
for i in range(len(lines)):
    if lines[i] == 'class istream;\n':
        break;
else:
    return;
lines[i] = '#include <iostream>\n'
lines.insert(i + 1, 'using namespace std;\n')
f.close()
f = open('lex.yy.cc', 'w')
f.writelines(lines)
f.close()

The script is easy, it opens the file, changes the line from “class istream;” to “#include ”, inserts “using namespace std;” next.

Put the file next to your sources and run it after the build process to fix the error.

Fixing both problems without executing anything manually:

After a while I got bored of executing the script manually and I decided that the script must be executed automatically.

To do that the script must be called by NetBeans, so back to the lex file properties I changed the Custom Build Command from “flex lex.l” to “python fixer.py”.

Now the fixer script is called to build the lex file, so the script must change to call the flex from the script itself:

import os

os.system("flex token.l")

f = open('lex.yy.cc')
lines = f.readlines()
i = 0
for i in range(len(lines)):
    if lines[i] == 'class istream;\n':
        break;
else:
    return;
lines[i] = '#include <iostream>\n'
lines.insert(i + 1, 'using namespace std;\n')
f.close()
f = open('lex.yy.cc', 'w')
f.writelines(lines)
f.close()

Now all my problems are solved, hope that yours will be solved too 🙂