Conversation
- SemanticValues: defensive copy in values(), add safe parsing methods - GrammarParser/ActionCompiler: replace fold() abuse with pattern matching - ActionCompiler: Option return type, fix resource leak, add security docs - PegEngine: extract lambda, optimize skipWhitespace allocation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ActionCompiler: instance-level counter instead of static - PegEngine: defensive copy for actions map, Option for null handling - ParseMode: convert from record to class (mutable context holder) - ParsingContext: StringBuilder for furthestExpected, Option for recoveryStartPos, LRU bounded packrat cache (10k entries) - GrammarLexer: input size limit (1M), StringBuilder capacity hints - ParserGenerator: buffer capacity hints, recursion depth limit Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR updates dependency versions and documentation, and makes multiple internal refactors: replaces nulls with Option/Result patterns, adds runtime/input bounds and recursion guards, converts Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java (1)
1-380: Fix JBCT formatting (CI is red).CI reports “JBCT formatting issue detected: file not properly formatted.” Please run the formatter on this file to unblock the pipeline.
src/main/java/org/pragmatica/peg/generator/ParserGenerator.java (1)
1-3214: Fix JBCT formatting (CI is red).CI reports “JBCT formatting issue detected: file not properly formatted.” Please run the formatter on this file to unblock the pipeline.
src/main/java/org/pragmatica/peg/action/ActionCompiler.java (1)
1-263: Fix JBCT formatting (CI is red).CI reports “JBCT formatting issue detected: file not properly formatted.” Please run the formatter on this file to unblock the pipeline.
src/main/java/org/pragmatica/peg/parser/ParsingContext.java (1)
1-394: Fix JBCT formatting (CI is red).CI reports “JBCT formatting issue detected: file not properly formatted.” Please run the formatter on this file to unblock the pipeline.
src/main/java/org/pragmatica/peg/parser/PegEngine.java (1)
1-1233: Fix JBCT formatting (CI is red).CI reports “JBCT formatting issue detected: file not properly formatted.” Please run the formatter on this file to unblock the pipeline.
src/main/java/org/pragmatica/peg/parser/ParseMode.java (1)
1-114: Fix JBCT formatting (CI is red).CI reports “JBCT formatting issue detected: file not properly formatted.” Please run the formatter on this file to unblock the pipeline.
🤖 Fix all issues with AI agents
In @pom.xml:
- Line 9: Update the pragmatica-lite:core dependency version in pom.xml from
0.9.10 to 0.9.0; locate the <version> element under the pragmatica-lite:core
dependency declaration and change its value to "0.9.0" so the only runtime
dependency matches the coding guideline.
In @src/main/java/org/pragmatica/peg/action/ActionCompiler.java:
- Around line 239-242: The current getClassBytes method uses
map(ByteArrayJavaFileObject::getBytes) which can yield an Option containing null
bytes; replace the map with flatMap and re-wrap the result via Option.option to
guard against null (e.g., flatMap(obj -> Option.option(obj.getBytes()))). Make
the same change for the similar code block at the other occurrence (lines
254-261) so ByteArrayJavaFileObject.getBytes() is always null-checked before
returning an Option used by defineClass.
- Around line 62-64: The current ActionCompiler invocation passes null for the
DiagnosticListener and uses a StringWriter for diagnostics so compilation errors
are dropped; replace that flow by creating a
DiagnosticCollector<JavaFileObject>, pass it as the third argument to
compiler.getTask(...) (instead of null), remove the StringWriter-based
diagnostics, and when returning Result.failure in the compilation branch (e.g.,
in the code handling Result.Failure<?> f and the compile task around lines
158–167 and the failure at line ~164) build the failure message from the
DiagnosticCollector's diagnostics to include compiler errors/warnings.
In @src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java:
- Around line 13-15: The current tokenize() method throws
IllegalArgumentException when input exceeds MAX_INPUT_SIZE, which breaks the
Result-based parsing flow; instead, modify tokenize() to never throw for
oversized input but to emit a GrammarToken.Error token (or sequence) indicating
the oversize condition (use the existing GrammarToken.Error variant), so
GrammarParser.parse() continues to return a Result<Grammar> and can map that
token to a ParseError; update any loop or early-return paths in tokenize() (and
places referencing DEFAULT_TOKEN_CAPACITY if relevant) to push a
GrammarToken.Error with an appropriate message/context and then stop
tokenization rather than throwing an exception.
In @src/main/java/org/pragmatica/peg/grammar/GrammarParser.java:
- Around line 52-54: Run the project's Java formatter on
src/main/java/org/pragmatica/peg/grammar/GrammarParser.java (and any other
changed files) to fix the JBCT formatting failure, then replace the explicit
instanceof Result.Failure<?> checks that call Result.failure(f.cause()) with
Result combinators to avoid unwrap/duplicate error plumbing: locate the blocks
using "result instanceof Result.Failure<?> f" (occurrences around the current
checks at lines 52-54, 62-64 and 113-115), and refactor them to use
result.map(...) or result.flatMap(...) (or result.mapErr/flatMapErr depending on
API) so that success values are transformed and failure causes are propagated
automatically rather than unwrapping and re-wrapping the error.
🧹 Nitpick comments (4)
CHANGELOG.md (1)
8-13: Consider documenting internal improvements in the changelog.The changelog only mentions the dependency update, but the PR objectives describe substantial internal changes including:
- Performance optimizations (hot-path allocations in PegEngine)
- Safety improvements (defensive copies, resource leak fixes)
- Bounded caches (ParsingContext with 10k entry LRU)
- Input validation (GrammarLexer 1M character limit)
- API enhancements (SemanticValues safe parsing methods)
While these may be internal changes, documenting them helps users understand performance characteristics and provides transparency for a release labeled "comprehensive JBCT compliance fixes."
src/main/java/org/pragmatica/peg/generator/ParserGenerator.java (1)
385-387: Recursion-depth guard: include rule/expression context (and confirm “indent” is the intended metric).Throwing is fine for a generator, but the current exception won’t tell users which rule/expression is too deep, and
indentis an indirect proxy for nesting. Consider threading the current rule name (and maybe expr kind) into the message.Also applies to: 2119-2121
src/main/java/org/pragmatica/peg/parser/PegEngine.java (1)
165-167: Helper extraction looks good; consider making the diagnostic message less generic.
toDiagnosticsResult()centralizes conversion nicely; optionally useparseError.message()as the primary diagnostic message (instead of"parse error") for better UX.Also applies to: 172-178
src/main/java/org/pragmatica/peg/parser/ParseMode.java (1)
65-93: Optional: de-duplicate getters vsshouldSkipWhitespace()/shouldCollectActions().You now expose both
skipWhitespace()/collectActions()andshouldSkipWhitespace()/shouldCollectActions(); consider keeping one naming style to reduce surface area.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
CHANGELOG.mdCLAUDE.mdREADME.mdpom.xmlsrc/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/action/SemanticValues.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.java
🧰 Additional context used
📓 Path-based instructions (9)
pom.xml
📄 CodeRabbit inference engine (CLAUDE.md)
Use pragmatica-lite:core 0.9.0 as the only runtime dependency, providing Result/Option/Promise types
Files:
pom.xml
**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.java: Use sealed interfaces for abstract types with fixed implementations (Expression, ParseResult, CstNode, AstNode, Trivia, ParseError)
Use record classes for immutable data types (Rule, Grammar, SourceLocation, SourceSpan, ParserConfig)
Files:
src/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/action/SemanticValues.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.java
src/main/java/org/pragmatica/peg/**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
src/main/java/org/pragmatica/peg/**/*.java: Package code under org.pragmatica.peg namespace
Use Result/Option types from pragmatica-lite for return values instead of exceptions or null
Files:
src/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/action/SemanticValues.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.java
src/main/java/org/pragmatica/peg/parser/**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
Implement both CST (Concrete Syntax Tree) and AST (Abstract Syntax Tree) output modes for parsers
Files:
src/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.java
src/main/java/org/pragmatica/peg/{parser,generator}/**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
Support both runtime compilation (JDK Compiler API with full Java support) and source generation (single self-contained Java file) modes
Files:
src/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.java
src/main/java/org/pragmatica/peg/parser/ParsingContext.java
📄 CodeRabbit inference engine (CLAUDE.md)
Use packrat memoization for parsing performance optimization with configurable enable/disable
Files:
src/main/java/org/pragmatica/peg/parser/ParsingContext.java
**/*[Gg]rammar*.java
📄 CodeRabbit inference engine (CLAUDE.md)
Inline Java actions must be written in { } blocks within grammar syntax and have access to SemanticValues (sv) with $0, $1, $2 references
Files:
src/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.java
src/main/java/org/pragmatica/peg/grammar/**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
Implement grammar syntax compatible with cpp-peglib, including operators (e1 e2, e1/e2, e*, e+, e?, &e, !e), extensions (< >, ~e, 'text'i, $name, ^), and directives (%whitespace)
Files:
src/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.java
src/main/java/org/pragmatica/peg/generator/**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
Generated parsers should only depend on pragmatica-lite:core, with optional ErrorReporting enum (BASIC/ADVANCED) for Rust-style diagnostics
Files:
src/main/java/org/pragmatica/peg/generator/ParserGenerator.java
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/test/java/org/pragmatica/peg/**/*.java : Test coverage should include: grammar parser (17), parsing engine (29), actions (6), generator (18), internal types (24), examples (135), and trivia handling (19)
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/**/*.java : Package code under org.pragmatica.peg namespace
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/grammar/**/*.java : Implement grammar syntax compatible with cpp-peglib, including operators (e1 e2, e1/e2, e*, e+, e?, &e, !e), extensions (< >, ~e, 'text'i, $name, ^), and directives (%whitespace)
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/**/*.java : Use Result/Option types from pragmatica-lite for return values instead of exceptions or null
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/{parser,generator}/**/*.java : Support both runtime compilation (JDK Compiler API with full Java support) and source generation (single self-contained Java file) modes
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to pom.xml : Use pragmatica-lite:core 0.9.0 as the only runtime dependency, providing Result/Option/Promise types
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/generator/**/*.java : Generated parsers should only depend on pragmatica-lite:core, with optional ErrorReporting enum (BASIC/ADVANCED) for Rust-style diagnostics
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/parser/**/*.java : Implement both CST (Concrete Syntax Tree) and AST (Abstract Syntax Tree) output modes for parsers
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/**/*.java : Package code under org.pragmatica.peg namespace
Applied to files:
README.mdpom.xmlCLAUDE.mdsrc/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to pom.xml : Use pragmatica-lite:core 0.9.0 as the only runtime dependency, providing Result/Option/Promise types
Applied to files:
README.mdpom.xmlCHANGELOG.md
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/generator/**/*.java : Generated parsers should only depend on pragmatica-lite:core, with optional ErrorReporting enum (BASIC/ADVANCED) for Rust-style diagnostics
Applied to files:
README.mdpom.xmlCLAUDE.mdsrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/grammar/**/*.java : Implement grammar syntax compatible with cpp-peglib, including operators (e1 e2, e1/e2, e*, e+, e?, &e, !e), extensions (< >, ~e, 'text'i, $name, ^), and directives (%whitespace)
Applied to files:
README.mdpom.xmlCLAUDE.mdsrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/**/*.java : Use Result/Option types from pragmatica-lite for return values instead of exceptions or null
Applied to files:
README.mdpom.xmlCLAUDE.mdsrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/action/SemanticValues.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/{parser,generator}/**/*.java : Support both runtime compilation (JDK Compiler API with full Java support) and source generation (single self-contained Java file) modes
Applied to files:
README.mdCLAUDE.mdsrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/parser/**/*.java : Implement both CST (Concrete Syntax Tree) and AST (Abstract Syntax Tree) output modes for parsers
Applied to files:
README.mdCLAUDE.mdsrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/test/java/org/pragmatica/peg/**/*.java : Test coverage should include: grammar parser (17), parsing engine (29), actions (6), generator (18), internal types (24), examples (135), and trivia handling (19)
Applied to files:
README.mdCLAUDE.mdsrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/error/**/*.java : Support configurable error recovery with three strategies: NONE (fail immediately), BASIC (report error with context), ADVANCED (continue parsing and collect multiple errors)
Applied to files:
CLAUDE.mdsrc/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.javasrc/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/grammar/Expression.java : Implement cut operator (^ or ↑) to commit to current choice and prevent backtracking
Applied to files:
CLAUDE.mdsrc/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/parser/ParsingContext.java : Use packrat memoization for parsing performance optimization with configurable enable/disable
Applied to files:
src/main/java/org/pragmatica/peg/parser/ParsingContext.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/error/Diagnostic.java : Implement Rust-style diagnostic formatting with error location (file:line:column), context lines, and help messages for error recovery output
Applied to files:
src/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to **/*.java : Use record classes for immutable data types (Rule, Grammar, SourceLocation, SourceSpan, ParserConfig)
Applied to files:
src/main/java/org/pragmatica/peg/parser/ParseMode.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/tree/Trivia.java : Support trivia classification by content inspection: lines starting with // are LineComment, /* ... */ are BlockComment, otherwise Whitespace
Applied to files:
src/main/java/org/pragmatica/peg/parser/PegEngine.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/tree/**/*.java : Group whitespace and comments as Trivia nodes (Trivia.Whitespace, Trivia.LineComment, Trivia.BlockComment) for lossless CST
Applied to files:
src/main/java/org/pragmatica/peg/parser/PegEngine.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/test/java/org/pragmatica/peg/examples/Java25GrammarExample.java : For Java 25 grammar implementation, distinguish between hard keywords (always reserved) and contextual keywords (context-dependent), matching contextual keywords in specific rules only
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to **/*[Gg]rammar*.java : Inline Java actions must be written in { } blocks within grammar syntax and have access to SemanticValues (sv) with $0, $1, $2 references
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.java
🧬 Code graph analysis (1)
src/main/java/org/pragmatica/peg/parser/PegEngine.java (1)
src/main/java/org/pragmatica/peg/action/SemanticValues.java (1)
SemanticValues(14-190)
🪛 GitHub Actions: CI
src/main/java/org/pragmatica/peg/parser/ParsingContext.java
[error] 1-1: JBCT formatting issue detected: file not properly formatted.
src/main/java/org/pragmatica/peg/grammar/GrammarParser.java
[error] 1-1: JBCT formatting issue detected: file not properly formatted.
src/main/java/org/pragmatica/peg/parser/ParseMode.java
[error] 1-1: JBCT formatting issue detected: file not properly formatted.
src/main/java/org/pragmatica/peg/parser/PegEngine.java
[error] 1-1: JBCT formatting issue detected: file not properly formatted.
src/main/java/org/pragmatica/peg/generator/ParserGenerator.java
[error] 1-1: JBCT formatting issue detected: file not properly formatted.
src/main/java/org/pragmatica/peg/action/ActionCompiler.java
[error] 1-1: JBCT formatting issue detected: file not properly formatted.
src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java
[error] 1-1: JBCT formatting issue detected: file not properly formatted.
🔇 Additional comments (20)
README.md (1)
25-25: LGTM!The version update in the dependency example is consistent with the version bump in pom.xml and CHANGELOG.md.
src/main/java/org/pragmatica/peg/action/SemanticValues.java (3)
65-87: Safe parsing methods improve error handling.The addition of
toIntSafe(),toLongSafe(), andtoDoubleSafe()methods provides Result-based alternatives to the exception-throwing methods, aligning with the project's JBCT compliance goals and the guideline to use Result/Option types.The methods properly delegate to
Number.parseInt/parseLong/parseDoublefrom pragmatica-lite after trimming the input.Based on learnings about using Result/Option types from pragmatica-lite for return values instead of exceptions.
169-174: Defensive copy preserves immutability.Returning
List.copyOf(values)instead of the internal list prevents external mutation and aligns with the immutability goals mentioned in the PR objectives.
4-5: pragmatica-lite:core 0.9.10 is not available on Maven Central and will cause a build failure.The pom.xml declares
pragmatica-lite.version=0.9.10, but Maven Central only publishes versions up to 0.8.x. No custom repository is configured in pom.xml to provide 0.9.10, so the build will fail during dependency resolution. The CHANGELOG indicates this was an intentional upgrade (v0.1.9), but the artifact doesn't exist in any public repository.Clarify whether:
- pragmatica-lite 0.9.10 will be published (and when)
- A custom repository should be added to pom.xml to resolve it
- The version should revert to an available release (e.g., 0.9.0)
The Number API verification cannot proceed until this dependency is resolved.
CLAUDE.md (2)
5-7: Agent usage directive added.The new section mandates using only the
jbct-coderagent for all coding tasks. This is a project-specific workflow guideline with no impact on code functionality.
151-151: Test count updated to reflect current state.The test count has been updated from 305 to 308, which aligns with the PR objectives stating "308 passing tests."
Also applies to: 422-422
src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java (1)
85-90: StringBuilder capacity hints look good.Reasonable micro-optimization; still safe since builders grow as needed.
Also applies to: 95-100, 104-105, 135-136, 173-175, 202-205, 218-224
src/main/java/org/pragmatica/peg/generator/ParserGenerator.java (1)
12-14: Buffer pre-sizing looks good.Using a larger initial
StringBuildercapacity for generated sources is a sensible perf win for non-trivial grammars.Also applies to: 118-119, 135-136
src/main/java/org/pragmatica/peg/action/ActionCompiler.java (3)
25-33: Security documentation addition is a good call.Clear warning about arbitrary code execution risk is important for this component.
38-39: Instance-scoped action class naming is safer than a static counter.Avoids cross-test/process interference and makes ActionCompiler behavior easier to reason about.
Also applies to: 94-100
152-176: Confirm Java toolchain expectations for--release 25.This will fail at runtime on older JDKs even if the library is otherwise usable. If Java 25 is required for the project, great—otherwise consider making the release level configurable or documenting it more explicitly.
src/main/java/org/pragmatica/peg/parser/ParsingContext.java (3)
21-23: Bounded LRU packrat cache is a good safety improvement.Capping to
MAX_CACHE_SIZEprevents unbounded memory growth while keeping recent entries hot. Based on learnings/guidelines about packrat memoization, this is a solid default.Also applies to: 47-57, 362-369
42-43:recoveryStartPosis now Option-wrapped: ensure it’s used or remove it.In this file it’s set/cleared but not otherwise referenced; please confirm it’s consumed elsewhere for error nodes/diagnostics (or drop it to avoid dead state).
Also applies to: 222-227, 232-235
36-37: This concern is not applicable to this codebase.The project targets Java 25 (
maven.compiler.release=25in pom.xml), andStringBuilder.isEmpty()has been available since Java 15. The current code usingisEmpty()is the correct, more readable approach—length() == 0would be an unnecessary downgrade.Likely an incorrect or invalid review comment.
src/main/java/org/pragmatica/peg/parser/PegEngine.java (5)
36-48: Defensive copy of actions map is the right call.
Map.copyOf(actions)prevents caller mutation from affecting engine behavior;Map.of()increateWithoutActions()also avoids accidental mutability.
316-325: Option-based token/action handling looks good.This aligns well with the project’s Option/Result style and avoids null checks.
458-470: Dictionary match refactor to Option is solid.Makes “no match” explicit and removes null tracking.
Also applies to: 478-483
747-752: Whitespace fast-path improvement looks good.Early
List.of()return avoids unnecessary allocations on hot paths.
889-891: Token-capture propagation via Option.onPresent is a nice cleanup.Keeps the “only on success” semantics clear and avoids manual null checks.
Also applies to: 935-937, 997-999, 1079-1081
src/main/java/org/pragmatica/peg/parser/ParseMode.java (1)
16-33: ParseMode as a mutable context holder is consistent with how it’s used.Factories +
childMode()+ Option-guarded mutation read well and match the intended semantics.Also applies to: 65-79, 97-103, 107-113
| <groupId>org.pragmatica-lite</groupId> | ||
| <artifactId>peglib</artifactId> | ||
| <version>0.1.8</version> | ||
| <version>0.1.9</version> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n pom.xml | head -60Repository: siy/java-peglib
Length of output: 2543
🏁 Script executed:
# Search for all dependency declarations in pom.xml
rg -A 3 "<dependency>" pom.xmlRepository: siy/java-peglib
Length of output: 547
🌐 Web query:
pragmatica-lite 0.9.10 maven central release
💡 Result:
I couldn't find pragmatica-lite version 0.9.10 on Maven Central. The Maven Central group listing and package pages show other versions (e.g. tcp 0.9.8, core up to ~0.9.0 / 0.8.x), but no 0.9.10 release. [1][2][3]
Sources:
- Maven Central group index for org.pragmatica-lite. [1]
- mvnrepository listing for org.pragmatica-lite tcp (shows 0.9.8). [2]
- javadoc.io / core package (latest shown ~0.9.0). [3]
Want me to watch for a 0.9.10 release and notify you when it appears?
🌐 Web query:
pragmatica-lite releases changelog 0.9.0 0.9.10
💡 Result:
Do you mean the pragmatica-lite "pragmatica-lite" artifact (or a specific module like core, tcp, etc.) — and do you want the full changelog entries for versions 0.9.0 and 0.9.10 or just a short summary?
🏁 Script executed:
#!/bin/bash
# Query Maven Central for pragmatica-lite:core versions
echo "Checking Maven Central for org.pragmatica-lite:core versions:"
curl -s "https://search.maven.org/solrsearch/select?q=g:org.pragmatica-lite+AND+a:core&core=gav&rows=100&wt=json" | jq '.response.docs[] | {v: .v}' | sort -uRepository: siy/java-peglib
Length of output: 120
🏁 Script executed:
#!/bin/bash
# Also check the GitHub releases for pragmatica-lite project
echo "Searching for pragmatica-lite releases:"
curl -s https://api.github.com/repos/siy/pragmatica-lite/releases 2>/dev/null | jq '.[] | {tag_name, published_at}' | head -40Repository: siy/java-peglib
Length of output: 720
Update pragmatica-lite:core dependency version to 0.9.0 per coding guideline.
The pom.xml specifies pragmatica-lite:core 0.9.10, but the coding guideline requires version 0.9.0 as the only runtime dependency. While 0.9.10 has been released (2026-01-07), the dependency version must align with the stated requirement.
pragmatica-lite:core is correctly the only runtime dependency; only the version number requires adjustment.
🤖 Prompt for AI Agents
In @pom.xml at line 9, Update the pragmatica-lite:core dependency version in
pom.xml from 0.9.10 to 0.9.0; locate the <version> element under the
pragmatica-lite:core dependency declaration and change its value to "0.9.0" so
the only runtime dependency matches the coding guideline.
| if (result instanceof Result.Failure<?> f) { | ||
| return Result.failure(f.cause()); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n src/main/java/org/pragmatica/peg/action/ActionCompiler.java | sed -n '50,75p'Repository: siy/java-peglib
Length of output: 1016
🏁 Script executed:
cat -n src/main/java/org/pragmatica/peg/action/ActionCompiler.java | sed -n '150,180p'Repository: siy/java-peglib
Length of output: 1841
🏁 Script executed:
head -20 src/main/java/org/pragmatica/peg/action/ActionCompiler.javaRepository: siy/java-peglib
Length of output: 684
🏁 Script executed:
cat > /tmp/check_compiler_api.py << 'EOF'
# Check Java Compiler API documentation
# The getTask method signature is:
# CompilationTask getTask(Writer out, JavaFileManager fileManager,
# DiagnosticListener<? super JavaFileObject> diagnosticListener,
# Iterable<String> options, Iterable<String> classes,
# Iterable<? extends JavaFileObject> compilationUnits)
# Parameter meanings:
# 1. Writer out - for non-diagnostic output (like verbose logging)
# 2. fileManager
# 3. DiagnosticListener - THIS is where compilation diagnostics (errors/warnings) go
# 4. options
# 5. classes
# 6. compilationUnits
# The issue: In the code, the StringWriter is passed as 'out' (parameter 1)
# But the DiagnosticListener parameter (parameter 3) is null
# This means diagnostics are dropped/not captured
print("""
Java Compiler API Analysis:
==========================
compiler.getTask() signature:
CompilationTask getTask(
Writer out, // <- StringWriter passed here (WRONG)
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener, // <- null here (PROBLEM)
Iterable<String> options,
Iterable<String> classes,
Iterable<? extends JavaFileObject> compilationUnits)
Current code (INCORRECT):
compiler.getTask(diagnostics, fileManager, null, ...)
- Passes StringWriter as 'out' (for general output, not diagnostics)
- Passes null for DiagnosticListener (where actual compilation errors go)
Result: Compilation errors/warnings are NOT captured properly
Solution:
Use DiagnosticCollector<JavaFileObject> for the DiagnosticListener parameter
Pass null or discard the 'out' parameter
DiagnosticCollector<JavaFileObject> collector = new DiagnosticCollector<>();
compiler.getTask(null, fileManager, collector, ...)
// Then use collector.getDiagnostics() to get errors/warnings
""")
EOF
python /tmp/check_compiler_api.pyRepository: siy/java-peglib
Length of output: 145
🏁 Script executed:
rg -A 5 "^import.*javax.tools" src/main/java/org/pragmatica/peg/action/ActionCompiler.javaRepository: siy/java-peglib
Length of output: 321
🏁 Script executed:
rg "DiagnosticCollector" src/main/java/org/pragmatica/peg/Repository: siy/java-peglib
Length of output: 41
🏁 Script executed:
cat -n src/main/java/org/pragmatica/peg/action/ActionCompiler.java | sed -n '152,177p'Repository: siy/java-peglib
Length of output: 1701
🏁 Script executed:
# Check if the compileAction method itself has similar issues
cat -n src/main/java/org/pragmatica/peg/action/ActionCompiler.java | sed -n '74,150p'Repository: siy/java-peglib
Length of output: 3746
Replace StringWriter diagnostics capture with DiagnosticCollector for proper compilation error reporting.
The compiler.getTask() method's first parameter is the general out stream, not a diagnostics sink. The third parameter is where DiagnosticListener should be passed to capture compilation errors and warnings. Currently, null is passed, meaning all diagnostics are dropped. When compilation fails at line 164, the error message will be nearly empty (just the StringWriter's content, which has nothing).
Use DiagnosticCollector<JavaFileObject> instead:
Required fix
+import javax.tools.DiagnosticCollector;
...
try (var standardFileManager = compiler.getStandardFileManager(null, null, null)) {
var fileManager = new InMemoryFileManager(standardFileManager);
var sourceFile = new StringJavaFileObject(className, sourceCode);
- var diagnostics = new StringWriter();
+ var collector = new DiagnosticCollector<JavaFileObject>();
var task = compiler.getTask(
- diagnostics, fileManager, null, List.of("--release", "25"), null, List.of(sourceFile));
+ null, fileManager, collector, List.of("--release", "25"), null, List.of(sourceFile));
if (!task.call()) {
return Result.failure(new ParseError.SemanticError(
- location, "Action compilation failed: " + diagnostics));
+ location, "Action compilation failed: " + collector.getDiagnostics()));
}Also applies to: 158–167
🤖 Prompt for AI Agents
In @src/main/java/org/pragmatica/peg/action/ActionCompiler.java around lines 62
- 64, The current ActionCompiler invocation passes null for the
DiagnosticListener and uses a StringWriter for diagnostics so compilation errors
are dropped; replace that flow by creating a
DiagnosticCollector<JavaFileObject>, pass it as the third argument to
compiler.getTask(...) (instead of null), remove the StringWriter-based
diagnostics, and when returning Result.failure in the compilation branch (e.g.,
in the code handling Result.Failure<?> f and the compile task around lines
158–167 and the failure at line ~164) build the failure message from the
DiagnosticCollector's diagnostics to include compiler errors/warnings.
| Option<byte[]> getClassBytes(String className) { | ||
| return Option.option(classFiles.get(className)) | ||
| .map(ByteArrayJavaFileObject::getBytes); | ||
| } |
There was a problem hiding this comment.
Harden Option<byte[]> so null bytes can’t slip through.
If ByteArrayJavaFileObject.getBytes() is still null, map(ByteArrayJavaFileObject::getBytes) may produce an Option that unwraps to null (depending on Option semantics), which would blow up in defineClass. Prefer flatMap to re-wrap via Option.option(...).
Proposed fix
Option<byte[]> getClassBytes(String className) {
- return Option.option(classFiles.get(className))
- .map(ByteArrayJavaFileObject::getBytes);
+ return Option.option(classFiles.get(className))
+ .flatMap(file -> Option.option(file.getBytes()));
}Also applies to: 254-261
🤖 Prompt for AI Agents
In @src/main/java/org/pragmatica/peg/action/ActionCompiler.java around lines 239
- 242, The current getClassBytes method uses
map(ByteArrayJavaFileObject::getBytes) which can yield an Option containing null
bytes; replace the map with flatMap and re-wrap the result via Option.option to
guard against null (e.g., flatMap(obj -> Option.option(obj.getBytes()))). Make
the same change for the similar code block at the other occurrence (lines
254-261) so ByteArrayJavaFileObject.getBytes() is always null-checked before
returning an Option used by defineClass.
| private static final int MAX_INPUT_SIZE = 1_000_000; | ||
| private static final int DEFAULT_TOKEN_CAPACITY = 32; | ||
|
|
There was a problem hiding this comment.
Avoid throwing in tokenize(): return a lexer error token to keep Result-based flow.
tokenize() throwing IllegalArgumentException will bypass GrammarParser.parse()’s Result<Grammar> contract on oversized inputs. Prefer emitting GrammarToken.Error so the caller can surface a ParseError consistently (as per learnings/guidelines about Result/Option usage).
Proposed fix (keep signature, no exception)
public static List<GrammarToken> tokenize(String input) {
- if (input.length() > MAX_INPUT_SIZE) {
- throw new IllegalArgumentException(
- "Grammar input exceeds maximum size of " + MAX_INPUT_SIZE + " characters");
- }
- return new GrammarLexer(input).tokenizeAll();
+ if (input.length() > MAX_INPUT_SIZE) {
+ var loc = SourceLocation.at(1, 1, 0);
+ var span = SourceSpan.at(loc);
+ return List.of(
+ new GrammarToken.Error(span, "Grammar input exceeds maximum size of " + MAX_INPUT_SIZE + " characters"),
+ new GrammarToken.Eof(span)
+ );
+ }
+ return new GrammarLexer(input).tokenizeAll();
}Also applies to: 29-33
🤖 Prompt for AI Agents
In @src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java around lines 13 -
15, The current tokenize() method throws IllegalArgumentException when input
exceeds MAX_INPUT_SIZE, which breaks the Result-based parsing flow; instead,
modify tokenize() to never throw for oversized input but to emit a
GrammarToken.Error token (or sequence) indicating the oversize condition (use
the existing GrammarToken.Error variant), so GrammarParser.parse() continues to
return a Result<Grammar> and can map that token to a ParseError; update any loop
or early-return paths in tokenize() (and places referencing
DEFAULT_TOKEN_CAPACITY if relevant) to push a GrammarToken.Error with an
appropriate message/context and then stop tokenization rather than throwing an
exception.
| if (result instanceof Result.Failure<?> f) { | ||
| return Result.failure(f.cause()); | ||
| } |
There was a problem hiding this comment.
Fix JBCT formatting (CI is red) + consider avoiding unwrap() via Result combinators.
- CI reports “JBCT formatting issue detected: file not properly formatted.” Please run the formatter on this file (and any other touched files) to unblock the pipeline.
- The new
instanceof Result.Failure<?> fpropagation is fine, but these blocks can usually becomereturn result.map(...)/flatMap(...)to avoidunwrap()and duplicate error plumbing.
Also applies to: 62-64, 113-115
🤖 Prompt for AI Agents
In @src/main/java/org/pragmatica/peg/grammar/GrammarParser.java around lines 52
- 54, Run the project's Java formatter on
src/main/java/org/pragmatica/peg/grammar/GrammarParser.java (and any other
changed files) to fix the JBCT formatting failure, then replace the explicit
instanceof Result.Failure<?> checks that call Result.failure(f.cause()) with
Result combinators to avoid unwrap/duplicate error plumbing: locate the blocks
using "result instanceof Result.Failure<?> f" (occurrences around the current
checks at lines 52-54, 62-64 and 113-115), and refactor them to use
result.map(...) or result.flatMap(...) (or result.mapErr/flatMapErr depending on
API) so that success values are transformed and failure causes are propagated
automatically rather than unwrapping and re-wrapping the error.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java (1)
29-32: Consider Result pattern for consistency.The input size validation is effective. However, based on learnings, the codebase prefers Result/Option types over exceptions. Consider returning
Result<List<GrammarToken>, String>to align with this pattern, though the current implementation is functional.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/generator/ParserGenerator.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.javasrc/main/java/org/pragmatica/peg/parser/ParseMode.javasrc/main/java/org/pragmatica/peg/parser/ParsingContext.javasrc/main/java/org/pragmatica/peg/parser/PegEngine.java
🚧 Files skipped from review as they are similar to previous changes (4)
- src/main/java/org/pragmatica/peg/generator/ParserGenerator.java
- src/main/java/org/pragmatica/peg/parser/PegEngine.java
- src/main/java/org/pragmatica/peg/parser/ParseMode.java
- src/main/java/org/pragmatica/peg/parser/ParsingContext.java
🧰 Additional context used
📓 Path-based instructions (4)
**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.java: Use sealed interfaces for abstract types with fixed implementations (Expression, ParseResult, CstNode, AstNode, Trivia, ParseError)
Use record classes for immutable data types (Rule, Grammar, SourceLocation, SourceSpan, ParserConfig)
Files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
src/main/java/org/pragmatica/peg/**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
src/main/java/org/pragmatica/peg/**/*.java: Package code under org.pragmatica.peg namespace
Use Result/Option types from pragmatica-lite for return values instead of exceptions or null
Files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
**/*[Gg]rammar*.java
📄 CodeRabbit inference engine (CLAUDE.md)
Inline Java actions must be written in { } blocks within grammar syntax and have access to SemanticValues (sv) with $0, $1, $2 references
Files:
src/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
src/main/java/org/pragmatica/peg/grammar/**/*.java
📄 CodeRabbit inference engine (CLAUDE.md)
Implement grammar syntax compatible with cpp-peglib, including operators (e1 e2, e1/e2, e*, e+, e?, &e, !e), extensions (< >, ~e, 'text'i, $name, ^), and directives (%whitespace)
Files:
src/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/**/*.java : Package code under org.pragmatica.peg namespace
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/test/java/org/pragmatica/peg/**/*.java : Test coverage should include: grammar parser (17), parsing engine (29), actions (6), generator (18), internal types (24), examples (135), and trivia handling (19)
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/grammar/**/*.java : Implement grammar syntax compatible with cpp-peglib, including operators (e1 e2, e1/e2, e*, e+, e?, &e, !e), extensions (< >, ~e, 'text'i, $name, ^), and directives (%whitespace)
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/**/*.java : Use Result/Option types from pragmatica-lite for return values instead of exceptions or null
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/{parser,generator}/**/*.java : Support both runtime compilation (JDK Compiler API with full Java support) and source generation (single self-contained Java file) modes
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to pom.xml : Use pragmatica-lite:core 0.9.0 as the only runtime dependency, providing Result/Option/Promise types
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/generator/**/*.java : Generated parsers should only depend on pragmatica-lite:core, with optional ErrorReporting enum (BASIC/ADVANCED) for Rust-style diagnostics
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/{parser,generator}/**/*.java : Support both runtime compilation (JDK Compiler API with full Java support) and source generation (single self-contained Java file) modes
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/test/java/org/pragmatica/peg/**/*.java : Test coverage should include: grammar parser (17), parsing engine (29), actions (6), generator (18), internal types (24), examples (135), and trivia handling (19)
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/**/*.java : Use Result/Option types from pragmatica-lite for return values instead of exceptions or null
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/**/*.java : Package code under org.pragmatica.peg namespace
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/generator/**/*.java : Generated parsers should only depend on pragmatica-lite:core, with optional ErrorReporting enum (BASIC/ADVANCED) for Rust-style diagnostics
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/grammar/**/*.java : Implement grammar syntax compatible with cpp-peglib, including operators (e1 e2, e1/e2, e*, e+, e?, &e, !e), extensions (< >, ~e, 'text'i, $name, ^), and directives (%whitespace)
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to **/*[Gg]rammar*.java : Inline Java actions must be written in { } blocks within grammar syntax and have access to SemanticValues (sv) with $0, $1, $2 references
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/error/Diagnostic.java : Implement Rust-style diagnostic formatting with error location (file:line:column), context lines, and help messages for error recovery output
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/grammar/Expression.java : Implement cut operator (^ or ↑) to commit to current choice and prevent backtracking
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/error/**/*.java : Support configurable error recovery with three strategies: NONE (fail immediately), BASIC (report error with context), ADVANCED (continue parsing and collect multiple errors)
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/main/java/org/pragmatica/peg/parser/**/*.java : Implement both CST (Concrete Syntax Tree) and AST (Abstract Syntax Tree) output modes for parsers
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
📚 Learning: 2025-12-30T12:39:57.084Z
Learnt from: CR
Repo: siy/java-peglib PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T12:39:57.084Z
Learning: Applies to src/test/java/org/pragmatica/peg/examples/Java25GrammarExample.java : For Java 25 grammar implementation, distinguish between hard keywords (always reserved) and contextual keywords (context-dependent), matching contextual keywords in specific rules only
Applied to files:
src/main/java/org/pragmatica/peg/action/ActionCompiler.javasrc/main/java/org/pragmatica/peg/grammar/GrammarLexer.javasrc/main/java/org/pragmatica/peg/grammar/GrammarParser.java
🔇 Additional comments (11)
src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java (2)
13-14: LGTM! Good defensive programming practice.The constants provide clear resource bounds and capacity hints, aligning with the PR's goal of adding runtime limits and optimizations.
85-85: LGTM! Effective allocation optimization.The StringBuilder capacity hints reduce reallocation overhead. The 32-character default is appropriate for most token types. Note that action code blocks (Line 173) may frequently exceed this capacity, but the StringBuilder will still resize automatically—this is a minor efficiency consideration rather than a functional concern.
Also applies to: 95-95, 104-104, 135-135, 173-173, 202-202, 218-218
src/main/java/org/pragmatica/peg/grammar/GrammarParser.java (3)
52-54: LGTM: Pattern matching for Result.Failure.The refactor from
isFailure()toinstanceof Result.Failure<?> fis idiomatic and consistent with the PR's broader Result handling improvements.
62-64: LGTM: Consistent failure propagation.Same pattern matching refactor as the directive parsing above.
113-115: LGTM: Uniform Result handling.Completes the consistent pattern matching refactor across all failure checks in
parseGrammar().src/main/java/org/pragmatica/peg/action/ActionCompiler.java (6)
25-32: Excellent security documentation.The added warning about arbitrary code execution risks is critical for users working with untrusted grammars. The guidance to use source generation mode for sandboxing is practical and actionable.
38-38: Good encapsulation improvement.Moving the counter from static to instance-level improves encapsulation and allows multiple
ActionCompilerinstances to operate independently. Since each compilation creates its ownInMemoryClassLoader, potential class name collisions across instances are safely isolated.
62-64: LGTM: Consistent Result.Failure pattern matching.Aligns with the same refactor applied across other files in this PR.
158-177: Critical resource leak fix.The try-with-resources block ensures
standardFileManageris properly closed, fixing a resource leak present in the previous implementation. TheInMemoryFileManagerdelegates to the underlying manager, so its cleanup is handled correctly.
239-242: Proper Option usage for null safety.Changing the return type to
Option<byte[]>aligns with the coding guidelines and eliminates null handling ambiguity.Based on learnings, projects should use Result/Option types from pragmatica-lite instead of null.
254-261: Correct Option handling.The updated
findClassproperly handles theOption<byte[]>fromgetClassBytes, checking for presence before unwrapping. The behavior remains correct.
Summary
Changes
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Chores
Tests
✏️ Tip: You can customize this high-level summary in your review settings.