ibex 0.2.0 → 0.4.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 +100 -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 +274 -0
- data/docs/development.md +196 -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 +1617 -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/impact.md +101 -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 +129 -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 +310 -0
- data/docs/stability.md +145 -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/sets.rb +14 -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/impact.rb +393 -0
- 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 +362 -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 +141 -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/impact/action_impact.rb +148 -0
- data/lib/ibex/impact/automaton_impact.rb +57 -0
- data/lib/ibex/impact/coverage_impact.rb +53 -0
- data/lib/ibex/impact/graph.rb +132 -0
- data/lib/ibex/impact/propagation.rb +147 -0
- data/lib/ibex/impact/report.rb +273 -0
- data/lib/ibex/impact/seeds.rb +69 -0
- data/lib/ibex/impact/severity.rb +139 -0
- data/lib/ibex/impact.rb +16 -0
- 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 +11 -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/impact-v1.schema.json +208 -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/analysis/sets.rbs +10 -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/impact.rbs +95 -0
- 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/impact/action_impact.rbs +58 -0
- data/sig/ibex/impact/automaton_impact.rbs +37 -0
- data/sig/ibex/impact/coverage_impact.rbs +28 -0
- data/sig/ibex/impact/graph.rbs +67 -0
- data/sig/ibex/impact/propagation.rbs +56 -0
- data/sig/ibex/impact/report.rbs +107 -0
- data/sig/ibex/impact/seeds.rbs +36 -0
- data/sig/ibex/impact/severity.rbs +55 -0
- data/sig/ibex/impact.rbs +6 -0
- 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 +254 -12
- data/lib/ibex/ir/migration.rb +0 -120
- data/sig/ibex/ir/migration.rbs +0 -34
|
@@ -57,7 +57,7 @@ module Ibex
|
|
|
57
57
|
|
|
58
58
|
offsets = line_offsets
|
|
59
59
|
tokens = Object.const_get(:Ripper).__send__(:lex, lexable_source)
|
|
60
|
-
# @type var tokens: Array[[[Integer, Integer], Symbol, String,
|
|
60
|
+
# @type var tokens: Array[[[Integer, Integer], Symbol, String, Object?]]
|
|
61
61
|
tokens.filter_map do |position, type, _token, _state|
|
|
62
62
|
next unless type == :on_ident
|
|
63
63
|
|
|
@@ -17,7 +17,7 @@ module Ibex
|
|
|
17
17
|
@generated_action_abi = generated_action_abi || GeneratedActionABI::Cache.new
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# @rbs (IR::Production production,
|
|
20
|
+
# @rbs (IR::Production production, IR::action_composition_step step, Integer index) -> String
|
|
21
21
|
def composed_fragment_method_source(production, step, index)
|
|
22
22
|
source = "private def #{composed_fragment_name(production, index)}" \
|
|
23
23
|
"(val, _values, _ibex_locations, _ibex_location_stack, _ibex_location); "
|
|
@@ -97,7 +97,7 @@ module Ibex
|
|
|
97
97
|
|
|
98
98
|
require "ripper"
|
|
99
99
|
tokens = Object.const_get(:Ripper).__send__(:lex, source)
|
|
100
|
-
# @type var tokens: Array[
|
|
100
|
+
# @type var tokens: Array[GeneratedActionABI::ripper_token]
|
|
101
101
|
tokens.any? { |_position, event, _token, _state| event == :on_heredoc_beg }
|
|
102
102
|
end
|
|
103
103
|
|
|
@@ -149,12 +149,11 @@ module Ibex
|
|
|
149
149
|
end
|
|
150
150
|
end
|
|
151
151
|
|
|
152
|
-
# @rbs (
|
|
152
|
+
# @rbs (IR::action_composition_step step) -> String
|
|
153
153
|
def composed_semantic_code(step)
|
|
154
154
|
maximum = [step.fetch(:inputs).length, step.fetch(:context_length)].max
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
).rewrite
|
|
155
|
+
code = step.fetch(:code) #: String
|
|
156
|
+
ActionLocations.new(code, maximum: maximum, location: step.fetch(:loc)).rewrite
|
|
158
157
|
end
|
|
159
158
|
|
|
160
159
|
# @rbs (String source, Array[IR::named_ref] named_refs) -> void
|
|
@@ -49,7 +49,8 @@ module Ibex
|
|
|
49
49
|
def append_value_printers(lines)
|
|
50
50
|
@grammar.value_printers.each do |printer|
|
|
51
51
|
symbol = @grammar.symbol(printer[:symbol]) || raise(Ibex::Error, "missing printer symbol #{printer[:symbol]}")
|
|
52
|
-
|
|
52
|
+
location = printer.fetch(:loc) #: IR::location
|
|
53
|
+
append_method(lines, location, @method_source.value_printer_method_source(symbol.id, printer))
|
|
53
54
|
end
|
|
54
55
|
end
|
|
55
56
|
|
|
@@ -83,7 +84,7 @@ module Ibex
|
|
|
83
84
|
|
|
84
85
|
# @rbs (Array[String] lines, IR::Production production) -> void
|
|
85
86
|
def append_action(lines, production)
|
|
86
|
-
location = production.action&.location || production.origin.fetch(:loc)
|
|
87
|
+
location = production.action&.location || production.origin.fetch(:loc) #: IR::location
|
|
87
88
|
append_method(lines, location, @method_source.compiled_action_method_source(production))
|
|
88
89
|
end
|
|
89
90
|
|
|
@@ -134,17 +134,18 @@ module Ibex
|
|
|
134
134
|
@automaton, state, conflict,
|
|
135
135
|
max_tokens: @max_tokens, max_configurations: @max_configurations
|
|
136
136
|
)
|
|
137
|
-
|
|
137
|
+
outcome = search.call
|
|
138
|
+
result = outcome[:result]
|
|
138
139
|
{
|
|
139
140
|
state: state.id,
|
|
140
141
|
type: conflict.fetch(:type).to_s,
|
|
141
142
|
token: conflict.fetch(:symbol),
|
|
142
|
-
result:
|
|
143
|
+
result: outcome[:status] == :found ? "ambiguous" : "not_found",
|
|
143
144
|
sentence: result ? symbol_names(result.fetch(:sentence_ids)) : [],
|
|
144
145
|
lookahead_index: result&.fetch(:lookahead_index),
|
|
145
146
|
interpretations: result ? result.fetch(:interpretations) : [],
|
|
146
|
-
explored_configurations:
|
|
147
|
-
configuration_budget_exhausted:
|
|
147
|
+
explored_configurations: outcome.fetch(:explored),
|
|
148
|
+
configuration_budget_exhausted: outcome.fetch(:exhausted)
|
|
148
149
|
}
|
|
149
150
|
end
|
|
150
151
|
|
data/lib/ibex/codegen/explain.rb
CHANGED
|
@@ -15,8 +15,20 @@ module Ibex
|
|
|
15
15
|
# type explain_entry = {
|
|
16
16
|
# state: IR::AutomatonState,
|
|
17
17
|
# conflict: IR::conflict,
|
|
18
|
-
# example:
|
|
18
|
+
# example: LALR::search_counterexample
|
|
19
19
|
# }
|
|
20
|
+
#
|
|
21
|
+
# type explain_token = { name: String, display_name: String?, label: String, ?query: String }
|
|
22
|
+
# type explain_alternative = { kind: String, ?state: Integer, ?production: Integer }
|
|
23
|
+
# type explain_search = {
|
|
24
|
+
# status: String, explored: Integer, exhausted: bool, bounds: Hash[Symbol, Integer]
|
|
25
|
+
# }
|
|
26
|
+
# type explain_tree_node = {
|
|
27
|
+
# ?symbol: explain_token, ?token: explain_token, ?production: Integer, ?children: Array[explain_tree]
|
|
28
|
+
# }
|
|
29
|
+
# type explain_tree = untyped
|
|
30
|
+
# type explain_interpretation = Hash[Symbol, untyped]
|
|
31
|
+
# type string_value = String | Integer | Symbol
|
|
20
32
|
|
|
21
33
|
# Renders a selected conflict explanation from Automaton IR and counterexamples.
|
|
22
34
|
# rubocop:disable Metrics/ClassLength -- inline contracts and two stable output formats stay near selection policy.
|
|
@@ -39,42 +51,50 @@ module Ibex
|
|
|
39
51
|
@entries = select_entries
|
|
40
52
|
end
|
|
41
53
|
|
|
42
|
-
# @rbs () -> Hash[Symbol,
|
|
54
|
+
# @rbs () -> Hash[Symbol, Object?]
|
|
43
55
|
def to_h
|
|
44
|
-
|
|
56
|
+
entries = @entries #: Array[explain_entry]
|
|
57
|
+
automaton = @automaton #: IR::Automaton
|
|
58
|
+
unifying = entries.count { |entry| entry.fetch(:example).fetch(:unifying) }
|
|
59
|
+
inconclusive = entries.count { |entry| entry.fetch(:example).fetch(:inconclusive) }
|
|
45
60
|
{
|
|
46
61
|
ibex_explain: "conflicts",
|
|
47
62
|
schema_version: SCHEMA_VERSION,
|
|
48
|
-
algorithm:
|
|
63
|
+
algorithm: automaton.algorithm,
|
|
49
64
|
selectors: {
|
|
50
65
|
state: @state_selector,
|
|
51
66
|
token: @token_selector && token_reference(@token_selector, query: @token_query)
|
|
52
67
|
},
|
|
53
68
|
search: { max_tokens: @max_tokens, max_configurations: @max_configurations },
|
|
54
69
|
summary: {
|
|
55
|
-
matched_conflicts:
|
|
70
|
+
matched_conflicts: entries.length,
|
|
56
71
|
unifying_counterexamples: unifying,
|
|
57
|
-
nonunifying_witnesses:
|
|
72
|
+
nonunifying_witnesses: entries.length - unifying - inconclusive,
|
|
73
|
+
inconclusive_searches: inconclusive
|
|
58
74
|
},
|
|
59
|
-
conflicts:
|
|
75
|
+
conflicts: entries.map { |entry| conflict_document(entry) }
|
|
60
76
|
}
|
|
61
77
|
end
|
|
62
78
|
|
|
63
79
|
# @rbs () -> String
|
|
64
80
|
def render_text
|
|
81
|
+
automaton = @automaton #: IR::Automaton
|
|
82
|
+
entries = @entries #: Array[explain_entry]
|
|
83
|
+
state_selector = @state_selector #: Integer?
|
|
84
|
+
token_selector = @token_selector #: IR::GrammarSymbol?
|
|
65
85
|
lines = [
|
|
66
86
|
"Ibex conflict explanation v#{SCHEMA_VERSION}",
|
|
67
|
-
"Algorithm: #{
|
|
68
|
-
"State selector: #{
|
|
69
|
-
"Token selector: #{
|
|
87
|
+
"Algorithm: #{automaton.algorithm}",
|
|
88
|
+
"State selector: #{state_selector || 'all'}",
|
|
89
|
+
"Token selector: #{token_selector ? token_label(token_selector, query: @token_query) : 'all'}",
|
|
70
90
|
"Search budget: #{@max_tokens} tokens, #{@max_configurations} configurations",
|
|
71
|
-
"Matched conflicts: #{
|
|
91
|
+
"Matched conflicts: #{entries.length}",
|
|
72
92
|
""
|
|
73
93
|
]
|
|
74
|
-
if
|
|
94
|
+
if entries.empty?
|
|
75
95
|
lines << "No conflicts matched the selectors."
|
|
76
96
|
else
|
|
77
|
-
|
|
97
|
+
entries.each_with_index { |entry, index| append_conflict(lines, entry, index + 1) }
|
|
78
98
|
end
|
|
79
99
|
"#{lines.join("\n")}\n"
|
|
80
100
|
end
|
|
@@ -85,10 +105,11 @@ module Ibex
|
|
|
85
105
|
def resolve_token(query)
|
|
86
106
|
return unless query
|
|
87
107
|
|
|
88
|
-
|
|
108
|
+
grammar = @grammar #: IR::Grammar
|
|
109
|
+
canonical = grammar.terminals.find { |symbol| symbol.name == query }
|
|
89
110
|
return canonical if canonical
|
|
90
111
|
|
|
91
|
-
displayed =
|
|
112
|
+
displayed = grammar.terminals.select { |symbol| symbol.display_name == query }
|
|
92
113
|
return displayed.first if displayed.one?
|
|
93
114
|
|
|
94
115
|
if displayed.length > 1
|
|
@@ -102,10 +123,12 @@ module Ibex
|
|
|
102
123
|
|
|
103
124
|
# @rbs () -> void
|
|
104
125
|
def validate_state!
|
|
105
|
-
|
|
106
|
-
|
|
126
|
+
state_selector = @state_selector #: Integer?
|
|
127
|
+
automaton = @automaton #: IR::Automaton
|
|
128
|
+
return unless state_selector
|
|
129
|
+
return if state_selector >= 0 && automaton.states.any? { |state| state.id == state_selector }
|
|
107
130
|
|
|
108
|
-
raise Ibex::Error, "(cli):1:1: unknown automaton state #{
|
|
131
|
+
raise Ibex::Error, "(cli):1:1: unknown automaton state #{state_selector}"
|
|
109
132
|
end
|
|
110
133
|
|
|
111
134
|
# @rbs () -> Array[explain_entry]
|
|
@@ -113,8 +136,9 @@ module Ibex
|
|
|
113
136
|
selections = selected_conflicts
|
|
114
137
|
return [] if selections.empty?
|
|
115
138
|
|
|
139
|
+
automaton = @automaton #: IR::Automaton
|
|
116
140
|
counterexamples = LALR::Counterexample.new(
|
|
117
|
-
|
|
141
|
+
automaton, max_tokens: @max_tokens, max_configurations: @max_configurations
|
|
118
142
|
)
|
|
119
143
|
selections.map do |selection|
|
|
120
144
|
state = selection.fetch(:state)
|
|
@@ -128,17 +152,20 @@ module Ibex
|
|
|
128
152
|
|
|
129
153
|
# @rbs () -> Array[explain_selection]
|
|
130
154
|
def selected_conflicts
|
|
131
|
-
@automaton
|
|
155
|
+
automaton = @automaton #: IR::Automaton
|
|
156
|
+
state_selector = @state_selector #: Integer?
|
|
157
|
+
token_selector = @token_selector #: IR::GrammarSymbol?
|
|
158
|
+
automaton.states.flat_map do |state|
|
|
132
159
|
state.conflicts.each_with_index.filter_map do |conflict, conflict_index|
|
|
133
|
-
next if
|
|
134
|
-
next if
|
|
160
|
+
next if state_selector && state.id != state_selector
|
|
161
|
+
next if token_selector && conflict[:symbol] != token_selector.name
|
|
135
162
|
|
|
136
163
|
{ state: state, conflict: conflict, conflict_index: conflict_index }
|
|
137
164
|
end
|
|
138
165
|
end
|
|
139
166
|
end
|
|
140
167
|
|
|
141
|
-
# @rbs (explain_entry entry) -> Hash[Symbol,
|
|
168
|
+
# @rbs (explain_entry entry) -> Hash[Symbol, Object?]
|
|
142
169
|
def conflict_document(entry)
|
|
143
170
|
state = entry.fetch(:state)
|
|
144
171
|
conflict = entry.fetch(:conflict)
|
|
@@ -150,69 +177,97 @@ module Ibex
|
|
|
150
177
|
alternatives: conflict_alternatives(conflict),
|
|
151
178
|
resolution: string_values(conflict.fetch(:resolution)),
|
|
152
179
|
witness: {
|
|
153
|
-
kind: example
|
|
180
|
+
kind: witness_kind(example),
|
|
154
181
|
sentence: example.fetch(:sentence).map { |name| symbol_reference(name) },
|
|
155
182
|
lookahead_index: example.fetch(:lookahead_index),
|
|
156
183
|
symbol_path: example.fetch(:symbol_path).map { |name| symbol_reference(name) },
|
|
184
|
+
search: search_document(example.fetch(:search)),
|
|
157
185
|
interpretations: example.fetch(:interpretations).map { |item| interpretation_document(item) }
|
|
158
186
|
}
|
|
159
|
-
} #: Hash[Symbol,
|
|
187
|
+
} #: Hash[Symbol, Object?]
|
|
160
188
|
document[:midrule_origins] = conflict[:midrule_origins] if conflict[:midrule_origins]
|
|
161
189
|
document
|
|
162
190
|
end
|
|
163
191
|
|
|
164
|
-
# @rbs (
|
|
192
|
+
# @rbs (LALR::search_counterexample example) -> String
|
|
193
|
+
def witness_kind(example)
|
|
194
|
+
return "unifying_counterexample" if example.fetch(:unifying)
|
|
195
|
+
return "inconclusive" if example.fetch(:inconclusive)
|
|
196
|
+
|
|
197
|
+
"nonunifying_witness"
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# @rbs (LALR::search_outcome outcome) -> explain_search
|
|
201
|
+
def search_document(outcome)
|
|
202
|
+
{
|
|
203
|
+
status: outcome.fetch(:status).to_s,
|
|
204
|
+
explored: outcome.fetch(:explored),
|
|
205
|
+
exhausted: outcome.fetch(:exhausted),
|
|
206
|
+
bounds: outcome.fetch(:bounds)
|
|
207
|
+
}
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# @rbs (IR::conflict conflict) -> Array[explain_alternative]
|
|
165
211
|
def conflict_alternatives(conflict)
|
|
166
212
|
case conflict[:type]
|
|
167
213
|
when :shift_reduce
|
|
168
|
-
|
|
169
|
-
|
|
214
|
+
shift = { kind: "shift", state: conflict.fetch(:shift_to) } # @type var shift: explain_alternative
|
|
215
|
+
reduce = { kind: "reduce", production: conflict.fetch(:reduce) } # @type var reduce: explain_alternative
|
|
216
|
+
[shift, reduce]
|
|
170
217
|
when :reduce_reduce
|
|
171
218
|
reduce_reduce = conflict #: IR::reduce_reduce_conflict
|
|
172
|
-
reduce_reduce[:reductions].map
|
|
219
|
+
reduce_reduce[:reductions].map do |production|
|
|
220
|
+
{ kind: "reduce", production: production }
|
|
221
|
+
end #: Array[explain_alternative]
|
|
173
222
|
else
|
|
174
223
|
[]
|
|
175
224
|
end
|
|
176
225
|
end
|
|
177
226
|
|
|
178
|
-
# @rbs (IR::interpretation interpretation) ->
|
|
227
|
+
# @rbs (IR::interpretation interpretation) -> explain_interpretation
|
|
179
228
|
def interpretation_document(interpretation)
|
|
180
|
-
|
|
181
|
-
|
|
229
|
+
kind = interpretation.fetch(:kind) #: Symbol
|
|
230
|
+
tree = interpretation.fetch(:tree) #: explain_tree
|
|
231
|
+
value = { kind: kind.to_s,
|
|
232
|
+
tree: tree_document(tree) } # @type var value: explain_interpretation
|
|
182
233
|
value[:state] = interpretation[:state] if interpretation.key?(:state)
|
|
183
234
|
value[:production] = interpretation[:production] if interpretation.key?(:production)
|
|
184
235
|
value
|
|
185
236
|
end
|
|
186
237
|
|
|
187
|
-
# @rbs (
|
|
238
|
+
# @rbs (explain_tree tree) -> explain_tree
|
|
188
239
|
def tree_document(tree)
|
|
189
240
|
return symbol_reference(tree.to_s) unless tree.is_a?(Hash)
|
|
190
241
|
|
|
191
|
-
|
|
192
|
-
value
|
|
193
|
-
value[:
|
|
194
|
-
value[:
|
|
195
|
-
value[:
|
|
242
|
+
node = tree #: explain_tree_node
|
|
243
|
+
value = {} # @type var value: explain_tree_node
|
|
244
|
+
value[:symbol] = symbol_reference(node[:symbol].to_s) if node[:symbol]
|
|
245
|
+
value[:token] = symbol_reference(node[:token].to_s) if node[:token]
|
|
246
|
+
value[:production] = node[:production] if node[:production]
|
|
247
|
+
value[:children] = node[:children].map { |child| tree_document(child) } if node[:children]
|
|
196
248
|
value
|
|
197
249
|
end
|
|
198
250
|
|
|
199
|
-
# @rbs (Hash[Symbol,
|
|
251
|
+
# @rbs (Hash[Symbol, string_value] value) -> Hash[Symbol, string_value]
|
|
200
252
|
def string_values(value)
|
|
201
|
-
value
|
|
253
|
+
values = value #: Hash[Symbol, string_value]
|
|
254
|
+
values.transform_values { |item| item.is_a?(Symbol) ? item.to_s : item }
|
|
202
255
|
end
|
|
203
256
|
|
|
204
|
-
# @rbs (String name) ->
|
|
257
|
+
# @rbs (String name) -> explain_token
|
|
205
258
|
def symbol_reference(name)
|
|
206
|
-
|
|
259
|
+
grammar = @grammar #: IR::Grammar
|
|
260
|
+
symbol = grammar.symbol(name)
|
|
207
261
|
return { name: name, display_name: nil, label: name } unless symbol
|
|
208
262
|
|
|
209
263
|
token_reference(symbol)
|
|
210
264
|
end
|
|
211
265
|
|
|
212
|
-
# @rbs (IR::GrammarSymbol symbol, ?query: String?) ->
|
|
266
|
+
# @rbs (IR::GrammarSymbol symbol, ?query: String?) -> explain_token
|
|
213
267
|
def token_reference(symbol, query: nil)
|
|
268
|
+
labels = @labels #: Hash[Integer, String]
|
|
214
269
|
value = { name: symbol.name, display_name: symbol.display_name,
|
|
215
|
-
label:
|
|
270
|
+
label: labels.fetch(symbol.id, symbol.name) } # @type var value: explain_token
|
|
216
271
|
value[:query] = query if query
|
|
217
272
|
value
|
|
218
273
|
end
|
|
@@ -222,14 +277,18 @@ module Ibex
|
|
|
222
277
|
state = entry.fetch(:state)
|
|
223
278
|
conflict = entry.fetch(:conflict)
|
|
224
279
|
example = entry.fetch(:example)
|
|
225
|
-
|
|
280
|
+
grammar = @grammar #: IR::Grammar
|
|
281
|
+
token = grammar.symbol(conflict.fetch(:symbol))
|
|
226
282
|
token_text = token ? token_label(token) : conflict.fetch(:symbol)
|
|
227
283
|
type = conflict.fetch(:type).to_s.tr("_", "/")
|
|
228
284
|
lines << "Conflict #{number}: state #{state.id}, #{type}, token #{token_text}"
|
|
229
285
|
append_midrule_origins(lines, conflict)
|
|
230
286
|
append_witness_steps(lines, state, conflict, example)
|
|
231
287
|
append_interpretations(lines, example)
|
|
232
|
-
|
|
288
|
+
if example.fetch(:inconclusive)
|
|
289
|
+
search = example.fetch(:search)
|
|
290
|
+
lines << " Search exhausted after #{search.fetch(:explored)} configurations; classification is inconclusive."
|
|
291
|
+
elsif !example.fetch(:unifying)
|
|
233
292
|
lines << " The search found no shared sentence within the configured budget; this witness is deterministic."
|
|
234
293
|
end
|
|
235
294
|
lines << ""
|
|
@@ -246,12 +305,16 @@ module Ibex
|
|
|
246
305
|
end
|
|
247
306
|
|
|
248
307
|
# @rbs (Array[String] lines, IR::AutomatonState state, IR::conflict conflict,
|
|
249
|
-
#
|
|
308
|
+
# LALR::search_counterexample example) -> void
|
|
250
309
|
def append_witness_steps(lines, state, conflict, example)
|
|
251
310
|
lines << " 1. Reach state #{state.id} with the witness prefix."
|
|
252
311
|
sentence = example.fetch(:sentence).map { |name| display_name(name) }
|
|
253
312
|
sentence.insert(example.fetch(:lookahead_index), "•")
|
|
254
|
-
kind = example
|
|
313
|
+
kind = case witness_kind(example)
|
|
314
|
+
when "unifying_counterexample" then "Unifying counterexample"
|
|
315
|
+
when "inconclusive" then "Inconclusive reachability witness"
|
|
316
|
+
else "Nonunifying reachability witness"
|
|
317
|
+
end
|
|
255
318
|
lines << " #{kind}: #{sentence.join(' ')}"
|
|
256
319
|
lines << " 2. The lookahead permits these competing actions:"
|
|
257
320
|
conflict_alternatives(conflict).each { |alternative| lines << " - #{alternative_text(alternative)}" }
|
|
@@ -259,7 +322,7 @@ module Ibex
|
|
|
259
322
|
lines << " 3. Resolution: #{resolution.fetch(:by)} chose #{resolution.fetch(:chose)}."
|
|
260
323
|
end
|
|
261
324
|
|
|
262
|
-
# @rbs (Array[String] lines,
|
|
325
|
+
# @rbs (Array[String] lines, LALR::search_counterexample example) -> void
|
|
263
326
|
def append_interpretations(lines, example)
|
|
264
327
|
lines << " Competing derivations:"
|
|
265
328
|
example.fetch(:interpretations).each_with_index do |interpretation, index|
|
|
@@ -268,24 +331,25 @@ module Ibex
|
|
|
268
331
|
end
|
|
269
332
|
end
|
|
270
333
|
|
|
271
|
-
# @rbs (
|
|
334
|
+
# @rbs (explain_alternative alternative) -> String
|
|
272
335
|
def alternative_text(alternative)
|
|
273
336
|
return "shift to state #{alternative.fetch(:state)}" if alternative.fetch(:kind) == "shift"
|
|
274
337
|
|
|
275
338
|
"reduce by production #{alternative.fetch(:production)}"
|
|
276
339
|
end
|
|
277
340
|
|
|
278
|
-
# @rbs (Array[String] lines,
|
|
341
|
+
# @rbs (Array[String] lines, explain_tree tree, String prefix, String connector) -> void
|
|
279
342
|
def append_tree(lines, tree, prefix, connector)
|
|
280
343
|
unless tree.is_a?(Hash)
|
|
281
344
|
lines << "#{prefix}#{connector}#{display_name(tree.to_s)}"
|
|
282
345
|
return
|
|
283
346
|
end
|
|
284
347
|
|
|
285
|
-
|
|
286
|
-
|
|
348
|
+
node = tree #: explain_tree_node
|
|
349
|
+
name = node[:symbol] || node[:token]
|
|
350
|
+
production = node[:production] ? " (production #{node[:production]})" : ""
|
|
287
351
|
lines << "#{prefix}#{connector}#{display_name(name.to_s)}#{production}"
|
|
288
|
-
children =
|
|
352
|
+
children = node.fetch(:children, [])
|
|
289
353
|
continuation = { "" => "", "|- " => "| " }.fetch(connector, " ")
|
|
290
354
|
child_prefix = "#{prefix}#{continuation}"
|
|
291
355
|
children.each_with_index do |child, index|
|
|
@@ -305,7 +369,11 @@ module Ibex
|
|
|
305
369
|
end
|
|
306
370
|
|
|
307
371
|
# @rbs (String name) -> String
|
|
308
|
-
def display_name(name)
|
|
372
|
+
def display_name(name)
|
|
373
|
+
grammar = @grammar #: IR::Grammar
|
|
374
|
+
labels = @labels #: Hash[Integer, String]
|
|
375
|
+
grammar.symbol(name)&.then { |symbol| labels.fetch(symbol.id, symbol.name) } || name
|
|
376
|
+
end
|
|
309
377
|
end
|
|
310
378
|
# rubocop:enable Metrics/ClassLength
|
|
311
379
|
end
|
|
@@ -9,6 +9,10 @@ module Ibex
|
|
|
9
9
|
# action's declared inputs.
|
|
10
10
|
# rubocop:disable Metrics/ModuleLength -- ABI proof and source rewriting must evolve together.
|
|
11
11
|
module GeneratedActionABI
|
|
12
|
+
# @rbs!
|
|
13
|
+
# type ripper_token = [[Integer, Integer], Symbol, String, Integer]
|
|
14
|
+
# type sexp_value = Symbol | String | Integer | nil | Array[sexp_value]
|
|
15
|
+
|
|
12
16
|
LEGACY_PARAMETERS = %w[
|
|
13
17
|
_values
|
|
14
18
|
_ibex_locations
|
|
@@ -148,6 +152,7 @@ module Ibex
|
|
|
148
152
|
assignment = /\Aresult\s*=\s*(.*)\z/m.match(body)
|
|
149
153
|
body = (assignment[1] || "").strip if assignment
|
|
150
154
|
return false if body.empty? || body.match?(/(?<![=!<>])=(?!=|>)/)
|
|
155
|
+
return true unless body.match?(/\bval\b/)
|
|
151
156
|
|
|
152
157
|
without_reads = body.gsub(/\bval\[\s*\d+\s*\]/, "")
|
|
153
158
|
without_reads != body && !without_reads.match?(/\bval\b/)
|
|
@@ -188,7 +193,7 @@ module Ibex
|
|
|
188
193
|
end
|
|
189
194
|
private_class_method :simple_indexed_positional_action_source
|
|
190
195
|
|
|
191
|
-
# @rbs (Array[
|
|
196
|
+
# @rbs (Array[ripper_token] tokens, Array[String] parameters) -> String?
|
|
192
197
|
def rewrite_positional_values(tokens, parameters)
|
|
193
198
|
result = [] #: Array[String]
|
|
194
199
|
index = 0
|
|
@@ -219,7 +224,7 @@ module Ibex
|
|
|
219
224
|
end
|
|
220
225
|
private_class_method :rewrite_positional_values
|
|
221
226
|
|
|
222
|
-
# @rbs (Array[
|
|
227
|
+
# @rbs (Array[ripper_token] tokens, Integer index, Array[String] parameters) -> [String, Integer]?
|
|
223
228
|
def positional_value_reference(tokens, index, parameters)
|
|
224
229
|
return nil if receiver_before_value?(tokens, index)
|
|
225
230
|
|
|
@@ -234,7 +239,7 @@ module Ibex
|
|
|
234
239
|
end
|
|
235
240
|
private_class_method :positional_value_reference
|
|
236
241
|
|
|
237
|
-
# @rbs (Array[
|
|
242
|
+
# @rbs (Array[ripper_token] tokens, Integer index) -> bool
|
|
238
243
|
def receiver_before_value?(tokens, index)
|
|
239
244
|
previous = tokens.first(index).reverse.find do |entry|
|
|
240
245
|
!%i[on_sp on_nl on_ignored_nl on_comment].include?(entry[1])
|
|
@@ -257,7 +262,7 @@ module Ibex
|
|
|
257
262
|
end
|
|
258
263
|
private_class_method :references_legacy_parameter?
|
|
259
264
|
|
|
260
|
-
# @rbs (
|
|
265
|
+
# @rbs (sexp_value node, ?sexp_value parent, ?Integer? child_index) -> bool
|
|
261
266
|
def read_only_value_references?(node, parent = nil, child_index = nil)
|
|
262
267
|
return true unless node.is_a?(Array)
|
|
263
268
|
return safe_value_reference?(parent, child_index) if value_reference?(node)
|
|
@@ -274,7 +279,7 @@ module Ibex
|
|
|
274
279
|
end
|
|
275
280
|
private_class_method :value_reference?
|
|
276
281
|
|
|
277
|
-
# @rbs (
|
|
282
|
+
# @rbs (sexp_value? parent, Integer? child_index) -> bool
|
|
278
283
|
def safe_value_reference?(parent, child_index)
|
|
279
284
|
return false unless parent.is_a?(Array)
|
|
280
285
|
|
data/lib/ibex/codegen/rbs.rb
CHANGED
|
@@ -8,6 +8,9 @@ module Ibex
|
|
|
8
8
|
# Generates an RBS declaration for the public surface of a generated parser.
|
|
9
9
|
# rubocop:disable Metrics/ClassLength -- one generator owns the complete parser signature.
|
|
10
10
|
class RBS
|
|
11
|
+
# @rbs!
|
|
12
|
+
# type syntax_definition = { name: String, kind: Integer, fields: Hash[String, CSTMetadata::field_slot] }
|
|
13
|
+
|
|
11
14
|
# @rbs @automaton: IR::Automaton
|
|
12
15
|
# @rbs @grammar: IR::Grammar
|
|
13
16
|
# @rbs @superclass: String
|
|
@@ -64,11 +67,11 @@ module Ibex
|
|
|
64
67
|
lines.push(" end", "")
|
|
65
68
|
end
|
|
66
69
|
|
|
67
|
-
# @rbs () -> Hash[String,
|
|
70
|
+
# @rbs () -> Hash[String, syntax_definition]
|
|
68
71
|
def syntax_node_definitions
|
|
69
72
|
metadata = CSTMetadata.new(@grammar).build
|
|
70
73
|
slots = metadata.fetch(:slots)
|
|
71
|
-
definitions = {} #: Hash[String,
|
|
74
|
+
definitions = {} #: Hash[String, syntax_definition]
|
|
72
75
|
@grammar.productions.each do |production|
|
|
73
76
|
node = production.node
|
|
74
77
|
next unless node
|
|
@@ -77,12 +80,13 @@ module Ibex
|
|
|
77
80
|
name = node.fetch(:name)
|
|
78
81
|
previous = definitions[name]
|
|
79
82
|
fields = previous ? merge_syntax_fields(previous.fetch(:fields), slot.fetch(:fields)) : slot.fetch(:fields)
|
|
80
|
-
|
|
83
|
+
definition = { name: name, kind: slot.fetch(:node_kind), fields: fields }.freeze #: syntax_definition
|
|
84
|
+
definitions[name] = definition
|
|
81
85
|
end
|
|
82
86
|
definitions
|
|
83
87
|
end
|
|
84
88
|
|
|
85
|
-
# @rbs (Hash[String,
|
|
89
|
+
# @rbs (Hash[String, CSTMetadata::field_slot] left, Hash[String, CSTMetadata::field_slot] right) -> Hash[String, CSTMetadata::field_slot]
|
|
86
90
|
def merge_syntax_fields(left, right)
|
|
87
91
|
left.to_h do |name, left_slot|
|
|
88
92
|
right_slot = right.fetch(name)
|
|
@@ -94,7 +98,7 @@ module Ibex
|
|
|
94
98
|
end.freeze
|
|
95
99
|
end
|
|
96
100
|
|
|
97
|
-
# @rbs (Array[String] lines,
|
|
101
|
+
# @rbs (Array[String] lines, syntax_definition definition) -> void
|
|
98
102
|
def append_syntax_node_contract(lines, definition)
|
|
99
103
|
name = definition.fetch(:name)
|
|
100
104
|
fields = definition.fetch(:fields)
|
|
@@ -122,17 +126,21 @@ module Ibex
|
|
|
122
126
|
types.one? ? types.fetch(0) : "(#{types.join(' | ')})"
|
|
123
127
|
end
|
|
124
128
|
|
|
125
|
-
# @rbs (Array[String] lines, Hash[String,
|
|
129
|
+
# @rbs (Array[String] lines, Hash[String, CSTMetadata::field_slot] fields) -> void
|
|
126
130
|
def append_repetition_contracts(lines, fields)
|
|
127
131
|
repeated = fields.select { |_field, slot| slot.is_a?(Hash) && slot[:extraction] }
|
|
128
132
|
element = "Enumerator[Ibex::Runtime::CST::SyntaxNode | Ibex::Runtime::CST::SyntaxToken, void]"
|
|
129
133
|
repeated.each do |field, slot|
|
|
134
|
+
next unless slot.is_a?(Hash)
|
|
135
|
+
|
|
130
136
|
lines << " def each_#{field}_element: () -> #{element}"
|
|
131
137
|
lines << " def each_#{field}_separator: () -> #{element}" if slot.fetch(:extraction) == :separated_list
|
|
132
138
|
end
|
|
133
139
|
return unless repeated.one?
|
|
134
140
|
|
|
135
141
|
_field, slot = repeated.first
|
|
142
|
+
return unless slot.is_a?(Hash)
|
|
143
|
+
|
|
136
144
|
lines << " def each_element: () -> #{element}"
|
|
137
145
|
lines << " def each_separator: () -> #{element}" if slot.fetch(:extraction) == :separated_list
|
|
138
146
|
end
|
|
@@ -320,7 +328,7 @@ module Ibex
|
|
|
320
328
|
end
|
|
321
329
|
end
|
|
322
330
|
|
|
323
|
-
# @rbs (IR::Production production,
|
|
331
|
+
# @rbs (IR::Production production, IR::action_composition_plan plan, Integer slot, Integer step_index) -> String
|
|
324
332
|
def composition_slot_type(production, plan, slot, step_index)
|
|
325
333
|
physical = plan.fetch(:physical)
|
|
326
334
|
return semantic_type(production.rhs.fetch(slot)) if slot < physical
|