Okay, where to begin? On the one hand, you make a quite valid point, which is that the current INCLUDE directive is quite crude and bloody-minded. As a code re-use mechanism, one could envisage quite a few refinements.
On the other hand, you veer into some self-evident silliness, this stuff about the Java language not having something like INCLUDE.
Marc, I’m sorry. The above is just silliness. You’re implicitly comparing two completely different situations. The Java language is an object-oriented language that has all the typical dispositions of an OOP language. It has inheritance obviously, and it has composition. So, if you are working on Foo class which is defined in the file Foo.java, you can reuse the code you defined in the Bar.java class by having Foo extend Bar. OR alternatively, you can have a Bar object as a member field of your Foo object…
So, the lack of an INCLUDE directive in Java is based on the calculation (probably quite valid) that, in just about any real-world usage case, you would be better off using inheritance and/or composition to achieve code reuse rather than some (compararively crude) INCLUDE mechanism.
Fine, but how does that apply to JavaCC? It doesn’t. For a very simple reason:
Legacy JavaCC has ZERO disposition for code reuse.
NOTHING! Rien… nada… nichts… Pretty much the only way to reuse code in legacy JavaCC is copy-paste. That’s all there ever has been and it looks like that is all there ever will be! I implemented INCLUDE back in 2008 because I just couldn’t fathom maintaining an entire Java grammar inside the JavaCC grammar that was not separately reusable!
If you cannot see how absurd this situation is… The day that they implement, let’s say, Lambda expressions (part of the Java language since JDK 8, released in 2014) they need, first of all, to implement it in two separate files, JJTree.jjt and JavaCC.jj, and even at that point, it is not separately usable anywhere else! As crude a disposition you might think that JavaCC 21’s INCLUDE is, it really does resolve this basic problem. The Java.javacc file that is INCLUDEd here is separately usable by any other project.
Maybe nobody is reusing it (probably not) but that’s just because they don’t know about it.
If I write an HTML grammar using legacy JavaCC, all the constructs for CSS, say, have to just be in the same file. With JavaCC21, I write a separately usable (again! key concept…) CSS.jj file and that is, in principle, separately usable by other projects. (Or it’s separably usable by ME! Or YOU! If one is going to be self-centered about things…)
So, I do have to say that your statement that this is not a “must have” is just wrong. It is an absolute “must have”. What you’re saying is based on the classic logical fallacy of confusing necessary with sufficient. Quite arguably, INCLUDE, as it is currently, is not entirely sufficient, okay, but it is necessary.
Granted, too, if there were (contrary to fact, at the moment) much more sophisticated mechanisms for grammar inheritance and/or composition, then quite possibly INCLUDE would no longer be necessary. Okay but that is a rather stretched kind of argument. Again, the only other existing version of JavaCC is the legacy tool, which again, has ZERO disposition for code reuse. NOTHING!
Now, as for composition of grammars, calling sub-parsers, well, yeah, okay. Legacy JavaCC does not have that either (quite obviously!) and neither does JavaCC 21. (JavaCC 21 could well have have this in the future. It is safe to say that the legacy project never will.) But composition of grammars, calling subparsers, that is not mutually exclusive with INCLUDE anyway.
Similarly, the new ATTEMPT/RECOVER I implemented is not mutually exclusive with the existing try-catch. I in fact, the existing try-catch still works. (For what it’s worth, which ain’t much…) It’s not even mutually exclusive with JAVACODE productions either. I could still put that back, but I doubt I will. (s I see it, you can’t just keep burdening yourself carrying things forward forever that almost nobody uses and are not very useful anyway.)
I mean, you’re also talking somewhat, as if things are mutually exclusive that are not mutually exclusive anyway. Having INCLUDE does not prevent us from later having more sophisticated code reuse or modularization. Also, it is possible maybe that INCLUDE could be refined and evolved towards being a better overall solution, since yes, it is a bit crude now.
But again, when you have a situation where the legacy tool has ZERO consideration for the whole problem… the conversation does get a bit frustrating, you know. I implemented INCLUDE in FreeCC 12 years ago or something and just about nobody ever got the benefit of even that.