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
@@ -1,34 +1,53 @@
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
+ require_relative "parser_configuration_support"
7
+
3
8
  module Ibex
4
9
  module Frontend
5
10
  # Semantic support and token delivery for the generated grammar parser.
11
+ # rubocop:disable Metrics/ClassLength -- generated grammar semantics share one parser support surface.
6
12
  class GeneratedParserBase < Runtime::Parser
13
+ include GeneratedParserMetadata
14
+ include GeneratedParserIncludes
15
+ include GeneratedParserParameters
16
+ include ParserConfigurationSupport
17
+
18
+ attr_reader :diagnostic_token #: Token?
19
+
7
20
  # @rbs @adapter: TokenAdapter
8
21
  # @rbs @mode: Symbol
9
22
 
10
23
  # @rbs (Array[Token] tokens, ?mode: Symbol) -> void
11
- def initialize(tokens, mode: :racc)
12
- raise ArgumentError, "mode must be :racc or :extended" unless %i[racc extended].include?(mode)
24
+ def initialize(tokens, mode: :default)
25
+ raise ArgumentError, "mode must be :default or :extended" unless %i[default extended].include?(mode)
13
26
 
14
27
  super()
15
- @adapter = TokenAdapter.new(tokens)
28
+ @adapter = TokenAdapter.new(tokens, extended: mode == :extended)
16
29
  @mode = mode
17
30
  end
18
31
 
19
- # @rbs () -> AST::Root
32
+ # @rbs () -> (AST::Root | AST::Fragment)
20
33
  def parse
21
- do_parse
34
+ do_parse #: AST::Root | AST::Fragment
22
35
  end
23
36
 
24
37
  # @rbs () -> ([external_token, Token] | false)
25
38
  def next_token
26
- @adapter.next_token
39
+ delivered = @adapter.next_token
40
+ @diagnostic_token = delivered ? delivered.fetch(1) : @adapter.eof_token
41
+ delivered
42
+ rescue Ibex::Error
43
+ @diagnostic_token = @adapter.last_token || @adapter.eof_token
44
+ raise
27
45
  end
28
46
 
29
- # @rbs (Integer? _token_id, Token? value, Array[untyped] _value_stack) -> bot
47
+ # @rbs (Integer? _token_id, Token? value, Array[Object?] _value_stack) -> bot
30
48
  def on_error(_token_id, value, _value_stack)
31
49
  token = value || @adapter.eof_token
50
+ @diagnostic_token = token
32
51
  raise_contextual_error(token)
33
52
 
34
53
  received = token&.value || token&.type || :eof
@@ -69,7 +88,7 @@ module Ibex
69
88
  def expected_description(token)
70
89
  expectation = @adapter.expectation(token)
71
90
  return expectation if expectation
72
- return ")" if @adapter.open_delimiter_kind == :separated
91
+ return ")" if %i[separated parameter].include?(@adapter.open_delimiter_kind)
73
92
 
74
93
  structural_expectation(token)
75
94
  end
@@ -87,13 +106,33 @@ module Ibex
87
106
  # @rbs (Token class_token, Array[String] class_parts, Array[String]? superclass,
88
107
  # Array[AST::declaration] declarations, Array[AST::Rule] rules, AST::user_code user_code) -> AST::Root
89
108
  def build_root(class_token, class_parts, superclass, declarations, rules, user_code)
109
+ validate_root_parser_configuration(declarations)
90
110
  AST::Root.new(class_name: class_parts.join("::"), superclass: superclass&.join("::"),
91
- declarations: declarations, rules: rules, user_code: user_code, loc: class_token.location)
111
+ declarations: declarations, rules: rules, user_code: user_code, loc: class_token.location,
112
+ extended: @mode == :extended || @adapter.extended_pragma? || @adapter.cst_pragma?,
113
+ cst: @adapter.cst_pragma?,
114
+ extended_loc: @adapter.extended_pragma_location || @adapter.cst_pragma_location)
92
115
  end
93
116
 
94
- # @rbs (Token keyword, Array[String] names) -> AST::Tokens
95
- def build_tokens(keyword, names)
96
- AST::Tokens.new(names: names, loc: keyword.location)
117
+ # @rbs (Token keyword, Array[[String, String?]] entries) -> AST::Tokens
118
+ def build_tokens(keyword, entries)
119
+ aliases = entries.filter_map { |name, value| [name, value] if value }.to_h
120
+ AST::Tokens.new(names: entries.map(&:first), aliases: aliases.empty? ? nil : aliases, loc: keyword.location)
121
+ end
122
+
123
+ # @rbs (Token token) -> [String, nil]
124
+ def build_token_entry(token)
125
+ [token_string(token), nil]
126
+ end
127
+
128
+ # @rbs (Token name, Token value) -> [String, String]
129
+ def build_token_alias(name, value)
130
+ extended_only!(name.location, "token aliases")
131
+ unless name.location.line == value.location.line
132
+ fail_at(name.location, "token alias must be written on one line")
133
+ end
134
+
135
+ [token_string(name), decode_metadata_value(value, "token alias")]
97
136
  end
98
137
 
99
138
  # @rbs (Token keyword, Symbol direction, Array[AST::PrecedenceLevel] levels) -> AST::Precedence
@@ -104,6 +143,7 @@ module Ibex
104
143
  # @rbs (Token association, Array[String] symbols) -> AST::PrecedenceLevel
105
144
  def build_precedence_level(association, symbols)
106
145
  fail_at(association.location, "expected at least one precedence symbol") if symbols.empty?
146
+ extended_only!(association.location, "%precedence") if token_string(association) == "precedence"
107
147
 
108
148
  AST::PrecedenceLevel.new(associativity: token_string(association).to_sym, symbols: symbols,
109
149
  loc: association.location)
@@ -119,9 +159,83 @@ module Ibex
119
159
  AST::Expect.new(conflicts: token_integer(integer), loc: keyword.location)
120
160
  end
121
161
 
122
- # @rbs (Token keyword, String name) -> AST::Start
123
- def build_start(keyword, name)
124
- AST::Start.new(name: name, loc: keyword.location)
162
+ # @rbs (Token keyword, Token integer) -> AST::ExpectRR
163
+ def build_expect_rr(keyword, integer)
164
+ extended_only!(keyword.location, "expect-rr declarations")
165
+ AST::ExpectRR.new(conflicts: token_integer(integer), loc: keyword.location)
166
+ end
167
+
168
+ # @rbs (Token keyword, Token name, Token? type) -> AST::Parameter
169
+ def build_parameter(keyword, name, type)
170
+ extended_only!(keyword.location, "%param")
171
+ if type && (keyword.location.line != name.location.line || name.location.line != type.location.line)
172
+ fail_at(keyword.location, "%param declaration must be written on one line")
173
+ end
174
+
175
+ semantic_type = type && decode_metadata_value(type, "%param")
176
+ AST::Parameter.new(name: token_string(name), semantic_type: semantic_type, loc: keyword.location)
177
+ end
178
+
179
+ # @rbs (Token keyword, Token symbol, Token action) -> AST::Printer
180
+ def build_printer(keyword, symbol, action)
181
+ extended_only!(keyword.location, "%printer")
182
+ AST::Printer.new(name: token_string(symbol), code: token_string(action), loc: keyword.location)
183
+ end
184
+
185
+ # @rbs (Token keyword, Array[String] names) -> AST::Start
186
+ def build_start(keyword, names)
187
+ fail_at(keyword.location, "start declaration requires at least one symbol") if names.empty?
188
+ extended_only!(keyword.location, "multiple start symbols") if names.length > 1
189
+ AST::Start.new(names: names, loc: keyword.location)
190
+ end
191
+
192
+ # @rbs (Token keyword, Token kind, Array[String] sync_tokens) -> AST::Recovery
193
+ def build_recovery(keyword, kind, sync_tokens)
194
+ extended_only!(keyword.location, "%recover")
195
+ fail_at(kind.location, "expected sync, got #{kind.value}") unless token_string(kind) == "sync"
196
+ fail_at(keyword.location, "%recover sync requires at least one token") if sync_tokens.empty?
197
+ AST::Recovery.new(sync_tokens: sync_tokens, loc: keyword.location)
198
+ end
199
+
200
+ # @rbs (Token keyword, Array[String] names) -> AST::OnErrorReduce
201
+ def build_on_error_reduce(keyword, names)
202
+ extended_only!(keyword.location, "%on_error_reduce")
203
+ fail_at(keyword.location, "%on_error_reduce requires at least one nonterminal") if names.empty?
204
+ AST::OnErrorReduce.new(names: names, loc: keyword.location)
205
+ end
206
+
207
+ # @rbs (Token keyword, Token expectation, Token source) -> AST::GrammarTest
208
+ def build_grammar_test(keyword, expectation, source)
209
+ extended_only!(keyword.location, "%test")
210
+ expected = token_string(expectation)
211
+ fail_at(expectation.location, "expected accept or reject, got #{expected}") unless
212
+ %w[accept reject].include?(expected)
213
+ literal = token_string(source)
214
+ fail_at(source.location, "%test source must use a double-quoted string") unless literal.start_with?('"')
215
+
216
+ AST::GrammarTest.new(expectation: expected.to_sym, source: literal.undump, loc: keyword.location)
217
+ rescue RuntimeError => e
218
+ fail_at(source.location, "invalid %test source: #{e.message}")
219
+ end
220
+
221
+ # @rbs (Token keyword, Array[AST::lexer_entry] entries) -> AST::Lexer
222
+ def build_lexer(keyword, entries)
223
+ extended_only!(keyword.location, "lexer declarations")
224
+ AST::Lexer.new(definitions: entries, loc: keyword.location)
225
+ end
226
+
227
+ # @rbs (Symbol kind, Token? name, Token pattern, Token? action, Token marker) -> AST::LexerRule
228
+ def build_lexer_rule(kind, name, pattern, action, marker)
229
+ fail_at(marker.location, "on lexer rules require an action") if kind == :on && !action
230
+ AST::LexerRule.new(
231
+ kind: kind, token: name && token_string(name), pattern: token_string(pattern),
232
+ pattern_kind: pattern.type, action: action && token_string(action), loc: marker.location
233
+ )
234
+ end
235
+
236
+ # @rbs (Token marker, Token name, Array[AST::lexer_entry] entries) -> AST::LexerState
237
+ def build_lexer_state(marker, name, entries)
238
+ AST::LexerState.new(name: token_string(name), definitions: entries, loc: marker.location)
125
239
  end
126
240
 
127
241
  # @rbs (Token keyword, Array[AST::Conversion] pairs) -> AST::Convert
@@ -146,13 +260,8 @@ module Ibex
146
260
  fail_at(name_token.location, "invalid conversion expression: #{e.message}")
147
261
  end
148
262
 
149
- # @rbs (Token lhs, Array[AST::Alternative] alternatives) -> AST::Rule
150
- def build_rule(lhs, alternatives)
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)
263
+ # @rbs (Array[AST::item] items, Token? precedence, AST::NodeAnnotation? node_annotation) -> AST::Alternative
264
+ def build_alternative(items, precedence, node_annotation)
156
265
  last_token = @adapter.last_token
157
266
  location = item_start_location(items.first) || precedence&.location || last_token&.location
158
267
  raise Ibex::Error, "missing alternative location" unless location
@@ -163,8 +272,24 @@ module Ibex
163
272
  items.pop
164
273
  action = last_item
165
274
  end
166
- AST::Alternative.new(items: items, action: action,
167
- precedence: precedence && token_string(precedence), loc: location)
275
+ AST::Alternative.new(
276
+ items: items, action: action, precedence: precedence && token_string(precedence),
277
+ node_annotation: node_annotation, loc: location
278
+ )
279
+ end
280
+
281
+ # @rbs (Token marker, Token name, Array[Token] fields) -> AST::NodeAnnotation
282
+ def build_node_annotation(marker, name, fields)
283
+ extended_only!(marker.location, "@node")
284
+ AST::NodeAnnotation.new(
285
+ name: token_string(name), fields: fields.map { |field| token_string(field) }, loc: marker.location
286
+ )
287
+ end
288
+
289
+ # @rbs (Token token) -> AST::Empty
290
+ def build_empty(token)
291
+ extended_only!(token.location, "%empty")
292
+ AST::Empty.new(loc: token.location)
168
293
  end
169
294
 
170
295
  # @rbs (AST::item? item) -> Location?
@@ -180,16 +305,21 @@ module Ibex
180
305
 
181
306
  # @rbs (Token token, [Token, Token]? named_reference, Array[Token] suffixes) -> AST::item
182
307
  def build_symbol_reference(token, named_reference, suffixes)
183
- if named_reference
184
- colon, name = named_reference
185
- extended_only!(colon.location, "named references")
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)
308
+ item = AST::SymbolReference.new(
309
+ name: token_string(token), named_reference: named_reference_value(named_reference), loc: token.location
310
+ )
190
311
  apply_suffixes(item, suffixes)
191
312
  end
192
313
 
314
+ # @rbs ([Token, Token]? named_reference) -> String?
315
+ def named_reference_value(named_reference)
316
+ return unless named_reference
317
+
318
+ colon, name = named_reference
319
+ extended_only!(colon.location, "named references")
320
+ token_string(name)
321
+ end
322
+
193
323
  # @rbs (Token token) -> AST::InlineAction
194
324
  def build_action(token)
195
325
  AST::InlineAction.new(code: token_string(token), loc: token.location)
@@ -228,6 +358,13 @@ module Ibex
228
358
  blocks
229
359
  end
230
360
 
361
+ # @rbs (Token token, AST::user_code blocks) -> AST::user_code
362
+ def prepend_user_code(token, blocks)
363
+ result = append_user_code(empty_user_code, token)
364
+ blocks.each { |name, chunks| result[name].concat(chunks) }
365
+ result
366
+ end
367
+
231
368
  # @rbs () -> AST::user_code
232
369
  def empty_user_code
233
370
  Hash.new { |hash, key| hash[key] = [] } #: AST::user_code
@@ -235,7 +372,7 @@ module Ibex
235
372
 
236
373
  # @rbs (Location location, String feature) -> void
237
374
  def extended_only!(location, feature)
238
- return if @mode == :extended || @adapter.extended_pragma?
375
+ return if @mode == :extended || @adapter.extended_pragma? || @adapter.cst_pragma?
239
376
 
240
377
  fail_at(location, "#{feature} require extended mode")
241
378
  end
@@ -269,5 +406,6 @@ module Ibex
269
406
  fail_at(token.location, "expected user-code token")
270
407
  end
271
408
  end
409
+ # rubocop:enable Metrics/ClassLength
272
410
  end
273
411
  end
@@ -0,0 +1,51 @@
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
+ AST::ROOT_ONLY_DECLARATION_NAMES.find { |node_class, _name| declaration.is_a?(node_class) }&.last
48
+ end
49
+ end
50
+ end
51
+ 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/parser"
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