ibex 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +247 -104
- data/docs/architecture.md +322 -28
- data/docs/cst-migration.md +107 -0
- data/docs/cst.md +213 -0
- data/docs/development.md +129 -0
- data/docs/editor-setup.md +25 -0
- data/docs/error-ux.md +60 -0
- data/docs/grammar-reference.md +458 -18
- data/docs/lexer-migration.md +51 -0
- data/docs/racc-migration.md +34 -6
- data/docs/release-readiness.md +163 -0
- data/docs/stability.md +124 -0
- data/examples/README.md +60 -0
- data/examples/calculator.y +44 -0
- data/examples/csv.y +32 -0
- data/examples/ini.y +70 -0
- data/examples/json.y +48 -0
- data/examples/tiny_language.y +75 -0
- data/lib/ibex/analysis/sets.rb +5 -4
- data/lib/ibex/artifact_set.rb +63 -0
- data/lib/ibex/cli/ambiguity.rb +66 -0
- data/lib/ibex/cli/counterexample_options.rb +6 -2
- data/lib/ibex/cli/coverage.rb +173 -0
- data/lib/ibex/cli/debug.rb +106 -0
- data/lib/ibex/cli/diagnostics.rb +116 -0
- data/lib/ibex/cli/documentation.rb +67 -0
- data/lib/ibex/cli/error_messages.rb +177 -0
- data/lib/ibex/cli/explain.rb +76 -0
- data/lib/ibex/cli/formatting.rb +386 -0
- data/lib/ibex/cli/generation_artifacts.rb +138 -0
- data/lib/ibex/cli/generation_error_messages.rb +39 -0
- data/lib/ibex/cli/grammar_tests.rb +122 -0
- data/lib/ibex/cli/ir_tools.rb +184 -0
- data/lib/ibex/cli/lsp.rb +33 -0
- data/lib/ibex/cli/outputs.rb +91 -8
- data/lib/ibex/cli/racc_migration.rb +87 -0
- data/lib/ibex/cli/samples.rb +92 -0
- data/lib/ibex/cli/watch.rb +103 -0
- data/lib/ibex/cli.rb +506 -37
- data/lib/ibex/codegen/action_locations.rb +103 -0
- data/lib/ibex/codegen/action_method_source.rb +210 -0
- data/lib/ibex/codegen/action_source.rb +118 -0
- data/lib/ibex/codegen/ambiguity.rb +173 -0
- data/lib/ibex/codegen/cst_metadata.rb +171 -0
- data/lib/ibex/codegen/documentation.rb +170 -0
- data/lib/ibex/codegen/explain.rb +312 -0
- data/lib/ibex/codegen/generated_action_abi.rb +288 -0
- data/lib/ibex/codegen/html.rb +94 -10
- data/lib/ibex/codegen/mermaid.rb +43 -0
- data/lib/ibex/codegen/railroad.rb +197 -0
- data/lib/ibex/codegen/railroad_documentation.rb +59 -0
- data/lib/ibex/codegen/rbs.rb +323 -2
- data/lib/ibex/codegen/report.rb +46 -6
- data/lib/ibex/codegen/ruby.rb +334 -59
- data/lib/ibex/codegen/ruby_actions.rb +143 -0
- data/lib/ibex/codegen/ruby_ast.rb +121 -0
- data/lib/ibex/codegen/ruby_error_messages.rb +28 -0
- data/lib/ibex/codegen/ruby_lexer.rb +83 -0
- data/lib/ibex/codegen/ruby_syntax.rb +90 -0
- data/lib/ibex/codegen/ruby_table_metadata.rb +57 -0
- data/lib/ibex/codegen/ruby_value_printers.rb +56 -0
- data/lib/ibex/codegen/symbol_labels.rb +1 -1
- data/lib/ibex/coverage/collector.rb +188 -0
- data/lib/ibex/coverage/event_stream.rb +97 -0
- data/lib/ibex/coverage/report.rb +259 -0
- data/lib/ibex/coverage/runtime_event_validator.rb +160 -0
- data/lib/ibex/coverage.rb +13 -0
- data/lib/ibex/error_messages/parser.rb +159 -0
- data/lib/ibex/error_messages/parser_v2.rb +198 -0
- data/lib/ibex/error_messages/renderer.rb +65 -0
- data/lib/ibex/error_messages/sentence_search.rb +196 -0
- data/lib/ibex/error_messages/update.rb +169 -0
- data/lib/ibex/error_messages.rb +165 -0
- data/lib/ibex/frontend/ast.rb +145 -6
- data/lib/ibex/frontend/bootstrap_parser.rb +47 -4
- data/lib/ibex/frontend/diagnostic.rb +81 -0
- data/lib/ibex/frontend/diagnostic_recovery.rb +268 -0
- data/lib/ibex/frontend/dsl.rb +66 -7
- data/lib/ibex/frontend/formatter.rb +407 -0
- data/lib/ibex/frontend/generated_parser.rb +614 -190
- data/lib/ibex/frontend/generated_parser_base.rb +164 -30
- data/lib/ibex/frontend/generated_parser_includes.rb +61 -0
- data/lib/ibex/frontend/generated_parser_metadata.rb +61 -0
- data/lib/ibex/frontend/generated_parser_parameters.rb +60 -0
- data/lib/ibex/frontend/generation.rb +33 -0
- data/lib/ibex/frontend/lexer.rb +162 -10
- data/lib/ibex/frontend/lexer_recovery.rb +84 -0
- data/lib/ibex/frontend/parser/declarations.rb +247 -11
- data/lib/ibex/frontend/parser/parameters.rb +82 -0
- data/lib/ibex/frontend/parser/rules.rb +43 -6
- data/lib/ibex/frontend/parser.rb +182 -4
- data/lib/ibex/frontend/regenerator.rb +26 -1
- data/lib/ibex/frontend/resolution.rb +69 -0
- data/lib/ibex/frontend/resolver.rb +217 -0
- data/lib/ibex/frontend/rule_documentation.rb +103 -0
- data/lib/ibex/frontend/source_cursor.rb +132 -8
- data/lib/ibex/frontend/source_document.rb +229 -0
- data/lib/ibex/frontend/source_loader.rb +150 -0
- data/lib/ibex/frontend/source_span.rb +81 -0
- data/lib/ibex/frontend/token_adapter/declaration_document_state.rb +47 -0
- data/lib/ibex/frontend/token_adapter/declaration_lexer_state.rb +83 -0
- data/lib/ibex/frontend/token_adapter/declaration_state.rb +216 -26
- data/lib/ibex/frontend/token_adapter/delimiter_tracker.rb +8 -2
- data/lib/ibex/frontend/token_adapter/rule_state.rb +60 -2
- data/lib/ibex/frontend/token_adapter.rb +8 -3
- data/lib/ibex/frontend.rb +13 -2
- data/lib/ibex/generation_input.rb +57 -0
- data/lib/ibex/generation_manifest.rb +200 -0
- data/lib/ibex/generation_transaction.rb +261 -0
- data/lib/ibex/generation_transaction_recovery.rb +109 -0
- data/lib/ibex/generation_transaction_validation.rb +196 -0
- data/lib/ibex/grammar_tests.rb +206 -0
- data/lib/ibex/ir/automaton_ir.rb +38 -5
- data/lib/ibex/ir/grammar_ir.rb +137 -24
- data/lib/ibex/ir/lexer_ir.rb +76 -0
- data/lib/ibex/ir/migration.rb +120 -0
- data/lib/ibex/ir/serialize.rb +110 -19
- data/lib/ibex/ir/validator/automaton.rb +345 -0
- data/lib/ibex/ir/validator/base.rb +129 -0
- data/lib/ibex/ir/validator/grammar.rb +604 -0
- data/lib/ibex/ir/validator/lexer.rb +113 -0
- data/lib/ibex/ir/validator.rb +62 -0
- data/lib/ibex/ir.rb +57 -4
- data/lib/ibex/lalr/build_metrics.rb +23 -0
- data/lib/ibex/lalr/builder.rb +379 -52
- data/lib/ibex/lalr/conflict.rb +1 -0
- data/lib/ibex/lalr/conflict_search.rb +11 -5
- data/lib/ibex/lalr/counterexample.rb +20 -5
- data/lib/ibex/lalr/direct_lookaheads.rb +236 -0
- data/lib/ibex/lalr/ielr_partition.rb +152 -0
- data/lib/ibex/lalr/on_error_reductions.rb +74 -0
- data/lib/ibex/lalr.rb +7 -0
- data/lib/ibex/location.rb +129 -0
- data/lib/ibex/lsp/document_handlers.rb +66 -0
- data/lib/ibex/lsp/document_store.rb +264 -0
- data/lib/ibex/lsp/document_store_diagnostics.rb +44 -0
- data/lib/ibex/lsp/document_store_validation.rb +61 -0
- data/lib/ibex/lsp/initialization_handlers.rb +78 -0
- data/lib/ibex/lsp/navigation_handlers.rb +56 -0
- data/lib/ibex/lsp/position_codec.rb +109 -0
- data/lib/ibex/lsp/protocol_error.rb +33 -0
- data/lib/ibex/lsp/request_handlers.rb +45 -0
- data/lib/ibex/lsp/request_support.rb +87 -0
- data/lib/ibex/lsp/server.rb +146 -0
- data/lib/ibex/lsp/symbol_index.rb +241 -0
- data/lib/ibex/lsp/symbol_index_builder.rb +267 -0
- data/lib/ibex/lsp/symbol_index_precedence_references.rb +44 -0
- data/lib/ibex/lsp/symbol_index_source_queries.rb +61 -0
- data/lib/ibex/lsp/symbol_occurrence.rb +17 -0
- data/lib/ibex/lsp/transport.rb +118 -0
- data/lib/ibex/lsp/workspace.rb +127 -0
- data/lib/ibex/lsp/workspace_analyzer.rb +199 -0
- data/lib/ibex/lsp.rb +32 -0
- data/lib/ibex/normalize/declarations.rb +140 -7
- data/lib/ibex/normalize/diagnostics.rb +50 -5
- data/lib/ibex/normalize/expander.rb +59 -55
- data/lib/ibex/normalize/expression.rb +60 -39
- data/lib/ibex/normalize/inline_expansion.rb +414 -0
- data/lib/ibex/normalize/inline_validation.rb +174 -0
- data/lib/ibex/normalize/lexer.rb +131 -0
- data/lib/ibex/normalize/named_references.rb +60 -0
- data/lib/ibex/normalize/nodes.rb +46 -0
- data/lib/ibex/normalize/parameter_ebnf_lowering.rb +69 -0
- data/lib/ibex/normalize/parameter_lowering.rb +126 -0
- data/lib/ibex/normalize/parameter_substitution.rb +125 -0
- data/lib/ibex/normalize/parameter_validation.rb +140 -0
- data/lib/ibex/normalize/parameters.rb +199 -0
- data/lib/ibex/normalize/recovery_declarations.rb +84 -0
- data/lib/ibex/normalize.rb +179 -14
- data/lib/ibex/racc_migration/checker.rb +122 -0
- data/lib/ibex/racc_migration/harness.rb +177 -0
- data/lib/ibex/racc_migration/report.rb +94 -0
- data/lib/ibex/racc_migration.rb +12 -0
- data/lib/ibex/rake_task.rb +116 -0
- data/lib/ibex/samples.rb +186 -0
- data/lib/ibex/table_simulation/result.rb +51 -0
- data/lib/ibex/table_simulation/simulator.rb +253 -0
- data/lib/ibex/table_simulation/step.rb +60 -0
- data/lib/ibex/table_simulation/text.rb +31 -0
- data/lib/ibex/table_simulation.rb +13 -0
- data/lib/ibex/tables.rb +9 -70
- data/lib/ibex/version.rb +1 -1
- data/lib/ibex/watch/runner.rb +172 -0
- data/lib/ibex/watch/source_snapshot.rb +93 -0
- data/lib/ibex/watch.rb +11 -0
- data/lib/ibex.rb +25 -1
- data/schema/automaton-ir-v1.schema.json +401 -0
- data/schema/automaton-ir-v2.schema.json +58 -0
- data/schema/benchmark-v1.schema.json +212 -0
- data/schema/benchmark-v2.schema.json +61 -0
- data/schema/cst-v1.json +170 -0
- data/schema/error-ux-v1.schema.json +258 -0
- data/schema/explain-v1.schema.json +433 -0
- data/schema/frontend-diagnostics-v1.schema.json +154 -0
- data/schema/generation-manifest-v1.schema.json +115 -0
- data/schema/grammar-ir-v1.schema.json +426 -0
- data/schema/grammar-ir-v2.schema.json +779 -0
- data/schema/lexer-ir-v1.schema.json +215 -0
- data/schema/migration-check-v1.schema.json +60 -0
- data/schema/performance-comparison-v1.schema.json +395 -0
- data/schema/public-performance-comparison-v1.schema.json +506 -0
- data/schema/public-performance-profile-v1.schema.json +360 -0
- data/schema/runtime-coverage-v1.schema.json +86 -0
- data/schema/runtime-event-v1.schema.json +308 -0
- data/schema/table-simulation-v1.schema.json +70 -0
- data/sig/ibex/artifact_set.rbs +37 -0
- data/sig/ibex/cli/ambiguity.rbs +22 -0
- data/sig/ibex/cli/counterexample_options.rbs +2 -0
- data/sig/ibex/cli/coverage.rbs +53 -0
- data/sig/ibex/cli/debug.rbs +28 -0
- data/sig/ibex/cli/diagnostics.rbs +38 -0
- data/sig/ibex/cli/documentation.rbs +25 -0
- data/sig/ibex/cli/error_messages.rbs +57 -0
- data/sig/ibex/cli/explain.rbs +25 -0
- data/sig/ibex/cli/formatting.rbs +103 -0
- data/sig/ibex/cli/generation_artifacts.rbs +50 -0
- data/sig/ibex/cli/generation_error_messages.rbs +19 -0
- data/sig/ibex/cli/grammar_tests.rbs +36 -0
- data/sig/ibex/cli/ir_tools.rbs +51 -0
- data/sig/ibex/cli/lsp.rbs +14 -0
- data/sig/ibex/cli/outputs.rbs +17 -0
- data/sig/ibex/cli/racc_migration.rbs +30 -0
- data/sig/ibex/cli/samples.rbs +30 -0
- data/sig/ibex/cli/watch.rbs +43 -0
- data/sig/ibex/cli.rbs +104 -5
- data/sig/ibex/codegen/action_locations.rbs +45 -0
- data/sig/ibex/codegen/action_method_source.rbs +65 -0
- data/sig/ibex/codegen/action_source.rbs +50 -0
- data/sig/ibex/codegen/ambiguity.rbs +60 -0
- data/sig/ibex/codegen/cst_metadata.rbs +59 -0
- data/sig/ibex/codegen/documentation.rbs +50 -0
- data/sig/ibex/codegen/explain.rbs +85 -0
- data/sig/ibex/codegen/generated_action_abi.rbs +101 -0
- data/sig/ibex/codegen/html.rbs +18 -2
- data/sig/ibex/codegen/mermaid.rbs +16 -0
- data/sig/ibex/codegen/railroad.rbs +82 -0
- data/sig/ibex/codegen/railroad_documentation.rbs +31 -0
- data/sig/ibex/codegen/rbs.rbs +84 -4
- data/sig/ibex/codegen/report.rbs +8 -0
- data/sig/ibex/codegen/ruby.rbs +97 -23
- data/sig/ibex/codegen/ruby_actions.rbs +54 -0
- data/sig/ibex/codegen/ruby_ast.rbs +34 -0
- data/sig/ibex/codegen/ruby_error_messages.rbs +16 -0
- data/sig/ibex/codegen/ruby_lexer.rbs +25 -0
- data/sig/ibex/codegen/ruby_syntax.rbs +25 -0
- data/sig/ibex/codegen/ruby_table_metadata.rbs +26 -0
- data/sig/ibex/codegen/ruby_value_printers.rbs +28 -0
- data/sig/ibex/coverage/collector.rbs +76 -0
- data/sig/ibex/coverage/event_stream.rbs +42 -0
- data/sig/ibex/coverage/report.rbs +100 -0
- data/sig/ibex/coverage/runtime_event_validator.rbs +68 -0
- data/sig/ibex/coverage.rbs +7 -0
- data/sig/ibex/error_messages/parser.rbs +58 -0
- data/sig/ibex/error_messages/parser_v2.rbs +67 -0
- data/sig/ibex/error_messages/renderer.rbs +23 -0
- data/sig/ibex/error_messages/sentence_search.rbs +80 -0
- data/sig/ibex/error_messages/update.rbs +43 -0
- data/sig/ibex/error_messages.rbs +85 -0
- data/sig/ibex/frontend/ast.rbs +208 -19
- data/sig/ibex/frontend/bootstrap_parser.rbs +11 -0
- data/sig/ibex/frontend/diagnostic.rbs +53 -0
- data/sig/ibex/frontend/diagnostic_recovery.rbs +98 -0
- data/sig/ibex/frontend/dsl.rbs +33 -4
- data/sig/ibex/frontend/formatter.rbs +135 -0
- data/sig/ibex/frontend/generated_parser.rbs +218 -68
- data/sig/ibex/frontend/generated_parser_base.rbs +61 -10
- data/sig/ibex/frontend/generated_parser_includes.rbs +23 -0
- data/sig/ibex/frontend/generated_parser_metadata.rbs +23 -0
- data/sig/ibex/frontend/generated_parser_parameters.rbs +24 -0
- data/sig/ibex/frontend/generation.rbs +6 -0
- data/sig/ibex/frontend/lexer.rbs +49 -2
- data/sig/ibex/frontend/lexer_recovery.rbs +25 -0
- data/sig/ibex/frontend/parser/declarations.rbs +54 -0
- data/sig/ibex/frontend/parser/parameters.rbs +28 -0
- data/sig/ibex/frontend/parser/rules.rbs +3 -0
- data/sig/ibex/frontend/parser.rbs +66 -0
- data/sig/ibex/frontend/regenerator.rbs +11 -0
- data/sig/ibex/frontend/resolution.rbs +33 -0
- data/sig/ibex/frontend/resolver.rbs +91 -0
- data/sig/ibex/frontend/rule_documentation.rbs +42 -0
- data/sig/ibex/frontend/source_cursor.rbs +36 -3
- data/sig/ibex/frontend/source_document.rbs +119 -0
- data/sig/ibex/frontend/source_loader.rbs +66 -0
- data/sig/ibex/frontend/source_span.rbs +53 -0
- data/sig/ibex/frontend/token_adapter/declaration_document_state.rbs +21 -0
- data/sig/ibex/frontend/token_adapter/declaration_lexer_state.rbs +27 -0
- data/sig/ibex/frontend/token_adapter/declaration_state.rbs +73 -5
- data/sig/ibex/frontend/token_adapter/rule_state.rbs +20 -0
- data/sig/ibex/frontend/token_adapter.rbs +5 -2
- data/sig/ibex/frontend.rbs +1 -1
- data/sig/ibex/generation_input.rbs +37 -0
- data/sig/ibex/generation_manifest.rbs +67 -0
- data/sig/ibex/generation_transaction.rbs +82 -0
- data/sig/ibex/generation_transaction_recovery.rbs +36 -0
- data/sig/ibex/generation_transaction_validation.rbs +65 -0
- data/sig/ibex/grammar_tests.rbs +93 -0
- data/sig/ibex/ir/automaton_ir.rbs +8 -2
- data/sig/ibex/ir/grammar_ir.rbs +75 -15
- data/sig/ibex/ir/lexer_ir.rbs +57 -0
- data/sig/ibex/ir/migration.rbs +34 -0
- data/sig/ibex/ir/serialize.rbs +23 -6
- data/sig/ibex/ir/validator/automaton.rbs +109 -0
- data/sig/ibex/ir/validator/base.rbs +65 -0
- data/sig/ibex/ir/validator/grammar.rbs +184 -0
- data/sig/ibex/ir/validator/lexer.rbs +37 -0
- data/sig/ibex/ir/validator.rbs +16 -0
- data/sig/ibex/ir.rbs +38 -4
- data/sig/ibex/lalr/build_metrics.rbs +20 -0
- data/sig/ibex/lalr/builder.rbs +95 -15
- data/sig/ibex/lalr/conflict_search.rbs +7 -3
- data/sig/ibex/lalr/counterexample.rbs +5 -2
- data/sig/ibex/lalr/direct_lookaheads.rbs +86 -0
- data/sig/ibex/lalr/ielr_partition.rbs +59 -0
- data/sig/ibex/lalr/on_error_reductions.rbs +22 -0
- data/sig/ibex/lalr.rbs +6 -0
- data/sig/ibex/location.rbs +67 -0
- data/sig/ibex/lsp/document_handlers.rbs +24 -0
- data/sig/ibex/lsp/document_store.rbs +94 -0
- data/sig/ibex/lsp/document_store_diagnostics.rbs +20 -0
- data/sig/ibex/lsp/document_store_validation.rbs +26 -0
- data/sig/ibex/lsp/initialization_handlers.rbs +30 -0
- data/sig/ibex/lsp/navigation_handlers.rbs +30 -0
- data/sig/ibex/lsp/position_codec.rbs +40 -0
- data/sig/ibex/lsp/protocol_error.rbs +32 -0
- data/sig/ibex/lsp/request_handlers.rbs +26 -0
- data/sig/ibex/lsp/request_support.rbs +40 -0
- data/sig/ibex/lsp/server.rbs +55 -0
- data/sig/ibex/lsp/symbol_index.rbs +78 -0
- data/sig/ibex/lsp/symbol_index_builder.rbs +87 -0
- data/sig/ibex/lsp/symbol_index_precedence_references.rbs +18 -0
- data/sig/ibex/lsp/symbol_index_source_queries.rbs +26 -0
- data/sig/ibex/lsp/symbol_occurrence.rbs +25 -0
- data/sig/ibex/lsp/transport.rbs +35 -0
- data/sig/ibex/lsp/workspace.rbs +41 -0
- data/sig/ibex/lsp/workspace_analyzer.rbs +69 -0
- data/sig/ibex/lsp.rbs +7 -0
- data/sig/ibex/normalize/declarations.rbs +31 -0
- data/sig/ibex/normalize/diagnostics.rbs +9 -0
- data/sig/ibex/normalize/expander.rbs +20 -14
- data/sig/ibex/normalize/expression.rbs +10 -10
- data/sig/ibex/normalize/inline_expansion.rbs +120 -0
- data/sig/ibex/normalize/inline_validation.rbs +40 -0
- data/sig/ibex/normalize/lexer.rbs +37 -0
- data/sig/ibex/normalize/named_references.rbs +20 -0
- data/sig/ibex/normalize/nodes.rbs +14 -0
- data/sig/ibex/normalize/parameter_ebnf_lowering.rbs +32 -0
- data/sig/ibex/normalize/parameter_lowering.rbs +35 -0
- data/sig/ibex/normalize/parameter_substitution.rbs +42 -0
- data/sig/ibex/normalize/parameter_validation.rbs +44 -0
- data/sig/ibex/normalize/parameters.rbs +46 -0
- data/sig/ibex/normalize/recovery_declarations.rbs +24 -0
- data/sig/ibex/normalize.rbs +123 -18
- data/sig/ibex/racc_migration/checker.rbs +36 -0
- data/sig/ibex/racc_migration/harness.rbs +16 -0
- data/sig/ibex/racc_migration/report.rbs +53 -0
- data/sig/ibex/racc_migration.rbs +8 -0
- data/sig/ibex/rake_task.rbs +51 -0
- data/sig/ibex/samples.rbs +51 -0
- data/sig/ibex/table_simulation/result.rbs +32 -0
- data/sig/ibex/table_simulation/simulator.rbs +98 -0
- data/sig/ibex/table_simulation/step.rbs +40 -0
- data/sig/ibex/table_simulation/text.rbs +14 -0
- data/sig/ibex/table_simulation.rbs +7 -0
- data/sig/ibex/tables.rbs +0 -26
- data/sig/ibex/watch/runner.rbs +48 -0
- data/sig/ibex/watch/source_snapshot.rbs +42 -0
- data/sig/ibex/watch.rbs +7 -0
- data/sig/ibex.rbs +2 -0
- metadata +301 -16
- data/.rubocop.yml +0 -43
- data/CHANGELOG.md +0 -30
- data/Rakefile +0 -25
- data/Steepfile +0 -10
- data/docs/compat-notes.md +0 -37
- data/docs/lexer-coverage.md +0 -14
- data/docs/phase10-extensions.md +0 -27
- data/gemfiles/Gemfile +0 -7
- data/gemfiles/Gemfile.lock +0 -98
- data/lib/ibex/frontend/grammar.y +0 -156
- data/lib/ibex/runtime/parser.rb +0 -360
- data/lib/ibex/runtime.rb +0 -8
- data/sig/ibex/runtime/parser.rbs +0 -167
- data/sig/ibex/runtime.rbs +0 -6
|
@@ -1,34 +1,51 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "generated_parser_metadata"
|
|
4
|
+
require_relative "generated_parser_includes"
|
|
5
|
+
require_relative "generated_parser_parameters"
|
|
6
|
+
|
|
3
7
|
module Ibex
|
|
4
8
|
module Frontend
|
|
5
9
|
# Semantic support and token delivery for the generated grammar parser.
|
|
10
|
+
# rubocop:disable Metrics/ClassLength -- generated grammar semantics share one parser support surface.
|
|
6
11
|
class GeneratedParserBase < Runtime::Parser
|
|
12
|
+
include GeneratedParserMetadata
|
|
13
|
+
include GeneratedParserIncludes
|
|
14
|
+
include GeneratedParserParameters
|
|
15
|
+
|
|
16
|
+
attr_reader :diagnostic_token #: Token?
|
|
17
|
+
|
|
7
18
|
# @rbs @adapter: TokenAdapter
|
|
8
19
|
# @rbs @mode: Symbol
|
|
9
20
|
|
|
10
21
|
# @rbs (Array[Token] tokens, ?mode: Symbol) -> void
|
|
11
|
-
def initialize(tokens, mode: :
|
|
12
|
-
raise ArgumentError, "mode must be :
|
|
22
|
+
def initialize(tokens, mode: :default)
|
|
23
|
+
raise ArgumentError, "mode must be :default or :extended" unless %i[default extended].include?(mode)
|
|
13
24
|
|
|
14
25
|
super()
|
|
15
|
-
@adapter = TokenAdapter.new(tokens)
|
|
26
|
+
@adapter = TokenAdapter.new(tokens, extended: mode == :extended)
|
|
16
27
|
@mode = mode
|
|
17
28
|
end
|
|
18
29
|
|
|
19
|
-
# @rbs () -> AST::Root
|
|
30
|
+
# @rbs () -> (AST::Root | AST::Fragment)
|
|
20
31
|
def parse
|
|
21
32
|
do_parse
|
|
22
33
|
end
|
|
23
34
|
|
|
24
35
|
# @rbs () -> ([external_token, Token] | false)
|
|
25
36
|
def next_token
|
|
26
|
-
@adapter.next_token
|
|
37
|
+
delivered = @adapter.next_token
|
|
38
|
+
@diagnostic_token = delivered ? delivered.fetch(1) : @adapter.eof_token
|
|
39
|
+
delivered
|
|
40
|
+
rescue Ibex::Error
|
|
41
|
+
@diagnostic_token = @adapter.last_token || @adapter.eof_token
|
|
42
|
+
raise
|
|
27
43
|
end
|
|
28
44
|
|
|
29
45
|
# @rbs (Integer? _token_id, Token? value, Array[untyped] _value_stack) -> bot
|
|
30
46
|
def on_error(_token_id, value, _value_stack)
|
|
31
47
|
token = value || @adapter.eof_token
|
|
48
|
+
@diagnostic_token = token
|
|
32
49
|
raise_contextual_error(token)
|
|
33
50
|
|
|
34
51
|
received = token&.value || token&.type || :eof
|
|
@@ -69,7 +86,7 @@ module Ibex
|
|
|
69
86
|
def expected_description(token)
|
|
70
87
|
expectation = @adapter.expectation(token)
|
|
71
88
|
return expectation if expectation
|
|
72
|
-
return ")" if @adapter.open_delimiter_kind
|
|
89
|
+
return ")" if %i[separated parameter].include?(@adapter.open_delimiter_kind)
|
|
73
90
|
|
|
74
91
|
structural_expectation(token)
|
|
75
92
|
end
|
|
@@ -88,12 +105,30 @@ module Ibex
|
|
|
88
105
|
# Array[AST::declaration] declarations, Array[AST::Rule] rules, AST::user_code user_code) -> AST::Root
|
|
89
106
|
def build_root(class_token, class_parts, superclass, declarations, rules, user_code)
|
|
90
107
|
AST::Root.new(class_name: class_parts.join("::"), superclass: superclass&.join("::"),
|
|
91
|
-
declarations: declarations, rules: rules, user_code: user_code, loc: class_token.location
|
|
108
|
+
declarations: declarations, rules: rules, user_code: user_code, loc: class_token.location,
|
|
109
|
+
extended: @mode == :extended || @adapter.extended_pragma? || @adapter.cst_pragma?,
|
|
110
|
+
cst: @adapter.cst_pragma?)
|
|
92
111
|
end
|
|
93
112
|
|
|
94
|
-
# @rbs (Token keyword, Array[String]
|
|
95
|
-
def build_tokens(keyword,
|
|
96
|
-
|
|
113
|
+
# @rbs (Token keyword, Array[[String, String?]] entries) -> AST::Tokens
|
|
114
|
+
def build_tokens(keyword, entries)
|
|
115
|
+
aliases = entries.filter_map { |name, value| [name, value] if value }.to_h
|
|
116
|
+
AST::Tokens.new(names: entries.map(&:first), aliases: aliases.empty? ? nil : aliases, loc: keyword.location)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# @rbs (Token token) -> [String, nil]
|
|
120
|
+
def build_token_entry(token)
|
|
121
|
+
[token_string(token), nil]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @rbs (Token name, Token value) -> [String, String]
|
|
125
|
+
def build_token_alias(name, value)
|
|
126
|
+
extended_only!(name.location, "token aliases")
|
|
127
|
+
unless name.location.line == value.location.line
|
|
128
|
+
fail_at(name.location, "token alias must be written on one line")
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
[token_string(name), decode_metadata_value(value, "token alias")]
|
|
97
132
|
end
|
|
98
133
|
|
|
99
134
|
# @rbs (Token keyword, Symbol direction, Array[AST::PrecedenceLevel] levels) -> AST::Precedence
|
|
@@ -104,6 +139,7 @@ module Ibex
|
|
|
104
139
|
# @rbs (Token association, Array[String] symbols) -> AST::PrecedenceLevel
|
|
105
140
|
def build_precedence_level(association, symbols)
|
|
106
141
|
fail_at(association.location, "expected at least one precedence symbol") if symbols.empty?
|
|
142
|
+
extended_only!(association.location, "%precedence") if token_string(association) == "precedence"
|
|
107
143
|
|
|
108
144
|
AST::PrecedenceLevel.new(associativity: token_string(association).to_sym, symbols: symbols,
|
|
109
145
|
loc: association.location)
|
|
@@ -119,9 +155,83 @@ module Ibex
|
|
|
119
155
|
AST::Expect.new(conflicts: token_integer(integer), loc: keyword.location)
|
|
120
156
|
end
|
|
121
157
|
|
|
122
|
-
# @rbs (Token keyword,
|
|
123
|
-
def
|
|
124
|
-
|
|
158
|
+
# @rbs (Token keyword, Token integer) -> AST::ExpectRR
|
|
159
|
+
def build_expect_rr(keyword, integer)
|
|
160
|
+
extended_only!(keyword.location, "expect-rr declarations")
|
|
161
|
+
AST::ExpectRR.new(conflicts: token_integer(integer), loc: keyword.location)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# @rbs (Token keyword, Token name, Token? type) -> AST::Parameter
|
|
165
|
+
def build_parameter(keyword, name, type)
|
|
166
|
+
extended_only!(keyword.location, "%param")
|
|
167
|
+
if type && (keyword.location.line != name.location.line || name.location.line != type.location.line)
|
|
168
|
+
fail_at(keyword.location, "%param declaration must be written on one line")
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
semantic_type = type && decode_metadata_value(type, "%param")
|
|
172
|
+
AST::Parameter.new(name: token_string(name), semantic_type: semantic_type, loc: keyword.location)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# @rbs (Token keyword, Token symbol, Token action) -> AST::Printer
|
|
176
|
+
def build_printer(keyword, symbol, action)
|
|
177
|
+
extended_only!(keyword.location, "%printer")
|
|
178
|
+
AST::Printer.new(name: token_string(symbol), code: token_string(action), loc: keyword.location)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# @rbs (Token keyword, Array[String] names) -> AST::Start
|
|
182
|
+
def build_start(keyword, names)
|
|
183
|
+
fail_at(keyword.location, "start declaration requires at least one symbol") if names.empty?
|
|
184
|
+
extended_only!(keyword.location, "multiple start symbols") if names.length > 1
|
|
185
|
+
AST::Start.new(names: names, loc: keyword.location)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# @rbs (Token keyword, Token kind, Array[String] sync_tokens) -> AST::Recovery
|
|
189
|
+
def build_recovery(keyword, kind, sync_tokens)
|
|
190
|
+
extended_only!(keyword.location, "%recover")
|
|
191
|
+
fail_at(kind.location, "expected sync, got #{kind.value}") unless token_string(kind) == "sync"
|
|
192
|
+
fail_at(keyword.location, "%recover sync requires at least one token") if sync_tokens.empty?
|
|
193
|
+
AST::Recovery.new(sync_tokens: sync_tokens, loc: keyword.location)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# @rbs (Token keyword, Array[String] names) -> AST::OnErrorReduce
|
|
197
|
+
def build_on_error_reduce(keyword, names)
|
|
198
|
+
extended_only!(keyword.location, "%on_error_reduce")
|
|
199
|
+
fail_at(keyword.location, "%on_error_reduce requires at least one nonterminal") if names.empty?
|
|
200
|
+
AST::OnErrorReduce.new(names: names, loc: keyword.location)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# @rbs (Token keyword, Token expectation, Token source) -> AST::GrammarTest
|
|
204
|
+
def build_grammar_test(keyword, expectation, source)
|
|
205
|
+
extended_only!(keyword.location, "%test")
|
|
206
|
+
expected = token_string(expectation)
|
|
207
|
+
fail_at(expectation.location, "expected accept or reject, got #{expected}") unless
|
|
208
|
+
%w[accept reject].include?(expected)
|
|
209
|
+
literal = token_string(source)
|
|
210
|
+
fail_at(source.location, "%test source must use a double-quoted string") unless literal.start_with?('"')
|
|
211
|
+
|
|
212
|
+
AST::GrammarTest.new(expectation: expected.to_sym, source: literal.undump, loc: keyword.location)
|
|
213
|
+
rescue RuntimeError => e
|
|
214
|
+
fail_at(source.location, "invalid %test source: #{e.message}")
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# @rbs (Token keyword, Array[AST::lexer_entry] entries) -> AST::Lexer
|
|
218
|
+
def build_lexer(keyword, entries)
|
|
219
|
+
extended_only!(keyword.location, "lexer declarations")
|
|
220
|
+
AST::Lexer.new(definitions: entries, loc: keyword.location)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# @rbs (Symbol kind, Token? name, Token pattern, Token? action, Token marker) -> AST::LexerRule
|
|
224
|
+
def build_lexer_rule(kind, name, pattern, action, marker)
|
|
225
|
+
fail_at(marker.location, "on lexer rules require an action") if kind == :on && !action
|
|
226
|
+
AST::LexerRule.new(
|
|
227
|
+
kind: kind, token: name && token_string(name), pattern: token_string(pattern),
|
|
228
|
+
pattern_kind: pattern.type, action: action && token_string(action), loc: marker.location
|
|
229
|
+
)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# @rbs (Token marker, Token name, Array[AST::lexer_entry] entries) -> AST::LexerState
|
|
233
|
+
def build_lexer_state(marker, name, entries)
|
|
234
|
+
AST::LexerState.new(name: token_string(name), definitions: entries, loc: marker.location)
|
|
125
235
|
end
|
|
126
236
|
|
|
127
237
|
# @rbs (Token keyword, Array[AST::Conversion] pairs) -> AST::Convert
|
|
@@ -146,13 +256,8 @@ module Ibex
|
|
|
146
256
|
fail_at(name_token.location, "invalid conversion expression: #{e.message}")
|
|
147
257
|
end
|
|
148
258
|
|
|
149
|
-
# @rbs (Token
|
|
150
|
-
def
|
|
151
|
-
AST::Rule.new(lhs: token_string(lhs), alternatives: alternatives, loc: lhs.location)
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# @rbs (Array[AST::item] items, Token? precedence) -> AST::Alternative
|
|
155
|
-
def build_alternative(items, precedence)
|
|
259
|
+
# @rbs (Array[AST::item] items, Token? precedence, AST::NodeAnnotation? node_annotation) -> AST::Alternative
|
|
260
|
+
def build_alternative(items, precedence, node_annotation)
|
|
156
261
|
last_token = @adapter.last_token
|
|
157
262
|
location = item_start_location(items.first) || precedence&.location || last_token&.location
|
|
158
263
|
raise Ibex::Error, "missing alternative location" unless location
|
|
@@ -163,8 +268,24 @@ module Ibex
|
|
|
163
268
|
items.pop
|
|
164
269
|
action = last_item
|
|
165
270
|
end
|
|
166
|
-
AST::Alternative.new(
|
|
167
|
-
|
|
271
|
+
AST::Alternative.new(
|
|
272
|
+
items: items, action: action, precedence: precedence && token_string(precedence),
|
|
273
|
+
node_annotation: node_annotation, loc: location
|
|
274
|
+
)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# @rbs (Token marker, Token name, Array[Token] fields) -> AST::NodeAnnotation
|
|
278
|
+
def build_node_annotation(marker, name, fields)
|
|
279
|
+
extended_only!(marker.location, "@node")
|
|
280
|
+
AST::NodeAnnotation.new(
|
|
281
|
+
name: token_string(name), fields: fields.map { |field| token_string(field) }, loc: marker.location
|
|
282
|
+
)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# @rbs (Token token) -> AST::Empty
|
|
286
|
+
def build_empty(token)
|
|
287
|
+
extended_only!(token.location, "%empty")
|
|
288
|
+
AST::Empty.new(loc: token.location)
|
|
168
289
|
end
|
|
169
290
|
|
|
170
291
|
# @rbs (AST::item? item) -> Location?
|
|
@@ -180,16 +301,21 @@ module Ibex
|
|
|
180
301
|
|
|
181
302
|
# @rbs (Token token, [Token, Token]? named_reference, Array[Token] suffixes) -> AST::item
|
|
182
303
|
def build_symbol_reference(token, named_reference, suffixes)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
named_reference = token_string(name)
|
|
187
|
-
end
|
|
188
|
-
item = AST::SymbolReference.new(name: token_string(token), named_reference: named_reference,
|
|
189
|
-
loc: token.location)
|
|
304
|
+
item = AST::SymbolReference.new(
|
|
305
|
+
name: token_string(token), named_reference: named_reference_value(named_reference), loc: token.location
|
|
306
|
+
)
|
|
190
307
|
apply_suffixes(item, suffixes)
|
|
191
308
|
end
|
|
192
309
|
|
|
310
|
+
# @rbs ([Token, Token]? named_reference) -> String?
|
|
311
|
+
def named_reference_value(named_reference)
|
|
312
|
+
return unless named_reference
|
|
313
|
+
|
|
314
|
+
colon, name = named_reference
|
|
315
|
+
extended_only!(colon.location, "named references")
|
|
316
|
+
token_string(name)
|
|
317
|
+
end
|
|
318
|
+
|
|
193
319
|
# @rbs (Token token) -> AST::InlineAction
|
|
194
320
|
def build_action(token)
|
|
195
321
|
AST::InlineAction.new(code: token_string(token), loc: token.location)
|
|
@@ -228,6 +354,13 @@ module Ibex
|
|
|
228
354
|
blocks
|
|
229
355
|
end
|
|
230
356
|
|
|
357
|
+
# @rbs (Token token, AST::user_code blocks) -> AST::user_code
|
|
358
|
+
def prepend_user_code(token, blocks)
|
|
359
|
+
result = append_user_code(empty_user_code, token)
|
|
360
|
+
blocks.each { |name, chunks| result[name].concat(chunks) }
|
|
361
|
+
result
|
|
362
|
+
end
|
|
363
|
+
|
|
231
364
|
# @rbs () -> AST::user_code
|
|
232
365
|
def empty_user_code
|
|
233
366
|
Hash.new { |hash, key| hash[key] = [] } #: AST::user_code
|
|
@@ -235,7 +368,7 @@ module Ibex
|
|
|
235
368
|
|
|
236
369
|
# @rbs (Location location, String feature) -> void
|
|
237
370
|
def extended_only!(location, feature)
|
|
238
|
-
return if @mode == :extended || @adapter.extended_pragma?
|
|
371
|
+
return if @mode == :extended || @adapter.extended_pragma? || @adapter.cst_pragma?
|
|
239
372
|
|
|
240
373
|
fail_at(location, "#{feature} require extended mode")
|
|
241
374
|
end
|
|
@@ -269,5 +402,6 @@ module Ibex
|
|
|
269
402
|
fail_at(token.location, "expected user-code token")
|
|
270
403
|
end
|
|
271
404
|
end
|
|
405
|
+
# rubocop:enable Metrics/ClassLength
|
|
272
406
|
end
|
|
273
407
|
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ibex
|
|
4
|
+
module Frontend
|
|
5
|
+
# Semantic builders for fragment and include frontend nodes.
|
|
6
|
+
module GeneratedParserIncludes
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
# @rbs (Token keyword, Array[AST::declaration] declarations, Array[AST::Rule] rules,
|
|
10
|
+
# AST::user_code user_code) -> AST::Fragment
|
|
11
|
+
def build_fragment(keyword, declarations, rules, user_code)
|
|
12
|
+
# @type self: GeneratedParserBase
|
|
13
|
+
extended_only!(keyword.location, "fragments")
|
|
14
|
+
reject_fragment_root_declarations(declarations)
|
|
15
|
+
user_block = user_code.values.flatten.first
|
|
16
|
+
fail_at(user_block.loc, "user code is not allowed in fragments") if user_block
|
|
17
|
+
AST::Fragment.new(declarations: declarations, rules: rules, loc: keyword.location)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @rbs (Token keyword, Token path) -> AST::Include
|
|
21
|
+
def build_include(keyword, path)
|
|
22
|
+
# @type self: GeneratedParserBase
|
|
23
|
+
label = token_string(keyword)
|
|
24
|
+
extended_only!(keyword.location, "#{label}s")
|
|
25
|
+
value = token_string(path)
|
|
26
|
+
unless value.start_with?('"') && value.end_with?('"')
|
|
27
|
+
fail_at(path.location, "#{label} path must use a double-quoted string")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
AST::Include.new(path: value.undump, loc: keyword.location)
|
|
31
|
+
rescue RuntimeError => e
|
|
32
|
+
fail_at(path.location, "invalid #{label} path: #{e.message}")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @rbs (Array[AST::declaration] declarations) -> void
|
|
36
|
+
def reject_fragment_root_declarations(declarations)
|
|
37
|
+
# @type self: GeneratedParserBase
|
|
38
|
+
root_only = declarations.find { |declaration| fragment_root_declaration_name(declaration) }
|
|
39
|
+
return unless root_only
|
|
40
|
+
|
|
41
|
+
name = fragment_root_declaration_name(root_only)
|
|
42
|
+
fail_at(root_only.loc, "#{name} declarations are not allowed in fragments")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @rbs (AST::declaration declaration) -> String?
|
|
46
|
+
def fragment_root_declaration_name(declaration)
|
|
47
|
+
return "options" if declaration.is_a?(AST::Options)
|
|
48
|
+
return "expect" if declaration.is_a?(AST::Expect)
|
|
49
|
+
return "%expect-rr" if declaration.is_a?(AST::ExpectRR)
|
|
50
|
+
return "%param" if declaration.is_a?(AST::Parameter)
|
|
51
|
+
return "start" if declaration.is_a?(AST::Start)
|
|
52
|
+
return "%recover" if declaration.is_a?(AST::Recovery)
|
|
53
|
+
return "%on_error_reduce" if declaration.is_a?(AST::OnErrorReduce)
|
|
54
|
+
return "%test" if declaration.is_a?(AST::GrammarTest)
|
|
55
|
+
return "lexer" if declaration.is_a?(AST::Lexer)
|
|
56
|
+
|
|
57
|
+
nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ibex
|
|
4
|
+
module Frontend
|
|
5
|
+
# Builds extended symbol metadata declarations for the generated grammar parser.
|
|
6
|
+
module GeneratedParserMetadata
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
# @rbs (Token keyword, Token name, Token value) -> AST::DisplayName
|
|
10
|
+
def build_display_name(keyword, name, value)
|
|
11
|
+
# @type self: GeneratedParserBase
|
|
12
|
+
extended_only!(keyword.location, "display declarations")
|
|
13
|
+
result = build_symbol_metadata(AST::DisplayName, keyword, name, value, "display")
|
|
14
|
+
return result if result.is_a?(AST::DisplayName)
|
|
15
|
+
|
|
16
|
+
raise Ibex::Error, "display metadata builder returned the wrong node"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @rbs (Token keyword, Token name, Token value) -> AST::SemanticType
|
|
20
|
+
def build_semantic_type(keyword, name, value)
|
|
21
|
+
# @type self: GeneratedParserBase
|
|
22
|
+
extended_only!(keyword.location, "type declarations")
|
|
23
|
+
result = build_symbol_metadata(AST::SemanticType, keyword, name, value, "type")
|
|
24
|
+
return result if result.is_a?(AST::SemanticType)
|
|
25
|
+
|
|
26
|
+
raise Ibex::Error, "type metadata builder returned the wrong node"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @rbs (singleton(AST::DisplayName) | singleton(AST::SemanticType) node_class,
|
|
30
|
+
# Token keyword, Token name, Token value, String feature) -> (AST::DisplayName | AST::SemanticType)
|
|
31
|
+
def build_symbol_metadata(node_class, keyword, name, value, feature)
|
|
32
|
+
# @type self: GeneratedParserBase
|
|
33
|
+
unless keyword.location.line == name.location.line && name.location.line == value.location.line
|
|
34
|
+
fail_at(keyword.location, "#{feature} declaration must be written on one line")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
decoded = decode_metadata_value(value, feature)
|
|
38
|
+
node_class.new(name: token_string(name), value: decoded, loc: keyword.location)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @rbs (Token token, String feature) -> String
|
|
42
|
+
def decode_metadata_value(token, feature)
|
|
43
|
+
# @type self: GeneratedParserBase
|
|
44
|
+
literal = token_string(token)
|
|
45
|
+
decoded = if literal.start_with?('"')
|
|
46
|
+
literal.undump
|
|
47
|
+
else
|
|
48
|
+
(literal[1...-1] || "").gsub("\\'", "'").gsub("\\\\", "\\")
|
|
49
|
+
end
|
|
50
|
+
fail_at(token.location, "#{feature} value must not be empty") if decoded.strip.empty?
|
|
51
|
+
fail_at(token.location, "#{feature} value must be a single line") if decoded.match?(/[\r\n]/)
|
|
52
|
+
fail_at(token.location, "#{feature} value must not contain control characters") if
|
|
53
|
+
decoded.match?(/[[:cntrl:]]/)
|
|
54
|
+
|
|
55
|
+
decoded
|
|
56
|
+
rescue RuntimeError => e
|
|
57
|
+
fail_at(token.location, "invalid #{feature} value: #{e.message}")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ibex
|
|
4
|
+
module Frontend
|
|
5
|
+
# Parameter-list and parameterized-reference builders for the generated frontend.
|
|
6
|
+
module GeneratedParserParameters
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
# @rbs (Token opening, Array[Token] parameters) -> [Token, Array[String]]
|
|
10
|
+
def build_rule_parameters(opening, parameters)
|
|
11
|
+
# @type self: GeneratedParserBase
|
|
12
|
+
extended_only!(opening.location, "parameterized rules")
|
|
13
|
+
[opening, parameters.map { |parameter| token_string(parameter) }]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @rbs (Token? inline_marker, Token lhs, [Token, Array[String]]? parameter_clause,
|
|
17
|
+
# Array[AST::Alternative] alternatives) -> AST::Rule
|
|
18
|
+
def build_rule(inline_marker, lhs, parameter_clause, alternatives)
|
|
19
|
+
# @type self: GeneratedParserBase
|
|
20
|
+
extended_only!(inline_marker.location, "inline rules") if inline_marker
|
|
21
|
+
parameters = [] #: Array[String]
|
|
22
|
+
if parameter_clause
|
|
23
|
+
opening, parameters = parameter_clause
|
|
24
|
+
require_adjacency!(lhs, opening, "parameter list must immediately follow rule name")
|
|
25
|
+
end
|
|
26
|
+
AST::Rule.new(
|
|
27
|
+
lhs: token_string(lhs), parameters: parameters, alternatives: alternatives, loc: lhs.location,
|
|
28
|
+
inline: !!inline_marker
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @rbs (Token callee, Token opening, Array[AST::item] arguments,
|
|
33
|
+
# [Token, Token]? named_reference, Array[Token] suffixes) -> AST::item
|
|
34
|
+
def build_parameterized_reference(callee, opening, arguments, named_reference, suffixes)
|
|
35
|
+
# @type self: GeneratedParserBase
|
|
36
|
+
extended_only!(opening.location, "parameterized rules")
|
|
37
|
+
require_adjacency!(callee, opening, "parameter list must immediately follow rule name")
|
|
38
|
+
item = AST::ParameterizedReference.new(
|
|
39
|
+
name: token_string(callee), arguments: arguments, named_reference: named_reference_value(named_reference),
|
|
40
|
+
loc: callee.location
|
|
41
|
+
)
|
|
42
|
+
apply_suffixes(item, suffixes)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @rbs (Token left, Token right, String message) -> void
|
|
46
|
+
def require_adjacency!(left, right, message)
|
|
47
|
+
# @type self: GeneratedParserBase
|
|
48
|
+
left_span = left.span
|
|
49
|
+
right_span = right.span
|
|
50
|
+
adjacent = if left_span && right_span
|
|
51
|
+
left_span.end_byte == right_span.start_byte
|
|
52
|
+
else
|
|
53
|
+
left.location.line == right.location.line &&
|
|
54
|
+
left.location.column + token_string(left).length == right.location.column
|
|
55
|
+
end
|
|
56
|
+
fail_at(right.location, message) unless adjacent
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Internal frontend surface needed by the ordinary grammar-to-Ruby pipeline.
|
|
4
|
+
# Public `require "ibex/frontend"` continues to load formatting, diagnostics,
|
|
5
|
+
# the DSL, and every other frontend facility.
|
|
6
|
+
require_relative "../error"
|
|
7
|
+
require_relative "../tables"
|
|
8
|
+
require "ibex/runtime"
|
|
9
|
+
require_relative "source_span"
|
|
10
|
+
require_relative "source_cursor"
|
|
11
|
+
require_relative "source_document"
|
|
12
|
+
require_relative "diagnostic"
|
|
13
|
+
require_relative "action_scanner"
|
|
14
|
+
require_relative "lexer"
|
|
15
|
+
require_relative "lexer_recovery"
|
|
16
|
+
require_relative "ast"
|
|
17
|
+
require_relative "rule_documentation"
|
|
18
|
+
require_relative "token_adapter/declaration_document_state"
|
|
19
|
+
require_relative "token_adapter/declaration_state"
|
|
20
|
+
require_relative "token_adapter/delimiter_tracker"
|
|
21
|
+
require_relative "token_adapter/rule_state"
|
|
22
|
+
require_relative "token_adapter"
|
|
23
|
+
require_relative "generated_parser_base"
|
|
24
|
+
require_relative "generated_parser"
|
|
25
|
+
require_relative "parser"
|
|
26
|
+
require_relative "resolution"
|
|
27
|
+
require_relative "source_loader"
|
|
28
|
+
require_relative "resolver"
|
|
29
|
+
|
|
30
|
+
module Ibex
|
|
31
|
+
module Frontend
|
|
32
|
+
end
|
|
33
|
+
end
|