ibex 0.2.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 +95 -272
- data/docs/architecture.md +187 -35
- 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 +3 -4
- data/docs/cst.md +24 -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 +179 -2
- data/docs/direct-ielr-decision.md +120 -0
- data/docs/direct-multi-entry-decision.md +82 -0
- data/docs/editor-setup.md +2 -1
- 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 +54 -0
- data/docs/getting-started.md +80 -0
- data/docs/grammar-reference.md +184 -13
- 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 +5 -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 +11 -0
- data/docs/release-readiness.md +126 -68
- data/docs/repair-semantics.md +123 -0
- data/docs/runtime-abi-evolution.md +307 -0
- data/docs/stability.md +144 -34
- 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/lib/ibex/analysis/digraph.rb +128 -0
- data/lib/ibex/analysis.rb +1 -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 +14 -5
- 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/diagnostics.rb +31 -11
- data/lib/ibex/cli/documentation.rb +11 -8
- data/lib/ibex/cli/equiv.rb +169 -0
- data/lib/ibex/cli/error_messages.rb +11 -4
- data/lib/ibex/cli/explain.rb +14 -5
- data/lib/ibex/cli/fix.rb +203 -0
- data/lib/ibex/cli/formatting.rb +11 -10
- data/lib/ibex/cli/fuzz.rb +200 -0
- data/lib/ibex/cli/fuzz_regressions.rb +145 -0
- data/lib/ibex/cli/generation_artifacts.rb +53 -2
- data/lib/ibex/cli/generation_error_messages.rb +1 -1
- data/lib/ibex/cli/grammar_tests.rb +32 -14
- data/lib/ibex/cli/ir_tools.rb +5 -61
- data/lib/ibex/cli/outputs.rb +60 -33
- data/lib/ibex/cli/reduce.rb +202 -0
- data/lib/ibex/cli/reduce_reporting.rb +71 -0
- data/lib/ibex/cli/samples.rb +49 -23
- data/lib/ibex/cli/verify.rb +116 -0
- data/lib/ibex/cli/watch.rb +6 -5
- data/lib/ibex/cli.rb +357 -56
- data/lib/ibex/codegen/action_locations.rb +1 -1
- data/lib/ibex/codegen/action_method_source.rb +5 -6
- data/lib/ibex/codegen/action_source.rb +3 -2
- data/lib/ibex/codegen/ambiguity.rb +5 -4
- data/lib/ibex/codegen/explain.rb +123 -55
- data/lib/ibex/codegen/generated_action_abi.rb +10 -5
- data/lib/ibex/codegen/rbs.rb +15 -7
- data/lib/ibex/codegen/report.rb +25 -13
- data/lib/ibex/codegen/ruby.rb +28 -64
- data/lib/ibex/codegen/ruby_actions.rb +9 -6
- data/lib/ibex/codegen/ruby_syntax.rb +15 -9
- 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 +21 -11
- data/lib/ibex/coverage/event_stream.rb +13 -7
- data/lib/ibex/coverage/report.rb +26 -18
- data/lib/ibex/coverage/runtime_event_validator.rb +30 -21
- 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/fix.rb +557 -0
- data/lib/ibex/frontend/ast.rb +22 -2
- data/lib/ibex/frontend/bootstrap_parser.rb +6 -13
- data/lib/ibex/frontend/diagnostic.rb +1 -1
- data/lib/ibex/frontend/formatter.rb +72 -26
- data/lib/ibex/frontend/generated_parser.rb +147 -117
- data/lib/ibex/frontend/generated_parser_base.rb +7 -3
- data/lib/ibex/frontend/generated_parser_includes.rb +1 -11
- data/lib/ibex/frontend/generation.rb +1 -1
- data/lib/ibex/frontend/parser/declarations.rb +17 -2
- data/lib/ibex/frontend/parser_configuration_support.rb +56 -0
- data/lib/ibex/frontend/regenerator.rb +1 -0
- data/lib/ibex/frontend/resolution.rb +2 -1
- data/lib/ibex/frontend/resolver.rb +1 -1
- data/lib/ibex/frontend/rule_documentation.rb +2 -1
- data/lib/ibex/frontend/source_cursor.rb +2 -2
- data/lib/ibex/frontend/source_span.rb +9 -1
- data/lib/ibex/frontend/token_adapter/declaration_state.rb +38 -6
- data/lib/ibex/frontend/token_adapter.rb +10 -0
- data/lib/ibex/frontend.rb +1 -0
- data/lib/ibex/fuzz.rb +219 -0
- data/lib/ibex/generation_input.rb +1 -1
- data/lib/ibex/generation_manifest.rb +36 -25
- data/lib/ibex/generation_transaction.rb +1 -1
- data/lib/ibex/generation_transaction_recovery.rb +4 -4
- data/lib/ibex/generation_transaction_validation.rb +2 -2
- data/lib/ibex/grammar_tests.rb +1 -1
- data/lib/ibex/ir/automaton_ir.rb +61 -19
- data/lib/ibex/ir/grammar_ir.rb +76 -45
- data/lib/ibex/ir/lexer_ir.rb +5 -5
- data/lib/ibex/ir/parser_contract.rb +135 -0
- data/lib/ibex/ir/serialize.rb +203 -76
- data/lib/ibex/ir/validator/automaton.rb +64 -34
- data/lib/ibex/ir/validator/base.rb +51 -33
- data/lib/ibex/ir/validator/grammar.rb +113 -83
- data/lib/ibex/ir/validator/lexer.rb +2 -2
- data/lib/ibex/ir/validator.rb +2 -1
- data/lib/ibex/ir.rb +16 -3
- data/lib/ibex/lalr/build_metrics.rb +50 -2
- data/lib/ibex/lalr/builder.rb +191 -56
- data/lib/ibex/lalr/conflict_search.rb +15 -4
- data/lib/ibex/lalr/counterexample.rb +19 -14
- data/lib/ibex/lalr/direct_lookaheads.rb +110 -57
- 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 +22 -8
- 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/unreachable_states.rb +80 -0
- data/lib/ibex/lalr.rb +52 -1
- data/lib/ibex/location.rb +3 -3
- data/lib/ibex/lsp/document_handlers.rb +9 -7
- data/lib/ibex/lsp/initialization_handlers.rb +9 -7
- data/lib/ibex/lsp/navigation_handlers.rb +25 -11
- data/lib/ibex/lsp/parser_configuration_assistance.rb +149 -0
- data/lib/ibex/lsp/position_codec.rb +6 -2
- data/lib/ibex/lsp/request_handlers.rb +3 -2
- data/lib/ibex/lsp/request_support.rb +14 -7
- data/lib/ibex/lsp/server.rb +13 -11
- data/lib/ibex/lsp/symbol_index.rb +13 -13
- data/lib/ibex/lsp/symbol_index_builder.rb +30 -20
- data/lib/ibex/lsp/symbol_occurrence.rb +8 -2
- data/lib/ibex/lsp/transport.rb +13 -3
- data/lib/ibex/lsp/workspace.rb +5 -4
- data/lib/ibex/lsp/workspace_analyzer.rb +1 -1
- data/lib/ibex/lsp.rb +1 -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 +2 -0
- data/lib/ibex/normalize/diagnostics.rb +63 -38
- data/lib/ibex/normalize/expander.rb +5 -4
- data/lib/ibex/normalize/expression.rb +8 -6
- data/lib/ibex/normalize/grammar_builder.rb +26 -0
- data/lib/ibex/normalize/inline_expansion.rb +100 -49
- data/lib/ibex/normalize/lexer.rb +3 -3
- data/lib/ibex/normalize/parameter_ebnf_lowering.rb +11 -10
- data/lib/ibex/normalize/parameter_lowering.rb +40 -23
- data/lib/ibex/normalize/parameters.rb +31 -4
- data/lib/ibex/normalize/parser_configuration.rb +70 -0
- data/lib/ibex/normalize.rb +10 -20
- data/lib/ibex/racc_migration/report.rb +6 -3
- data/lib/ibex/rake_task.rb +1 -1
- data/lib/ibex/samples.rb +43 -13
- 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 +6 -2
- data/lib/ibex/table_simulation/step.rb +3 -1
- data/lib/ibex/tables.rb +14 -0
- 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 +10 -1
- data/lib/ibex/watch/source_snapshot.rb +13 -8
- data/lib/ibex.rb +10 -0
- data/schema/{automaton-ir-v1.schema.json → automaton-ir-definitions.schema.json} +6 -6
- data/schema/{automaton-ir-v2.schema.json → automaton-ir.schema.json} +14 -7
- 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/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/explain-v1.schema.json +63 -1
- 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/fuzz-regression-v1.schema.json +79 -0
- data/schema/fuzz-v1.schema.json +114 -0
- data/schema/{grammar-ir-v2.schema.json → grammar-ir-extensions.schema.json} +20 -65
- data/schema/{grammar-ir-v1.schema.json → grammar-ir-foundation.schema.json} +3 -3
- data/schema/grammar-ir.schema.json +271 -0
- data/schema/ielr-benchmark-v1.schema.json +85 -0
- data/schema/lexer-profile-v1.schema.json +491 -0
- data/schema/metrics-v1.schema.json +60 -0
- data/schema/reduce-v1.schema.json +22 -0
- data/schema/reduce-v2.schema.json +63 -0
- data/schema/table-artifact-v1.schema.json +377 -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/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 +6 -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/diagnostics.rbs +16 -3
- data/sig/ibex/cli/documentation.rbs +5 -1
- data/sig/ibex/cli/equiv.rbs +49 -0
- data/sig/ibex/cli/error_messages.rbs +6 -0
- data/sig/ibex/cli/explain.rbs +6 -0
- data/sig/ibex/cli/fix.rbs +53 -0
- data/sig/ibex/cli/formatting.rbs +5 -1
- data/sig/ibex/cli/fuzz.rbs +47 -0
- data/sig/ibex/cli/fuzz_regressions.rbs +40 -0
- data/sig/ibex/cli/generation_artifacts.rbs +21 -2
- data/sig/ibex/cli/generation_error_messages.rbs +2 -2
- data/sig/ibex/cli/grammar_tests.rbs +15 -3
- data/sig/ibex/cli/ir_tools.rbs +7 -19
- data/sig/ibex/cli/outputs.rbs +9 -3
- data/sig/ibex/cli/reduce.rbs +60 -0
- data/sig/ibex/cli/reduce_reporting.rbs +27 -0
- data/sig/ibex/cli/samples.rbs +8 -0
- data/sig/ibex/cli/verify.rbs +28 -0
- data/sig/ibex/cli/watch.rbs +2 -2
- data/sig/ibex/cli.rbs +79 -5
- data/sig/ibex/codegen/action_method_source.rbs +4 -4
- data/sig/ibex/codegen/explain.rbs +45 -25
- data/sig/ibex/codegen/generated_action_abi.rbs +14 -10
- data/sig/ibex/codegen/rbs.rbs +12 -10
- data/sig/ibex/codegen/report.rbs +12 -12
- data/sig/ibex/codegen/ruby.rbs +18 -15
- data/sig/ibex/codegen/ruby_actions.rbs +6 -6
- data/sig/ibex/codegen/ruby_syntax.rbs +10 -8
- 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 +16 -14
- data/sig/ibex/coverage/event_stream.rbs +12 -10
- data/sig/ibex/coverage/report.rbs +20 -18
- data/sig/ibex/coverage/runtime_event_validator.rbs +38 -36
- 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/fix.rbs +138 -0
- data/sig/ibex/frontend/ast.rbs +33 -7
- data/sig/ibex/frontend/bootstrap_parser.rbs +2 -0
- data/sig/ibex/frontend/diagnostic.rbs +2 -2
- data/sig/ibex/frontend/formatter.rbs +38 -30
- data/sig/ibex/frontend/generated_parser.rbs +87 -77
- data/sig/ibex/frontend/generated_parser_base.rbs +4 -2
- data/sig/ibex/frontend/parser/declarations.rbs +3 -0
- data/sig/ibex/frontend/parser_configuration_support.rbs +27 -0
- data/sig/ibex/frontend/resolution.rbs +3 -2
- data/sig/ibex/frontend/source_cursor.rbs +2 -2
- data/sig/ibex/frontend/source_span.rbs +5 -2
- data/sig/ibex/frontend/token_adapter/declaration_state.rbs +13 -1
- data/sig/ibex/frontend/token_adapter.rbs +6 -0
- data/sig/ibex/fuzz.rbs +71 -0
- data/sig/ibex/generation_input.rbs +2 -2
- data/sig/ibex/generation_manifest.rbs +35 -32
- data/sig/ibex/generation_transaction_recovery.rbs +2 -2
- data/sig/ibex/generation_transaction_validation.rbs +2 -2
- data/sig/ibex/grammar_tests.rbs +2 -2
- data/sig/ibex/ir/automaton_ir.rbs +30 -11
- data/sig/ibex/ir/grammar_ir.rbs +41 -27
- data/sig/ibex/ir/lexer_ir.rbs +8 -8
- data/sig/ibex/ir/parser_contract.rbs +69 -0
- data/sig/ibex/ir/serialize.rbs +63 -28
- data/sig/ibex/ir/validator/automaton.rbs +47 -44
- data/sig/ibex/ir/validator/base.rbs +35 -31
- data/sig/ibex/ir/validator/grammar.rbs +78 -67
- data/sig/ibex/ir/validator/lexer.rbs +4 -4
- data/sig/ibex/ir.rbs +9 -3
- data/sig/ibex/lalr/build_metrics.rbs +42 -2
- data/sig/ibex/lalr/builder.rbs +75 -24
- data/sig/ibex/lalr/conflict_search.rbs +5 -2
- data/sig/ibex/lalr/counterexample.rbs +17 -14
- data/sig/ibex/lalr/direct_lookaheads.rbs +35 -28
- 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 +17 -5
- 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/unreachable_states.rbs +25 -0
- data/sig/ibex/lalr.rbs +11 -1
- data/sig/ibex/location.rbs +6 -6
- data/sig/ibex/lsp/document_handlers.rbs +8 -8
- data/sig/ibex/lsp/initialization_handlers.rbs +12 -12
- data/sig/ibex/lsp/navigation_handlers.rbs +15 -12
- data/sig/ibex/lsp/parser_configuration_assistance.rbs +49 -0
- data/sig/ibex/lsp/position_codec.rbs +8 -4
- data/sig/ibex/lsp/request_handlers.rbs +4 -4
- data/sig/ibex/lsp/request_support.rbs +8 -8
- data/sig/ibex/lsp/server.rbs +16 -16
- data/sig/ibex/lsp/symbol_index.rbs +20 -21
- data/sig/ibex/lsp/symbol_index_builder.rbs +9 -8
- data/sig/ibex/lsp/symbol_occurrence.rbs +11 -5
- data/sig/ibex/lsp/transport.rbs +18 -6
- data/sig/ibex/lsp/workspace.rbs +3 -2
- data/sig/ibex/lsp/workspace_analyzer.rbs +1 -1
- data/sig/ibex/messages.rbs +26 -0
- data/sig/ibex/metrics.rbs +50 -0
- data/sig/ibex/normalize/diagnostics.rbs +4 -4
- data/sig/ibex/normalize/expander.rbs +2 -2
- data/sig/ibex/normalize/expression.rbs +10 -8
- data/sig/ibex/normalize/grammar_builder.rbs +11 -0
- data/sig/ibex/normalize/inline_expansion.rbs +59 -50
- data/sig/ibex/normalize/lexer.rbs +4 -4
- data/sig/ibex/normalize/parameter_ebnf_lowering.rbs +15 -14
- data/sig/ibex/normalize/parameter_lowering.rbs +18 -18
- data/sig/ibex/normalize/parameters.rbs +13 -8
- data/sig/ibex/normalize/parser_configuration.rbs +23 -0
- data/sig/ibex/normalize.rbs +11 -5
- data/sig/ibex/racc_migration/report.rbs +8 -6
- data/sig/ibex/rake_task.rbs +1 -1
- data/sig/ibex/samples.rbs +13 -4
- 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 +8 -4
- data/sig/ibex/table_simulation/step.rbs +4 -2
- data/sig/ibex/tables.rbs +10 -9
- 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 +12 -2
- data/sig/ibex/watch/source_snapshot.rbs +13 -9
- metadata +232 -12
- data/lib/ibex/ir/migration.rb +0 -120
- data/sig/ibex/ir/migration.rbs +0 -34
data/docs/architecture.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Architecture
|
|
3
|
+
description: Ibex's grammar, IR, parser construction, runtime, and verification boundaries.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Architecture and IR schemas
|
|
2
7
|
|
|
3
|
-
Ibex keeps syntax, grammar meaning, automaton construction, and output concerns behind two
|
|
8
|
+
Ibex keeps syntax, grammar meaning, automaton construction, and output concerns behind two immutable current contracts.
|
|
4
9
|
|
|
5
10
|
```text
|
|
6
11
|
.y root/fragments -> Frontend Lexer/CST -> self-hosted LR Parser -> canonical Resolver ─┐
|
|
@@ -8,7 +13,7 @@ Ruby DSL ───────────────────────
|
|
|
8
13
|
| |
|
|
9
14
|
| Lexer IR v1
|
|
10
15
|
|
|
|
11
|
-
|
|
16
|
+
set analysis
|
|
12
17
|
|
|
|
13
18
|
SLR/LALR/IELR/LR1 Builder -> Automaton IR
|
|
14
19
|
|
|
|
@@ -18,8 +23,56 @@ Ruby DSL ───────────────────────
|
|
|
18
23
|
Frontend changes stop at the Normalizer. Algorithm strategies consume Grammar IR and produce identical Automaton IR shapes.
|
|
19
24
|
Outputs consume Automaton IR and never call builder internals. The CLI only connects stages and supports JSON resumption.
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
IELR has two construction strategies. The conservative `partition` strategy
|
|
27
|
+
builds canonical LR(1) and partitions compatible isocores. The opt-in `direct`
|
|
28
|
+
strategy works from LR(0), goto-follow closures, lane annotations, and targeted
|
|
29
|
+
state splitting before rerunning lookahead propagation. Both use the shared
|
|
30
|
+
conflict resolver and downstream Automaton IR pipeline. See the [IELR guide](ielr.md).
|
|
31
|
+
|
|
32
|
+
## Execution trust boundary
|
|
33
|
+
|
|
34
|
+
`syntax-only` means that the LR runtime suppresses parser production actions.
|
|
35
|
+
It does not mean that no application Ruby executes.
|
|
36
|
+
|
|
37
|
+
| Execution path | Parser production actions | Generated lexer actions | User `header` / `inner` / `footer` | Trust |
|
|
38
|
+
| --- | --- | --- | --- | --- |
|
|
39
|
+
| Grammar parse/normalize, format, LSP, reports, conflict/diff/equiv/verify/debug, internal fuzz | No | No | No | Nonexecuting without an external-command option |
|
|
40
|
+
| Generated-lexer semantic: `parse`, `lex(...).do_parse`, `parse_with_syntax(source)` | Yes | Yes | May execute when the generated file loads | Trusted application code; not a sandbox |
|
|
41
|
+
| Handwritten pull semantic: `do_parse`, no-argument `parse_with_syntax` | Yes | No | May execute when the generated file loads | Trusted application code; not a sandbox |
|
|
42
|
+
| Caller-fed semantic: `yyparse`, `push` / `finish` | Yes | No | May execute when the generated file loads | Trusted application code; not a sandbox |
|
|
43
|
+
| Generated syntax-only parse | No | Yes | May execute when the generated file loads | Trusted application code; not a sandbox |
|
|
44
|
+
| Future safe syntax profile | No | Declarative built-ins only | No | Nonexecuting profile; not currently available |
|
|
45
|
+
|
|
46
|
+
Static paths operate on source, Grammar IR, Lexer IR, Automaton IR, or parser
|
|
47
|
+
tables without requiring the generated application parser. Parser actions,
|
|
48
|
+
lexer actions, conversions, and user sections remain opaque data on those
|
|
49
|
+
paths. Code generation may emit source that compiles them when the artifact is
|
|
50
|
+
loaded, but the generator does not load that artifact.
|
|
51
|
+
|
|
52
|
+
The static guarantee excludes explicit external-command options.
|
|
53
|
+
`ibex fuzz --against=COMMAND` and `ibex reduce --command=COMMAND` spawn the
|
|
54
|
+
supplied executable and may run arbitrary application code with host permissions.
|
|
55
|
+
Subprocess resource limits and process-group cleanup are not sandboxes and do
|
|
56
|
+
not confine side effects.
|
|
57
|
+
|
|
58
|
+
Semantic runtime entry points execute committed parser production actions.
|
|
59
|
+
Generated lexer actions execute only when tokens are pulled through
|
|
60
|
+
`GeneratedLexer#next_token`; handwritten `next_token`, `yyparse`, and
|
|
61
|
+
`push` / `finish` paths do not invoke that lexer. Syntax-only entry points
|
|
62
|
+
suppress parser actions but still use the generated lexer to emit tokens,
|
|
63
|
+
convert values, and mutate lexer state. Every generated runtime path crosses
|
|
64
|
+
the trusted application boundary because loading the generated Ruby file may
|
|
65
|
+
execute arbitrary user sections. Resource budgets and process-isolation
|
|
66
|
+
building blocks do not make those paths sandboxes.
|
|
67
|
+
|
|
68
|
+
A future profile for untrusted syntax work must use data-only parser tables, a
|
|
69
|
+
declarative lexer whose operations are restricted to built-ins, no parser
|
|
70
|
+
actions, no arbitrary conversions, and no `header`, `inner`, or `footer`
|
|
71
|
+
sections. The current generated parser API must not be described as that
|
|
72
|
+
profile.
|
|
73
|
+
|
|
74
|
+
An optional root-only `lexer` declaration normalizes to the independently versioned
|
|
75
|
+
Lexer IR and its flat rule list, which are embedded unchanged in the current Grammar IR.
|
|
23
76
|
records state, declaration id, pattern source/options, action, and provenance;
|
|
24
77
|
`--emit=lexer-ir` exposes the same document. Code generation compiles every
|
|
25
78
|
pattern with an internal current-position anchor and emits immutable,
|
|
@@ -27,7 +80,7 @@ state-indexed rules. Per-parser mutable input, position, emission, and state
|
|
|
27
80
|
stacks live in `Runtime::GeneratedLexer`, never in the tables. See
|
|
28
81
|
[ADR 0014](decisions/0014-versioned-generated-lexer.md).
|
|
29
82
|
|
|
30
|
-
`pragma cst` remains an optional Grammar IR
|
|
83
|
+
`pragma cst` remains an optional current Grammar IR flag. Regenerated format-v6
|
|
31
84
|
tables add deterministic kind and normalized slot metadata. `Runtime::Parser`
|
|
32
85
|
builds a pure-syntax Green entry for every shift and reduction on a stack
|
|
33
86
|
parallel to the semantic stack, so tree shape no longer depends on semantic
|
|
@@ -61,8 +114,9 @@ Validation reconstructs every derived width, flag, and descendant count.
|
|
|
61
114
|
Non-UTF-8 bytes use canonical Base64. See
|
|
62
115
|
[ADR 0017](decisions/0017-persistent-syntax-artifacts.md).
|
|
63
116
|
|
|
64
|
-
Incremental sessions are syntax-only: parser production actions do not run
|
|
65
|
-
The generated lexer first validates token/state
|
|
117
|
+
Incremental sessions are syntax-only: parser production actions do not run,
|
|
118
|
+
but generated lexer actions do. The generated lexer first validates token/state
|
|
119
|
+
resynchronization. `Blender`
|
|
66
120
|
then offers either a fresh token or an old Green nonterminal to the LR driver.
|
|
67
121
|
A subtree is pushed directly through `goto` only when damage, recorded
|
|
68
122
|
left-state, follow-token identity, error flags, and positive width satisfy the
|
|
@@ -70,7 +124,18 @@ conservative reuse proof. Token and parse memos remain preorder/occurrence
|
|
|
70
124
|
state owned by one session; resource exhaustion falls back to the fresh token
|
|
71
125
|
stream. See [ADR 0018](decisions/0018-conservative-incremental-syntax-reuse.md).
|
|
72
126
|
|
|
73
|
-
|
|
127
|
+
`Runtime::SyntaxSession` is a thin generated-language service boundary over
|
|
128
|
+
that same engine. Current generated classes expose only
|
|
129
|
+
`:trusted_application_code`, and callers must explicitly acknowledge that
|
|
130
|
+
profile because lexer actions still execute. Immutable operation snapshots add
|
|
131
|
+
expected-token and reuse/fallback evidence plus cooperative cancellation and
|
|
132
|
+
service bounds. The façade belongs to `ibex-runtime`; it defines neither LSP
|
|
133
|
+
nor workspace semantics. Its additive `repair` operation projects bounded
|
|
134
|
+
syntax repairs into byte edits and fresh syntax results without exposing
|
|
135
|
+
semantic values or invoking application repair callbacks. See
|
|
136
|
+
[ADR 0019](decisions/0019-runtime-syntax-session-boundary.md).
|
|
137
|
+
|
|
138
|
+
Alternative-level `@node` declarations are preserved in the current Grammar IR
|
|
74
139
|
production metadata. Runtime Ruby, static action-shadow Ruby, and generated
|
|
75
140
|
RBS all derive Data node classes and Visitor/Listener hooks from that same
|
|
76
141
|
metadata; action source is never inspected to infer a shape. Symbol semantic
|
|
@@ -125,6 +190,20 @@ The executable's ordinary generation path declares this pipeline directly instea
|
|
|
125
190
|
subcommand. Optional subcommands and generation outputs load at their invocation boundary while their public constants remain
|
|
126
191
|
autoloadable.
|
|
127
192
|
|
|
193
|
+
### Effective configuration boundary
|
|
194
|
+
|
|
195
|
+
`Ibex::Configuration` gives generation, grammar-test, and analysis paths one closed definition for parser construction and
|
|
196
|
+
build-policy concepts. Each immutable value records its canonical key, typed domain, owner, override policy, selected origin,
|
|
197
|
+
explicitness, and whether the selection is canonical. `Configuration::CLIAdapter` translates the existing internal option
|
|
198
|
+
hash into domain values such as `parser.entries=isolated`, `cst.trivia=leading`, and
|
|
199
|
+
`source.line_mapping=all`; code generators do not interpret legacy CLI shapes directly.
|
|
200
|
+
|
|
201
|
+
`Configuration::Resolver` applies fixed and monotone-minimum algebra without loading a grammar file or executing user code.
|
|
202
|
+
A fixed grammar declaration accepts a matching request and raises `Configuration::Conflict` for a contradiction. An explicit
|
|
203
|
+
analysis override remains noncanonical and serializes both the declared and selected values. Evidence JSON is emitted in
|
|
204
|
+
canonical-key order. This boundary intentionally adds neither grammar syntax nor a project configuration file; those adapters
|
|
205
|
+
must supply the same closed keys when their separately reviewed formats exist.
|
|
206
|
+
|
|
128
207
|
Extended grammar paths cross an explicit `Frontend::Resolver` boundary. The canonical `import` declaration and compatible
|
|
129
208
|
`include` spelling share this boundary. Roots retain class, start, options, and user code;
|
|
130
209
|
fragments contain composable declarations and rules. Canonical realpaths define DFS order, diamond deduplication, cycle identity,
|
|
@@ -145,7 +224,7 @@ precedence, metadata, documentation, locations, and definition include chains fl
|
|
|
145
224
|
|
|
146
225
|
Inline definitions are lowered temporarily, then a bounded deterministic post-pass substitutes marked alternatives through
|
|
147
226
|
ordinary, parameterized, and EBNF productions before diagnostics and LR construction. It removes every marked symbol and
|
|
148
|
-
production, remaps the dense symbol/production ids, and retains eliminated semantic reductions as a
|
|
227
|
+
production, remaps the dense symbol/production ids, and retains eliminated semantic reductions as a stable post-order
|
|
149
228
|
action plan. The plan addresses flattened physical values followed by earlier logical results, records a nullable semantic
|
|
150
229
|
`result_type` on every newly emitted step, reconstructs surrounding stack
|
|
151
230
|
prefixes and semantic spans, and remains executable after IR serialization. Cycle validation covers paths through ordinary
|
|
@@ -181,17 +260,19 @@ Ruby DSL, IR records, and automaton actions use concrete domain types. Generated
|
|
|
181
260
|
cells, decoded JSON values, and user methods embedded as opaque Ruby source remain `untyped`; applications can reopen the generated
|
|
182
261
|
class in their own RBS files to declare embedded methods.
|
|
183
262
|
|
|
184
|
-
## Grammar IR
|
|
263
|
+
## Current Grammar IR
|
|
264
|
+
|
|
265
|
+
<!-- stable:current-ir:v1 -->
|
|
185
266
|
|
|
186
267
|
Top-level fields:
|
|
187
268
|
|
|
188
269
|
| Field | Meaning |
|
|
189
270
|
|---|---|
|
|
190
|
-
| `ibex_ir`, `schema_version` | `"grammar"`,
|
|
271
|
+
| `ibex_ir`, `schema_version` | `"grammar"`, current format |
|
|
191
272
|
| `class_name`, `superclass` | Generated Ruby class contract |
|
|
192
273
|
| `start`, optional `starts`, `expect`, `options` | Primary/ordered start names, unresolved S/R expectation, result/action flags |
|
|
193
274
|
| optional `params`, `printers` | Generated-constructor keywords and symbol-specific debug value formatters |
|
|
194
|
-
| optional `lexer` | Embedded independently versioned Lexer IR
|
|
275
|
+
| optional `lexer` | Embedded independently versioned Lexer IR |
|
|
195
276
|
| `symbols` | Interned terminals and nonterminals; `$eof` id 0 and `error` id 1 |
|
|
196
277
|
| `productions` | Numeric LHS/RHS ids, action, precedence override, source origin |
|
|
197
278
|
| `user_code`, `conversions`, `warnings` | Concatenated code, external token expressions, structured diagnostics |
|
|
@@ -199,24 +280,23 @@ Top-level fields:
|
|
|
199
280
|
|
|
200
281
|
Warning records use the additive type vocabulary `undeclared_terminal`, `unused_terminal`, `unused_precedence`,
|
|
201
282
|
`unreachable_terminal`, `unreachable_nonterminal`, `duplicate_production`, and `empty_language`, and retain source locations.
|
|
202
|
-
|
|
283
|
+
The CLI applies display/error policy at the boundary;
|
|
203
284
|
normalization and IR serialization do not discard diagnostics.
|
|
204
285
|
|
|
205
286
|
A symbol has `id`, `name`, `kind`, `reserved`, optional `prec {associativity, level}`, `loc`, `display_name`, and
|
|
206
|
-
`semantic_type`.
|
|
287
|
+
`semantic_type`.
|
|
207
288
|
A production has `id`, `lhs`, `rhs`, optional `action`, optional `prec_override`, and `origin`. Synthetic EBNF origins include
|
|
208
289
|
an additive, deterministic `expression` label used by text, DOT, and HTML presentation while numeric symbol identities remain
|
|
209
290
|
unchanged. An action has opaque `code`, `loc`, `named_refs [{name,index}]`, and `context_length`; middle-action helpers use the
|
|
210
291
|
last field to view preceding stack values.
|
|
211
292
|
|
|
212
|
-
IR objects and nested collections are frozen. JSON keys have deterministic order, so dump/load/dump is byte-stable.
|
|
213
|
-
`user_code_chunks` field remains optional in version 1 so older JSON stays loadable.
|
|
293
|
+
IR objects and nested collections are frozen. JSON keys have deterministic order, so dump/load/dump is byte-stable.
|
|
214
294
|
|
|
215
|
-
|
|
295
|
+
Normalized grammars use the current format for declaration-free source and carry explicit nullable metadata:
|
|
216
296
|
|
|
217
|
-
| Record |
|
|
297
|
+
| Record | Current-format metadata |
|
|
218
298
|
|---|---|
|
|
219
|
-
| grammar | `source_provenance {file, root, byte_span {start,end}}`
|
|
299
|
+
| grammar | `source_provenance {file, root, byte_span {start,end}}` |
|
|
220
300
|
| symbol | `doc` |
|
|
221
301
|
| production | `doc` and `expansion {parameter, inline, include_chain}` |
|
|
222
302
|
| action | `composition {strategy, fragments, plan {version, physical, steps}}`; new steps include nullable `result_type` |
|
|
@@ -225,13 +305,28 @@ The source-only text frontend supplies the source filename and leaves unknown me
|
|
|
225
305
|
canonical source root and each production's include chain while preserving its original-file origin. Lossless rule comments
|
|
226
306
|
populate symbol and user-production documentation, including through fragment resolution; synthetic EBNF helpers remain
|
|
227
307
|
undocumented. Parameterized specializations populate `expansion.parameter` with the template name and canonical structural
|
|
228
|
-
arguments while retaining the definition's include chain.
|
|
229
|
-
`
|
|
230
|
-
|
|
231
|
-
`
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
308
|
+
arguments while retaining the definition's include chain.
|
|
309
|
+
The current format adds one closed, root-owned `parser_contract`. Its `algorithm`, `entries`, and `cst_trivia` members each carry
|
|
310
|
+
`value`, `explicit`, and `loc`. An explicit member has an admitted value and source location; an unspecified member has all
|
|
311
|
+
three states fixed to `value: null`, `explicit: false`, and `loc: null`. Unspecified is not an encoding of the current built-in
|
|
312
|
+
default. The contract sits only at the root, so fragments cannot change parser-wide construction while their normalized
|
|
313
|
+
productions and source provenance remain composable.
|
|
314
|
+
|
|
315
|
+
Extended root grammars can populate `algorithm` and `entries` through one
|
|
316
|
+
domain-specific `parser ... end` declaration. The frontend rejects that block
|
|
317
|
+
in fragments and compatible mode, and rejects duplicate blocks, duplicate or
|
|
318
|
+
unknown keys, unknown values, and `algorithm auto` before normalization. The
|
|
319
|
+
typed configuration resolver treats those values as fixed grammar contracts:
|
|
320
|
+
canonical generation accepts only an absent or matching CLI request. Analysis
|
|
321
|
+
and grammar-test commands may move an explicitly different algorithm into a
|
|
322
|
+
reported noncanonical analysis origin; entry construction remains fixed. The
|
|
323
|
+
configuration inspector reads the same AST and import closure without running
|
|
324
|
+
actions or user sections.
|
|
325
|
+
|
|
326
|
+
`Serialize.load` and `Validator.validate` accept only the current Grammar IR format. Both declaration-free and
|
|
327
|
+
`parser`-declared sources write that same format, so there is no in-process migration path or compatibility reader.
|
|
328
|
+
Callers construct the current object directly through `IR::Grammar.new`; see
|
|
329
|
+
[ADR 0020](decisions/0020-grammar-ir-parser-contract.md).
|
|
235
330
|
|
|
236
331
|
The v1 stabilization freeze covers required core fields, meanings, ordering,
|
|
237
332
|
identity, and validation behavior. The future `x-` experimental namespace is
|
|
@@ -245,7 +340,7 @@ railroad SVG. The railroad renderer includes visible wrapped rule descriptions i
|
|
|
245
340
|
full escaped text through SVG descriptions. `ibex doc` resolves the same canonical include graph and writes to stdout or an
|
|
246
341
|
atomic file without generating or executing application parser code.
|
|
247
342
|
|
|
248
|
-
## Automaton IR
|
|
343
|
+
## Current Automaton IR
|
|
249
344
|
|
|
250
345
|
Top-level fields are `ibex_ir: "automaton"`, `schema_version`, `algorithm`, `grammar_digest`, embedded `grammar`, `states`,
|
|
251
346
|
optional `entry_states`, and `conflict_summary`. Embedding Grammar IR makes automaton JSON sufficient for code generation after
|
|
@@ -264,10 +359,17 @@ Each state contains:
|
|
|
264
359
|
`conflict_summary.sr` counts unresolved default-shift conflicts for `expect`; `resolved_sr` counts retained precedence or
|
|
265
360
|
associativity decisions; `rr` counts reduce/reduce cells.
|
|
266
361
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
362
|
+
The current Automaton IR embeds the exact current Grammar IR, includes the parser contract in `grammar_digest`, and records
|
|
363
|
+
`entry_construction` as `shared` or `isolated`. Older documents are rejected rather than migrated. Callers construct the
|
|
364
|
+
current object directly through `IR::Automaton.new`.
|
|
365
|
+
|
|
366
|
+
`--from=grammar-ir` applies the current parser contract through the typed configuration resolver before constructing tables;
|
|
367
|
+
matching CLI values are allowed and conflicts are rejected with the contract location. `--from=automaton-ir` generates without
|
|
368
|
+
the original source and rejects algorithm/entry construction flags because its tables are already built. A generation
|
|
369
|
+
manifest records the grammar digest and contract separately from the embedded automaton's algorithm/entry facts and codegen-only
|
|
370
|
+
effective configuration. Static IR views validate opaque action strings but never execute them. Published Draft 2020-12
|
|
371
|
+
contracts for both current IR documents live under `schema/`; see
|
|
372
|
+
[ADR 0001](decisions/0001-separate-ir-pipeline.md).
|
|
271
373
|
|
|
272
374
|
`--emit=sets` is a deterministic analysis view rather than another IR: it emits lexically sorted nullable nonterminals and
|
|
273
375
|
FIRST/FOLLOW maps for nonterminals. DOT, Mermaid, and the self-contained searchable HTML report are deterministic presentation
|
|
@@ -298,6 +400,56 @@ shortest reachability witness instead of claiming ambiguity.
|
|
|
298
400
|
shape. `Counterexample#all` retains its original all-conflict behavior. The view performs no additional parser analysis and does
|
|
299
401
|
not extend Grammar or Automaton IR.
|
|
300
402
|
|
|
403
|
+
`Ibex::Verify::Verifier` accepts validated Automaton IR and derives LR(0) or
|
|
404
|
+
canonical LR(1) collections from the embedded Grammar IR without calling the
|
|
405
|
+
parser builder. Default checks validate item/action soundness,
|
|
406
|
+
algorithm-specific lookaheads, expanded default reductions and error masks,
|
|
407
|
+
reachability, productivity, epsilon termination, resolver consistency, and
|
|
408
|
+
rebuilt plain/compact row equality. `--strict` adds collection completeness
|
|
409
|
+
and reports that same row equality as V5 rather than V4. The verifier does not
|
|
410
|
+
consume generated Ruby or a supplied executable table artifact. Strict IELR
|
|
411
|
+
verification also runs the bounded V9 canonical acceptance witness; this is
|
|
412
|
+
not an unbounded equivalence proof. Its exact
|
|
413
|
+
shared dependencies, algorithm limits, resource semantics, fault mapping, and
|
|
414
|
+
non-goals are documented in the [verifier trust boundary](verifier-trust-boundary.md).
|
|
415
|
+
`ibex verify` uses exit statuses 0 for valid, 1 for a violation, and 2 for
|
|
416
|
+
reference-budget exhaustion.
|
|
417
|
+
|
|
418
|
+
`Ibex::Equiv` first compares normalized grammar structure, then generates
|
|
419
|
+
sentences in both directions and explores the product of two immutable LR
|
|
420
|
+
state-stack machines in breadth-first order. The product key includes both
|
|
421
|
+
stacks, statuses, and consumed-action counts; a supplied rule map also adds
|
|
422
|
+
both postorder reduction traces. The first reported token witness is therefore
|
|
423
|
+
shortest within the declared token/configuration bounds. Simulation uses only
|
|
424
|
+
Automaton IR actions and gotos. It validates both inputs with the independent
|
|
425
|
+
verifier and does not evaluate semantic actions. A rule map requests bounded
|
|
426
|
+
tree comparison; without one, only accepted language is compared. Every
|
|
427
|
+
successful bounded report explicitly states that it is not an equivalence
|
|
428
|
+
proof.
|
|
429
|
+
|
|
430
|
+
`Ibex::Fix` composes those two read-only safety oracles around a finite repair
|
|
431
|
+
space. It rebuilds a candidate through the shared construction pipeline, but
|
|
432
|
+
accepts it only after the target fingerprint disappears, other fingerprints
|
|
433
|
+
do not increase, independent verification succeeds, and bounded language plus
|
|
434
|
+
identity-mapped reduction traces find no difference. User actions remain
|
|
435
|
+
opaque. Source proposals are whole-file deterministic edits; the CLI delegates
|
|
436
|
+
application to the existing transactional writer and refuses aliased inputs.
|
|
437
|
+
`Ibex::Diff` and `Ibex::Metrics` are deterministic views over the same frozen
|
|
438
|
+
Grammar and Automaton IR. They do not add an IR stage or alter generated
|
|
439
|
+
parsers.
|
|
440
|
+
|
|
441
|
+
`Ibex::BisonImport` is a clean-room adapter in front of that frozen pipeline.
|
|
442
|
+
Its iterative scanner recovers declarations, production alternatives, source
|
|
443
|
+
positions, and opaque C actions under byte/token/rule/action budgets, then
|
|
444
|
+
emits ordinary extended source. It adds no frontend syntax or IR field.
|
|
445
|
+
Deterministic terminal/nonterminal namespaces prevent Bison casing and keyword
|
|
446
|
+
rules from changing symbol kinds. The report separates unsupported directives
|
|
447
|
+
that leave the recovered production graph complete from structural gaps.
|
|
448
|
+
Analysis may continue across either result, but Ruby generation rejects the C
|
|
449
|
+
action sentinel and `Fix` rejects structurally incomplete source. Pinned
|
|
450
|
+
third-party grammars exist only in temporary external CI directories; see the
|
|
451
|
+
[import guide](bison-import.md).
|
|
452
|
+
|
|
301
453
|
The repository's self-authored representative grammar feeds the current versioned `ibex_benchmark` v2 document. Its JSON Schema
|
|
302
454
|
is shipped beside the IR schemas, while committed environment-specific observations live under the matching
|
|
303
455
|
`benchmark/results/vN` directory. Timing and peak RSS remain non-gating; CI reproduces only deterministic structure and digests.
|
|
@@ -332,7 +484,7 @@ committed events without changing parser results; the recovery hook retains the
|
|
|
332
484
|
ordinary token shift. A configured value printer affects only human `yydebug` output. Their ordering and payload contract is
|
|
333
485
|
extended additively by
|
|
334
486
|
[ADR 0010](decisions/0010-committed-runtime-observation.md). Grammar-declared
|
|
335
|
-
symbol printers are optional IR
|
|
487
|
+
symbol printers are optional current IR metadata compiled into private methods and
|
|
336
488
|
an id-indexed table.
|
|
337
489
|
|
|
338
490
|
Ordinary generated tables are recursively frozen and made Ractor-shareable. Threads and Ractors share those tables but parse
|
|
@@ -341,7 +493,7 @@ single instance rejects overlapping drivers. Immutable `Runtime::ResourceLimits`
|
|
|
341
493
|
entry with finite defaults. Exhaustion raises the structured `ResourceLimitError`; see
|
|
342
494
|
[ADR 0009](decisions/0009-isolated-parser-sessions.md).
|
|
343
495
|
|
|
344
|
-
Extended Grammar IR
|
|
496
|
+
Extended current Grammar IR may additionally carry synchronization terminals and ordered `%on_error_reduce` groups. Table
|
|
345
497
|
construction fills only otherwise erroneous ACTION cells with a unique highest-priority completed declared production. At
|
|
346
498
|
runtime, an explicit shift of the synthetic `error` token always wins; only when it is unavailable does panic recovery discard
|
|
347
499
|
through a configured synchronization token and pop to a state that accepts that retained lookahead. Generated parsers without
|
|
@@ -352,7 +504,7 @@ The separate `Runtime::Parser#observe` API publishes ordered, immutable schema-v
|
|
|
352
504
|
copies only JSON data and never retains application identities or private stacks. With no observer, parse transitions construct
|
|
353
505
|
no Event, payload summary, or dispatch snapshot; parser initialization still creates its ownership mutex. Generated tables
|
|
354
506
|
contribute grammar digest, table format, state count, and production count to the `start` event. `Runtime::EventJSONLTracer`
|
|
355
|
-
exposes the versioned stream
|
|
507
|
+
exposes the versioned stream. The protocol and
|
|
356
508
|
exception/threading behavior are fixed by
|
|
357
509
|
[ADR 0010](decisions/0010-committed-runtime-observation.md).
|
|
358
510
|
|
|
@@ -375,7 +527,7 @@ source stored in Grammar IR. Immutable steps expose state, lookahead, selected a
|
|
|
375
527
|
depth. Action and stack budgets bound default/epsilon cycles and growth. The text/JSON CLI and versioned output contract are
|
|
376
528
|
fixed by [ADR 0012](decisions/0012-bounded-nonexecuting-analysis.md).
|
|
377
529
|
|
|
378
|
-
Grammar IR
|
|
530
|
+
The current Grammar IR may carry ordered accept/reject source tests without adding them to parser tables. `GrammarTests::Runner` generates
|
|
379
531
|
one embedded parser and executes fresh parser instances in a separate Ruby process, distinguishing `ParseError` rejection from
|
|
380
532
|
lexer/application errors and bounding the whole suite by a timeout. The separate runner loads the generated file, so guarded
|
|
381
533
|
footer programs stay inactive. The source contract, isolation boundary, and CI behavior are fixed by
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Bison grammar import for analysis
|
|
2
|
+
|
|
3
|
+
`ibex import bison` converts Bison-shaped grammar structure into ordinary
|
|
4
|
+
extended Ibex source for analysis. It is a one-way adapter, not a parser
|
|
5
|
+
generator compatibility mode. Imported C actions remain opaque, are never
|
|
6
|
+
executed by analysis, and make Ruby generation fail before code is emitted.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
ibex import bison parser.y -o parser.analysis.y
|
|
10
|
+
ibex import bison --format=json parser.y > import-report.json
|
|
11
|
+
ibex explain --state=STATE parser.y
|
|
12
|
+
ibex metrics parser.y
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`explain`, `metrics`, `diff`, and the other read-only grammar analysis paths
|
|
16
|
+
recognize a file with two Bison `%%` section markers and import it in memory.
|
|
17
|
+
Source-repair commands need a canonical imported file because edits against
|
|
18
|
+
the generated analysis source do not map byte-for-byte onto the Bison input.
|
|
19
|
+
|
|
20
|
+
## Conversion contract
|
|
21
|
+
|
|
22
|
+
| Classification | Directives | Treatment |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| converted | `%token`, `%left`, `%right`, `%nonassoc`, `%precedence`, `%start`, `%expect`, `%expect-rr`, `%empty`, `%prec` | existing extended declarations or production syntax |
|
|
25
|
+
| recognized metadata | `%nterm`, `%type`, `%union`, `%destructor`, `%printer`, `%param`, `%parse-param`, `%lex-param`, `%define`, `%code` | positioned report entries; no new Ibex syntax is invented |
|
|
26
|
+
| unsupported | `%dprec`, `%merge`, GLR controls, generator/output controls, and every unknown directive | every occurrence is reported with its original line and column |
|
|
27
|
+
|
|
28
|
+
`$$`, `$1`, `$<type>1`, and `@$` become `result`, `val[0]`, `val[0]`, and
|
|
29
|
+
`result_loc` inside an opaque hexadecimal action sentinel. Ordinary `@1`
|
|
30
|
+
locations remain `@1`. Balanced action scanning handles nested braces,
|
|
31
|
+
strings, character literals, and C comments iteratively.
|
|
32
|
+
|
|
33
|
+
Bison permits uppercase nonterminals, lowercase terminals, names that collide
|
|
34
|
+
after punctuation removal, and names that are Ibex declaration words. The
|
|
35
|
+
adapter deterministically namespaces nonterminals as `bison_nt_*`, maps
|
|
36
|
+
lowercase terminals into `BISON_T_*`, and adds stable numeric suffixes to
|
|
37
|
+
sanitization collisions. Named LHS forms such as `expression[result]:` are
|
|
38
|
+
recognized.
|
|
39
|
+
|
|
40
|
+
The source and JSON report distinguish general unsupported directives from
|
|
41
|
+
structural gaps. Output/language controls and opaque initialization hooks do
|
|
42
|
+
not make the recovered production graph incomplete. Unknown directives,
|
|
43
|
+
`%dprec`, `%merge`, GLR semantics, and grammar-macro directives do. A generated
|
|
44
|
+
header therefore contains exactly one of:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
# ibex-bison-structural-status: complete
|
|
48
|
+
# ibex-bison-structural-status: incomplete
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`ibex fix` refuses a structurally incomplete import. This prevents a repair
|
|
52
|
+
from being called safe when the bounded comparison only covered an
|
|
53
|
+
approximation of the source grammar.
|
|
54
|
+
|
|
55
|
+
## Limits and failure behavior
|
|
56
|
+
|
|
57
|
+
The defaults are 20 MiB of input, 1,000,000 structural tokens, 50,000 rule
|
|
58
|
+
groups, and 100,000 actions. Override them with `--max-bytes`,
|
|
59
|
+
`--max-tokens`, `--max-rules`, and `--max-actions`; every value must be
|
|
60
|
+
positive. Exhaustion produces a version-1 JSON envelope and exits 2.
|
|
61
|
+
Successful import exits 0 even when unsupported directives are present,
|
|
62
|
+
because the report—not silence—is the result. Invocation and malformed-input
|
|
63
|
+
errors go to stderr and exit 1.
|
|
64
|
+
|
|
65
|
+
`-o` writes atomically, rejects an input/output alias, and refuses symlink
|
|
66
|
+
targets or files with multiple hard links. Third-party grammar files are not
|
|
67
|
+
packaged or committed.
|
|
68
|
+
|
|
69
|
+
## External evidence and the `parse.y` boundary
|
|
70
|
+
|
|
71
|
+
The scheduled external gate downloads five checksum-pinned GNU Bison grammars
|
|
72
|
+
listed in [`gallery/EXTERNAL.md`](../gallery/EXTERNAL.md). It validates the
|
|
73
|
+
import report, parses the generated source, normalizes it, and builds an Ibex
|
|
74
|
+
LALR automaton. Current aggregate evidence is:
|
|
75
|
+
|
|
76
|
+
| Grammar | Rule groups | Actions | Productions | Ibex states | Unresolved S/R |
|
|
77
|
+
|---|---:|---:|---:|---:|---:|
|
|
78
|
+
| GNU Bison calc | 5 | 7 | 13 | 22 | 0 |
|
|
79
|
+
| jq | 29 | 167 | 167 | 311 | 408 |
|
|
80
|
+
| PHP | 177 | 552 | 635 | 1,203 | 0 |
|
|
81
|
+
| PostgreSQL | 795 | 2,436 | 3,640 | 6,942 | 0 |
|
|
82
|
+
| CRuby Bison-era `parse.y` | 223 | 594 | 781 | 1,303 | 0 |
|
|
83
|
+
|
|
84
|
+
For the pinned Bison-era CRuby grammar, GNU Bison 3.8.2 and Ibex both recover
|
|
85
|
+
781 non-augmented productions and zero unresolved conflicts. Bison reports
|
|
86
|
+
1,304 states while Ibex reports 1,303. The one-state difference is explained
|
|
87
|
+
by the acceptance convention: Bison shifts end-of-input into a separate
|
|
88
|
+
accept state, while Ibex accepts from the completed augmented start item.
|
|
89
|
+
|
|
90
|
+
Current CRuby `parse.y` is an Lrama input, not raw GNU Bison input. The pinned
|
|
91
|
+
current file imports 231 rule groups and 486 actions, but reports 22
|
|
92
|
+
structurally unsupported occurrences, including `%rule` grammar macros. The
|
|
93
|
+
approximate automaton has 1,152 states and 27 unresolved S/R conflicts.
|
|
94
|
+
Selecting state 413 keeps `explain` bounded and yields one nonunifying
|
|
95
|
+
reachability witness for the `'rescue' modifier` shift/reduce choice within 8
|
|
96
|
+
tokens and 10,000 configurations. That is useful diagnostic evidence about
|
|
97
|
+
the recovered approximation, not a claim about CRuby's actual Lrama table.
|
|
98
|
+
`fix` refuses this input because proposing a language-preserving repair across
|
|
99
|
+
unexpanded `%rule` definitions would be unsound.
|
|
100
|
+
|
|
101
|
+
The external gate reads public grammar text and GNU Bison's black-box report
|
|
102
|
+
only. It does not inspect Bison implementation source or generated C, and
|
|
103
|
+
publishes only aggregate counts.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Comparative claim policy
|
|
2
|
+
|
|
3
|
+
This policy defines when Ibex documentation may compare Ibex with another
|
|
4
|
+
parser tool. The machine-readable registry is [`claims.yml`](claims.yml), and
|
|
5
|
+
`bundle exec rake quality:comparative_claims` validates the registry and its
|
|
6
|
+
public claim markers.
|
|
7
|
+
|
|
8
|
+
The initial comparison set is Racc, Lrama, GNU Bison, Menhir, Tree-sitter, and
|
|
9
|
+
ANTLR. A tool being in the set does not imply that a comparison has been made.
|
|
10
|
+
An unmeasured tool remains `not_compared`; unknown facts remain `unknown`.
|
|
11
|
+
Each entry also owns its canonical public aliases. README scanning recognizes
|
|
12
|
+
only this declared set and aliases; adding a tool or spelling requires a
|
|
13
|
+
reviewed registry change.
|
|
14
|
+
|
|
15
|
+
Tool-level state is derived from every registered claim that names that tool.
|
|
16
|
+
`pending_claims` is the canonical ordered list of claim IDs that are not yet
|
|
17
|
+
`measured`, and the reason is generated deterministically from those IDs,
|
|
18
|
+
their pending state, and their declared missing evidence. A tool with no claims
|
|
19
|
+
is `not_compared` with an empty pending list and unknown identity. A tool with
|
|
20
|
+
any pending claim is `evidence_pending`, even if another claim for that tool is
|
|
21
|
+
measured. `compared` is valid only when the tool has at least one claim, every
|
|
22
|
+
one is measured, and `pending_claims` is empty.
|
|
23
|
+
|
|
24
|
+
## Required record
|
|
25
|
+
|
|
26
|
+
Every measured, evidence-pending, or review-pending record contains:
|
|
27
|
+
|
|
28
|
+
- an immutable claim ID and narrowly scoped wording;
|
|
29
|
+
- each subject's exact released version and, when applicable, repository
|
|
30
|
+
revision;
|
|
31
|
+
- one public command represented as an executable and an ordered argv list;
|
|
32
|
+
- fixed corpus paths and external revisions;
|
|
33
|
+
- known environment values and an explicit list of unrecorded values;
|
|
34
|
+
- excluded or unsupported semantics;
|
|
35
|
+
- the subjective review method and its completion state;
|
|
36
|
+
- repository-relative evidence paths and explicit limitations; and
|
|
37
|
+
- the SHA-256 of the canonical marker body, including every table and note; and
|
|
38
|
+
- an exact-revision validity scope, expiry statement, and conditions that
|
|
39
|
+
require review.
|
|
40
|
+
|
|
41
|
+
Repository subjects and corpora use immutable 40- or 64-hex revisions. Released
|
|
42
|
+
tools use an exact release version and may use `not_applicable` only for the
|
|
43
|
+
repository revision. It must not conceal missing information. Every required
|
|
44
|
+
environment identity is either recorded as a non-placeholder value or listed
|
|
45
|
+
as `unknown`, and each unknown field is repeated in the public limitations.
|
|
46
|
+
|
|
47
|
+
No extra JSON Schema is used for this YAML registry. Its cross-file rules—file
|
|
48
|
+
existence, canonical ordering, public markers, and wording restrictions—need an
|
|
49
|
+
explicit repository validator and would not be made clearer by duplicating
|
|
50
|
+
them in a data-only schema.
|
|
51
|
+
|
|
52
|
+
## Public interface and corpus rules
|
|
53
|
+
|
|
54
|
+
Comparisons use public commands, public callbacks, or documented artifact
|
|
55
|
+
formats. Do not inspect another tool's implementation or generated source to
|
|
56
|
+
manufacture an advantage. If a public interface cannot expose a value, record
|
|
57
|
+
that limitation instead of inferring it.
|
|
58
|
+
|
|
59
|
+
Inputs, grammar revisions, lifecycle choices, lexer inclusion, runtime backend,
|
|
60
|
+
warm-up, repetitions, random seeds, and instrumentation must be fixed before a
|
|
61
|
+
measurement. Failure rows stay in the evidence. Results from different
|
|
62
|
+
environments or configurations form separate observations and must not be
|
|
63
|
+
silently merged.
|
|
64
|
+
|
|
65
|
+
## Subjective review
|
|
66
|
+
|
|
67
|
+
Diagnostic and repair usefulness are human judgments. The review method must
|
|
68
|
+
fix case IDs and the allowed labels, retain rationale and disagreements, and
|
|
69
|
+
separate maintainer assessment from independent assessment. A record whose
|
|
70
|
+
required independent review is missing stays `review_pending`; a record missing
|
|
71
|
+
its direct result artifact stays `evidence_pending`. Neither state can use a
|
|
72
|
+
public strong-claim marker or be worded as a completed comparative conclusion.
|
|
73
|
+
|
|
74
|
+
Performance statistics and deterministic behavior digests do not require a
|
|
75
|
+
subjective reviewer, but their scope and limitations still require ordinary
|
|
76
|
+
code review.
|
|
77
|
+
|
|
78
|
+
## Scoped wording
|
|
79
|
+
|
|
80
|
+
Comparative wording names the claim ID and states the relevant revision or
|
|
81
|
+
release, corpus, environment, measurement category, and important limitation.
|
|
82
|
+
For example:
|
|
83
|
+
|
|
84
|
+
> At revision X, on corpus Y and environment Z, metric M had the recorded
|
|
85
|
+
> relationship to tool version V. This does not describe other revisions,
|
|
86
|
+
> workloads, backends, or semantic capabilities.
|
|
87
|
+
|
|
88
|
+
Do not publish wording such as “faster than Racc” or “better diagnostics”
|
|
89
|
+
without those boundaries. README comparative strength wording is enclosed by
|
|
90
|
+
`comparative-claim` markers. Only a `measured` record with a direct result
|
|
91
|
+
artifact may use that marker. Pending material instead uses a
|
|
92
|
+
`comparative-evidence` marker around the full table or conclusion it records.
|
|
93
|
+
The validator requires each marker body to contain the registry wording exactly
|
|
94
|
+
and every registered table anchor. It also canonicalizes line endings and
|
|
95
|
+
trailing whitespace and requires the complete body SHA-256 to match, so any
|
|
96
|
+
other prose, table-cell, row, or blank-line change fails independently of its
|
|
97
|
+
vocabulary. It always scans README, even when no claim targets README, and
|
|
98
|
+
rejects unmarked paragraphs that combine a declared tool alias with English or
|
|
99
|
+
Japanese strength wording.
|
|
100
|
+
|
|
101
|
+
## No cross-category ordering
|
|
102
|
+
|
|
103
|
+
<!-- comparison-policy:forbidden-terms:start -->
|
|
104
|
+
Do not collapse performance, diagnostics, recovery, migration, ecosystem, and
|
|
105
|
+
verification into an aggregate score or tool ranking. The categories have
|
|
106
|
+
different semantics and trust boundaries. Publish each observation and its
|
|
107
|
+
limitations separately. Numeric totals never imply semantic equivalence.
|
|
108
|
+
<!-- comparison-policy:forbidden-terms:end -->
|
|
109
|
+
|
|
110
|
+
## Review and update workflow
|
|
111
|
+
|
|
112
|
+
1. Add evidence without deleting unfavorable or failed rows.
|
|
113
|
+
2. Add or update the claim in canonical claim-ID order. Keep corpus and evidence
|
|
114
|
+
entries ordered by ID and path.
|
|
115
|
+
3. Mark unavailable tools or facts `not_compared` or `unknown`; do not estimate
|
|
116
|
+
values.
|
|
117
|
+
4. Bind measured wording with claim markers or pending tables and conclusions
|
|
118
|
+
with evidence markers. The body must retain the exact registered wording.
|
|
119
|
+
5. After reviewing an intentional marker-body diff, run the quality task. Its
|
|
120
|
+
mismatch reports both the registered and actual SHA-256; copy the actual
|
|
121
|
+
digest into `body_sha256` only in the same reviewed change. Never refresh a
|
|
122
|
+
digest merely to make the task pass.
|
|
123
|
+
6. Run `bundle exec rake quality:comparative_claims`, the focused tests, and
|
|
124
|
+
documentation coverage.
|
|
125
|
+
7. When a review condition fires, either remeasure under a new claim ID or
|
|
126
|
+
narrow the old wording to its historical scope. Historical observations are
|
|
127
|
+
retained rather than rewritten as current results.
|