ibex 0.1.0 → 0.2.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 +247 -104
- data/docs/architecture.md +322 -28
- data/docs/cst-migration.md +107 -0
- data/docs/cst.md +213 -0
- data/docs/development.md +129 -0
- data/docs/editor-setup.md +25 -0
- data/docs/error-ux.md +60 -0
- data/docs/grammar-reference.md +458 -18
- data/docs/lexer-migration.md +51 -0
- data/docs/racc-migration.md +34 -6
- data/docs/release-readiness.md +163 -0
- data/docs/stability.md +124 -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/sets.rb +5 -4
- data/lib/ibex/artifact_set.rb +63 -0
- data/lib/ibex/cli/ambiguity.rb +66 -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 +116 -0
- data/lib/ibex/cli/documentation.rb +67 -0
- data/lib/ibex/cli/error_messages.rb +177 -0
- data/lib/ibex/cli/explain.rb +76 -0
- data/lib/ibex/cli/formatting.rb +386 -0
- data/lib/ibex/cli/generation_artifacts.rb +138 -0
- data/lib/ibex/cli/generation_error_messages.rb +39 -0
- data/lib/ibex/cli/grammar_tests.rb +122 -0
- data/lib/ibex/cli/ir_tools.rb +184 -0
- data/lib/ibex/cli/lsp.rb +33 -0
- data/lib/ibex/cli/outputs.rb +91 -8
- data/lib/ibex/cli/racc_migration.rb +87 -0
- data/lib/ibex/cli/samples.rb +92 -0
- data/lib/ibex/cli/watch.rb +103 -0
- data/lib/ibex/cli.rb +506 -37
- data/lib/ibex/codegen/action_locations.rb +103 -0
- data/lib/ibex/codegen/action_method_source.rb +210 -0
- data/lib/ibex/codegen/action_source.rb +118 -0
- data/lib/ibex/codegen/ambiguity.rb +173 -0
- data/lib/ibex/codegen/cst_metadata.rb +171 -0
- data/lib/ibex/codegen/documentation.rb +170 -0
- data/lib/ibex/codegen/explain.rb +312 -0
- data/lib/ibex/codegen/generated_action_abi.rb +288 -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 +323 -2
- data/lib/ibex/codegen/report.rb +46 -6
- data/lib/ibex/codegen/ruby.rb +334 -59
- data/lib/ibex/codegen/ruby_actions.rb +143 -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 +90 -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/coverage/collector.rb +188 -0
- data/lib/ibex/coverage/event_stream.rb +97 -0
- data/lib/ibex/coverage/report.rb +259 -0
- data/lib/ibex/coverage/runtime_event_validator.rb +160 -0
- data/lib/ibex/coverage.rb +13 -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/frontend/ast.rb +145 -6
- data/lib/ibex/frontend/bootstrap_parser.rb +47 -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 +407 -0
- data/lib/ibex/frontend/generated_parser.rb +614 -190
- data/lib/ibex/frontend/generated_parser_base.rb +164 -30
- data/lib/ibex/frontend/generated_parser_includes.rb +61 -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 +247 -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/regenerator.rb +26 -1
- data/lib/ibex/frontend/resolution.rb +69 -0
- data/lib/ibex/frontend/resolver.rb +217 -0
- data/lib/ibex/frontend/rule_documentation.rb +103 -0
- data/lib/ibex/frontend/source_cursor.rb +132 -8
- 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 +81 -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 +216 -26
- 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 +8 -3
- data/lib/ibex/frontend.rb +13 -2
- data/lib/ibex/generation_input.rb +57 -0
- data/lib/ibex/generation_manifest.rb +200 -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 +38 -5
- data/lib/ibex/ir/grammar_ir.rb +137 -24
- data/lib/ibex/ir/lexer_ir.rb +76 -0
- data/lib/ibex/ir/migration.rb +120 -0
- data/lib/ibex/ir/serialize.rb +110 -19
- data/lib/ibex/ir/validator/automaton.rb +345 -0
- data/lib/ibex/ir/validator/base.rb +129 -0
- data/lib/ibex/ir/validator/grammar.rb +604 -0
- data/lib/ibex/ir/validator/lexer.rb +113 -0
- data/lib/ibex/ir/validator.rb +62 -0
- data/lib/ibex/ir.rb +57 -4
- data/lib/ibex/lalr/build_metrics.rb +23 -0
- data/lib/ibex/lalr/builder.rb +379 -52
- data/lib/ibex/lalr/conflict.rb +1 -0
- data/lib/ibex/lalr/conflict_search.rb +11 -5
- data/lib/ibex/lalr/counterexample.rb +20 -5
- data/lib/ibex/lalr/direct_lookaheads.rb +236 -0
- data/lib/ibex/lalr/ielr_partition.rb +152 -0
- data/lib/ibex/lalr/on_error_reductions.rb +74 -0
- data/lib/ibex/lalr.rb +7 -0
- data/lib/ibex/location.rb +129 -0
- data/lib/ibex/lsp/document_handlers.rb +66 -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 +78 -0
- data/lib/ibex/lsp/navigation_handlers.rb +56 -0
- data/lib/ibex/lsp/position_codec.rb +109 -0
- data/lib/ibex/lsp/protocol_error.rb +33 -0
- data/lib/ibex/lsp/request_handlers.rb +45 -0
- data/lib/ibex/lsp/request_support.rb +87 -0
- data/lib/ibex/lsp/server.rb +146 -0
- data/lib/ibex/lsp/symbol_index.rb +241 -0
- data/lib/ibex/lsp/symbol_index_builder.rb +267 -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 +17 -0
- data/lib/ibex/lsp/transport.rb +118 -0
- data/lib/ibex/lsp/workspace.rb +127 -0
- data/lib/ibex/lsp/workspace_analyzer.rb +199 -0
- data/lib/ibex/lsp.rb +32 -0
- data/lib/ibex/normalize/declarations.rb +140 -7
- data/lib/ibex/normalize/diagnostics.rb +50 -5
- data/lib/ibex/normalize/expander.rb +59 -55
- data/lib/ibex/normalize/expression.rb +60 -39
- data/lib/ibex/normalize/inline_expansion.rb +414 -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 +69 -0
- data/lib/ibex/normalize/parameter_lowering.rb +126 -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 +199 -0
- data/lib/ibex/normalize/recovery_declarations.rb +84 -0
- data/lib/ibex/normalize.rb +179 -14
- 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 +94 -0
- data/lib/ibex/racc_migration.rb +12 -0
- data/lib/ibex/rake_task.rb +116 -0
- data/lib/ibex/samples.rb +186 -0
- data/lib/ibex/table_simulation/result.rb +51 -0
- data/lib/ibex/table_simulation/simulator.rb +253 -0
- data/lib/ibex/table_simulation/step.rb +60 -0
- data/lib/ibex/table_simulation/text.rb +31 -0
- data/lib/ibex/table_simulation.rb +13 -0
- data/lib/ibex/tables.rb +9 -70
- data/lib/ibex/version.rb +1 -1
- data/lib/ibex/watch/runner.rb +172 -0
- data/lib/ibex/watch/source_snapshot.rb +93 -0
- data/lib/ibex/watch.rb +11 -0
- data/lib/ibex.rb +25 -1
- data/schema/automaton-ir-v1.schema.json +401 -0
- data/schema/automaton-ir-v2.schema.json +58 -0
- data/schema/benchmark-v1.schema.json +212 -0
- data/schema/benchmark-v2.schema.json +61 -0
- data/schema/cst-v1.json +170 -0
- data/schema/error-ux-v1.schema.json +258 -0
- data/schema/explain-v1.schema.json +433 -0
- data/schema/frontend-diagnostics-v1.schema.json +154 -0
- data/schema/generation-manifest-v1.schema.json +115 -0
- data/schema/grammar-ir-v1.schema.json +426 -0
- data/schema/grammar-ir-v2.schema.json +779 -0
- data/schema/lexer-ir-v1.schema.json +215 -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/runtime-coverage-v1.schema.json +86 -0
- data/schema/runtime-event-v1.schema.json +308 -0
- data/schema/table-simulation-v1.schema.json +70 -0
- data/sig/ibex/artifact_set.rbs +37 -0
- data/sig/ibex/cli/ambiguity.rbs +22 -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 +38 -0
- data/sig/ibex/cli/documentation.rbs +25 -0
- data/sig/ibex/cli/error_messages.rbs +57 -0
- data/sig/ibex/cli/explain.rbs +25 -0
- data/sig/ibex/cli/formatting.rbs +103 -0
- data/sig/ibex/cli/generation_artifacts.rbs +50 -0
- data/sig/ibex/cli/generation_error_messages.rbs +19 -0
- data/sig/ibex/cli/grammar_tests.rbs +36 -0
- data/sig/ibex/cli/ir_tools.rbs +51 -0
- data/sig/ibex/cli/lsp.rbs +14 -0
- data/sig/ibex/cli/outputs.rbs +17 -0
- data/sig/ibex/cli/racc_migration.rbs +30 -0
- data/sig/ibex/cli/samples.rbs +30 -0
- data/sig/ibex/cli/watch.rbs +43 -0
- data/sig/ibex/cli.rbs +104 -5
- 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 +85 -0
- data/sig/ibex/codegen/generated_action_abi.rbs +101 -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 +84 -4
- data/sig/ibex/codegen/report.rbs +8 -0
- data/sig/ibex/codegen/ruby.rbs +97 -23
- 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 +25 -0
- data/sig/ibex/codegen/ruby_table_metadata.rbs +26 -0
- data/sig/ibex/codegen/ruby_value_printers.rbs +28 -0
- data/sig/ibex/coverage/collector.rbs +76 -0
- data/sig/ibex/coverage/event_stream.rbs +42 -0
- data/sig/ibex/coverage/report.rbs +100 -0
- data/sig/ibex/coverage/runtime_event_validator.rbs +68 -0
- data/sig/ibex/coverage.rbs +7 -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/frontend/ast.rbs +208 -19
- data/sig/ibex/frontend/bootstrap_parser.rbs +11 -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 +135 -0
- data/sig/ibex/frontend/generated_parser.rbs +218 -68
- data/sig/ibex/frontend/generated_parser_base.rbs +61 -10
- 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 +54 -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/regenerator.rbs +11 -0
- data/sig/ibex/frontend/resolution.rbs +33 -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 +36 -3
- 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 +53 -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 +73 -5
- data/sig/ibex/frontend/token_adapter/rule_state.rbs +20 -0
- data/sig/ibex/frontend/token_adapter.rbs +5 -2
- data/sig/ibex/frontend.rbs +1 -1
- data/sig/ibex/generation_input.rbs +37 -0
- data/sig/ibex/generation_manifest.rbs +67 -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 +8 -2
- data/sig/ibex/ir/grammar_ir.rbs +75 -15
- data/sig/ibex/ir/lexer_ir.rbs +57 -0
- data/sig/ibex/ir/migration.rbs +34 -0
- data/sig/ibex/ir/serialize.rbs +23 -6
- data/sig/ibex/ir/validator/automaton.rbs +109 -0
- data/sig/ibex/ir/validator/base.rbs +65 -0
- data/sig/ibex/ir/validator/grammar.rbs +184 -0
- data/sig/ibex/ir/validator/lexer.rbs +37 -0
- data/sig/ibex/ir/validator.rbs +16 -0
- data/sig/ibex/ir.rbs +38 -4
- data/sig/ibex/lalr/build_metrics.rbs +20 -0
- data/sig/ibex/lalr/builder.rbs +95 -15
- data/sig/ibex/lalr/conflict_search.rbs +7 -3
- data/sig/ibex/lalr/counterexample.rbs +5 -2
- data/sig/ibex/lalr/direct_lookaheads.rbs +86 -0
- data/sig/ibex/lalr/ielr_partition.rbs +59 -0
- data/sig/ibex/lalr/on_error_reductions.rbs +22 -0
- data/sig/ibex/lalr.rbs +6 -0
- 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 +30 -0
- data/sig/ibex/lsp/position_codec.rbs +40 -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 +78 -0
- data/sig/ibex/lsp/symbol_index_builder.rbs +87 -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 +25 -0
- data/sig/ibex/lsp/transport.rbs +35 -0
- data/sig/ibex/lsp/workspace.rbs +41 -0
- data/sig/ibex/lsp/workspace_analyzer.rbs +69 -0
- data/sig/ibex/lsp.rbs +7 -0
- data/sig/ibex/normalize/declarations.rbs +31 -0
- data/sig/ibex/normalize/diagnostics.rbs +9 -0
- data/sig/ibex/normalize/expander.rbs +20 -14
- data/sig/ibex/normalize/expression.rbs +10 -10
- data/sig/ibex/normalize/inline_expansion.rbs +120 -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 +32 -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 +46 -0
- data/sig/ibex/normalize/recovery_declarations.rbs +24 -0
- data/sig/ibex/normalize.rbs +123 -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 +53 -0
- data/sig/ibex/racc_migration.rbs +8 -0
- data/sig/ibex/rake_task.rbs +51 -0
- data/sig/ibex/samples.rbs +51 -0
- data/sig/ibex/table_simulation/result.rbs +32 -0
- data/sig/ibex/table_simulation/simulator.rbs +98 -0
- data/sig/ibex/table_simulation/step.rbs +40 -0
- data/sig/ibex/table_simulation/text.rbs +14 -0
- data/sig/ibex/table_simulation.rbs +7 -0
- data/sig/ibex/tables.rbs +0 -26
- data/sig/ibex/watch/runner.rbs +48 -0
- data/sig/ibex/watch/source_snapshot.rbs +42 -0
- data/sig/ibex/watch.rbs +7 -0
- data/sig/ibex.rbs +2 -0
- metadata +301 -16
- 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
data/docs/cst.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Red/Green concrete syntax trees
|
|
2
|
+
|
|
3
|
+
`pragma cst` generates a lossless, error-tolerant syntax tree alongside the
|
|
4
|
+
ordinary semantic result. Regenerate the parser with the current generator to
|
|
5
|
+
receive parser-table format v6 and this API. Batch parsing, typed views,
|
|
6
|
+
editing, diffing, and `ibex_cst` serialization are Stable for v1; syntax-only
|
|
7
|
+
incremental sessions are Experimental.
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
class Calculator
|
|
11
|
+
pragma cst
|
|
12
|
+
token NUM PLUS
|
|
13
|
+
lexer
|
|
14
|
+
skip /[[:space:]]+/
|
|
15
|
+
NUM /[0-9]+/ { lexeme.to_i }
|
|
16
|
+
PLUS '+'
|
|
17
|
+
end
|
|
18
|
+
rule
|
|
19
|
+
start: expression
|
|
20
|
+
expression: NUM PLUS NUM @node Addition(left, operator, right)
|
|
21
|
+
end
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Parsing and tree shape
|
|
25
|
+
|
|
26
|
+
`parse_with_syntax` runs semantic actions normally and returns both results:
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
result = Calculator.new.parse_with_syntax("1 + 2", file: "input.txt")
|
|
30
|
+
value = result.value
|
|
31
|
+
root = result.syntax_root
|
|
32
|
+
diagnostics = result.diagnostics
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`parse`, `do_parse`, and `yyparse` keep their semantic return values.
|
|
36
|
+
`parser.syntax_root` exposes the most recent syntax root. Every successful root
|
|
37
|
+
has this physical shape:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
source_file
|
|
41
|
+
├── selected start-symbol node
|
|
42
|
+
└── $eof
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The immutable Green layer stores kind ids, source bytes, trivia, flags, widths,
|
|
46
|
+
and children without parents or absolute positions. It is Ractor-shareable.
|
|
47
|
+
The Red `SyntaxNode`/`SyntaxToken` layer adds lazy parent, child-index, offset,
|
|
48
|
+
span, and location navigation for one occurrence. Equal Green values can
|
|
49
|
+
therefore appear at several positions without sharing Red coordinates.
|
|
50
|
+
|
|
51
|
+
`root.to_source` reconstructs the consumed bytes exactly. Early `yyaccept`
|
|
52
|
+
marks `root.incomplete_input?` and reconstructs the consumed prefix.
|
|
53
|
+
|
|
54
|
+
## Trivia and coordinates
|
|
55
|
+
|
|
56
|
+
Select trivia ownership while generating:
|
|
57
|
+
|
|
58
|
+
- `leading` owns skipped text on the following token;
|
|
59
|
+
- `balanced` owns text through the first newline on the preceding token and
|
|
60
|
+
the remainder on the following token;
|
|
61
|
+
- `drop` omits trivia.
|
|
62
|
+
|
|
63
|
+
Pass the policy explicitly when needed:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
ibex --cst-trivia=leading grammar.y
|
|
67
|
+
ibex --cst-trivia=balanced grammar.y
|
|
68
|
+
ibex --cst-trivia=drop grammar.y
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`attach` is accepted as an alias for `leading`. EOF owns final leading trivia.
|
|
72
|
+
`drop` trees deliberately reject span, location, and incremental APIs because
|
|
73
|
+
their offsets cannot describe the original source.
|
|
74
|
+
|
|
75
|
+
Spans are zero-based, half-open byte ranges. `SourceText#position` and
|
|
76
|
+
`#location` convert them to one-based Unicode-scalar lines and columns while
|
|
77
|
+
preserving byte offsets.
|
|
78
|
+
|
|
79
|
+
## Typed syntax views
|
|
80
|
+
|
|
81
|
+
An `@node` annotation generates a view in `Parser::Syntax` without changing the
|
|
82
|
+
physical tree:
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
addition = Calculator::Syntax::Addition.cast(
|
|
86
|
+
result.syntax_root.children.fetch(0).children.fetch(0)
|
|
87
|
+
)
|
|
88
|
+
addition.left
|
|
89
|
+
addition.operator
|
|
90
|
+
addition.right
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Accessors use normalized physical RHS slots. Lowered repetitions add element
|
|
94
|
+
enumerators; separated lists also expose separators. These views are distinct
|
|
95
|
+
from generated `Parser::AST` Data values: syntax views retain punctuation and
|
|
96
|
+
trivia, while AST values are semantic-action results.
|
|
97
|
+
|
|
98
|
+
## Errors and repair
|
|
99
|
+
|
|
100
|
+
Lexical failure, yacc recovery, panic discard, and bounded repair all produce a
|
|
101
|
+
tree. Inspect `diagnostics`, `contains_error?`, error nodes, missing tokens, and
|
|
102
|
+
Green flags. Inserted tokens are zero-width `missing_token` values. Discarded
|
|
103
|
+
input remains under error nodes or `skipped_tokens` trivia. An unrecoverable
|
|
104
|
+
parse uses `synthetic_root`.
|
|
105
|
+
|
|
106
|
+
## Persistent editing and diffing
|
|
107
|
+
|
|
108
|
+
Editing returns a new Red root and path-copies only changed ancestors:
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
old_root = result.syntax_root
|
|
112
|
+
first = old_root.first_token
|
|
113
|
+
new_root = first.with_text("10")
|
|
114
|
+
edits = Ibex::Runtime::CST::Diff.text_edits(old_root, new_root)
|
|
115
|
+
new_source = old_root.source_text.apply(edits)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Nodes support `replace_with`, `with_child`, `insert_child`, and `remove_child`.
|
|
119
|
+
Tokens support `replace_with`, `with_text`, `with_leading`, and
|
|
120
|
+
`with_trailing`. `SyntaxRewriter` performs bottom-up kind dispatch;
|
|
121
|
+
`SyntaxEditor` applies several occurrence-addressed replacements in one pass.
|
|
122
|
+
`SyntaxAnnotation` marks one occurrence and excludes annotated Green values
|
|
123
|
+
from interning.
|
|
124
|
+
|
|
125
|
+
## Incremental syntax sessions
|
|
126
|
+
|
|
127
|
+
Incremental parsing is Experimental and deliberately syntax-only:
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
source = Ibex::Runtime::CST::SourceText.new("1 + 2", file: "input.txt")
|
|
131
|
+
session = Calculator.incremental_session(source)
|
|
132
|
+
result = session.edit([
|
|
133
|
+
Ibex::Runtime::CST::TextEdit.new(
|
|
134
|
+
start: 4,
|
|
135
|
+
delete_length: 1,
|
|
136
|
+
insert_text: "3"
|
|
137
|
+
)
|
|
138
|
+
])
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The initial parse and every edit suppress parser production actions.
|
|
142
|
+
`SyntaxResult` therefore has `syntax_root`, `diagnostics`, and `reused_ratio`,
|
|
143
|
+
but no semantic value. Generated lexer actions still run because they define
|
|
144
|
+
token emission and lexer-state changes. Run a normal parse separately when a
|
|
145
|
+
semantic value or side effect is required.
|
|
146
|
+
|
|
147
|
+
Sessions require `SourceText`, a generated lexer, format-v6 CST metadata, and
|
|
148
|
+
non-`drop` trivia. Handwritten token sources and push input are unsupported.
|
|
149
|
+
Parser actions that alone switch lexer state are also unavailable because the
|
|
150
|
+
syntax-only contract forbids executing them.
|
|
151
|
+
|
|
152
|
+
The default Stage B path relexes soundly from the beginning, validates old
|
|
153
|
+
token boundaries/states, and directly reuses only subtrees whose LR state,
|
|
154
|
+
follow token, flags, width, and damage range are safe. Pass `blender: false` to
|
|
155
|
+
retain the Stage A full LR drive. `ResourceLimits` bounds decomposition and
|
|
156
|
+
memo bytes; a bound failure deterministically falls back to the fresh token
|
|
157
|
+
stream. Observe `cst_built`, `cst_reuse`, and `cst_fallback` runtime events for
|
|
158
|
+
metrics.
|
|
159
|
+
|
|
160
|
+
## Serialization
|
|
161
|
+
|
|
162
|
+
`ibex_cst` schema v1 is independent from Grammar IR:
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
tables = Calculator.parser_tables
|
|
166
|
+
json = Ibex::Runtime::CST::Serialize.dump(
|
|
167
|
+
session.result.syntax_root,
|
|
168
|
+
grammar_digest: tables.fetch(:grammar_digest),
|
|
169
|
+
table_format: tables.fetch(:format_version),
|
|
170
|
+
state_count: tables.fetch(:state_count),
|
|
171
|
+
production_count: tables.fetch(:production_count),
|
|
172
|
+
memo: session.parse_memo
|
|
173
|
+
)
|
|
174
|
+
loaded = Ibex::Runtime::CST::Serialize.load(
|
|
175
|
+
json,
|
|
176
|
+
grammar_digest: tables.fetch(:grammar_digest),
|
|
177
|
+
state_count: tables.fetch(:state_count),
|
|
178
|
+
production_count: tables.fetch(:production_count)
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Valid UTF-8 bytes use JSON strings; other bytes use canonical Base64 objects.
|
|
183
|
+
Loading rebuilds widths, aggregate flags, and descendant counts. A grammar
|
|
184
|
+
digest mismatch raises `ValidationError`. State or production count mismatch
|
|
185
|
+
silently discards only the optional parse memo. Annotations are session-local
|
|
186
|
+
and cannot be serialized.
|
|
187
|
+
|
|
188
|
+
## Invariants and test coverage
|
|
189
|
+
|
|
190
|
+
The Red/Green contract is continuously exercised by the following repository
|
|
191
|
+
tests:
|
|
192
|
+
|
|
193
|
+
| Invariant | Automated evidence |
|
|
194
|
+
| --- | --- |
|
|
195
|
+
| 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. |
|
|
196
|
+
| 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. |
|
|
197
|
+
| I3 lazy Red navigation | `test/runtime/cst_red_test.rb` checks occurrence-local memoization, offsets, parents, cursors, and deterministic traversal. |
|
|
198
|
+
| 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. |
|
|
199
|
+
| 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. |
|
|
200
|
+
| 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. |
|
|
201
|
+
| 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. |
|
|
202
|
+
| I8 type soundness | CI regenerates the `sig/` tree, runs Steep and RBS validation, and rejects a type-statistics regression. |
|
|
203
|
+
|
|
204
|
+
`test/runtime/cst_incremental_property_test.rb` is the large PT2 authority. Its
|
|
205
|
+
fixed seed generates four grammar shapes and executes 20,000 random edits
|
|
206
|
+
through Stage A plus 20,000 through Stage B, comparing fresh syntax sessions in
|
|
207
|
+
Green structure, bytes, flags, diagnostics, and memo cardinality after every
|
|
208
|
+
edit. `test/runtime/cst_incremental_test.rb` adds focused stateful-lexer,
|
|
209
|
+
fallback, sharing, minimal-diff, action-suppression, no-value, and unsupported
|
|
210
|
+
configuration cases.
|
|
211
|
+
|
|
212
|
+
See [the migration guide](cst-migration.md) for removed tree-shape changes and
|
|
213
|
+
[the stability policy](stability.md) for support levels.
|
data/docs/development.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Development and quality checks
|
|
2
|
+
|
|
3
|
+
This document describes contributor workflow and repository quality gates.
|
|
4
|
+
These practices verify the implementation but are not implementation
|
|
5
|
+
architecture decisions.
|
|
6
|
+
|
|
7
|
+
## Default checks
|
|
8
|
+
|
|
9
|
+
Use Ruby 3.4 or newer, install the complete development toolchain once, and run
|
|
10
|
+
the unit, integration, documentation, and style suite:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
bundle install
|
|
14
|
+
bundle exec rake
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Additional repository checks are:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
bundle exec rake frontend:check
|
|
21
|
+
bundle exec rake grammar:test
|
|
22
|
+
bundle exec rake quality:error_ux
|
|
23
|
+
npm ci
|
|
24
|
+
npm run test:site
|
|
25
|
+
actionlint
|
|
26
|
+
zizmor .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
CI runs the supported Ruby matrix separately from optional experimental Ruby
|
|
30
|
+
implementations. Workflow and dependency-update configuration are authoritative
|
|
31
|
+
for the current matrix, schedules, permissions, and pinned action versions.
|
|
32
|
+
The matrix uses the intentionally unlocked `gemfiles/compat.Gemfile` so each
|
|
33
|
+
supported Ruby resolves compatible test dependencies. Contributors use the
|
|
34
|
+
root `Gemfile` and its committed lockfile for every development tool.
|
|
35
|
+
|
|
36
|
+
## Browser site and API documentation
|
|
37
|
+
|
|
38
|
+
Install the locked browser dependencies and build the same self-hosted site
|
|
39
|
+
bundle exercised in CI:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npm ci
|
|
43
|
+
npm run test:site
|
|
44
|
+
bundle exec yard doc
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`tool/build_site.rb`, the YARD configuration, and
|
|
48
|
+
`.github/workflows/pages.yml` are authoritative for documentation inputs,
|
|
49
|
+
build versions, artifact retention, deployment permissions, and the protected
|
|
50
|
+
Pages environment. Publication runs from `main`; pull requests validate the
|
|
51
|
+
site without receiving deployment credentials.
|
|
52
|
+
|
|
53
|
+
Changing those operational settings does not require an implementation ADR.
|
|
54
|
+
A change to the shipped browser analyzer's worker isolation, execution limits,
|
|
55
|
+
or Ruby/JavaScript data boundary does.
|
|
56
|
+
|
|
57
|
+
## Self-hosted frontend
|
|
58
|
+
|
|
59
|
+
`lib/ibex/frontend/grammar.y` is the production grammar. Regenerate its
|
|
60
|
+
committed parser after changing the frontend language:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
bundle exec rake frontend:generate
|
|
64
|
+
bundle exec rake frontend:check
|
|
65
|
+
bundle exec ruby -Itest test/frontend/self_host_test.rb
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`lib/ibex/frontend/shadow_grammar.y` independently describes the same language
|
|
69
|
+
using parameterized and inline rules. Tests build it through the bootstrap
|
|
70
|
+
frontend and compare its location-preserving AST with the production parser.
|
|
71
|
+
The shadow source must change with the canonical grammar, but it never replaces
|
|
72
|
+
the committed production parser.
|
|
73
|
+
|
|
74
|
+
## RBS and Steep
|
|
75
|
+
|
|
76
|
+
The development bundle includes the type toolchain. Regenerate the committed
|
|
77
|
+
RBS tree, validate it, type-check the library, and refresh the documented
|
|
78
|
+
statistics with:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
ruby -e '
|
|
82
|
+
sources = Dir.glob("lib/**/*.rb").sort
|
|
83
|
+
exec("bundle", "exec", "rbs-inline", "--opt-out", "--base=lib", "--output=sig", *sources)
|
|
84
|
+
'
|
|
85
|
+
bundle exec rbs -r digest -r json -r optparse -r tempfile -r timeout -r tmpdir -r uri -I sig validate
|
|
86
|
+
bundle exec steep check
|
|
87
|
+
bundle exec ruby tool/type_stats.rb --write
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
CI generates signatures into a clean temporary directory and compares the
|
|
91
|
+
complete tree, so both missing and stale signature files fail.
|
|
92
|
+
|
|
93
|
+
## Bounded mutation testing
|
|
94
|
+
|
|
95
|
+
Mutation analysis is part of the development bundle:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
bundle exec rake quality:mutation
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The job uses MRI 4.0, two workers, a ten-minute job budget, and the focused
|
|
102
|
+
`Ibex::Tables::Compact#initialize` matcher. `TablesTest` owns the mutation
|
|
103
|
+
coverage declaration. The mutation environment declares open-source usage and
|
|
104
|
+
applies a one-second timeout to each deterministic mutation. Expanding the
|
|
105
|
+
subject requires an explicit test owner, no surviving non-equivalent mutations,
|
|
106
|
+
and a measured duration within the same bounded job.
|
|
107
|
+
|
|
108
|
+
The supported runtime matrix uses `gemfiles/compat.Gemfile`, so the mutation
|
|
109
|
+
tool's Ruby floor does not change the library's Ruby floor.
|
|
110
|
+
|
|
111
|
+
## Benchmarks and evidence
|
|
112
|
+
|
|
113
|
+
Performance observations are not ordinary CI timing thresholds. Follow the
|
|
114
|
+
[benchmark guide](../benchmark/README.md) for workload identities, formal
|
|
115
|
+
comparison commands, environment matching, artifact validation, and
|
|
116
|
+
append-only result history.
|
|
117
|
+
|
|
118
|
+
The development bundle includes the exact-version external-grammar profiler:
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
bundle exec ruby benchmark/public_profile.rb --help
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Its output is diagnostic-only and must remain outside `benchmark/results/`.
|
|
125
|
+
Use it to locate costs, then repeat the uninstrumented public comparison to
|
|
126
|
+
produce reviewable performance evidence.
|
|
127
|
+
|
|
128
|
+
The versioned error-experience snapshot and its review procedure live in
|
|
129
|
+
[`docs/error-ux.md`](error-ux.md).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Editor setup
|
|
2
|
+
|
|
3
|
+
Ibex ships an LSP 3.17 server for grammar files:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
ibex lsp --stdio
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Configure an editor language client to start that command for `.y` files and pass the project directory as `rootUri` or an
|
|
10
|
+
initial `workspaceFolders` entry. The server uses standard Content-Length framing on stdin/stdout. Do not wrap it with a command
|
|
11
|
+
that writes banners or logs to stdout; Ibex writes its own logs to stderr.
|
|
12
|
+
|
|
13
|
+
The server negotiates UTF-16 positions and full-document text synchronization. It provides:
|
|
14
|
+
|
|
15
|
+
- bounded parse and include diagnostics, including unsaved included fragments;
|
|
16
|
+
- definition and references for rules, formal parameters, terminals, and include targets;
|
|
17
|
+
- guarded cross-file prepare-rename and rename; and
|
|
18
|
+
- hover for rule signatures/documentation, terminal metadata/precedence, and include targets.
|
|
19
|
+
|
|
20
|
+
Only local `file:` URIs below the initialized workspace roots are accepted. Symlink escapes, traversal, remote authorities,
|
|
21
|
+
query/fragment URI components, and ambiguous encoded separators are rejected. Open buffers override disk until `didClose`;
|
|
22
|
+
closing first clears the buffer diagnostics and then restores the disk snapshot.
|
|
23
|
+
|
|
24
|
+
For a generic editor configuration, use command `ibex`, arguments `lsp --stdio`, language id `ibex`, and file pattern `*.y`.
|
|
25
|
+
Ibex never executes semantic actions or `header`, `inner`, or `footer` code while serving editor requests.
|
data/docs/error-ux.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# JSON error UX evidence
|
|
2
|
+
|
|
3
|
+
This report fixes the Phase 14 error-experience baseline against ten malformed
|
|
4
|
+
inputs for the gallery JSON grammar. It is generated from
|
|
5
|
+
[`json-errors-v1.json`](../test/fixtures/error_ux/json-errors-v1.json) by:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
bundle exec ruby tool/error_ux_snapshot.rb
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Use `--write` only after reviewing a deliberate diagnostic, parser-table, racc,
|
|
12
|
+
or repair-policy change. CI regenerates the evidence and requires byte-for-byte
|
|
13
|
+
equality.
|
|
14
|
+
|
|
15
|
+
## Comparison method
|
|
16
|
+
|
|
17
|
+
Ibex uses [`examples/json.y`](../examples/json.y), including its generated
|
|
18
|
+
lexer locations. The migration from its previous handwritten lexer is guarded
|
|
19
|
+
by exact location and error-snapshot tests. The comparison uses the self-authored compatible grammar
|
|
20
|
+
[`json_racc.y`](../test/fixtures/error_ux/json_racc.y), racc 1.8.1, and only the
|
|
21
|
+
public `racc` executable and `on_error(token, value, value_stack)` callback.
|
|
22
|
+
Neither racc implementation files nor generated source are inspected. Both
|
|
23
|
+
parsers receive the same source strings and equivalent token streams.
|
|
24
|
+
|
|
25
|
+
The racc column records the neutral callback wrapper's token argument. It does
|
|
26
|
+
not claim that an application cannot build richer diagnostics around racc; it
|
|
27
|
+
shows what the compared parser runtime exposes at that boundary without an
|
|
28
|
+
additional state-to-message layer.
|
|
29
|
+
|
|
30
|
+
| Case | Invalid source | Ibex diagnostic evidence | racc callback | Selected repair | Useful |
|
|
31
|
+
|---|---|---|---|---|---|
|
|
32
|
+
| EUX-01 | `{"a":,}` | line 1, column 6; 7 expected values; caret | token 9 | delete `,`, insert `STRING` | yes |
|
|
33
|
+
| EUX-02 | `{"a" 1}` | line 1, column 6; expected `:`; caret | token 3 | insert `:` | yes |
|
|
34
|
+
| EUX-03 | `{"a":1,}` | line 1, column 8; expected `STRING`; caret | token 8 | insert a complete member | no |
|
|
35
|
+
| EUX-04 | `[1,]` | line 1, column 4; 7 expected values; caret | token 12 | insert `STRING` | no |
|
|
36
|
+
| EUX-05 | `[1 2]` | line 1, column 4; expected `,` or `]`; caret | token 3 | insert `,` | yes |
|
|
37
|
+
| EUX-06 | `{"a":[true false]}` | line 1, column 12; expected `,` or `]`; caret | token 5 | insert `,` | yes |
|
|
38
|
+
| EUX-07 | `{"a":null "b":2}` | line 1, column 11; expected `}` or `,`; caret | token 2 | insert `,` | yes |
|
|
39
|
+
| EUX-08 | `{]` | line 1, column 2; expected `STRING` or `}`; caret | token 12 | replace `]` with `}` | yes |
|
|
40
|
+
| EUX-09 | `[}` | line 1, column 2; 8 expected values/closer; caret | token 8 | replace `}` with `]` | yes |
|
|
41
|
+
| EUX-10 | `true false` | line 1, column 6; expected EOF; caret | token 5 | delete extra `FALSE` | yes |
|
|
42
|
+
|
|
43
|
+
The committed JSON is the normative snapshot and also retains exact messages,
|
|
44
|
+
LR states, expected-token arrays, token values, repair costs, configuration
|
|
45
|
+
counts, and edit positions. Its public structure is validated by
|
|
46
|
+
[`schema/error-ux-v1.schema.json`](../schema/error-ux-v1.schema.json).
|
|
47
|
+
|
|
48
|
+
## SP-4 decision
|
|
49
|
+
|
|
50
|
+
The bounded insertion/deletion/replacement search produced a completing plan
|
|
51
|
+
for all ten cases. Eight plans are reasonable representations of the likely
|
|
52
|
+
human edit; two trailing-comma cases invent a missing value/member where
|
|
53
|
+
deleting the comma would usually be preferable. The measured useful rate is
|
|
54
|
+
therefore **8/10 (80%)**, above the required majority.
|
|
55
|
+
|
|
56
|
+
SP-4 is **go** for the existing opt-in bounded single-plan repair described by
|
|
57
|
+
[ADR 0012](decisions/0012-bounded-nonexecuting-analysis.md). It remains
|
|
58
|
+
experimental: a selected edit can require a nil semantic value, and the search
|
|
59
|
+
does not enumerate every equal-cost CPCT+ repair. The stable default answer
|
|
60
|
+
remains exact expected tokens plus explicit yacc/synchronization recovery.
|