Debugging ANTLR Grammars

Scott Stanchfield, FGM, Inc & JavaDude.com

There are currently four ways you can debug an ANTLR gramar:

The first approach is pretty straightforward. If you don't already know how to do this, consider another line of work. Seriously. There's too much chance that I'll end up maintaining your code. Do us both a favor, well, at least me, and quit before I have to suffer.

Let's look at the other three options...

Rule Call traces

This option adds code to each generated rule method at its beginning and end to call traceIn() and traceOut(). These two methods are defined in the parser, lexer, and tree parser superclasses, and by default print the rule calls with indentation based on how deep the call is. You can override traceIn() and traceOut() in your parser to do something different if you would like.

To turn on these options, specify one or more of the following options when running ANTLR to compile your grammar files:

-trace all rules in your grammar file will be annotated with calls to traceIn() and traceOut() during code generation
-traceParser rules defined in a Parser grammar will be annotated
-traceLexer rules defined in a Lexer grammar will be annotated
-traceTreeParser rules defined in a Tree Parser grammar will be annotated

ParseView

By specifying the -debug option when running ANTLR to compile your grammar files, the ParseView debugging API will be added to your parser. This API uses the Observer pattern to notify any interested listeners. You can add your own parser listener classes, or use the standard ParseView visualization.

If you do not override the default ParseView support, the ParseView GUI will appear when you run your parser.

I'm working on a newer version of ParseView that plugs into Eclipse...

More details will be added here later.

JSR-45 Grammar-Source-Level Debugging

If you specify the -smap option when running ANTLR to compile your grammar files, ANTLR will generate a source map file for each grammar. A source map is a listing of line mappings from the source grammar file to the target java source. If the generated source map is then installed into a compiled java class, a JSR-45 compliant debugger (like the one in Eclipse) will show the grammar file source as you step through your program.

The -smap option is turned on by default in the ANTLR-eclipse plugin, but is off by default in the command-line version of ANTLR and in the <antlr> ant task.

To use this option in eclipse, all you need to do is install the ANTLR-eclipse plugin and set breakpoints in your grammar file the same way you would set them in java source. When you run your program using a debug launcher in eclipse, the debugger will stop at the breakpoints.

To run outside of eclipse, you need to think of the compile as three phases:

All three steps are performed by the ANTLR eclipse plugin. There is currently no standalone SMAP installer, but I'll extract it from the eclipse plugin soon.

To use grammar-level debugging:

  1. Turn on breakpoints in your grammar in the same manner you would in a Java program. Note that the ANTLR-eclipse plugin currently will allow you to create some unreachable breakpoints (on blank lines for example). You can break on action code, rule references and rule definitions.
  2. Start your program in eclipse debug mode
  3. You should see the debugger break on your grammar file
  4. You can step over, into rules, into method calls, etc. Note that there may be some "extra" methods that you step into while debugging. You may want to exclude antlr.* in your debug settings.

More details will be added here later.