ibex 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +247 -104
  3. data/docs/architecture.md +322 -28
  4. data/docs/cst-migration.md +107 -0
  5. data/docs/cst.md +213 -0
  6. data/docs/development.md +129 -0
  7. data/docs/editor-setup.md +25 -0
  8. data/docs/error-ux.md +60 -0
  9. data/docs/grammar-reference.md +458 -18
  10. data/docs/lexer-migration.md +51 -0
  11. data/docs/racc-migration.md +34 -6
  12. data/docs/release-readiness.md +163 -0
  13. data/docs/stability.md +124 -0
  14. data/examples/README.md +60 -0
  15. data/examples/calculator.y +44 -0
  16. data/examples/csv.y +32 -0
  17. data/examples/ini.y +70 -0
  18. data/examples/json.y +48 -0
  19. data/examples/tiny_language.y +75 -0
  20. data/lib/ibex/analysis/sets.rb +5 -4
  21. data/lib/ibex/artifact_set.rb +63 -0
  22. data/lib/ibex/cli/ambiguity.rb +66 -0
  23. data/lib/ibex/cli/counterexample_options.rb +6 -2
  24. data/lib/ibex/cli/coverage.rb +173 -0
  25. data/lib/ibex/cli/debug.rb +106 -0
  26. data/lib/ibex/cli/diagnostics.rb +116 -0
  27. data/lib/ibex/cli/documentation.rb +67 -0
  28. data/lib/ibex/cli/error_messages.rb +177 -0
  29. data/lib/ibex/cli/explain.rb +76 -0
  30. data/lib/ibex/cli/formatting.rb +386 -0
  31. data/lib/ibex/cli/generation_artifacts.rb +138 -0
  32. data/lib/ibex/cli/generation_error_messages.rb +39 -0
  33. data/lib/ibex/cli/grammar_tests.rb +122 -0
  34. data/lib/ibex/cli/ir_tools.rb +184 -0
  35. data/lib/ibex/cli/lsp.rb +33 -0
  36. data/lib/ibex/cli/outputs.rb +91 -8
  37. data/lib/ibex/cli/racc_migration.rb +87 -0
  38. data/lib/ibex/cli/samples.rb +92 -0
  39. data/lib/ibex/cli/watch.rb +103 -0
  40. data/lib/ibex/cli.rb +506 -37
  41. data/lib/ibex/codegen/action_locations.rb +103 -0
  42. data/lib/ibex/codegen/action_method_source.rb +210 -0
  43. data/lib/ibex/codegen/action_source.rb +118 -0
  44. data/lib/ibex/codegen/ambiguity.rb +173 -0
  45. data/lib/ibex/codegen/cst_metadata.rb +171 -0
  46. data/lib/ibex/codegen/documentation.rb +170 -0
  47. data/lib/ibex/codegen/explain.rb +312 -0
  48. data/lib/ibex/codegen/generated_action_abi.rb +288 -0
  49. data/lib/ibex/codegen/html.rb +94 -10
  50. data/lib/ibex/codegen/mermaid.rb +43 -0
  51. data/lib/ibex/codegen/railroad.rb +197 -0
  52. data/lib/ibex/codegen/railroad_documentation.rb +59 -0
  53. data/lib/ibex/codegen/rbs.rb +323 -2
  54. data/lib/ibex/codegen/report.rb +46 -6
  55. data/lib/ibex/codegen/ruby.rb +334 -59
  56. data/lib/ibex/codegen/ruby_actions.rb +143 -0
  57. data/lib/ibex/codegen/ruby_ast.rb +121 -0
  58. data/lib/ibex/codegen/ruby_error_messages.rb +28 -0
  59. data/lib/ibex/codegen/ruby_lexer.rb +83 -0
  60. data/lib/ibex/codegen/ruby_syntax.rb +90 -0
  61. data/lib/ibex/codegen/ruby_table_metadata.rb +57 -0
  62. data/lib/ibex/codegen/ruby_value_printers.rb +56 -0
  63. data/lib/ibex/codegen/symbol_labels.rb +1 -1
  64. data/lib/ibex/coverage/collector.rb +188 -0
  65. data/lib/ibex/coverage/event_stream.rb +97 -0
  66. data/lib/ibex/coverage/report.rb +259 -0
  67. data/lib/ibex/coverage/runtime_event_validator.rb +160 -0
  68. data/lib/ibex/coverage.rb +13 -0
  69. data/lib/ibex/error_messages/parser.rb +159 -0
  70. data/lib/ibex/error_messages/parser_v2.rb +198 -0
  71. data/lib/ibex/error_messages/renderer.rb +65 -0
  72. data/lib/ibex/error_messages/sentence_search.rb +196 -0
  73. data/lib/ibex/error_messages/update.rb +169 -0
  74. data/lib/ibex/error_messages.rb +165 -0
  75. data/lib/ibex/frontend/ast.rb +145 -6
  76. data/lib/ibex/frontend/bootstrap_parser.rb +47 -4
  77. data/lib/ibex/frontend/diagnostic.rb +81 -0
  78. data/lib/ibex/frontend/diagnostic_recovery.rb +268 -0
  79. data/lib/ibex/frontend/dsl.rb +66 -7
  80. data/lib/ibex/frontend/formatter.rb +407 -0
  81. data/lib/ibex/frontend/generated_parser.rb +614 -190
  82. data/lib/ibex/frontend/generated_parser_base.rb +164 -30
  83. data/lib/ibex/frontend/generated_parser_includes.rb +61 -0
  84. data/lib/ibex/frontend/generated_parser_metadata.rb +61 -0
  85. data/lib/ibex/frontend/generated_parser_parameters.rb +60 -0
  86. data/lib/ibex/frontend/generation.rb +33 -0
  87. data/lib/ibex/frontend/lexer.rb +162 -10
  88. data/lib/ibex/frontend/lexer_recovery.rb +84 -0
  89. data/lib/ibex/frontend/parser/declarations.rb +247 -11
  90. data/lib/ibex/frontend/parser/parameters.rb +82 -0
  91. data/lib/ibex/frontend/parser/rules.rb +43 -6
  92. data/lib/ibex/frontend/parser.rb +182 -4
  93. data/lib/ibex/frontend/regenerator.rb +26 -1
  94. data/lib/ibex/frontend/resolution.rb +69 -0
  95. data/lib/ibex/frontend/resolver.rb +217 -0
  96. data/lib/ibex/frontend/rule_documentation.rb +103 -0
  97. data/lib/ibex/frontend/source_cursor.rb +132 -8
  98. data/lib/ibex/frontend/source_document.rb +229 -0
  99. data/lib/ibex/frontend/source_loader.rb +150 -0
  100. data/lib/ibex/frontend/source_span.rb +81 -0
  101. data/lib/ibex/frontend/token_adapter/declaration_document_state.rb +47 -0
  102. data/lib/ibex/frontend/token_adapter/declaration_lexer_state.rb +83 -0
  103. data/lib/ibex/frontend/token_adapter/declaration_state.rb +216 -26
  104. data/lib/ibex/frontend/token_adapter/delimiter_tracker.rb +8 -2
  105. data/lib/ibex/frontend/token_adapter/rule_state.rb +60 -2
  106. data/lib/ibex/frontend/token_adapter.rb +8 -3
  107. data/lib/ibex/frontend.rb +13 -2
  108. data/lib/ibex/generation_input.rb +57 -0
  109. data/lib/ibex/generation_manifest.rb +200 -0
  110. data/lib/ibex/generation_transaction.rb +261 -0
  111. data/lib/ibex/generation_transaction_recovery.rb +109 -0
  112. data/lib/ibex/generation_transaction_validation.rb +196 -0
  113. data/lib/ibex/grammar_tests.rb +206 -0
  114. data/lib/ibex/ir/automaton_ir.rb +38 -5
  115. data/lib/ibex/ir/grammar_ir.rb +137 -24
  116. data/lib/ibex/ir/lexer_ir.rb +76 -0
  117. data/lib/ibex/ir/migration.rb +120 -0
  118. data/lib/ibex/ir/serialize.rb +110 -19
  119. data/lib/ibex/ir/validator/automaton.rb +345 -0
  120. data/lib/ibex/ir/validator/base.rb +129 -0
  121. data/lib/ibex/ir/validator/grammar.rb +604 -0
  122. data/lib/ibex/ir/validator/lexer.rb +113 -0
  123. data/lib/ibex/ir/validator.rb +62 -0
  124. data/lib/ibex/ir.rb +57 -4
  125. data/lib/ibex/lalr/build_metrics.rb +23 -0
  126. data/lib/ibex/lalr/builder.rb +379 -52
  127. data/lib/ibex/lalr/conflict.rb +1 -0
  128. data/lib/ibex/lalr/conflict_search.rb +11 -5
  129. data/lib/ibex/lalr/counterexample.rb +20 -5
  130. data/lib/ibex/lalr/direct_lookaheads.rb +236 -0
  131. data/lib/ibex/lalr/ielr_partition.rb +152 -0
  132. data/lib/ibex/lalr/on_error_reductions.rb +74 -0
  133. data/lib/ibex/lalr.rb +7 -0
  134. data/lib/ibex/location.rb +129 -0
  135. data/lib/ibex/lsp/document_handlers.rb +66 -0
  136. data/lib/ibex/lsp/document_store.rb +264 -0
  137. data/lib/ibex/lsp/document_store_diagnostics.rb +44 -0
  138. data/lib/ibex/lsp/document_store_validation.rb +61 -0
  139. data/lib/ibex/lsp/initialization_handlers.rb +78 -0
  140. data/lib/ibex/lsp/navigation_handlers.rb +56 -0
  141. data/lib/ibex/lsp/position_codec.rb +109 -0
  142. data/lib/ibex/lsp/protocol_error.rb +33 -0
  143. data/lib/ibex/lsp/request_handlers.rb +45 -0
  144. data/lib/ibex/lsp/request_support.rb +87 -0
  145. data/lib/ibex/lsp/server.rb +146 -0
  146. data/lib/ibex/lsp/symbol_index.rb +241 -0
  147. data/lib/ibex/lsp/symbol_index_builder.rb +267 -0
  148. data/lib/ibex/lsp/symbol_index_precedence_references.rb +44 -0
  149. data/lib/ibex/lsp/symbol_index_source_queries.rb +61 -0
  150. data/lib/ibex/lsp/symbol_occurrence.rb +17 -0
  151. data/lib/ibex/lsp/transport.rb +118 -0
  152. data/lib/ibex/lsp/workspace.rb +127 -0
  153. data/lib/ibex/lsp/workspace_analyzer.rb +199 -0
  154. data/lib/ibex/lsp.rb +32 -0
  155. data/lib/ibex/normalize/declarations.rb +140 -7
  156. data/lib/ibex/normalize/diagnostics.rb +50 -5
  157. data/lib/ibex/normalize/expander.rb +59 -55
  158. data/lib/ibex/normalize/expression.rb +60 -39
  159. data/lib/ibex/normalize/inline_expansion.rb +414 -0
  160. data/lib/ibex/normalize/inline_validation.rb +174 -0
  161. data/lib/ibex/normalize/lexer.rb +131 -0
  162. data/lib/ibex/normalize/named_references.rb +60 -0
  163. data/lib/ibex/normalize/nodes.rb +46 -0
  164. data/lib/ibex/normalize/parameter_ebnf_lowering.rb +69 -0
  165. data/lib/ibex/normalize/parameter_lowering.rb +126 -0
  166. data/lib/ibex/normalize/parameter_substitution.rb +125 -0
  167. data/lib/ibex/normalize/parameter_validation.rb +140 -0
  168. data/lib/ibex/normalize/parameters.rb +199 -0
  169. data/lib/ibex/normalize/recovery_declarations.rb +84 -0
  170. data/lib/ibex/normalize.rb +179 -14
  171. data/lib/ibex/racc_migration/checker.rb +122 -0
  172. data/lib/ibex/racc_migration/harness.rb +177 -0
  173. data/lib/ibex/racc_migration/report.rb +94 -0
  174. data/lib/ibex/racc_migration.rb +12 -0
  175. data/lib/ibex/rake_task.rb +116 -0
  176. data/lib/ibex/samples.rb +186 -0
  177. data/lib/ibex/table_simulation/result.rb +51 -0
  178. data/lib/ibex/table_simulation/simulator.rb +253 -0
  179. data/lib/ibex/table_simulation/step.rb +60 -0
  180. data/lib/ibex/table_simulation/text.rb +31 -0
  181. data/lib/ibex/table_simulation.rb +13 -0
  182. data/lib/ibex/tables.rb +9 -70
  183. data/lib/ibex/version.rb +1 -1
  184. data/lib/ibex/watch/runner.rb +172 -0
  185. data/lib/ibex/watch/source_snapshot.rb +93 -0
  186. data/lib/ibex/watch.rb +11 -0
  187. data/lib/ibex.rb +25 -1
  188. data/schema/automaton-ir-v1.schema.json +401 -0
  189. data/schema/automaton-ir-v2.schema.json +58 -0
  190. data/schema/benchmark-v1.schema.json +212 -0
  191. data/schema/benchmark-v2.schema.json +61 -0
  192. data/schema/cst-v1.json +170 -0
  193. data/schema/error-ux-v1.schema.json +258 -0
  194. data/schema/explain-v1.schema.json +433 -0
  195. data/schema/frontend-diagnostics-v1.schema.json +154 -0
  196. data/schema/generation-manifest-v1.schema.json +115 -0
  197. data/schema/grammar-ir-v1.schema.json +426 -0
  198. data/schema/grammar-ir-v2.schema.json +779 -0
  199. data/schema/lexer-ir-v1.schema.json +215 -0
  200. data/schema/migration-check-v1.schema.json +60 -0
  201. data/schema/performance-comparison-v1.schema.json +395 -0
  202. data/schema/public-performance-comparison-v1.schema.json +506 -0
  203. data/schema/public-performance-profile-v1.schema.json +360 -0
  204. data/schema/runtime-coverage-v1.schema.json +86 -0
  205. data/schema/runtime-event-v1.schema.json +308 -0
  206. data/schema/table-simulation-v1.schema.json +70 -0
  207. data/sig/ibex/artifact_set.rbs +37 -0
  208. data/sig/ibex/cli/ambiguity.rbs +22 -0
  209. data/sig/ibex/cli/counterexample_options.rbs +2 -0
  210. data/sig/ibex/cli/coverage.rbs +53 -0
  211. data/sig/ibex/cli/debug.rbs +28 -0
  212. data/sig/ibex/cli/diagnostics.rbs +38 -0
  213. data/sig/ibex/cli/documentation.rbs +25 -0
  214. data/sig/ibex/cli/error_messages.rbs +57 -0
  215. data/sig/ibex/cli/explain.rbs +25 -0
  216. data/sig/ibex/cli/formatting.rbs +103 -0
  217. data/sig/ibex/cli/generation_artifacts.rbs +50 -0
  218. data/sig/ibex/cli/generation_error_messages.rbs +19 -0
  219. data/sig/ibex/cli/grammar_tests.rbs +36 -0
  220. data/sig/ibex/cli/ir_tools.rbs +51 -0
  221. data/sig/ibex/cli/lsp.rbs +14 -0
  222. data/sig/ibex/cli/outputs.rbs +17 -0
  223. data/sig/ibex/cli/racc_migration.rbs +30 -0
  224. data/sig/ibex/cli/samples.rbs +30 -0
  225. data/sig/ibex/cli/watch.rbs +43 -0
  226. data/sig/ibex/cli.rbs +104 -5
  227. data/sig/ibex/codegen/action_locations.rbs +45 -0
  228. data/sig/ibex/codegen/action_method_source.rbs +65 -0
  229. data/sig/ibex/codegen/action_source.rbs +50 -0
  230. data/sig/ibex/codegen/ambiguity.rbs +60 -0
  231. data/sig/ibex/codegen/cst_metadata.rbs +59 -0
  232. data/sig/ibex/codegen/documentation.rbs +50 -0
  233. data/sig/ibex/codegen/explain.rbs +85 -0
  234. data/sig/ibex/codegen/generated_action_abi.rbs +101 -0
  235. data/sig/ibex/codegen/html.rbs +18 -2
  236. data/sig/ibex/codegen/mermaid.rbs +16 -0
  237. data/sig/ibex/codegen/railroad.rbs +82 -0
  238. data/sig/ibex/codegen/railroad_documentation.rbs +31 -0
  239. data/sig/ibex/codegen/rbs.rbs +84 -4
  240. data/sig/ibex/codegen/report.rbs +8 -0
  241. data/sig/ibex/codegen/ruby.rbs +97 -23
  242. data/sig/ibex/codegen/ruby_actions.rbs +54 -0
  243. data/sig/ibex/codegen/ruby_ast.rbs +34 -0
  244. data/sig/ibex/codegen/ruby_error_messages.rbs +16 -0
  245. data/sig/ibex/codegen/ruby_lexer.rbs +25 -0
  246. data/sig/ibex/codegen/ruby_syntax.rbs +25 -0
  247. data/sig/ibex/codegen/ruby_table_metadata.rbs +26 -0
  248. data/sig/ibex/codegen/ruby_value_printers.rbs +28 -0
  249. data/sig/ibex/coverage/collector.rbs +76 -0
  250. data/sig/ibex/coverage/event_stream.rbs +42 -0
  251. data/sig/ibex/coverage/report.rbs +100 -0
  252. data/sig/ibex/coverage/runtime_event_validator.rbs +68 -0
  253. data/sig/ibex/coverage.rbs +7 -0
  254. data/sig/ibex/error_messages/parser.rbs +58 -0
  255. data/sig/ibex/error_messages/parser_v2.rbs +67 -0
  256. data/sig/ibex/error_messages/renderer.rbs +23 -0
  257. data/sig/ibex/error_messages/sentence_search.rbs +80 -0
  258. data/sig/ibex/error_messages/update.rbs +43 -0
  259. data/sig/ibex/error_messages.rbs +85 -0
  260. data/sig/ibex/frontend/ast.rbs +208 -19
  261. data/sig/ibex/frontend/bootstrap_parser.rbs +11 -0
  262. data/sig/ibex/frontend/diagnostic.rbs +53 -0
  263. data/sig/ibex/frontend/diagnostic_recovery.rbs +98 -0
  264. data/sig/ibex/frontend/dsl.rbs +33 -4
  265. data/sig/ibex/frontend/formatter.rbs +135 -0
  266. data/sig/ibex/frontend/generated_parser.rbs +218 -68
  267. data/sig/ibex/frontend/generated_parser_base.rbs +61 -10
  268. data/sig/ibex/frontend/generated_parser_includes.rbs +23 -0
  269. data/sig/ibex/frontend/generated_parser_metadata.rbs +23 -0
  270. data/sig/ibex/frontend/generated_parser_parameters.rbs +24 -0
  271. data/sig/ibex/frontend/generation.rbs +6 -0
  272. data/sig/ibex/frontend/lexer.rbs +49 -2
  273. data/sig/ibex/frontend/lexer_recovery.rbs +25 -0
  274. data/sig/ibex/frontend/parser/declarations.rbs +54 -0
  275. data/sig/ibex/frontend/parser/parameters.rbs +28 -0
  276. data/sig/ibex/frontend/parser/rules.rbs +3 -0
  277. data/sig/ibex/frontend/parser.rbs +66 -0
  278. data/sig/ibex/frontend/regenerator.rbs +11 -0
  279. data/sig/ibex/frontend/resolution.rbs +33 -0
  280. data/sig/ibex/frontend/resolver.rbs +91 -0
  281. data/sig/ibex/frontend/rule_documentation.rbs +42 -0
  282. data/sig/ibex/frontend/source_cursor.rbs +36 -3
  283. data/sig/ibex/frontend/source_document.rbs +119 -0
  284. data/sig/ibex/frontend/source_loader.rbs +66 -0
  285. data/sig/ibex/frontend/source_span.rbs +53 -0
  286. data/sig/ibex/frontend/token_adapter/declaration_document_state.rbs +21 -0
  287. data/sig/ibex/frontend/token_adapter/declaration_lexer_state.rbs +27 -0
  288. data/sig/ibex/frontend/token_adapter/declaration_state.rbs +73 -5
  289. data/sig/ibex/frontend/token_adapter/rule_state.rbs +20 -0
  290. data/sig/ibex/frontend/token_adapter.rbs +5 -2
  291. data/sig/ibex/frontend.rbs +1 -1
  292. data/sig/ibex/generation_input.rbs +37 -0
  293. data/sig/ibex/generation_manifest.rbs +67 -0
  294. data/sig/ibex/generation_transaction.rbs +82 -0
  295. data/sig/ibex/generation_transaction_recovery.rbs +36 -0
  296. data/sig/ibex/generation_transaction_validation.rbs +65 -0
  297. data/sig/ibex/grammar_tests.rbs +93 -0
  298. data/sig/ibex/ir/automaton_ir.rbs +8 -2
  299. data/sig/ibex/ir/grammar_ir.rbs +75 -15
  300. data/sig/ibex/ir/lexer_ir.rbs +57 -0
  301. data/sig/ibex/ir/migration.rbs +34 -0
  302. data/sig/ibex/ir/serialize.rbs +23 -6
  303. data/sig/ibex/ir/validator/automaton.rbs +109 -0
  304. data/sig/ibex/ir/validator/base.rbs +65 -0
  305. data/sig/ibex/ir/validator/grammar.rbs +184 -0
  306. data/sig/ibex/ir/validator/lexer.rbs +37 -0
  307. data/sig/ibex/ir/validator.rbs +16 -0
  308. data/sig/ibex/ir.rbs +38 -4
  309. data/sig/ibex/lalr/build_metrics.rbs +20 -0
  310. data/sig/ibex/lalr/builder.rbs +95 -15
  311. data/sig/ibex/lalr/conflict_search.rbs +7 -3
  312. data/sig/ibex/lalr/counterexample.rbs +5 -2
  313. data/sig/ibex/lalr/direct_lookaheads.rbs +86 -0
  314. data/sig/ibex/lalr/ielr_partition.rbs +59 -0
  315. data/sig/ibex/lalr/on_error_reductions.rbs +22 -0
  316. data/sig/ibex/lalr.rbs +6 -0
  317. data/sig/ibex/location.rbs +67 -0
  318. data/sig/ibex/lsp/document_handlers.rbs +24 -0
  319. data/sig/ibex/lsp/document_store.rbs +94 -0
  320. data/sig/ibex/lsp/document_store_diagnostics.rbs +20 -0
  321. data/sig/ibex/lsp/document_store_validation.rbs +26 -0
  322. data/sig/ibex/lsp/initialization_handlers.rbs +30 -0
  323. data/sig/ibex/lsp/navigation_handlers.rbs +30 -0
  324. data/sig/ibex/lsp/position_codec.rbs +40 -0
  325. data/sig/ibex/lsp/protocol_error.rbs +32 -0
  326. data/sig/ibex/lsp/request_handlers.rbs +26 -0
  327. data/sig/ibex/lsp/request_support.rbs +40 -0
  328. data/sig/ibex/lsp/server.rbs +55 -0
  329. data/sig/ibex/lsp/symbol_index.rbs +78 -0
  330. data/sig/ibex/lsp/symbol_index_builder.rbs +87 -0
  331. data/sig/ibex/lsp/symbol_index_precedence_references.rbs +18 -0
  332. data/sig/ibex/lsp/symbol_index_source_queries.rbs +26 -0
  333. data/sig/ibex/lsp/symbol_occurrence.rbs +25 -0
  334. data/sig/ibex/lsp/transport.rbs +35 -0
  335. data/sig/ibex/lsp/workspace.rbs +41 -0
  336. data/sig/ibex/lsp/workspace_analyzer.rbs +69 -0
  337. data/sig/ibex/lsp.rbs +7 -0
  338. data/sig/ibex/normalize/declarations.rbs +31 -0
  339. data/sig/ibex/normalize/diagnostics.rbs +9 -0
  340. data/sig/ibex/normalize/expander.rbs +20 -14
  341. data/sig/ibex/normalize/expression.rbs +10 -10
  342. data/sig/ibex/normalize/inline_expansion.rbs +120 -0
  343. data/sig/ibex/normalize/inline_validation.rbs +40 -0
  344. data/sig/ibex/normalize/lexer.rbs +37 -0
  345. data/sig/ibex/normalize/named_references.rbs +20 -0
  346. data/sig/ibex/normalize/nodes.rbs +14 -0
  347. data/sig/ibex/normalize/parameter_ebnf_lowering.rbs +32 -0
  348. data/sig/ibex/normalize/parameter_lowering.rbs +35 -0
  349. data/sig/ibex/normalize/parameter_substitution.rbs +42 -0
  350. data/sig/ibex/normalize/parameter_validation.rbs +44 -0
  351. data/sig/ibex/normalize/parameters.rbs +46 -0
  352. data/sig/ibex/normalize/recovery_declarations.rbs +24 -0
  353. data/sig/ibex/normalize.rbs +123 -18
  354. data/sig/ibex/racc_migration/checker.rbs +36 -0
  355. data/sig/ibex/racc_migration/harness.rbs +16 -0
  356. data/sig/ibex/racc_migration/report.rbs +53 -0
  357. data/sig/ibex/racc_migration.rbs +8 -0
  358. data/sig/ibex/rake_task.rbs +51 -0
  359. data/sig/ibex/samples.rbs +51 -0
  360. data/sig/ibex/table_simulation/result.rbs +32 -0
  361. data/sig/ibex/table_simulation/simulator.rbs +98 -0
  362. data/sig/ibex/table_simulation/step.rbs +40 -0
  363. data/sig/ibex/table_simulation/text.rbs +14 -0
  364. data/sig/ibex/table_simulation.rbs +7 -0
  365. data/sig/ibex/tables.rbs +0 -26
  366. data/sig/ibex/watch/runner.rbs +48 -0
  367. data/sig/ibex/watch/source_snapshot.rbs +42 -0
  368. data/sig/ibex/watch.rbs +7 -0
  369. data/sig/ibex.rbs +2 -0
  370. metadata +301 -16
  371. data/.rubocop.yml +0 -43
  372. data/CHANGELOG.md +0 -30
  373. data/Rakefile +0 -25
  374. data/Steepfile +0 -10
  375. data/docs/compat-notes.md +0 -37
  376. data/docs/lexer-coverage.md +0 -14
  377. data/docs/phase10-extensions.md +0 -27
  378. data/gemfiles/Gemfile +0 -7
  379. data/gemfiles/Gemfile.lock +0 -98
  380. data/lib/ibex/frontend/grammar.y +0 -156
  381. data/lib/ibex/runtime/parser.rb +0 -360
  382. data/lib/ibex/runtime.rb +0 -8
  383. data/sig/ibex/runtime/parser.rbs +0 -167
  384. data/sig/ibex/runtime.rbs +0 -6
data/docs/cst.md ADDED
@@ -0,0 +1,213 @@
1
+ # Red/Green concrete syntax trees
2
+
3
+ `pragma cst` generates a lossless, error-tolerant syntax tree alongside the
4
+ ordinary semantic result. Regenerate the parser with the current generator to
5
+ receive parser-table format v6 and this API. Batch parsing, typed views,
6
+ editing, diffing, and `ibex_cst` serialization are Stable for v1; syntax-only
7
+ incremental sessions are Experimental.
8
+
9
+ ```text
10
+ class Calculator
11
+ pragma cst
12
+ token NUM PLUS
13
+ lexer
14
+ skip /[[:space:]]+/
15
+ NUM /[0-9]+/ { lexeme.to_i }
16
+ PLUS '+'
17
+ end
18
+ rule
19
+ start: expression
20
+ expression: NUM PLUS NUM @node Addition(left, operator, right)
21
+ end
22
+ ```
23
+
24
+ ## Parsing and tree shape
25
+
26
+ `parse_with_syntax` runs semantic actions normally and returns both results:
27
+
28
+ ```ruby
29
+ result = Calculator.new.parse_with_syntax("1 + 2", file: "input.txt")
30
+ value = result.value
31
+ root = result.syntax_root
32
+ diagnostics = result.diagnostics
33
+ ```
34
+
35
+ `parse`, `do_parse`, and `yyparse` keep their semantic return values.
36
+ `parser.syntax_root` exposes the most recent syntax root. Every successful root
37
+ has this physical shape:
38
+
39
+ ```text
40
+ source_file
41
+ ├── selected start-symbol node
42
+ └── $eof
43
+ ```
44
+
45
+ The immutable Green layer stores kind ids, source bytes, trivia, flags, widths,
46
+ and children without parents or absolute positions. It is Ractor-shareable.
47
+ The Red `SyntaxNode`/`SyntaxToken` layer adds lazy parent, child-index, offset,
48
+ span, and location navigation for one occurrence. Equal Green values can
49
+ therefore appear at several positions without sharing Red coordinates.
50
+
51
+ `root.to_source` reconstructs the consumed bytes exactly. Early `yyaccept`
52
+ marks `root.incomplete_input?` and reconstructs the consumed prefix.
53
+
54
+ ## Trivia and coordinates
55
+
56
+ Select trivia ownership while generating:
57
+
58
+ - `leading` owns skipped text on the following token;
59
+ - `balanced` owns text through the first newline on the preceding token and
60
+ the remainder on the following token;
61
+ - `drop` omits trivia.
62
+
63
+ Pass the policy explicitly when needed:
64
+
65
+ ```sh
66
+ ibex --cst-trivia=leading grammar.y
67
+ ibex --cst-trivia=balanced grammar.y
68
+ ibex --cst-trivia=drop grammar.y
69
+ ```
70
+
71
+ `attach` is accepted as an alias for `leading`. EOF owns final leading trivia.
72
+ `drop` trees deliberately reject span, location, and incremental APIs because
73
+ their offsets cannot describe the original source.
74
+
75
+ Spans are zero-based, half-open byte ranges. `SourceText#position` and
76
+ `#location` convert them to one-based Unicode-scalar lines and columns while
77
+ preserving byte offsets.
78
+
79
+ ## Typed syntax views
80
+
81
+ An `@node` annotation generates a view in `Parser::Syntax` without changing the
82
+ physical tree:
83
+
84
+ ```ruby
85
+ addition = Calculator::Syntax::Addition.cast(
86
+ result.syntax_root.children.fetch(0).children.fetch(0)
87
+ )
88
+ addition.left
89
+ addition.operator
90
+ addition.right
91
+ ```
92
+
93
+ Accessors use normalized physical RHS slots. Lowered repetitions add element
94
+ enumerators; separated lists also expose separators. These views are distinct
95
+ from generated `Parser::AST` Data values: syntax views retain punctuation and
96
+ trivia, while AST values are semantic-action results.
97
+
98
+ ## Errors and repair
99
+
100
+ Lexical failure, yacc recovery, panic discard, and bounded repair all produce a
101
+ tree. Inspect `diagnostics`, `contains_error?`, error nodes, missing tokens, and
102
+ Green flags. Inserted tokens are zero-width `missing_token` values. Discarded
103
+ input remains under error nodes or `skipped_tokens` trivia. An unrecoverable
104
+ parse uses `synthetic_root`.
105
+
106
+ ## Persistent editing and diffing
107
+
108
+ Editing returns a new Red root and path-copies only changed ancestors:
109
+
110
+ ```ruby
111
+ old_root = result.syntax_root
112
+ first = old_root.first_token
113
+ new_root = first.with_text("10")
114
+ edits = Ibex::Runtime::CST::Diff.text_edits(old_root, new_root)
115
+ new_source = old_root.source_text.apply(edits)
116
+ ```
117
+
118
+ Nodes support `replace_with`, `with_child`, `insert_child`, and `remove_child`.
119
+ Tokens support `replace_with`, `with_text`, `with_leading`, and
120
+ `with_trailing`. `SyntaxRewriter` performs bottom-up kind dispatch;
121
+ `SyntaxEditor` applies several occurrence-addressed replacements in one pass.
122
+ `SyntaxAnnotation` marks one occurrence and excludes annotated Green values
123
+ from interning.
124
+
125
+ ## Incremental syntax sessions
126
+
127
+ Incremental parsing is Experimental and deliberately syntax-only:
128
+
129
+ ```ruby
130
+ source = Ibex::Runtime::CST::SourceText.new("1 + 2", file: "input.txt")
131
+ session = Calculator.incremental_session(source)
132
+ result = session.edit([
133
+ Ibex::Runtime::CST::TextEdit.new(
134
+ start: 4,
135
+ delete_length: 1,
136
+ insert_text: "3"
137
+ )
138
+ ])
139
+ ```
140
+
141
+ The initial parse and every edit suppress parser production actions.
142
+ `SyntaxResult` therefore has `syntax_root`, `diagnostics`, and `reused_ratio`,
143
+ but no semantic value. Generated lexer actions still run because they define
144
+ token emission and lexer-state changes. Run a normal parse separately when a
145
+ semantic value or side effect is required.
146
+
147
+ Sessions require `SourceText`, a generated lexer, format-v6 CST metadata, and
148
+ non-`drop` trivia. Handwritten token sources and push input are unsupported.
149
+ Parser actions that alone switch lexer state are also unavailable because the
150
+ syntax-only contract forbids executing them.
151
+
152
+ The default Stage B path relexes soundly from the beginning, validates old
153
+ token boundaries/states, and directly reuses only subtrees whose LR state,
154
+ follow token, flags, width, and damage range are safe. Pass `blender: false` to
155
+ retain the Stage A full LR drive. `ResourceLimits` bounds decomposition and
156
+ memo bytes; a bound failure deterministically falls back to the fresh token
157
+ stream. Observe `cst_built`, `cst_reuse`, and `cst_fallback` runtime events for
158
+ metrics.
159
+
160
+ ## Serialization
161
+
162
+ `ibex_cst` schema v1 is independent from Grammar IR:
163
+
164
+ ```ruby
165
+ tables = Calculator.parser_tables
166
+ json = Ibex::Runtime::CST::Serialize.dump(
167
+ session.result.syntax_root,
168
+ grammar_digest: tables.fetch(:grammar_digest),
169
+ table_format: tables.fetch(:format_version),
170
+ state_count: tables.fetch(:state_count),
171
+ production_count: tables.fetch(:production_count),
172
+ memo: session.parse_memo
173
+ )
174
+ loaded = Ibex::Runtime::CST::Serialize.load(
175
+ json,
176
+ grammar_digest: tables.fetch(:grammar_digest),
177
+ state_count: tables.fetch(:state_count),
178
+ production_count: tables.fetch(:production_count)
179
+ )
180
+ ```
181
+
182
+ Valid UTF-8 bytes use JSON strings; other bytes use canonical Base64 objects.
183
+ Loading rebuilds widths, aggregate flags, and descendant counts. A grammar
184
+ digest mismatch raises `ValidationError`. State or production count mismatch
185
+ silently discards only the optional parse memo. Annotations are session-local
186
+ and cannot be serialized.
187
+
188
+ ## Invariants and test coverage
189
+
190
+ The Red/Green contract is continuously exercised by the following repository
191
+ tests:
192
+
193
+ | Invariant | Automated evidence |
194
+ | --- | --- |
195
+ | I1 consumed-input fidelity | `test/runtime/cst_fidelity_property_test.rb` is PT1 over random grammars and valid, lexical-error, recovery, repair, and early-accept inputs; `test/fixtures/cst/runtime-paths-v1.json` fixes every error/trivia path, including long unmatched remainders and repair deletion. |
196
+ | I2 Green purity | `test/runtime/cst_green_test.rb` checks derived-only immutable state and Ractor shareability; `test/codegen/cst_characterization_test.rb` keeps semantic values outside syntax children. |
197
+ | I3 lazy Red navigation | `test/runtime/cst_red_test.rb` checks occurrence-local memoization, offsets, parents, cursors, and deterministic traversal. |
198
+ | I4 determinism | PT3 in `test/runtime/cst_green_test.rb` compares cache-on/off structure, source, and dump; PT6 in `test/runtime/cst_serialize_test.rb` checks byte-stable dump/load/dump; generated Ruby and RBS have golden tests. |
199
+ | I5 unchanged action contract | `test/codegen/cst_contract_test.rb` compares CST/no-CST `parse`, `do_parse`, `yyparse`, hooks, observer order, and non-CST table shape; characterization and obsolete-CST-table rejection regressions remain active. |
200
+ | I6 sharing boundary | PT5 in `test/runtime/cst_green_test.rb` checks Green shareability and concurrent Ractor reads; editing and parser-table tests keep Red/session state occurrence-owned. |
201
+ | I7 versioned contracts | `test/runtime/cst_serialize_test.rb`, `test/runtime/table_format_test.rb`, and `test/packaging/schema_files_test.rb` cover schema validation, memo compatibility, old table readers, and schema packaging. |
202
+ | I8 type soundness | CI regenerates the `sig/` tree, runs Steep and RBS validation, and rejects a type-statistics regression. |
203
+
204
+ `test/runtime/cst_incremental_property_test.rb` is the large PT2 authority. Its
205
+ fixed seed generates four grammar shapes and executes 20,000 random edits
206
+ through Stage A plus 20,000 through Stage B, comparing fresh syntax sessions in
207
+ Green structure, bytes, flags, diagnostics, and memo cardinality after every
208
+ edit. `test/runtime/cst_incremental_test.rb` adds focused stateful-lexer,
209
+ fallback, sharing, minimal-diff, action-suppression, no-value, and unsupported
210
+ configuration cases.
211
+
212
+ See [the migration guide](cst-migration.md) for removed tree-shape changes and
213
+ [the stability policy](stability.md) for support levels.
@@ -0,0 +1,129 @@
1
+ # Development and quality checks
2
+
3
+ This document describes contributor workflow and repository quality gates.
4
+ These practices verify the implementation but are not implementation
5
+ architecture decisions.
6
+
7
+ ## Default checks
8
+
9
+ Use Ruby 3.4 or newer, install the complete development toolchain once, and run
10
+ the unit, integration, documentation, and style suite:
11
+
12
+ ```sh
13
+ bundle install
14
+ bundle exec rake
15
+ ```
16
+
17
+ Additional repository checks are:
18
+
19
+ ```sh
20
+ bundle exec rake frontend:check
21
+ bundle exec rake grammar:test
22
+ bundle exec rake quality:error_ux
23
+ npm ci
24
+ npm run test:site
25
+ actionlint
26
+ zizmor .
27
+ ```
28
+
29
+ CI runs the supported Ruby matrix separately from optional experimental Ruby
30
+ implementations. Workflow and dependency-update configuration are authoritative
31
+ for the current matrix, schedules, permissions, and pinned action versions.
32
+ The matrix uses the intentionally unlocked `gemfiles/compat.Gemfile` so each
33
+ supported Ruby resolves compatible test dependencies. Contributors use the
34
+ root `Gemfile` and its committed lockfile for every development tool.
35
+
36
+ ## Browser site and API documentation
37
+
38
+ Install the locked browser dependencies and build the same self-hosted site
39
+ bundle exercised in CI:
40
+
41
+ ```sh
42
+ npm ci
43
+ npm run test:site
44
+ bundle exec yard doc
45
+ ```
46
+
47
+ `tool/build_site.rb`, the YARD configuration, and
48
+ `.github/workflows/pages.yml` are authoritative for documentation inputs,
49
+ build versions, artifact retention, deployment permissions, and the protected
50
+ Pages environment. Publication runs from `main`; pull requests validate the
51
+ site without receiving deployment credentials.
52
+
53
+ Changing those operational settings does not require an implementation ADR.
54
+ A change to the shipped browser analyzer's worker isolation, execution limits,
55
+ or Ruby/JavaScript data boundary does.
56
+
57
+ ## Self-hosted frontend
58
+
59
+ `lib/ibex/frontend/grammar.y` is the production grammar. Regenerate its
60
+ committed parser after changing the frontend language:
61
+
62
+ ```sh
63
+ bundle exec rake frontend:generate
64
+ bundle exec rake frontend:check
65
+ bundle exec ruby -Itest test/frontend/self_host_test.rb
66
+ ```
67
+
68
+ `lib/ibex/frontend/shadow_grammar.y` independently describes the same language
69
+ using parameterized and inline rules. Tests build it through the bootstrap
70
+ frontend and compare its location-preserving AST with the production parser.
71
+ The shadow source must change with the canonical grammar, but it never replaces
72
+ the committed production parser.
73
+
74
+ ## RBS and Steep
75
+
76
+ The development bundle includes the type toolchain. Regenerate the committed
77
+ RBS tree, validate it, type-check the library, and refresh the documented
78
+ statistics with:
79
+
80
+ ```sh
81
+ ruby -e '
82
+ sources = Dir.glob("lib/**/*.rb").sort
83
+ exec("bundle", "exec", "rbs-inline", "--opt-out", "--base=lib", "--output=sig", *sources)
84
+ '
85
+ bundle exec rbs -r digest -r json -r optparse -r tempfile -r timeout -r tmpdir -r uri -I sig validate
86
+ bundle exec steep check
87
+ bundle exec ruby tool/type_stats.rb --write
88
+ ```
89
+
90
+ CI generates signatures into a clean temporary directory and compares the
91
+ complete tree, so both missing and stale signature files fail.
92
+
93
+ ## Bounded mutation testing
94
+
95
+ Mutation analysis is part of the development bundle:
96
+
97
+ ```sh
98
+ bundle exec rake quality:mutation
99
+ ```
100
+
101
+ The job uses MRI 4.0, two workers, a ten-minute job budget, and the focused
102
+ `Ibex::Tables::Compact#initialize` matcher. `TablesTest` owns the mutation
103
+ coverage declaration. The mutation environment declares open-source usage and
104
+ applies a one-second timeout to each deterministic mutation. Expanding the
105
+ subject requires an explicit test owner, no surviving non-equivalent mutations,
106
+ and a measured duration within the same bounded job.
107
+
108
+ The supported runtime matrix uses `gemfiles/compat.Gemfile`, so the mutation
109
+ tool's Ruby floor does not change the library's Ruby floor.
110
+
111
+ ## Benchmarks and evidence
112
+
113
+ Performance observations are not ordinary CI timing thresholds. Follow the
114
+ [benchmark guide](../benchmark/README.md) for workload identities, formal
115
+ comparison commands, environment matching, artifact validation, and
116
+ append-only result history.
117
+
118
+ The development bundle includes the exact-version external-grammar profiler:
119
+
120
+ ```sh
121
+ bundle exec ruby benchmark/public_profile.rb --help
122
+ ```
123
+
124
+ Its output is diagnostic-only and must remain outside `benchmark/results/`.
125
+ Use it to locate costs, then repeat the uninstrumented public comparison to
126
+ produce reviewable performance evidence.
127
+
128
+ The versioned error-experience snapshot and its review procedure live in
129
+ [`docs/error-ux.md`](error-ux.md).
@@ -0,0 +1,25 @@
1
+ # Editor setup
2
+
3
+ Ibex ships an LSP 3.17 server for grammar files:
4
+
5
+ ```sh
6
+ ibex lsp --stdio
7
+ ```
8
+
9
+ Configure an editor language client to start that command for `.y` files and pass the project directory as `rootUri` or an
10
+ initial `workspaceFolders` entry. The server uses standard Content-Length framing on stdin/stdout. Do not wrap it with a command
11
+ that writes banners or logs to stdout; Ibex writes its own logs to stderr.
12
+
13
+ The server negotiates UTF-16 positions and full-document text synchronization. It provides:
14
+
15
+ - bounded parse and include diagnostics, including unsaved included fragments;
16
+ - definition and references for rules, formal parameters, terminals, and include targets;
17
+ - guarded cross-file prepare-rename and rename; and
18
+ - hover for rule signatures/documentation, terminal metadata/precedence, and include targets.
19
+
20
+ Only local `file:` URIs below the initialized workspace roots are accepted. Symlink escapes, traversal, remote authorities,
21
+ query/fragment URI components, and ambiguous encoded separators are rejected. Open buffers override disk until `didClose`;
22
+ closing first clears the buffer diagnostics and then restores the disk snapshot.
23
+
24
+ For a generic editor configuration, use command `ibex`, arguments `lsp --stdio`, language id `ibex`, and file pattern `*.y`.
25
+ Ibex never executes semantic actions or `header`, `inner`, or `footer` code while serving editor requests.
data/docs/error-ux.md ADDED
@@ -0,0 +1,60 @@
1
+ # JSON error UX evidence
2
+
3
+ This report fixes the Phase 14 error-experience baseline against ten malformed
4
+ inputs for the gallery JSON grammar. It is generated from
5
+ [`json-errors-v1.json`](../test/fixtures/error_ux/json-errors-v1.json) by:
6
+
7
+ ```sh
8
+ bundle exec ruby tool/error_ux_snapshot.rb
9
+ ```
10
+
11
+ Use `--write` only after reviewing a deliberate diagnostic, parser-table, racc,
12
+ or repair-policy change. CI regenerates the evidence and requires byte-for-byte
13
+ equality.
14
+
15
+ ## Comparison method
16
+
17
+ Ibex uses [`examples/json.y`](../examples/json.y), including its generated
18
+ lexer locations. The migration from its previous handwritten lexer is guarded
19
+ by exact location and error-snapshot tests. The comparison uses the self-authored compatible grammar
20
+ [`json_racc.y`](../test/fixtures/error_ux/json_racc.y), racc 1.8.1, and only the
21
+ public `racc` executable and `on_error(token, value, value_stack)` callback.
22
+ Neither racc implementation files nor generated source are inspected. Both
23
+ parsers receive the same source strings and equivalent token streams.
24
+
25
+ The racc column records the neutral callback wrapper's token argument. It does
26
+ not claim that an application cannot build richer diagnostics around racc; it
27
+ shows what the compared parser runtime exposes at that boundary without an
28
+ additional state-to-message layer.
29
+
30
+ | Case | Invalid source | Ibex diagnostic evidence | racc callback | Selected repair | Useful |
31
+ |---|---|---|---|---|---|
32
+ | EUX-01 | `{"a":,}` | line 1, column 6; 7 expected values; caret | token 9 | delete `,`, insert `STRING` | yes |
33
+ | EUX-02 | `{"a" 1}` | line 1, column 6; expected `:`; caret | token 3 | insert `:` | yes |
34
+ | EUX-03 | `{"a":1,}` | line 1, column 8; expected `STRING`; caret | token 8 | insert a complete member | no |
35
+ | EUX-04 | `[1,]` | line 1, column 4; 7 expected values; caret | token 12 | insert `STRING` | no |
36
+ | EUX-05 | `[1 2]` | line 1, column 4; expected `,` or `]`; caret | token 3 | insert `,` | yes |
37
+ | EUX-06 | `{"a":[true false]}` | line 1, column 12; expected `,` or `]`; caret | token 5 | insert `,` | yes |
38
+ | EUX-07 | `{"a":null "b":2}` | line 1, column 11; expected `}` or `,`; caret | token 2 | insert `,` | yes |
39
+ | EUX-08 | `{]` | line 1, column 2; expected `STRING` or `}`; caret | token 12 | replace `]` with `}` | yes |
40
+ | EUX-09 | `[}` | line 1, column 2; 8 expected values/closer; caret | token 8 | replace `}` with `]` | yes |
41
+ | EUX-10 | `true false` | line 1, column 6; expected EOF; caret | token 5 | delete extra `FALSE` | yes |
42
+
43
+ The committed JSON is the normative snapshot and also retains exact messages,
44
+ LR states, expected-token arrays, token values, repair costs, configuration
45
+ counts, and edit positions. Its public structure is validated by
46
+ [`schema/error-ux-v1.schema.json`](../schema/error-ux-v1.schema.json).
47
+
48
+ ## SP-4 decision
49
+
50
+ The bounded insertion/deletion/replacement search produced a completing plan
51
+ for all ten cases. Eight plans are reasonable representations of the likely
52
+ human edit; two trailing-comma cases invent a missing value/member where
53
+ deleting the comma would usually be preferable. The measured useful rate is
54
+ therefore **8/10 (80%)**, above the required majority.
55
+
56
+ SP-4 is **go** for the existing opt-in bounded single-plan repair described by
57
+ [ADR 0012](decisions/0012-bounded-nonexecuting-analysis.md). It remains
58
+ experimental: a selected edit can require a nil semantic value, and the search
59
+ does not enumerate every equal-cost CPCT+ repair. The stable default answer
60
+ remains exact expected tokens plus explicit yacc/synchronization recovery.