Rémi, why don't you bring it to javadoc-dev?

On Fri, Jun 19, 2026 at 4:09 PM Remi Forax <[email protected]> wrote:
>
> Hello,
> over the last few months, I've developed a small library called LazyLR 
> (runtime grammar parsers) and because it requires Java 25, I use the markdown 
> doc-comments introduced by JEP 467.
>
> The overall experience is great, it's better than the traditional 
> doc-comments that mix documentation and HTML tags.
>
> Here is my field trip report:
>
> Pro:
>   - /// really shine to write one line doc for private methods, the visual 
> overhead is minimal compared to /** ... */
>   - /// does not requires escaping, even /// inside a /// is correctly 
> recognized
>   - Markdown is a better format than HTML for the documentation (especially 
> lists and tables)
>   - A blank line in markdown is really a blank line, unlike in HTML, so the 
> the doc comments are closer to the rendered javadoc (What you see is closer 
> to what you get)
>   - Code snippets using three backticks (```java) are easier to use than 
> <pre> (no &lt;, no escaping needed)
>
> Cons:
>   - If you have 100 lines of /// and one of then is a //, the javadoc will 
> skip all the lines before the '//' without a warning.
>     It should be great if javadoc could emit a warning in that case.
>   - Inline backtick `, are hard to read so it's easy to miss the ending 
> backtick,
>     Again, here, I think I would like a warning if there is no end backtick 
> at the end of the line
>
> regards,
> Rémi
>
> Here is a full example:
>   
> https://github.com/forax/lazylr/blob/master/src/main/java/com/github/forax/lazylr/package-info.java
>
> /// # Lazy LR — A Lightweight Runtime LR(1) Parser Library
> ///
> /// This package provides all the building blocks to define a context-free 
> grammar,
> /// tokenize raw text, and parse token streams into structured results at 
> runtime,
> /// without a separate code-generation step.
> ///
> /// ## Core Concepts
> ///
> /// A [com.github.forax.lazylr.Grammar] is a validated set of
> /// [com.github.forax.lazylr.Production] rules plus a
> /// start [com.github.forax.lazylr.NonTerminal].
> /// Productions are built from two kinds of [com.github.forax.lazylr.Symbol]s:
> /// [com.github.forax.lazylr.Terminal] (a concrete token, e.g. `"+"` or 
> `"num"`)
> /// and [com.github.forax.lazylr.NonTerminal] (an abstract construct, e.g. 
> `"E"`).
> ///
> /// [com.github.forax.lazylr.MetaGrammar] lets you describe tokens, 
> precedence,
> /// and productions in a compact text instead of building Java objects 
> programmaticaly:
> ///
> /// ```java
> /// var mg = MetaGrammar.load("""
> ///     tokens {
> ///       num: /[0-9]+/
> ///       /[ ]+/
> ///     }
> ///     precedence {
> ///       left:  '+'
> ///       left:  '*'
> ///       right: '^'
> ///     }
> ///     grammar {
> ///       E: num
> ///       E: E '+' E
> ///       E: E '*' E
> ///       E: E '^' E   %prec '^'
> ///     }
> ///     """);
> /// ```
> ///
> /// The text has three optional sections:
> /// - **`tokens`**: named terminals (`name: /regex/`) and unnamed
> ///   skip patterns (`/regex/`).
> /// - **`precedence`**: `left:` or `right:` lines, lowest first,
> ///   multiple terminals per line share the same level.
> /// - **`grammar`**: BNF-style rules; quoted literals like `'+'` are
> ///   auto-registered as terminals.
> ///   Lines with no right-hand side are epsilon productions,
> ///   `%prec TOKEN` overrides a production's default precedence.
> ///
> /// ## Typical Usage
> ///
> /// ```java
> /// // 1. Load the grammar
> /// MetaGrammar mg = MetaGrammar.load(grammarText);
> ///
> /// // 2. Optionally verify for conflicts
> /// mg.verify();
> ///
> /// // 3. Parse and evaluate
> /// String inputText = ...
> /// var result = mg.parse(inputText, new MyVisitor());
> /// ```
> ///
> /// ## Key Classes
> /// [com.github.forax.lazylr.LALRVerifier] performs a full offline LALR(1)
> /// analysis and can print the complete state automaton with conflict markers.
> /// This is the class used by [com.github.forax.lazylr.MetaGrammar#verify()].
> ///
> /// [com.github.forax.lazylr.Lexer] converts a `CharSequence` into
> /// a lazy `Iterator<Terminal>` using a longest-match rule, ties
> /// broken by declaration order.
> ///
> /// [com.github.forax.lazylr.Parser] implements a lazy LR(1) algorithm:
> /// states are computed on demand.
> /// Shift/reduce conflicts are resolved via a 
> [com.github.forax.lazylr.Precedence] map;
> /// unresolved conflicts cause a [com.github.forax.lazylr.ParsingException]
> /// during parsing.
> /// A call to 
> [com.github.forax.lazylr.MetaGrammar#parse(java.lang.CharSequence, 
> com.github.forax.lazylr.Visitor)()]
> /// creates a lexer and a parser.
> ///
> /// [com.github.forax.lazylr.Visitor] maps terminal and productions to 
> typechecked methods.
> /// When a terminal is shifted, the corresponding terminal method is called.
> /// When a production is reduced, the production method is called with the 
> values
> /// of the symbols of the production in left-to-right order.
> /// 
> [com.github.forax.lazylr.Visitor#reflect(java.lang.invoke.MethodHandles.Lookup,
>  com.github.forax.lazylr.Visitor)]
> /// creates an evaluator from a visitor using reflection.
> ///
> /// [com.github.forax.lazylr.Evaluator] maps parse events to a result
> /// of type `T`: `evaluate(Terminal)` is called on every shift,
> /// `evaluate(Production, List<T>)` on every reduction.
> /// For event-driven use without a result, prefer 
> [com.github.forax.lazylr.ParserListener].
> ///
> /// ## Thread Safety
> /// All classes are immutable and thread-safe except 
> [com.github.forax.lazylr.Parser],
> /// which is stateful and bound to the thread that uses it.
> ///
> /// [com.github.forax.lazylr.MetaGrammar] is thread-safe and can be shared 
> globally.
> ///
> /// For concurrent workloads, you can share a 
> [com.github.forax.lazylr.ParserFactory]
> /// and call [com.github.forax.lazylr.ParserFactory#createParser()]
> /// once per thread.
> ///
> /// @see com.github.forax.lazylr.Terminal
> /// @see com.github.forax.lazylr.Production
> /// @see com.github.forax.lazylr.Grammar
> /// @see com.github.forax.lazylr.MetaGrammar
> /// @see com.github.forax.lazylr.Visitor
>

Reply via email to