{"id":416418,"date":"2024-06-30T00:56:36","date_gmt":"2024-06-30T00:56:36","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=416418"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=416418","title":{"rendered":"<span>JavaCC 21 Parser Generator<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><a href=\"https:\/\/javacc.com\/\" rel=\"nofollow\">JavaCC 21<\/a> is a continuation of work on the venerable JavaCC parser generator, originally developed at Sun Microsystems in the 1990\u2019s and released under a liberal open source license in 2003. It is currently the most advanced version of JavaCC. It has many feature enhancements (with more to come soon) and also generates much more modern, readable Java code. Also, certain key bugs have finally been fixed. (N.B. The \u201c21\u201d in JavaCC 21 is not a version number. It is simply part of the project name and means that this is a JavaCC for the 21st century!)<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>Here are some highlights:<\/p>\n<p>  <\/p>\n<h2 id=\"up-to-date-java-language-support\">Up-to-date Java language support<\/h2>\n<p>  <\/p>\n<p>JavaCC 21 supports the Java language through JDK 13. See <a href=\"https:\/\/javacc.com\/2020\/03\/22\/milestone-javacc-21-now-supports-the-java-language-up-to-jdk-13\/\" rel=\"nofollow\">here<\/a>. The Java grammar that JavaCC 21 uses internally can be used in your own projects without any restriction.<\/p>\n<p>  <\/p>\n<h2 id=\"major-bugfix-nested-syntactic-lookahead-now-works-correctly\">Major Bugfix! Nested Syntactic Lookahead now works correctly!<\/h2>\n<p>  <\/p>\n<p>A longstanding limitation of JavaCC has been that syntactic lookahead does not nest, i.e. work recursively. This has been an issue in JavaCC for 24 years and was never addressed, and surely caused the tool to be less generally useful than it could have been, since attempts to do anything at all sophisticated would typically use recursive lookahead and would simply not work. This is <a href=\"https:\/\/javacc.com\/2020\/03\/22\/milestone-javacc-21-now-supports-the-java-language-up-to-jdk-13\/\" rel=\"nofollow\">now fixed in JavaCC 21<\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"streamlined-syntax\">Streamlined Syntax<\/h2>\n<p>  <\/p>\n<p>Though the original (or legacy) syntax is still supported (and will be for the indefinite future), JavaCC 21 offers a <a href=\"https:\/\/doku.javacc.com\/doku.php?id=new_syntax_summary\" rel=\"nofollow\">new streamlined syntax<\/a> that should be easier to read and write. Sometimes the improvement in readability is truly dramatic! For example, where you would previously have written:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">void FooBar() : {} {     Foo() Bar() }<\/code><\/pre>\n<p>  <\/p>\n<p>with the streamlined syntax, you can now write:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">FooBar : Foo Bar ;<\/code><\/pre>\n<p>  <\/p>\n<p>Cumbersome aspects of the legacy <code>LOOKAHEAD<\/code> construct have been streamlined. See <a href=\"https:\/\/doku.javacc.com\/doku.php?id=new_syntax_summary\" rel=\"nofollow\">here<\/a>. Again, the newer syntax sometimes affords dramatic improvements in clarity. Where you would have written before:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">LOOKAHEAD(Foo() Bar() Baz()) Foo() Bar() Baz()<\/code><\/pre>\n<p>  <\/p>\n<p>In JavaCC 21, you can write:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">=> Foo Bar Baz<\/code><\/pre>\n<p>  <\/p>\n<p>The new <a href=\"https:\/\/doku.javacc.com\/doku.php?id=up_to_here\" rel=\"nofollow\">up-to-here marker<\/a> also offers great gains in readability and maintainability. For example, where you would have written before:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">LOOKAHEAD(Foo() Bar()) Foo() Bar() Baz()<\/code><\/pre>\n<p>  <\/p>\n<p>You can now write:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">Foo Bar =>|| Baz<\/code><\/pre>\n<p>  <\/p>\n<p>The new syntactic element <code>=>||<\/code> is called the <em>up-to-here marker<\/em> and expresses much more clearly and succinctly the concept that, when deciding whether to enter the <code>Foo Bar Baz<\/code> expansion, we scan forward up to and including the <code>Bar<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"lookbehind-predicates\">Lookbehind predicates<\/h2>\n<p>  <\/p>\n<p><a href=\"https:\/\/doku.javacc.com\/doku.php?id=lookbehind\" rel=\"nofollow\">Lookbehind<\/a> is a new feature in JavaCC 21 that allows you to write predicates at choice points that check whether you are at a given point in the parse. For example:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">SCAN \u2026\\Foo => Bar<\/code><\/pre>\n<p>  <\/p>\n<p>The above uses a lookbehind predicate to express the idea that we only enter the Bar production if we have previously entered a Foo. Or, for example:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">SCAN ~\\\u2026\\Foo => Foo<\/code><\/pre>\n<p>  <\/p>\n<p>This means that we can only enter the Foo production if we are not already in a Foo. (Or in other words, Foo is not re-entrant.) (Lookbehind is quite a useful feature, already used in internal development, and we are not aware of any similar tools that offer this.)<\/p>\n<p>  <\/p>\n<h2 id=\"tree-building-enhancements\">Tree Building Enhancements<\/h2>\n<p>  <\/p>\n<p>JavaCC 21 is based on the view that building an AST (Abstract Syntax Tree) is the normal usage of this sort of tool. While the legacy JavaCC package does contain automatic tree-building functionality, i.e. the JJTree preprocessor, JJTree has some (very) longstanding usability issues that JavaCC 21 addresses.<\/p>\n<p>  <\/p>\n<p>For one thing, a lot of what makes JJTree quite cumbersome to use is precisely that it is a preprocessor! In JavaCC 21, all of the JJTree functionality is simply in the core tool and the generated parser builds an AST by default. (Tree building can be turned off however.)<\/p>\n<p>  <\/p>\n<p>(NB. JavaCC 21 uses the same syntax for tree-building annotations as legacy JJTree.)<\/p>\n<p>  <\/p>\n<p>JavaCC 21 has an <a href=\"https:\/\/doku.javacc.com\/doku.php?id=code_injection_in_javacc_21\" rel=\"nofollow\">INJECT<\/a> statement that allows you to inject Java code into any generated file thus doing away with the unwieldy anti-pattern of post-editing generated files.<\/p>\n<p>  <\/p>\n<h2 id=\"better-generated-code\">Better Generated Code<\/h2>\n<p>  <\/p>\n<p>JavaCC 21 generates more readable code generally. Certain things have been modernized significantly. Consider the <code>Token.kind<\/code> field in the <code>Token.java<\/code> file generated by the legacy tool. That field is an integer and is also (contrary to well known best practices) publicly accessible. In the <code>Token.java<\/code> file that JavaCC 21 generates, the <code>Token.getType()<\/code> method returns a type-safe Enum and all of the code in the generated parser that previously used integers to represent the type of Token, now uses <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/Enum.html\" rel=\"nofollow\">type-safe Enums<\/a>.<\/p>\n<p>  <\/p>\n<p>Code generated by legacy JavaCC gave just about zero information about where the generated code originated. Parsers generated by JavaCC 21 have line\/column information (relative to the real source file, the grammar file) and they also inject information into the stack trace generated by <code>ParseException<\/code> that contain line\/column information relative to the grammar file.<\/p>\n<p>  <\/p>\n<p>If you want to compare side-by-side code generated by legacy JavaCC with that generated by JavaCC 21, see <a href=\"https:\/\/www.freemarker.es\/2020\/05\/08\/generatd-parsers-ymtd\/\" rel=\"nofollow\">this page<\/a>.<\/p>\n<p>  <\/p>\n<p>The current JavaCC 21 codebase itself is the result of a massive refactoring\/cleanup. Code generation has been externalized to FreeMarker templates. To get an idea of what this looks like in practice, here is the main template that generates Java code for grammatical productions.<\/p>\n<p>  <\/p>\n<h2 id=\"assorted-usability-enhancements\">Assorted Usability Enhancements<\/h2>\n<p>  <\/p>\n<p>In general, JavaCC 21 has more sensible default settings and is much more usable out-of-the-box. See <a href=\"https:\/\/doku.javacc.com\/doku.php?id=convention_over_configuration\" rel=\"nofollow\">here<\/a><\/p>\n<p>  <\/p>\n<h2 id=\"javacc-21-is-actively-developed\">JavaCC 21 is actively developed!<\/h2>\n<p>  <\/p>\n<p>Perhaps most importantly, the project is again under active development. Now that the project is active again, users can expect significant new features fairly soon. Given that code generation has been externalized to template files, the ability to generate parsers in other languages is probably not very far off. Another near-term major goal is to provide support for fault-tolerant parsing, where a parser incorporates heuristics for building an AST even when the input is invalid (unbalanced delimiters, missing semicolon and such).<\/p>\n<p>  <\/p>\n<p>One way to stay up to date with the JavaCC 21 project is to subscribe to <a href=\"https:\/\/javacc.com\/feed\" rel=\"nofollow\">our blog newsfeed<\/a> in any newsreader.<\/p>\n<p>  <\/p>\n<p>Usage is really quite simple. As described <a href=\"https:\/\/doku.javacc.com\/doku.php?id=start_hacking\" rel=\"nofollow\">here<\/a> JavaCC 21 is invoked on the command line via:<br \/>  (N.B. The \u201c21\u201d in JavaCC 21 is not a version number. It is simply part of the project name and means that this is a JavaCC for the 21st century!)<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">java -jar javacc-full.jar MyGrammar.javacc<\/code><\/pre>\n<p>  <\/p>\n<p>The latest source code can be checked out from Github via:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">git clone https:\/\/github.com\/javacc21\/javacc21.git<\/code><\/pre>\n<p>  <\/p>\n<p>And then you can do a build by invoking ant from the top-level directory. You should also be able to run the test suite by running <code>ant test<\/code>.<\/p>\n<p>  <\/p>\n<p>If you are interested in this project, either as a user or as a developer, you may <a href=\"mailto:javacc21@gmail.com\">write us<\/a>. Better yet, you can sign up on our <a href=\"https:\/\/parsers.org\/\" rel=\"nofollow\">Discourse forum<\/a> and post any questions or suggestions there.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/521664\/\"> https:\/\/habr.com\/ru\/articles\/521664\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><a href=\"https:\/\/javacc.com\/\" rel=\"nofollow\">JavaCC 21<\/a> is a continuation of work on the venerable JavaCC parser generator, originally developed at Sun Microsystems in the 1990\u2019s and released under a liberal open source license in 2003. It is currently the most advanced version of JavaCC. It has many feature enhancements (with more to come soon) and also generates much more modern, readable Java code. Also, certain key bugs have finally been fixed. (N.B. The \u201c21\u201d in JavaCC 21 is not a version number. It is simply part of the project name and means that this is a JavaCC for the 21st century!)<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-416418","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/416418","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=416418"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/416418\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=416418"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=416418"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=416418"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}