ibex 0.1.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.
Files changed (603) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +89 -123
  3. data/docs/architecture.md +477 -31
  4. data/docs/bison-import.md +103 -0
  5. data/docs/comparison-policy.md +127 -0
  6. data/docs/configuration-model.md +59 -0
  7. data/docs/configuration-report.md +28 -0
  8. data/docs/conflict-explanation-reviews/v1/records/README.md +28 -0
  9. data/docs/conflict-explanation-study.md +62 -0
  10. data/docs/construction-profiling.md +157 -0
  11. data/docs/cst-migration.md +106 -0
  12. data/docs/cst.md +237 -0
  13. data/docs/decisions/0000-template.md +24 -0
  14. data/docs/decisions/0001-separate-ir-pipeline.md +34 -0
  15. data/docs/decisions/0002-opaque-user-code-boundary.md +32 -0
  16. data/docs/decisions/0003-self-hosted-grammar-frontend.md +32 -0
  17. data/docs/decisions/0004-shared-semantic-and-lossless-source-model.md +33 -0
  18. data/docs/decisions/0005-contained-grammar-composition.md +34 -0
  19. data/docs/decisions/0006-bounded-structural-grammar-lowering.md +32 -0
  20. data/docs/decisions/0007-shared-parser-construction-pipeline.md +33 -0
  21. data/docs/decisions/0008-versioned-runtime-package-boundary.md +36 -0
  22. data/docs/decisions/0009-isolated-parser-sessions.md +34 -0
  23. data/docs/decisions/0010-committed-runtime-observation.md +34 -0
  24. data/docs/decisions/0011-versioned-semantic-action-boundary.md +37 -0
  25. data/docs/decisions/0012-bounded-nonexecuting-analysis.md +37 -0
  26. data/docs/decisions/0013-transactional-generation-publication.md +37 -0
  27. data/docs/decisions/0014-versioned-generated-lexer.md +35 -0
  28. data/docs/decisions/0015-worker-isolated-browser-analysis.md +32 -0
  29. data/docs/decisions/0016-red-green-concrete-syntax.md +34 -0
  30. data/docs/decisions/0017-persistent-syntax-artifacts.md +35 -0
  31. data/docs/decisions/0018-conservative-incremental-syntax-reuse.md +38 -0
  32. data/docs/decisions/0019-runtime-syntax-session-boundary.md +51 -0
  33. data/docs/decisions/0020-grammar-ir-parser-contract.md +65 -0
  34. data/docs/decisions/0021-data-only-parser-table-sidecar.md +50 -0
  35. data/docs/decisions/0022-manifest-bound-verification-report.md +77 -0
  36. data/docs/decisions/0023-syntax-only-repair-results.md +48 -0
  37. data/docs/decisions/0024-direct-ielr-construction.md +42 -0
  38. data/docs/decisions/README.md +74 -0
  39. data/docs/declarative-configuration.md +262 -0
  40. data/docs/development.md +306 -0
  41. data/docs/direct-ielr-decision.md +120 -0
  42. data/docs/direct-multi-entry-decision.md +82 -0
  43. data/docs/editor-setup.md +26 -0
  44. data/docs/error-ux-review-rubric-v1.md +117 -0
  45. data/docs/error-ux-reviews/v1/records/README.md +22 -0
  46. data/docs/error-ux-round2-review-status-v1.json +27 -0
  47. data/docs/error-ux-round2-reviews/v1/records/README.md +30 -0
  48. data/docs/error-ux-round2-v1.json +1581 -0
  49. data/docs/error-ux-round2.md +111 -0
  50. data/docs/error-ux.md +114 -0
  51. data/docs/getting-started.md +80 -0
  52. data/docs/grammar-reference.md +629 -18
  53. data/docs/ielr-design.md +43 -0
  54. data/docs/ielr.md +92 -0
  55. data/docs/ja/bison-import.md +51 -0
  56. data/docs/ja/stable-api.md +53 -0
  57. data/docs/lexer-construction-profile.md +109 -0
  58. data/docs/lexer-migration.md +56 -0
  59. data/docs/maturity.md +128 -0
  60. data/docs/project-site-strategy.md +54 -0
  61. data/docs/racc-migration-evidence.md +45 -0
  62. data/docs/racc-migration.md +45 -6
  63. data/docs/release-readiness.md +221 -0
  64. data/docs/repair-semantics.md +123 -0
  65. data/docs/runtime-abi-evolution.md +307 -0
  66. data/docs/stability.md +234 -0
  67. data/docs/status.md +43 -0
  68. data/docs/syntax-sessions.md +183 -0
  69. data/docs/table-artifact.md +125 -0
  70. data/docs/test-interactions.md +219 -0
  71. data/docs/verification-report.md +137 -0
  72. data/docs/verifier-trust-boundary.md +199 -0
  73. data/docs/workloads.md +132 -0
  74. data/examples/README.md +60 -0
  75. data/examples/calculator.y +44 -0
  76. data/examples/csv.y +32 -0
  77. data/examples/ini.y +70 -0
  78. data/examples/json.y +48 -0
  79. data/examples/tiny_language.y +75 -0
  80. data/lib/ibex/analysis/digraph.rb +128 -0
  81. data/lib/ibex/analysis/sets.rb +5 -4
  82. data/lib/ibex/analysis.rb +1 -0
  83. data/lib/ibex/artifact_set.rb +63 -0
  84. data/lib/ibex/bison_import/importer.rb +516 -0
  85. data/lib/ibex/bison_import/tokenizer.rb +260 -0
  86. data/lib/ibex/bison_import.rb +200 -0
  87. data/lib/ibex/bounded_subprocess.rb +171 -0
  88. data/lib/ibex/cli/ambiguity.rb +75 -0
  89. data/lib/ibex/cli/analysis.rb +134 -0
  90. data/lib/ibex/cli/bison_import.rb +121 -0
  91. data/lib/ibex/cli/config.rb +128 -0
  92. data/lib/ibex/cli/counterexample_options.rb +6 -2
  93. data/lib/ibex/cli/coverage.rb +173 -0
  94. data/lib/ibex/cli/debug.rb +106 -0
  95. data/lib/ibex/cli/diagnostics.rb +136 -0
  96. data/lib/ibex/cli/documentation.rb +70 -0
  97. data/lib/ibex/cli/equiv.rb +169 -0
  98. data/lib/ibex/cli/error_messages.rb +184 -0
  99. data/lib/ibex/cli/explain.rb +85 -0
  100. data/lib/ibex/cli/fix.rb +203 -0
  101. data/lib/ibex/cli/formatting.rb +387 -0
  102. data/lib/ibex/cli/fuzz.rb +200 -0
  103. data/lib/ibex/cli/fuzz_regressions.rb +145 -0
  104. data/lib/ibex/cli/generation_artifacts.rb +189 -0
  105. data/lib/ibex/cli/generation_error_messages.rb +39 -0
  106. data/lib/ibex/cli/grammar_tests.rb +140 -0
  107. data/lib/ibex/cli/ir_tools.rb +128 -0
  108. data/lib/ibex/cli/lsp.rb +33 -0
  109. data/lib/ibex/cli/outputs.rb +133 -23
  110. data/lib/ibex/cli/racc_migration.rb +87 -0
  111. data/lib/ibex/cli/reduce.rb +202 -0
  112. data/lib/ibex/cli/reduce_reporting.rb +71 -0
  113. data/lib/ibex/cli/samples.rb +118 -0
  114. data/lib/ibex/cli/verify.rb +116 -0
  115. data/lib/ibex/cli/watch.rb +104 -0
  116. data/lib/ibex/cli.rb +825 -55
  117. data/lib/ibex/codegen/action_locations.rb +103 -0
  118. data/lib/ibex/codegen/action_method_source.rb +209 -0
  119. data/lib/ibex/codegen/action_source.rb +119 -0
  120. data/lib/ibex/codegen/ambiguity.rb +174 -0
  121. data/lib/ibex/codegen/cst_metadata.rb +171 -0
  122. data/lib/ibex/codegen/documentation.rb +170 -0
  123. data/lib/ibex/codegen/explain.rb +380 -0
  124. data/lib/ibex/codegen/generated_action_abi.rb +293 -0
  125. data/lib/ibex/codegen/html.rb +94 -10
  126. data/lib/ibex/codegen/mermaid.rb +43 -0
  127. data/lib/ibex/codegen/railroad.rb +197 -0
  128. data/lib/ibex/codegen/railroad_documentation.rb +59 -0
  129. data/lib/ibex/codegen/rbs.rb +331 -2
  130. data/lib/ibex/codegen/report.rb +67 -15
  131. data/lib/ibex/codegen/ruby.rb +305 -66
  132. data/lib/ibex/codegen/ruby_actions.rb +146 -0
  133. data/lib/ibex/codegen/ruby_ast.rb +121 -0
  134. data/lib/ibex/codegen/ruby_error_messages.rb +28 -0
  135. data/lib/ibex/codegen/ruby_lexer.rb +83 -0
  136. data/lib/ibex/codegen/ruby_syntax.rb +96 -0
  137. data/lib/ibex/codegen/ruby_table_metadata.rb +57 -0
  138. data/lib/ibex/codegen/ruby_value_printers.rb +56 -0
  139. data/lib/ibex/codegen/symbol_labels.rb +1 -1
  140. data/lib/ibex/configuration/analysis_grammar.rb +35 -0
  141. data/lib/ibex/configuration/explanation.rb +421 -0
  142. data/lib/ibex/configuration/inspector.rb +232 -0
  143. data/lib/ibex/configuration.rb +580 -0
  144. data/lib/ibex/coverage/collector.rb +198 -0
  145. data/lib/ibex/coverage/event_stream.rb +103 -0
  146. data/lib/ibex/coverage/report.rb +267 -0
  147. data/lib/ibex/coverage/runtime_event_validator.rb +169 -0
  148. data/lib/ibex/coverage.rb +13 -0
  149. data/lib/ibex/delta_reducer.rb +99 -0
  150. data/lib/ibex/diff.rb +140 -0
  151. data/lib/ibex/equiv/machine.rb +135 -0
  152. data/lib/ibex/equiv.rb +373 -0
  153. data/lib/ibex/error_messages/parser.rb +159 -0
  154. data/lib/ibex/error_messages/parser_v2.rb +198 -0
  155. data/lib/ibex/error_messages/renderer.rb +65 -0
  156. data/lib/ibex/error_messages/sentence_search.rb +196 -0
  157. data/lib/ibex/error_messages/update.rb +169 -0
  158. data/lib/ibex/error_messages.rb +165 -0
  159. data/lib/ibex/fix.rb +557 -0
  160. data/lib/ibex/frontend/ast.rb +166 -7
  161. data/lib/ibex/frontend/bootstrap_parser.rb +40 -4
  162. data/lib/ibex/frontend/diagnostic.rb +81 -0
  163. data/lib/ibex/frontend/diagnostic_recovery.rb +268 -0
  164. data/lib/ibex/frontend/dsl.rb +66 -7
  165. data/lib/ibex/frontend/formatter.rb +453 -0
  166. data/lib/ibex/frontend/generated_parser.rb +644 -190
  167. data/lib/ibex/frontend/generated_parser_base.rb +170 -32
  168. data/lib/ibex/frontend/generated_parser_includes.rb +51 -0
  169. data/lib/ibex/frontend/generated_parser_metadata.rb +61 -0
  170. data/lib/ibex/frontend/generated_parser_parameters.rb +60 -0
  171. data/lib/ibex/frontend/generation.rb +33 -0
  172. data/lib/ibex/frontend/lexer.rb +162 -10
  173. data/lib/ibex/frontend/lexer_recovery.rb +84 -0
  174. data/lib/ibex/frontend/parser/declarations.rb +262 -11
  175. data/lib/ibex/frontend/parser/parameters.rb +82 -0
  176. data/lib/ibex/frontend/parser/rules.rb +43 -6
  177. data/lib/ibex/frontend/parser.rb +182 -4
  178. data/lib/ibex/frontend/parser_configuration_support.rb +56 -0
  179. data/lib/ibex/frontend/regenerator.rb +27 -1
  180. data/lib/ibex/frontend/resolution.rb +70 -0
  181. data/lib/ibex/frontend/resolver.rb +217 -0
  182. data/lib/ibex/frontend/rule_documentation.rb +104 -0
  183. data/lib/ibex/frontend/source_cursor.rb +133 -9
  184. data/lib/ibex/frontend/source_document.rb +229 -0
  185. data/lib/ibex/frontend/source_loader.rb +150 -0
  186. data/lib/ibex/frontend/source_span.rb +89 -0
  187. data/lib/ibex/frontend/token_adapter/declaration_document_state.rb +47 -0
  188. data/lib/ibex/frontend/token_adapter/declaration_lexer_state.rb +83 -0
  189. data/lib/ibex/frontend/token_adapter/declaration_state.rb +244 -22
  190. data/lib/ibex/frontend/token_adapter/delimiter_tracker.rb +8 -2
  191. data/lib/ibex/frontend/token_adapter/rule_state.rb +60 -2
  192. data/lib/ibex/frontend/token_adapter.rb +18 -3
  193. data/lib/ibex/frontend.rb +14 -2
  194. data/lib/ibex/fuzz.rb +219 -0
  195. data/lib/ibex/generation_input.rb +57 -0
  196. data/lib/ibex/generation_manifest.rb +211 -0
  197. data/lib/ibex/generation_transaction.rb +261 -0
  198. data/lib/ibex/generation_transaction_recovery.rb +109 -0
  199. data/lib/ibex/generation_transaction_validation.rb +196 -0
  200. data/lib/ibex/grammar_tests.rb +206 -0
  201. data/lib/ibex/ir/automaton_ir.rb +86 -11
  202. data/lib/ibex/ir/grammar_ir.rb +170 -26
  203. data/lib/ibex/ir/lexer_ir.rb +76 -0
  204. data/lib/ibex/ir/parser_contract.rb +135 -0
  205. data/lib/ibex/ir/serialize.rb +268 -50
  206. data/lib/ibex/ir/validator/automaton.rb +375 -0
  207. data/lib/ibex/ir/validator/base.rb +147 -0
  208. data/lib/ibex/ir/validator/grammar.rb +634 -0
  209. data/lib/ibex/ir/validator/lexer.rb +113 -0
  210. data/lib/ibex/ir/validator.rb +63 -0
  211. data/lib/ibex/ir.rb +71 -5
  212. data/lib/ibex/lalr/build_metrics.rb +71 -0
  213. data/lib/ibex/lalr/builder.rb +514 -52
  214. data/lib/ibex/lalr/conflict.rb +1 -0
  215. data/lib/ibex/lalr/conflict_search.rb +26 -9
  216. data/lib/ibex/lalr/counterexample.rb +38 -18
  217. data/lib/ibex/lalr/direct_lookaheads.rb +289 -0
  218. data/lib/ibex/lalr/goto_follows.rb +229 -0
  219. data/lib/ibex/lalr/ielr/annotator.rb +214 -0
  220. data/lib/ibex/lalr/ielr/bits.rb +28 -0
  221. data/lib/ibex/lalr/ielr/inadequacy.rb +47 -0
  222. data/lib/ibex/lalr/ielr/item_lookaheads.rb +78 -0
  223. data/lib/ibex/lalr/ielr/pipeline.rb +75 -0
  224. data/lib/ibex/lalr/ielr/split_stability.rb +78 -0
  225. data/lib/ibex/lalr/ielr/split_state.rb +20 -0
  226. data/lib/ibex/lalr/ielr/state_splitter.rb +258 -0
  227. data/lib/ibex/lalr/ielr_partition.rb +166 -0
  228. data/lib/ibex/lalr/inadequacy_report.rb +50 -0
  229. data/lib/ibex/lalr/lookahead_propagation.rb +111 -0
  230. data/lib/ibex/lalr/lr0_collection.rb +121 -0
  231. data/lib/ibex/lalr/on_error_reductions.rb +74 -0
  232. data/lib/ibex/lalr/unreachable_states.rb +80 -0
  233. data/lib/ibex/lalr.rb +59 -1
  234. data/lib/ibex/location.rb +129 -0
  235. data/lib/ibex/lsp/document_handlers.rb +68 -0
  236. data/lib/ibex/lsp/document_store.rb +264 -0
  237. data/lib/ibex/lsp/document_store_diagnostics.rb +44 -0
  238. data/lib/ibex/lsp/document_store_validation.rb +61 -0
  239. data/lib/ibex/lsp/initialization_handlers.rb +80 -0
  240. data/lib/ibex/lsp/navigation_handlers.rb +70 -0
  241. data/lib/ibex/lsp/parser_configuration_assistance.rb +149 -0
  242. data/lib/ibex/lsp/position_codec.rb +113 -0
  243. data/lib/ibex/lsp/protocol_error.rb +33 -0
  244. data/lib/ibex/lsp/request_handlers.rb +46 -0
  245. data/lib/ibex/lsp/request_support.rb +94 -0
  246. data/lib/ibex/lsp/server.rb +148 -0
  247. data/lib/ibex/lsp/symbol_index.rb +241 -0
  248. data/lib/ibex/lsp/symbol_index_builder.rb +277 -0
  249. data/lib/ibex/lsp/symbol_index_precedence_references.rb +44 -0
  250. data/lib/ibex/lsp/symbol_index_source_queries.rb +61 -0
  251. data/lib/ibex/lsp/symbol_occurrence.rb +23 -0
  252. data/lib/ibex/lsp/transport.rb +128 -0
  253. data/lib/ibex/lsp/workspace.rb +128 -0
  254. data/lib/ibex/lsp/workspace_analyzer.rb +199 -0
  255. data/lib/ibex/lsp.rb +33 -0
  256. data/lib/ibex/messages/en.yml +28 -0
  257. data/lib/ibex/messages/ja.yml +28 -0
  258. data/lib/ibex/messages.rb +68 -0
  259. data/lib/ibex/metrics.rb +175 -0
  260. data/lib/ibex/normalize/declarations.rb +142 -7
  261. data/lib/ibex/normalize/diagnostics.rb +94 -24
  262. data/lib/ibex/normalize/expander.rb +64 -59
  263. data/lib/ibex/normalize/expression.rb +63 -40
  264. data/lib/ibex/normalize/grammar_builder.rb +26 -0
  265. data/lib/ibex/normalize/inline_expansion.rb +465 -0
  266. data/lib/ibex/normalize/inline_validation.rb +174 -0
  267. data/lib/ibex/normalize/lexer.rb +131 -0
  268. data/lib/ibex/normalize/named_references.rb +60 -0
  269. data/lib/ibex/normalize/nodes.rb +46 -0
  270. data/lib/ibex/normalize/parameter_ebnf_lowering.rb +70 -0
  271. data/lib/ibex/normalize/parameter_lowering.rb +143 -0
  272. data/lib/ibex/normalize/parameter_substitution.rb +125 -0
  273. data/lib/ibex/normalize/parameter_validation.rb +140 -0
  274. data/lib/ibex/normalize/parameters.rb +226 -0
  275. data/lib/ibex/normalize/parser_configuration.rb +70 -0
  276. data/lib/ibex/normalize/recovery_declarations.rb +84 -0
  277. data/lib/ibex/normalize.rb +172 -17
  278. data/lib/ibex/racc_migration/checker.rb +122 -0
  279. data/lib/ibex/racc_migration/harness.rb +177 -0
  280. data/lib/ibex/racc_migration/report.rb +97 -0
  281. data/lib/ibex/racc_migration.rb +12 -0
  282. data/lib/ibex/rake_task.rb +116 -0
  283. data/lib/ibex/samples.rb +216 -0
  284. data/lib/ibex/table_artifact/builder.rb +266 -0
  285. data/lib/ibex/table_artifact/cst_projection.rb +70 -0
  286. data/lib/ibex/table_artifact/document.rb +39 -0
  287. data/lib/ibex/table_artifact/executor.rb +187 -0
  288. data/lib/ibex/table_artifact/serializer.rb +57 -0
  289. data/lib/ibex/table_artifact/validator/metadata.rb +179 -0
  290. data/lib/ibex/table_artifact/validator/support.rb +86 -0
  291. data/lib/ibex/table_artifact/validator/tables.rb +238 -0
  292. data/lib/ibex/table_artifact/validator.rb +253 -0
  293. data/lib/ibex/table_artifact.rb +88 -0
  294. data/lib/ibex/table_simulation/result.rb +55 -0
  295. data/lib/ibex/table_simulation/simulator.rb +253 -0
  296. data/lib/ibex/table_simulation/step.rb +62 -0
  297. data/lib/ibex/table_simulation/text.rb +31 -0
  298. data/lib/ibex/table_simulation.rb +13 -0
  299. data/lib/ibex/tables.rb +22 -69
  300. data/lib/ibex/verifiable_generation_bundle.rb +86 -0
  301. data/lib/ibex/verification_report/builder.rb +159 -0
  302. data/lib/ibex/verification_report/canonical_ir.rb +123 -0
  303. data/lib/ibex/verification_report/logical_path.rb +68 -0
  304. data/lib/ibex/verification_report/validator.rb +329 -0
  305. data/lib/ibex/verification_report.rb +69 -0
  306. data/lib/ibex/verify/action_correspondence.rb +138 -0
  307. data/lib/ibex/verify/language_witness.rb +295 -0
  308. data/lib/ibex/verify/reference_collection.rb +190 -0
  309. data/lib/ibex/verify/result.rb +73 -0
  310. data/lib/ibex/verify/verifier.rb +598 -0
  311. data/lib/ibex/verify.rb +15 -0
  312. data/lib/ibex/version.rb +1 -1
  313. data/lib/ibex/watch/runner.rb +181 -0
  314. data/lib/ibex/watch/source_snapshot.rb +98 -0
  315. data/lib/ibex/watch.rb +11 -0
  316. data/lib/ibex.rb +35 -1
  317. data/schema/automaton-ir-definitions.schema.json +401 -0
  318. data/schema/automaton-ir.schema.json +65 -0
  319. data/schema/benchmark-v1.schema.json +212 -0
  320. data/schema/benchmark-v2.schema.json +61 -0
  321. data/schema/bison-import-v1.schema.json +106 -0
  322. data/schema/conflict-explanation-review-v1.schema.json +196 -0
  323. data/schema/conflict-explanation-study-v1.schema.json +528 -0
  324. data/schema/construction-profile-v1.schema.json +779 -0
  325. data/schema/cst-v1.json +170 -0
  326. data/schema/diff-v1.schema.json +41 -0
  327. data/schema/direct-ielr-decision-v1.schema.json +200 -0
  328. data/schema/equiv-v1.schema.json +64 -0
  329. data/schema/error-ux-review-v1.schema.json +609 -0
  330. data/schema/error-ux-round2-review-v1.schema.json +191 -0
  331. data/schema/error-ux-round2-v1.schema.json +519 -0
  332. data/schema/error-ux-v1.schema.json +258 -0
  333. data/schema/explain-v1.schema.json +495 -0
  334. data/schema/fix-v1.schema.json +64 -0
  335. data/schema/fix-v2.schema.json +66 -0
  336. data/schema/fix-v3.schema.json +101 -0
  337. data/schema/frontend-diagnostics-v1.schema.json +154 -0
  338. data/schema/fuzz-regression-v1.schema.json +79 -0
  339. data/schema/fuzz-v1.schema.json +114 -0
  340. data/schema/generation-manifest-v1.schema.json +115 -0
  341. data/schema/grammar-ir-extensions.schema.json +734 -0
  342. data/schema/grammar-ir-foundation.schema.json +426 -0
  343. data/schema/grammar-ir.schema.json +271 -0
  344. data/schema/ielr-benchmark-v1.schema.json +85 -0
  345. data/schema/lexer-ir-v1.schema.json +215 -0
  346. data/schema/lexer-profile-v1.schema.json +491 -0
  347. data/schema/metrics-v1.schema.json +60 -0
  348. data/schema/migration-check-v1.schema.json +60 -0
  349. data/schema/performance-comparison-v1.schema.json +395 -0
  350. data/schema/public-performance-comparison-v1.schema.json +506 -0
  351. data/schema/public-performance-profile-v1.schema.json +360 -0
  352. data/schema/reduce-v1.schema.json +22 -0
  353. data/schema/reduce-v2.schema.json +63 -0
  354. data/schema/runtime-coverage-v1.schema.json +86 -0
  355. data/schema/runtime-event-v1.schema.json +308 -0
  356. data/schema/table-artifact-v1.schema.json +377 -0
  357. data/schema/table-simulation-v1.schema.json +70 -0
  358. data/schema/verification-report-v1.schema.json +222 -0
  359. data/schema/verify-v1.schema.json +42 -0
  360. data/sig/ibex/analysis/digraph.rbs +19 -0
  361. data/sig/ibex/artifact_set.rbs +37 -0
  362. data/sig/ibex/bison_import/importer.rbs +140 -0
  363. data/sig/ibex/bison_import/tokenizer.rbs +91 -0
  364. data/sig/ibex/bison_import.rbs +95 -0
  365. data/sig/ibex/bounded_subprocess.rbs +76 -0
  366. data/sig/ibex/cli/ambiguity.rbs +28 -0
  367. data/sig/ibex/cli/analysis.rbs +43 -0
  368. data/sig/ibex/cli/bison_import.rbs +32 -0
  369. data/sig/ibex/cli/config.rbs +35 -0
  370. data/sig/ibex/cli/counterexample_options.rbs +2 -0
  371. data/sig/ibex/cli/coverage.rbs +53 -0
  372. data/sig/ibex/cli/debug.rbs +28 -0
  373. data/sig/ibex/cli/diagnostics.rbs +51 -0
  374. data/sig/ibex/cli/documentation.rbs +29 -0
  375. data/sig/ibex/cli/equiv.rbs +49 -0
  376. data/sig/ibex/cli/error_messages.rbs +63 -0
  377. data/sig/ibex/cli/explain.rbs +31 -0
  378. data/sig/ibex/cli/fix.rbs +53 -0
  379. data/sig/ibex/cli/formatting.rbs +107 -0
  380. data/sig/ibex/cli/fuzz.rbs +47 -0
  381. data/sig/ibex/cli/fuzz_regressions.rbs +40 -0
  382. data/sig/ibex/cli/generation_artifacts.rbs +69 -0
  383. data/sig/ibex/cli/generation_error_messages.rbs +19 -0
  384. data/sig/ibex/cli/grammar_tests.rbs +48 -0
  385. data/sig/ibex/cli/ir_tools.rbs +39 -0
  386. data/sig/ibex/cli/lsp.rbs +14 -0
  387. data/sig/ibex/cli/outputs.rbs +26 -3
  388. data/sig/ibex/cli/racc_migration.rbs +30 -0
  389. data/sig/ibex/cli/reduce.rbs +60 -0
  390. data/sig/ibex/cli/reduce_reporting.rbs +27 -0
  391. data/sig/ibex/cli/samples.rbs +38 -0
  392. data/sig/ibex/cli/verify.rbs +28 -0
  393. data/sig/ibex/cli/watch.rbs +43 -0
  394. data/sig/ibex/cli.rbs +182 -9
  395. data/sig/ibex/codegen/action_locations.rbs +45 -0
  396. data/sig/ibex/codegen/action_method_source.rbs +65 -0
  397. data/sig/ibex/codegen/action_source.rbs +50 -0
  398. data/sig/ibex/codegen/ambiguity.rbs +60 -0
  399. data/sig/ibex/codegen/cst_metadata.rbs +59 -0
  400. data/sig/ibex/codegen/documentation.rbs +50 -0
  401. data/sig/ibex/codegen/explain.rbs +105 -0
  402. data/sig/ibex/codegen/generated_action_abi.rbs +105 -0
  403. data/sig/ibex/codegen/html.rbs +18 -2
  404. data/sig/ibex/codegen/mermaid.rbs +16 -0
  405. data/sig/ibex/codegen/railroad.rbs +82 -0
  406. data/sig/ibex/codegen/railroad_documentation.rbs +31 -0
  407. data/sig/ibex/codegen/rbs.rbs +86 -4
  408. data/sig/ibex/codegen/report.rbs +16 -8
  409. data/sig/ibex/codegen/ruby.rbs +105 -28
  410. data/sig/ibex/codegen/ruby_actions.rbs +54 -0
  411. data/sig/ibex/codegen/ruby_ast.rbs +34 -0
  412. data/sig/ibex/codegen/ruby_error_messages.rbs +16 -0
  413. data/sig/ibex/codegen/ruby_lexer.rbs +25 -0
  414. data/sig/ibex/codegen/ruby_syntax.rbs +27 -0
  415. data/sig/ibex/codegen/ruby_table_metadata.rbs +26 -0
  416. data/sig/ibex/codegen/ruby_value_printers.rbs +28 -0
  417. data/sig/ibex/configuration/analysis_grammar.rbs +13 -0
  418. data/sig/ibex/configuration/explanation.rbs +195 -0
  419. data/sig/ibex/configuration/inspector.rbs +53 -0
  420. data/sig/ibex/configuration.rbs +242 -0
  421. data/sig/ibex/coverage/collector.rbs +78 -0
  422. data/sig/ibex/coverage/event_stream.rbs +44 -0
  423. data/sig/ibex/coverage/report.rbs +102 -0
  424. data/sig/ibex/coverage/runtime_event_validator.rbs +70 -0
  425. data/sig/ibex/coverage.rbs +7 -0
  426. data/sig/ibex/delta_reducer.rbs +38 -0
  427. data/sig/ibex/diff.rbs +47 -0
  428. data/sig/ibex/equiv/machine.rbs +54 -0
  429. data/sig/ibex/equiv.rbs +129 -0
  430. data/sig/ibex/error_messages/parser.rbs +58 -0
  431. data/sig/ibex/error_messages/parser_v2.rbs +67 -0
  432. data/sig/ibex/error_messages/renderer.rbs +23 -0
  433. data/sig/ibex/error_messages/sentence_search.rbs +80 -0
  434. data/sig/ibex/error_messages/update.rbs +43 -0
  435. data/sig/ibex/error_messages.rbs +85 -0
  436. data/sig/ibex/fix.rbs +138 -0
  437. data/sig/ibex/frontend/ast.rbs +237 -22
  438. data/sig/ibex/frontend/bootstrap_parser.rbs +13 -0
  439. data/sig/ibex/frontend/diagnostic.rbs +53 -0
  440. data/sig/ibex/frontend/diagnostic_recovery.rbs +98 -0
  441. data/sig/ibex/frontend/dsl.rbs +33 -4
  442. data/sig/ibex/frontend/formatter.rbs +143 -0
  443. data/sig/ibex/frontend/generated_parser.rbs +228 -68
  444. data/sig/ibex/frontend/generated_parser_base.rbs +65 -12
  445. data/sig/ibex/frontend/generated_parser_includes.rbs +23 -0
  446. data/sig/ibex/frontend/generated_parser_metadata.rbs +23 -0
  447. data/sig/ibex/frontend/generated_parser_parameters.rbs +24 -0
  448. data/sig/ibex/frontend/generation.rbs +6 -0
  449. data/sig/ibex/frontend/lexer.rbs +49 -2
  450. data/sig/ibex/frontend/lexer_recovery.rbs +25 -0
  451. data/sig/ibex/frontend/parser/declarations.rbs +57 -0
  452. data/sig/ibex/frontend/parser/parameters.rbs +28 -0
  453. data/sig/ibex/frontend/parser/rules.rbs +3 -0
  454. data/sig/ibex/frontend/parser.rbs +66 -0
  455. data/sig/ibex/frontend/parser_configuration_support.rbs +27 -0
  456. data/sig/ibex/frontend/regenerator.rbs +11 -0
  457. data/sig/ibex/frontend/resolution.rbs +34 -0
  458. data/sig/ibex/frontend/resolver.rbs +91 -0
  459. data/sig/ibex/frontend/rule_documentation.rbs +42 -0
  460. data/sig/ibex/frontend/source_cursor.rbs +38 -5
  461. data/sig/ibex/frontend/source_document.rbs +119 -0
  462. data/sig/ibex/frontend/source_loader.rbs +66 -0
  463. data/sig/ibex/frontend/source_span.rbs +56 -0
  464. data/sig/ibex/frontend/token_adapter/declaration_document_state.rbs +21 -0
  465. data/sig/ibex/frontend/token_adapter/declaration_lexer_state.rbs +27 -0
  466. data/sig/ibex/frontend/token_adapter/declaration_state.rbs +83 -3
  467. data/sig/ibex/frontend/token_adapter/rule_state.rbs +20 -0
  468. data/sig/ibex/frontend/token_adapter.rbs +11 -2
  469. data/sig/ibex/frontend.rbs +1 -1
  470. data/sig/ibex/fuzz.rbs +71 -0
  471. data/sig/ibex/generation_input.rbs +37 -0
  472. data/sig/ibex/generation_manifest.rbs +70 -0
  473. data/sig/ibex/generation_transaction.rbs +82 -0
  474. data/sig/ibex/generation_transaction_recovery.rbs +36 -0
  475. data/sig/ibex/generation_transaction_validation.rbs +65 -0
  476. data/sig/ibex/grammar_tests.rbs +93 -0
  477. data/sig/ibex/ir/automaton_ir.rbs +35 -10
  478. data/sig/ibex/ir/grammar_ir.rbs +96 -22
  479. data/sig/ibex/ir/lexer_ir.rbs +57 -0
  480. data/sig/ibex/ir/parser_contract.rbs +69 -0
  481. data/sig/ibex/ir/serialize.rbs +75 -23
  482. data/sig/ibex/ir/validator/automaton.rbs +112 -0
  483. data/sig/ibex/ir/validator/base.rbs +69 -0
  484. data/sig/ibex/ir/validator/grammar.rbs +195 -0
  485. data/sig/ibex/ir/validator/lexer.rbs +37 -0
  486. data/sig/ibex/ir/validator.rbs +16 -0
  487. data/sig/ibex/ir.rbs +45 -5
  488. data/sig/ibex/lalr/build_metrics.rbs +60 -0
  489. data/sig/ibex/lalr/builder.rbs +150 -19
  490. data/sig/ibex/lalr/conflict_search.rbs +12 -5
  491. data/sig/ibex/lalr/counterexample.rbs +20 -14
  492. data/sig/ibex/lalr/direct_lookaheads.rbs +93 -0
  493. data/sig/ibex/lalr/goto_follows.rbs +89 -0
  494. data/sig/ibex/lalr/ielr/annotator.rbs +67 -0
  495. data/sig/ibex/lalr/ielr/bits.rbs +14 -0
  496. data/sig/ibex/lalr/ielr/inadequacy.rbs +24 -0
  497. data/sig/ibex/lalr/ielr/item_lookaheads.rbs +35 -0
  498. data/sig/ibex/lalr/ielr/pipeline.rbs +17 -0
  499. data/sig/ibex/lalr/ielr/split_stability.rbs +27 -0
  500. data/sig/ibex/lalr/ielr/split_state.rbs +14 -0
  501. data/sig/ibex/lalr/ielr/state_splitter.rbs +76 -0
  502. data/sig/ibex/lalr/ielr_partition.rbs +71 -0
  503. data/sig/ibex/lalr/inadequacy_report.rbs +21 -0
  504. data/sig/ibex/lalr/lookahead_propagation.rbs +38 -0
  505. data/sig/ibex/lalr/lr0_collection.rbs +50 -0
  506. data/sig/ibex/lalr/on_error_reductions.rbs +22 -0
  507. data/sig/ibex/lalr/unreachable_states.rbs +25 -0
  508. data/sig/ibex/lalr.rbs +17 -1
  509. data/sig/ibex/location.rbs +67 -0
  510. data/sig/ibex/lsp/document_handlers.rbs +24 -0
  511. data/sig/ibex/lsp/document_store.rbs +94 -0
  512. data/sig/ibex/lsp/document_store_diagnostics.rbs +20 -0
  513. data/sig/ibex/lsp/document_store_validation.rbs +26 -0
  514. data/sig/ibex/lsp/initialization_handlers.rbs +30 -0
  515. data/sig/ibex/lsp/navigation_handlers.rbs +33 -0
  516. data/sig/ibex/lsp/parser_configuration_assistance.rbs +49 -0
  517. data/sig/ibex/lsp/position_codec.rbs +44 -0
  518. data/sig/ibex/lsp/protocol_error.rbs +32 -0
  519. data/sig/ibex/lsp/request_handlers.rbs +26 -0
  520. data/sig/ibex/lsp/request_support.rbs +40 -0
  521. data/sig/ibex/lsp/server.rbs +55 -0
  522. data/sig/ibex/lsp/symbol_index.rbs +77 -0
  523. data/sig/ibex/lsp/symbol_index_builder.rbs +88 -0
  524. data/sig/ibex/lsp/symbol_index_precedence_references.rbs +18 -0
  525. data/sig/ibex/lsp/symbol_index_source_queries.rbs +26 -0
  526. data/sig/ibex/lsp/symbol_occurrence.rbs +31 -0
  527. data/sig/ibex/lsp/transport.rbs +47 -0
  528. data/sig/ibex/lsp/workspace.rbs +42 -0
  529. data/sig/ibex/lsp/workspace_analyzer.rbs +69 -0
  530. data/sig/ibex/lsp.rbs +7 -0
  531. data/sig/ibex/messages.rbs +26 -0
  532. data/sig/ibex/metrics.rbs +50 -0
  533. data/sig/ibex/normalize/declarations.rbs +31 -0
  534. data/sig/ibex/normalize/diagnostics.rbs +13 -4
  535. data/sig/ibex/normalize/expander.rbs +22 -16
  536. data/sig/ibex/normalize/expression.rbs +11 -9
  537. data/sig/ibex/normalize/grammar_builder.rbs +11 -0
  538. data/sig/ibex/normalize/inline_expansion.rbs +129 -0
  539. data/sig/ibex/normalize/inline_validation.rbs +40 -0
  540. data/sig/ibex/normalize/lexer.rbs +37 -0
  541. data/sig/ibex/normalize/named_references.rbs +20 -0
  542. data/sig/ibex/normalize/nodes.rbs +14 -0
  543. data/sig/ibex/normalize/parameter_ebnf_lowering.rbs +33 -0
  544. data/sig/ibex/normalize/parameter_lowering.rbs +35 -0
  545. data/sig/ibex/normalize/parameter_substitution.rbs +42 -0
  546. data/sig/ibex/normalize/parameter_validation.rbs +44 -0
  547. data/sig/ibex/normalize/parameters.rbs +51 -0
  548. data/sig/ibex/normalize/parser_configuration.rbs +23 -0
  549. data/sig/ibex/normalize/recovery_declarations.rbs +24 -0
  550. data/sig/ibex/normalize.rbs +129 -18
  551. data/sig/ibex/racc_migration/checker.rbs +36 -0
  552. data/sig/ibex/racc_migration/harness.rbs +16 -0
  553. data/sig/ibex/racc_migration/report.rbs +55 -0
  554. data/sig/ibex/racc_migration.rbs +8 -0
  555. data/sig/ibex/rake_task.rbs +51 -0
  556. data/sig/ibex/samples.rbs +60 -0
  557. data/sig/ibex/table_artifact/builder.rbs +93 -0
  558. data/sig/ibex/table_artifact/cst_projection.rbs +20 -0
  559. data/sig/ibex/table_artifact/document.rbs +27 -0
  560. data/sig/ibex/table_artifact/executor.rbs +66 -0
  561. data/sig/ibex/table_artifact/serializer.rbs +25 -0
  562. data/sig/ibex/table_artifact/validator/metadata.rbs +52 -0
  563. data/sig/ibex/table_artifact/validator/support.rbs +46 -0
  564. data/sig/ibex/table_artifact/validator/tables.rbs +63 -0
  565. data/sig/ibex/table_artifact/validator.rbs +66 -0
  566. data/sig/ibex/table_artifact.rbs +32 -0
  567. data/sig/ibex/table_simulation/result.rbs +36 -0
  568. data/sig/ibex/table_simulation/simulator.rbs +98 -0
  569. data/sig/ibex/table_simulation/step.rbs +42 -0
  570. data/sig/ibex/table_simulation/text.rbs +14 -0
  571. data/sig/ibex/table_simulation.rbs +7 -0
  572. data/sig/ibex/tables.rbs +10 -35
  573. data/sig/ibex/verifiable_generation_bundle.rbs +24 -0
  574. data/sig/ibex/verification_report/builder.rbs +53 -0
  575. data/sig/ibex/verification_report/canonical_ir.rbs +41 -0
  576. data/sig/ibex/verification_report/logical_path.rbs +34 -0
  577. data/sig/ibex/verification_report/validator.rbs +114 -0
  578. data/sig/ibex/verification_report.rbs +44 -0
  579. data/sig/ibex/verify/action_correspondence.rbs +50 -0
  580. data/sig/ibex/verify/language_witness.rbs +112 -0
  581. data/sig/ibex/verify/reference_collection.rbs +63 -0
  582. data/sig/ibex/verify/result.rbs +52 -0
  583. data/sig/ibex/verify/verifier.rbs +170 -0
  584. data/sig/ibex/verify.rbs +6 -0
  585. data/sig/ibex/watch/runner.rbs +58 -0
  586. data/sig/ibex/watch/source_snapshot.rbs +46 -0
  587. data/sig/ibex/watch.rbs +7 -0
  588. data/sig/ibex.rbs +2 -0
  589. metadata +524 -19
  590. data/.rubocop.yml +0 -43
  591. data/CHANGELOG.md +0 -30
  592. data/Rakefile +0 -25
  593. data/Steepfile +0 -10
  594. data/docs/compat-notes.md +0 -37
  595. data/docs/lexer-coverage.md +0 -14
  596. data/docs/phase10-extensions.md +0 -27
  597. data/gemfiles/Gemfile +0 -7
  598. data/gemfiles/Gemfile.lock +0 -98
  599. data/lib/ibex/frontend/grammar.y +0 -156
  600. data/lib/ibex/runtime/parser.rb +0 -360
  601. data/lib/ibex/runtime.rb +0 -8
  602. data/sig/ibex/runtime/parser.rbs +0 -167
  603. data/sig/ibex/runtime.rbs +0 -6
@@ -11,27 +11,162 @@ module Ibex
11
11
  @declared_tokens = {} #: Hash[String, IR::location]
12
12
  @precedence = {} #: Hash[String, IR::precedence]
13
13
  @precedence_locations = {} #: Hash[String, IR::location]
14
+ @display_names = {} #: Hash[String, String]
15
+ @display_name_locations = {} #: Hash[String, IR::location]
16
+ @semantic_types = {} #: Hash[String, String]
17
+ @semantic_type_locations = {} #: Hash[String, IR::location]
14
18
  @options = { result_var: true, omit_action_call: true }
19
+ @options[:cst] = true if @ast.cst
15
20
  @expected_conflicts = 0
21
+ @expected_rr_conflicts = nil
16
22
  @conversions = {} #: Hash[String, String]
23
+ @parser_parameters = [] #: Array[IR::parser_parameter]
24
+ @value_printers = {} #: Hash[String, IR::value_printer]
25
+ @recovery_sync_tokens = [] #: Array[String]
26
+ @recovery_sync_location = nil #: Frontend::Location?
27
+ @on_error_reduce_groups = [] #: Array[Array[String]]
28
+ @on_error_reduce_locations = {} #: Hash[String, Frontend::Location]
29
+ @grammar_tests = [] #: Array[IR::grammar_test]
30
+ @lexer_declaration = nil #: Frontend::AST::Lexer?
31
+ @parser_configuration = nil #: Frontend::AST::ParserConfiguration?
32
+ @node_shapes = {} #: Hash[String, Array[String]]
17
33
  @ast.declarations.each { |declaration| read_declaration(declaration) }
18
34
  end
19
35
 
20
36
  # @rbs (Frontend::AST::declaration declaration) -> void
21
- def read_declaration(declaration)
37
+ def read_declaration(declaration) # rubocop:disable Metrics/CyclomaticComplexity
22
38
  # @type self: Normalizer
23
39
  case declaration
24
- when Frontend::AST::Tokens then declaration.names.each { |name| @declared_tokens[name] = declaration.loc.to_h }
40
+ when Frontend::AST::Tokens then read_tokens(declaration)
25
41
  when Frontend::AST::Precedence then read_precedence(declaration)
26
- when Frontend::AST::Options then declaration.names.each { |name| read_option(name, declaration.loc) }
42
+ when Frontend::AST::Options then read_options(declaration)
27
43
  when Frontend::AST::Expect then @expected_conflicts = declaration.conflicts
28
- when Frontend::AST::Start
29
- @explicit_start = declaration.name
30
- @start_location = declaration.loc
31
- when Frontend::AST::Convert then declaration.pairs.each { |pair| @conversions[pair.name] = pair.expression }
44
+ when Frontend::AST::ExpectRR then @expected_rr_conflicts = declaration.conflicts
45
+ when Frontend::AST::Start, Frontend::AST::Recovery, Frontend::AST::OnErrorReduce, Frontend::AST::GrammarTest
46
+ read_parser_control_declaration(declaration)
47
+ when Frontend::AST::Lexer
48
+ fail_at(declaration.loc, "duplicate lexer declaration") if @lexer_declaration
49
+ @lexer_declaration = declaration
50
+ when Frontend::AST::ParserConfiguration then read_parser_configuration(declaration)
51
+ when Frontend::AST::Convert then read_conversions(declaration)
52
+ when Frontend::AST::DisplayName, Frontend::AST::SemanticType, Frontend::AST::Parameter, Frontend::AST::Printer
53
+ read_extended_declaration(declaration)
54
+ when Frontend::AST::Include then fail_at(declaration.loc, "includes must be resolved before normalization")
32
55
  end
33
56
  end
34
57
 
58
+ # @rbs (Frontend::AST::Start declaration) -> void
59
+ def read_start_declaration(declaration)
60
+ # @type self: Normalizer
61
+ fail_at(declaration.loc, "duplicate start declaration") if @explicit_starts
62
+ if declaration.names.length > 1 && @mode != :extended
63
+ fail_at(declaration.loc, "multiple start symbols require extended mode")
64
+ end
65
+ fail_at(declaration.loc, "start declaration requires at least one symbol") if declaration.names.empty?
66
+ unless declaration.names.uniq.length == declaration.names.length
67
+ fail_at(declaration.loc, "start symbols must be unique")
68
+ end
69
+
70
+ @explicit_starts = declaration.names
71
+ @start_location = declaration.loc
72
+ end
73
+
74
+ # @rbs (Frontend::AST::symbol_metadata | Frontend::AST::Parameter | Frontend::AST::Printer declaration) -> void
75
+ def read_extended_declaration(declaration)
76
+ if declaration.is_a?(Frontend::AST::Parameter)
77
+ read_parser_parameter(declaration)
78
+ elsif declaration.is_a?(Frontend::AST::Printer)
79
+ read_value_printer(declaration)
80
+ else
81
+ read_symbol_metadata_declaration(declaration)
82
+ end
83
+ end
84
+
85
+ # @rbs (Frontend::AST::Printer declaration) -> void
86
+ def read_value_printer(declaration)
87
+ # @type self: Normalizer
88
+ if @value_printers.key?(declaration.name)
89
+ fail_at(declaration.loc, "duplicate %printer declaration for #{declaration.name}")
90
+ end
91
+
92
+ @value_printers[declaration.name] = {
93
+ symbol: declaration.name, code: declaration.code, loc: declaration.loc.to_h
94
+ }
95
+ end
96
+
97
+ # @rbs () -> void
98
+ def validate_value_printers
99
+ @value_printers.each_value do |printer|
100
+ next if @symbols_by_name.key?(printer[:symbol])
101
+
102
+ location = printer[:loc]
103
+ raise Ibex::Error,
104
+ "#{location[:file]}:#{location[:line]}:#{location[:column]}: " \
105
+ "%printer references missing symbol #{printer[:symbol]}"
106
+ end
107
+ end
108
+
109
+ # @rbs (Frontend::AST::Parameter declaration) -> void
110
+ def read_parser_parameter(declaration)
111
+ # @type self: Normalizer
112
+ if @parser_parameters.any? { |parameter| parameter[:name] == declaration.name }
113
+ fail_at(declaration.loc, "duplicate %param declaration for #{declaration.name}")
114
+ end
115
+ unless declaration.name.match?(/\A[a-z_][a-zA-Z0-9_]*\z/)
116
+ fail_at(declaration.loc, "%param name #{declaration.name.inspect} must be a Ruby local identifier")
117
+ end
118
+ if Normalizer::RUBY_KEYWORDS.include?(declaration.name)
119
+ fail_at(declaration.loc, "%param name #{declaration.name.inspect} is a Ruby keyword")
120
+ end
121
+
122
+ @parser_parameters << { name: declaration.name, semantic_type: declaration.semantic_type }
123
+ end
124
+
125
+ # @rbs (Frontend::AST::Tokens declaration) -> void
126
+ def read_tokens(declaration)
127
+ # @type self: Normalizer
128
+ declaration.names.each { |name| @declared_tokens[name] = declaration.loc.to_h }
129
+ (declaration.aliases || {}).each do |name, value|
130
+ fail_at(declaration.loc, "duplicate display declaration for #{name}") if @display_names.key?(name)
131
+
132
+ @display_names[name] = value
133
+ @display_name_locations[name] = declaration.loc.to_h
134
+ end
135
+ end
136
+
137
+ # @rbs (Frontend::AST::Options declaration) -> void
138
+ def read_options(declaration)
139
+ declaration.names.each { |name| read_option(name, declaration.loc) }
140
+ end
141
+
142
+ # @rbs (Frontend::AST::Convert declaration) -> void
143
+ def read_conversions(declaration)
144
+ # @type self: Normalizer
145
+ declaration.pairs.each { |pair| @conversions[pair.name] = pair.expression }
146
+ end
147
+
148
+ # @rbs (Frontend::AST::symbol_metadata declaration) -> void
149
+ def read_symbol_metadata_declaration(declaration)
150
+ # @type self: Normalizer
151
+ if declaration.is_a?(Frontend::AST::DisplayName)
152
+ read_symbol_metadata(declaration, @display_names, @display_name_locations, "display")
153
+ else
154
+ read_symbol_metadata(declaration, @semantic_types, @semantic_type_locations, "type")
155
+ end
156
+ end
157
+
158
+ # @rbs (Frontend::AST::symbol_metadata declaration, Hash[String, String] values,
159
+ # Hash[String, IR::location] locations, String label) -> void
160
+ def read_symbol_metadata(declaration, values, locations, label)
161
+ # @type self: Normalizer
162
+ if values.key?(declaration.name)
163
+ fail_at(declaration.loc, "duplicate #{label} declaration for #{declaration.name}")
164
+ end
165
+
166
+ values[declaration.name] = declaration.value
167
+ locations[declaration.name] = declaration.loc.to_h
168
+ end
169
+
35
170
  # @rbs (Frontend::AST::Precedence declaration) -> void
36
171
  def read_precedence(declaration)
37
172
  # @type self: Normalizer
@@ -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
@@ -10,21 +8,41 @@ module Ibex
10
8
  # @rbs () -> void
11
9
  def validate_grammar
12
10
  # @type self: Normalizer
11
+ validate_symbol_metadata
13
12
  warn_duplicate_productions
14
13
  warn_unreachable_nonterminals
14
+ warn_unreachable_terminals
15
15
  warn_unused_terminals
16
+ warn_unused_precedence
16
17
  warn_empty_language
17
18
  end
18
19
 
20
+ # @rbs () -> void
21
+ def validate_symbol_metadata
22
+ # @type self: Normalizer
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|
27
+ locations.each do |name, location|
28
+ fail_hash(location, "#{label} declaration references undefined symbol #{name}") unless
29
+ symbol(name) || parameter_template?(name) || (label == :type && inline_rule_names.include?(name))
30
+ end
31
+ end
32
+ end
33
+
19
34
  # @rbs () -> void
20
35
  def warn_duplicate_productions
21
36
  # @type self: Normalizer
37
+ productions = @productions #: Array[IR::Production]
38
+ warnings = @warnings #: Array[IR::grammar_warning]
22
39
  seen = {} #: Hash[[Integer, Array[Integer]], Integer]
23
- @productions.each do |production|
40
+ productions.each do |production|
24
41
  signature = [production.lhs, production.rhs] #: [Integer, Array[Integer]]
25
42
  if seen.key?(signature)
26
- @warnings << { type: :duplicate_production, production: production.id, original: seen[signature],
27
- loc: production.origin[:loc] }
43
+ location = production.origin[:loc] #: IR::location?
44
+ warnings << { type: :duplicate_production, production: production.id, original: seen[signature],
45
+ loc: location }
28
46
  else
29
47
  seen[signature] = production.id
30
48
  end
@@ -34,23 +52,27 @@ module Ibex
34
52
  # @rbs () -> void
35
53
  def warn_unreachable_nonterminals
36
54
  # @type self: Normalizer
55
+ symbols = @symbols #: Array[IR::GrammarSymbol]
56
+ warnings = @warnings #: Array[IR::grammar_warning]
37
57
  reachable = reachable_symbol_ids
38
- @symbols.select(&:nonterminal?).each do |grammar_symbol|
39
- next if reachable.include?(grammar_symbol.id) || grammar_symbol.name.start_with?("$")
58
+ symbols.select(&:nonterminal?).each do |grammar_symbol|
59
+ next if reachable.key?(grammar_symbol.id) || grammar_symbol.name.start_with?("$")
40
60
 
41
- @warnings << { type: :unreachable_nonterminal, symbol: grammar_symbol.name, loc: grammar_symbol.location }
61
+ warnings << { type: :unreachable_nonterminal, symbol: grammar_symbol.name, loc: grammar_symbol.location }
42
62
  end
43
63
  end
44
64
 
45
- # @rbs () -> Set[Integer]
65
+ # @rbs () -> Hash[Integer, true]
46
66
  def reachable_symbol_ids
47
67
  # @type self: Normalizer
48
- start = required_symbol(@start_name).id
49
- reachable = Set[start]
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]
50
72
  loop do
51
73
  before = reachable.length
52
- @productions.select { |production| reachable.include?(production.lhs) }.each do |production|
53
- production.rhs.each { |id| reachable << id }
74
+ productions.select { |production| reachable.key?(production.lhs) }.each do |production|
75
+ production.rhs.each { |id| reachable[id] = true }
54
76
  end
55
77
  return reachable if reachable.length == before
56
78
  end
@@ -59,35 +81,83 @@ module Ibex
59
81
  # @rbs () -> void
60
82
  def warn_unused_terminals
61
83
  # @type self: Normalizer
62
- used = @productions.flat_map(&:rhs).to_set
63
- @symbols.select(&:terminal?).each do |grammar_symbol|
64
- next if grammar_symbol.reserved || used.include?(grammar_symbol.id) || @precedence.key?(grammar_symbol.name)
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 }
93
+ end
94
+ end
95
+
96
+ # @rbs () -> void
97
+ def warn_unreachable_terminals
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]
102
+ reachable = reachable_symbol_ids
103
+ used = productions.flat_map(&:rhs).to_h { |id| [id, true] } #: Hash[Integer, true]
104
+ declared_tokens.each_key do |name|
105
+ grammar_symbol = required_symbol(name)
106
+ next unless used.key?(grammar_symbol.id)
107
+ next if reachable.key?(grammar_symbol.id)
65
108
 
66
- @warnings << { type: :unused_terminal, symbol: grammar_symbol.name, loc: grammar_symbol.location }
109
+ warnings << { type: :unreachable_terminal, symbol: name, loc: declared_tokens[name] }
110
+ end
111
+ end
112
+
113
+ # @rbs () -> void
114
+ def warn_unused_precedence
115
+ # @type self: Normalizer
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
125
+ end
126
+ precedence.each_key do |name|
127
+ grammar_symbol = required_symbol(name)
128
+ next if referenced.key?(grammar_symbol.id)
129
+
130
+ warnings << { type: :unused_precedence, symbol: name, loc: precedence_locations[name] }
67
131
  end
68
132
  end
69
133
 
70
134
  # @rbs () -> void
71
135
  def warn_empty_language
72
136
  # @type self: Normalizer
137
+ productions = @productions #: Array[IR::Production]
138
+ start_names = @start_names #: Array[String]
139
+ warnings = @warnings #: Array[IR::grammar_warning]
73
140
  productive = productive_terminal_ids
74
141
  loop do
75
142
  before = productive.length
76
- @productions.each do |production|
77
- productive << production.lhs if production.rhs.all? { |id| productive.include?(id) }
143
+ productions.each do |production|
144
+ productive[production.lhs] = true if production.rhs.all? { |id| productive.key?(id) }
78
145
  end
79
146
  break if productive.length == before
80
147
  end
81
- return if productive.include?(required_symbol(@start_name).id)
148
+ start_names.each do |name|
149
+ next if productive.key?(required_symbol(name).id)
82
150
 
83
- start_symbol = required_symbol(@start_name)
84
- @warnings << { type: :empty_language, symbol: @start_name, loc: start_symbol.location }
151
+ start_symbol = required_symbol(name)
152
+ warnings << { type: :empty_language, symbol: name, loc: start_symbol.location }
153
+ end
85
154
  end
86
155
 
87
- # @rbs () -> Set[Integer]
156
+ # @rbs () -> Hash[Integer, true]
88
157
  def productive_terminal_ids
89
158
  # @type self: Normalizer
90
- @symbols.select { |grammar_symbol| productive_terminal?(grammar_symbol) }.to_set(&:id)
159
+ symbols = @symbols #: Array[IR::GrammarSymbol]
160
+ symbols.select { |grammar_symbol| productive_terminal?(grammar_symbol) }.to_h { |symbol| [symbol.id, true] }
91
161
  end
92
162
 
93
163
  # @rbs (IR::GrammarSymbol grammar_symbol) -> bool
@@ -9,6 +9,9 @@ module Ibex
9
9
  def normalize_user_productions
10
10
  # @type self: Normalizer
11
11
  @ast.rules.each do |rule|
12
+ next if parameterized_rule?(rule)
13
+
14
+ @current_include_chain = @resolution&.include_chain_for(rule) || []
12
15
  rule.alternatives.each { |alternative| normalize_alternative(rule, alternative) }
13
16
  end
14
17
  end
@@ -18,7 +21,8 @@ module Ibex
18
21
  # @type self: Normalizer
19
22
  rhs = [] #: Array[String]
20
23
  named_refs = [] #: Array[IR::named_ref]
21
- alternative.items.each do |item|
24
+ items = normalized_alternative_items(alternative)
25
+ items.each do |item|
22
26
  if item.is_a?(Frontend::AST::InlineAction)
23
27
  rhs << expand_inline_action(item, rhs.length, named_refs)
24
28
  next
@@ -28,14 +32,31 @@ module Ibex
28
32
  add_named_reference(item, named_refs, rhs.length - 1)
29
33
  end
30
34
  action = normalize_action(alternative.action, named_refs)
35
+ node = normalize_node_annotation(alternative, rhs)
31
36
  add_production(rule.lhs, rhs, action, alternative.precedence,
32
- { kind: :user, loc: alternative.loc.to_h })
37
+ { kind: :user, loc: alternative.loc.to_h }, rule.documentation, node)
38
+ end
39
+
40
+ # @rbs (Frontend::AST::Alternative alternative) -> Array[Frontend::AST::item]
41
+ def normalized_alternative_items(alternative)
42
+ # @type self: Normalizer
43
+ explicit = alternative.items.grep(Frontend::AST::Empty)
44
+ if explicit.any?
45
+ fail_at(explicit.first.loc, "%empty must be the only item in an alternative") unless alternative.items.one?
46
+ return []
47
+ end
48
+
49
+ if alternative.items.empty? && (@mode.to_sym == :extended || @ast.extended)
50
+ @warnings << { type: :implicit_empty, loc: alternative.loc.to_h }
51
+ end
52
+ alternative.items
33
53
  end
34
54
 
35
55
  # @rbs (Frontend::AST::item item) -> String
36
56
  def normalize_item(item)
37
57
  # @type self: Normalizer
38
58
  return symbol_for_reference(item).name if item.is_a?(Frontend::AST::SymbolReference)
59
+ return specialize_parameterized_reference(item) if item.is_a?(Frontend::AST::ParameterizedReference)
39
60
  return expand_group(item) if item.is_a?(Frontend::AST::Group)
40
61
  return expand_optional(item) if item.is_a?(Frontend::AST::Optional)
41
62
  return expand_star(item) if item.is_a?(Frontend::AST::Star)
@@ -59,6 +80,12 @@ module Ibex
59
80
  def expand_optional(item)
60
81
  # @type self: Normalizer
61
82
  base = normalize_item(item.item)
83
+ build_optional(item, base)
84
+ end
85
+
86
+ # @rbs (Frontend::AST::Optional item, String base) -> String
87
+ def build_optional(item, base)
88
+ # @type self: Normalizer
62
89
  helper = new_helper("optional", item.loc)
63
90
  add_production(helper, [], synthetic_action("nil", item.loc), nil, synthetic_origin(:optional, item))
64
91
  add_production(helper, [base], synthetic_action("val[0]", item.loc), nil, synthetic_origin(:optional, item))
@@ -69,6 +96,12 @@ module Ibex
69
96
  def expand_star(item)
70
97
  # @type self: Normalizer
71
98
  base = normalize_item(item.item)
99
+ build_star(item, base)
100
+ end
101
+
102
+ # @rbs (Frontend::AST::Star item, String base) -> String
103
+ def build_star(item, base)
104
+ # @type self: Normalizer
72
105
  helper = new_helper("star", item.loc)
73
106
  add_production(helper, [], synthetic_action("[]", item.loc), nil, synthetic_origin(:star, item))
74
107
  add_production(helper, [helper, base], synthetic_action("val[0] + [val[1]]", item.loc), nil,
@@ -80,6 +113,12 @@ module Ibex
80
113
  def expand_plus(item)
81
114
  # @type self: Normalizer
82
115
  base = normalize_item(item.item)
116
+ build_plus(item, base)
117
+ end
118
+
119
+ # @rbs (Frontend::AST::Plus item, String base) -> String
120
+ def build_plus(item, base)
121
+ # @type self: Normalizer
83
122
  helper = new_helper("plus", item.loc)
84
123
  add_production(helper, [base], synthetic_action("[val[0]]", item.loc), nil, synthetic_origin(:plus, item))
85
124
  add_production(helper, [helper, base], synthetic_action("val[0] + [val[1]]", item.loc), nil,
@@ -92,6 +131,12 @@ module Ibex
92
131
  # @type self: Normalizer
93
132
  base = normalize_item(item.item)
94
133
  separator = normalize_item(item.separator)
134
+ build_separated_list(item, base, separator)
135
+ end
136
+
137
+ # @rbs (Frontend::AST::SeparatedList item, String base, String separator) -> String
138
+ def build_separated_list(item, base, separator)
139
+ # @type self: Normalizer
95
140
  helper = new_helper("separated_list", item.loc)
96
141
  unless item.nonempty
97
142
  add_production(helper, [], synthetic_action("[]", item.loc), nil, synthetic_origin(:separated_list, item))
@@ -110,12 +155,18 @@ module Ibex
110
155
  helper = new_helper("group", item.loc)
111
156
  item.alternatives.each do |alternative|
112
157
  rhs = alternative.map { |child| normalize_item(child) }
113
- expression = group_value_expression(rhs.length)
114
- add_production(helper, rhs, synthetic_action(expression, item.loc), nil, synthetic_origin(:group, item))
158
+ add_group_production(helper, rhs, item)
115
159
  end
116
160
  helper
117
161
  end
118
162
 
163
+ # @rbs (String helper, Array[String] rhs, Frontend::AST::Group item) -> void
164
+ def add_group_production(helper, rhs, item)
165
+ # @type self: Normalizer
166
+ expression = group_value_expression(rhs.length)
167
+ add_production(helper, rhs, synthetic_action(expression, item.loc), nil, synthetic_origin(:group, item))
168
+ end
169
+
119
170
  # @rbs (Integer length) -> String
120
171
  def group_value_expression(length)
121
172
  # @type self: Normalizer
@@ -125,28 +176,6 @@ module Ibex
125
176
  "val"
126
177
  end
127
178
 
128
- # @rbs (Frontend::AST::Group group) -> void
129
- def reject_group_named_references(group)
130
- # @type self: Normalizer
131
- reference = group.alternatives.flatten.filter_map { |item| named_reference_in(item) }.first
132
- fail_at(reference.loc, "named references inside EBNF groups are not supported") if reference
133
- end
134
-
135
- # @rbs (Frontend::AST::item item) -> Frontend::AST::SymbolReference?
136
- def named_reference_in(item)
137
- # @type self: Normalizer
138
- return item if item.is_a?(Frontend::AST::SymbolReference) && item.named_reference
139
- if item.is_a?(Frontend::AST::Group)
140
- return item.alternatives.flatten.filter_map { |child| named_reference_in(child) }.first
141
- end
142
- if item.is_a?(Frontend::AST::Optional) || item.is_a?(Frontend::AST::Star) ||
143
- item.is_a?(Frontend::AST::Plus) || item.is_a?(Frontend::AST::SeparatedList)
144
- return named_reference_in(item.item)
145
- end
146
-
147
- nil
148
- end
149
-
150
179
  # @rbs (String kind, Frontend::Location location) -> String
151
180
  def new_helper(kind, location)
152
181
  # @type self: Normalizer
@@ -163,7 +192,7 @@ module Ibex
163
192
  IR::Action.new(code: code, location: location.to_h)
164
193
  end
165
194
 
166
- # @rbs (Symbol kind, Frontend::AST::item item) -> Hash[Symbol, untyped]
195
+ # @rbs (Symbol kind, Frontend::AST::item item) -> Hash[Symbol, Object?]
167
196
  def synthetic_origin(kind, item)
168
197
  # @type self: Normalizer
169
198
  { kind: :"#{kind}_expansion", expression: NormalizeExpression.render(item), loc: item.loc.to_h }
@@ -177,42 +206,18 @@ module Ibex
177
206
  IR::Action.new(code: action.code, location: action.loc.to_h, named_refs: named_refs)
178
207
  end
179
208
 
180
- # @rbs (Frontend::AST::item item, Array[IR::named_ref] refs, Integer index) -> void
181
- def add_named_reference(item, refs, index)
182
- # @type self: Normalizer
183
- reference = unwrap_reference(item)
184
- return unless reference
185
-
186
- name = reference.named_reference
187
- return unless name
188
-
189
- fail_at(reference.loc, "reserved named reference #{name}") if Normalizer::RESERVED_NAMES.include?(name)
190
- fail_at(reference.loc, "duplicate named reference #{name}") if refs.any? { |entry| entry[:name] == name }
191
- refs << { name: name, index: index }
192
- end
193
-
194
- # @rbs (Frontend::AST::item item) -> Frontend::AST::SymbolReference?
195
- def unwrap_reference(item)
196
- # @type self: Normalizer
197
- return item if item.is_a?(Frontend::AST::SymbolReference)
198
- if item.is_a?(Frontend::AST::Optional) || item.is_a?(Frontend::AST::Star) ||
199
- item.is_a?(Frontend::AST::Plus) || item.is_a?(Frontend::AST::SeparatedList)
200
- return unwrap_reference(item.item)
201
- end
202
-
203
- nil
204
- end
205
-
206
209
  # @rbs (String lhs_name, Array[String] rhs_names, IR::Action? action, String? precedence_name,
207
- # Hash[Symbol, untyped] origin) -> void
208
- def add_production(lhs_name, rhs_names, action, precedence_name, origin)
210
+ # Hash[Symbol, untyped] origin, ?String? documentation, ?IR::node_annotation? node) -> void
211
+ def add_production(lhs_name, rhs_names, action, precedence_name, origin, documentation = nil, node = nil)
209
212
  # @type self: Normalizer
210
- lhs = symbol(lhs_name) || intern(lhs_name, :nonterminal, location: origin[:loc])
211
- rhs = rhs_names.map { |name| symbol(name)&.id || fail_hash(origin[:loc], "undefined symbol #{name}") }
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}") }
212
216
  precedence = precedence_name && symbol(precedence_name)
213
- fail_hash(origin[:loc], "undefined precedence symbol #{precedence_name}") if precedence_name && !precedence
217
+ fail_hash(location, "undefined precedence symbol #{precedence_name}") if precedence_name && !precedence
214
218
  @productions << IR::Production.new(id: @productions.length, lhs: lhs.id, rhs: rhs, action: action,
215
- precedence_override: precedence&.id, origin: origin)
219
+ precedence_override: precedence&.id, origin: origin,
220
+ documentation: documentation, expansion: resolved_expansion, node: node)
216
221
  end
217
222
  end
218
223
  end