Happy New Year! Some Backward-Incompatible API Changes!

In conjunction with New Year 2021 (a landmark year for JavaCC 21 for sure!) I decided to scratch some longstanding itches -- even at the expense of introducing some (minor) backward incompatibilities.

The various option settings can only be set in the grammar file.

There was a longstanding setup in legacy JavaCC (carried forward in FreeCC and JavaCC21) that any option could be set on the command line or in an options block at the top of the grammar file. So, you could put:

OPTIONS {
    IGNORE_CASE=true;
}

at the top of your grammar. Or you could invoke javacc with:

javacc -IGNORE_CASE=true Foo.jj

As a general rule, there is not much reason to want to specify things like this on the command-line. So, as of 2021, the only way to specify the above is at the top of the grammar file. Note that, in the new streamlined syntax there is no need for the OPTIONS {..} part. You just write:

 IGNORE_CASE=true;

at the top of your grammar.

Actually, as of New Year 2021, the only options available from the command-line are the following:

  • Specifying that you don't want the tool to generate as much information, i.e. to be quiet. This is the -q option. (This can only be set on the command line.)
  • Suppressing the check for a newer version. This is the -n option. (This can also only be set on the command line.)
  • Specifying where to generate the files. (By default, this is relative to where the grammar file is.) You can (optionally) specify this using the -d option on the command line. You can also put BASE_SRC_DIR=location in the grammar file. This is the only setting that can be set either on the command line or in the grammar file. (If it is set in both places, the command-line option has priority.)

A few other options, based on user feedback will likely be introduced over time, but the goal here is to make usage of the tool extremely simple. As for the various things to set at the top of a grammar, with sane defaults, there is fairly little reason to change any of them. See this page for more information.

Still, I mention all this, because anybody who was relying on the fact that you could specify these things on the command-line must now make certain adjustments.

The Nodes class is gone.

From back in the FreeCC days (circa 2008) the tool generated a Node.java and a Nodes.java. The reason for this was hyper-technical really. Prior to Java 8 (released in 2014) there was no such as thing as a default or static method in an interface. So, for an interface like Node, one would typically need an accompanying class as a holder for various static methods that operated on Node objects. (Thus the Nodes class.) There is no real reason for a separate Nodes object, so if you were using any of that, you need to make certain adjustments in your code. So, for example, there was a convenience method:

 public List Nodes.getAllTokens(node);

that would get all of a Node object's Token descendants. That is now just a default method in the Node interface itself:

 default List getAllToken() {...}

Generally, the API is cleaner now, but if you were using that Nodes API, you need to make certain adjustments in your code. Also, if you had any code injection, like:

 INJECT Nodes : {
    //add your own static utility methods here 
 }

That won't work because the Nodes class no longer exists. You could inject the same static routines into Node though and you should be fine.

Well, in closing, I don't think the above backward incompatible changes will require adjustments in any existing projects that set you back more than ten or fifteen minutes. If this is a big deal, sorry. JavaCC 21 does come with a double money back guarantee!

Happy New Year!