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,13 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require_relative "table_simulation/step"
5
+ require_relative "table_simulation/result"
6
+ require_relative "table_simulation/simulator"
7
+ require_relative "table_simulation/text"
8
+
9
+ module Ibex
10
+ # Safe LR table simulation over validated Automaton IR.
11
+ module TableSimulation
12
+ end
13
+ end
data/lib/ibex/tables.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "ibex/tables/compact"
4
+ require "ibex/tables/compact_actions"
5
+ require "ibex/tables/compact_productions"
6
+
3
7
  module Ibex
4
8
  # Parser table construction and row-displacement compression.
5
9
  module Tables
@@ -9,75 +13,6 @@ module Ibex
9
13
 
10
14
  TableSet = Struct.new(:actions, :gotos, :default_actions, keyword_init: true)
11
15
 
12
- # Sparse table represented by per-row offsets and ownership checks.
13
- class Compact
14
- attr_reader :offsets #: Array[Integer]
15
- attr_reader :values #: Array[untyped]
16
- attr_reader :checks #: Array[Integer?]
17
- attr_reader :row_count #: Integer
18
-
19
- class << self
20
- # @rbs (Array[Hash[Integer, untyped]] rows) -> Compact
21
- def build(rows)
22
- offsets = Array.new(rows.length, 0)
23
- values = [] #: Array[untyped]
24
- checks = [] #: Array[Integer?]
25
- rows.each_index.sort_by { |row| [-rows[row].length, row] }.each do |row|
26
- offset = find_offset(rows[row].keys, checks)
27
- offsets[row] = offset
28
- rows[row].each do |column, value|
29
- index = offset + column
30
- values[index] = value
31
- checks[index] = row
32
- end
33
- end
34
- new(offsets: offsets, values: values, checks: checks, row_count: rows.length)
35
- end
36
-
37
- private
38
-
39
- # @rbs (Array[Integer] columns, Array[Integer?] checks) -> Integer
40
- def find_offset(columns, checks)
41
- offset = 0
42
- offset += 1 while columns.any? { |column| checks[offset + column] }
43
- offset
44
- end
45
- end
46
-
47
- # @rbs (offsets: Array[Integer], values: Array[untyped], checks: Array[Integer?], row_count: Integer) -> void
48
- def initialize(offsets:, values:, checks:, row_count:)
49
- @offsets = offsets.freeze
50
- @values = values.freeze
51
- @checks = checks.freeze
52
- @row_count = row_count
53
- freeze
54
- end
55
-
56
- # @rbs (Integer row, Integer column) -> untyped
57
- def lookup(row, column)
58
- return nil unless row.between?(0, @row_count - 1)
59
- return nil if column.negative?
60
-
61
- index = @offsets.fetch(row) + column
62
- return nil unless index.between?(0, @checks.length - 1)
63
-
64
- @checks[index] == row ? @values[index] : nil
65
- end
66
-
67
- # @rbs (Integer row) -> Hash[Integer, untyped]
68
- def row(row)
69
- return {} unless row.between?(0, @row_count - 1)
70
-
71
- result = {} #: Hash[Integer, untyped]
72
- @checks.each_index do |index|
73
- next unless @checks[index] == row
74
-
75
- result[index - @offsets[row]] = @values[index]
76
- end
77
- result
78
- end
79
- end
80
-
81
16
  # @rbs (IR::Automaton automaton, ?format: Symbol | String) -> TableSet
82
17
  def build(automaton, format: :compact)
83
18
  action_rows = automaton.states.map do |state|
@@ -95,7 +30,11 @@ module Ibex
95
30
  end
96
31
  raise ArgumentError, "unknown table format #{format.inspect}" unless format.to_sym == :compact
97
32
 
98
- TableSet.new(actions: Compact.build(action_rows), gotos: Compact.build(goto_rows), default_actions: defaults)
33
+ TableSet.new(
34
+ actions: CompactActions.build(action_rows),
35
+ gotos: Compact.build(goto_rows),
36
+ default_actions: defaults
37
+ )
99
38
  end
100
39
  module_function :build
101
40
 
data/lib/ibex/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Ibex generates and runs Pure Ruby LR parsers.
4
4
  module Ibex
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ module Ibex
5
+ module Watch
6
+ # Polls source fingerprints, debounces changes, and publishes stable builds.
7
+ class Runner
8
+ DEFAULT_INTERVAL = 0.25 #: Float
9
+ DEFAULT_DEBOUNCE = 0.05 #: Float
10
+
11
+ # rubocop:disable Layout/LineLength
12
+ # @rbs (paths: Array[String], build: ^() -> untyped, publish: ^(untyped, SourceSnapshot, ^() -> bool) -> void, failure_paths: ^() -> Array[String], stderr: untyped, clock: ^() -> Float, sleeper: ^(Float) -> void, iteration_hook: ^(Symbol, Integer, Array[String]) -> (Integer | Symbol | nil), ?interval: Float, ?debounce: Float) -> void
13
+ def initialize(paths:, build:, publish:, failure_paths:, stderr:, clock:, sleeper:, iteration_hook:,
14
+ interval: DEFAULT_INTERVAL, debounce: DEFAULT_DEBOUNCE)
15
+ @fixed_paths = normalize_paths(paths)
16
+ @successful_paths = [] #: Array[String]
17
+ @paths = @fixed_paths
18
+ @build = build
19
+ @publish = publish
20
+ @failure_paths = failure_paths
21
+ @stderr = stderr
22
+ @clock = clock
23
+ @sleeper = sleeper
24
+ @iteration_hook = iteration_hook
25
+ @interval = interval
26
+ @debounce = debounce
27
+ @signal_status = nil #: Integer?
28
+ @requested_status = nil #: Integer?
29
+ @last_failure_message = nil #: String?
30
+ @last_failure_snapshot = nil #: SourceSnapshot?
31
+ @iteration = 0
32
+ end
33
+ # rubocop:enable Layout/LineLength
34
+
35
+ # @rbs () -> Integer
36
+ def run
37
+ with_signal_handlers do
38
+ snapshot = SourceSnapshot.new(@paths)
39
+ loop do
40
+ status = stop_status(:before_build)
41
+ return status if status
42
+
43
+ snapshot, retry_build = build_once(snapshot)
44
+ status = stop_status(:after_build)
45
+ return status if status
46
+
47
+ if retry_build
48
+ snapshot = debounce(snapshot)
49
+ status = @signal_status || @requested_status
50
+ return status if status
51
+
52
+ next
53
+ end
54
+
55
+ snapshot = wait_for_change(snapshot)
56
+ status = @signal_status || @requested_status
57
+ return status if status
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ # @rbs (SourceSnapshot before) -> [SourceSnapshot, bool]
65
+ def build_once(before)
66
+ @iteration += 1
67
+ result = @build.call
68
+ @paths = normalize_paths(@fixed_paths + result.source_paths + result.attempted_paths)
69
+ rendered = SourceSnapshot.new(@paths)
70
+ return [rendered, true] unless rendered.unchanged_since?(before)
71
+ return [rendered, false] if @signal_status
72
+
73
+ @publish.call(result, rendered, -> { @signal_status.nil? })
74
+ @last_failure_message = nil
75
+ @last_failure_snapshot = nil
76
+ @successful_paths = @paths - @fixed_paths
77
+ published = SourceSnapshot.new(@paths)
78
+ [published, published != rendered]
79
+ rescue GenerationTransaction::SourceChanged
80
+ [SourceSnapshot.new(@paths), true]
81
+ rescue GenerationTransaction::Error => e
82
+ raise if e.rollback_failed
83
+
84
+ failed_build(before, e)
85
+ rescue Ibex::Error, SystemCallError, SystemStackError => e
86
+ failed_build(before, e)
87
+ end
88
+
89
+ # @rbs (SourceSnapshot snapshot) -> SourceSnapshot
90
+ def wait_for_change(snapshot)
91
+ loop do
92
+ @sleeper.call(@interval)
93
+ return snapshot if @signal_status
94
+
95
+ status = stop_status(:poll)
96
+ return snapshot if status
97
+
98
+ changed = SourceSnapshot.new(@paths)
99
+ next if changed == snapshot
100
+
101
+ return debounce(changed)
102
+ end
103
+ end
104
+
105
+ # @rbs (SourceSnapshot changed) -> SourceSnapshot
106
+ def debounce(changed)
107
+ loop do
108
+ @clock.call
109
+ @sleeper.call(@debounce)
110
+ return changed if @signal_status
111
+
112
+ settled = SourceSnapshot.new(@paths)
113
+ return settled if settled == changed
114
+
115
+ changed = settled
116
+ end
117
+ end
118
+
119
+ # @rbs (Exception error) -> void
120
+ def report_failure(error)
121
+ @stderr.puts(error.message)
122
+ end
123
+
124
+ # @rbs (SourceSnapshot before, Exception error) -> [SourceSnapshot, bool]
125
+ def failed_build(before, error)
126
+ previous_paths = @paths
127
+ @paths = normalize_paths(@fixed_paths + @successful_paths + @failure_paths.call)
128
+ current = SourceSnapshot.new(@paths)
129
+ retry_build = @paths != previous_paths || !current.unchanged_since?(before)
130
+ report_failure_once(error, current)
131
+ [current, retry_build]
132
+ end
133
+
134
+ # @rbs (Exception error, SourceSnapshot snapshot) -> void
135
+ def report_failure_once(error, snapshot)
136
+ duplicate = @last_failure_message == error.message && @last_failure_snapshot == snapshot
137
+ report_failure(error) unless duplicate
138
+ @last_failure_message = error.message
139
+ @last_failure_snapshot = snapshot
140
+ end
141
+
142
+ # @rbs (Symbol event) -> Integer?
143
+ def stop_status(event)
144
+ return @signal_status if @signal_status
145
+
146
+ result = @iteration_hook.call(event, @iteration, @paths.dup)
147
+ @requested_status = result if result.is_a?(Integer)
148
+ @requested_status = 0 if result == :stop
149
+ return @requested_status if @requested_status
150
+
151
+ nil
152
+ end
153
+
154
+ # @rbs (Array[String] paths) -> Array[String]
155
+ def normalize_paths(paths)
156
+ paths.map { |path| File.expand_path(path) }.uniq.sort
157
+ end
158
+
159
+ # @rbs () { () -> Integer } -> Integer
160
+ def with_signal_handlers
161
+ previous = {} #: Hash[String, untyped]
162
+ if Thread.current == Thread.main
163
+ previous["INT"] = Signal.trap("INT") { @signal_status = 130 }
164
+ previous["TERM"] = Signal.trap("TERM") { @signal_status = 143 }
165
+ end
166
+ yield
167
+ ensure
168
+ previous&.each { |signal, handler| Signal.trap(signal, handler) }
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require "digest"
5
+
6
+ module Ibex
7
+ module Watch
8
+ # Stable metadata and content fingerprints for watched source paths.
9
+ class SourceSnapshot
10
+ attr_reader :paths #: Array[String]
11
+
12
+ # @rbs (Array[String] paths) -> void
13
+ def initialize(paths)
14
+ @paths = paths.map { |path| File.expand_path(path) }.uniq.sort.freeze
15
+ @entries = @paths.to_h { |path| [path, fingerprint(path)] }.freeze #: Hash[String, Hash[Symbol, untyped]]
16
+ freeze
17
+ end
18
+
19
+ # @rbs (SourceSnapshot other) -> bool
20
+ def ==(other)
21
+ @entries == other.__send__(:entries)
22
+ end
23
+
24
+ # Every path in this snapshot must have had the same value in the older snapshot.
25
+ # @rbs (SourceSnapshot older) -> bool
26
+ def unchanged_since?(older)
27
+ @paths.all? do |path|
28
+ older.__send__(:entry, path) == @entries.fetch(path)
29
+ end
30
+ end
31
+
32
+ protected
33
+
34
+ attr_reader :entries #: Hash[String, Hash[Symbol, untyped]]
35
+
36
+ # @rbs (String path) -> Hash[Symbol, untyped]?
37
+ def entry(path)
38
+ @entries[path]
39
+ end
40
+
41
+ private
42
+
43
+ # @rbs (String path) -> Hash[Symbol, untyped]
44
+ def fingerprint(path)
45
+ stat = File.lstat(path)
46
+ value = stat_signature(stat)
47
+ if stat.symlink?
48
+ value[:readlink] = File.readlink(path)
49
+ add_resolved_target(value, path)
50
+ else
51
+ value[:resolved_path] = File.realpath(path)
52
+ value[:sha256] = Digest::SHA256.file(path).hexdigest if stat.file?
53
+ end
54
+ value
55
+ rescue SystemCallError => e
56
+ { kind: :error, error: e.class.name, errno: e.respond_to?(:errno) ? e.errno : nil }
57
+ end
58
+
59
+ # @rbs (File::Stat stat) -> Hash[Symbol, untyped]
60
+ def stat_signature(stat)
61
+ {
62
+ kind: file_kind(stat), dev: stat.dev, ino: stat.ino, size: stat.size,
63
+ mtime_ns: nanoseconds(stat.mtime), ctime_ns: nanoseconds(stat.ctime)
64
+ }
65
+ end
66
+
67
+ # @rbs (File::Stat stat) -> Symbol
68
+ def file_kind(stat)
69
+ return :file if stat.file?
70
+ return :directory if stat.directory?
71
+ return :symlink if stat.symlink?
72
+
73
+ :other
74
+ end
75
+
76
+ # @rbs (Time time) -> Integer
77
+ def nanoseconds(time)
78
+ (time.to_i * 1_000_000_000) + time.nsec
79
+ end
80
+
81
+ # @rbs (Hash[Symbol, untyped] value, String path) -> void
82
+ def add_resolved_target(value, path)
83
+ target = File.realpath(path)
84
+ stat = File.stat(target)
85
+ value[:resolved_path] = target
86
+ value[:resolved] = stat_signature(stat)
87
+ value[:resolved][:sha256] = Digest::SHA256.file(target).hexdigest if stat.file?
88
+ rescue SystemCallError => e
89
+ value[:resolved] = { kind: :error, error: e.class.name, errno: e.respond_to?(:errno) ? e.errno : nil }
90
+ end
91
+ end
92
+ end
93
+ end
data/lib/ibex/watch.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require_relative "watch/source_snapshot"
5
+ require_relative "watch/runner"
6
+
7
+ module Ibex
8
+ # Portable polling support for repeatable parser generation.
9
+ module Watch
10
+ end
11
+ end
data/lib/ibex.rb CHANGED
@@ -3,21 +3,45 @@
3
3
 
4
4
  require_relative "ibex/version"
5
5
  require_relative "ibex/error"
6
+ require_relative "ibex/location"
7
+ require_relative "ibex/error_messages"
8
+ require_relative "ibex/artifact_set"
9
+ require_relative "ibex/generation_input"
10
+ require_relative "ibex/generation_manifest"
11
+ require_relative "ibex/generation_transaction"
12
+ require_relative "ibex/watch"
6
13
  require_relative "ibex/tables"
7
- require_relative "ibex/runtime"
14
+ require "ibex/runtime"
15
+ require_relative "ibex/coverage"
16
+ require_relative "ibex/table_simulation"
8
17
  require_relative "ibex/frontend"
9
18
  require_relative "ibex/ir"
10
19
  require_relative "ibex/normalize"
11
20
  require_relative "ibex/analysis"
21
+ require_relative "ibex/samples"
22
+ require_relative "ibex/grammar_tests"
23
+ require_relative "ibex/racc_migration"
12
24
  require_relative "ibex/lalr"
13
25
  require_relative "ibex/codegen/symbol_labels"
14
26
  require_relative "ibex/codegen/report"
27
+ require_relative "ibex/codegen/explain"
28
+ require_relative "ibex/codegen/ambiguity"
29
+ require_relative "ibex/codegen/action_locations"
30
+ require_relative "ibex/codegen/generated_action_abi"
31
+ require_relative "ibex/codegen/action_method_source"
32
+ require_relative "ibex/codegen/cst_metadata"
33
+ require_relative "ibex/codegen/ruby_actions"
15
34
  require_relative "ibex/codegen/ruby"
16
35
  require_relative "ibex/codegen/rbs"
36
+ require_relative "ibex/codegen/action_source"
17
37
  require_relative "ibex/codegen/dot"
38
+ require_relative "ibex/codegen/mermaid"
18
39
  require_relative "ibex/codegen/html"
40
+ require_relative "ibex/codegen/railroad"
41
+ require_relative "ibex/codegen/documentation"
19
42
 
20
43
  # Ibex generates and runs Pure Ruby LR parsers.
21
44
  module Ibex
22
45
  ParseError = Runtime::ParseError #: singleton(Runtime::ParseError)
46
+ ResourceLimitError = Runtime::ResourceLimitError #: singleton(Runtime::ResourceLimitError)
23
47
  end