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
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "set"
|
|
4
|
-
|
|
5
3
|
module Ibex
|
|
6
4
|
# Static grammar diagnostics used by Normalizer.
|
|
7
5
|
module NormalizeDiagnostics
|
|
@@ -22,10 +20,13 @@ module Ibex
|
|
|
22
20
|
# @rbs () -> void
|
|
23
21
|
def validate_symbol_metadata
|
|
24
22
|
# @type self: Normalizer
|
|
25
|
-
|
|
23
|
+
display_locations = @display_name_locations #: Hash[String, IR::location]
|
|
24
|
+
semantic_locations = @semantic_type_locations #: Hash[String, IR::location]
|
|
25
|
+
inline_rule_names = @inline_rule_names #: Set[String]
|
|
26
|
+
{ display: display_locations, type: semantic_locations }.each do |label, locations|
|
|
26
27
|
locations.each do |name, location|
|
|
27
28
|
fail_hash(location, "#{label} declaration references undefined symbol #{name}") unless
|
|
28
|
-
symbol(name) || parameter_template?(name) || (label == :type &&
|
|
29
|
+
symbol(name) || parameter_template?(name) || (label == :type && inline_rule_names.include?(name))
|
|
29
30
|
end
|
|
30
31
|
end
|
|
31
32
|
end
|
|
@@ -33,12 +34,15 @@ module Ibex
|
|
|
33
34
|
# @rbs () -> void
|
|
34
35
|
def warn_duplicate_productions
|
|
35
36
|
# @type self: Normalizer
|
|
37
|
+
productions = @productions #: Array[IR::Production]
|
|
38
|
+
warnings = @warnings #: Array[IR::grammar_warning]
|
|
36
39
|
seen = {} #: Hash[[Integer, Array[Integer]], Integer]
|
|
37
|
-
|
|
40
|
+
productions.each do |production|
|
|
38
41
|
signature = [production.lhs, production.rhs] #: [Integer, Array[Integer]]
|
|
39
42
|
if seen.key?(signature)
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
location = production.origin[:loc] #: IR::location?
|
|
44
|
+
warnings << { type: :duplicate_production, production: production.id, original: seen[signature],
|
|
45
|
+
loc: location }
|
|
42
46
|
else
|
|
43
47
|
seen[signature] = production.id
|
|
44
48
|
end
|
|
@@ -48,23 +52,27 @@ module Ibex
|
|
|
48
52
|
# @rbs () -> void
|
|
49
53
|
def warn_unreachable_nonterminals
|
|
50
54
|
# @type self: Normalizer
|
|
55
|
+
symbols = @symbols #: Array[IR::GrammarSymbol]
|
|
56
|
+
warnings = @warnings #: Array[IR::grammar_warning]
|
|
51
57
|
reachable = reachable_symbol_ids
|
|
52
|
-
|
|
53
|
-
next if reachable.
|
|
58
|
+
symbols.select(&:nonterminal?).each do |grammar_symbol|
|
|
59
|
+
next if reachable.key?(grammar_symbol.id) || grammar_symbol.name.start_with?("$")
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
warnings << { type: :unreachable_nonterminal, symbol: grammar_symbol.name, loc: grammar_symbol.location }
|
|
56
62
|
end
|
|
57
63
|
end
|
|
58
64
|
|
|
59
|
-
# @rbs () ->
|
|
65
|
+
# @rbs () -> Hash[Integer, true]
|
|
60
66
|
def reachable_symbol_ids
|
|
61
67
|
# @type self: Normalizer
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
start_names = @start_names #: Array[String]
|
|
69
|
+
productions = @productions #: Array[IR::Production]
|
|
70
|
+
starts = start_names.map { |name| required_symbol(name).id }
|
|
71
|
+
reachable = starts.to_h { |id| [id, true] } #: Hash[Integer, true]
|
|
64
72
|
loop do
|
|
65
73
|
before = reachable.length
|
|
66
|
-
|
|
67
|
-
production.rhs.each { |id| reachable
|
|
74
|
+
productions.select { |production| reachable.key?(production.lhs) }.each do |production|
|
|
75
|
+
production.rhs.each { |id| reachable[id] = true }
|
|
68
76
|
end
|
|
69
77
|
return reachable if reachable.length == before
|
|
70
78
|
end
|
|
@@ -73,66 +81,83 @@ module Ibex
|
|
|
73
81
|
# @rbs () -> void
|
|
74
82
|
def warn_unused_terminals
|
|
75
83
|
# @type self: Normalizer
|
|
76
|
-
|
|
77
|
-
@symbols
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
productions = @productions #: Array[IR::Production]
|
|
85
|
+
symbols = @symbols #: Array[IR::GrammarSymbol]
|
|
86
|
+
precedence = @precedence #: Hash[String, IR::precedence]
|
|
87
|
+
warnings = @warnings #: Array[IR::grammar_warning]
|
|
88
|
+
used = productions.flat_map(&:rhs).to_h { |id| [id, true] } #: Hash[Integer, true]
|
|
89
|
+
symbols.select(&:terminal?).each do |grammar_symbol|
|
|
90
|
+
next if grammar_symbol.reserved || used.key?(grammar_symbol.id) || precedence.key?(grammar_symbol.name)
|
|
91
|
+
|
|
92
|
+
warnings << { type: :unused_terminal, symbol: grammar_symbol.name, loc: grammar_symbol.location }
|
|
81
93
|
end
|
|
82
94
|
end
|
|
83
95
|
|
|
84
96
|
# @rbs () -> void
|
|
85
97
|
def warn_unreachable_terminals
|
|
86
98
|
# @type self: Normalizer
|
|
99
|
+
productions = @productions #: Array[IR::Production]
|
|
100
|
+
declared_tokens = @declared_tokens #: Hash[String, IR::location]
|
|
101
|
+
warnings = @warnings #: Array[IR::grammar_warning]
|
|
87
102
|
reachable = reachable_symbol_ids
|
|
88
|
-
used =
|
|
89
|
-
|
|
103
|
+
used = productions.flat_map(&:rhs).to_h { |id| [id, true] } #: Hash[Integer, true]
|
|
104
|
+
declared_tokens.each_key do |name|
|
|
90
105
|
grammar_symbol = required_symbol(name)
|
|
91
|
-
next unless used.
|
|
92
|
-
next if reachable.
|
|
106
|
+
next unless used.key?(grammar_symbol.id)
|
|
107
|
+
next if reachable.key?(grammar_symbol.id)
|
|
93
108
|
|
|
94
|
-
|
|
109
|
+
warnings << { type: :unreachable_terminal, symbol: name, loc: declared_tokens[name] }
|
|
95
110
|
end
|
|
96
111
|
end
|
|
97
112
|
|
|
98
113
|
# @rbs () -> void
|
|
99
114
|
def warn_unused_precedence
|
|
100
115
|
# @type self: Normalizer
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
productions = @productions #: Array[IR::Production]
|
|
117
|
+
precedence = @precedence #: Hash[String, IR::precedence]
|
|
118
|
+
precedence_locations = @precedence_locations #: Hash[String, IR::location]
|
|
119
|
+
warnings = @warnings #: Array[IR::grammar_warning]
|
|
120
|
+
referenced = {} # @type var referenced: Hash[Integer, true]
|
|
121
|
+
productions.each do |production|
|
|
122
|
+
symbol_ids = referenced
|
|
123
|
+
production.rhs.each { |id| symbol_ids[id] = true }
|
|
124
|
+
symbol_ids[production.precedence_override] = true if production.precedence_override
|
|
104
125
|
end
|
|
105
|
-
|
|
126
|
+
precedence.each_key do |name|
|
|
106
127
|
grammar_symbol = required_symbol(name)
|
|
107
|
-
next if referenced.
|
|
128
|
+
next if referenced.key?(grammar_symbol.id)
|
|
108
129
|
|
|
109
|
-
|
|
130
|
+
warnings << { type: :unused_precedence, symbol: name, loc: precedence_locations[name] }
|
|
110
131
|
end
|
|
111
132
|
end
|
|
112
133
|
|
|
113
134
|
# @rbs () -> void
|
|
114
135
|
def warn_empty_language
|
|
115
136
|
# @type self: Normalizer
|
|
137
|
+
productions = @productions #: Array[IR::Production]
|
|
138
|
+
start_names = @start_names #: Array[String]
|
|
139
|
+
warnings = @warnings #: Array[IR::grammar_warning]
|
|
116
140
|
productive = productive_terminal_ids
|
|
117
141
|
loop do
|
|
118
142
|
before = productive.length
|
|
119
|
-
|
|
120
|
-
productive
|
|
143
|
+
productions.each do |production|
|
|
144
|
+
productive[production.lhs] = true if production.rhs.all? { |id| productive.key?(id) }
|
|
121
145
|
end
|
|
122
146
|
break if productive.length == before
|
|
123
147
|
end
|
|
124
|
-
|
|
125
|
-
next if productive.
|
|
148
|
+
start_names.each do |name|
|
|
149
|
+
next if productive.key?(required_symbol(name).id)
|
|
126
150
|
|
|
127
151
|
start_symbol = required_symbol(name)
|
|
128
|
-
|
|
152
|
+
warnings << { type: :empty_language, symbol: name, loc: start_symbol.location }
|
|
129
153
|
end
|
|
130
154
|
end
|
|
131
155
|
|
|
132
|
-
# @rbs () ->
|
|
156
|
+
# @rbs () -> Hash[Integer, true]
|
|
133
157
|
def productive_terminal_ids
|
|
134
158
|
# @type self: Normalizer
|
|
135
|
-
|
|
159
|
+
symbols = @symbols #: Array[IR::GrammarSymbol]
|
|
160
|
+
symbols.select { |grammar_symbol| productive_terminal?(grammar_symbol) }.to_h { |symbol| [symbol.id, true] }
|
|
136
161
|
end
|
|
137
162
|
|
|
138
163
|
# @rbs (IR::GrammarSymbol grammar_symbol) -> bool
|
|
@@ -192,7 +192,7 @@ module Ibex
|
|
|
192
192
|
IR::Action.new(code: code, location: location.to_h)
|
|
193
193
|
end
|
|
194
194
|
|
|
195
|
-
# @rbs (Symbol kind, Frontend::AST::item item) -> Hash[Symbol,
|
|
195
|
+
# @rbs (Symbol kind, Frontend::AST::item item) -> Hash[Symbol, Object?]
|
|
196
196
|
def synthetic_origin(kind, item)
|
|
197
197
|
# @type self: Normalizer
|
|
198
198
|
{ kind: :"#{kind}_expansion", expression: NormalizeExpression.render(item), loc: item.loc.to_h }
|
|
@@ -210,10 +210,11 @@ module Ibex
|
|
|
210
210
|
# Hash[Symbol, untyped] origin, ?String? documentation, ?IR::node_annotation? node) -> void
|
|
211
211
|
def add_production(lhs_name, rhs_names, action, precedence_name, origin, documentation = nil, node = nil)
|
|
212
212
|
# @type self: Normalizer
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
location = origin[:loc] #: IR::location
|
|
214
|
+
lhs = symbol(lhs_name) || intern(lhs_name, :nonterminal, location: location)
|
|
215
|
+
rhs = rhs_names.map { |name| symbol(name)&.id || fail_hash(location, "undefined symbol #{name}") }
|
|
215
216
|
precedence = precedence_name && symbol(precedence_name)
|
|
216
|
-
fail_hash(
|
|
217
|
+
fail_hash(location, "undefined precedence symbol #{precedence_name}") if precedence_name && !precedence
|
|
217
218
|
@productions << IR::Production.new(id: @productions.length, lhs: lhs.id, rhs: rhs, action: action,
|
|
218
219
|
precedence_override: precedence&.id, origin: origin,
|
|
219
220
|
documentation: documentation, expansion: resolved_expansion, node: node)
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
module Ibex
|
|
4
4
|
# Deterministically renders frontend EBNF items for production origin metadata.
|
|
5
5
|
module NormalizeExpression
|
|
6
|
+
# @rbs! type pending_item = String | Frontend::AST::item
|
|
7
|
+
|
|
6
8
|
class << self
|
|
7
9
|
# @rbs (Frontend::AST::item item) -> String
|
|
8
10
|
def render(item)
|
|
9
|
-
pending = [item] #: Array[
|
|
11
|
+
pending = [item] #: Array[pending_item]
|
|
10
12
|
output = [] #: Array[String]
|
|
11
13
|
until pending.empty?
|
|
12
|
-
current = pending.pop
|
|
14
|
+
current = pending.pop || raise(ArgumentError, "expression stack unexpectedly empty")
|
|
13
15
|
if current.is_a?(String)
|
|
14
16
|
output << current
|
|
15
17
|
next
|
|
@@ -22,7 +24,7 @@ module Ibex
|
|
|
22
24
|
|
|
23
25
|
private
|
|
24
26
|
|
|
25
|
-
# @rbs (Array[
|
|
27
|
+
# @rbs (Array[pending_item] pending, Frontend::AST::item item) -> void
|
|
26
28
|
def push_render_item(pending, item)
|
|
27
29
|
case item
|
|
28
30
|
when Frontend::AST::SymbolReference
|
|
@@ -45,7 +47,7 @@ module Ibex
|
|
|
45
47
|
end
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
# @rbs (Array[
|
|
50
|
+
# @rbs (Array[pending_item] pending, Frontend::AST::ParameterizedReference item) -> void
|
|
49
51
|
def push_render_parameterized_reference(pending, item)
|
|
50
52
|
pending << ":#{item.named_reference}" if item.named_reference
|
|
51
53
|
pending << ")"
|
|
@@ -53,7 +55,7 @@ module Ibex
|
|
|
53
55
|
pending.push("(", item.name)
|
|
54
56
|
end
|
|
55
57
|
|
|
56
|
-
# @rbs (Array[
|
|
58
|
+
# @rbs (Array[pending_item] pending, Frontend::AST::Group item) -> void
|
|
57
59
|
def push_render_group(pending, item)
|
|
58
60
|
pending << ")"
|
|
59
61
|
(item.alternatives.length - 1).downto(0) do |index|
|
|
@@ -63,7 +65,7 @@ module Ibex
|
|
|
63
65
|
pending << "("
|
|
64
66
|
end
|
|
65
67
|
|
|
66
|
-
# @rbs (Array[
|
|
68
|
+
# @rbs (Array[pending_item] pending, Array[Frontend::AST::item] items, String separator) -> void
|
|
67
69
|
def push_render_items(pending, items, separator)
|
|
68
70
|
(items.length - 1).downto(0) do |index|
|
|
69
71
|
pending << separator if index < items.length - 1
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ibex
|
|
4
|
+
# Builds the single current Grammar IR format for every normalized source.
|
|
5
|
+
module NormalizeGrammarBuilder
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
# @rbs (IR::ParserContract? parser_contract) -> IR::Grammar
|
|
9
|
+
def build_grammar(parser_contract)
|
|
10
|
+
# @type self: Normalizer
|
|
11
|
+
keywords = {
|
|
12
|
+
class_name: @ast.class_name, superclass: @ast.superclass, start: @start_name,
|
|
13
|
+
expect: @expected_conflicts, options: @options, symbols: @symbols,
|
|
14
|
+
mode: @mode, starts: @start_names, expect_rr: @expected_rr_conflicts,
|
|
15
|
+
parser_parameters: @parser_parameters, value_printers: @value_printers.values,
|
|
16
|
+
grammar_tests: @grammar_tests, lexer: normalize_lexer,
|
|
17
|
+
recovery: { sync_tokens: @recovery_sync_tokens, on_error_reduce: @on_error_reduce_groups },
|
|
18
|
+
productions: @productions, user_code: normalized_user_code,
|
|
19
|
+
conversions: @conversions, warnings: @warnings, user_code_chunks: normalized_user_code_chunks,
|
|
20
|
+
source_provenance: { file: @ast.loc.file, root: @resolution&.root_directory, byte_span: nil }
|
|
21
|
+
} #: { class_name: String, superclass: String?, start: String, expect: Integer, options: IR::grammar_options, symbols: Array[IR::GrammarSymbol], productions: Array[IR::Production], user_code: Hash[String, String], conversions: Hash[String, String], warnings: Array[IR::grammar_warning] } # rubocop:disable Layout/LineLength -- inline Steep shape mirrors the normalized builder contract.
|
|
22
|
+
|
|
23
|
+
IR::Grammar.new(**keywords, parser_contract: parser_contract || IR::ParserContract.new) # steep:ignore Ruby::InsufficientKeywordArguments
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -1,9 +1,43 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
2
3
|
|
|
3
4
|
module Ibex
|
|
4
5
|
# Deterministically substitutes inline-rule productions before LR construction.
|
|
5
6
|
# rubocop:disable Metrics/ModuleLength -- expansion, action plans, and id remapping share one invariant.
|
|
6
7
|
module NormalizeInlineExpansion
|
|
8
|
+
# @rbs!
|
|
9
|
+
# type inline_reference = [:physical | :step, Integer]
|
|
10
|
+
# type inline_step = {
|
|
11
|
+
# kind: :inline | :rule,
|
|
12
|
+
# rule: String?,
|
|
13
|
+
# code: String?,
|
|
14
|
+
# loc: IR::location,
|
|
15
|
+
# named_refs: Array[IR::named_ref],
|
|
16
|
+
# context_length: Integer,
|
|
17
|
+
# inputs: Array[inline_reference],
|
|
18
|
+
# stack_inputs: Array[inline_reference],
|
|
19
|
+
# lookahead: Integer,
|
|
20
|
+
# result_var: bool,
|
|
21
|
+
# result_type: String?
|
|
22
|
+
# }
|
|
23
|
+
# type inline_variant = {
|
|
24
|
+
# rhs: Array[Integer],
|
|
25
|
+
# steps: Array[inline_step],
|
|
26
|
+
# logical_refs: Array[inline_reference],
|
|
27
|
+
# output_ref: inline_reference?,
|
|
28
|
+
# inline_used: bool,
|
|
29
|
+
# inline_rule: String?,
|
|
30
|
+
# precedence_override: Integer?,
|
|
31
|
+
# precedence_contributes: bool,
|
|
32
|
+
# parameter: IR::parameter_expansion?
|
|
33
|
+
# }
|
|
34
|
+
# type inline_frame = {
|
|
35
|
+
# production: IR::Production,
|
|
36
|
+
# symbol_id: Integer?,
|
|
37
|
+
# index: Integer,
|
|
38
|
+
# variant: inline_variant
|
|
39
|
+
# }
|
|
40
|
+
|
|
7
41
|
private
|
|
8
42
|
|
|
9
43
|
# @rbs () -> void
|
|
@@ -33,20 +67,21 @@ module Ibex
|
|
|
33
67
|
# The single-definition path reuses its accumulated arrays, so a long
|
|
34
68
|
# acyclic chain remains linear in the size of its final action plan.
|
|
35
69
|
# @rbs (IR::Production production, Hash[Integer, Array[IR::Production]] definitions) ->
|
|
36
|
-
# Array[
|
|
70
|
+
# Array[inline_variant]
|
|
37
71
|
def expand_inline_production(production, definitions)
|
|
38
72
|
# @type self: Normalizer
|
|
39
|
-
variants = [] #: Array[
|
|
40
|
-
worklist = [[inline_expansion_frame(production, nil)]] #: Array[Array[
|
|
73
|
+
variants = [] #: Array[inline_variant]
|
|
74
|
+
worklist = [[inline_expansion_frame(production, nil)]] #: Array[Array[inline_frame]]
|
|
41
75
|
until worklist.empty?
|
|
42
76
|
frames = worklist.pop || raise(Ibex::Error, "internal inline expansion worklist underflow")
|
|
43
|
-
|
|
77
|
+
location = production.origin[:loc] #: IR::location?
|
|
78
|
+
drain_inline_expansion_frames(frames, definitions, worklist, variants, location)
|
|
44
79
|
end
|
|
45
80
|
variants
|
|
46
81
|
end
|
|
47
82
|
|
|
48
|
-
# @rbs (Array[
|
|
49
|
-
# Array[Array[
|
|
83
|
+
# @rbs (Array[inline_frame] frames, Hash[Integer, Array[IR::Production]] definitions,
|
|
84
|
+
# Array[Array[inline_frame]] worklist, Array[inline_variant] variants,
|
|
50
85
|
# IR::location? location) -> void
|
|
51
86
|
def drain_inline_expansion_frames(frames, definitions, worklist, variants, location)
|
|
52
87
|
loop do
|
|
@@ -60,8 +95,8 @@ module Ibex
|
|
|
60
95
|
end
|
|
61
96
|
end
|
|
62
97
|
|
|
63
|
-
# @rbs (Array[
|
|
64
|
-
# Array[Array[
|
|
98
|
+
# @rbs (Array[inline_frame] frames, Hash[Integer, Array[IR::Production]] definitions,
|
|
99
|
+
# Array[Array[inline_frame]] worklist, Array[inline_variant] variants,
|
|
65
100
|
# IR::location? location) -> bool
|
|
66
101
|
def advance_inline_expansion_frame?(frames, definitions, worklist, variants, location)
|
|
67
102
|
frame = frames.fetch(-1)
|
|
@@ -85,8 +120,8 @@ module Ibex
|
|
|
85
120
|
true
|
|
86
121
|
end
|
|
87
122
|
|
|
88
|
-
# @rbs (Array[
|
|
89
|
-
# Array[Array[
|
|
123
|
+
# @rbs (Array[inline_frame] frames, Array[IR::Production] choices, Integer symbol_id,
|
|
124
|
+
# Array[Array[inline_frame]] worklist) -> void
|
|
90
125
|
def schedule_inline_choice_branches(frames, choices, symbol_id, worklist)
|
|
91
126
|
choices.reverse_each do |choice|
|
|
92
127
|
branch = clone_inline_expansion_frames(frames)
|
|
@@ -95,8 +130,8 @@ module Ibex
|
|
|
95
130
|
end
|
|
96
131
|
end
|
|
97
132
|
|
|
98
|
-
# @rbs (Array[
|
|
99
|
-
# Array[Array[
|
|
133
|
+
# @rbs (Array[inline_frame] frames, Array[inline_variant] variants,
|
|
134
|
+
# Array[Array[inline_frame]] worklist, IR::location? location) -> bool
|
|
100
135
|
def complete_inline_expansion_frame?(frames, variants, worklist, location)
|
|
101
136
|
frame = frames.fetch(-1)
|
|
102
137
|
current = frame.fetch(:production)
|
|
@@ -108,32 +143,34 @@ module Ibex
|
|
|
108
143
|
return true
|
|
109
144
|
end
|
|
110
145
|
|
|
111
|
-
|
|
146
|
+
symbol_id = frame.fetch(:symbol_id) || raise(Ibex::Error, "inline expansion frame is missing its symbol")
|
|
147
|
+
choice = finish_inline_choice(completed, current, symbol_id)
|
|
112
148
|
parent = frames.fetch(-1)
|
|
113
149
|
parent[:variant] = combine_inline_variant(parent.fetch(:variant), choice)
|
|
114
150
|
false
|
|
115
151
|
end
|
|
116
152
|
|
|
117
|
-
# @rbs (IR::Production production, Integer? symbol_id) ->
|
|
153
|
+
# @rbs (IR::Production production, Integer? symbol_id) -> inline_frame
|
|
118
154
|
def inline_expansion_frame(production, symbol_id)
|
|
119
155
|
{ production: production, symbol_id: symbol_id, index: 0, variant: empty_inline_variant(production) }
|
|
120
156
|
end
|
|
121
157
|
|
|
122
|
-
# @rbs (Array[
|
|
158
|
+
# @rbs (Array[inline_frame] frames) -> Array[inline_frame]
|
|
123
159
|
def clone_inline_expansion_frames(frames)
|
|
124
160
|
frames.map do |frame|
|
|
125
161
|
variant = frame.fetch(:variant)
|
|
126
|
-
frame.merge(
|
|
162
|
+
cloned = frame.merge(
|
|
127
163
|
variant: variant.merge(
|
|
128
164
|
rhs: variant.fetch(:rhs).dup,
|
|
129
165
|
steps: variant.fetch(:steps).dup,
|
|
130
166
|
logical_refs: variant.fetch(:logical_refs).dup
|
|
131
167
|
)
|
|
132
168
|
)
|
|
169
|
+
cloned #: inline_frame
|
|
133
170
|
end
|
|
134
171
|
end
|
|
135
172
|
|
|
136
|
-
# @rbs (IR::Production production) ->
|
|
173
|
+
# @rbs (IR::Production production) -> inline_variant
|
|
137
174
|
def empty_inline_variant(production)
|
|
138
175
|
{
|
|
139
176
|
rhs: [],
|
|
@@ -148,61 +185,69 @@ module Ibex
|
|
|
148
185
|
}
|
|
149
186
|
end
|
|
150
187
|
|
|
151
|
-
# @rbs (
|
|
188
|
+
# @rbs (inline_variant variant, Integer symbol_id) -> inline_variant
|
|
152
189
|
def append_inline_symbol(variant, symbol_id)
|
|
153
190
|
# @type self: Normalizer
|
|
154
191
|
rhs = variant.fetch(:rhs)
|
|
155
192
|
terminal = @symbols.fetch(symbol_id).terminal?
|
|
193
|
+
reference = [:physical, rhs.length] #: inline_reference
|
|
194
|
+
logical_refs = variant.fetch(:logical_refs) + [reference] #: Array[inline_reference]
|
|
156
195
|
variant.merge(
|
|
157
196
|
rhs: rhs + [symbol_id],
|
|
158
|
-
logical_refs:
|
|
197
|
+
logical_refs: logical_refs,
|
|
159
198
|
precedence_override: terminal ? nil : variant[:precedence_override],
|
|
160
199
|
precedence_contributes: terminal || variant.fetch(:precedence_contributes)
|
|
161
|
-
)
|
|
200
|
+
) #: inline_variant
|
|
162
201
|
end
|
|
163
202
|
|
|
164
|
-
# @rbs (
|
|
203
|
+
# @rbs (inline_variant parent, inline_variant child) -> inline_variant
|
|
165
204
|
def combine_inline_variant(parent, child)
|
|
166
205
|
physical_offset = parent.fetch(:rhs).length
|
|
167
206
|
step_offset = parent.fetch(:steps).length
|
|
168
207
|
steps = combined_inline_steps(parent, child, physical_offset, step_offset)
|
|
208
|
+
output_ref = child.fetch(:output_ref) || raise(Ibex::Error, "inline choice has no output reference")
|
|
209
|
+
rhs = append_inline_array(parent.fetch(:rhs), child.fetch(:rhs)) #: Array[Integer]
|
|
210
|
+
combined_steps = append_inline_array(parent.fetch(:steps), steps) #: Array[inline_step]
|
|
211
|
+
logical_refs = parent.fetch(:logical_refs) + [
|
|
212
|
+
remap_inline_reference(output_ref, physical_offset, step_offset)
|
|
213
|
+
] #: Array[inline_reference]
|
|
169
214
|
parent.merge(
|
|
170
|
-
rhs:
|
|
171
|
-
steps:
|
|
172
|
-
logical_refs:
|
|
173
|
-
remap_inline_reference(child.fetch(:output_ref), physical_offset, step_offset)
|
|
174
|
-
],
|
|
215
|
+
rhs: rhs,
|
|
216
|
+
steps: combined_steps,
|
|
217
|
+
logical_refs: logical_refs,
|
|
175
218
|
inline_used: true,
|
|
176
219
|
inline_rule: parent[:inline_rule] || child[:inline_rule],
|
|
177
220
|
precedence_override: combined_inline_precedence(parent, child),
|
|
178
221
|
precedence_contributes: parent.fetch(:precedence_contributes) ||
|
|
179
222
|
child.fetch(:precedence_contributes),
|
|
180
223
|
parameter: parent[:parameter] || child[:parameter]
|
|
181
|
-
)
|
|
224
|
+
) #: inline_variant
|
|
182
225
|
end
|
|
183
226
|
|
|
184
|
-
# @rbs (
|
|
185
|
-
# Integer physical_offset, Integer step_offset) -> Array[
|
|
227
|
+
# @rbs (inline_variant parent, inline_variant child,
|
|
228
|
+
# Integer physical_offset, Integer step_offset) -> Array[inline_step]
|
|
186
229
|
def combined_inline_steps(parent, child, physical_offset, step_offset)
|
|
187
230
|
return child.fetch(:steps) if physical_offset.zero? && step_offset.zero? && parent.fetch(:logical_refs).empty?
|
|
188
231
|
|
|
189
232
|
remap_inline_steps(parent, child, physical_offset, step_offset)
|
|
190
233
|
end
|
|
191
234
|
|
|
192
|
-
#
|
|
235
|
+
# The helper is shared by homogeneous integer and step arrays; callers
|
|
236
|
+
# assert the concrete element type at each use site.
|
|
237
|
+
# @rbs (Array[Object?] left, Array[Object?] right) -> Array[Object?]
|
|
193
238
|
def append_inline_array(left, right)
|
|
194
239
|
left.empty? ? right : left + right
|
|
195
240
|
end
|
|
196
241
|
|
|
197
|
-
# @rbs (
|
|
242
|
+
# @rbs (inline_variant parent, inline_variant child) -> Integer?
|
|
198
243
|
def combined_inline_precedence(parent, child)
|
|
199
244
|
return child[:precedence_override] if child.fetch(:precedence_contributes)
|
|
200
245
|
|
|
201
246
|
parent[:precedence_override]
|
|
202
247
|
end
|
|
203
248
|
|
|
204
|
-
# @rbs (
|
|
205
|
-
# Integer physical_offset, Integer step_offset) -> Array[
|
|
249
|
+
# @rbs (inline_variant parent, inline_variant child,
|
|
250
|
+
# Integer physical_offset, Integer step_offset) -> Array[inline_step]
|
|
206
251
|
def remap_inline_steps(parent, child, physical_offset, step_offset)
|
|
207
252
|
child.fetch(:steps).map do |step|
|
|
208
253
|
inputs = step.fetch(:inputs).map do |reference|
|
|
@@ -211,11 +256,12 @@ module Ibex
|
|
|
211
256
|
stack_inputs = step.fetch(:stack_inputs).map do |reference|
|
|
212
257
|
remap_inline_reference(reference, physical_offset, step_offset)
|
|
213
258
|
end
|
|
214
|
-
step.merge(
|
|
259
|
+
remapped = step.merge(
|
|
215
260
|
inputs: inputs,
|
|
216
261
|
stack_inputs: parent.fetch(:logical_refs) + stack_inputs,
|
|
217
262
|
lookahead: step.fetch(:lookahead) + physical_offset
|
|
218
263
|
)
|
|
264
|
+
remapped #: inline_step
|
|
219
265
|
end
|
|
220
266
|
end
|
|
221
267
|
|
|
@@ -229,17 +275,16 @@ module Ibex
|
|
|
229
275
|
[kind, index + (kind == :physical ? physical_offset : step_offset)]
|
|
230
276
|
end
|
|
231
277
|
|
|
232
|
-
# @rbs (
|
|
278
|
+
# @rbs (inline_variant variant, IR::Production production) -> inline_variant
|
|
233
279
|
def finish_inline_precedence(variant, production)
|
|
234
280
|
explicit = production.precedence_override
|
|
235
281
|
variant.merge(
|
|
236
282
|
precedence_override: explicit || variant[:precedence_override],
|
|
237
283
|
precedence_contributes: !explicit.nil? || variant.fetch(:precedence_contributes)
|
|
238
|
-
)
|
|
284
|
+
) #: inline_variant
|
|
239
285
|
end
|
|
240
286
|
|
|
241
|
-
# @rbs (
|
|
242
|
-
# Hash[Symbol, untyped]
|
|
287
|
+
# @rbs (inline_variant variant, IR::Production production, Integer symbol_id) -> inline_variant
|
|
243
288
|
def finish_inline_choice(variant, production, symbol_id)
|
|
244
289
|
steps = variant.fetch(:steps)
|
|
245
290
|
rule = @inline_rule_by_symbol.fetch(symbol_id)
|
|
@@ -250,18 +295,20 @@ module Ibex
|
|
|
250
295
|
output_ref: [:step, steps.length - 1],
|
|
251
296
|
inline_used: true,
|
|
252
297
|
inline_rule: rule
|
|
253
|
-
)
|
|
298
|
+
) #: inline_variant
|
|
254
299
|
end
|
|
255
300
|
|
|
256
|
-
# @rbs (IR::Production production, Array[
|
|
257
|
-
#
|
|
301
|
+
# @rbs (IR::Production production, Array[inline_reference] inputs, Integer lookahead,
|
|
302
|
+
# :inline | :rule kind, String? rule) -> inline_step
|
|
258
303
|
def inline_action_step(production, inputs, lookahead, kind, rule)
|
|
259
304
|
action = production.action
|
|
305
|
+
location = action&.location || production.origin.fetch(:loc)
|
|
306
|
+
typed_location = location #: IR::location
|
|
260
307
|
{
|
|
261
308
|
kind: kind,
|
|
262
309
|
rule: rule,
|
|
263
310
|
code: action&.code,
|
|
264
|
-
loc:
|
|
311
|
+
loc: typed_location,
|
|
265
312
|
named_refs: action&.named_refs || [],
|
|
266
313
|
context_length: action&.context_length || 0,
|
|
267
314
|
inputs: inputs,
|
|
@@ -272,7 +319,7 @@ module Ibex
|
|
|
272
319
|
}
|
|
273
320
|
end
|
|
274
321
|
|
|
275
|
-
# @rbs (IR::Production production,
|
|
322
|
+
# @rbs (IR::Production production, inline_variant variant, Integer id) -> IR::Production
|
|
276
323
|
def composed_inline_production(production, variant, id)
|
|
277
324
|
steps = variant.fetch(:steps)
|
|
278
325
|
caller = inline_action_step(
|
|
@@ -288,9 +335,11 @@ module Ibex
|
|
|
288
335
|
)
|
|
289
336
|
end
|
|
290
337
|
|
|
291
|
-
# @rbs (IR::Production production, Integer physical_length, Array[
|
|
338
|
+
# @rbs (IR::Production production, Integer physical_length, Array[inline_step]) -> IR::Action
|
|
292
339
|
def composed_inline_action(production, physical_length, steps)
|
|
293
340
|
action = production.action
|
|
341
|
+
location = action&.location || production.origin.fetch(:loc)
|
|
342
|
+
typed_location = location #: IR::location
|
|
294
343
|
fragments = steps.map do |step|
|
|
295
344
|
{ kind: step.fetch(:kind), source: inline_source_provenance(step.fetch(:loc)) }
|
|
296
345
|
end
|
|
@@ -302,12 +351,12 @@ module Ibex
|
|
|
302
351
|
} #: IR::action_composition
|
|
303
352
|
IR::Action.new(
|
|
304
353
|
code: action&.code || inline_implicit_code(production.rhs.length),
|
|
305
|
-
location:
|
|
354
|
+
location: typed_location,
|
|
306
355
|
composition: composition
|
|
307
356
|
)
|
|
308
357
|
end
|
|
309
358
|
|
|
310
|
-
# @rbs (
|
|
359
|
+
# @rbs (inline_step step, Integer physical_length) -> IR::action_composition_step
|
|
311
360
|
def composition_plan_step(step, physical_length)
|
|
312
361
|
{
|
|
313
362
|
kind: step.fetch(:kind),
|
|
@@ -345,12 +394,13 @@ module Ibex
|
|
|
345
394
|
{ file: location[:file], root: @resolution&.root_directory, byte_span: nil }
|
|
346
395
|
end
|
|
347
396
|
|
|
348
|
-
# @rbs (IR::Production production,
|
|
397
|
+
# @rbs (IR::Production production, inline_variant variant) -> IR::production_expansion
|
|
349
398
|
def inline_production_expansion(production, variant)
|
|
350
399
|
existing = production.expansion
|
|
400
|
+
inline_rule = variant.fetch(:inline_rule) || raise(Ibex::Error, "inline expansion has no rule")
|
|
351
401
|
{
|
|
352
402
|
parameter: existing&.dig(:parameter) || variant[:parameter],
|
|
353
|
-
inline: { rule:
|
|
403
|
+
inline: { rule: inline_rule },
|
|
354
404
|
include_chain: existing&.dig(:include_chain) || []
|
|
355
405
|
}
|
|
356
406
|
end
|
|
@@ -367,7 +417,8 @@ module Ibex
|
|
|
367
417
|
# @rbs (IR::Production production) -> void
|
|
368
418
|
def charge_inline_expansion!(production)
|
|
369
419
|
@inline_expansion_count += 1
|
|
370
|
-
|
|
420
|
+
location = production.origin[:loc] #: IR::location?
|
|
421
|
+
enforce_inline_choice_limit!(@inline_expansion_count, location)
|
|
371
422
|
end
|
|
372
423
|
|
|
373
424
|
# @rbs (Integer count, IR::location? location) -> void
|