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
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require_relative "../frontend"
5
+ require_relative "../normalize"
6
+ require_relative "../codegen/documentation"
7
+
8
+ module Ibex
9
+ # Generates standalone grammar documentation from the canonical include closure.
10
+ module CLIDocumentation
11
+ # @rbs!
12
+ # type documentation_settings = {
13
+ # format: String,
14
+ # mode: Symbol,
15
+ # ?output: String,
16
+ # ?help: bool
17
+ # }
18
+ #
19
+ # private def input_path: (Array[String]) -> String
20
+ # private def same_file_target?: (String left, String right) -> bool
21
+ # private def atomic_write_ir: (String path, String source) -> void
22
+
23
+ private
24
+
25
+ # @rbs (Array[String] arguments) -> Integer
26
+ def run_documentation_command(arguments)
27
+ settings = { format: "markdown", mode: :default } #: documentation_settings
28
+ parser = documentation_option_parser(settings)
29
+ remaining = parser.parse(arguments)
30
+ if settings[:help]
31
+ @stdout.puts(parser)
32
+ return 0
33
+ end
34
+
35
+ path = input_path(remaining)
36
+ output = settings[:output]
37
+ resolution = Frontend::Resolver.new(path, mode: settings.fetch(:mode)).resolve
38
+ reject_documentation_output_collision(output, resolution.files) if output
39
+ grammar = Normalizer.new(resolution, mode: settings.fetch(:mode)).normalize
40
+ rendered = Codegen::Documentation.render(grammar, format: settings.fetch(:format))
41
+ output ? atomic_write_ir(output, rendered) : @stdout.write(rendered)
42
+ 0
43
+ end
44
+
45
+ # @rbs (String output, Array[String] grammar_files) -> void
46
+ def reject_documentation_output_collision(output, grammar_files)
47
+ collision = grammar_files.find { |grammar_file| same_file_target?(grammar_file, output) }
48
+ return unless collision
49
+
50
+ raise Ibex::Error,
51
+ "(cli):1:1: doc input and output paths must be distinct; output aliases grammar source #{collision}"
52
+ end
53
+
54
+ # @rbs (documentation_settings settings) -> OptionParser
55
+ def documentation_option_parser(settings)
56
+ OptionParser.new do |options|
57
+ options.banner = "Usage: ibex doc [options] grammarfile"
58
+ options.on("--format=FORMAT", Codegen::Documentation::FORMATS, "markdown, html, or railroad") do |value|
59
+ settings[:format] = value
60
+ end
61
+ options.on("-o FILE", "--output=FILE", "write atomically to FILE") { |value| settings[:output] = value }
62
+ options.on("--mode=MODE", %w[default extended], "grammar mode") { |value| settings[:mode] = value.to_sym }
63
+ options.on("--help", "show help") { settings[:help] = true }
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tempfile"
4
+ require_relative "../error_messages"
5
+ require_relative "../ir"
6
+
7
+ module Ibex
8
+ # CLI subcommand and generation-file handling for example-keyed errors.
9
+ module CLIErrorMessages
10
+ # @rbs!
11
+ # private def print_help: (OptionParser) -> Integer
12
+ # private def input_path: (Array[String]) -> String
13
+ # private def warning_categories: (String) -> Array[Symbol]
14
+ # private def report_status: (String) -> void
15
+ # private def handle_grammar_warnings: (IR::Grammar, String) -> void
16
+ # private def build_automaton: (IR::Grammar, String) -> IR::Automaton
17
+ # private def prepare_loaded_automaton: (IR::Automaton, String) -> void
18
+ # private def default_output_path: (String, String) -> String
19
+ # private def same_file_target?: (String, String) -> bool
20
+ # private def normalize_grammar_path: (String) -> IR::Grammar
21
+ # private def record_generation_input: (String, String) -> GenerationInput
22
+
23
+ private
24
+
25
+ # @rbs (Array[String] arguments) -> Integer
26
+ def run_error_messages_command(arguments)
27
+ parser = error_messages_option_parser
28
+ remaining = parser.parse(arguments)
29
+ return print_help(parser) if @options[:help]
30
+ if @options[:messages_list] && @options[:messages_update]
31
+ raise Ibex::Error, "(cli):1:1: errors command accepts only one of --list or --update"
32
+ end
33
+ unless @options[:messages_list] || @options[:messages_update]
34
+ raise Ibex::Error, "(cli):1:1: errors command requires --list or --update[=FILE]"
35
+ end
36
+
37
+ input = input_path(remaining)
38
+ automaton = automaton_for_error_messages(input)
39
+ if @options[:messages_list]
40
+ @stdout.write(ErrorMessages.render(automaton, **error_message_search_limits))
41
+ else
42
+ write_error_messages(automaton, input)
43
+ end
44
+ 0
45
+ end
46
+
47
+ # @rbs () -> OptionParser
48
+ def error_messages_option_parser
49
+ OptionParser.new do |options|
50
+ options.banner = "Usage: ibex errors (--list | --update[=FILE]) [options] grammarfile"
51
+ options.on("--list", "list shortest error sentences on stdout") { @options[:messages_list] = true }
52
+ options.on("--update[=FILE]", "update messages (defaults to grammar.messages)") do |value|
53
+ @options[:messages_update] = value || true
54
+ end
55
+ options.on("--max-tokens=N", Integer, "maximum error-sentence token budget") do |value|
56
+ @options[:messages_max_tokens] = positive_messages_limit(value, "--max-tokens")
57
+ end
58
+ options.on("--max-configurations=N", Integer, "maximum error-sentence configuration budget") do |value|
59
+ @options[:messages_max_configurations] = positive_messages_limit(value, "--max-configurations")
60
+ end
61
+ options.on("--from=FORMAT", %w[grammar-ir automaton-ir], "resume from IR JSON") do |value|
62
+ @options[:from] = value
63
+ end
64
+ options.on("--mode=MODE", %w[default extended], "grammar mode") { |value| @options[:mode] = value.to_sym }
65
+ options.on("--algorithm=NAME", %w[slr lalr ielr lr1], "parser construction algorithm") do |value|
66
+ @options[:algorithm] = value.to_sym
67
+ @options[:messages_algorithm_explicit] = true
68
+ end
69
+ options.on("--warnings=CATEGORIES", "all, error, all,error, or none") do |value|
70
+ @options[:warnings] = warning_categories(value)
71
+ end
72
+ options.on("-S", "--output-status", "show pipeline status") { @options[:status] = true }
73
+ options.on("--help", "show help") { @options[:help] = true }
74
+ end
75
+ end
76
+
77
+ # @rbs (String input_path) -> IR::Automaton
78
+ def automaton_for_error_messages(input_path)
79
+ return automaton_from_ir_for_messages(input_path) if @options[:from]
80
+
81
+ report_status("reading #{input_path}")
82
+ grammar = normalize_grammar_path(input_path)
83
+ handle_grammar_warnings(grammar, input_path)
84
+ build_automaton(grammar, input_path)
85
+ end
86
+
87
+ # @rbs (String input_path) -> IR::Automaton
88
+ def automaton_from_ir_for_messages(input_path)
89
+ report_status("reading #{input_path}")
90
+ value = IR::Validator.validate(File.read(input_path))
91
+ expected = @options[:from] == "grammar-ir" ? IR::Grammar : IR::Automaton
92
+ raise Ibex::Error, "#{input_path}:1:1: expected #{@options[:from]} input" unless value.is_a?(expected)
93
+ if value.is_a?(IR::Automaton) && @options[:messages_algorithm_explicit]
94
+ raise Ibex::Error, "(cli):1:1: --algorithm cannot be combined with --from=automaton-ir"
95
+ end
96
+
97
+ grammar = if value.is_a?(IR::Grammar)
98
+ value
99
+ elsif value.is_a?(IR::Automaton)
100
+ value.grammar
101
+ else
102
+ raise Ibex::Error, "#{input_path}:1:1: expected #{@options[:from]} input"
103
+ end
104
+ handle_grammar_warnings(grammar, input_path)
105
+ return build_automaton(value, input_path) if value.is_a?(IR::Grammar)
106
+
107
+ if value.is_a?(IR::Automaton)
108
+ prepare_loaded_automaton(value, input_path)
109
+ return value
110
+ end
111
+
112
+ raise Ibex::Error, "#{input_path}:1:1: expected #{@options[:from]} input"
113
+ end
114
+
115
+ # @rbs (IR::Automaton automaton, String input_path) -> void
116
+ def write_error_messages(automaton, input_path)
117
+ configured = @options[:messages_update]
118
+ path = configured == true ? default_output_path(input_path, ".messages") : configured
119
+ raise Ibex::Error, "(cli):1:1: messages update path must not be empty" unless path.is_a?(String) && !path.empty?
120
+ if same_file_target?(path, input_path)
121
+ raise Ibex::Error, "(cli):1:1: messages update path must differ from the input path"
122
+ end
123
+
124
+ existing = if File.exist?(path)
125
+ ErrorMessages.load(path)
126
+ else
127
+ ErrorMessages::Document.new(entries: [])
128
+ end
129
+ update = ErrorMessages.update(automaton, existing: existing, **error_message_search_limits)
130
+ target_path = File.symlink?(path) ? File.realpath(path) : path
131
+ directory = File.dirname(File.expand_path(target_path))
132
+ Tempfile.create([".ibex-messages-", ".tmp"], directory, encoding: "UTF-8") do |file|
133
+ file.write(update.source)
134
+ File.chmod(messages_file_mode(target_path), file.path)
135
+ file.flush
136
+ file.fsync
137
+ File.rename(file.path, target_path)
138
+ end
139
+ write_error_message_update_report(update)
140
+ report_status("wrote #{path}")
141
+ end
142
+
143
+ # @rbs () -> { max_tokens: Integer, max_configurations: Integer }
144
+ def error_message_search_limits
145
+ {
146
+ max_tokens: @options.fetch(:messages_max_tokens, ErrorMessages::SentenceSearch::DEFAULT_MAX_TOKENS),
147
+ max_configurations: @options.fetch(
148
+ :messages_max_configurations, ErrorMessages::SentenceSearch::DEFAULT_MAX_CONFIGURATIONS
149
+ )
150
+ }
151
+ end
152
+
153
+ # @rbs (Integer value, String option) -> Integer
154
+ def positive_messages_limit(value, option)
155
+ return value if value.positive?
156
+
157
+ raise Ibex::Error, "(cli):1:1: #{option} must be positive"
158
+ end
159
+
160
+ # @rbs (ErrorMessages::Update update) -> void
161
+ def write_error_message_update_report(update)
162
+ classifications = {
163
+ "uncovered" => update.uncovered, "unreachable" => update.unreachable, "moved" => update.moved
164
+ }
165
+ classifications.each do |label, items|
166
+ items.each { |item| @stdout.puts("#{label}: #{item}") }
167
+ end
168
+ end
169
+
170
+ # @rbs (String path) -> Integer
171
+ def messages_file_mode(path)
172
+ return File.stat(path).mode & 0o777 if File.exist?(path)
173
+
174
+ 0o666 & ~File.umask
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "optparse"
5
+ require_relative "../codegen/explain"
6
+
7
+ module Ibex
8
+ # Dedicated command-line view for selected parser conflicts.
9
+ module CLIExplain
10
+ # @rbs!
11
+ # private def print_help: (OptionParser) -> Integer
12
+ # private def input_path: (Array[String]) -> String
13
+ # private def positive_counterexample_limit: (Integer, String) -> Integer
14
+ # private def normalize_grammar_path: (String) -> IR::Grammar
15
+
16
+ private
17
+
18
+ # @rbs (Array[String] arguments) -> Integer
19
+ def run_explain_command(arguments)
20
+ parser = explain_option_parser
21
+ remaining = parser.parse(arguments)
22
+ return print_help(parser) if @options[:help]
23
+
24
+ path = input_path(remaining)
25
+ grammar = normalize_grammar_path(path)
26
+ automaton = LALR::Builder.new(
27
+ grammar, algorithm: @options[:algorithm] || :lalr, entry_isolation: @options[:entry_isolation] == true
28
+ ).build
29
+ explanation = Codegen::Explain.new(
30
+ automaton, state: @options[:explain_state], token: @options[:explain_token],
31
+ max_tokens: @options.fetch(:counterexample_max_tokens),
32
+ max_configurations: @options.fetch(:counterexample_max_configurations)
33
+ )
34
+ output = @options[:explain_format] == "json" ? JSON.pretty_generate(explanation.to_h) : explanation.render_text
35
+ @stdout.puts(output)
36
+ 0
37
+ end
38
+
39
+ # @rbs () -> OptionParser
40
+ def explain_option_parser
41
+ OptionParser.new do |options|
42
+ options.banner = "Usage: ibex explain [options] grammarfile"
43
+ options.on("--state=N", Integer, "select one automaton state") { |value| @options[:explain_state] = value }
44
+ options.on("--token=NAME", "select a grammar token name or exact display name") do |value|
45
+ @options[:explain_token] = value
46
+ end
47
+ options.on("--format=FORMAT", %w[text json], "text or json (default: text)") do |value|
48
+ @options[:explain_format] = value
49
+ end
50
+ options.on("--algorithm=NAME", %w[slr lalr ielr lr1], "parser construction algorithm") do |value|
51
+ @options[:algorithm] = value.to_sym
52
+ end
53
+ options.on("--entry-isolation", "build independent state sets for each start symbol") do
54
+ @options[:entry_isolation] = true
55
+ end
56
+ options.on("--mode=MODE", %w[default extended], "grammar mode") { |value| @options[:mode] = value.to_sym }
57
+ add_explain_search_options(options)
58
+ options.on("--help", "show help") { @options[:help] = true }
59
+ end
60
+ end
61
+
62
+ # @rbs (OptionParser options) -> void
63
+ def add_explain_search_options(options)
64
+ options.on("--counterexample-max-tokens=N", Integer, "maximum counterexample search token budget") do |value|
65
+ @options[:counterexample_max_tokens] = positive_counterexample_limit(value, "--counterexample-max-tokens")
66
+ end
67
+ options.on(
68
+ "--counterexample-max-configurations=N", Integer, "maximum counterexample search configuration budget"
69
+ ) do |value|
70
+ @options[:counterexample_max_configurations] = positive_counterexample_limit(
71
+ value, "--counterexample-max-configurations"
72
+ )
73
+ end
74
+ end
75
+ end
76
+ end