ibex 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +89 -123
- data/docs/architecture.md +477 -31
- data/docs/bison-import.md +103 -0
- data/docs/comparison-policy.md +127 -0
- data/docs/configuration-model.md +59 -0
- data/docs/configuration-report.md +28 -0
- data/docs/conflict-explanation-reviews/v1/records/README.md +28 -0
- data/docs/conflict-explanation-study.md +62 -0
- data/docs/construction-profiling.md +157 -0
- data/docs/cst-migration.md +106 -0
- data/docs/cst.md +237 -0
- data/docs/decisions/0000-template.md +24 -0
- data/docs/decisions/0001-separate-ir-pipeline.md +34 -0
- data/docs/decisions/0002-opaque-user-code-boundary.md +32 -0
- data/docs/decisions/0003-self-hosted-grammar-frontend.md +32 -0
- data/docs/decisions/0004-shared-semantic-and-lossless-source-model.md +33 -0
- data/docs/decisions/0005-contained-grammar-composition.md +34 -0
- data/docs/decisions/0006-bounded-structural-grammar-lowering.md +32 -0
- data/docs/decisions/0007-shared-parser-construction-pipeline.md +33 -0
- data/docs/decisions/0008-versioned-runtime-package-boundary.md +36 -0
- data/docs/decisions/0009-isolated-parser-sessions.md +34 -0
- data/docs/decisions/0010-committed-runtime-observation.md +34 -0
- data/docs/decisions/0011-versioned-semantic-action-boundary.md +37 -0
- data/docs/decisions/0012-bounded-nonexecuting-analysis.md +37 -0
- data/docs/decisions/0013-transactional-generation-publication.md +37 -0
- data/docs/decisions/0014-versioned-generated-lexer.md +35 -0
- data/docs/decisions/0015-worker-isolated-browser-analysis.md +32 -0
- data/docs/decisions/0016-red-green-concrete-syntax.md +34 -0
- data/docs/decisions/0017-persistent-syntax-artifacts.md +35 -0
- data/docs/decisions/0018-conservative-incremental-syntax-reuse.md +38 -0
- data/docs/decisions/0019-runtime-syntax-session-boundary.md +51 -0
- data/docs/decisions/0020-grammar-ir-parser-contract.md +65 -0
- data/docs/decisions/0021-data-only-parser-table-sidecar.md +50 -0
- data/docs/decisions/0022-manifest-bound-verification-report.md +77 -0
- data/docs/decisions/0023-syntax-only-repair-results.md +48 -0
- data/docs/decisions/0024-direct-ielr-construction.md +42 -0
- data/docs/decisions/README.md +74 -0
- data/docs/declarative-configuration.md +262 -0
- data/docs/development.md +306 -0
- data/docs/direct-ielr-decision.md +120 -0
- data/docs/direct-multi-entry-decision.md +82 -0
- data/docs/editor-setup.md +26 -0
- data/docs/error-ux-review-rubric-v1.md +117 -0
- data/docs/error-ux-reviews/v1/records/README.md +22 -0
- data/docs/error-ux-round2-review-status-v1.json +27 -0
- data/docs/error-ux-round2-reviews/v1/records/README.md +30 -0
- data/docs/error-ux-round2-v1.json +1581 -0
- data/docs/error-ux-round2.md +111 -0
- data/docs/error-ux.md +114 -0
- data/docs/getting-started.md +80 -0
- data/docs/grammar-reference.md +629 -18
- data/docs/ielr-design.md +43 -0
- data/docs/ielr.md +92 -0
- data/docs/ja/bison-import.md +51 -0
- data/docs/ja/stable-api.md +53 -0
- data/docs/lexer-construction-profile.md +109 -0
- data/docs/lexer-migration.md +56 -0
- data/docs/maturity.md +128 -0
- data/docs/project-site-strategy.md +54 -0
- data/docs/racc-migration-evidence.md +45 -0
- data/docs/racc-migration.md +45 -6
- data/docs/release-readiness.md +221 -0
- data/docs/repair-semantics.md +123 -0
- data/docs/runtime-abi-evolution.md +307 -0
- data/docs/stability.md +234 -0
- data/docs/status.md +43 -0
- data/docs/syntax-sessions.md +183 -0
- data/docs/table-artifact.md +125 -0
- data/docs/test-interactions.md +219 -0
- data/docs/verification-report.md +137 -0
- data/docs/verifier-trust-boundary.md +199 -0
- data/docs/workloads.md +132 -0
- data/examples/README.md +60 -0
- data/examples/calculator.y +44 -0
- data/examples/csv.y +32 -0
- data/examples/ini.y +70 -0
- data/examples/json.y +48 -0
- data/examples/tiny_language.y +75 -0
- data/lib/ibex/analysis/digraph.rb +128 -0
- data/lib/ibex/analysis/sets.rb +5 -4
- data/lib/ibex/analysis.rb +1 -0
- data/lib/ibex/artifact_set.rb +63 -0
- data/lib/ibex/bison_import/importer.rb +516 -0
- data/lib/ibex/bison_import/tokenizer.rb +260 -0
- data/lib/ibex/bison_import.rb +200 -0
- data/lib/ibex/bounded_subprocess.rb +171 -0
- data/lib/ibex/cli/ambiguity.rb +75 -0
- data/lib/ibex/cli/analysis.rb +134 -0
- data/lib/ibex/cli/bison_import.rb +121 -0
- data/lib/ibex/cli/config.rb +128 -0
- data/lib/ibex/cli/counterexample_options.rb +6 -2
- data/lib/ibex/cli/coverage.rb +173 -0
- data/lib/ibex/cli/debug.rb +106 -0
- data/lib/ibex/cli/diagnostics.rb +136 -0
- data/lib/ibex/cli/documentation.rb +70 -0
- data/lib/ibex/cli/equiv.rb +169 -0
- data/lib/ibex/cli/error_messages.rb +184 -0
- data/lib/ibex/cli/explain.rb +85 -0
- data/lib/ibex/cli/fix.rb +203 -0
- data/lib/ibex/cli/formatting.rb +387 -0
- data/lib/ibex/cli/fuzz.rb +200 -0
- data/lib/ibex/cli/fuzz_regressions.rb +145 -0
- data/lib/ibex/cli/generation_artifacts.rb +189 -0
- data/lib/ibex/cli/generation_error_messages.rb +39 -0
- data/lib/ibex/cli/grammar_tests.rb +140 -0
- data/lib/ibex/cli/ir_tools.rb +128 -0
- data/lib/ibex/cli/lsp.rb +33 -0
- data/lib/ibex/cli/outputs.rb +133 -23
- data/lib/ibex/cli/racc_migration.rb +87 -0
- data/lib/ibex/cli/reduce.rb +202 -0
- data/lib/ibex/cli/reduce_reporting.rb +71 -0
- data/lib/ibex/cli/samples.rb +118 -0
- data/lib/ibex/cli/verify.rb +116 -0
- data/lib/ibex/cli/watch.rb +104 -0
- data/lib/ibex/cli.rb +825 -55
- data/lib/ibex/codegen/action_locations.rb +103 -0
- data/lib/ibex/codegen/action_method_source.rb +209 -0
- data/lib/ibex/codegen/action_source.rb +119 -0
- data/lib/ibex/codegen/ambiguity.rb +174 -0
- data/lib/ibex/codegen/cst_metadata.rb +171 -0
- data/lib/ibex/codegen/documentation.rb +170 -0
- data/lib/ibex/codegen/explain.rb +380 -0
- data/lib/ibex/codegen/generated_action_abi.rb +293 -0
- data/lib/ibex/codegen/html.rb +94 -10
- data/lib/ibex/codegen/mermaid.rb +43 -0
- data/lib/ibex/codegen/railroad.rb +197 -0
- data/lib/ibex/codegen/railroad_documentation.rb +59 -0
- data/lib/ibex/codegen/rbs.rb +331 -2
- data/lib/ibex/codegen/report.rb +67 -15
- data/lib/ibex/codegen/ruby.rb +305 -66
- data/lib/ibex/codegen/ruby_actions.rb +146 -0
- data/lib/ibex/codegen/ruby_ast.rb +121 -0
- data/lib/ibex/codegen/ruby_error_messages.rb +28 -0
- data/lib/ibex/codegen/ruby_lexer.rb +83 -0
- data/lib/ibex/codegen/ruby_syntax.rb +96 -0
- data/lib/ibex/codegen/ruby_table_metadata.rb +57 -0
- data/lib/ibex/codegen/ruby_value_printers.rb +56 -0
- data/lib/ibex/codegen/symbol_labels.rb +1 -1
- data/lib/ibex/configuration/analysis_grammar.rb +35 -0
- data/lib/ibex/configuration/explanation.rb +421 -0
- data/lib/ibex/configuration/inspector.rb +232 -0
- data/lib/ibex/configuration.rb +580 -0
- data/lib/ibex/coverage/collector.rb +198 -0
- data/lib/ibex/coverage/event_stream.rb +103 -0
- data/lib/ibex/coverage/report.rb +267 -0
- data/lib/ibex/coverage/runtime_event_validator.rb +169 -0
- data/lib/ibex/coverage.rb +13 -0
- data/lib/ibex/delta_reducer.rb +99 -0
- data/lib/ibex/diff.rb +140 -0
- data/lib/ibex/equiv/machine.rb +135 -0
- data/lib/ibex/equiv.rb +373 -0
- data/lib/ibex/error_messages/parser.rb +159 -0
- data/lib/ibex/error_messages/parser_v2.rb +198 -0
- data/lib/ibex/error_messages/renderer.rb +65 -0
- data/lib/ibex/error_messages/sentence_search.rb +196 -0
- data/lib/ibex/error_messages/update.rb +169 -0
- data/lib/ibex/error_messages.rb +165 -0
- data/lib/ibex/fix.rb +557 -0
- data/lib/ibex/frontend/ast.rb +166 -7
- data/lib/ibex/frontend/bootstrap_parser.rb +40 -4
- data/lib/ibex/frontend/diagnostic.rb +81 -0
- data/lib/ibex/frontend/diagnostic_recovery.rb +268 -0
- data/lib/ibex/frontend/dsl.rb +66 -7
- data/lib/ibex/frontend/formatter.rb +453 -0
- data/lib/ibex/frontend/generated_parser.rb +644 -190
- data/lib/ibex/frontend/generated_parser_base.rb +170 -32
- data/lib/ibex/frontend/generated_parser_includes.rb +51 -0
- data/lib/ibex/frontend/generated_parser_metadata.rb +61 -0
- data/lib/ibex/frontend/generated_parser_parameters.rb +60 -0
- data/lib/ibex/frontend/generation.rb +33 -0
- data/lib/ibex/frontend/lexer.rb +162 -10
- data/lib/ibex/frontend/lexer_recovery.rb +84 -0
- data/lib/ibex/frontend/parser/declarations.rb +262 -11
- data/lib/ibex/frontend/parser/parameters.rb +82 -0
- data/lib/ibex/frontend/parser/rules.rb +43 -6
- data/lib/ibex/frontend/parser.rb +182 -4
- data/lib/ibex/frontend/parser_configuration_support.rb +56 -0
- data/lib/ibex/frontend/regenerator.rb +27 -1
- data/lib/ibex/frontend/resolution.rb +70 -0
- data/lib/ibex/frontend/resolver.rb +217 -0
- data/lib/ibex/frontend/rule_documentation.rb +104 -0
- data/lib/ibex/frontend/source_cursor.rb +133 -9
- data/lib/ibex/frontend/source_document.rb +229 -0
- data/lib/ibex/frontend/source_loader.rb +150 -0
- data/lib/ibex/frontend/source_span.rb +89 -0
- data/lib/ibex/frontend/token_adapter/declaration_document_state.rb +47 -0
- data/lib/ibex/frontend/token_adapter/declaration_lexer_state.rb +83 -0
- data/lib/ibex/frontend/token_adapter/declaration_state.rb +244 -22
- data/lib/ibex/frontend/token_adapter/delimiter_tracker.rb +8 -2
- data/lib/ibex/frontend/token_adapter/rule_state.rb +60 -2
- data/lib/ibex/frontend/token_adapter.rb +18 -3
- data/lib/ibex/frontend.rb +14 -2
- data/lib/ibex/fuzz.rb +219 -0
- data/lib/ibex/generation_input.rb +57 -0
- data/lib/ibex/generation_manifest.rb +211 -0
- data/lib/ibex/generation_transaction.rb +261 -0
- data/lib/ibex/generation_transaction_recovery.rb +109 -0
- data/lib/ibex/generation_transaction_validation.rb +196 -0
- data/lib/ibex/grammar_tests.rb +206 -0
- data/lib/ibex/ir/automaton_ir.rb +86 -11
- data/lib/ibex/ir/grammar_ir.rb +170 -26
- data/lib/ibex/ir/lexer_ir.rb +76 -0
- data/lib/ibex/ir/parser_contract.rb +135 -0
- data/lib/ibex/ir/serialize.rb +268 -50
- data/lib/ibex/ir/validator/automaton.rb +375 -0
- data/lib/ibex/ir/validator/base.rb +147 -0
- data/lib/ibex/ir/validator/grammar.rb +634 -0
- data/lib/ibex/ir/validator/lexer.rb +113 -0
- data/lib/ibex/ir/validator.rb +63 -0
- data/lib/ibex/ir.rb +71 -5
- data/lib/ibex/lalr/build_metrics.rb +71 -0
- data/lib/ibex/lalr/builder.rb +514 -52
- data/lib/ibex/lalr/conflict.rb +1 -0
- data/lib/ibex/lalr/conflict_search.rb +26 -9
- data/lib/ibex/lalr/counterexample.rb +38 -18
- data/lib/ibex/lalr/direct_lookaheads.rb +289 -0
- data/lib/ibex/lalr/goto_follows.rb +229 -0
- data/lib/ibex/lalr/ielr/annotator.rb +214 -0
- data/lib/ibex/lalr/ielr/bits.rb +28 -0
- data/lib/ibex/lalr/ielr/inadequacy.rb +47 -0
- data/lib/ibex/lalr/ielr/item_lookaheads.rb +78 -0
- data/lib/ibex/lalr/ielr/pipeline.rb +75 -0
- data/lib/ibex/lalr/ielr/split_stability.rb +78 -0
- data/lib/ibex/lalr/ielr/split_state.rb +20 -0
- data/lib/ibex/lalr/ielr/state_splitter.rb +258 -0
- data/lib/ibex/lalr/ielr_partition.rb +166 -0
- data/lib/ibex/lalr/inadequacy_report.rb +50 -0
- data/lib/ibex/lalr/lookahead_propagation.rb +111 -0
- data/lib/ibex/lalr/lr0_collection.rb +121 -0
- data/lib/ibex/lalr/on_error_reductions.rb +74 -0
- data/lib/ibex/lalr/unreachable_states.rb +80 -0
- data/lib/ibex/lalr.rb +59 -1
- data/lib/ibex/location.rb +129 -0
- data/lib/ibex/lsp/document_handlers.rb +68 -0
- data/lib/ibex/lsp/document_store.rb +264 -0
- data/lib/ibex/lsp/document_store_diagnostics.rb +44 -0
- data/lib/ibex/lsp/document_store_validation.rb +61 -0
- data/lib/ibex/lsp/initialization_handlers.rb +80 -0
- data/lib/ibex/lsp/navigation_handlers.rb +70 -0
- data/lib/ibex/lsp/parser_configuration_assistance.rb +149 -0
- data/lib/ibex/lsp/position_codec.rb +113 -0
- data/lib/ibex/lsp/protocol_error.rb +33 -0
- data/lib/ibex/lsp/request_handlers.rb +46 -0
- data/lib/ibex/lsp/request_support.rb +94 -0
- data/lib/ibex/lsp/server.rb +148 -0
- data/lib/ibex/lsp/symbol_index.rb +241 -0
- data/lib/ibex/lsp/symbol_index_builder.rb +277 -0
- data/lib/ibex/lsp/symbol_index_precedence_references.rb +44 -0
- data/lib/ibex/lsp/symbol_index_source_queries.rb +61 -0
- data/lib/ibex/lsp/symbol_occurrence.rb +23 -0
- data/lib/ibex/lsp/transport.rb +128 -0
- data/lib/ibex/lsp/workspace.rb +128 -0
- data/lib/ibex/lsp/workspace_analyzer.rb +199 -0
- data/lib/ibex/lsp.rb +33 -0
- data/lib/ibex/messages/en.yml +28 -0
- data/lib/ibex/messages/ja.yml +28 -0
- data/lib/ibex/messages.rb +68 -0
- data/lib/ibex/metrics.rb +175 -0
- data/lib/ibex/normalize/declarations.rb +142 -7
- data/lib/ibex/normalize/diagnostics.rb +94 -24
- data/lib/ibex/normalize/expander.rb +64 -59
- data/lib/ibex/normalize/expression.rb +63 -40
- data/lib/ibex/normalize/grammar_builder.rb +26 -0
- data/lib/ibex/normalize/inline_expansion.rb +465 -0
- data/lib/ibex/normalize/inline_validation.rb +174 -0
- data/lib/ibex/normalize/lexer.rb +131 -0
- data/lib/ibex/normalize/named_references.rb +60 -0
- data/lib/ibex/normalize/nodes.rb +46 -0
- data/lib/ibex/normalize/parameter_ebnf_lowering.rb +70 -0
- data/lib/ibex/normalize/parameter_lowering.rb +143 -0
- data/lib/ibex/normalize/parameter_substitution.rb +125 -0
- data/lib/ibex/normalize/parameter_validation.rb +140 -0
- data/lib/ibex/normalize/parameters.rb +226 -0
- data/lib/ibex/normalize/parser_configuration.rb +70 -0
- data/lib/ibex/normalize/recovery_declarations.rb +84 -0
- data/lib/ibex/normalize.rb +172 -17
- data/lib/ibex/racc_migration/checker.rb +122 -0
- data/lib/ibex/racc_migration/harness.rb +177 -0
- data/lib/ibex/racc_migration/report.rb +97 -0
- data/lib/ibex/racc_migration.rb +12 -0
- data/lib/ibex/rake_task.rb +116 -0
- data/lib/ibex/samples.rb +216 -0
- data/lib/ibex/table_artifact/builder.rb +266 -0
- data/lib/ibex/table_artifact/cst_projection.rb +70 -0
- data/lib/ibex/table_artifact/document.rb +39 -0
- data/lib/ibex/table_artifact/executor.rb +187 -0
- data/lib/ibex/table_artifact/serializer.rb +57 -0
- data/lib/ibex/table_artifact/validator/metadata.rb +179 -0
- data/lib/ibex/table_artifact/validator/support.rb +86 -0
- data/lib/ibex/table_artifact/validator/tables.rb +238 -0
- data/lib/ibex/table_artifact/validator.rb +253 -0
- data/lib/ibex/table_artifact.rb +88 -0
- data/lib/ibex/table_simulation/result.rb +55 -0
- data/lib/ibex/table_simulation/simulator.rb +253 -0
- data/lib/ibex/table_simulation/step.rb +62 -0
- data/lib/ibex/table_simulation/text.rb +31 -0
- data/lib/ibex/table_simulation.rb +13 -0
- data/lib/ibex/tables.rb +22 -69
- data/lib/ibex/verifiable_generation_bundle.rb +86 -0
- data/lib/ibex/verification_report/builder.rb +159 -0
- data/lib/ibex/verification_report/canonical_ir.rb +123 -0
- data/lib/ibex/verification_report/logical_path.rb +68 -0
- data/lib/ibex/verification_report/validator.rb +329 -0
- data/lib/ibex/verification_report.rb +69 -0
- data/lib/ibex/verify/action_correspondence.rb +138 -0
- data/lib/ibex/verify/language_witness.rb +295 -0
- data/lib/ibex/verify/reference_collection.rb +190 -0
- data/lib/ibex/verify/result.rb +73 -0
- data/lib/ibex/verify/verifier.rb +598 -0
- data/lib/ibex/verify.rb +15 -0
- data/lib/ibex/version.rb +1 -1
- data/lib/ibex/watch/runner.rb +181 -0
- data/lib/ibex/watch/source_snapshot.rb +98 -0
- data/lib/ibex/watch.rb +11 -0
- data/lib/ibex.rb +35 -1
- data/schema/automaton-ir-definitions.schema.json +401 -0
- data/schema/automaton-ir.schema.json +65 -0
- data/schema/benchmark-v1.schema.json +212 -0
- data/schema/benchmark-v2.schema.json +61 -0
- data/schema/bison-import-v1.schema.json +106 -0
- data/schema/conflict-explanation-review-v1.schema.json +196 -0
- data/schema/conflict-explanation-study-v1.schema.json +528 -0
- data/schema/construction-profile-v1.schema.json +779 -0
- data/schema/cst-v1.json +170 -0
- data/schema/diff-v1.schema.json +41 -0
- data/schema/direct-ielr-decision-v1.schema.json +200 -0
- data/schema/equiv-v1.schema.json +64 -0
- data/schema/error-ux-review-v1.schema.json +609 -0
- data/schema/error-ux-round2-review-v1.schema.json +191 -0
- data/schema/error-ux-round2-v1.schema.json +519 -0
- data/schema/error-ux-v1.schema.json +258 -0
- data/schema/explain-v1.schema.json +495 -0
- data/schema/fix-v1.schema.json +64 -0
- data/schema/fix-v2.schema.json +66 -0
- data/schema/fix-v3.schema.json +101 -0
- data/schema/frontend-diagnostics-v1.schema.json +154 -0
- data/schema/fuzz-regression-v1.schema.json +79 -0
- data/schema/fuzz-v1.schema.json +114 -0
- data/schema/generation-manifest-v1.schema.json +115 -0
- data/schema/grammar-ir-extensions.schema.json +734 -0
- data/schema/grammar-ir-foundation.schema.json +426 -0
- data/schema/grammar-ir.schema.json +271 -0
- data/schema/ielr-benchmark-v1.schema.json +85 -0
- data/schema/lexer-ir-v1.schema.json +215 -0
- data/schema/lexer-profile-v1.schema.json +491 -0
- data/schema/metrics-v1.schema.json +60 -0
- data/schema/migration-check-v1.schema.json +60 -0
- data/schema/performance-comparison-v1.schema.json +395 -0
- data/schema/public-performance-comparison-v1.schema.json +506 -0
- data/schema/public-performance-profile-v1.schema.json +360 -0
- data/schema/reduce-v1.schema.json +22 -0
- data/schema/reduce-v2.schema.json +63 -0
- data/schema/runtime-coverage-v1.schema.json +86 -0
- data/schema/runtime-event-v1.schema.json +308 -0
- data/schema/table-artifact-v1.schema.json +377 -0
- data/schema/table-simulation-v1.schema.json +70 -0
- data/schema/verification-report-v1.schema.json +222 -0
- data/schema/verify-v1.schema.json +42 -0
- data/sig/ibex/analysis/digraph.rbs +19 -0
- data/sig/ibex/artifact_set.rbs +37 -0
- data/sig/ibex/bison_import/importer.rbs +140 -0
- data/sig/ibex/bison_import/tokenizer.rbs +91 -0
- data/sig/ibex/bison_import.rbs +95 -0
- data/sig/ibex/bounded_subprocess.rbs +76 -0
- data/sig/ibex/cli/ambiguity.rbs +28 -0
- data/sig/ibex/cli/analysis.rbs +43 -0
- data/sig/ibex/cli/bison_import.rbs +32 -0
- data/sig/ibex/cli/config.rbs +35 -0
- data/sig/ibex/cli/counterexample_options.rbs +2 -0
- data/sig/ibex/cli/coverage.rbs +53 -0
- data/sig/ibex/cli/debug.rbs +28 -0
- data/sig/ibex/cli/diagnostics.rbs +51 -0
- data/sig/ibex/cli/documentation.rbs +29 -0
- data/sig/ibex/cli/equiv.rbs +49 -0
- data/sig/ibex/cli/error_messages.rbs +63 -0
- data/sig/ibex/cli/explain.rbs +31 -0
- data/sig/ibex/cli/fix.rbs +53 -0
- data/sig/ibex/cli/formatting.rbs +107 -0
- data/sig/ibex/cli/fuzz.rbs +47 -0
- data/sig/ibex/cli/fuzz_regressions.rbs +40 -0
- data/sig/ibex/cli/generation_artifacts.rbs +69 -0
- data/sig/ibex/cli/generation_error_messages.rbs +19 -0
- data/sig/ibex/cli/grammar_tests.rbs +48 -0
- data/sig/ibex/cli/ir_tools.rbs +39 -0
- data/sig/ibex/cli/lsp.rbs +14 -0
- data/sig/ibex/cli/outputs.rbs +26 -3
- data/sig/ibex/cli/racc_migration.rbs +30 -0
- data/sig/ibex/cli/reduce.rbs +60 -0
- data/sig/ibex/cli/reduce_reporting.rbs +27 -0
- data/sig/ibex/cli/samples.rbs +38 -0
- data/sig/ibex/cli/verify.rbs +28 -0
- data/sig/ibex/cli/watch.rbs +43 -0
- data/sig/ibex/cli.rbs +182 -9
- data/sig/ibex/codegen/action_locations.rbs +45 -0
- data/sig/ibex/codegen/action_method_source.rbs +65 -0
- data/sig/ibex/codegen/action_source.rbs +50 -0
- data/sig/ibex/codegen/ambiguity.rbs +60 -0
- data/sig/ibex/codegen/cst_metadata.rbs +59 -0
- data/sig/ibex/codegen/documentation.rbs +50 -0
- data/sig/ibex/codegen/explain.rbs +105 -0
- data/sig/ibex/codegen/generated_action_abi.rbs +105 -0
- data/sig/ibex/codegen/html.rbs +18 -2
- data/sig/ibex/codegen/mermaid.rbs +16 -0
- data/sig/ibex/codegen/railroad.rbs +82 -0
- data/sig/ibex/codegen/railroad_documentation.rbs +31 -0
- data/sig/ibex/codegen/rbs.rbs +86 -4
- data/sig/ibex/codegen/report.rbs +16 -8
- data/sig/ibex/codegen/ruby.rbs +105 -28
- data/sig/ibex/codegen/ruby_actions.rbs +54 -0
- data/sig/ibex/codegen/ruby_ast.rbs +34 -0
- data/sig/ibex/codegen/ruby_error_messages.rbs +16 -0
- data/sig/ibex/codegen/ruby_lexer.rbs +25 -0
- data/sig/ibex/codegen/ruby_syntax.rbs +27 -0
- data/sig/ibex/codegen/ruby_table_metadata.rbs +26 -0
- data/sig/ibex/codegen/ruby_value_printers.rbs +28 -0
- data/sig/ibex/configuration/analysis_grammar.rbs +13 -0
- data/sig/ibex/configuration/explanation.rbs +195 -0
- data/sig/ibex/configuration/inspector.rbs +53 -0
- data/sig/ibex/configuration.rbs +242 -0
- data/sig/ibex/coverage/collector.rbs +78 -0
- data/sig/ibex/coverage/event_stream.rbs +44 -0
- data/sig/ibex/coverage/report.rbs +102 -0
- data/sig/ibex/coverage/runtime_event_validator.rbs +70 -0
- data/sig/ibex/coverage.rbs +7 -0
- data/sig/ibex/delta_reducer.rbs +38 -0
- data/sig/ibex/diff.rbs +47 -0
- data/sig/ibex/equiv/machine.rbs +54 -0
- data/sig/ibex/equiv.rbs +129 -0
- data/sig/ibex/error_messages/parser.rbs +58 -0
- data/sig/ibex/error_messages/parser_v2.rbs +67 -0
- data/sig/ibex/error_messages/renderer.rbs +23 -0
- data/sig/ibex/error_messages/sentence_search.rbs +80 -0
- data/sig/ibex/error_messages/update.rbs +43 -0
- data/sig/ibex/error_messages.rbs +85 -0
- data/sig/ibex/fix.rbs +138 -0
- data/sig/ibex/frontend/ast.rbs +237 -22
- data/sig/ibex/frontend/bootstrap_parser.rbs +13 -0
- data/sig/ibex/frontend/diagnostic.rbs +53 -0
- data/sig/ibex/frontend/diagnostic_recovery.rbs +98 -0
- data/sig/ibex/frontend/dsl.rbs +33 -4
- data/sig/ibex/frontend/formatter.rbs +143 -0
- data/sig/ibex/frontend/generated_parser.rbs +228 -68
- data/sig/ibex/frontend/generated_parser_base.rbs +65 -12
- data/sig/ibex/frontend/generated_parser_includes.rbs +23 -0
- data/sig/ibex/frontend/generated_parser_metadata.rbs +23 -0
- data/sig/ibex/frontend/generated_parser_parameters.rbs +24 -0
- data/sig/ibex/frontend/generation.rbs +6 -0
- data/sig/ibex/frontend/lexer.rbs +49 -2
- data/sig/ibex/frontend/lexer_recovery.rbs +25 -0
- data/sig/ibex/frontend/parser/declarations.rbs +57 -0
- data/sig/ibex/frontend/parser/parameters.rbs +28 -0
- data/sig/ibex/frontend/parser/rules.rbs +3 -0
- data/sig/ibex/frontend/parser.rbs +66 -0
- data/sig/ibex/frontend/parser_configuration_support.rbs +27 -0
- data/sig/ibex/frontend/regenerator.rbs +11 -0
- data/sig/ibex/frontend/resolution.rbs +34 -0
- data/sig/ibex/frontend/resolver.rbs +91 -0
- data/sig/ibex/frontend/rule_documentation.rbs +42 -0
- data/sig/ibex/frontend/source_cursor.rbs +38 -5
- data/sig/ibex/frontend/source_document.rbs +119 -0
- data/sig/ibex/frontend/source_loader.rbs +66 -0
- data/sig/ibex/frontend/source_span.rbs +56 -0
- data/sig/ibex/frontend/token_adapter/declaration_document_state.rbs +21 -0
- data/sig/ibex/frontend/token_adapter/declaration_lexer_state.rbs +27 -0
- data/sig/ibex/frontend/token_adapter/declaration_state.rbs +83 -3
- data/sig/ibex/frontend/token_adapter/rule_state.rbs +20 -0
- data/sig/ibex/frontend/token_adapter.rbs +11 -2
- data/sig/ibex/frontend.rbs +1 -1
- data/sig/ibex/fuzz.rbs +71 -0
- data/sig/ibex/generation_input.rbs +37 -0
- data/sig/ibex/generation_manifest.rbs +70 -0
- data/sig/ibex/generation_transaction.rbs +82 -0
- data/sig/ibex/generation_transaction_recovery.rbs +36 -0
- data/sig/ibex/generation_transaction_validation.rbs +65 -0
- data/sig/ibex/grammar_tests.rbs +93 -0
- data/sig/ibex/ir/automaton_ir.rbs +35 -10
- data/sig/ibex/ir/grammar_ir.rbs +96 -22
- data/sig/ibex/ir/lexer_ir.rbs +57 -0
- data/sig/ibex/ir/parser_contract.rbs +69 -0
- data/sig/ibex/ir/serialize.rbs +75 -23
- data/sig/ibex/ir/validator/automaton.rbs +112 -0
- data/sig/ibex/ir/validator/base.rbs +69 -0
- data/sig/ibex/ir/validator/grammar.rbs +195 -0
- data/sig/ibex/ir/validator/lexer.rbs +37 -0
- data/sig/ibex/ir/validator.rbs +16 -0
- data/sig/ibex/ir.rbs +45 -5
- data/sig/ibex/lalr/build_metrics.rbs +60 -0
- data/sig/ibex/lalr/builder.rbs +150 -19
- data/sig/ibex/lalr/conflict_search.rbs +12 -5
- data/sig/ibex/lalr/counterexample.rbs +20 -14
- data/sig/ibex/lalr/direct_lookaheads.rbs +93 -0
- data/sig/ibex/lalr/goto_follows.rbs +89 -0
- data/sig/ibex/lalr/ielr/annotator.rbs +67 -0
- data/sig/ibex/lalr/ielr/bits.rbs +14 -0
- data/sig/ibex/lalr/ielr/inadequacy.rbs +24 -0
- data/sig/ibex/lalr/ielr/item_lookaheads.rbs +35 -0
- data/sig/ibex/lalr/ielr/pipeline.rbs +17 -0
- data/sig/ibex/lalr/ielr/split_stability.rbs +27 -0
- data/sig/ibex/lalr/ielr/split_state.rbs +14 -0
- data/sig/ibex/lalr/ielr/state_splitter.rbs +76 -0
- data/sig/ibex/lalr/ielr_partition.rbs +71 -0
- data/sig/ibex/lalr/inadequacy_report.rbs +21 -0
- data/sig/ibex/lalr/lookahead_propagation.rbs +38 -0
- data/sig/ibex/lalr/lr0_collection.rbs +50 -0
- data/sig/ibex/lalr/on_error_reductions.rbs +22 -0
- data/sig/ibex/lalr/unreachable_states.rbs +25 -0
- data/sig/ibex/lalr.rbs +17 -1
- data/sig/ibex/location.rbs +67 -0
- data/sig/ibex/lsp/document_handlers.rbs +24 -0
- data/sig/ibex/lsp/document_store.rbs +94 -0
- data/sig/ibex/lsp/document_store_diagnostics.rbs +20 -0
- data/sig/ibex/lsp/document_store_validation.rbs +26 -0
- data/sig/ibex/lsp/initialization_handlers.rbs +30 -0
- data/sig/ibex/lsp/navigation_handlers.rbs +33 -0
- data/sig/ibex/lsp/parser_configuration_assistance.rbs +49 -0
- data/sig/ibex/lsp/position_codec.rbs +44 -0
- data/sig/ibex/lsp/protocol_error.rbs +32 -0
- data/sig/ibex/lsp/request_handlers.rbs +26 -0
- data/sig/ibex/lsp/request_support.rbs +40 -0
- data/sig/ibex/lsp/server.rbs +55 -0
- data/sig/ibex/lsp/symbol_index.rbs +77 -0
- data/sig/ibex/lsp/symbol_index_builder.rbs +88 -0
- data/sig/ibex/lsp/symbol_index_precedence_references.rbs +18 -0
- data/sig/ibex/lsp/symbol_index_source_queries.rbs +26 -0
- data/sig/ibex/lsp/symbol_occurrence.rbs +31 -0
- data/sig/ibex/lsp/transport.rbs +47 -0
- data/sig/ibex/lsp/workspace.rbs +42 -0
- data/sig/ibex/lsp/workspace_analyzer.rbs +69 -0
- data/sig/ibex/lsp.rbs +7 -0
- data/sig/ibex/messages.rbs +26 -0
- data/sig/ibex/metrics.rbs +50 -0
- data/sig/ibex/normalize/declarations.rbs +31 -0
- data/sig/ibex/normalize/diagnostics.rbs +13 -4
- data/sig/ibex/normalize/expander.rbs +22 -16
- data/sig/ibex/normalize/expression.rbs +11 -9
- data/sig/ibex/normalize/grammar_builder.rbs +11 -0
- data/sig/ibex/normalize/inline_expansion.rbs +129 -0
- data/sig/ibex/normalize/inline_validation.rbs +40 -0
- data/sig/ibex/normalize/lexer.rbs +37 -0
- data/sig/ibex/normalize/named_references.rbs +20 -0
- data/sig/ibex/normalize/nodes.rbs +14 -0
- data/sig/ibex/normalize/parameter_ebnf_lowering.rbs +33 -0
- data/sig/ibex/normalize/parameter_lowering.rbs +35 -0
- data/sig/ibex/normalize/parameter_substitution.rbs +42 -0
- data/sig/ibex/normalize/parameter_validation.rbs +44 -0
- data/sig/ibex/normalize/parameters.rbs +51 -0
- data/sig/ibex/normalize/parser_configuration.rbs +23 -0
- data/sig/ibex/normalize/recovery_declarations.rbs +24 -0
- data/sig/ibex/normalize.rbs +129 -18
- data/sig/ibex/racc_migration/checker.rbs +36 -0
- data/sig/ibex/racc_migration/harness.rbs +16 -0
- data/sig/ibex/racc_migration/report.rbs +55 -0
- data/sig/ibex/racc_migration.rbs +8 -0
- data/sig/ibex/rake_task.rbs +51 -0
- data/sig/ibex/samples.rbs +60 -0
- data/sig/ibex/table_artifact/builder.rbs +93 -0
- data/sig/ibex/table_artifact/cst_projection.rbs +20 -0
- data/sig/ibex/table_artifact/document.rbs +27 -0
- data/sig/ibex/table_artifact/executor.rbs +66 -0
- data/sig/ibex/table_artifact/serializer.rbs +25 -0
- data/sig/ibex/table_artifact/validator/metadata.rbs +52 -0
- data/sig/ibex/table_artifact/validator/support.rbs +46 -0
- data/sig/ibex/table_artifact/validator/tables.rbs +63 -0
- data/sig/ibex/table_artifact/validator.rbs +66 -0
- data/sig/ibex/table_artifact.rbs +32 -0
- data/sig/ibex/table_simulation/result.rbs +36 -0
- data/sig/ibex/table_simulation/simulator.rbs +98 -0
- data/sig/ibex/table_simulation/step.rbs +42 -0
- data/sig/ibex/table_simulation/text.rbs +14 -0
- data/sig/ibex/table_simulation.rbs +7 -0
- data/sig/ibex/tables.rbs +10 -35
- data/sig/ibex/verifiable_generation_bundle.rbs +24 -0
- data/sig/ibex/verification_report/builder.rbs +53 -0
- data/sig/ibex/verification_report/canonical_ir.rbs +41 -0
- data/sig/ibex/verification_report/logical_path.rbs +34 -0
- data/sig/ibex/verification_report/validator.rbs +114 -0
- data/sig/ibex/verification_report.rbs +44 -0
- data/sig/ibex/verify/action_correspondence.rbs +50 -0
- data/sig/ibex/verify/language_witness.rbs +112 -0
- data/sig/ibex/verify/reference_collection.rbs +63 -0
- data/sig/ibex/verify/result.rbs +52 -0
- data/sig/ibex/verify/verifier.rbs +170 -0
- data/sig/ibex/verify.rbs +6 -0
- data/sig/ibex/watch/runner.rbs +58 -0
- data/sig/ibex/watch/source_snapshot.rbs +46 -0
- data/sig/ibex/watch.rbs +7 -0
- data/sig/ibex.rbs +2 -0
- metadata +524 -19
- data/.rubocop.yml +0 -43
- data/CHANGELOG.md +0 -30
- data/Rakefile +0 -25
- data/Steepfile +0 -10
- data/docs/compat-notes.md +0 -37
- data/docs/lexer-coverage.md +0 -14
- data/docs/phase10-extensions.md +0 -27
- data/gemfiles/Gemfile +0 -7
- data/gemfiles/Gemfile.lock +0 -98
- data/lib/ibex/frontend/grammar.y +0 -156
- data/lib/ibex/runtime/parser.rb +0 -360
- data/lib/ibex/runtime.rb +0 -8
- data/sig/ibex/runtime/parser.rbs +0 -167
- data/sig/ibex/runtime.rbs +0 -6
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# CST Red/Green migration
|
|
2
|
+
|
|
3
|
+
The runtime supports only the current format-v6 Red/Green representation for
|
|
4
|
+
`pragma cst`. CST parser tables from formats v1 through v5, boolean
|
|
5
|
+
`cst: true` tables without structured metadata, and all v1-v5 non-CST tables
|
|
6
|
+
fail before the first token is read and instruct the application to regenerate.
|
|
7
|
+
|
|
8
|
+
Regenerate with the same command used for the grammar, for example:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
ibex grammar.y -o parser.rb
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Upgrade the generator and runtime together, regenerate the parser, and update
|
|
15
|
+
consumers to the current APIs below. The removed `CST::Trivia`, `CST::Token`,
|
|
16
|
+
`CST::Missing`, `CST::Error`, and `CST::Node` constants are not defined.
|
|
17
|
+
|
|
18
|
+
## Parsing
|
|
19
|
+
|
|
20
|
+
Use `parse_with_syntax` when both the semantic result and syntax are needed:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
result = parser.parse_with_syntax(source, file: "input.txt")
|
|
24
|
+
value = result.value
|
|
25
|
+
root = result.syntax_root
|
|
26
|
+
diagnostics = result.diagnostics
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`parse`, `do_parse`, and `yyparse` keep returning the semantic result. After a
|
|
30
|
+
CST parse, `syntax_root` exposes the most recently built Red root.
|
|
31
|
+
|
|
32
|
+
## Changed tree shape
|
|
33
|
+
|
|
34
|
+
The new root is always `source_file`:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
source_file
|
|
38
|
+
├── selected start-symbol node
|
|
39
|
+
└── $eof
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The EOF token owns final trivia. Code that previously treated the returned CST
|
|
43
|
+
as the start node should use `result.syntax_root.children.fetch(0)`.
|
|
44
|
+
|
|
45
|
+
The legacy implementation exposed semantic values inside an actionless
|
|
46
|
+
parent. For example, an action-bearing `term` could appear as a `CST::Token`
|
|
47
|
+
whose symbol was `"term"` and whose value was the action result. Format v6
|
|
48
|
+
always exposes the physical `term` syntax node in that position. Read the
|
|
49
|
+
semantic result from `result.value`; syntax children never contain semantic
|
|
50
|
+
values.
|
|
51
|
+
|
|
52
|
+
These are the primary incompatible shapes found by the migration
|
|
53
|
+
characterization suite. `deconstruct` continues to return syntax children and
|
|
54
|
+
`deconstruct_keys` retains the compatibility keys. Typed field keys are added
|
|
55
|
+
from `@node` slot metadata.
|
|
56
|
+
|
|
57
|
+
## Removed public API mapping
|
|
58
|
+
|
|
59
|
+
The inventory below records the removed values and their format-v6
|
|
60
|
+
replacements.
|
|
61
|
+
|
|
62
|
+
| Removed value and members | Previous use | Format-v6 replacement |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `CST::Trivia#text`, `#location`, `#to_h` | leading/trailing trivia assertions | `GreenTrivia#text` and `#kind`; obtain absolute location from the owning Red token |
|
|
65
|
+
| `CST::Token#symbol`, `#value`, `#location`, `#leading_trivia` | terminal names, lexer action values, positions, skipped text | `SyntaxToken#kind_name`/`#symbol`, `#location`, and `#leading_trivia`; compatibility `#value` returns the same source bytes as `#text`, while semantic lexer values stay in the normal action/value path |
|
|
66
|
+
| `CST::Token#kind`, `#children`, `#deconstruct`, `#deconstruct_keys`, `#to_h` | error classification and pattern matching | integer `#kind`, `#error?`/`#missing?`, empty `#children`/`#deconstruct`, and compatibility pattern/hash keys |
|
|
67
|
+
| `CST::Missing` | bounded-repair insertion checks | `SyntaxToken#missing?`, `GreenToken#expected_kind`, and `CONTAINS_MISSING` |
|
|
68
|
+
| `CST::Error#reason` | lexical, syntax, delete, and discard checks | `SyntaxToken#error?`, `SyntaxNode#error?`, diagnostics, and Green error/skipped flags |
|
|
69
|
+
| `CST::Node#symbol`, `#production_id`, `#children`, `#location`, `#trailing_trivia` | root/reduction shape, source position, final trivia | `SyntaxNode#symbol`, `#children`, `#location`, and compatibility `#trailing_trivia`; `#production_id` is the `-1` sentinel because kinds/slot metadata replace occurrence-local production identity |
|
|
70
|
+
| `CST::Node#each`, `#deconstruct`, `#deconstruct_keys`, `#to_h`, `#with_trailing_trivia` | enumeration, pattern matching, final-trivia attachment | Red `Enumerable`/pattern/hash methods; persistent trivia changes use the owning token's `with_leading`/`with_trailing` |
|
|
71
|
+
|
|
72
|
+
Current pure-syntax shape and compatibility accessors are executable in
|
|
73
|
+
`test/codegen/cst_characterization_test.rb`. Rejection of obsolete CST table
|
|
74
|
+
shapes is covered by `test/runtime/table_format_test.rb` and
|
|
75
|
+
`test/codegen/cst_runtime_integration_test.rb`. The semantic-value removal is
|
|
76
|
+
the C1 change; the `source_file` root is C2.
|
|
77
|
+
|
|
78
|
+
## Trivia
|
|
79
|
+
|
|
80
|
+
`--cst-trivia=attach` remains accepted and means `leading`.
|
|
81
|
+
|
|
82
|
+
- `leading`: skipped lexer text belongs to the next token.
|
|
83
|
+
- `balanced`: text through the first newline belongs to the preceding token,
|
|
84
|
+
with the remainder leading the next token.
|
|
85
|
+
- `drop`: trivia is omitted; source-coordinate and incremental APIs raise
|
|
86
|
+
because offsets no longer correspond to the original source.
|
|
87
|
+
|
|
88
|
+
Use `to_source` for a binary-exact reconstruction. On early `yyaccept`,
|
|
89
|
+
`incomplete_input?` is true and `to_source` is the consumed prefix.
|
|
90
|
+
|
|
91
|
+
## Errors and repair
|
|
92
|
+
|
|
93
|
+
Lexical failures, yacc recovery, panic discards, and bounded repair return a
|
|
94
|
+
syntax result rather than changing the semantic action contract. Inspect
|
|
95
|
+
`diagnostics`, `contains_error?`, `each_error`, missing tokens, and Green flags
|
|
96
|
+
for skipped input. Unrecoverable input is retained under `synthetic_root`.
|
|
97
|
+
|
|
98
|
+
## New capabilities
|
|
99
|
+
|
|
100
|
+
Format v6 provides typed `Parser::Syntax` views, persistent
|
|
101
|
+
path-copy editing, annotations, structural text diffing, `ibex_cst` v1
|
|
102
|
+
serialization, and syntax-only incremental sessions. These APIs have no
|
|
103
|
+
equivalent on the removed mixed semantic/syntax tree. Batch CST, views,
|
|
104
|
+
editing, and serialization are Stable; incremental sessions remain
|
|
105
|
+
Experimental. See the [CST guide](cst.md) for examples and the incremental
|
|
106
|
+
action contract.
|
data/docs/cst.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Concrete syntax trees
|
|
3
|
+
description: Lossless Red/Green CSTs, typed views, editing, and incremental session boundaries.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Red/Green concrete syntax trees
|
|
7
|
+
|
|
8
|
+
<!-- stable:batch-cst:v1 -->
|
|
9
|
+
|
|
10
|
+
`pragma cst` generates a lossless, error-tolerant syntax tree alongside the
|
|
11
|
+
ordinary semantic result. Regenerate the parser with the current generator to
|
|
12
|
+
receive parser-table format v6 and this API. Batch parsing, typed views,
|
|
13
|
+
editing, diffing, and `ibex_cst` serialization are Stable for v1; syntax-only
|
|
14
|
+
incremental sessions are Experimental.
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
class Calculator
|
|
18
|
+
pragma cst
|
|
19
|
+
token NUM PLUS
|
|
20
|
+
lexer
|
|
21
|
+
skip /[[:space:]]+/
|
|
22
|
+
NUM /[0-9]+/ { lexeme.to_i }
|
|
23
|
+
PLUS '+'
|
|
24
|
+
end
|
|
25
|
+
rule
|
|
26
|
+
start: expression
|
|
27
|
+
expression: NUM PLUS NUM @node Addition(left, operator, right)
|
|
28
|
+
end
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Parsing and tree shape
|
|
32
|
+
|
|
33
|
+
`parse_with_syntax` runs semantic actions normally and returns both results:
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
result = Calculator.new.parse_with_syntax("1 + 2", file: "input.txt")
|
|
37
|
+
value = result.value
|
|
38
|
+
root = result.syntax_root
|
|
39
|
+
diagnostics = result.diagnostics
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This is a trusted application runtime path. Parser production actions and
|
|
43
|
+
generated lexer actions execute, and loading the generated Ruby file may run
|
|
44
|
+
`header`, `inner`, or `footer` code. `parse_with_syntax` is not a sandbox.
|
|
45
|
+
|
|
46
|
+
`parse`, `do_parse`, and `yyparse` keep their semantic return values.
|
|
47
|
+
`parser.syntax_root` exposes the most recent syntax root. Every successful root
|
|
48
|
+
has this physical shape:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
source_file
|
|
52
|
+
├── selected start-symbol node
|
|
53
|
+
└── $eof
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The immutable Green layer stores kind ids, source bytes, trivia, flags, widths,
|
|
57
|
+
and children without parents or absolute positions. It is Ractor-shareable.
|
|
58
|
+
The Red `SyntaxNode`/`SyntaxToken` layer adds lazy parent, child-index, offset,
|
|
59
|
+
span, and location navigation for one occurrence. Equal Green values can
|
|
60
|
+
therefore appear at several positions without sharing Red coordinates.
|
|
61
|
+
|
|
62
|
+
`root.to_source` reconstructs the consumed bytes exactly. Early `yyaccept`
|
|
63
|
+
marks `root.incomplete_input?` and reconstructs the consumed prefix.
|
|
64
|
+
|
|
65
|
+
## Trivia and coordinates
|
|
66
|
+
|
|
67
|
+
Select trivia ownership while generating:
|
|
68
|
+
|
|
69
|
+
- `leading` owns skipped text on the following token;
|
|
70
|
+
- `balanced` owns text through the first newline on the preceding token and
|
|
71
|
+
the remainder on the following token;
|
|
72
|
+
- `drop` omits trivia.
|
|
73
|
+
|
|
74
|
+
Pass the policy explicitly when needed:
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
ibex --cst-trivia=leading grammar.y
|
|
78
|
+
ibex --cst-trivia=balanced grammar.y
|
|
79
|
+
ibex --cst-trivia=drop grammar.y
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`attach` is accepted as an alias for `leading`. EOF owns final leading trivia.
|
|
83
|
+
`drop` trees deliberately reject span, location, and incremental APIs because
|
|
84
|
+
their offsets cannot describe the original source.
|
|
85
|
+
|
|
86
|
+
Spans are zero-based, half-open byte ranges. `SourceText#position` and
|
|
87
|
+
`#location` convert them to one-based Unicode-scalar lines and columns while
|
|
88
|
+
preserving byte offsets.
|
|
89
|
+
|
|
90
|
+
## Typed syntax views
|
|
91
|
+
|
|
92
|
+
An `@node` annotation generates a view in `Parser::Syntax` without changing the
|
|
93
|
+
physical tree:
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
addition = Calculator::Syntax::Addition.cast(
|
|
97
|
+
result.syntax_root.children.fetch(0).children.fetch(0)
|
|
98
|
+
)
|
|
99
|
+
addition.left
|
|
100
|
+
addition.operator
|
|
101
|
+
addition.right
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Accessors use normalized physical RHS slots. Lowered repetitions add element
|
|
105
|
+
enumerators; separated lists also expose separators. These views are distinct
|
|
106
|
+
from generated `Parser::AST` Data values: syntax views retain punctuation and
|
|
107
|
+
trivia, while AST values are semantic-action results.
|
|
108
|
+
|
|
109
|
+
## Errors and repair
|
|
110
|
+
|
|
111
|
+
Lexical failure, yacc recovery, panic discard, and bounded repair all produce a
|
|
112
|
+
tree. Inspect `diagnostics`, `contains_error?`, error nodes, missing tokens, and
|
|
113
|
+
Green flags. Inserted tokens are zero-width `missing_token` values. Discarded
|
|
114
|
+
input remains under error nodes or `skipped_tokens` trivia. An unrecoverable
|
|
115
|
+
parse uses `synthetic_root`.
|
|
116
|
+
|
|
117
|
+
## Persistent editing and diffing
|
|
118
|
+
|
|
119
|
+
Editing returns a new Red root and path-copies only changed ancestors:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
old_root = result.syntax_root
|
|
123
|
+
first = old_root.first_token
|
|
124
|
+
new_root = first.with_text("10")
|
|
125
|
+
edits = Ibex::Runtime::CST::Diff.text_edits(old_root, new_root)
|
|
126
|
+
new_source = old_root.source_text.apply(edits)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Nodes support `replace_with`, `with_child`, `insert_child`, and `remove_child`.
|
|
130
|
+
Tokens support `replace_with`, `with_text`, `with_leading`, and
|
|
131
|
+
`with_trailing`. `SyntaxRewriter` performs bottom-up kind dispatch;
|
|
132
|
+
`SyntaxEditor` applies several occurrence-addressed replacements in one pass.
|
|
133
|
+
`SyntaxAnnotation` marks one occurrence and excludes annotated Green values
|
|
134
|
+
from interning.
|
|
135
|
+
|
|
136
|
+
## Incremental syntax sessions
|
|
137
|
+
|
|
138
|
+
Incremental parsing is Experimental and deliberately syntax-only:
|
|
139
|
+
|
|
140
|
+
```ruby
|
|
141
|
+
source = Ibex::Runtime::CST::SourceText.new("1 + 2", file: "input.txt")
|
|
142
|
+
session = Calculator.incremental_session(source)
|
|
143
|
+
result = session.edit([
|
|
144
|
+
Ibex::Runtime::CST::TextEdit.new(
|
|
145
|
+
start: 4,
|
|
146
|
+
delete_length: 1,
|
|
147
|
+
insert_text: "3"
|
|
148
|
+
)
|
|
149
|
+
])
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The initial parse and every edit suppress parser production actions.
|
|
153
|
+
`SyntaxResult` therefore has `syntax_root`, `diagnostics`, and `reused_ratio`,
|
|
154
|
+
but no semantic value. Generated lexer actions still run because they define
|
|
155
|
+
token emission and lexer-state changes. Run a normal parse separately when a
|
|
156
|
+
semantic value or side effect is required.
|
|
157
|
+
|
|
158
|
+
Consequently, `parse_syntax` and `incremental_session` are syntax-only but not
|
|
159
|
+
"no user code" APIs. Loading the generated class may execute user sections,
|
|
160
|
+
and lexer actions may perform arbitrary Ruby side effects. Treat the generated
|
|
161
|
+
class as trusted application code. A future nonexecuting syntax profile would
|
|
162
|
+
require a declarative built-in-only lexer and no `header`, `inner`, or `footer`
|
|
163
|
+
sections; the current API does not provide that profile.
|
|
164
|
+
|
|
165
|
+
Sessions require `SourceText`, a generated lexer, format-v6 CST metadata, and
|
|
166
|
+
non-`drop` trivia. Handwritten token sources and push input are unsupported.
|
|
167
|
+
Parser actions that alone switch lexer state are also unavailable because the
|
|
168
|
+
syntax-only contract forbids executing them.
|
|
169
|
+
|
|
170
|
+
The default Stage B path relexes soundly from the beginning, validates old
|
|
171
|
+
token boundaries/states, and directly reuses only subtrees whose LR state,
|
|
172
|
+
follow token, flags, width, and damage range are safe. Pass `blender: false` to
|
|
173
|
+
retain the Stage A full LR drive. `ResourceLimits` bounds decomposition and
|
|
174
|
+
memo bytes; a bound failure deterministically falls back to the fresh token
|
|
175
|
+
stream. Observe `cst_built`, `cst_reuse`, and `cst_fallback` runtime events for
|
|
176
|
+
metrics.
|
|
177
|
+
|
|
178
|
+
Applications that need an explicit generated-language service boundary can use
|
|
179
|
+
the Experimental [`syntax_session` façade](syntax-sessions.md). It adds
|
|
180
|
+
trust-profile acknowledgement, immutable operation snapshots, expected tokens,
|
|
181
|
+
reuse/fallback metrics, cancellation, and service resource bounds while using
|
|
182
|
+
this same incremental engine. It does not add LSP or workspace semantics.
|
|
183
|
+
|
|
184
|
+
## Serialization
|
|
185
|
+
|
|
186
|
+
`ibex_cst` schema v1 is independent from Grammar IR:
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
tables = Calculator.parser_tables
|
|
190
|
+
json = Ibex::Runtime::CST::Serialize.dump(
|
|
191
|
+
session.result.syntax_root,
|
|
192
|
+
grammar_digest: tables.fetch(:grammar_digest),
|
|
193
|
+
table_format: tables.fetch(:format_version),
|
|
194
|
+
state_count: tables.fetch(:state_count),
|
|
195
|
+
production_count: tables.fetch(:production_count),
|
|
196
|
+
memo: session.parse_memo
|
|
197
|
+
)
|
|
198
|
+
loaded = Ibex::Runtime::CST::Serialize.load(
|
|
199
|
+
json,
|
|
200
|
+
grammar_digest: tables.fetch(:grammar_digest),
|
|
201
|
+
state_count: tables.fetch(:state_count),
|
|
202
|
+
production_count: tables.fetch(:production_count)
|
|
203
|
+
)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Valid UTF-8 bytes use JSON strings; other bytes use canonical Base64 objects.
|
|
207
|
+
Loading rebuilds widths, aggregate flags, and descendant counts. A grammar
|
|
208
|
+
digest mismatch raises `ValidationError`. State or production count mismatch
|
|
209
|
+
silently discards only the optional parse memo. Annotations are session-local
|
|
210
|
+
and cannot be serialized.
|
|
211
|
+
|
|
212
|
+
## Invariants and test coverage
|
|
213
|
+
|
|
214
|
+
The Red/Green contract is continuously exercised by the following repository
|
|
215
|
+
tests:
|
|
216
|
+
|
|
217
|
+
| Invariant | Automated evidence |
|
|
218
|
+
| --- | --- |
|
|
219
|
+
| I1 consumed-input fidelity | `test/runtime/cst_fidelity_property_test.rb` is PT1 over random grammars and valid, lexical-error, recovery, repair, and early-accept inputs; `test/fixtures/cst/runtime-paths-v1.json` fixes every error/trivia path, including long unmatched remainders and repair deletion. |
|
|
220
|
+
| I2 Green purity | `test/runtime/cst_green_test.rb` checks derived-only immutable state and Ractor shareability; `test/codegen/cst_characterization_test.rb` keeps semantic values outside syntax children. |
|
|
221
|
+
| I3 lazy Red navigation | `test/runtime/cst_red_test.rb` checks occurrence-local memoization, offsets, parents, cursors, and deterministic traversal. |
|
|
222
|
+
| I4 determinism | PT3 in `test/runtime/cst_green_test.rb` compares cache-on/off structure, source, and dump; PT6 in `test/runtime/cst_serialize_test.rb` checks byte-stable dump/load/dump; generated Ruby and RBS have golden tests. |
|
|
223
|
+
| I5 unchanged action contract | `test/codegen/cst_contract_test.rb` compares CST/no-CST `parse`, `do_parse`, `yyparse`, hooks, observer order, and non-CST table shape; characterization and obsolete-CST-table rejection regressions remain active. |
|
|
224
|
+
| I6 sharing boundary | PT5 in `test/runtime/cst_green_test.rb` checks Green shareability and concurrent Ractor reads; editing and parser-table tests keep Red/session state occurrence-owned. |
|
|
225
|
+
| I7 versioned contracts | `test/runtime/cst_serialize_test.rb`, `test/runtime/table_format_test.rb`, and `test/packaging/schema_files_test.rb` cover schema validation, memo compatibility, old table readers, and schema packaging. |
|
|
226
|
+
| I8 type soundness | CI regenerates the `sig/` tree, runs Steep and RBS validation, and rejects a type-statistics regression. |
|
|
227
|
+
|
|
228
|
+
`test/runtime/cst_incremental_property_test.rb` is the large PT2 authority. Its
|
|
229
|
+
fixed seed generates four grammar shapes and executes 20,000 random edits
|
|
230
|
+
through Stage A plus 20,000 through Stage B, comparing fresh syntax sessions in
|
|
231
|
+
Green structure, bytes, flags, diagnostics, and memo cardinality after every
|
|
232
|
+
edit. `test/runtime/cst_incremental_test.rb` adds focused stateful-lexer,
|
|
233
|
+
fallback, sharing, minimal-diff, action-suppression, no-value, and unsupported
|
|
234
|
+
configuration cases.
|
|
235
|
+
|
|
236
|
+
See [the migration guide](cst-migration.md) for removed tree-shape changes and
|
|
237
|
+
[the stability policy](stability.md) for support levels.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# ADR NNNN: Implementation decision title
|
|
2
|
+
|
|
3
|
+
- Status: Proposed
|
|
4
|
+
- Date: YYYY-MM-DD
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Describe the concrete implementation question and its compatibility, data,
|
|
9
|
+
runtime, or component constraints. Operational workflow and release policy do
|
|
10
|
+
not belong in this directory; see [the scope](README.md).
|
|
11
|
+
|
|
12
|
+
Name the credible alternatives. If there was no meaningful alternative, record
|
|
13
|
+
the behavior in reference documentation instead of creating an ADR.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
Describe the durable boundary or architecture choice. Leave command syntax,
|
|
18
|
+
field-by-field formats, test evidence, benchmark results, and migration steps
|
|
19
|
+
in their authoritative documents.
|
|
20
|
+
|
|
21
|
+
## Consequences
|
|
22
|
+
|
|
23
|
+
Describe the important positive and negative trade-offs, including what would
|
|
24
|
+
make this decision worth revisiting.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# ADR 0001: Separate pipeline stages with current IR
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Frontend parsing, normalization, automaton construction, and code generation
|
|
9
|
+
must be independently testable and resumable. Passing frontend objects between
|
|
10
|
+
all stages would couple later stages to source syntax and make serialized
|
|
11
|
+
artifacts ambiguous.
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
|
|
15
|
+
Normalization produces immutable Grammar IR. Parser construction consumes
|
|
16
|
+
Grammar IR and produces immutable Automaton IR. Automaton IR embeds the Grammar
|
|
17
|
+
IR required to resume code generation; later stages do not reach back into
|
|
18
|
+
frontend AST objects.
|
|
19
|
+
|
|
20
|
+
Both IRs have deterministic JSON encodings and shipped closed schemas. Their
|
|
21
|
+
current schema contract is explicit and validated. Untrusted JSON crosses a
|
|
22
|
+
validator that checks both shape and cross-record references before constructing
|
|
23
|
+
Ruby objects. A pre-v1 change that alters the meaning or required shape is
|
|
24
|
+
coordinated across writers, readers, schemas, fixtures, and downstream
|
|
25
|
+
consumers; no legacy reader is retained solely to preserve an obsolete format.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Source, resumed Grammar IR, and resumed Automaton IR use the same downstream
|
|
30
|
+
implementations.
|
|
31
|
+
- Incompatibility is detected at the document boundary rather than deep in
|
|
32
|
+
generation.
|
|
33
|
+
- Presentation views and operational reports are not additional IRs unless
|
|
34
|
+
another tool must consume them as durable data.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# ADR 0002: Keep grammar-embedded Ruby opaque until code generation
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Semantic actions and user-code sections contain Ruby constructs whose braces,
|
|
9
|
+
quotes, regular expressions, interpolation, and heredocs overlap grammar
|
|
10
|
+
delimiters. Parsing Ruby in the grammar frontend would add a second language
|
|
11
|
+
implementation and would still not validate parser-local bindings correctly.
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
|
|
15
|
+
The grammar lexer delegates action bodies to a balanced source scanner. That
|
|
16
|
+
scanner recognizes only the Ruby lexical structure needed to find the matching
|
|
17
|
+
grammar boundary and preserves the original bytes and source location.
|
|
18
|
+
User-code sections are likewise retained as ordered opaque chunks.
|
|
19
|
+
|
|
20
|
+
The frontend, normalizer, IR tools, reports, and static analysis never evaluate
|
|
21
|
+
or rewrite the opaque body. Ruby compilation occurs only when generated parser
|
|
22
|
+
methods are loaded. Tools that promise not to execute application code must
|
|
23
|
+
operate entirely before that boundary.
|
|
24
|
+
|
|
25
|
+
## Consequences
|
|
26
|
+
|
|
27
|
+
- Grammar parsing is independent of a Ruby parser and preserves exact user
|
|
28
|
+
source for mapping and generation.
|
|
29
|
+
- The balanced scanner has an explicit lexical coverage obligation; unsupported
|
|
30
|
+
Ruby syntax must fail instead of being silently truncated.
|
|
31
|
+
- Features that need meaning from an action must use conservative lexical
|
|
32
|
+
evidence or decline the optimization.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# ADR 0003: Self-host the grammar parser behind an explicit bootstrap
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Keeping grammar syntax in a handwritten parser makes the generator unable to
|
|
9
|
+
exercise its own parser pipeline. Direct self-hosting creates a cycle because
|
|
10
|
+
the generated grammar parser is needed to regenerate itself.
|
|
11
|
+
|
|
12
|
+
## Decision
|
|
13
|
+
|
|
14
|
+
`lib/ibex/frontend/grammar.y` is the canonical grammar syntax. Its generated
|
|
15
|
+
parser is committed and is the normal frontend implementation. A specialized
|
|
16
|
+
lexer remains outside that grammar because opaque Ruby scanning and source
|
|
17
|
+
locations are lexical responsibilities.
|
|
18
|
+
|
|
19
|
+
An explicitly named bootstrap parser exists only to regenerate the committed
|
|
20
|
+
parser when that parser is absent. The regeneration path loads the minimum
|
|
21
|
+
frontend and generation components directly and does not load the normal
|
|
22
|
+
generated frontend. Normal library loading does not use the bootstrap.
|
|
23
|
+
|
|
24
|
+
No racc implementation or racc-generated source participates in bootstrap or
|
|
25
|
+
normal execution.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Ordinary grammar parsing continuously exercises Ibex-generated code.
|
|
30
|
+
- Grammar syntax changes must keep the canonical grammar, bootstrap capability,
|
|
31
|
+
and generated parser deterministic and mutually consistent.
|
|
32
|
+
- The bootstrap is recovery infrastructure, not a second supported frontend.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# ADR 0004: Derive semantic and lossless source views from one lexing pass
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Generation needs a semantic AST, while formatting, diagnostics, documentation,
|
|
9
|
+
and editor features need comments, trivia, opaque bodies, and exact byte
|
|
10
|
+
ranges. Re-lexing independently for each tool can disagree with the token
|
|
11
|
+
stream that defined grammar meaning.
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
|
|
15
|
+
One frontend lexing pass produces semantic tokens and immutable lossless
|
|
16
|
+
segments over the same UTF-8 source. A source document correlates those views
|
|
17
|
+
with half-open byte spans and reproduces the accepted input exactly. The
|
|
18
|
+
self-hosted parser remains the authority for the semantic AST.
|
|
19
|
+
|
|
20
|
+
Recovering diagnostics are bounded and may expose a clearly marked partial AST,
|
|
21
|
+
but never attach that projection to the unchanged source as if it were a
|
|
22
|
+
complete parse. Formatting changes trivia only, then reparses and rejects any
|
|
23
|
+
semantic difference. Filesystem and unsaved-buffer access are supplied through
|
|
24
|
+
an injected source loader; the parser itself performs no I/O.
|
|
25
|
+
|
|
26
|
+
## Consequences
|
|
27
|
+
|
|
28
|
+
- Formatter, documentation, resolver, and LSP features share one interpretation
|
|
29
|
+
of tokens, opaque Ruby, locations, and source bytes.
|
|
30
|
+
- Exact byte coordinates remain distinct from editor-specific coordinate
|
|
31
|
+
encodings such as UTF-16.
|
|
32
|
+
- Error recovery and overlays are tool boundaries around the strict parser,
|
|
33
|
+
not alternative grammar semantics.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# ADR 0005: Resolve grammar composition in a contained filesystem boundary
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Composing grammar fragments introduces file identity, traversal order, cycles,
|
|
9
|
+
diamonds, source provenance, and symlink escape. Textual concatenation loses
|
|
10
|
+
those properties and makes programmatic source parsing perform implicit I/O.
|
|
11
|
+
|
|
12
|
+
## Decision
|
|
13
|
+
|
|
14
|
+
Root and fragment files have distinct syntax and ownership. Parsing records
|
|
15
|
+
`import` nodes without reading their targets. A resolver is the sole filesystem
|
|
16
|
+
boundary and returns one immutable resolution containing the merged AST,
|
|
17
|
+
canonical dependency closure, and include provenance.
|
|
18
|
+
|
|
19
|
+
Canonical real paths define identity. Imports are resolved in deterministic
|
|
20
|
+
depth-first order, a completed canonical file is merged once, and cycles are
|
|
21
|
+
reported by canonical path. Targets must remain below the canonical root
|
|
22
|
+
directory after symlink resolution; absolute paths, parent traversal, and
|
|
23
|
+
ambiguous path forms are rejected.
|
|
24
|
+
|
|
25
|
+
Every CLI and build integration that accepts a grammar path uses this resolver.
|
|
26
|
+
Programmatic source-string parsing must opt into it explicitly.
|
|
27
|
+
|
|
28
|
+
## Consequences
|
|
29
|
+
|
|
30
|
+
- All consumers observe the same merge order and dependency closure.
|
|
31
|
+
- Diamonds are deterministic and symlink aliases cannot hide a cycle or escape
|
|
32
|
+
the root.
|
|
33
|
+
- Composition is intentionally a flat merge; namespaces and re-export policy
|
|
34
|
+
require a separate design.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# ADR 0006: Lower grammar extensions structurally and under explicit bounds
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
EBNF, parameterized rules, and inline rules can be represented as textual
|
|
9
|
+
macros, frontend-only closures, or structural transformations. Textual
|
|
10
|
+
expansion loses locations and can capture names; unbounded recursive expansion
|
|
11
|
+
can exhaust the Ruby stack or memory.
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
|
|
15
|
+
The frontend represents extensions as AST structure. Normalization lowers them
|
|
16
|
+
into ordinary symbols, productions, and serializable action-composition plans
|
|
17
|
+
before automaton construction. Synthetic names cannot collide with source
|
|
18
|
+
identifiers, and generated productions retain source and expansion provenance.
|
|
19
|
+
|
|
20
|
+
Parameterized specializations are memoized by structural arguments. Recursive
|
|
21
|
+
work uses explicit worklists, rejects structurally growing cycles, and has a
|
|
22
|
+
total specialization bound. Inline substitution rejects recursive dependency
|
|
23
|
+
cycles and has a separate materialization bound for alternative products.
|
|
24
|
+
Opaque action fragments remain ordered data in Grammar IR rather than
|
|
25
|
+
generator-only closures.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Every parser-construction algorithm consumes the same lowered Grammar IR.
|
|
30
|
+
- Resumed IR preserves extension semantics and source mapping.
|
|
31
|
+
- Some theoretically finite expansions may be rejected by conservative cycle
|
|
32
|
+
or resource bounds; callers can raise size bounds deliberately.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# ADR 0007: Share one downstream pipeline across parser algorithms
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
SLR, LALR, IELR, and canonical LR(1) differ in state construction and
|
|
9
|
+
lookahead precision. Separate conflict resolution, table generation, or code
|
|
10
|
+
generation paths would make algorithm selection change more than the automaton.
|
|
11
|
+
|
|
12
|
+
## Decision
|
|
13
|
+
|
|
14
|
+
All algorithms consume Grammar IR and produce the same Automaton IR contract.
|
|
15
|
+
They share action candidate construction, conflict resolution, default-action
|
|
16
|
+
selection, reporting, table generation, and code generation.
|
|
17
|
+
|
|
18
|
+
LALR is the default and computes lookaheads directly over deterministic LR(0)
|
|
19
|
+
item occurrences. SLR uses the same LR(0) collection with FOLLOW sets.
|
|
20
|
+
Canonical LR(1) retains distinct contexts. IELR conservatively merges
|
|
21
|
+
compatible canonical states and prefers extra states whenever equivalence is
|
|
22
|
+
uncertain; it does not claim a minimum state count.
|
|
23
|
+
|
|
24
|
+
Reference strategies may remain for equivalence testing, but they are not
|
|
25
|
+
additional public algorithm identities when their output contract is the same.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Algorithm choice changes automaton precision without changing downstream
|
|
30
|
+
semantics or generated APIs.
|
|
31
|
+
- LALR avoids canonical state explosion in the default path.
|
|
32
|
+
- IELR can avoid LALR merge inadequacies but may pay canonical construction
|
|
33
|
+
cost and retain more states than a lane-tracing implementation.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# ADR 0008: Separate the runtime behind a versioned parser-table ABI
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Applications executing a generated parser do not need the grammar frontend or
|
|
9
|
+
generator. Independently installed generated code and runtime code still need a
|
|
10
|
+
precise compatibility boundary; otherwise a table-shape change can fail or be
|
|
11
|
+
misinterpreted during a parse.
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
|
|
15
|
+
The dependency-free parser runtime ships as `ibex-runtime`; the generator
|
|
16
|
+
depends on it but runtime deployments do not depend on generator code. Normal
|
|
17
|
+
generated parsers require the runtime package, while embedded output carries
|
|
18
|
+
the same runtime implementation.
|
|
19
|
+
|
|
20
|
+
Every generated table declares a parser-table format version. The runtime
|
|
21
|
+
validates the version and marker combinations before consuming input. Changes
|
|
22
|
+
to required shape, action calling convention, or table meaning increment that
|
|
23
|
+
version.
|
|
24
|
+
|
|
25
|
+
Plain and compact tables are two encodings of the same lookup contract.
|
|
26
|
+
Compression may change representation only when every declared and unknown
|
|
27
|
+
token retains the same shift, reduce, accept, or error result. In particular,
|
|
28
|
+
explicit error cells must mask default reductions.
|
|
29
|
+
|
|
30
|
+
## Consequences
|
|
31
|
+
|
|
32
|
+
- Generator and runtime packaging can evolve independently within the declared
|
|
33
|
+
dependency and table-format contracts.
|
|
34
|
+
- Unsupported generated parsers fail before lexer or semantic side effects.
|
|
35
|
+
- Compact representation remains replaceable and optimizable without becoming
|
|
36
|
+
a second parser semantics.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# ADR 0009: Isolate mutable parser sessions from immutable parser data
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Date: 2026-07-28
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Generated tables are immutable program data, while LR stacks, lexer state,
|
|
9
|
+
lookahead, recovery state, observers, and incremental caches are per parse.
|
|
10
|
+
Supporting pull, yielding, and push input through separate engines would make
|
|
11
|
+
their recovery and callback behavior drift.
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
|
|
15
|
+
Generated parser classes own recursively frozen tables. Each parser instance
|
|
16
|
+
owns one mutable session and permits only one active driver. Pull, yielding, and
|
|
17
|
+
push APIs feed the same LR transition and recovery machinery; nested or mixed
|
|
18
|
+
drivers fail before mutating state.
|
|
19
|
+
|
|
20
|
+
State, semantic value, optional location, and optional Green stacks remain
|
|
21
|
+
index-aligned. Capabilities allocate their parallel state only when the
|
|
22
|
+
generated grammar or runtime tooling requires it.
|
|
23
|
+
|
|
24
|
+
Per-instance resource limits bound stack growth, recovery attempts, and other
|
|
25
|
+
session-owned search or memo structures. Exceeding a bound produces a
|
|
26
|
+
structured failure rather than unbounded work. Sharing a parser instance or
|
|
27
|
+
its application callbacks across concurrent parses is outside the contract.
|
|
28
|
+
|
|
29
|
+
## Consequences
|
|
30
|
+
|
|
31
|
+
- Parser classes and eligible table graphs can be shared while sessions remain
|
|
32
|
+
independently mutable.
|
|
33
|
+
- All input lifecycles preserve one action, recovery, and callback ordering.
|
|
34
|
+
- Applications choose stricter or larger limits without regenerating tables.
|