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/lib/ibex/lalr/builder.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
2
3
|
|
|
3
4
|
require "set"
|
|
4
5
|
|
|
@@ -11,10 +12,12 @@ module Ibex
|
|
|
11
12
|
|
|
12
13
|
ALGORITHMS = %i[slr lalr ielr lr1].freeze #: Array[Symbol]
|
|
13
14
|
LALR_STRATEGIES = %i[direct canonical_merge].freeze #: Array[Symbol]
|
|
15
|
+
IELR_STRATEGIES = %i[direct partition].freeze #: Array[Symbol]
|
|
14
16
|
|
|
15
17
|
# @rbs @grammar: IR::Grammar
|
|
16
18
|
# @rbs @algorithm: Symbol
|
|
17
19
|
# @rbs @lalr_strategy: Symbol
|
|
20
|
+
# @rbs @ielr_strategy: Symbol
|
|
18
21
|
# @rbs @sets: Analysis::Sets
|
|
19
22
|
# @rbs @productions_by_lhs: Hash[Integer, Array[IR::Production]]
|
|
20
23
|
# @rbs @resolver: ConflictResolver
|
|
@@ -22,6 +25,8 @@ module Ibex
|
|
|
22
25
|
# @rbs @start_names: Array[String]
|
|
23
26
|
# @rbs @entry_isolation: bool
|
|
24
27
|
# @rbs @attribute_entries: bool
|
|
28
|
+
# @rbs @profile: bool
|
|
29
|
+
# @rbs @remove_unreachable: bool
|
|
25
30
|
# @rbs @canonical_suffix_lookahead_cache: Hash[Integer, Hash[Integer, Hash[Integer, Array[Integer]]]]
|
|
26
31
|
# @rbs @canonical_item_cache: Hash[Integer, Array[Array[lr_item?]?]]?
|
|
27
32
|
# @rbs @canonical_key_radices: [Integer, Integer, Integer]?
|
|
@@ -29,19 +34,26 @@ module Ibex
|
|
|
29
34
|
attr_reader :metrics #: BuildMetrics?
|
|
30
35
|
|
|
31
36
|
# @rbs (IR::Grammar grammar, ?algorithm: Symbol | String, ?lalr_strategy: Symbol | String,
|
|
32
|
-
# ?
|
|
37
|
+
# ?ielr_strategy: Symbol | String,
|
|
38
|
+
# ?entry_isolation: bool, ?starts: Array[String]?, ?attribute_entries: bool, ?profile: bool,
|
|
39
|
+
# ?remove_unreachable: bool) -> void
|
|
33
40
|
def initialize(grammar, algorithm: :lalr, lalr_strategy: :direct, entry_isolation: false,
|
|
34
|
-
starts: nil, attribute_entries: true
|
|
41
|
+
ielr_strategy: :partition, starts: nil, attribute_entries: true, profile: false,
|
|
42
|
+
remove_unreachable: false)
|
|
35
43
|
unless ALGORITHMS.include?(algorithm.to_sym)
|
|
36
44
|
raise ArgumentError, "unknown parser algorithm #{algorithm.inspect}"
|
|
37
45
|
end
|
|
38
46
|
unless LALR_STRATEGIES.include?(lalr_strategy.to_sym)
|
|
39
47
|
raise ArgumentError, "unknown LALR construction strategy #{lalr_strategy.inspect}"
|
|
40
48
|
end
|
|
49
|
+
unless IELR_STRATEGIES.include?(ielr_strategy.to_sym)
|
|
50
|
+
raise ArgumentError, "unknown IELR construction strategy #{ielr_strategy.inspect}"
|
|
51
|
+
end
|
|
41
52
|
|
|
42
53
|
@grammar = grammar
|
|
43
54
|
@algorithm = algorithm.to_sym
|
|
44
55
|
@lalr_strategy = lalr_strategy.to_sym
|
|
56
|
+
@ielr_strategy = ielr_strategy.to_sym
|
|
45
57
|
@sets = Analysis::Sets.new(grammar)
|
|
46
58
|
@productions_by_lhs = grammar.productions.group_by(&:lhs)
|
|
47
59
|
@resolver = ConflictResolver.new(grammar)
|
|
@@ -56,31 +68,43 @@ module Ibex
|
|
|
56
68
|
|
|
57
69
|
@entry_isolation = entry_isolation
|
|
58
70
|
@attribute_entries = attribute_entries
|
|
71
|
+
@profile = profile
|
|
72
|
+
@remove_unreachable = remove_unreachable
|
|
59
73
|
end
|
|
60
74
|
|
|
61
75
|
# @rbs () -> IR::Automaton
|
|
62
76
|
def build
|
|
63
77
|
return build_isolated_automaton if @entry_isolation && @start_names.length > 1
|
|
64
78
|
|
|
65
|
-
merged_items, merged_transitions,
|
|
79
|
+
merged_items, merged_transitions, collection = automaton_collection
|
|
66
80
|
states = build_states(merged_items, merged_transitions)
|
|
67
81
|
states = OnErrorReductions.apply(@grammar, states)
|
|
68
82
|
states = DefaultReductions.apply(states, terminal_ids: @grammar.terminals.map(&:id))
|
|
69
83
|
entry_states = entry_states_for(merged_items)
|
|
84
|
+
if @remove_unreachable
|
|
85
|
+
states, mapping = UnreachableStates.remove(states, entry_states.values.uniq)
|
|
86
|
+
entry_states = entry_states.transform_values { |state_id| mapping.fetch(state_id) }
|
|
87
|
+
collection[:ielr_unreachable_removed] = mapping.length - states.length if collection.respond_to?(:[]=)
|
|
88
|
+
end
|
|
70
89
|
states = attribute_entry_conflicts(states, entry_states) if @attribute_entries && @start_names.length > 1
|
|
71
90
|
summary = conflict_summary(states)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
final_states: states.length,
|
|
76
|
-
strategy: strategy
|
|
77
|
-
)
|
|
78
|
-
IR::Automaton.new(grammar: @grammar, states: states, conflict_summary: summary,
|
|
79
|
-
algorithm: algorithm_name, entry_states: entry_states)
|
|
91
|
+
final_items, final_lookahead_items = profiled_final_item_counts(merged_items)
|
|
92
|
+
@metrics = build_metrics(collection, states.length, final_items, final_lookahead_items)
|
|
93
|
+
build_output_automaton(states: states, conflict_summary: summary, entry_states: entry_states)
|
|
80
94
|
end
|
|
81
95
|
|
|
82
96
|
private
|
|
83
97
|
|
|
98
|
+
# @rbs (states: Array[IR::AutomatonState], conflict_summary: IR::conflict_summary,
|
|
99
|
+
# entry_states: Hash[String, Integer]) -> IR::Automaton
|
|
100
|
+
def build_output_automaton(states:, conflict_summary:, entry_states:)
|
|
101
|
+
IR::Automaton.new(
|
|
102
|
+
grammar: @grammar, states: states, conflict_summary: conflict_summary,
|
|
103
|
+
algorithm: algorithm_name, entry_states: entry_states,
|
|
104
|
+
entry_construction: output_entry_construction || raise(Ibex::Error, "missing entry construction")
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
|
|
84
108
|
# @rbs (Array[IR::AutomatonState] states) -> IR::conflict_summary
|
|
85
109
|
def conflict_summary(states)
|
|
86
110
|
conflicts = states.flat_map(&:conflicts)
|
|
@@ -99,39 +123,112 @@ module Ibex
|
|
|
99
123
|
summary
|
|
100
124
|
end
|
|
101
125
|
|
|
102
|
-
# @rbs () -> [Array[packed_items], transitions,
|
|
126
|
+
# @rbs () -> [Array[packed_items], transitions, build_collection]
|
|
103
127
|
def automaton_collection
|
|
104
|
-
if @algorithm == :ielr
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
end
|
|
128
|
+
return ielr_collection if @algorithm == :ielr
|
|
129
|
+
return canonical_lr1_collection if @algorithm == :lr1
|
|
130
|
+
return merged_canonical_collection(:canonical_merge) if @lalr_strategy == :canonical_merge
|
|
131
|
+
return merged_canonical_collection(:canonical_merge_multi_entry) if @grammar.starts.length > 1
|
|
109
132
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
133
|
+
direct_collection
|
|
134
|
+
ensure
|
|
135
|
+
@canonical_item_cache = nil
|
|
136
|
+
end
|
|
114
137
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
apply_slr_lookaheads(items) if @algorithm == :slr
|
|
119
|
-
return [items, merged_transitions, states.length, states.length, :canonical_merge]
|
|
120
|
-
end
|
|
138
|
+
# @rbs () -> [Array[packed_items], transitions, build_collection]
|
|
139
|
+
def ielr_collection
|
|
140
|
+
return ielr_direct_collection if @ielr_strategy == :direct
|
|
121
141
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
142
|
+
states, transitions = canonical_collection
|
|
143
|
+
partition = IELRPartition.new(@grammar, states, transitions, profile: @profile)
|
|
144
|
+
items, merged_transitions = partition.build
|
|
145
|
+
profile = canonical_profile(states, strategy: :ielr_partition)
|
|
146
|
+
profile[:ielr_initial_partitions] = partition.initial_partition_count
|
|
147
|
+
profile[:ielr_final_partitions] = partition.final_partition_count
|
|
148
|
+
[items, merged_transitions, profile]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @rbs () -> [Array[packed_items], transitions, build_collection]
|
|
152
|
+
def ielr_direct_collection
|
|
153
|
+
pipeline = IELR::Pipeline.new(@grammar, @sets, starts: @start_names, profile: @profile)
|
|
154
|
+
pipeline.build
|
|
155
|
+
end
|
|
128
156
|
|
|
129
|
-
|
|
157
|
+
# @rbs () -> [Array[packed_items], transitions, build_collection]
|
|
158
|
+
def canonical_lr1_collection
|
|
159
|
+
states, transitions = canonical_collection
|
|
160
|
+
[pack_canonical_items(states), transitions, canonical_profile(states, strategy: :canonical_lr1)]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# @rbs (Symbol strategy) -> [Array[packed_items], transitions, build_collection]
|
|
164
|
+
def merged_canonical_collection(strategy)
|
|
165
|
+
states, transitions = canonical_collection
|
|
166
|
+
items, merged_transitions = merge_lalr(states, transitions)
|
|
130
167
|
apply_slr_lookaheads(items) if @algorithm == :slr
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
168
|
+
[items, merged_transitions, canonical_profile(states, strategy: strategy)]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# @rbs () -> untyped
|
|
172
|
+
def direct_collection
|
|
173
|
+
direct = DirectLookaheads.new(@grammar, @sets, profile: @profile)
|
|
174
|
+
items, transitions = direct.build
|
|
175
|
+
apply_slr_lookaheads(items) if @algorithm == :slr
|
|
176
|
+
profile = {
|
|
177
|
+
construction_states: items.length, canonical_states: nil, strategy: :direct_lalr,
|
|
178
|
+
lr0_states: direct.lr0_state_count, lr0_items: direct.lr0_item_count, canonical_items: nil,
|
|
179
|
+
propagation_edges: direct.propagation_edge_count,
|
|
180
|
+
ielr_initial_partitions: nil, ielr_final_partitions: nil,
|
|
181
|
+
ielr_annotations: nil, ielr_annotated_states: nil, ielr_inadequacies: nil,
|
|
182
|
+
ielr_split_stable_discarded: nil, ielr_lalr_states: nil, ielr_split_states: nil,
|
|
183
|
+
ielr_unreachable_removed: nil, ielr_remergeable_candidates: nil
|
|
184
|
+
}
|
|
185
|
+
[items, transitions, profile]
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# @rbs (Array[item_set] states, strategy: Symbol) -> build_collection
|
|
189
|
+
def canonical_profile(states, strategy:)
|
|
190
|
+
cores = states.to_h { |items| [core_key(items), true] }.keys if @profile
|
|
191
|
+
{
|
|
192
|
+
construction_states: states.length, canonical_states: states.length, strategy: strategy,
|
|
193
|
+
lr0_states: cores&.length, lr0_items: cores&.sum(&:length),
|
|
194
|
+
canonical_items: @profile ? states.sum(&:length) : nil,
|
|
195
|
+
propagation_edges: nil, ielr_initial_partitions: nil, ielr_final_partitions: nil,
|
|
196
|
+
ielr_annotations: nil, ielr_annotated_states: nil, ielr_inadequacies: nil,
|
|
197
|
+
ielr_split_stable_discarded: nil, ielr_lalr_states: nil, ielr_split_states: nil,
|
|
198
|
+
ielr_unreachable_removed: nil, ielr_remergeable_candidates: nil
|
|
199
|
+
}
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# @rbs (Array[packed_items] items) -> [Integer?, Integer?]
|
|
203
|
+
def profiled_final_item_counts(items)
|
|
204
|
+
return [nil, nil] unless @profile
|
|
205
|
+
|
|
206
|
+
[items.sum(&:length), items.sum { |state| state.values.sum(&:length) }]
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# @rbs (build_collection collection, Integer final_states, Integer? final_items,
|
|
210
|
+
# Integer? final_lookahead_items) -> BuildMetrics
|
|
211
|
+
def build_metrics(collection, final_states, final_items, final_lookahead_items)
|
|
212
|
+
BuildMetrics.new(
|
|
213
|
+
construction_states: collection.fetch(:construction_states),
|
|
214
|
+
canonical_states: collection.fetch(:canonical_states),
|
|
215
|
+
strategy: collection.fetch(:strategy),
|
|
216
|
+
lr0_states: collection.fetch(:lr0_states),
|
|
217
|
+
lr0_items: collection.fetch(:lr0_items),
|
|
218
|
+
canonical_items: collection.fetch(:canonical_items),
|
|
219
|
+
propagation_edges: collection.fetch(:propagation_edges),
|
|
220
|
+
ielr_initial_partitions: collection.fetch(:ielr_initial_partitions),
|
|
221
|
+
ielr_final_partitions: collection.fetch(:ielr_final_partitions),
|
|
222
|
+
ielr_annotations: collection.fetch(:ielr_annotations, nil),
|
|
223
|
+
ielr_annotated_states: collection.fetch(:ielr_annotated_states, nil),
|
|
224
|
+
ielr_inadequacies: collection.fetch(:ielr_inadequacies, nil),
|
|
225
|
+
ielr_split_stable_discarded: collection.fetch(:ielr_split_stable_discarded, nil),
|
|
226
|
+
ielr_lalr_states: collection.fetch(:ielr_lalr_states, nil),
|
|
227
|
+
ielr_split_states: collection.fetch(:ielr_split_states, nil),
|
|
228
|
+
ielr_unreachable_removed: collection.fetch(:ielr_unreachable_removed, nil),
|
|
229
|
+
ielr_remergeable_candidates: collection.fetch(:ielr_remergeable_candidates, nil),
|
|
230
|
+
final_states: final_states, final_items: final_items, final_lookahead_items: final_lookahead_items
|
|
231
|
+
)
|
|
135
232
|
end
|
|
136
233
|
|
|
137
234
|
# @rbs () -> String
|
|
@@ -335,21 +432,21 @@ module Ibex
|
|
|
335
432
|
end
|
|
336
433
|
|
|
337
434
|
# Conflict hashes are produced locally immediately before this boundary.
|
|
338
|
-
#
|
|
339
|
-
#
|
|
340
|
-
# @rbs (untyped conflict) -> IR::conflict
|
|
435
|
+
# Both conflict variants carry the same optional midrule provenance field.
|
|
436
|
+
# @rbs (IR::conflict conflict) -> IR::conflict
|
|
341
437
|
def attribute_midrule_conflict(conflict)
|
|
342
438
|
production_ids = if conflict[:type] == :shift_reduce
|
|
343
439
|
[conflict[:reduce]]
|
|
344
440
|
else
|
|
345
441
|
conflict[:reductions]
|
|
346
|
-
end
|
|
442
|
+
end #: Array[Integer]
|
|
347
443
|
origins = production_ids.filter_map do |production_id|
|
|
348
444
|
production = @grammar.productions.fetch(production_id)
|
|
349
445
|
production.origin[:loc] if production.origin[:kind] == :inline_action
|
|
350
446
|
end
|
|
351
|
-
|
|
352
|
-
|
|
447
|
+
result = conflict.dup #: Hash[Symbol, untyped]
|
|
448
|
+
result[:midrule_origins] = origins.uniq unless origins.empty?
|
|
449
|
+
result #: IR::conflict
|
|
353
450
|
end
|
|
354
451
|
|
|
355
452
|
# @rbs (Array[IR::AutomatonItem] items, Hash[Integer, Array[IR::parser_action]] candidates) -> void
|
|
@@ -465,23 +562,60 @@ module Ibex
|
|
|
465
562
|
canonical_counts << metrics.canonical_states
|
|
466
563
|
end
|
|
467
564
|
canonical_states = canonical_counts.compact.sum if canonical_counts.none?(&:nil?)
|
|
468
|
-
@metrics =
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
final_states: states.length,
|
|
472
|
-
strategy: :entry_isolation
|
|
565
|
+
@metrics = isolated_metrics(entries, construction_states, canonical_states, states.length)
|
|
566
|
+
build_output_automaton(
|
|
567
|
+
states: states, conflict_summary: conflict_summary(states), entry_states: entry_states
|
|
473
568
|
)
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
# @rbs (Array[[String, IR::Automaton, BuildMetrics]] entries, Integer construction_states,
|
|
572
|
+
# Integer? canonical_states, Integer final_states) -> BuildMetrics
|
|
573
|
+
def isolated_metrics(entries, construction_states, canonical_states, final_states)
|
|
574
|
+
BuildMetrics.new(
|
|
575
|
+
construction_states: construction_states, canonical_states: canonical_states,
|
|
576
|
+
final_states: final_states, strategy: :entry_isolation,
|
|
577
|
+
lr0_states: sum_optional_metric(entries, :lr0_states),
|
|
578
|
+
lr0_items: sum_optional_metric(entries, :lr0_items),
|
|
579
|
+
canonical_items: sum_optional_metric(entries, :canonical_items),
|
|
580
|
+
final_items: sum_optional_metric(entries, :final_items),
|
|
581
|
+
final_lookahead_items: sum_optional_metric(entries, :final_lookahead_items),
|
|
582
|
+
propagation_edges: sum_optional_metric(entries, :propagation_edges),
|
|
583
|
+
ielr_initial_partitions: sum_optional_metric(entries, :ielr_initial_partitions),
|
|
584
|
+
ielr_final_partitions: sum_optional_metric(entries, :ielr_final_partitions),
|
|
585
|
+
ielr_annotations: sum_optional_metric(entries, :ielr_annotations),
|
|
586
|
+
ielr_annotated_states: sum_optional_metric(entries, :ielr_annotated_states),
|
|
587
|
+
ielr_inadequacies: sum_optional_metric(entries, :ielr_inadequacies),
|
|
588
|
+
ielr_split_stable_discarded: sum_optional_metric(entries, :ielr_split_stable_discarded),
|
|
589
|
+
ielr_lalr_states: sum_optional_metric(entries, :ielr_lalr_states),
|
|
590
|
+
ielr_split_states: sum_optional_metric(entries, :ielr_split_states),
|
|
591
|
+
ielr_unreachable_removed: sum_optional_metric(entries, :ielr_unreachable_removed),
|
|
592
|
+
ielr_remergeable_candidates: sum_optional_metric(entries, :ielr_remergeable_candidates)
|
|
477
593
|
)
|
|
478
594
|
end
|
|
479
595
|
|
|
596
|
+
# @rbs (Array[[String, IR::Automaton, BuildMetrics]] entries, Symbol method) -> Integer?
|
|
597
|
+
def sum_optional_metric(entries, method)
|
|
598
|
+
values = entries.map { |_name, _automaton, metrics| metrics.public_send(method) }
|
|
599
|
+
values.compact.sum if values.none?(&:nil?)
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
# @rbs () -> Integer
|
|
603
|
+
def output_schema_version
|
|
604
|
+
IR::SCHEMA_VERSION
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
# @rbs () -> String?
|
|
608
|
+
def output_entry_construction
|
|
609
|
+
@entry_isolation ? "isolated" : "shared"
|
|
610
|
+
end
|
|
611
|
+
|
|
480
612
|
# @rbs (String name) -> [String, IR::Automaton, BuildMetrics]
|
|
481
613
|
def isolated_entry(name)
|
|
482
614
|
builder = self.class.new(
|
|
483
615
|
@grammar, algorithm: @algorithm, lalr_strategy: @lalr_strategy,
|
|
484
|
-
|
|
616
|
+
ielr_strategy: @ielr_strategy,
|
|
617
|
+
starts: [name], entry_isolation: true, attribute_entries: false, profile: @profile,
|
|
618
|
+
remove_unreachable: @remove_unreachable
|
|
485
619
|
)
|
|
486
620
|
automaton = builder.build
|
|
487
621
|
metrics = builder.metrics
|
|
@@ -569,11 +703,12 @@ module Ibex
|
|
|
569
703
|
reachable
|
|
570
704
|
end
|
|
571
705
|
|
|
572
|
-
# @rbs () -> Set[
|
|
706
|
+
# @rbs () -> Set[conflict_fingerprint]
|
|
573
707
|
def isolated_conflict_fingerprints
|
|
574
708
|
@start_names.each_with_object(Set.new) do |name, fingerprints|
|
|
575
709
|
isolated = self.class.new(
|
|
576
710
|
@grammar, algorithm: @algorithm, lalr_strategy: @lalr_strategy,
|
|
711
|
+
ielr_strategy: @ielr_strategy,
|
|
577
712
|
starts: [name], attribute_entries: false
|
|
578
713
|
).build
|
|
579
714
|
isolated.states.each do |state|
|
|
@@ -582,13 +717,13 @@ module Ibex
|
|
|
582
717
|
end
|
|
583
718
|
end
|
|
584
719
|
|
|
585
|
-
# @rbs (IR::conflict conflict) ->
|
|
720
|
+
# @rbs (IR::conflict conflict) -> conflict_fingerprint
|
|
586
721
|
def conflict_fingerprint(conflict)
|
|
587
722
|
reductions = if conflict[:type] == :shift_reduce
|
|
588
723
|
[conflict[:reduce]]
|
|
589
724
|
else
|
|
590
725
|
conflict[:reductions]
|
|
591
|
-
end
|
|
726
|
+
end #: Array[Integer]
|
|
592
727
|
[conflict[:type], conflict[:symbol], reductions]
|
|
593
728
|
end
|
|
594
729
|
end
|
|
@@ -47,9 +47,9 @@ module Ibex
|
|
|
47
47
|
@initial_state = automaton.entry_states.fetch(entry)
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
# @rbs () ->
|
|
50
|
+
# @rbs () -> search_outcome
|
|
51
51
|
def call
|
|
52
|
-
return unless @lookahead
|
|
52
|
+
return outcome(:not_found) unless @lookahead
|
|
53
53
|
|
|
54
54
|
initial = configuration([@initial_state], Array.new(0))
|
|
55
55
|
queue = [[initial, Array.new(0)]] #: Array[[Configuration, Array[Integer]]]
|
|
@@ -58,11 +58,11 @@ module Ibex
|
|
|
58
58
|
current, prefix = queue.shift
|
|
59
59
|
conflict_configurations(current).each do |candidate|
|
|
60
60
|
result = unify_from(candidate, prefix)
|
|
61
|
-
return result if result
|
|
61
|
+
return outcome(:found, result) if result
|
|
62
62
|
end
|
|
63
63
|
enqueue_prefixes(queue, visited, current, prefix)
|
|
64
64
|
end
|
|
65
|
-
|
|
65
|
+
outcome(exhausted? ? :exhausted : :not_found)
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
# @rbs () -> bool
|
|
@@ -70,6 +70,17 @@ module Ibex
|
|
|
70
70
|
|
|
71
71
|
private
|
|
72
72
|
|
|
73
|
+
# @rbs (:found | :not_found | :exhausted status, ?search_result? result) -> search_outcome
|
|
74
|
+
def outcome(status, result = nil)
|
|
75
|
+
{
|
|
76
|
+
status: status,
|
|
77
|
+
result: result,
|
|
78
|
+
explored: @explored,
|
|
79
|
+
exhausted: status == :exhausted,
|
|
80
|
+
bounds: { max_tokens: @max_tokens, max_configurations: @max_configurations }
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
|
|
73
84
|
# @rbs (Configuration current) -> Array[Configuration]
|
|
74
85
|
def conflict_configurations(current)
|
|
75
86
|
advance(current, required_lookahead, stop_at: @state.id, branch_conflicts: true)
|
|
@@ -17,14 +17,14 @@ module Ibex
|
|
|
17
17
|
@shortest_yields = compute_shortest_yields
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# @rbs () -> Array[
|
|
20
|
+
# @rbs () -> Array[search_counterexample]
|
|
21
21
|
def all
|
|
22
22
|
@automaton.states.flat_map do |state|
|
|
23
23
|
state.conflicts.map { |conflict| build_example(state, conflict) }
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# @rbs (Integer state_id, Integer conflict_index) ->
|
|
27
|
+
# @rbs (Integer state_id, Integer conflict_index) -> search_counterexample
|
|
28
28
|
def for_conflict(state_id, conflict_index)
|
|
29
29
|
state = @automaton.states.find { |candidate| candidate.id == state_id }
|
|
30
30
|
raise ArgumentError, "unknown automaton state #{state_id}" unless state
|
|
@@ -39,31 +39,34 @@ module Ibex
|
|
|
39
39
|
|
|
40
40
|
private
|
|
41
41
|
|
|
42
|
-
# @rbs (IR::AutomatonState state, IR::conflict conflict) ->
|
|
42
|
+
# @rbs (IR::AutomatonState state, IR::conflict conflict) -> search_counterexample
|
|
43
43
|
def build_example(state, conflict)
|
|
44
|
-
|
|
44
|
+
outcome = ConflictSearch.new(
|
|
45
45
|
@automaton, state, conflict, max_tokens: @max_tokens, max_configurations: @max_configurations
|
|
46
46
|
).call
|
|
47
|
-
|
|
47
|
+
result = outcome[:result]
|
|
48
|
+
return unifying_example(state, conflict, outcome, result) if outcome[:status] == :found && result
|
|
48
49
|
|
|
49
|
-
reachability_example(state, conflict)
|
|
50
|
+
reachability_example(state, conflict, outcome)
|
|
50
51
|
end
|
|
51
52
|
|
|
52
|
-
# @rbs (IR::AutomatonState state, IR::conflict conflict,
|
|
53
|
-
|
|
53
|
+
# @rbs (IR::AutomatonState state, IR::conflict conflict, search_outcome outcome,
|
|
54
|
+
# search_result result) -> search_counterexample
|
|
55
|
+
def unifying_example(state, conflict, outcome, result)
|
|
54
56
|
{ state: state.id, type: conflict[:type], symbol_path: Array.new(0),
|
|
55
57
|
sentence: names(result[:sentence_ids]), lookahead_index: result[:lookahead_index], unifying: true,
|
|
56
|
-
interpretations: result[:interpretations] }
|
|
58
|
+
inconclusive: false, search: outcome, interpretations: result[:interpretations] }
|
|
57
59
|
end
|
|
58
60
|
|
|
59
|
-
# @rbs (IR::AutomatonState state, IR::conflict conflict) ->
|
|
60
|
-
def reachability_example(state, conflict)
|
|
61
|
+
# @rbs (IR::AutomatonState state, IR::conflict conflict, search_outcome outcome) -> search_counterexample
|
|
62
|
+
def reachability_example(state, conflict, outcome)
|
|
61
63
|
path = shortest_state_path(state.id, conflict)
|
|
62
64
|
lookahead = @grammar.symbol(conflict[:symbol])
|
|
63
65
|
terminal_ids = path.flat_map { |symbol_id| @shortest_yields[symbol_id] || [] }
|
|
64
66
|
terminal_ids << lookahead.id if lookahead
|
|
65
67
|
{ state: state.id, type: conflict[:type], symbol_path: names(path), sentence: names(terminal_ids),
|
|
66
|
-
lookahead_index: terminal_ids.length - 1, unifying: false,
|
|
68
|
+
lookahead_index: terminal_ids.length - 1, unifying: false,
|
|
69
|
+
inconclusive: outcome[:status] == :exhausted, search: outcome, interpretations: interpretations(conflict) }
|
|
67
70
|
end
|
|
68
71
|
|
|
69
72
|
# @rbs (Integer target, IR::conflict conflict) -> Array[Integer]
|
|
@@ -125,12 +128,14 @@ module Ibex
|
|
|
125
128
|
end
|
|
126
129
|
end
|
|
127
130
|
|
|
128
|
-
#
|
|
131
|
+
# The compact counterexample tree intentionally uses a lightweight shape
|
|
132
|
+
# whose children are symbol names rather than recursively expanded nodes.
|
|
133
|
+
# @rbs (IR::shift_reduce_conflict conflict) -> untyped
|
|
129
134
|
def shift_interpretation(conflict)
|
|
130
135
|
{ kind: :shift, state: conflict[:shift_to], tree: { token: conflict[:symbol] } }
|
|
131
136
|
end
|
|
132
137
|
|
|
133
|
-
# @rbs (Integer production_id) ->
|
|
138
|
+
# @rbs (Integer production_id) -> untyped
|
|
134
139
|
def reduce_interpretation(production_id)
|
|
135
140
|
production = @grammar.productions.fetch(production_id)
|
|
136
141
|
lhs = symbol_name(production.lhs)
|