Friday, April 17, 2009

An updated template for the Lemon Parser Generator

I have always been fond of the Lemon Parser Generator. Ever since I became interested in compilers, Lemon has always been my default choice when considering parser generators. Hyacc is also a good choice, if you need a cannonical LR(1) generator, but - like most parser generators - it carries too much baggage trying to be compatible with yacc.

However, during the construction of my NuBASIC grammar, I discovered a couple of minor problems with the default template (lempar.c), packaged with the source code.

The first problem was minor - lempar.c didn't #include , even though it used assert(). A simple fix.

The second problem was more serious. Lemon uses a directive, %extra_argument, to allow the user to supply an extra argument to the parser, which is of user-defined type. This is in keeping with Lemons philospohy of being a fully reentrant parser. The documentation for Lemon states:

The %extra_argument directive instructs Lemon to add a 4th parameter to the parameter list of the Parse() function it generates. Lemon doesn't do anything itself with this extra argument, but it does make the argument available to C-code action routines, destructors, and so forth. For example, if the grammar file contains:


Unfortunately, this is not the case when using the default template. The %extra_argument is not available to destructor code. If you take a look at yy_destructor(), there is simply nothing there to make it available.

I have repaired both of these problems by modifying lempar.c. I would have been more elegant to modify the source code itself, but I was in a hurry - and it works.

My modification adds an extra argument to yy_destructor(). The original looks like this:

static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor)

and the modified version:

static void yy_destructor(yyParser * yypParser, YYCODETYPE yymajor, YYMINORTYPE *yypminor)

The yypParser parameter is required, since it contains the value of the %extra_argument. After the definition of yy_destructor(), it is redefined as a macro to ensure the following code passes a (yyParser *) o the function. I also did some identifier renaming to ensure the macro worked throughout the code.

Finally, an added ParseARG_FETCH; is inserted into yy_destructor(), making %extra_argument available to the destructor code.

The modified lempar.c can be downloaded here.

First Post!

Howdy,

Welcome to my blog, Programming While Drunk.

This blog is named after of a time-honoured tradition, established by myself, of programming whilst in various states of intoxication. It is one of the most underrated programming paradigms.

So what is the point of this blog? Well, it is basically a dumping ground for my thoughts and comments on programming, mainly in C, in the hope that someone, somewhere might find this stuff actually useful. Also, I can rant.

If you would like to know something about myself, here it is:

I am not a professional programmer, I am a truck driver. Programming, for me, is a hobby. I started in Microsoft QBASIC at age 14 before moving to Borland Turbo Pascal, where I took my first dip into the world of assembly programming.

I decided to learn C++ when I realised Pascal was dead, before "downgrading" to C, and never looking back. I have a love affair with C. I am not blind to its flaws, but... well - I don't know how to finish that sentence. There is so much I love about C. I still use C++ occasionally, but C is my workhorse.

Not being a professional programmer, I rarely finish any projects. They are in a perpetual state of development. The closest I ever came to a finished project was a real-time 3D Engine for the Texas Instruments TI-83 series of graphing calculators. It is written entirely in Z80 assembly, and has some pretty sophisticated features (given the processor) such as 3D clipping. It's still not finished, but every 18 months or so I get into a groove and get a whole lot of work done. You can check out it's progress here.

I have also dabbled in neural-network AI, resulting in a program I call Neural Bots, with demonstration videos available on YouTube.

At the moment I am working on a BASIC to C compiler for a QBASIC-compatible dialect, which I call "NuBASIC". I found there is already a project called "NuBASIC", but it has been dead for several years, so I am claiming the name. If this project dies, someone else can claim the name.

That's it!