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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cf3b4cceb041622899923a174e36d413adb399c22cdb44f8023f1f199acea73
4
- data.tar.gz: 62ac1c3098103ac5270a8c684065424fcfc8bb2759332b3414672454ecbb25ca
3
+ metadata.gz: 46d7505f93788dea378cffff477d2d881b786445c3fd1fc805de78267784d11a
4
+ data.tar.gz: 853d1ad44d6224c7feba09fb00e012aa883ad3a86bbcbbaedc878b3f151f7bd6
5
5
  SHA512:
6
- metadata.gz: ec45347b6c9ec5f427261ade9ea4102a2b7b6583bcec47ee024d920fc624018bae9315a7129657977de47241e867ef23809ccef372169cb8e1d6a9ad858e31b3
7
- data.tar.gz: a163ab0fb84918570c2f62a9299d395653a0896c510e43a7672677803fe73f6010d74305868e1f6e5018b13b30d053c1a4d0852e16a0941f56a123bb883e7422
6
+ metadata.gz: 6b4f1e69a42798bc4b8b81be22ce21ce18a3a63e4fab0684e22e9d092055eba37d7a3d7341c3aec54bd04177553e8d8570419564130e1c8369e27ef742dffee9
7
+ data.tar.gz: 26d34199203cea82c17da593b06c067e24c661496ea13a1f0ec9bb2a4884730fb439ce5427c15c4bc193400ab365e237677462e540b539c1a31e74fa02b6e9c0
data/README.md CHANGED
@@ -1,28 +1,71 @@
1
1
  # Ibex
2
2
 
3
- Ibex is a Pure Ruby LR parser generator. It accepts racc-compatible grammar files, generates parsers with the familiar
4
- `do_parse` / `yyparse` API, and requires no C or Java extension. Its staged Grammar IR and Automaton IR can also drive extended
5
- EBNF syntax, diagnostics, visualizations, and alternate LR construction algorithms.
3
+ [![Gem Version](https://badge.fury.io/rb/ibex.svg)](https://badge.fury.io/rb/ibex)
4
+ [![CI](https://github.com/ydah/ibex/actions/workflows/main.yml/badge.svg)](https://github.com/ydah/ibex/actions/workflows/main.yml)
5
+
6
+ Ibex is a Pure Ruby LR parser generator. It reads racc-compatible grammar
7
+ files, generates parsers with the familiar `do_parse` / `yyparse` API, and
8
+ requires no C or Java extension.
9
+
10
+ > [!IMPORTANT]
11
+ > Ibex is pre-1.0. The current v1.0 decision is
12
+ > [**HOLD**](docs/release-readiness.md): compatibility and scale evidence pass,
13
+ > but cold generation and new-instance runtime still trail Racc's Ruby backend,
14
+ > and the error UX evidence still needs independent review. Compatible mode is
15
+ > the stable baseline; opt-in features have the maturity levels documented in
16
+ > the [stability policy](docs/stability.md).
17
+
18
+ - Try grammar analysis in the
19
+ [browser playground](https://ydah.github.io/ibex/playground/).
20
+ - Start with the [grammar reference](docs/grammar-reference.md).
21
+ - Build lossless and incremental tooling with the
22
+ [Red/Green CST guide](docs/cst.md).
23
+ - Migrate an existing parser with the
24
+ [racc migration guide](docs/racc-migration.md).
25
+ - Browse the [API reference](https://ydah.github.io/ibex/api/).
26
+
27
+ The playground runs in a local Web Worker. It does not upload grammar source
28
+ or execute semantic action bodies.
29
+
30
+ ## At a glance
31
+
32
+ | Concern | Ibex default |
33
+ | --- | --- |
34
+ | Grammar input | racc-compatible `.y` source |
35
+ | Construction | Direct LALR(1) |
36
+ | Generated tables | Compact, immutable Ruby data |
37
+ | Parser API | Pull parsing with `do_parse` / `yyparse` |
38
+ | Generated dependency | The separately versioned `ibex-runtime` gem |
39
+ | Ruby support | Ruby 3.0 or later |
40
+ | Extensions | Disabled unless `pragma extended` or `--mode=extended` is used |
41
+ | Concrete syntax | Stable format-v6 Red/Green CST with `pragma cst` |
42
+ | Semantic actions | Opaque during generation and analysis; executed only by a running parser |
43
+
44
+ The generator and runtime are deliberately separate:
6
45
 
7
- ## Requirements and installation
46
+ ```text
47
+ grammar.y + lexer contract
48
+ |
49
+ v
50
+ ibex -----> parser.rb --------> ibex-runtime
51
+ |
52
+ +--------> optional RBS, IR, reports, diagrams, and docs
53
+ ```
8
54
 
9
- Ibex supports Ruby 3.0 or later and has no runtime gem dependencies. From a source checkout:
55
+ Use `-E` when a generated parser must embed the runtime instead of depending
56
+ on `ibex-runtime`.
10
57
 
11
- ```sh
12
- bundle install
13
- bundle exec rake
14
- ```
58
+ ## Quick start from a checkout
15
59
 
16
- Build and install the local gem when you want the `ibex` executable on your `PATH`:
60
+ Clone the repository and install its locked development dependencies:
17
61
 
18
62
  ```sh
19
- gem build ibex.gemspec
20
- gem install ./ibex-0.1.0.gem
63
+ git clone https://github.com/ydah/ibex.git
64
+ cd ibex
65
+ bundle install
21
66
  ```
22
67
 
23
- ## Three-minute calculator
24
-
25
- Save this as `calculator.y`:
68
+ Save this grammar as `calculator.y`:
26
69
 
27
70
  <!-- calculator-grammar:start -->
28
71
  ```text
@@ -54,141 +97,241 @@ end
54
97
  ```
55
98
  <!-- calculator-grammar:end -->
56
99
 
57
- Generate and run it:
100
+ Generate and run the parser without installing local gems:
101
+
102
+ ```sh
103
+ bundle exec ruby -Ilib exe/ibex calculator.y
104
+ bundle exec ruby -Ilib calculator.rb
105
+ # 14
106
+ ```
107
+
108
+ With the local gems installed, the equivalent commands are:
58
109
 
59
110
  ```sh
60
111
  ibex calculator.y
61
112
  ruby calculator.rb
62
- # 14
63
113
  ```
64
114
 
65
- From a checkout without installing the gem, use `bundle exec ruby -Ilib exe/ibex calculator.y` and
66
- `bundle exec ruby -Ilib calculator.rb` instead.
115
+ Ibex writes `calculator.rb`, uses compact tables, and generates a parser that
116
+ requires `ibex-runtime`. Use `-o PATH` to choose the output, `--table=plain`
117
+ for inspectable Hash rows, `--check` to compare without rewriting, or `-E` to
118
+ embed the runtime.
119
+
120
+ ## Generated parser contract
121
+
122
+ ### Tokens and lexers
123
+
124
+ A handwritten pull lexer implements `next_token` and returns:
125
+
126
+ ```ruby
127
+ [token, value]
128
+ [token, value, location]
129
+ ```
67
130
 
68
- Ibex generates compact tables by default. Compatibility-safe default reductions shrink profitable states while retaining
69
- explicit error cells, including recovery and undeclared-token behavior. `--table=plain` produces inspectable Hash rows, while
70
- `-E` embeds the runtime into a single dependency-free output file.
131
+ `false` or `nil` marks EOF. Bare grammar tokens use Ruby symbols such as
132
+ `:NUM`; quoted terminals use strings such as `'+'`. Locations are
133
+ application-owned objects and remain optional.
71
134
 
72
- ## Lexer contract
135
+ Existing lexers can use the [lexer migration guide](docs/lexer-migration.md).
136
+ Extended grammars may instead generate a streaming lexer from declarative
137
+ regular-expression rules.
73
138
 
74
- Ibex does not generate a lexer. A pull parser implements `next_token` and returns `[token, value]`; `false` or `nil` marks EOF.
75
- Bare grammar tokens normally use Ruby symbols (`:NUM`), and quoted grammar tokens use strings (`'+'`). A push source can call
76
- `yyparse(receiver, method_name)` where the receiver method yields the same pairs.
139
+ ### Semantic actions and locations
77
140
 
78
- The default `on_error(token_id, value, value_stack)` raises `Ibex::ParseError`. Override it to use yacc-style `error` recovery.
79
- Semantic actions can call `yyerror`, `yyerrok`, or `yyaccept`, and `expected_tokens` reports valid lookaheads in the current state.
80
- Parser subclasses can also override `on_shift(token_id, value, state)`,
81
- `on_reduce(production_id, values, result)`, and `on_error_recover(token_id, value, value_stack)` as no-op-by-default observers.
82
- Ordinary shifts and the synthetic recovery-token shift use separate hooks; observer return values never replace semantic values.
141
+ Actions read RHS values through `val`. `@1`, `@2`, and so on address parallel
142
+ semantic locations, while `@$` is the span of the current reduction. Action
143
+ source remains opaque Ruby: Ibex preserves its source mapping but does not
144
+ parse, type-check, or sandbox it.
83
145
 
84
- ## Extended mode
146
+ ### Parse lifecycles and errors
85
147
 
86
- `--mode=extended` enables optional, repeated, and separated values plus named references. A grammar can make the same choice
87
- locally with `pragma extended` immediately after its `class` header:
148
+ Generated parsers support:
149
+
150
+ - `do_parse` and yielding `yyparse` for racc-compatible pull parsing;
151
+ - `push(token, value, location)` and `finish(location:)` for caller-driven
152
+ streaming;
153
+ - structured `Ibex::ParseError` values containing the token, expected tokens,
154
+ state, location, and spelling suggestions;
155
+ - yacc-style recovery through `on_error`, `yyerror`, `yyerrok`, and
156
+ `yyaccept`; and
157
+ - immutable, shareable generated tables.
158
+
159
+ Use one parser instance per concurrent parse. Isolated runtime sessions and
160
+ resource budgets are opt-in when application code needs explicit execution
161
+ boundaries.
162
+
163
+ ## Choose a grammar mode
164
+
165
+ | Mode | Use it for | Contract |
166
+ | --- | --- | --- |
167
+ | `default` | Existing racc grammars and conservative migrations | Compatible syntax and runtime behavior |
168
+ | `extended` | New grammars that need composition or generated tooling | Preview, explicitly enabled |
169
+
170
+ Enable extended syntax with `pragma extended` in the grammar or
171
+ `--mode=extended` on the command line:
88
172
 
89
173
  ```text
90
174
  class ExtendedParser
91
175
  pragma extended
176
+ token NUM KEY VALUE
92
177
  rule
93
- arguments : separated_list(NUM, ',') { result = val[0] }
178
+ arguments : separated_list(NUM, ',')
94
179
  sum : NUM:left '+' NUM:right { result = left + right }
95
180
  maybe : NUM?
96
181
  many : NUM*
97
- some : NUM+
98
- pairs : (KEY VALUE)*
182
+ groups : (KEY VALUE)+
183
+ list(X) : X | list(X) ',' X
184
+ %inline signed(X): '-' X { result = -val[1] }
185
+ negative : signed(NUM)
99
186
  end
100
187
  ```
101
188
 
102
- The value conventions are `nil` or a value for `?`, and arrays for `*`, `+`, `separated_list`, and
103
- `separated_nonempty_list`. Parenthesized sequences and alternatives can be nested; multi-item groups produce an Array value.
104
- Text, DOT, and HTML automaton reports label lowered helper symbols with these source-level EBNF expressions.
189
+ Extended mode includes nested EBNF groups, named references, parameterized and
190
+ inline rules, multiple entry points, canonical fragment imports, generated
191
+ lexers, CST or typed `Data` AST generation, declarative recovery, semantic
192
+ types, and grammar-declared tests. These features do not silently change the
193
+ default compatible frontend. Maturity is assigned per API: format-v6 batch
194
+ Red/Green CST is Stable, while the wider extended grammar surface remains
195
+ Preview and incremental CST sessions remain Experimental.
105
196
 
106
- ## Pipeline and diagnostics
197
+ ## Choose a construction algorithm
107
198
 
108
- ```sh
109
- ibex --emit=grammar-ir grammar.y > grammar.json
110
- ibex --from=grammar-ir --emit=automaton-ir grammar.json > automaton.json
111
- ibex --from=automaton-ir -o parser.rb automaton.json
112
- ibex -v --dot=states.dot --html=states.html grammar.y
113
- ibex --algorithm=lr1 grammar.y
114
- ibex --counterexamples --counterexample-max-tokens=64 --counterexample-max-configurations=100000 grammar.y
115
- ibex --rbs -o parser.rb grammar.y
116
- ibex --warnings=all,error -C grammar.y
117
- ```
199
+ | Option | When to use it |
200
+ | --- | --- |
201
+ | `--algorithm=lalr` | Default direct LALR(1) construction |
202
+ | `--algorithm=slr` | Grammars whose FOLLOW-set reductions are sufficient |
203
+ | `--algorithm=ielr` | Preview backend for conflicts introduced by LALR state merging |
204
+ | `--algorithm=lr1` | Canonical LR(1) analysis when the larger automaton is acceptable |
118
205
 
119
- Supported construction algorithms are `slr`, `lalr` (default), and canonical `lr1`. Reports retain precedence-resolved
120
- conflicts and distinguish unifying counterexamples from nonunifying reachability witnesses. Counterexample searches default to
121
- 32 tokens and 50,000 explored configurations; `--counterexample-max-tokens=N` and
122
- `--counterexample-max-configurations=N` set positive per-run budgets and request a report. `--rbs` writes a signature beside the
123
- generated parser; `--rbs=FILE` selects another path. Application methods supplied as opaque `---- inner` code can be declared by
124
- reopening the generated class in an application RBS file.
206
+ `--suggest-ielr` checks whether IELR removes an unexpected LALR conflict and
207
+ prints an advisory note when it does.
208
+ That note does not change the selected algorithm or exit status.
125
209
 
126
- `--warnings=all` prints unused terminals, unreachable nonterminals, duplicate productions, undeclared terminals, and empty-language
127
- diagnostics. Add `error` (`--warnings=all,error`, or simply `--warnings=error`) to make any such diagnostic fail the command.
128
- Action exceptions and `inner` methods point back to their `.y` lines by default. `--line-convert-all` extends that mapping to
129
- `header` and `footer`; `-l` disables every source-line conversion. User-code chunk locations survive Grammar/Automaton IR JSON
130
- round trips, so resumed generation has the same backtraces as direct generation.
210
+ Conflict freedom is not the same as a proof of unambiguity. `ibex check
211
+ --ambiguity` searches for a concrete sentence with two interpretations, but
212
+ the token and configuration budgets make every result explicitly bounded.
131
213
 
132
- ## Documentation
214
+ ## Integrate generation into a build
133
215
 
134
- - [Grammar reference](docs/grammar-reference.md)
135
- - [racc migration guide](docs/racc-migration.md)
136
- - [Architecture and IR schemas](docs/architecture.md)
137
- - [Compatibility observations](docs/compat-notes.md)
138
- - [Phase 10 extensions](docs/phase10-extensions.md)
216
+ Treat grammar source as the input and generated Ruby as a reproducible build
217
+ artifact:
139
218
 
140
- ## Development
219
+ ```sh
220
+ ibex --warnings=error -o lib/calculator.rb grammar/calculator.y
221
+ ibex --warnings=error --check -o lib/calculator.rb grammar/calculator.y
222
+ ```
141
223
 
142
- Run all unit, integration, documentation, and optional local racc black-box tests with `bundle exec rake test`; run style checks
143
- with `bundle exec rake lint`. The default `bundle exec rake` runs both. Compatibility tests skip automatically when the `racc`
144
- command is unavailable.
224
+ The first command writes the parser. The second is suitable for CI and fails
225
+ when the committed output is stale without modifying it.
145
226
 
146
- Ibex's grammar frontend is self-hosted. Edit `lib/ibex/frontend/grammar.y`, then regenerate and verify the committed parser with:
227
+ Rake projects can declare the dependency directly:
147
228
 
148
- ```sh
149
- bundle exec rake frontend:generate
150
- git diff --exit-code -- lib/ibex/frontend/generated_parser.rb
151
- bundle exec ruby -Itest test/frontend/self_host_test.rb
229
+ ```ruby
230
+ require "ibex/rake_task"
231
+
232
+ Ibex::RakeTask.new("lib/calculator.rb") do |task|
233
+ task.grammar = "grammar/calculator.y"
234
+ task.options = ["--warnings=error"]
235
+ end
152
236
  ```
153
237
 
154
- Normal library and CLI execution use the generated parser. The handwritten `BootstrapParser` is loaded only by this regeneration
155
- workflow, whose direct dependency graph also works when the generated file is absent. Byte-comparison and AST/error parity tests
156
- prevent generated-source drift.
238
+ The task follows the grammar's fragment dependency closure. Multi-output
239
+ generation can additionally publish a manifest containing input identities,
240
+ output paths, sizes, and SHA-256 digests. Generation renders all requested
241
+ outputs before publishing them; `--watch` retains the last successful output
242
+ when a later edit is invalid.
157
243
 
158
- Fixed-seed property tests exercise SLR, LALR, and LR(1) pipeline invariants, while versioned Grammar and Automaton IR fixtures
159
- guard byte-stable schema compatibility. Intentional fixture updates are documented in `test/fixtures/ir/README.md`. Run the
160
- reproducible whole-builder benchmark without a timing pass/fail threshold with:
244
+ Applications that only execute generated parsers need `ibex-runtime`, not the
245
+ generator. To build and install both current local gems:
161
246
 
162
247
  ```sh
163
- benchmark/pipeline.rb --rules 200 --iterations 5 --seed 12345
248
+ gem build ibex-runtime.gemspec
249
+ gem build ibex.gemspec
250
+ gem install ./ibex-runtime-0.1.0.gem
251
+ gem install ./ibex-0.1.0.gem
164
252
  ```
165
253
 
166
- Signatures for every Ruby source under `lib/` are generated from rbs-inline annotations and checked with Steep, including the
167
- self-hosted generated parser. To regenerate the committed signature tree and reproduce its validation locally:
254
+ ## Diagnose, verify, and inspect
255
+
256
+ | Goal | Command |
257
+ | --- | --- |
258
+ | Promote grammar warnings to errors | `ibex --warnings=error -C grammar.y` |
259
+ | Collect structured frontend diagnostics | `ibex diagnose --format=json grammar.y` |
260
+ | Explain one conflict | `ibex explain --state=7 --token=ELSE grammar.y` |
261
+ | Search for a concrete ambiguity | `ibex check --ambiguity --algorithm=lr1 grammar.y` |
262
+ | Run grammar-declared tests | `ibex test --coverage=100 grammar.y` |
263
+ | Check canonical formatting | `ibex fmt --check grammar.y` |
264
+ | Render grammar documentation | `ibex doc --format=html -o grammar.html grammar.y` |
265
+ | Emit Automaton IR | `ibex --emit=automaton-ir grammar.y > automaton.json` |
266
+ | Simulate table behavior without actions | `ibex debug automaton.json NUMBER PLUS NUMBER` |
267
+ | Check a racc migration | `ibex migrate-check grammar.y` |
268
+ | Start the language server | `ibex lsp --stdio` |
269
+
270
+ Grammar IR, Automaton IR, generated table formats, diagnostic JSON, runtime
271
+ events, coverage, and manifests are versioned contracts. Reports can also be
272
+ rendered as text, DOT, Mermaid, HTML, railroad SVG, samples, or conflict
273
+ counterexamples.
274
+
275
+ ## Safety boundaries and non-goals
276
+
277
+ - Frontend parsing, diagnosis, formatting, documentation, LSP, static
278
+ migration checks, IR validation, and table simulation do not execute
279
+ semantic actions or user-code sections.
280
+ - Generated parsers, grammar-declared tests, and explicit migration harnesses
281
+ do execute application Ruby. They are not sandboxes.
282
+ - Fragment imports are confined to the declared source root and reject
283
+ traversal, cycles, and symlink escapes.
284
+ - Counterexample, ambiguity, sample, repair, and runtime-budget searches are
285
+ bounded. Exhausting a budget is distinct from finding no witness within it.
286
+ - Ibex generates deterministic LR parsers. It does not provide GLR or
287
+ generalized ambiguity handling. Incremental CST sessions are syntax-only
288
+ and experimental.
289
+ - racc compatibility is a migration surface, not a claim that every generated
290
+ parser is a byte-for-byte or adapter-free replacement.
291
+ - Preview and experimental features may have weaker compatibility guarantees
292
+ than the default mode.
293
+
294
+ ## Documentation by task
295
+
296
+ | When you need to... | Start here |
297
+ | --- | --- |
298
+ | Write a grammar or use the runtime | [Grammar reference](docs/grammar-reference.md) |
299
+ | Build, edit, serialize, or incrementally update syntax trees | [Red/Green CST guide](docs/cst.md) and [migration guide](docs/cst-migration.md) |
300
+ | Learn from executable grammars | [Examples](examples/README.md) |
301
+ | Migrate from racc | [racc migration guide](docs/racc-migration.md) |
302
+ | Adapt a handwritten lexer | [Lexer migration guide](docs/lexer-migration.md) |
303
+ | Configure an editor or LSP client | [Editor setup](docs/editor-setup.md) |
304
+ | Understand the pipeline, IR, algorithms, or tables | [Architecture](docs/architecture.md) |
305
+ | Check API maturity and deprecation rules | [Stability policy](docs/stability.md) |
306
+ | Evaluate readiness, performance, or error UX | [Release readiness](docs/release-readiness.md), [benchmarks](benchmark/README.md), and [error UX](docs/error-ux.md) |
307
+ | Contribute or run every quality gate | [Development guide](docs/development.md) |
308
+ | Review implementation decisions | [Architecture decision records](docs/decisions/README.md) |
309
+
310
+ The published documentation separates the
311
+ [compatibility contract](https://ydah.github.io/ibex/compatibility/),
312
+ [opt-in extensions](https://ydah.github.io/ibex/extensions/), and
313
+ [experimental surfaces](https://ydah.github.io/ibex/experimental/). The
314
+ [grammar gallery](https://ydah.github.io/ibex/gallery/) contains executable
315
+ examples whose declared tests reach complete production coverage.
316
+
317
+ ## Development
318
+
319
+ The [development guide](docs/development.md) contains frontend regeneration,
320
+ RBS/Steep validation, grammar coverage, browser checks, mutation analysis, and
321
+ workflow lint commands. The default local gate is:
168
322
 
169
323
  ```sh
170
- BUNDLE_GEMFILE=gemfiles/Gemfile bundle install
171
- BUNDLE_GEMFILE=gemfiles/Gemfile ruby -e '
172
- sources = Dir.glob("lib/**/*.rb").sort
173
- exec("bundle", "exec", "rbs-inline", "--opt-out", "--base=lib", "--output=sig", *sources)
174
- '
175
- BUNDLE_GEMFILE=gemfiles/Gemfile bundle exec rbs -r digest -r json -r optparse -I sig validate
176
- BUNDLE_GEMFILE=gemfiles/Gemfile bundle exec steep check
177
- BUNDLE_GEMFILE=gemfiles/Gemfile bundle exec steep stats
178
- BUNDLE_GEMFILE=gemfiles/Gemfile bundle exec ruby tool/type_stats.rb --write
324
+ bundle install
325
+ bundle exec rake
179
326
  ```
180
327
 
181
- CI performs generation in a clean temporary directory and compares the complete trees, so missing source signatures and stale
182
- signature files both fail the build.
183
328
  <!-- type-stats:start -->
184
- The current whole-library `steep stats` result is 3,771 typed calls and 449 untyped calls out of 4,220 (89.4% typed).
185
- The generated signature tree contains 397 explicit `untyped` occurrences across 16 files.
329
+ The current whole-library `steep stats` result is 20,629 typed calls and 2,275 untyped calls out of 22,904 (90.1% typed).
330
+ The generated signature tree contains 2,084 explicit `untyped` occurrences across 103 files.
186
331
  <!-- type-stats:end -->
187
332
 
188
- Those boundaries are concentrated in generated-parser reduction values, heterogeneous JSON decoding/serialization, runtime
189
- semantic values and parser-table cells, and embedded user Ruby. Token/location records, the complete grammar AST, parser
190
- classifier state, IR, the public Ruby DSL, bootstrap parser state, analysis, automaton construction, code generators, table
191
- construction, and CLI options use concrete domain types. The committed self-hosted parser remains in the Steep target; no library
192
- directory or generated source is excluded.
333
+ Performance measurements are evidence, not portable scores or CI timing
334
+ thresholds. Follow the [benchmark guide](benchmark/README.md) to reproduce and
335
+ compare results under the same environment and configuration.
193
336
 
194
337
  Ibex is available under the [MIT License](LICENSE.txt).