Generating LPG 1.0 parsers on OSX using Eclipse

In fall I began maintaining the parser of the VIATRA2 framework. Funny.

Mostly because it uses the LPG parser generator framework, and to make things worse, a very old version (v1.1) of it. Today it is available a new 2.0 version (since 2008), but they are not compatible at all, e.g. they define define packages in the LPG runtime. As the release was near, there was no chance of upgrading the parser, so we were stuck with version 1.0.

The problem with the old version is, that although it is written in C++, even its makefile uses explicitely the Visual C++ compiler, so simply compiling it for OSX is not possible. That means, every time I have to change the grammar file, I have to start a Windows binary. And I like to do it from Eclipse.

My two chances were Wine and VMware (not Parallels, because I don’t have a licence for it 🙂 ). The latter is too hard on resources and is so much harder to integrate with my Eclipse in OSX, so the first choice was Wine. Luckily the Wine developers did quality work, so the LPG generator binary can be run with wine.

The Eclipse integration is not too hard (at least in a basic way, that would work for a while), as there is support for running External tools using the appropriate icon from the toolbar (or from the Run menü).

Such an External tool can be parameterized using various variables of Eclipse, of which two are needed:

  • [cci]$resource_loc[/cci]: the file system path (not workspace-relative path) of the selected resource
  • [cci]$container_loc[/cci]: the the container folder’s (or directory) location, that holds the selected resource (also in the file system)

The tool will be the wine installation, as it will execute the lpg.exe binary, that will receive it as a runtime parameter. This way both the location of the lpg.exe binary and the lpg parameters have to be written to the tools parameters section. It is important to note, that the location of the lpg binary can be given using OSX paths, there is no need to translate them into Wine paths, Wine can handle native OSX paths.

LPG uses a working folder, where it puts the generated parser and AST classes. This will be defined using the [cci]$container_loc[/cci] variable.

LPG needs three types of information: the grammar file (that can be given as a parameter to LPG, we will use the [cci]$resource_loc[/cci] variable), an includes directory (for grammar snippets) and a templates directory (for parser and lexer templates).

The directories can either be found in the working directory (this is needed for local templates), given as parameters or set as environment variables. I choose the third one, as it seemed the most maintainable solution.

For this reason the [cci]LPG_INCLUDE[/cci] and the [cci]LPG_TEMPLATE[/cci] environment variables have to be set on the Environment variables tab respectively.

The described settings (except the environment variables) are shown on the following screenshot:

Running LPG with Wine on the current selection

After these settings are done, by selecting the parser.g file, it becomes possible to run this new tool, that will generate the various parser-related Java classes.

After running the tool, the console output of the lpg generator is shown, where all paths are listed beginning with [cci]Y:\[/cci], although the selected files appear in the folder structure of the Eclipse workspace.

There are some minor shortcomings of this integration: first I cannot use the pop-up menu to execute this tool, as the external tools are not listed. Another annoyance is, that the file has to be selected in Navigator view, the open editor is not enough.

This means, I have to select first the file in the Project Navigator (or Package Explorer, etc.), then run the tool manually from the Run configuration menu. Quite disturbing, but the grammar does not need to be changed too often.

Another problem is, that the error output of the generator is not back-annotated as Eclipse errors (problem markers), only a console output is available. For a brand new grammar this would be not the best solution, but for maintenance it is enough.

The LPG IDE of the IMP (IDE Metatooling Platform) project overcomes this challange by using a newer version of LPG, that is written in cross-platform C (or C++), and uses a builder (that automatically calls the LPG binary if the grammar files are changed), and the builder results are showed as proper error messages.

This means, the future for LPG development in Eclipse is the LPG IDE, but for legacy projects it cannot be used. In these cases my solution can become a good alternative.