From 4b9fe87575d3498fc9043aac3c708989162d926d Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 04:55:32 +0200 Subject: [PATCH 1/9] chore: prepare release 0.3.0 --- CHANGELOG.md | 2 ++ README.md | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57412d0..de6dead 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0] - 2026-04-22 + ## [0.2.9] - 2026-04-22 ### Added diff --git a/README.md b/README.md index 7ba751b..0650124 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ A PEG (Parsing Expression Grammar) parser library for Java, inspired by [cpp-peg org.pragmatica-lite peglib - 0.2.9 + 0.3.0 ``` @@ -354,7 +354,7 @@ The `peglib-maven-plugin` module (separate artifact, sibling to `peglib`) wraps org.pragmatica-lite peglib-maven-plugin - 0.2.9 + 0.3.0 diff --git a/pom.xml b/pom.xml index 5722390..239e21b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.pragmatica-lite peglib - 0.2.9 + 0.3.0 jar Peglib From 255ffa652dc98eb499de4c64f6a232eb8872c841 Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 05:17:33 +0200 Subject: [PATCH 2/9] refactor: convert to multi-module peglib-parent (peglib-core + incremental/formatter shells) --- peglib-core/pom.xml | 183 ++++++++++++++ .../peg/bench/Java25ParseBenchmark.java | 0 .../peg/bench/PackratStatsProbe.java | 0 .../java/org/pragmatica/peg/PegParser.java | 0 .../org/pragmatica/peg/action/Action.java | 0 .../pragmatica/peg/action/ActionCompiler.java | 0 .../org/pragmatica/peg/action/Actions.java | 0 .../org/pragmatica/peg/action/RuleId.java | 0 .../pragmatica/peg/action/SemanticValues.java | 0 .../org/pragmatica/peg/analyzer/Analyzer.java | 0 .../pragmatica/peg/analyzer/AnalyzerMain.java | 0 .../peg/analyzer/AnalyzerReport.java | 0 .../org/pragmatica/peg/analyzer/Finding.java | 0 .../org/pragmatica/peg/error/Diagnostic.java | 0 .../org/pragmatica/peg/error/ParseError.java | 0 .../peg/error/RecoveryStrategy.java | 0 .../peg/generator/ChoiceDispatchAnalyzer.java | 0 .../peg/generator/ErrorReporting.java | 0 .../peg/generator/ParserGenerator.java | 0 .../pragmatica/peg/grammar/Expression.java | 0 .../org/pragmatica/peg/grammar/Grammar.java | 0 .../pragmatica/peg/grammar/GrammarLexer.java | 0 .../pragmatica/peg/grammar/GrammarParser.java | 0 .../peg/grammar/GrammarResolver.java | 0 .../pragmatica/peg/grammar/GrammarSource.java | 0 .../pragmatica/peg/grammar/GrammarToken.java | 0 .../org/pragmatica/peg/grammar/Import.java | 0 .../java/org/pragmatica/peg/grammar/Rule.java | 0 .../peg/grammar/analysis/ExpressionShape.java | 0 .../grammar/analysis/FirstCharAnalysis.java | 0 .../analysis/LeftRecursionAnalysis.java | 0 .../org/pragmatica/peg/parser/ParseMode.java | 0 .../pragmatica/peg/parser/ParseResult.java | 0 .../parser/ParseResultWithDiagnostics.java | 0 .../org/pragmatica/peg/parser/Parser.java | 0 .../pragmatica/peg/parser/ParserConfig.java | 0 .../pragmatica/peg/parser/ParsingContext.java | 0 .../org/pragmatica/peg/parser/PegEngine.java | 0 .../java/org/pragmatica/peg/tree/AstNode.java | 0 .../java/org/pragmatica/peg/tree/CstNode.java | 0 .../pragmatica/peg/tree/SourceLocation.java | 0 .../org/pragmatica/peg/tree/SourceSpan.java | 0 .../java/org/pragmatica/peg/tree/Trivia.java | 0 .../java/org/pragmatica/peg/EdgeCaseTest.java | 0 .../org/pragmatica/peg/ErrorRecoveryTest.java | 0 .../peg/GeneratedParserTriviaTest.java | 0 .../peg/GeneratorConformanceTest.java | 0 .../peg/NegativeLookaheadBugTest.java | 0 .../org/pragmatica/peg/PegParserTest.java | 0 .../java/org/pragmatica/peg/TriviaTest.java | 0 .../peg/action/ActionsImmutabilityTest.java | 0 .../peg/action/LambdaActionTest.java | 0 .../peg/action/LambdaVsInlineActionTest.java | 0 .../peg/action/RuleIdEmissionTest.java | 0 .../pragmatica/peg/analyzer/AnalyzerTest.java | 0 .../peg/error/DiagnosticTagTest.java | 0 .../peg/error/RuleRecoveryTest.java | 0 .../peg/error/SemanticExpectedTest.java | 0 .../pragmatica/peg/error/SuggestionTest.java | 0 .../peg/examples/CalculatorExample.java | 0 .../peg/examples/CsvParserExample.java | 0 .../examples/CutOperatorRegressionTest.java | 0 .../peg/examples/ErrorRecoveryExample.java | 0 .../peg/examples/Java25GrammarExample.java | 0 .../peg/examples/Java25ParserTest.java | 0 .../peg/examples/JsonParserExample.java | 0 .../peg/examples/SExpressionExample.java | 0 .../peg/examples/SourceGenerationExample.java | 0 .../generator/ChoiceDispatchAnalyzerTest.java | 0 .../GeneratedParserDiagnosticsTest.java | 0 .../generator/GeneratorFlagInertnessTest.java | 0 .../peg/generator/ParserGeneratorTest.java | 0 .../peg/grammar/GrammarCompositionTest.java | 0 .../peg/grammar/GrammarParserTest.java | 0 .../peg/grammar/LeftRecursionTest.java | 0 .../peg/parser/ParseResultTest.java | 0 .../peg/parser/ParsingContextTest.java | 0 .../peg/perf/BaselineGenerator.java | 0 .../peg/perf/BaselineGeneratorRunner.java | 0 .../pragmatica/peg/perf/CorpusParityTest.java | 0 .../java/org/pragmatica/peg/perf/CstHash.java | 0 .../pragmatica/peg/perf/CstReconstruct.java | 0 .../peg/perf/GeneratedJava25Parser.java | 0 .../perf/InterpreterBaselineGenerator.java | 0 .../peg/perf/Phase1InterpreterParityTest.java | 0 .../pragmatica/peg/perf/Phase1ParityTest.java | 0 .../perf/Phase2AllStructuralParityTest.java | 0 ...2ChoiceDispatchAndMarkResetParityTest.java | 0 .../perf/Phase2ChoiceDispatchParityTest.java | 0 .../perf/Phase2InlineLocationsParityTest.java | 0 .../Phase2MarkResetChildrenParityTest.java | 0 ...se2SelectivePackratEmptySetParityTest.java | 0 .../Phase2SelectivePackratParityTest.java | 0 .../pragmatica/peg/perf/RoundTripTest.java | 0 .../src}/test/resources/ParseError.java | 0 .../src}/test/resources/java25.peg | 0 .../BlankLineRules.java.hash | 0 .../BlankLineRules.java.ruleHits.txt | 0 .../format-examples/Annotations.java.hash | 0 .../Annotations.java.ruleHits.txt | 0 .../format-examples/BlankLines.java.hash | 0 .../BlankLines.java.ruleHits.txt | 0 .../format-examples/ChainAlignment.java.hash | 0 .../ChainAlignment.java.ruleHits.txt | 0 .../format-examples/ClassLiterals.java.hash | 0 .../ClassLiterals.java.ruleHits.txt | 0 .../format-examples/Comments.java.hash | 0 .../Comments.java.ruleHits.txt | 0 .../CompoundAssignments.java.hash | 0 .../CompoundAssignments.java.ruleHits.txt | 0 .../format-examples/DeepGenerics.java.hash | 0 .../DeepGenerics.java.ruleHits.txt | 0 .../format-examples/Enums.java.hash | 0 .../format-examples/Enums.java.ruleHits.txt | 0 .../ExhaustiveSwitchPatterns.java.hash | 0 ...ExhaustiveSwitchPatterns.java.ruleHits.txt | 0 .../format-examples/Imports.java.hash | 0 .../format-examples/Imports.java.ruleHits.txt | 0 .../KeywordPrefixedIdentifiers.java.hash | 0 ...ywordPrefixedIdentifiers.java.ruleHits.txt | 0 .../format-examples/Lambdas.java.hash | 0 .../format-examples/Lambdas.java.ruleHits.txt | 0 .../format-examples/LineWrapping.java.hash | 0 .../LineWrapping.java.ruleHits.txt | 0 .../format-examples/ModuleInfo.java.hash | 0 .../ModuleInfo.java.ruleHits.txt | 0 .../MultilineArguments.java.hash | 0 .../MultilineArguments.java.ruleHits.txt | 0 .../MultilineParameters.java.hash | 0 .../MultilineParameters.java.ruleHits.txt | 0 .../format-examples/Records.java.hash | 0 .../format-examples/Records.java.ruleHits.txt | 0 .../SwitchExpressions.java.hash | 0 .../SwitchExpressions.java.ruleHits.txt | 0 .../TernaryOperators.java.hash | 0 .../TernaryOperators.java.ruleHits.txt | 0 .../format-examples/TextBlocks.java.hash | 0 .../TextBlocks.java.ruleHits.txt | 0 .../large/FactoryClassGenerator.java.txt.hash | 0 ...actoryClassGenerator.java.txt.ruleHits.txt | 0 .../perf-corpus-baseline/ruleCoverage.txt | 0 .../BlankLineRules.java.hash | 0 .../format-examples/Annotations.java.hash | 0 .../format-examples/BlankLines.java.hash | 0 .../format-examples/ChainAlignment.java.hash | 0 .../format-examples/ClassLiterals.java.hash | 0 .../format-examples/Comments.java.hash | 0 .../CompoundAssignments.java.hash | 0 .../format-examples/DeepGenerics.java.hash | 0 .../format-examples/Enums.java.hash | 0 .../ExhaustiveSwitchPatterns.java.hash | 0 .../format-examples/Imports.java.hash | 0 .../KeywordPrefixedIdentifiers.java.hash | 0 .../format-examples/Lambdas.java.hash | 0 .../format-examples/LineWrapping.java.hash | 0 .../format-examples/ModuleInfo.java.hash | 0 .../MultilineArguments.java.hash | 0 .../MultilineParameters.java.hash | 0 .../format-examples/Records.java.hash | 0 .../SwitchExpressions.java.hash | 0 .../TernaryOperators.java.hash | 0 .../format-examples/TextBlocks.java.hash | 0 .../large/FactoryClassGenerator.java.txt.hash | 0 .../flow-format-examples/BlankLineRules.java | 0 .../format-examples/Annotations.java | 0 .../format-examples/BlankLines.java | 0 .../format-examples/ChainAlignment.java | 0 .../format-examples/ClassLiterals.java | 0 .../perf-corpus/format-examples/Comments.java | 0 .../format-examples/CompoundAssignments.java | 0 .../format-examples/DeepGenerics.java | 0 .../perf-corpus/format-examples/Enums.java | 0 .../ExhaustiveSwitchPatterns.java | 0 .../perf-corpus/format-examples/Imports.java | 0 .../KeywordPrefixedIdentifiers.java | 0 .../perf-corpus/format-examples/Lambdas.java | 0 .../format-examples/LineWrapping.java | 0 .../format-examples/ModuleInfo.java | 0 .../format-examples/MultilineArguments.java | 0 .../format-examples/MultilineParameters.java | 0 .../perf-corpus/format-examples/Records.java | 0 .../format-examples/SwitchExpressions.java | 0 .../format-examples/TernaryOperators.java | 0 .../format-examples/TextBlocks.java | 0 .../large/FactoryClassGenerator.java.txt | 0 .../src}/test/resources/test-grammars/Lib.peg | 0 .../test-java-files/OptionMetrics.java | 0 .../test-java-files/PromiseTest.java | 0 .../test-java-files/ResultMetrics.java | 0 .../resources/test-java-files/TypeToken.java | 0 peglib-formatter/pom.xml | 51 ++++ .../peg/formatter/package-info.java | 5 + peglib-incremental/pom.xml | 51 ++++ .../peg/incremental/package-info.java | 5 + peglib-maven-plugin/pom.xml | 33 +-- peglib-playground/pom.xml | 36 +-- pom.xml | 231 +++++------------- 197 files changed, 375 insertions(+), 220 deletions(-) create mode 100644 peglib-core/pom.xml rename {src => peglib-core/src}/jmh/java/org/pragmatica/peg/bench/Java25ParseBenchmark.java (100%) rename {src => peglib-core/src}/jmh/java/org/pragmatica/peg/bench/PackratStatsProbe.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/PegParser.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/action/Action.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/action/ActionCompiler.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/action/Actions.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/action/RuleId.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/action/SemanticValues.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/analyzer/Analyzer.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/analyzer/AnalyzerMain.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/analyzer/AnalyzerReport.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/analyzer/Finding.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/error/Diagnostic.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/error/ParseError.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/error/RecoveryStrategy.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzer.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/generator/ErrorReporting.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/generator/ParserGenerator.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/Expression.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/Grammar.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/GrammarLexer.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/GrammarParser.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/GrammarResolver.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/GrammarSource.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/GrammarToken.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/Import.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/Rule.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/analysis/ExpressionShape.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/analysis/FirstCharAnalysis.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/grammar/analysis/LeftRecursionAnalysis.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/parser/ParseMode.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/parser/ParseResult.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/parser/ParseResultWithDiagnostics.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/parser/Parser.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/parser/ParserConfig.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/parser/ParsingContext.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/parser/PegEngine.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/tree/AstNode.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/tree/CstNode.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/tree/SourceLocation.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/tree/SourceSpan.java (100%) rename {src => peglib-core/src}/main/java/org/pragmatica/peg/tree/Trivia.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/EdgeCaseTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/ErrorRecoveryTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/GeneratedParserTriviaTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/GeneratorConformanceTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/NegativeLookaheadBugTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/PegParserTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/TriviaTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/action/ActionsImmutabilityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/action/LambdaActionTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/action/LambdaVsInlineActionTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/action/RuleIdEmissionTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/analyzer/AnalyzerTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/error/DiagnosticTagTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/error/RuleRecoveryTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/error/SemanticExpectedTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/error/SuggestionTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/CalculatorExample.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/CsvParserExample.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/CutOperatorRegressionTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/ErrorRecoveryExample.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/Java25GrammarExample.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/Java25ParserTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/JsonParserExample.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/SExpressionExample.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/examples/SourceGenerationExample.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzerTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/generator/GeneratedParserDiagnosticsTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/generator/GeneratorFlagInertnessTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/generator/ParserGeneratorTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/grammar/GrammarCompositionTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/grammar/GrammarParserTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/grammar/LeftRecursionTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/parser/ParseResultTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/parser/ParsingContextTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/BaselineGenerator.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/BaselineGeneratorRunner.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/CorpusParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/CstHash.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/CstReconstruct.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/GeneratedJava25Parser.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/InterpreterBaselineGenerator.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase1InterpreterParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase1ParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase2AllStructuralParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchAndMarkResetParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase2InlineLocationsParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase2MarkResetChildrenParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratEmptySetParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratParityTest.java (100%) rename {src => peglib-core/src}/test/java/org/pragmatica/peg/perf/RoundTripTest.java (100%) rename {src => peglib-core/src}/test/resources/ParseError.java (100%) rename {src => peglib-core/src}/test/resources/java25.peg (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Annotations.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Annotations.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Comments.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Comments.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Enums.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Enums.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Imports.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Imports.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Records.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/Records.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.ruleHits.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-baseline/ruleCoverage.txt (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/flow-format-examples/BlankLineRules.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/Annotations.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/BlankLines.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/ChainAlignment.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/ClassLiterals.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/Comments.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/CompoundAssignments.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/DeepGenerics.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/Enums.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/Imports.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/Lambdas.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/LineWrapping.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/ModuleInfo.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineArguments.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineParameters.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/Records.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/SwitchExpressions.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/TernaryOperators.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/format-examples/TextBlocks.java.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus-interpreter-baseline/large/FactoryClassGenerator.java.txt.hash (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/flow-format-examples/BlankLineRules.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/Annotations.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/BlankLines.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/ChainAlignment.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/ClassLiterals.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/Comments.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/CompoundAssignments.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/DeepGenerics.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/Enums.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/ExhaustiveSwitchPatterns.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/Imports.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/KeywordPrefixedIdentifiers.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/Lambdas.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/LineWrapping.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/ModuleInfo.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/MultilineArguments.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/MultilineParameters.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/Records.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/SwitchExpressions.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/TernaryOperators.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/format-examples/TextBlocks.java (100%) rename {src => peglib-core/src}/test/resources/perf-corpus/large/FactoryClassGenerator.java.txt (100%) rename {src => peglib-core/src}/test/resources/test-grammars/Lib.peg (100%) rename {src => peglib-core/src}/test/resources/test-java-files/OptionMetrics.java (100%) rename {src => peglib-core/src}/test/resources/test-java-files/PromiseTest.java (100%) rename {src => peglib-core/src}/test/resources/test-java-files/ResultMetrics.java (100%) rename {src => peglib-core/src}/test/resources/test-java-files/TypeToken.java (100%) create mode 100644 peglib-formatter/pom.xml create mode 100644 peglib-formatter/src/main/java/org/pragmatica/peg/formatter/package-info.java create mode 100644 peglib-incremental/pom.xml create mode 100644 peglib-incremental/src/main/java/org/pragmatica/peg/incremental/package-info.java diff --git a/peglib-core/pom.xml b/peglib-core/pom.xml new file mode 100644 index 0000000..c74aca7 --- /dev/null +++ b/peglib-core/pom.xml @@ -0,0 +1,183 @@ + + + 4.0.0 + + + org.pragmatica-lite + peglib-parent + 0.3.0 + ../pom.xml + + + peglib + jar + + Peglib + PEG parser library for Java with CST/AST support, inspired by cpp-peglib + https://github.com/siy/java-peglib + + + + + org.pragmatica-lite + core + + + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*Test.java + **/*Example.java + + + + + org.pragmatica-lite + jbct-maven-plugin + 0.4.1 + + + check + + check + + + + + + + + + + bench + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + add-jmh-sources + generate-sources + + add-source + + + + src/jmh/java + + + + + add-jmh-resources + generate-resources + + add-resource + + + + + src/test/resources + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.openjdk.jmh + jmh-generator-annprocess + 1.37 + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.5.0 + + org.openjdk.jmh.Main + compile + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.3 + + + benchmarks-uberjar + package + + shade + + + benchmarks + + + org.openjdk.jmh.Main + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + + org.openjdk.jmh + jmh-core + 1.37 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.37 + provided + + + + + diff --git a/src/jmh/java/org/pragmatica/peg/bench/Java25ParseBenchmark.java b/peglib-core/src/jmh/java/org/pragmatica/peg/bench/Java25ParseBenchmark.java similarity index 100% rename from src/jmh/java/org/pragmatica/peg/bench/Java25ParseBenchmark.java rename to peglib-core/src/jmh/java/org/pragmatica/peg/bench/Java25ParseBenchmark.java diff --git a/src/jmh/java/org/pragmatica/peg/bench/PackratStatsProbe.java b/peglib-core/src/jmh/java/org/pragmatica/peg/bench/PackratStatsProbe.java similarity index 100% rename from src/jmh/java/org/pragmatica/peg/bench/PackratStatsProbe.java rename to peglib-core/src/jmh/java/org/pragmatica/peg/bench/PackratStatsProbe.java diff --git a/src/main/java/org/pragmatica/peg/PegParser.java b/peglib-core/src/main/java/org/pragmatica/peg/PegParser.java similarity index 100% rename from src/main/java/org/pragmatica/peg/PegParser.java rename to peglib-core/src/main/java/org/pragmatica/peg/PegParser.java diff --git a/src/main/java/org/pragmatica/peg/action/Action.java b/peglib-core/src/main/java/org/pragmatica/peg/action/Action.java similarity index 100% rename from src/main/java/org/pragmatica/peg/action/Action.java rename to peglib-core/src/main/java/org/pragmatica/peg/action/Action.java diff --git a/src/main/java/org/pragmatica/peg/action/ActionCompiler.java b/peglib-core/src/main/java/org/pragmatica/peg/action/ActionCompiler.java similarity index 100% rename from src/main/java/org/pragmatica/peg/action/ActionCompiler.java rename to peglib-core/src/main/java/org/pragmatica/peg/action/ActionCompiler.java diff --git a/src/main/java/org/pragmatica/peg/action/Actions.java b/peglib-core/src/main/java/org/pragmatica/peg/action/Actions.java similarity index 100% rename from src/main/java/org/pragmatica/peg/action/Actions.java rename to peglib-core/src/main/java/org/pragmatica/peg/action/Actions.java diff --git a/src/main/java/org/pragmatica/peg/action/RuleId.java b/peglib-core/src/main/java/org/pragmatica/peg/action/RuleId.java similarity index 100% rename from src/main/java/org/pragmatica/peg/action/RuleId.java rename to peglib-core/src/main/java/org/pragmatica/peg/action/RuleId.java diff --git a/src/main/java/org/pragmatica/peg/action/SemanticValues.java b/peglib-core/src/main/java/org/pragmatica/peg/action/SemanticValues.java similarity index 100% rename from src/main/java/org/pragmatica/peg/action/SemanticValues.java rename to peglib-core/src/main/java/org/pragmatica/peg/action/SemanticValues.java diff --git a/src/main/java/org/pragmatica/peg/analyzer/Analyzer.java b/peglib-core/src/main/java/org/pragmatica/peg/analyzer/Analyzer.java similarity index 100% rename from src/main/java/org/pragmatica/peg/analyzer/Analyzer.java rename to peglib-core/src/main/java/org/pragmatica/peg/analyzer/Analyzer.java diff --git a/src/main/java/org/pragmatica/peg/analyzer/AnalyzerMain.java b/peglib-core/src/main/java/org/pragmatica/peg/analyzer/AnalyzerMain.java similarity index 100% rename from src/main/java/org/pragmatica/peg/analyzer/AnalyzerMain.java rename to peglib-core/src/main/java/org/pragmatica/peg/analyzer/AnalyzerMain.java diff --git a/src/main/java/org/pragmatica/peg/analyzer/AnalyzerReport.java b/peglib-core/src/main/java/org/pragmatica/peg/analyzer/AnalyzerReport.java similarity index 100% rename from src/main/java/org/pragmatica/peg/analyzer/AnalyzerReport.java rename to peglib-core/src/main/java/org/pragmatica/peg/analyzer/AnalyzerReport.java diff --git a/src/main/java/org/pragmatica/peg/analyzer/Finding.java b/peglib-core/src/main/java/org/pragmatica/peg/analyzer/Finding.java similarity index 100% rename from src/main/java/org/pragmatica/peg/analyzer/Finding.java rename to peglib-core/src/main/java/org/pragmatica/peg/analyzer/Finding.java diff --git a/src/main/java/org/pragmatica/peg/error/Diagnostic.java b/peglib-core/src/main/java/org/pragmatica/peg/error/Diagnostic.java similarity index 100% rename from src/main/java/org/pragmatica/peg/error/Diagnostic.java rename to peglib-core/src/main/java/org/pragmatica/peg/error/Diagnostic.java diff --git a/src/main/java/org/pragmatica/peg/error/ParseError.java b/peglib-core/src/main/java/org/pragmatica/peg/error/ParseError.java similarity index 100% rename from src/main/java/org/pragmatica/peg/error/ParseError.java rename to peglib-core/src/main/java/org/pragmatica/peg/error/ParseError.java diff --git a/src/main/java/org/pragmatica/peg/error/RecoveryStrategy.java b/peglib-core/src/main/java/org/pragmatica/peg/error/RecoveryStrategy.java similarity index 100% rename from src/main/java/org/pragmatica/peg/error/RecoveryStrategy.java rename to peglib-core/src/main/java/org/pragmatica/peg/error/RecoveryStrategy.java diff --git a/src/main/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzer.java b/peglib-core/src/main/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzer.java similarity index 100% rename from src/main/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzer.java rename to peglib-core/src/main/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzer.java diff --git a/src/main/java/org/pragmatica/peg/generator/ErrorReporting.java b/peglib-core/src/main/java/org/pragmatica/peg/generator/ErrorReporting.java similarity index 100% rename from src/main/java/org/pragmatica/peg/generator/ErrorReporting.java rename to peglib-core/src/main/java/org/pragmatica/peg/generator/ErrorReporting.java diff --git a/src/main/java/org/pragmatica/peg/generator/ParserGenerator.java b/peglib-core/src/main/java/org/pragmatica/peg/generator/ParserGenerator.java similarity index 100% rename from src/main/java/org/pragmatica/peg/generator/ParserGenerator.java rename to peglib-core/src/main/java/org/pragmatica/peg/generator/ParserGenerator.java diff --git a/src/main/java/org/pragmatica/peg/grammar/Expression.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/Expression.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/Expression.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/Expression.java diff --git a/src/main/java/org/pragmatica/peg/grammar/Grammar.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/Grammar.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/Grammar.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/Grammar.java diff --git a/src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarLexer.java diff --git a/src/main/java/org/pragmatica/peg/grammar/GrammarParser.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarParser.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/GrammarParser.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarParser.java diff --git a/src/main/java/org/pragmatica/peg/grammar/GrammarResolver.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarResolver.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/GrammarResolver.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarResolver.java diff --git a/src/main/java/org/pragmatica/peg/grammar/GrammarSource.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarSource.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/GrammarSource.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarSource.java diff --git a/src/main/java/org/pragmatica/peg/grammar/GrammarToken.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarToken.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/GrammarToken.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/GrammarToken.java diff --git a/src/main/java/org/pragmatica/peg/grammar/Import.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/Import.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/Import.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/Import.java diff --git a/src/main/java/org/pragmatica/peg/grammar/Rule.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/Rule.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/Rule.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/Rule.java diff --git a/src/main/java/org/pragmatica/peg/grammar/analysis/ExpressionShape.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/analysis/ExpressionShape.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/analysis/ExpressionShape.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/analysis/ExpressionShape.java diff --git a/src/main/java/org/pragmatica/peg/grammar/analysis/FirstCharAnalysis.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/analysis/FirstCharAnalysis.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/analysis/FirstCharAnalysis.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/analysis/FirstCharAnalysis.java diff --git a/src/main/java/org/pragmatica/peg/grammar/analysis/LeftRecursionAnalysis.java b/peglib-core/src/main/java/org/pragmatica/peg/grammar/analysis/LeftRecursionAnalysis.java similarity index 100% rename from src/main/java/org/pragmatica/peg/grammar/analysis/LeftRecursionAnalysis.java rename to peglib-core/src/main/java/org/pragmatica/peg/grammar/analysis/LeftRecursionAnalysis.java diff --git a/src/main/java/org/pragmatica/peg/parser/ParseMode.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/ParseMode.java similarity index 100% rename from src/main/java/org/pragmatica/peg/parser/ParseMode.java rename to peglib-core/src/main/java/org/pragmatica/peg/parser/ParseMode.java diff --git a/src/main/java/org/pragmatica/peg/parser/ParseResult.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/ParseResult.java similarity index 100% rename from src/main/java/org/pragmatica/peg/parser/ParseResult.java rename to peglib-core/src/main/java/org/pragmatica/peg/parser/ParseResult.java diff --git a/src/main/java/org/pragmatica/peg/parser/ParseResultWithDiagnostics.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/ParseResultWithDiagnostics.java similarity index 100% rename from src/main/java/org/pragmatica/peg/parser/ParseResultWithDiagnostics.java rename to peglib-core/src/main/java/org/pragmatica/peg/parser/ParseResultWithDiagnostics.java diff --git a/src/main/java/org/pragmatica/peg/parser/Parser.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java similarity index 100% rename from src/main/java/org/pragmatica/peg/parser/Parser.java rename to peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java diff --git a/src/main/java/org/pragmatica/peg/parser/ParserConfig.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/ParserConfig.java similarity index 100% rename from src/main/java/org/pragmatica/peg/parser/ParserConfig.java rename to peglib-core/src/main/java/org/pragmatica/peg/parser/ParserConfig.java diff --git a/src/main/java/org/pragmatica/peg/parser/ParsingContext.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/ParsingContext.java similarity index 100% rename from src/main/java/org/pragmatica/peg/parser/ParsingContext.java rename to peglib-core/src/main/java/org/pragmatica/peg/parser/ParsingContext.java diff --git a/src/main/java/org/pragmatica/peg/parser/PegEngine.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java similarity index 100% rename from src/main/java/org/pragmatica/peg/parser/PegEngine.java rename to peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java diff --git a/src/main/java/org/pragmatica/peg/tree/AstNode.java b/peglib-core/src/main/java/org/pragmatica/peg/tree/AstNode.java similarity index 100% rename from src/main/java/org/pragmatica/peg/tree/AstNode.java rename to peglib-core/src/main/java/org/pragmatica/peg/tree/AstNode.java diff --git a/src/main/java/org/pragmatica/peg/tree/CstNode.java b/peglib-core/src/main/java/org/pragmatica/peg/tree/CstNode.java similarity index 100% rename from src/main/java/org/pragmatica/peg/tree/CstNode.java rename to peglib-core/src/main/java/org/pragmatica/peg/tree/CstNode.java diff --git a/src/main/java/org/pragmatica/peg/tree/SourceLocation.java b/peglib-core/src/main/java/org/pragmatica/peg/tree/SourceLocation.java similarity index 100% rename from src/main/java/org/pragmatica/peg/tree/SourceLocation.java rename to peglib-core/src/main/java/org/pragmatica/peg/tree/SourceLocation.java diff --git a/src/main/java/org/pragmatica/peg/tree/SourceSpan.java b/peglib-core/src/main/java/org/pragmatica/peg/tree/SourceSpan.java similarity index 100% rename from src/main/java/org/pragmatica/peg/tree/SourceSpan.java rename to peglib-core/src/main/java/org/pragmatica/peg/tree/SourceSpan.java diff --git a/src/main/java/org/pragmatica/peg/tree/Trivia.java b/peglib-core/src/main/java/org/pragmatica/peg/tree/Trivia.java similarity index 100% rename from src/main/java/org/pragmatica/peg/tree/Trivia.java rename to peglib-core/src/main/java/org/pragmatica/peg/tree/Trivia.java diff --git a/src/test/java/org/pragmatica/peg/EdgeCaseTest.java b/peglib-core/src/test/java/org/pragmatica/peg/EdgeCaseTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/EdgeCaseTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/EdgeCaseTest.java diff --git a/src/test/java/org/pragmatica/peg/ErrorRecoveryTest.java b/peglib-core/src/test/java/org/pragmatica/peg/ErrorRecoveryTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/ErrorRecoveryTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/ErrorRecoveryTest.java diff --git a/src/test/java/org/pragmatica/peg/GeneratedParserTriviaTest.java b/peglib-core/src/test/java/org/pragmatica/peg/GeneratedParserTriviaTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/GeneratedParserTriviaTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/GeneratedParserTriviaTest.java diff --git a/src/test/java/org/pragmatica/peg/GeneratorConformanceTest.java b/peglib-core/src/test/java/org/pragmatica/peg/GeneratorConformanceTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/GeneratorConformanceTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/GeneratorConformanceTest.java diff --git a/src/test/java/org/pragmatica/peg/NegativeLookaheadBugTest.java b/peglib-core/src/test/java/org/pragmatica/peg/NegativeLookaheadBugTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/NegativeLookaheadBugTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/NegativeLookaheadBugTest.java diff --git a/src/test/java/org/pragmatica/peg/PegParserTest.java b/peglib-core/src/test/java/org/pragmatica/peg/PegParserTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/PegParserTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/PegParserTest.java diff --git a/src/test/java/org/pragmatica/peg/TriviaTest.java b/peglib-core/src/test/java/org/pragmatica/peg/TriviaTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/TriviaTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/TriviaTest.java diff --git a/src/test/java/org/pragmatica/peg/action/ActionsImmutabilityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/action/ActionsImmutabilityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/action/ActionsImmutabilityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/action/ActionsImmutabilityTest.java diff --git a/src/test/java/org/pragmatica/peg/action/LambdaActionTest.java b/peglib-core/src/test/java/org/pragmatica/peg/action/LambdaActionTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/action/LambdaActionTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/action/LambdaActionTest.java diff --git a/src/test/java/org/pragmatica/peg/action/LambdaVsInlineActionTest.java b/peglib-core/src/test/java/org/pragmatica/peg/action/LambdaVsInlineActionTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/action/LambdaVsInlineActionTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/action/LambdaVsInlineActionTest.java diff --git a/src/test/java/org/pragmatica/peg/action/RuleIdEmissionTest.java b/peglib-core/src/test/java/org/pragmatica/peg/action/RuleIdEmissionTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/action/RuleIdEmissionTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/action/RuleIdEmissionTest.java diff --git a/src/test/java/org/pragmatica/peg/analyzer/AnalyzerTest.java b/peglib-core/src/test/java/org/pragmatica/peg/analyzer/AnalyzerTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/analyzer/AnalyzerTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/analyzer/AnalyzerTest.java diff --git a/src/test/java/org/pragmatica/peg/error/DiagnosticTagTest.java b/peglib-core/src/test/java/org/pragmatica/peg/error/DiagnosticTagTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/error/DiagnosticTagTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/error/DiagnosticTagTest.java diff --git a/src/test/java/org/pragmatica/peg/error/RuleRecoveryTest.java b/peglib-core/src/test/java/org/pragmatica/peg/error/RuleRecoveryTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/error/RuleRecoveryTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/error/RuleRecoveryTest.java diff --git a/src/test/java/org/pragmatica/peg/error/SemanticExpectedTest.java b/peglib-core/src/test/java/org/pragmatica/peg/error/SemanticExpectedTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/error/SemanticExpectedTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/error/SemanticExpectedTest.java diff --git a/src/test/java/org/pragmatica/peg/error/SuggestionTest.java b/peglib-core/src/test/java/org/pragmatica/peg/error/SuggestionTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/error/SuggestionTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/error/SuggestionTest.java diff --git a/src/test/java/org/pragmatica/peg/examples/CalculatorExample.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/CalculatorExample.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/CalculatorExample.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/CalculatorExample.java diff --git a/src/test/java/org/pragmatica/peg/examples/CsvParserExample.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/CsvParserExample.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/CsvParserExample.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/CsvParserExample.java diff --git a/src/test/java/org/pragmatica/peg/examples/CutOperatorRegressionTest.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/CutOperatorRegressionTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/CutOperatorRegressionTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/CutOperatorRegressionTest.java diff --git a/src/test/java/org/pragmatica/peg/examples/ErrorRecoveryExample.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/ErrorRecoveryExample.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/ErrorRecoveryExample.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/ErrorRecoveryExample.java diff --git a/src/test/java/org/pragmatica/peg/examples/Java25GrammarExample.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/Java25GrammarExample.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/Java25GrammarExample.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/Java25GrammarExample.java diff --git a/src/test/java/org/pragmatica/peg/examples/Java25ParserTest.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/Java25ParserTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/Java25ParserTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/Java25ParserTest.java diff --git a/src/test/java/org/pragmatica/peg/examples/JsonParserExample.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/JsonParserExample.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/JsonParserExample.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/JsonParserExample.java diff --git a/src/test/java/org/pragmatica/peg/examples/SExpressionExample.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/SExpressionExample.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/SExpressionExample.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/SExpressionExample.java diff --git a/src/test/java/org/pragmatica/peg/examples/SourceGenerationExample.java b/peglib-core/src/test/java/org/pragmatica/peg/examples/SourceGenerationExample.java similarity index 100% rename from src/test/java/org/pragmatica/peg/examples/SourceGenerationExample.java rename to peglib-core/src/test/java/org/pragmatica/peg/examples/SourceGenerationExample.java diff --git a/src/test/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzerTest.java b/peglib-core/src/test/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzerTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzerTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/generator/ChoiceDispatchAnalyzerTest.java diff --git a/src/test/java/org/pragmatica/peg/generator/GeneratedParserDiagnosticsTest.java b/peglib-core/src/test/java/org/pragmatica/peg/generator/GeneratedParserDiagnosticsTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/generator/GeneratedParserDiagnosticsTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/generator/GeneratedParserDiagnosticsTest.java diff --git a/src/test/java/org/pragmatica/peg/generator/GeneratorFlagInertnessTest.java b/peglib-core/src/test/java/org/pragmatica/peg/generator/GeneratorFlagInertnessTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/generator/GeneratorFlagInertnessTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/generator/GeneratorFlagInertnessTest.java diff --git a/src/test/java/org/pragmatica/peg/generator/ParserGeneratorTest.java b/peglib-core/src/test/java/org/pragmatica/peg/generator/ParserGeneratorTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/generator/ParserGeneratorTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/generator/ParserGeneratorTest.java diff --git a/src/test/java/org/pragmatica/peg/grammar/GrammarCompositionTest.java b/peglib-core/src/test/java/org/pragmatica/peg/grammar/GrammarCompositionTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/grammar/GrammarCompositionTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/grammar/GrammarCompositionTest.java diff --git a/src/test/java/org/pragmatica/peg/grammar/GrammarParserTest.java b/peglib-core/src/test/java/org/pragmatica/peg/grammar/GrammarParserTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/grammar/GrammarParserTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/grammar/GrammarParserTest.java diff --git a/src/test/java/org/pragmatica/peg/grammar/LeftRecursionTest.java b/peglib-core/src/test/java/org/pragmatica/peg/grammar/LeftRecursionTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/grammar/LeftRecursionTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/grammar/LeftRecursionTest.java diff --git a/src/test/java/org/pragmatica/peg/parser/ParseResultTest.java b/peglib-core/src/test/java/org/pragmatica/peg/parser/ParseResultTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/parser/ParseResultTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/parser/ParseResultTest.java diff --git a/src/test/java/org/pragmatica/peg/parser/ParsingContextTest.java b/peglib-core/src/test/java/org/pragmatica/peg/parser/ParsingContextTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/parser/ParsingContextTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/parser/ParsingContextTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/BaselineGenerator.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/BaselineGenerator.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/BaselineGenerator.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/BaselineGenerator.java diff --git a/src/test/java/org/pragmatica/peg/perf/BaselineGeneratorRunner.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/BaselineGeneratorRunner.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/BaselineGeneratorRunner.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/BaselineGeneratorRunner.java diff --git a/src/test/java/org/pragmatica/peg/perf/CorpusParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/CorpusParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/CorpusParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/CorpusParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/CstHash.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/CstHash.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/CstHash.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/CstHash.java diff --git a/src/test/java/org/pragmatica/peg/perf/CstReconstruct.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/CstReconstruct.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/CstReconstruct.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/CstReconstruct.java diff --git a/src/test/java/org/pragmatica/peg/perf/GeneratedJava25Parser.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/GeneratedJava25Parser.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/GeneratedJava25Parser.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/GeneratedJava25Parser.java diff --git a/src/test/java/org/pragmatica/peg/perf/InterpreterBaselineGenerator.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/InterpreterBaselineGenerator.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/InterpreterBaselineGenerator.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/InterpreterBaselineGenerator.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase1InterpreterParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase1InterpreterParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase1InterpreterParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase1InterpreterParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase1ParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase1ParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase1ParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase1ParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase2AllStructuralParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2AllStructuralParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase2AllStructuralParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2AllStructuralParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchAndMarkResetParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchAndMarkResetParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchAndMarkResetParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchAndMarkResetParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2ChoiceDispatchParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase2InlineLocationsParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2InlineLocationsParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase2InlineLocationsParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2InlineLocationsParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase2MarkResetChildrenParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2MarkResetChildrenParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase2MarkResetChildrenParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2MarkResetChildrenParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratEmptySetParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratEmptySetParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratEmptySetParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratEmptySetParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratParityTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratParityTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratParityTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/Phase2SelectivePackratParityTest.java diff --git a/src/test/java/org/pragmatica/peg/perf/RoundTripTest.java b/peglib-core/src/test/java/org/pragmatica/peg/perf/RoundTripTest.java similarity index 100% rename from src/test/java/org/pragmatica/peg/perf/RoundTripTest.java rename to peglib-core/src/test/java/org/pragmatica/peg/perf/RoundTripTest.java diff --git a/src/test/resources/ParseError.java b/peglib-core/src/test/resources/ParseError.java similarity index 100% rename from src/test/resources/ParseError.java rename to peglib-core/src/test/resources/ParseError.java diff --git a/src/test/resources/java25.peg b/peglib-core/src/test/resources/java25.peg similarity index 100% rename from src/test/resources/java25.peg rename to peglib-core/src/test/resources/java25.peg diff --git a/src/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.hash diff --git a/src/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/flow-format-examples/BlankLineRules.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Annotations.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Annotations.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Annotations.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Annotations.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Annotations.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Annotations.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Annotations.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Annotations.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/BlankLines.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ChainAlignment.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ClassLiterals.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Comments.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Comments.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Comments.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Comments.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Comments.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Comments.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Comments.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Comments.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/CompoundAssignments.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/DeepGenerics.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Enums.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Enums.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Enums.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Enums.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Enums.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Enums.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Enums.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Enums.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ExhaustiveSwitchPatterns.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Imports.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Imports.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Imports.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Imports.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Imports.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Imports.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Imports.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Imports.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/KeywordPrefixedIdentifiers.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Lambdas.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/LineWrapping.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/ModuleInfo.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/MultilineArguments.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/MultilineParameters.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Records.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Records.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Records.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Records.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/Records.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Records.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/Records.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/Records.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/SwitchExpressions.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/TernaryOperators.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.hash b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.hash diff --git a/src/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/format-examples/TextBlocks.java.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.hash b/peglib-core/src/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.hash similarity index 100% rename from src/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.hash rename to peglib-core/src/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.hash diff --git a/src/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.ruleHits.txt b/peglib-core/src/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.ruleHits.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.ruleHits.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/large/FactoryClassGenerator.java.txt.ruleHits.txt diff --git a/src/test/resources/perf-corpus-baseline/ruleCoverage.txt b/peglib-core/src/test/resources/perf-corpus-baseline/ruleCoverage.txt similarity index 100% rename from src/test/resources/perf-corpus-baseline/ruleCoverage.txt rename to peglib-core/src/test/resources/perf-corpus-baseline/ruleCoverage.txt diff --git a/src/test/resources/perf-corpus-interpreter-baseline/flow-format-examples/BlankLineRules.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/flow-format-examples/BlankLineRules.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/flow-format-examples/BlankLineRules.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/flow-format-examples/BlankLineRules.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Annotations.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Annotations.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/Annotations.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Annotations.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/BlankLines.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/BlankLines.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/BlankLines.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/BlankLines.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ChainAlignment.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ChainAlignment.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/ChainAlignment.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ChainAlignment.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ClassLiterals.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ClassLiterals.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/ClassLiterals.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ClassLiterals.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Comments.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Comments.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/Comments.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Comments.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/CompoundAssignments.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/CompoundAssignments.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/CompoundAssignments.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/CompoundAssignments.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/DeepGenerics.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/DeepGenerics.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/DeepGenerics.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/DeepGenerics.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Enums.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Enums.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/Enums.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Enums.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ExhaustiveSwitchPatterns.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Imports.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Imports.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/Imports.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Imports.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/KeywordPrefixedIdentifiers.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Lambdas.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Lambdas.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/Lambdas.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Lambdas.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/LineWrapping.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/LineWrapping.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/LineWrapping.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/LineWrapping.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ModuleInfo.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ModuleInfo.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/ModuleInfo.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/ModuleInfo.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineArguments.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineArguments.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineArguments.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineArguments.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineParameters.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineParameters.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineParameters.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/MultilineParameters.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Records.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Records.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/Records.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/Records.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/SwitchExpressions.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/SwitchExpressions.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/SwitchExpressions.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/SwitchExpressions.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/TernaryOperators.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/TernaryOperators.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/TernaryOperators.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/TernaryOperators.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/format-examples/TextBlocks.java.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/TextBlocks.java.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/format-examples/TextBlocks.java.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/format-examples/TextBlocks.java.hash diff --git a/src/test/resources/perf-corpus-interpreter-baseline/large/FactoryClassGenerator.java.txt.hash b/peglib-core/src/test/resources/perf-corpus-interpreter-baseline/large/FactoryClassGenerator.java.txt.hash similarity index 100% rename from src/test/resources/perf-corpus-interpreter-baseline/large/FactoryClassGenerator.java.txt.hash rename to peglib-core/src/test/resources/perf-corpus-interpreter-baseline/large/FactoryClassGenerator.java.txt.hash diff --git a/src/test/resources/perf-corpus/flow-format-examples/BlankLineRules.java b/peglib-core/src/test/resources/perf-corpus/flow-format-examples/BlankLineRules.java similarity index 100% rename from src/test/resources/perf-corpus/flow-format-examples/BlankLineRules.java rename to peglib-core/src/test/resources/perf-corpus/flow-format-examples/BlankLineRules.java diff --git a/src/test/resources/perf-corpus/format-examples/Annotations.java b/peglib-core/src/test/resources/perf-corpus/format-examples/Annotations.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/Annotations.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/Annotations.java diff --git a/src/test/resources/perf-corpus/format-examples/BlankLines.java b/peglib-core/src/test/resources/perf-corpus/format-examples/BlankLines.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/BlankLines.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/BlankLines.java diff --git a/src/test/resources/perf-corpus/format-examples/ChainAlignment.java b/peglib-core/src/test/resources/perf-corpus/format-examples/ChainAlignment.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/ChainAlignment.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/ChainAlignment.java diff --git a/src/test/resources/perf-corpus/format-examples/ClassLiterals.java b/peglib-core/src/test/resources/perf-corpus/format-examples/ClassLiterals.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/ClassLiterals.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/ClassLiterals.java diff --git a/src/test/resources/perf-corpus/format-examples/Comments.java b/peglib-core/src/test/resources/perf-corpus/format-examples/Comments.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/Comments.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/Comments.java diff --git a/src/test/resources/perf-corpus/format-examples/CompoundAssignments.java b/peglib-core/src/test/resources/perf-corpus/format-examples/CompoundAssignments.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/CompoundAssignments.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/CompoundAssignments.java diff --git a/src/test/resources/perf-corpus/format-examples/DeepGenerics.java b/peglib-core/src/test/resources/perf-corpus/format-examples/DeepGenerics.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/DeepGenerics.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/DeepGenerics.java diff --git a/src/test/resources/perf-corpus/format-examples/Enums.java b/peglib-core/src/test/resources/perf-corpus/format-examples/Enums.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/Enums.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/Enums.java diff --git a/src/test/resources/perf-corpus/format-examples/ExhaustiveSwitchPatterns.java b/peglib-core/src/test/resources/perf-corpus/format-examples/ExhaustiveSwitchPatterns.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/ExhaustiveSwitchPatterns.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/ExhaustiveSwitchPatterns.java diff --git a/src/test/resources/perf-corpus/format-examples/Imports.java b/peglib-core/src/test/resources/perf-corpus/format-examples/Imports.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/Imports.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/Imports.java diff --git a/src/test/resources/perf-corpus/format-examples/KeywordPrefixedIdentifiers.java b/peglib-core/src/test/resources/perf-corpus/format-examples/KeywordPrefixedIdentifiers.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/KeywordPrefixedIdentifiers.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/KeywordPrefixedIdentifiers.java diff --git a/src/test/resources/perf-corpus/format-examples/Lambdas.java b/peglib-core/src/test/resources/perf-corpus/format-examples/Lambdas.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/Lambdas.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/Lambdas.java diff --git a/src/test/resources/perf-corpus/format-examples/LineWrapping.java b/peglib-core/src/test/resources/perf-corpus/format-examples/LineWrapping.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/LineWrapping.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/LineWrapping.java diff --git a/src/test/resources/perf-corpus/format-examples/ModuleInfo.java b/peglib-core/src/test/resources/perf-corpus/format-examples/ModuleInfo.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/ModuleInfo.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/ModuleInfo.java diff --git a/src/test/resources/perf-corpus/format-examples/MultilineArguments.java b/peglib-core/src/test/resources/perf-corpus/format-examples/MultilineArguments.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/MultilineArguments.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/MultilineArguments.java diff --git a/src/test/resources/perf-corpus/format-examples/MultilineParameters.java b/peglib-core/src/test/resources/perf-corpus/format-examples/MultilineParameters.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/MultilineParameters.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/MultilineParameters.java diff --git a/src/test/resources/perf-corpus/format-examples/Records.java b/peglib-core/src/test/resources/perf-corpus/format-examples/Records.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/Records.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/Records.java diff --git a/src/test/resources/perf-corpus/format-examples/SwitchExpressions.java b/peglib-core/src/test/resources/perf-corpus/format-examples/SwitchExpressions.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/SwitchExpressions.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/SwitchExpressions.java diff --git a/src/test/resources/perf-corpus/format-examples/TernaryOperators.java b/peglib-core/src/test/resources/perf-corpus/format-examples/TernaryOperators.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/TernaryOperators.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/TernaryOperators.java diff --git a/src/test/resources/perf-corpus/format-examples/TextBlocks.java b/peglib-core/src/test/resources/perf-corpus/format-examples/TextBlocks.java similarity index 100% rename from src/test/resources/perf-corpus/format-examples/TextBlocks.java rename to peglib-core/src/test/resources/perf-corpus/format-examples/TextBlocks.java diff --git a/src/test/resources/perf-corpus/large/FactoryClassGenerator.java.txt b/peglib-core/src/test/resources/perf-corpus/large/FactoryClassGenerator.java.txt similarity index 100% rename from src/test/resources/perf-corpus/large/FactoryClassGenerator.java.txt rename to peglib-core/src/test/resources/perf-corpus/large/FactoryClassGenerator.java.txt diff --git a/src/test/resources/test-grammars/Lib.peg b/peglib-core/src/test/resources/test-grammars/Lib.peg similarity index 100% rename from src/test/resources/test-grammars/Lib.peg rename to peglib-core/src/test/resources/test-grammars/Lib.peg diff --git a/src/test/resources/test-java-files/OptionMetrics.java b/peglib-core/src/test/resources/test-java-files/OptionMetrics.java similarity index 100% rename from src/test/resources/test-java-files/OptionMetrics.java rename to peglib-core/src/test/resources/test-java-files/OptionMetrics.java diff --git a/src/test/resources/test-java-files/PromiseTest.java b/peglib-core/src/test/resources/test-java-files/PromiseTest.java similarity index 100% rename from src/test/resources/test-java-files/PromiseTest.java rename to peglib-core/src/test/resources/test-java-files/PromiseTest.java diff --git a/src/test/resources/test-java-files/ResultMetrics.java b/peglib-core/src/test/resources/test-java-files/ResultMetrics.java similarity index 100% rename from src/test/resources/test-java-files/ResultMetrics.java rename to peglib-core/src/test/resources/test-java-files/ResultMetrics.java diff --git a/src/test/resources/test-java-files/TypeToken.java b/peglib-core/src/test/resources/test-java-files/TypeToken.java similarity index 100% rename from src/test/resources/test-java-files/TypeToken.java rename to peglib-core/src/test/resources/test-java-files/TypeToken.java diff --git a/peglib-formatter/pom.xml b/peglib-formatter/pom.xml new file mode 100644 index 0000000..6789126 --- /dev/null +++ b/peglib-formatter/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + + org.pragmatica-lite + peglib-parent + 0.3.0 + ../pom.xml + + + peglib-formatter + jar + + Peglib Formatter + Reserved for peglib-formatter v1 — Wadler-style pretty-printer framework for peglib CSTs. + https://github.com/siy/java-peglib + + + + org.pragmatica-lite + peglib + + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + diff --git a/peglib-formatter/src/main/java/org/pragmatica/peg/formatter/package-info.java b/peglib-formatter/src/main/java/org/pragmatica/peg/formatter/package-info.java new file mode 100644 index 0000000..6e91c3a --- /dev/null +++ b/peglib-formatter/src/main/java/org/pragmatica/peg/formatter/package-info.java @@ -0,0 +1,5 @@ +/** + * Reserved for peglib-formatter v1 — Wadler-style pretty-printer framework + * that consumes peglib CSTs. See the 0.3.3 roadmap entry for the full design. + */ +package org.pragmatica.peg.formatter; diff --git a/peglib-incremental/pom.xml b/peglib-incremental/pom.xml new file mode 100644 index 0000000..24f3668 --- /dev/null +++ b/peglib-incremental/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + + org.pragmatica-lite + peglib-parent + 0.3.0 + ../pom.xml + + + peglib-incremental + jar + + Peglib Incremental + Reserved for peglib-incremental v1 — cursor-anchored incremental CST reparsing. See docs/incremental/SPEC.md. + https://github.com/siy/java-peglib + + + + org.pragmatica-lite + peglib + + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + diff --git a/peglib-incremental/src/main/java/org/pragmatica/peg/incremental/package-info.java b/peglib-incremental/src/main/java/org/pragmatica/peg/incremental/package-info.java new file mode 100644 index 0000000..aa2d6d7 --- /dev/null +++ b/peglib-incremental/src/main/java/org/pragmatica/peg/incremental/package-info.java @@ -0,0 +1,5 @@ +/** + * Reserved for peglib-incremental v1 — cursor-anchored incremental CST reparsing. + * See {@code docs/incremental/SPEC.md} for the full design. + */ +package org.pragmatica.peg.incremental; diff --git a/peglib-maven-plugin/pom.xml b/peglib-maven-plugin/pom.xml index da8361c..465ed65 100644 --- a/peglib-maven-plugin/pom.xml +++ b/peglib-maven-plugin/pom.xml @@ -4,45 +4,30 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.pragmatica-lite + + org.pragmatica-lite + peglib-parent + 0.3.0 + ../pom.xml + + peglib-maven-plugin - 0.2.5 maven-plugin Peglib Maven Plugin Maven plugin for generating PEG parsers and linting grammars https://github.com/siy/java-peglib - - - MIT License - https://opensource.org/licenses/MIT - repo - - - - - - siy - Sergiy Yevtushenko - https://github.com/siy - - - - UTF-8 - 25 3.9.9 3.15.1 9.9 - 0.2.5 org.pragmatica-lite peglib - ${peglib.version} @@ -69,13 +54,11 @@ org.junit.jupiter junit-jupiter - 5.11.0 test org.assertj assertj-core - 3.26.0 test @@ -85,7 +68,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.14.0 org.apache.maven.plugins @@ -139,7 +121,6 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.0 diff --git a/peglib-playground/pom.xml b/peglib-playground/pom.xml index be043b3..161f2df 100644 --- a/peglib-playground/pom.xml +++ b/peglib-playground/pom.xml @@ -4,54 +4,34 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.pragmatica-lite + + org.pragmatica-lite + peglib-parent + 0.3.0 + ../pom.xml + + peglib-playground - 0.2.7 jar Peglib Playground Interactive grammar playground: CLI REPL and embedded web UI for peglib https://github.com/siy/java-peglib - - - MIT License - https://opensource.org/licenses/MIT - repo - - - - - - siy - Sergiy Yevtushenko - https://github.com/siy - - - - - UTF-8 - 25 - 0.2.7 - - org.pragmatica-lite peglib - ${peglib.version} org.junit.jupiter junit-jupiter - 5.11.0 test org.assertj assertj-core - 3.26.0 test @@ -61,12 +41,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.14.0 org.apache.maven.plugins maven-surefire-plugin - 3.5.0 org.apache.maven.plugins diff --git a/pom.xml b/pom.xml index 239e21b..7da6b09 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.pragmatica-lite - peglib + peglib-parent 0.3.0 - jar + pom - Peglib - PEG parser library for Java with CST/AST support, inspired by cpp-peglib + Peglib Parent + Multi-module parent POM for peglib PEG parser library https://github.com/siy/java-peglib @@ -35,178 +35,79 @@ https://github.com/siy/java-peglib + + peglib-core + peglib-incremental + peglib-formatter + peglib-maven-plugin + peglib-playground + + UTF-8 25 0.24.0 + 5.11.0 + 3.26.0 + 3.14.0 + 3.5.0 - - - - org.pragmatica-lite - core - ${pragmatica-lite.version} - - - - - org.junit.jupiter - junit-jupiter - 5.11.0 - test - - - org.assertj - assertj-core - 3.26.0 - test - - + + + + org.pragmatica-lite + peglib + ${project.version} + + + org.pragmatica-lite + peglib-incremental + ${project.version} + + + org.pragmatica-lite + peglib-formatter + ${project.version} + + + org.pragmatica-lite + core + ${pragmatica-lite.version} + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + - - - org.apache.maven.plugins - maven-compiler-plugin - 3.14.0 - - - org.apache.maven.plugins - maven-surefire-plugin - 3.5.0 - - - **/*Test.java - **/*Example.java - - - - - org.pragmatica-lite - jbct-maven-plugin - 0.4.1 - - - check - - check - - - - - + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.plugin.version} + + + - - bench - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.6.0 - - - add-jmh-sources - generate-sources - - add-source - - - - src/jmh/java - - - - - add-jmh-resources - generate-resources - - add-resource - - - - - src/test/resources - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - - org.openjdk.jmh - jmh-generator-annprocess - 1.37 - - - - - - org.codehaus.mojo - exec-maven-plugin - 3.5.0 - - org.openjdk.jmh.Main - compile - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.3 - - - benchmarks-uberjar - package - - shade - - - benchmarks - - - org.openjdk.jmh.Main - - - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - - org.openjdk.jmh - jmh-core - 1.37 - - - org.openjdk.jmh - jmh-generator-annprocess - 1.37 - provided - - - release From b1b6d7d01c554e25428827a8f975c1d34a53da0e Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 05:21:08 +0200 Subject: [PATCH 3/9] feat: parseRuleAt API on Parser interface + PegEngine dispatch --- .../org/pragmatica/peg/parser/Parser.java | 25 ++++++ .../pragmatica/peg/parser/PartialParse.java | 22 +++++ .../org/pragmatica/peg/parser/PegEngine.java | 86 +++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 peglib-core/src/main/java/org/pragmatica/peg/parser/PartialParse.java diff --git a/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java index dfc58bf..8d24959 100644 --- a/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java +++ b/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java @@ -1,6 +1,7 @@ package org.pragmatica.peg.parser; import org.pragmatica.lang.Result; +import org.pragmatica.peg.action.RuleId; import org.pragmatica.peg.tree.AstNode; import org.pragmatica.peg.tree.CstNode; @@ -53,4 +54,28 @@ public interface Parser { * Parse input with error recovery starting from a specific rule. */ ParseResultWithDiagnostics parseCstWithDiagnostics(String input, String startRule); + + /** + * Parse the rule identified by {@code ruleId} starting at {@code offset} in + * {@code input}. Unlike {@link #parseCst(String)}, the matched rule is not + * required to consume all remaining input — parsing stops when the rule + * itself finishes, and the returned {@link PartialParse#endOffset()} + * reports the absolute offset at which it stopped. + * + *

Intended for cursor-anchored incremental reparsing (see + * {@code docs/incremental/SPEC.md} §5.6) and grammar-debugging tooling. + * Uses the same packrat cache, trivia capture, and action machinery as + * {@link #parseCst(String)}. + * + * @param ruleId class whose {@link RuleId#name()} identifies the rule to + * invoke (default: {@link Class#getSimpleName()}) + * @param input full buffer text + * @param offset absolute input offset at which to begin parsing + * @return {@code Result.success} with the CST subtree and the absolute + * offset where parsing stopped, or {@code Result.failure} when + * the rule class is unknown, {@code offset} is out of range, or + * the rule fails to match at {@code offset}. + * @since 0.3.0 + */ + Result parseRuleAt(Class ruleId, String input, int offset); } diff --git a/peglib-core/src/main/java/org/pragmatica/peg/parser/PartialParse.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/PartialParse.java new file mode 100644 index 0000000..64b34fe --- /dev/null +++ b/peglib-core/src/main/java/org/pragmatica/peg/parser/PartialParse.java @@ -0,0 +1,22 @@ +package org.pragmatica.peg.parser; + +import org.pragmatica.peg.tree.CstNode; + +/** + * Result of a partial parse via + * {@link Parser#parseRuleAt(Class, String, int)}. Bundles the produced CST + * subtree with the offset where parsing stopped. + * + *

{@code endOffset} is the absolute offset into the original input where + * the rule finished matching (exclusive). It equals + * {@code node.span().end().offset()} plus any trailing trivia consumed by the + * rule — callers interested in the raw matched range should use + * {@link CstNode#span()} instead. + * + *

Introduced in 0.3.0 for cursor-anchored incremental reparsing. See + * {@code docs/incremental/SPEC.md} §5.6. + * + * @param node the CST subtree produced by the rule + * @param endOffset absolute input offset where the rule finished matching + */ +public record PartialParse(CstNode node, int endOffset) {} diff --git a/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java index 7d521f8..c2d225d 100644 --- a/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java +++ b/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java @@ -5,6 +5,7 @@ import org.pragmatica.peg.action.Action; import org.pragmatica.peg.action.ActionCompiler; import org.pragmatica.peg.action.Actions; +import org.pragmatica.peg.action.RuleId; import org.pragmatica.peg.action.SemanticValues; import org.pragmatica.peg.error.Diagnostic; import org.pragmatica.peg.error.ParseError; @@ -345,6 +346,91 @@ public ParseResultWithDiagnostics parseCstWithDiagnostics(String input, String s return parseWithRecovery(ctx, ruleOpt.unwrap(), input); } + /** + * 0.3.0 — parse a specific rule starting at a given offset. See + * {@link Parser#parseRuleAt(Class, String, int)}. + * + *

The rule is resolved from {@code ruleId.name()} (defaults to + * {@link Class#getSimpleName()}, matching the sanitized rule-name + * convention used by {@link org.pragmatica.peg.generator.ParserGenerator}). + * The parsing context is positioned at {@code offset} with a computed + * line/column, then {@link #parseRule(ParsingContext, Rule)} is invoked. + * Trailing whitespace after the rule is not consumed here — the + * returned {@link PartialParse#endOffset()} is the absolute offset + * immediately after the rule's matched span (including trailing trivia + * attached by the rule itself). + */ + @Override + public Result parseRuleAt(Class ruleId, String input, int offset) { + if (ruleId == null) { + return Result.failure(new ParseError.SemanticError( + SourceLocation.START, "Rule id class is null")); + } + if (input == null) { + return Result.failure(new ParseError.SemanticError( + SourceLocation.START, "Input is null")); + } + if (offset < 0 || offset > input.length()) { + return Result.failure(new ParseError.SemanticError( + SourceLocation.START, + "Offset " + offset + " out of range [0, " + input.length() + "]")); + } + var ruleName = resolveRuleName(ruleId); + var ruleOpt = grammar.rule(ruleName); + if (ruleOpt.isEmpty()) { + return Result.failure(new ParseError.SemanticError( + SourceLocation.START, "Unknown rule for class " + + ruleId.getSimpleName() + ": " + ruleName)); + } + var ctx = ParsingContext.create(input, grammar, config); + ctx.setSuggestionVocabulary(suggestionVocabulary); + ctx.restoreLocation(computeLocation(input, offset)); + var result = parseRule(ctx, ruleOpt.unwrap()); + if (result.isFailure()) { + return Result.failure(buildParseError(result, ctx, input)); + } + var success = (ParseResult.Success) result; + return Result.success(new PartialParse(success.node(), ctx.pos())); + } + + /** + * Resolve the sanitized rule name associated with a {@link RuleId} class. + * Instantiates the class when it is a parameterless record so + * {@link RuleId#name()} can override the default {@code Class#getSimpleName()} + * lookup. Falls back to the simple class name when no zero-arg constructor + * is available. + */ + private static String resolveRuleName(Class ruleId) { + try { + var ctor = ruleId.getDeclaredConstructor(); + ctor.setAccessible(true); + return ctor.newInstance() + .name(); + }catch (ReflectiveOperationException ignored) { + return ruleId.getSimpleName(); + } + } + + /** + * Compute the {@link SourceLocation} at {@code offset} in {@code input} by + * walking the prefix. Matches the line/column convention used elsewhere in + * the engine (1-based, {@code '\n'} advances to the next line, column + * resets to 1). + */ + private static SourceLocation computeLocation(String input, int offset) { + int line = 1; + int column = 1; + for (int i = 0; i < offset; i++ ) { + if (input.charAt(i) == '\n') { + line++ ; + column = 1; + }else { + column++ ; + } + } + return SourceLocation.at(line, column, offset); + } + private ParseResultWithDiagnostics toDiagnosticsResult(ParseError parseError, String input) { var loc = parseError.location(); var span = SourceSpan.at(loc); From 6e9719f3f4810b646387424eccd856745fef4e7f Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 05:22:52 +0200 Subject: [PATCH 4/9] feat: ParserGenerator emits parseRuleAt dispatch on generated parsers --- .../peg/generator/ParserGenerator.java | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/peglib-core/src/main/java/org/pragmatica/peg/generator/ParserGenerator.java b/peglib-core/src/main/java/org/pragmatica/peg/generator/ParserGenerator.java index 12fb7c2..18f3228 100644 --- a/peglib-core/src/main/java/org/pragmatica/peg/generator/ParserGenerator.java +++ b/peglib-core/src/main/java/org/pragmatica/peg/generator/ParserGenerator.java @@ -2337,6 +2337,109 @@ public ParseResultWithDiagnostics parseWithDiagnostics(String input) { """.formatted(sanitizedName)); } + generateCstParseRuleAt(sb); + } + + /** + * 0.3.0 — emit {@code parseRuleAt(Class<? extends RuleId>, String, int)} + * plus its supporting dispatch table for the generated CST parser. Each + * grammar rule contributes a map entry keyed by its {@code RuleId} marker + * record class; invocation seeks the parsing context to {@code offset} + * (computing {@code line}/{@code column} from the prefix) and calls the + * rule's generated {@code parse_()} method. + */ + private void generateCstParseRuleAt(StringBuilder sb) { + sb.append(""" + // === PartialParse (0.3.0) === + + /** + * Result of a partial parse via + * {@link #parseRuleAt(Class, String, int)}. Pairs the produced CST + * subtree with the absolute offset where parsing stopped. + */ + public record PartialParse(CstNode node, int endOffset) {} + + // Dispatch table: RuleId marker class -> rule method. + private final Map, + java.util.function.Supplier> ruleDispatch = buildRuleDispatch(); + + private Map, + java.util.function.Supplier> buildRuleDispatch() { + var m = new java.util.HashMap, + java.util.function.Supplier>(); + """); + for (var rule : grammar.rules()) { + var ruleClassName = toClassName(rule.name()); + var methodName = "parse_" + sanitize(rule.name()); + sb.append(" m.put(RuleId.") + .append(ruleClassName) + .append(".class, this::") + .append(methodName) + .append(");\n"); + } + sb.append(""" + return java.util.Map.copyOf(m); + } + + /** + * Parse the rule identified by {@code ruleId} starting at {@code offset} + * in {@code input}. Unlike {@link #parse(String)}, the matched rule is + * not required to consume all remaining input — parsing stops when the + * rule itself finishes, and the returned {@link PartialParse#endOffset()} + * reports the absolute offset at which it stopped. + * + * @since 0.3.0 + */ + public Result parseRuleAt( + Class ruleId, + String input, int offset) { + if (ruleId == null) { + return Result.failure(new ParseError(SourceLocation.START, "Rule id class is null")); + } + if (input == null) { + return Result.failure(new ParseError(SourceLocation.START, "Input is null")); + } + if (offset < 0 || offset > input.length()) { + return Result.failure(new ParseError(SourceLocation.START, + "Offset " + offset + " out of range [0, " + input.length() + "]")); + } + var supplier = ruleDispatch.get(ruleId); + if (supplier == null) { + return Result.failure(new ParseError(SourceLocation.START, + "Unknown rule for class " + ruleId.getSimpleName())); + } + init(input); + seekTo(offset); + var result = supplier.get(); + if (result.isFailure()) { + var errorLoc = furthestFailure.or(location()); + var expected = furthestExpected.filter(s -> !s.isEmpty()).or(result.expected.or("valid input")); + return Result.failure(new ParseError(errorLoc, "expected " + expected)); + } + return Result.success(new PartialParse(result.node.unwrap(), pos)); + } + + /** + * Seek the parsing context to {@code offset}, computing + * {@code line}/{@code column} from the prefix. Shared by + * {@link #parseRuleAt(Class, String, int)}. + */ + private void seekTo(int offset) { + this.pos = 0; + this.line = 1; + this.column = 1; + for (int i = 0; i < offset; i++) { + if (input.charAt(i) == '\\n') { + line++; + column = 1; + } else { + column++; + } + } + this.pos = offset; + } + + """); } private void generateCstRuleMethods(StringBuilder sb) { From a1c8fd100cc246fb8a2810b59d51c830c3e218f8 Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 05:24:00 +0200 Subject: [PATCH 5/9] test: ParseRuleAtTest interpreter + generated parity --- .../peg/parser/ParseRuleAtTest.java | 298 ++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 peglib-core/src/test/java/org/pragmatica/peg/parser/ParseRuleAtTest.java diff --git a/peglib-core/src/test/java/org/pragmatica/peg/parser/ParseRuleAtTest.java b/peglib-core/src/test/java/org/pragmatica/peg/parser/ParseRuleAtTest.java new file mode 100644 index 0000000..deebdd2 --- /dev/null +++ b/peglib-core/src/test/java/org/pragmatica/peg/parser/ParseRuleAtTest.java @@ -0,0 +1,298 @@ +package org.pragmatica.peg.parser; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.pragmatica.peg.PegParser; +import org.pragmatica.peg.action.RuleId; +import org.pragmatica.peg.tree.CstNode; + +import javax.tools.ToolProvider; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link Parser#parseRuleAt(Class, String, int)} — the 0.3.0 + * partial-parse entry point used by the incremental reparsing module. Covers + * the interpreter path (via {@code PegEngine}) and the generated-parser path + * (via {@code ParserGenerator}) including cross-path parity. + * + *

See {@code docs/incremental/SPEC.md} §5.6 for the design rationale. + */ +class ParseRuleAtTest { + + private static final String NUMBER_GRAMMAR = """ + Number <- < [0-9]+ > + """; + + private static final String NUMBER_WS_GRAMMAR = """ + Number <- < [0-9]+ > + %whitespace <- [ \\t]* + """; + + // Marker for negative test — intentionally not part of NUMBER_GRAMMAR. + record Bar() implements RuleId {} + + // Used for interpreter dispatch; matches rule name "Number" via simple name. + record Number() implements RuleId {} + + @Nested + class Interpreter { + + @Test + void parseRuleAt_offsetZero_returnsEndOffsetAtMatchEnd() { + var parser = PegParser.fromGrammar(NUMBER_GRAMMAR) + .unwrap(); + + var result = parser.parseRuleAt(Number.class, "42", 0); + + assertThat(result.isSuccess()).isTrue(); + var partial = result.unwrap(); + assertThat(partial.endOffset()).isEqualTo(2); + assertThat(partial.node()).isNotNull(); + assertThat(partial.node() + .span() + .end() + .offset()).isEqualTo(2); + } + + @Test + void parseRuleAt_nonZeroOffset_returnsCorrectEndOffset() { + var parser = PegParser.fromGrammar(NUMBER_WS_GRAMMAR) + .unwrap(); + + // Input: " 42 ", rule invoked at offset 2 should match "42" and stop at offset 4. + var result = parser.parseRuleAt(Number.class, " 42 ", 2); + + assertThat(result.isSuccess()).isTrue(); + var partial = result.unwrap(); + assertThat(partial.endOffset()).isEqualTo(4); + assertThat(partial.node() + .span() + .end() + .offset()).isEqualTo(4); + } + + @Test + void parseRuleAt_unknownRuleClass_returnsFailure() { + var parser = PegParser.fromGrammar(NUMBER_GRAMMAR) + .unwrap(); + + // "Bar" is not a rule in NUMBER_GRAMMAR. + var result = parser.parseRuleAt(Bar.class, "42", 0); + + assertThat(result.isFailure()).isTrue(); + assertThat(result.toString()).contains("Bar"); + } + + @Test + void parseRuleAt_parseFailureAtOffset_returnsFailure() { + var parser = PegParser.fromGrammar(NUMBER_GRAMMAR) + .unwrap(); + + // Input at offset 0 is 'a', not a digit — rule fails. + var result = parser.parseRuleAt(Number.class, "abc", 0); + + assertThat(result.isFailure()).isTrue(); + } + + @Test + void parseRuleAt_offsetOutOfRange_returnsFailure() { + var parser = PegParser.fromGrammar(NUMBER_GRAMMAR) + .unwrap(); + + var negative = parser.parseRuleAt(Number.class, "42", -1); + var tooLarge = parser.parseRuleAt(Number.class, "42", 10); + + assertThat(negative.isFailure()).isTrue(); + assertThat(tooLarge.isFailure()).isTrue(); + } + + @Test + void parseRuleAt_endOffsetEqualsInputLength_whenRuleConsumesAll() { + var parser = PegParser.fromGrammar(NUMBER_GRAMMAR) + .unwrap(); + + var result = parser.parseRuleAt(Number.class, "12345", 0); + + assertThat(result.isSuccess()).isTrue(); + assertThat(result.unwrap() + .endOffset()).isEqualTo(5); + } + + @Test + void parseRuleAt_nullRuleId_returnsFailure() { + var parser = PegParser.fromGrammar(NUMBER_GRAMMAR) + .unwrap(); + + var result = parser.parseRuleAt(null, "42", 0); + + assertThat(result.isFailure()).isTrue(); + } + } + + @Nested + class PartialParseRecord { + + @Test + void partialParse_accessorsExposeFields() { + var parser = PegParser.fromGrammar(NUMBER_GRAMMAR) + .unwrap(); + var partial = parser.parseRuleAt(Number.class, "42", 0) + .unwrap(); + + assertThat(partial.node()).isInstanceOf(CstNode.class); + assertThat(partial.endOffset()).isEqualTo(2); + } + + @Test + void partialParse_equalityAndHashCode() { + CstNode node = new CstNode.Terminal( + org.pragmatica.peg.tree.SourceSpan.of( + org.pragmatica.peg.tree.SourceLocation.at(1, 1, 0), + org.pragmatica.peg.tree.SourceLocation.at(1, 3, 2)), + "Number", "42", java.util.List.of(), java.util.List.of()); + + var a = new PartialParse(node, 2); + var b = new PartialParse(node, 2); + + assertThat(a).isEqualTo(b); + assertThat(a.hashCode()).isEqualTo(b.hashCode()); + } + } + + @Nested + class GeneratorParity { + + @Test + void generatedParser_parseRuleAt_matchesInterpreter() throws Exception { + // Generate a CST parser for NUMBER_WS_GRAMMAR. + var source = PegParser.generateCstParser(NUMBER_WS_GRAMMAR, + "test.partial", + "PartialParser") + .unwrap(); + var parserClass = compileAndLoad(source, "test.partial.PartialParser"); + var parser = parserClass.getDeclaredConstructor() + .newInstance(); + + var ruleIdIfc = parserClass.getClasses(); + Class numberRuleId = null; + for (var c : ruleIdIfc) { + if (c.getSimpleName() + .equals("RuleId")) { + for (var inner : c.getClasses()) { + if (inner.getSimpleName() + .equals("Number")) { + numberRuleId = inner; + break; + } + } + break; + } + } + assertThat(numberRuleId).isNotNull(); + var parseRuleAt = parserClass.getMethod("parseRuleAt", Class.class, String.class, int.class); + + // Offset 0 + var input1 = "42"; + var genResult1 = parseRuleAt.invoke(parser, numberRuleId, input1, 0); + var isSuccess1 = (boolean) genResult1.getClass() + .getMethod("isSuccess") + .invoke(genResult1); + assertThat(isSuccess1).isTrue(); + var partial1 = genResult1.getClass() + .getMethod("unwrap") + .invoke(genResult1); + int endOffset1 = (int) partial1.getClass() + .getMethod("endOffset") + .invoke(partial1); + + var interpEnd1 = PegParser.fromGrammar(NUMBER_WS_GRAMMAR) + .unwrap() + .parseRuleAt(Number.class, input1, 0) + .unwrap() + .endOffset(); + assertThat(endOffset1).isEqualTo(interpEnd1); + + // Offset 2 in " 42 " + var input2 = " 42 "; + var genResult2 = parseRuleAt.invoke(parser, numberRuleId, input2, 2); + var isSuccess2 = (boolean) genResult2.getClass() + .getMethod("isSuccess") + .invoke(genResult2); + assertThat(isSuccess2).isTrue(); + var partial2 = genResult2.getClass() + .getMethod("unwrap") + .invoke(genResult2); + int endOffset2 = (int) partial2.getClass() + .getMethod("endOffset") + .invoke(partial2); + var interpEnd2 = PegParser.fromGrammar(NUMBER_WS_GRAMMAR) + .unwrap() + .parseRuleAt(Number.class, input2, 2) + .unwrap() + .endOffset(); + assertThat(endOffset2).isEqualTo(interpEnd2); + } + + @Test + void generatedParser_parseRuleAt_failureOnBadInput() throws Exception { + var source = PegParser.generateCstParser(NUMBER_GRAMMAR, + "test.partial.fail", + "FailParser") + .unwrap(); + var parserClass = compileAndLoad(source, "test.partial.fail.FailParser"); + var parser = parserClass.getDeclaredConstructor() + .newInstance(); + + Class numberRuleId = null; + for (var c : parserClass.getClasses()) { + if (c.getSimpleName() + .equals("RuleId")) { + for (var inner : c.getClasses()) { + if (inner.getSimpleName() + .equals("Number")) { + numberRuleId = inner; + break; + } + } + } + } + assertThat(numberRuleId).isNotNull(); + var parseRuleAt = parserClass.getMethod("parseRuleAt", Class.class, String.class, int.class); + + // "abc" at offset 0 is not digits — must fail. + var genResult = parseRuleAt.invoke(parser, numberRuleId, "abc", 0); + var isFailure = (boolean) genResult.getClass() + .getMethod("isFailure") + .invoke(genResult); + assertThat(isFailure).isTrue(); + } + } + + private static Class compileAndLoad(String source, String className) throws Exception { + var tempDir = Files.createTempDirectory("peglib-parseRuleAt-test"); + var packagePath = className.substring(0, className.lastIndexOf('.')) + .replace('.', '/'); + var simpleClassName = className.substring(className.lastIndexOf('.') + 1); + + var packageDir = tempDir.resolve(packagePath); + Files.createDirectories(packageDir); + var sourceFile = packageDir.resolve(simpleClassName + ".java"); + Files.writeString(sourceFile, source); + + var compiler = ToolProvider.getSystemJavaCompiler(); + var rc = compiler.run(null, null, null, + "-d", tempDir.toString(), + "-cp", System.getProperty("java.class.path"), + sourceFile.toString()); + if (rc != 0) { + throw new RuntimeException("Compilation failed for " + className); + } + var classLoader = new URLClassLoader(new URL[]{tempDir.toUri() + .toURL()}); + return classLoader.loadClass(className); + } +} From b8466553e7f4f2d2b801469549cdb822848e62cb Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 05:25:00 +0200 Subject: [PATCH 6/9] chore: jbct format for parseRuleAt additions --- .../main/java/org/pragmatica/peg/parser/Parser.java | 2 +- .../java/org/pragmatica/peg/parser/PegEngine.java | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java index 8d24959..2877300 100644 --- a/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java +++ b/peglib-core/src/main/java/org/pragmatica/peg/parser/Parser.java @@ -77,5 +77,5 @@ public interface Parser { * the rule fails to match at {@code offset}. * @since 0.3.0 */ - Result parseRuleAt(Class ruleId, String input, int offset); + Result parseRuleAt(Class< ? extends RuleId> ruleId, String input, int offset); } diff --git a/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java b/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java index c2d225d..63fbfa4 100644 --- a/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java +++ b/peglib-core/src/main/java/org/pragmatica/peg/parser/PegEngine.java @@ -361,7 +361,7 @@ public ParseResultWithDiagnostics parseCstWithDiagnostics(String input, String s * attached by the rule itself). */ @Override - public Result parseRuleAt(Class ruleId, String input, int offset) { + public Result parseRuleAt(Class< ? extends RuleId> ruleId, String input, int offset) { if (ruleId == null) { return Result.failure(new ParseError.SemanticError( SourceLocation.START, "Rule id class is null")); @@ -372,15 +372,13 @@ public Result parseRuleAt(Class ruleId, String i } if (offset < 0 || offset > input.length()) { return Result.failure(new ParseError.SemanticError( - SourceLocation.START, - "Offset " + offset + " out of range [0, " + input.length() + "]")); + SourceLocation.START, "Offset " + offset + " out of range [0, " + input.length() + "]")); } var ruleName = resolveRuleName(ruleId); var ruleOpt = grammar.rule(ruleName); if (ruleOpt.isEmpty()) { return Result.failure(new ParseError.SemanticError( - SourceLocation.START, "Unknown rule for class " - + ruleId.getSimpleName() + ": " + ruleName)); + SourceLocation.START, "Unknown rule for class " + ruleId.getSimpleName() + ": " + ruleName)); } var ctx = ParsingContext.create(input, grammar, config); ctx.setSuggestionVocabulary(suggestionVocabulary); @@ -400,8 +398,8 @@ public Result parseRuleAt(Class ruleId, String i * lookup. Falls back to the simple class name when no zero-arg constructor * is available. */ - private static String resolveRuleName(Class ruleId) { - try { + private static String resolveRuleName(Class< ? extends RuleId> ruleId) { + try{ var ctor = ruleId.getDeclaredConstructor(); ctor.setAccessible(true); return ctor.newInstance() From 2083c7f1517953d3dd49ec61d6aca1bce28a8f4c Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 05:26:22 +0200 Subject: [PATCH 7/9] docs: parseRuleAt API + 0.3.0 module layout --- README.md | 36 +++++++++++++- docs/GRAMMAR-DSL.md | 2 + docs/PARTIAL-PARSE.md | 112 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 docs/PARTIAL-PARSE.md diff --git a/README.md b/README.md index 0650124..daee24b 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,22 @@ A PEG (Parsing Expression Grammar) parser library for Java, inspired by [cpp-peg - **Source code generation** - Generate standalone parser Java files - **Java 25** - Uses latest Java features (records, sealed interfaces, pattern matching) +## Module Layout (0.3.0) + +Peglib is a multi-module Maven reactor. Pick the module you need; transitive deps stay minimal. + +``` +peglib-parent (pom) +├── peglib-core # engine, generator, analyzer — the core parser +├── peglib-incremental # cursor-anchored incremental reparsing (shell; spec-driven) +├── peglib-formatter # grammar-driven source formatter (shell) +├── peglib-maven-plugin # codegen + analyzer goals for Maven builds +└── peglib-playground # interactive REPL / web playground +``` + +The artifact id `peglib` is reserved for the parent pom; production consumers depend on +`peglib-core`. The other modules are optional add-ons. + ## Quick Start ### Dependency @@ -22,7 +38,7 @@ A PEG (Parsing Expression Grammar) parser library for Java, inspired by [cpp-peg ```xml org.pragmatica-lite - peglib + peglib-core 0.3.0 ``` @@ -63,6 +79,24 @@ Integer result = (Integer) calculator.parse("3 + 5 * 2").unwrap(); // result = 13 ``` +### Partial parse (0.3.0) + +`parseRuleAt` invokes a single rule against a substring of the buffer starting at a +given offset. Intended for cursor-anchored incremental reparsing and grammar-debugging +tooling. See [docs/PARTIAL-PARSE.md](docs/PARTIAL-PARSE.md) for the full API. + +```java +record Number() implements org.pragmatica.peg.action.RuleId {} + +var parser = PegParser.fromGrammar(""" + Number <- < [0-9]+ > + %whitespace <- [ \\t]* + """).unwrap(); + +var partial = parser.parseRuleAt(Number.class, " 42 ", 2).unwrap(); +// partial.endOffset() == 4, partial.node() is the CST for "42" +``` + ## Grammar Syntax Peglib uses [PEG](https://bford.info/pub/lang/peg.pdf) syntax compatible with [cpp-peglib](https://github.com/yhirose/cpp-peglib): diff --git a/docs/GRAMMAR-DSL.md b/docs/GRAMMAR-DSL.md index 1a9a1d2..63a712f 100644 --- a/docs/GRAMMAR-DSL.md +++ b/docs/GRAMMAR-DSL.md @@ -548,5 +548,7 @@ tooling integrations. formatting, `ParseResultWithDiagnostics` API - [Trivia Attribution](TRIVIA-ATTRIBUTION.md) — how whitespace/comments are attached to CST nodes +- [Partial Parse](PARTIAL-PARSE.md) — the 0.3.0 `parseRuleAt` API for + cursor-anchored partial parsing and incremental reparse - [`CHANGELOG.md`](../CHANGELOG.md) — per-release history of grammar-DSL additions diff --git a/docs/PARTIAL-PARSE.md b/docs/PARTIAL-PARSE.md new file mode 100644 index 0000000..293b401 --- /dev/null +++ b/docs/PARTIAL-PARSE.md @@ -0,0 +1,112 @@ +# Partial parse — `parseRuleAt` (0.3.0) + +`Parser.parseRuleAt` invokes a specific grammar rule at a given offset in the +input buffer, returning the produced CST subtree plus the absolute offset where +parsing stopped. Unlike `parseCst`, the matched rule is not required to consume +all remaining input — parsing stops when the rule itself finishes. + +The feature is primarily consumed by the `peglib-incremental` module for +cursor-anchored reparsing (see [`docs/incremental/SPEC.md`](incremental/SPEC.md) §5.6) +but is also useful for grammar debugging and testing. + +## API + +```java +// In org.pragmatica.peg.parser + +public interface Parser { + // ... existing methods ... + + Result parseRuleAt(Class ruleId, + String input, + int offset); +} + +public record PartialParse(CstNode node, int endOffset) {} +``` + +`RuleId` lives in `org.pragmatica.peg.action`. It's the same marker interface +used by the 0.2.6 programmatic-action API, and — importantly — the exact +interface that generated parsers' nested `sealed interface RuleId` extends. +That means the same `RuleId` class value works against both the interpreter +and a generated parser. + +## Resolution rules + +The rule name is resolved from `ruleId.name()`. The default implementation +returns `getClass().getSimpleName()`, which matches the sanitized rule-name +convention used by `ParserGenerator`. For custom marker records that override +`name()`, the interpreter instantiates the class (requires a zero-arg +constructor) to invoke the override. + +## Semantics + +| Input condition | Result | +| ---------------------------------------- | ------------------------------------------------ | +| `ruleId` class unknown to the grammar | `Result.failure(SemanticError)` | +| `offset < 0 \|\| offset > input.length()` | `Result.failure(SemanticError)` | +| Rule matches prefix of `input[offset:]` | `Result.success(PartialParse(node, endOffset))` | +| Rule fails at `offset` | `Result.failure(UnexpectedInput)` from the normal parser error path | + +`endOffset` is the absolute offset at which the rule stopped matching. When the +rule (or any nested rule) attaches trailing trivia, that trivia is included in +`endOffset`; the raw matched span is `partial.node().span()`. + +The method reuses the packrat cache, trivia capture, and (for the runtime +interpreter) lambda/inline action machinery used by `parseCst`. There is no +state carried between calls — each invocation creates a fresh `ParsingContext`. + +## Examples + +### Interpreter + +```java +record Number() implements RuleId {} + +var parser = PegParser.fromGrammar(""" + Number <- < [0-9]+ > + %whitespace <- [ \\t]* + """).unwrap(); + +// offset 0 +var p1 = parser.parseRuleAt(Number.class, "42", 0).unwrap(); +// p1.endOffset() == 2 + +// offset 2 in " 42 " +var p2 = parser.parseRuleAt(Number.class, " 42 ", 2).unwrap(); +// p2.endOffset() == 4 +``` + +### Generated parser + +Generated CST parsers emit a public `parseRuleAt(Class, String, int)` method +that returns the generated parser's own `PartialParse` record. The dispatch +keys are the nested `RuleId` record classes: + +```java +var parser = new MyGeneratedParser(); +var partial = parser.parseRuleAt(MyGeneratedParser.RuleId.Number.class, input, offset) + .unwrap(); +``` + +The generator emits a private `Map, Supplier>` +dispatch table populated once at construction, so each call is a constant-time +lookup. + +## Limitations + +- **Action replay is not incremental.** Actions run every time `parseRuleAt` + is invoked, the same as any other parse call. Incremental action replay + (avoiding re-running actions over unchanged subtrees) is out of scope. +- **No error recovery.** `parseRuleAt` uses the standard fail-fast path. If + you need `ADVANCED` diagnostics over a partial region, use the full + `parseCstWithDiagnostics` API. + +## See also + +- [`docs/incremental/SPEC.md`](incremental/SPEC.md) — full incremental reparse spec +- [`GRAMMAR-DSL.md`](GRAMMAR-DSL.md) — grammar syntax reference +- [`RuleId`](../peglib-core/src/main/java/org/pragmatica/peg/action/RuleId.java) + and + [`Actions`](../peglib-core/src/main/java/org/pragmatica/peg/action/Actions.java) + — marker type and programmatic action API From d1605ff49558dba861e20b9c3cf9b4d8dc3c1cab Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 05:28:44 +0200 Subject: [PATCH 8/9] docs: README artifactId remains peglib (coordinate preserved in peglib-core module) --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index daee24b..0029862 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,9 @@ peglib-parent (pom) └── peglib-playground # interactive REPL / web playground ``` -The artifact id `peglib` is reserved for the parent pom; production consumers depend on -`peglib-core`. The other modules are optional add-ons. +The `peglib-core` module directory ships the primary artifact `org.pragmatica-lite:peglib` — +the Maven coordinate is preserved from 0.2.x for downstream compatibility. The other modules +are optional add-ons. ## Quick Start @@ -38,7 +39,7 @@ The artifact id `peglib` is reserved for the parent pom; production consumers de ```xml org.pragmatica-lite - peglib-core + peglib 0.3.0 ``` From 3f1891a504c0641e16b005713739ca9ed1fbfeed Mon Sep 17 00:00:00 2001 From: Sergiy Yevtushenko Date: Wed, 22 Apr 2026 05:29:26 +0200 Subject: [PATCH 9/9] docs: CHANGELOG for 0.3.0 (multi-module reshape + parseRuleAt) --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de6dead..0e9dcf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.3.0] - 2026-04-22 +Infrastructure-only minor-bump release. No new user-facing features beyond the `parseRuleAt` API. Sets up the project structure and API additions that `peglib-incremental` (0.3.1) and `peglib-formatter` (0.3.3) will build against. + +### Changed + +- **Root pom converted to a multi-module parent.** Previous structure was a single-module `org.pragmatica-lite:peglib` with sibling directories holding their own poms. New structure: + ``` + peglib-parent (root pom, packaging=pom) + ├── peglib-core (the primary artifact: org.pragmatica-lite:peglib:0.3.0) + ├── peglib-incremental (shell module, reserved for 0.3.1) + ├── peglib-formatter (shell module, reserved for 0.3.3) + ├── peglib-maven-plugin (was sibling; now reactor module) + └── peglib-playground (was sibling; now reactor module) + ``` +- **Maven coordinate preserved.** `org.pragmatica-lite:peglib:0.3.0` still resolves to the same jar content consumers got in 0.2.x — the artifact simply lives in a sub-directory. Downstream consumers pinning the `peglib` coordinate need no changes. +- `peglib-maven-plugin` and `peglib-playground` modules now inherit from `peglib-parent` — their poms gain `` references; artifactIds unchanged. + +### Added + +- `Parser#parseRuleAt(Class ruleId, String input, int offset)` — partial-parse entry point. Parses a specific rule against input starting at the given offset; returns `Result` wrapping the resulting CST subtree and its end offset. Implemented by `PegEngine` (interpreter) and by generated parsers via an identity map keyed on the `RuleId` marker classes the generator has been emitting since 0.2.6. This is the API `peglib-incremental` (0.3.1) depends on per `docs/incremental/SPEC.md` §5.6. +- `org.pragmatica.peg.parser.PartialParse` record `(CstNode node, int endOffset)`. +- `peglib-incremental` and `peglib-formatter` shell modules — empty placeholders with just a `package-info.java` each. Reservations for 0.3.1 and 0.3.3. +- `docs/PARTIAL-PARSE.md` — `parseRuleAt` API reference. +- README updated with a Module Layout section and `parseRuleAt` usage snippet. + +### Tests + +- Root reactor: 663 → **674 passing** in `peglib-core`, +11 new in `ParseRuleAtTest` (interpreter + generator parity + `PartialParse` record). Plus 5 in `peglib-maven-plugin`, 22 in `peglib-playground` — aggregate **701 tests, 0 failures, 1 skipped** (pre-existing `RoundTripTest`). +- All 22-file corpus parity suites stay 22/22 under the new structure. +- `GeneratorFlagInertnessTest` stays 3/3 green — `parseRuleAt` emission lands in both config-vs-no-config sides. + +### Notes + +- Non-CST (Object-returning) generator path uses a different `ParseResult` type; `parseRuleAt` is scoped to the CST generator path (used by `peglib-incremental`). Per-path rationale in `docs/PARTIAL-PARSE.md`. + ## [0.2.9] - 2026-04-22 ### Added