ibex 0.2.0 → 0.4.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 (461) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +100 -272
  3. data/docs/architecture.md +187 -35
  4. data/docs/bison-import.md +103 -0
  5. data/docs/comparison-policy.md +127 -0
  6. data/docs/configuration-model.md +59 -0
  7. data/docs/configuration-report.md +28 -0
  8. data/docs/conflict-explanation-reviews/v1/records/README.md +28 -0
  9. data/docs/conflict-explanation-study.md +62 -0
  10. data/docs/construction-profiling.md +157 -0
  11. data/docs/cst-migration.md +3 -4
  12. data/docs/cst.md +24 -0
  13. data/docs/decisions/0000-template.md +24 -0
  14. data/docs/decisions/0001-separate-ir-pipeline.md +34 -0
  15. data/docs/decisions/0002-opaque-user-code-boundary.md +32 -0
  16. data/docs/decisions/0003-self-hosted-grammar-frontend.md +32 -0
  17. data/docs/decisions/0004-shared-semantic-and-lossless-source-model.md +33 -0
  18. data/docs/decisions/0005-contained-grammar-composition.md +34 -0
  19. data/docs/decisions/0006-bounded-structural-grammar-lowering.md +32 -0
  20. data/docs/decisions/0007-shared-parser-construction-pipeline.md +33 -0
  21. data/docs/decisions/0008-versioned-runtime-package-boundary.md +36 -0
  22. data/docs/decisions/0009-isolated-parser-sessions.md +34 -0
  23. data/docs/decisions/0010-committed-runtime-observation.md +34 -0
  24. data/docs/decisions/0011-versioned-semantic-action-boundary.md +37 -0
  25. data/docs/decisions/0012-bounded-nonexecuting-analysis.md +37 -0
  26. data/docs/decisions/0013-transactional-generation-publication.md +37 -0
  27. data/docs/decisions/0014-versioned-generated-lexer.md +35 -0
  28. data/docs/decisions/0015-worker-isolated-browser-analysis.md +32 -0
  29. data/docs/decisions/0016-red-green-concrete-syntax.md +34 -0
  30. data/docs/decisions/0017-persistent-syntax-artifacts.md +35 -0
  31. data/docs/decisions/0018-conservative-incremental-syntax-reuse.md +38 -0
  32. data/docs/decisions/0019-runtime-syntax-session-boundary.md +51 -0
  33. data/docs/decisions/0020-grammar-ir-parser-contract.md +65 -0
  34. data/docs/decisions/0021-data-only-parser-table-sidecar.md +50 -0
  35. data/docs/decisions/0022-manifest-bound-verification-report.md +77 -0
  36. data/docs/decisions/0023-syntax-only-repair-results.md +48 -0
  37. data/docs/decisions/0024-direct-ielr-construction.md +42 -0
  38. data/docs/decisions/README.md +74 -0
  39. data/docs/declarative-configuration.md +274 -0
  40. data/docs/development.md +196 -2
  41. data/docs/direct-ielr-decision.md +120 -0
  42. data/docs/direct-multi-entry-decision.md +82 -0
  43. data/docs/editor-setup.md +2 -1
  44. data/docs/error-ux-review-rubric-v1.md +117 -0
  45. data/docs/error-ux-reviews/v1/records/README.md +22 -0
  46. data/docs/error-ux-round2-review-status-v1.json +27 -0
  47. data/docs/error-ux-round2-reviews/v1/records/README.md +30 -0
  48. data/docs/error-ux-round2-v1.json +1617 -0
  49. data/docs/error-ux-round2.md +111 -0
  50. data/docs/error-ux.md +54 -0
  51. data/docs/getting-started.md +80 -0
  52. data/docs/grammar-reference.md +184 -13
  53. data/docs/ielr-design.md +43 -0
  54. data/docs/ielr.md +92 -0
  55. data/docs/impact.md +101 -0
  56. data/docs/ja/bison-import.md +51 -0
  57. data/docs/ja/stable-api.md +53 -0
  58. data/docs/lexer-construction-profile.md +109 -0
  59. data/docs/lexer-migration.md +5 -0
  60. data/docs/maturity.md +129 -0
  61. data/docs/project-site-strategy.md +54 -0
  62. data/docs/racc-migration-evidence.md +45 -0
  63. data/docs/racc-migration.md +11 -0
  64. data/docs/release-readiness.md +126 -68
  65. data/docs/repair-semantics.md +123 -0
  66. data/docs/runtime-abi-evolution.md +310 -0
  67. data/docs/stability.md +145 -34
  68. data/docs/status.md +43 -0
  69. data/docs/syntax-sessions.md +183 -0
  70. data/docs/table-artifact.md +125 -0
  71. data/docs/test-interactions.md +219 -0
  72. data/docs/verification-report.md +137 -0
  73. data/docs/verifier-trust-boundary.md +199 -0
  74. data/docs/workloads.md +132 -0
  75. data/lib/ibex/analysis/digraph.rb +128 -0
  76. data/lib/ibex/analysis/sets.rb +14 -0
  77. data/lib/ibex/analysis.rb +1 -0
  78. data/lib/ibex/bison_import/importer.rb +516 -0
  79. data/lib/ibex/bison_import/tokenizer.rb +260 -0
  80. data/lib/ibex/bison_import.rb +200 -0
  81. data/lib/ibex/bounded_subprocess.rb +171 -0
  82. data/lib/ibex/cli/ambiguity.rb +14 -5
  83. data/lib/ibex/cli/analysis.rb +134 -0
  84. data/lib/ibex/cli/bison_import.rb +121 -0
  85. data/lib/ibex/cli/config.rb +128 -0
  86. data/lib/ibex/cli/diagnostics.rb +31 -11
  87. data/lib/ibex/cli/documentation.rb +11 -8
  88. data/lib/ibex/cli/equiv.rb +169 -0
  89. data/lib/ibex/cli/error_messages.rb +11 -4
  90. data/lib/ibex/cli/explain.rb +14 -5
  91. data/lib/ibex/cli/fix.rb +203 -0
  92. data/lib/ibex/cli/formatting.rb +11 -10
  93. data/lib/ibex/cli/fuzz.rb +200 -0
  94. data/lib/ibex/cli/fuzz_regressions.rb +145 -0
  95. data/lib/ibex/cli/generation_artifacts.rb +53 -2
  96. data/lib/ibex/cli/generation_error_messages.rb +1 -1
  97. data/lib/ibex/cli/grammar_tests.rb +32 -14
  98. data/lib/ibex/cli/impact.rb +393 -0
  99. data/lib/ibex/cli/ir_tools.rb +5 -61
  100. data/lib/ibex/cli/outputs.rb +60 -33
  101. data/lib/ibex/cli/reduce.rb +202 -0
  102. data/lib/ibex/cli/reduce_reporting.rb +71 -0
  103. data/lib/ibex/cli/samples.rb +49 -23
  104. data/lib/ibex/cli/verify.rb +116 -0
  105. data/lib/ibex/cli/watch.rb +6 -5
  106. data/lib/ibex/cli.rb +362 -56
  107. data/lib/ibex/codegen/action_locations.rb +1 -1
  108. data/lib/ibex/codegen/action_method_source.rb +5 -6
  109. data/lib/ibex/codegen/action_source.rb +3 -2
  110. data/lib/ibex/codegen/ambiguity.rb +5 -4
  111. data/lib/ibex/codegen/explain.rb +123 -55
  112. data/lib/ibex/codegen/generated_action_abi.rb +10 -5
  113. data/lib/ibex/codegen/rbs.rb +15 -7
  114. data/lib/ibex/codegen/report.rb +25 -13
  115. data/lib/ibex/codegen/ruby.rb +28 -64
  116. data/lib/ibex/codegen/ruby_actions.rb +9 -6
  117. data/lib/ibex/codegen/ruby_syntax.rb +15 -9
  118. data/lib/ibex/configuration/analysis_grammar.rb +35 -0
  119. data/lib/ibex/configuration/explanation.rb +421 -0
  120. data/lib/ibex/configuration/inspector.rb +232 -0
  121. data/lib/ibex/configuration.rb +580 -0
  122. data/lib/ibex/coverage/collector.rb +21 -11
  123. data/lib/ibex/coverage/event_stream.rb +13 -7
  124. data/lib/ibex/coverage/report.rb +26 -18
  125. data/lib/ibex/coverage/runtime_event_validator.rb +30 -21
  126. data/lib/ibex/delta_reducer.rb +99 -0
  127. data/lib/ibex/diff.rb +141 -0
  128. data/lib/ibex/equiv/machine.rb +135 -0
  129. data/lib/ibex/equiv.rb +373 -0
  130. data/lib/ibex/fix.rb +557 -0
  131. data/lib/ibex/frontend/ast.rb +22 -2
  132. data/lib/ibex/frontend/bootstrap_parser.rb +6 -13
  133. data/lib/ibex/frontend/diagnostic.rb +1 -1
  134. data/lib/ibex/frontend/formatter.rb +72 -26
  135. data/lib/ibex/frontend/generated_parser.rb +147 -117
  136. data/lib/ibex/frontend/generated_parser_base.rb +7 -3
  137. data/lib/ibex/frontend/generated_parser_includes.rb +1 -11
  138. data/lib/ibex/frontend/generation.rb +1 -1
  139. data/lib/ibex/frontend/parser/declarations.rb +17 -2
  140. data/lib/ibex/frontend/parser_configuration_support.rb +56 -0
  141. data/lib/ibex/frontend/regenerator.rb +1 -0
  142. data/lib/ibex/frontend/resolution.rb +2 -1
  143. data/lib/ibex/frontend/resolver.rb +1 -1
  144. data/lib/ibex/frontend/rule_documentation.rb +2 -1
  145. data/lib/ibex/frontend/source_cursor.rb +2 -2
  146. data/lib/ibex/frontend/source_span.rb +9 -1
  147. data/lib/ibex/frontend/token_adapter/declaration_state.rb +38 -6
  148. data/lib/ibex/frontend/token_adapter.rb +10 -0
  149. data/lib/ibex/frontend.rb +1 -0
  150. data/lib/ibex/fuzz.rb +219 -0
  151. data/lib/ibex/generation_input.rb +1 -1
  152. data/lib/ibex/generation_manifest.rb +36 -25
  153. data/lib/ibex/generation_transaction.rb +1 -1
  154. data/lib/ibex/generation_transaction_recovery.rb +4 -4
  155. data/lib/ibex/generation_transaction_validation.rb +2 -2
  156. data/lib/ibex/grammar_tests.rb +1 -1
  157. data/lib/ibex/impact/action_impact.rb +148 -0
  158. data/lib/ibex/impact/automaton_impact.rb +57 -0
  159. data/lib/ibex/impact/coverage_impact.rb +53 -0
  160. data/lib/ibex/impact/graph.rb +132 -0
  161. data/lib/ibex/impact/propagation.rb +147 -0
  162. data/lib/ibex/impact/report.rb +273 -0
  163. data/lib/ibex/impact/seeds.rb +69 -0
  164. data/lib/ibex/impact/severity.rb +139 -0
  165. data/lib/ibex/impact.rb +16 -0
  166. data/lib/ibex/ir/automaton_ir.rb +61 -19
  167. data/lib/ibex/ir/grammar_ir.rb +76 -45
  168. data/lib/ibex/ir/lexer_ir.rb +5 -5
  169. data/lib/ibex/ir/parser_contract.rb +135 -0
  170. data/lib/ibex/ir/serialize.rb +203 -76
  171. data/lib/ibex/ir/validator/automaton.rb +64 -34
  172. data/lib/ibex/ir/validator/base.rb +51 -33
  173. data/lib/ibex/ir/validator/grammar.rb +113 -83
  174. data/lib/ibex/ir/validator/lexer.rb +2 -2
  175. data/lib/ibex/ir/validator.rb +2 -1
  176. data/lib/ibex/ir.rb +16 -3
  177. data/lib/ibex/lalr/build_metrics.rb +50 -2
  178. data/lib/ibex/lalr/builder.rb +191 -56
  179. data/lib/ibex/lalr/conflict_search.rb +15 -4
  180. data/lib/ibex/lalr/counterexample.rb +19 -14
  181. data/lib/ibex/lalr/direct_lookaheads.rb +110 -57
  182. data/lib/ibex/lalr/goto_follows.rb +229 -0
  183. data/lib/ibex/lalr/ielr/annotator.rb +214 -0
  184. data/lib/ibex/lalr/ielr/bits.rb +28 -0
  185. data/lib/ibex/lalr/ielr/inadequacy.rb +47 -0
  186. data/lib/ibex/lalr/ielr/item_lookaheads.rb +78 -0
  187. data/lib/ibex/lalr/ielr/pipeline.rb +75 -0
  188. data/lib/ibex/lalr/ielr/split_stability.rb +78 -0
  189. data/lib/ibex/lalr/ielr/split_state.rb +20 -0
  190. data/lib/ibex/lalr/ielr/state_splitter.rb +258 -0
  191. data/lib/ibex/lalr/ielr_partition.rb +22 -8
  192. data/lib/ibex/lalr/inadequacy_report.rb +50 -0
  193. data/lib/ibex/lalr/lookahead_propagation.rb +111 -0
  194. data/lib/ibex/lalr/lr0_collection.rb +121 -0
  195. data/lib/ibex/lalr/unreachable_states.rb +80 -0
  196. data/lib/ibex/lalr.rb +52 -1
  197. data/lib/ibex/location.rb +3 -3
  198. data/lib/ibex/lsp/document_handlers.rb +9 -7
  199. data/lib/ibex/lsp/initialization_handlers.rb +9 -7
  200. data/lib/ibex/lsp/navigation_handlers.rb +25 -11
  201. data/lib/ibex/lsp/parser_configuration_assistance.rb +149 -0
  202. data/lib/ibex/lsp/position_codec.rb +6 -2
  203. data/lib/ibex/lsp/request_handlers.rb +3 -2
  204. data/lib/ibex/lsp/request_support.rb +14 -7
  205. data/lib/ibex/lsp/server.rb +13 -11
  206. data/lib/ibex/lsp/symbol_index.rb +13 -13
  207. data/lib/ibex/lsp/symbol_index_builder.rb +30 -20
  208. data/lib/ibex/lsp/symbol_occurrence.rb +8 -2
  209. data/lib/ibex/lsp/transport.rb +13 -3
  210. data/lib/ibex/lsp/workspace.rb +5 -4
  211. data/lib/ibex/lsp/workspace_analyzer.rb +1 -1
  212. data/lib/ibex/lsp.rb +1 -0
  213. data/lib/ibex/messages/en.yml +28 -0
  214. data/lib/ibex/messages/ja.yml +28 -0
  215. data/lib/ibex/messages.rb +68 -0
  216. data/lib/ibex/metrics.rb +175 -0
  217. data/lib/ibex/normalize/declarations.rb +2 -0
  218. data/lib/ibex/normalize/diagnostics.rb +63 -38
  219. data/lib/ibex/normalize/expander.rb +5 -4
  220. data/lib/ibex/normalize/expression.rb +8 -6
  221. data/lib/ibex/normalize/grammar_builder.rb +26 -0
  222. data/lib/ibex/normalize/inline_expansion.rb +100 -49
  223. data/lib/ibex/normalize/lexer.rb +3 -3
  224. data/lib/ibex/normalize/parameter_ebnf_lowering.rb +11 -10
  225. data/lib/ibex/normalize/parameter_lowering.rb +40 -23
  226. data/lib/ibex/normalize/parameters.rb +31 -4
  227. data/lib/ibex/normalize/parser_configuration.rb +70 -0
  228. data/lib/ibex/normalize.rb +10 -20
  229. data/lib/ibex/racc_migration/report.rb +6 -3
  230. data/lib/ibex/rake_task.rb +1 -1
  231. data/lib/ibex/samples.rb +43 -13
  232. data/lib/ibex/table_artifact/builder.rb +266 -0
  233. data/lib/ibex/table_artifact/cst_projection.rb +70 -0
  234. data/lib/ibex/table_artifact/document.rb +39 -0
  235. data/lib/ibex/table_artifact/executor.rb +187 -0
  236. data/lib/ibex/table_artifact/serializer.rb +57 -0
  237. data/lib/ibex/table_artifact/validator/metadata.rb +179 -0
  238. data/lib/ibex/table_artifact/validator/support.rb +86 -0
  239. data/lib/ibex/table_artifact/validator/tables.rb +238 -0
  240. data/lib/ibex/table_artifact/validator.rb +253 -0
  241. data/lib/ibex/table_artifact.rb +88 -0
  242. data/lib/ibex/table_simulation/result.rb +6 -2
  243. data/lib/ibex/table_simulation/step.rb +3 -1
  244. data/lib/ibex/tables.rb +14 -0
  245. data/lib/ibex/verifiable_generation_bundle.rb +86 -0
  246. data/lib/ibex/verification_report/builder.rb +159 -0
  247. data/lib/ibex/verification_report/canonical_ir.rb +123 -0
  248. data/lib/ibex/verification_report/logical_path.rb +68 -0
  249. data/lib/ibex/verification_report/validator.rb +329 -0
  250. data/lib/ibex/verification_report.rb +69 -0
  251. data/lib/ibex/verify/action_correspondence.rb +138 -0
  252. data/lib/ibex/verify/language_witness.rb +295 -0
  253. data/lib/ibex/verify/reference_collection.rb +190 -0
  254. data/lib/ibex/verify/result.rb +73 -0
  255. data/lib/ibex/verify/verifier.rb +598 -0
  256. data/lib/ibex/verify.rb +15 -0
  257. data/lib/ibex/version.rb +1 -1
  258. data/lib/ibex/watch/runner.rb +10 -1
  259. data/lib/ibex/watch/source_snapshot.rb +13 -8
  260. data/lib/ibex.rb +11 -0
  261. data/schema/{automaton-ir-v1.schema.json → automaton-ir-definitions.schema.json} +6 -6
  262. data/schema/{automaton-ir-v2.schema.json → automaton-ir.schema.json} +14 -7
  263. data/schema/bison-import-v1.schema.json +106 -0
  264. data/schema/conflict-explanation-review-v1.schema.json +196 -0
  265. data/schema/conflict-explanation-study-v1.schema.json +528 -0
  266. data/schema/construction-profile-v1.schema.json +779 -0
  267. data/schema/diff-v1.schema.json +41 -0
  268. data/schema/direct-ielr-decision-v1.schema.json +200 -0
  269. data/schema/equiv-v1.schema.json +64 -0
  270. data/schema/error-ux-review-v1.schema.json +609 -0
  271. data/schema/error-ux-round2-review-v1.schema.json +191 -0
  272. data/schema/error-ux-round2-v1.schema.json +519 -0
  273. data/schema/explain-v1.schema.json +63 -1
  274. data/schema/fix-v1.schema.json +64 -0
  275. data/schema/fix-v2.schema.json +66 -0
  276. data/schema/fix-v3.schema.json +101 -0
  277. data/schema/fuzz-regression-v1.schema.json +79 -0
  278. data/schema/fuzz-v1.schema.json +114 -0
  279. data/schema/{grammar-ir-v2.schema.json → grammar-ir-extensions.schema.json} +20 -65
  280. data/schema/{grammar-ir-v1.schema.json → grammar-ir-foundation.schema.json} +3 -3
  281. data/schema/grammar-ir.schema.json +271 -0
  282. data/schema/ielr-benchmark-v1.schema.json +85 -0
  283. data/schema/impact-v1.schema.json +208 -0
  284. data/schema/lexer-profile-v1.schema.json +491 -0
  285. data/schema/metrics-v1.schema.json +60 -0
  286. data/schema/reduce-v1.schema.json +22 -0
  287. data/schema/reduce-v2.schema.json +63 -0
  288. data/schema/table-artifact-v1.schema.json +377 -0
  289. data/schema/verification-report-v1.schema.json +222 -0
  290. data/schema/verify-v1.schema.json +42 -0
  291. data/sig/ibex/analysis/digraph.rbs +19 -0
  292. data/sig/ibex/analysis/sets.rbs +10 -0
  293. data/sig/ibex/bison_import/importer.rbs +140 -0
  294. data/sig/ibex/bison_import/tokenizer.rbs +91 -0
  295. data/sig/ibex/bison_import.rbs +95 -0
  296. data/sig/ibex/bounded_subprocess.rbs +76 -0
  297. data/sig/ibex/cli/ambiguity.rbs +6 -0
  298. data/sig/ibex/cli/analysis.rbs +43 -0
  299. data/sig/ibex/cli/bison_import.rbs +32 -0
  300. data/sig/ibex/cli/config.rbs +35 -0
  301. data/sig/ibex/cli/diagnostics.rbs +16 -3
  302. data/sig/ibex/cli/documentation.rbs +5 -1
  303. data/sig/ibex/cli/equiv.rbs +49 -0
  304. data/sig/ibex/cli/error_messages.rbs +6 -0
  305. data/sig/ibex/cli/explain.rbs +6 -0
  306. data/sig/ibex/cli/fix.rbs +53 -0
  307. data/sig/ibex/cli/formatting.rbs +5 -1
  308. data/sig/ibex/cli/fuzz.rbs +47 -0
  309. data/sig/ibex/cli/fuzz_regressions.rbs +40 -0
  310. data/sig/ibex/cli/generation_artifacts.rbs +21 -2
  311. data/sig/ibex/cli/generation_error_messages.rbs +2 -2
  312. data/sig/ibex/cli/grammar_tests.rbs +15 -3
  313. data/sig/ibex/cli/impact.rbs +95 -0
  314. data/sig/ibex/cli/ir_tools.rbs +7 -19
  315. data/sig/ibex/cli/outputs.rbs +9 -3
  316. data/sig/ibex/cli/reduce.rbs +60 -0
  317. data/sig/ibex/cli/reduce_reporting.rbs +27 -0
  318. data/sig/ibex/cli/samples.rbs +8 -0
  319. data/sig/ibex/cli/verify.rbs +28 -0
  320. data/sig/ibex/cli/watch.rbs +2 -2
  321. data/sig/ibex/cli.rbs +79 -5
  322. data/sig/ibex/codegen/action_method_source.rbs +4 -4
  323. data/sig/ibex/codegen/explain.rbs +45 -25
  324. data/sig/ibex/codegen/generated_action_abi.rbs +14 -10
  325. data/sig/ibex/codegen/rbs.rbs +12 -10
  326. data/sig/ibex/codegen/report.rbs +12 -12
  327. data/sig/ibex/codegen/ruby.rbs +18 -15
  328. data/sig/ibex/codegen/ruby_actions.rbs +6 -6
  329. data/sig/ibex/codegen/ruby_syntax.rbs +10 -8
  330. data/sig/ibex/configuration/analysis_grammar.rbs +13 -0
  331. data/sig/ibex/configuration/explanation.rbs +195 -0
  332. data/sig/ibex/configuration/inspector.rbs +53 -0
  333. data/sig/ibex/configuration.rbs +242 -0
  334. data/sig/ibex/coverage/collector.rbs +16 -14
  335. data/sig/ibex/coverage/event_stream.rbs +12 -10
  336. data/sig/ibex/coverage/report.rbs +20 -18
  337. data/sig/ibex/coverage/runtime_event_validator.rbs +38 -36
  338. data/sig/ibex/delta_reducer.rbs +38 -0
  339. data/sig/ibex/diff.rbs +47 -0
  340. data/sig/ibex/equiv/machine.rbs +54 -0
  341. data/sig/ibex/equiv.rbs +129 -0
  342. data/sig/ibex/fix.rbs +138 -0
  343. data/sig/ibex/frontend/ast.rbs +33 -7
  344. data/sig/ibex/frontend/bootstrap_parser.rbs +2 -0
  345. data/sig/ibex/frontend/diagnostic.rbs +2 -2
  346. data/sig/ibex/frontend/formatter.rbs +38 -30
  347. data/sig/ibex/frontend/generated_parser.rbs +87 -77
  348. data/sig/ibex/frontend/generated_parser_base.rbs +4 -2
  349. data/sig/ibex/frontend/parser/declarations.rbs +3 -0
  350. data/sig/ibex/frontend/parser_configuration_support.rbs +27 -0
  351. data/sig/ibex/frontend/resolution.rbs +3 -2
  352. data/sig/ibex/frontend/source_cursor.rbs +2 -2
  353. data/sig/ibex/frontend/source_span.rbs +5 -2
  354. data/sig/ibex/frontend/token_adapter/declaration_state.rbs +13 -1
  355. data/sig/ibex/frontend/token_adapter.rbs +6 -0
  356. data/sig/ibex/fuzz.rbs +71 -0
  357. data/sig/ibex/generation_input.rbs +2 -2
  358. data/sig/ibex/generation_manifest.rbs +35 -32
  359. data/sig/ibex/generation_transaction_recovery.rbs +2 -2
  360. data/sig/ibex/generation_transaction_validation.rbs +2 -2
  361. data/sig/ibex/grammar_tests.rbs +2 -2
  362. data/sig/ibex/impact/action_impact.rbs +58 -0
  363. data/sig/ibex/impact/automaton_impact.rbs +37 -0
  364. data/sig/ibex/impact/coverage_impact.rbs +28 -0
  365. data/sig/ibex/impact/graph.rbs +67 -0
  366. data/sig/ibex/impact/propagation.rbs +56 -0
  367. data/sig/ibex/impact/report.rbs +107 -0
  368. data/sig/ibex/impact/seeds.rbs +36 -0
  369. data/sig/ibex/impact/severity.rbs +55 -0
  370. data/sig/ibex/impact.rbs +6 -0
  371. data/sig/ibex/ir/automaton_ir.rbs +30 -11
  372. data/sig/ibex/ir/grammar_ir.rbs +41 -27
  373. data/sig/ibex/ir/lexer_ir.rbs +8 -8
  374. data/sig/ibex/ir/parser_contract.rbs +69 -0
  375. data/sig/ibex/ir/serialize.rbs +63 -28
  376. data/sig/ibex/ir/validator/automaton.rbs +47 -44
  377. data/sig/ibex/ir/validator/base.rbs +35 -31
  378. data/sig/ibex/ir/validator/grammar.rbs +78 -67
  379. data/sig/ibex/ir/validator/lexer.rbs +4 -4
  380. data/sig/ibex/ir.rbs +9 -3
  381. data/sig/ibex/lalr/build_metrics.rbs +42 -2
  382. data/sig/ibex/lalr/builder.rbs +75 -24
  383. data/sig/ibex/lalr/conflict_search.rbs +5 -2
  384. data/sig/ibex/lalr/counterexample.rbs +17 -14
  385. data/sig/ibex/lalr/direct_lookaheads.rbs +35 -28
  386. data/sig/ibex/lalr/goto_follows.rbs +89 -0
  387. data/sig/ibex/lalr/ielr/annotator.rbs +67 -0
  388. data/sig/ibex/lalr/ielr/bits.rbs +14 -0
  389. data/sig/ibex/lalr/ielr/inadequacy.rbs +24 -0
  390. data/sig/ibex/lalr/ielr/item_lookaheads.rbs +35 -0
  391. data/sig/ibex/lalr/ielr/pipeline.rbs +17 -0
  392. data/sig/ibex/lalr/ielr/split_stability.rbs +27 -0
  393. data/sig/ibex/lalr/ielr/split_state.rbs +14 -0
  394. data/sig/ibex/lalr/ielr/state_splitter.rbs +76 -0
  395. data/sig/ibex/lalr/ielr_partition.rbs +17 -5
  396. data/sig/ibex/lalr/inadequacy_report.rbs +21 -0
  397. data/sig/ibex/lalr/lookahead_propagation.rbs +38 -0
  398. data/sig/ibex/lalr/lr0_collection.rbs +50 -0
  399. data/sig/ibex/lalr/unreachable_states.rbs +25 -0
  400. data/sig/ibex/lalr.rbs +11 -1
  401. data/sig/ibex/location.rbs +6 -6
  402. data/sig/ibex/lsp/document_handlers.rbs +8 -8
  403. data/sig/ibex/lsp/initialization_handlers.rbs +12 -12
  404. data/sig/ibex/lsp/navigation_handlers.rbs +15 -12
  405. data/sig/ibex/lsp/parser_configuration_assistance.rbs +49 -0
  406. data/sig/ibex/lsp/position_codec.rbs +8 -4
  407. data/sig/ibex/lsp/request_handlers.rbs +4 -4
  408. data/sig/ibex/lsp/request_support.rbs +8 -8
  409. data/sig/ibex/lsp/server.rbs +16 -16
  410. data/sig/ibex/lsp/symbol_index.rbs +20 -21
  411. data/sig/ibex/lsp/symbol_index_builder.rbs +9 -8
  412. data/sig/ibex/lsp/symbol_occurrence.rbs +11 -5
  413. data/sig/ibex/lsp/transport.rbs +18 -6
  414. data/sig/ibex/lsp/workspace.rbs +3 -2
  415. data/sig/ibex/lsp/workspace_analyzer.rbs +1 -1
  416. data/sig/ibex/messages.rbs +26 -0
  417. data/sig/ibex/metrics.rbs +50 -0
  418. data/sig/ibex/normalize/diagnostics.rbs +4 -4
  419. data/sig/ibex/normalize/expander.rbs +2 -2
  420. data/sig/ibex/normalize/expression.rbs +10 -8
  421. data/sig/ibex/normalize/grammar_builder.rbs +11 -0
  422. data/sig/ibex/normalize/inline_expansion.rbs +59 -50
  423. data/sig/ibex/normalize/lexer.rbs +4 -4
  424. data/sig/ibex/normalize/parameter_ebnf_lowering.rbs +15 -14
  425. data/sig/ibex/normalize/parameter_lowering.rbs +18 -18
  426. data/sig/ibex/normalize/parameters.rbs +13 -8
  427. data/sig/ibex/normalize/parser_configuration.rbs +23 -0
  428. data/sig/ibex/normalize.rbs +11 -5
  429. data/sig/ibex/racc_migration/report.rbs +8 -6
  430. data/sig/ibex/rake_task.rbs +1 -1
  431. data/sig/ibex/samples.rbs +13 -4
  432. data/sig/ibex/table_artifact/builder.rbs +93 -0
  433. data/sig/ibex/table_artifact/cst_projection.rbs +20 -0
  434. data/sig/ibex/table_artifact/document.rbs +27 -0
  435. data/sig/ibex/table_artifact/executor.rbs +66 -0
  436. data/sig/ibex/table_artifact/serializer.rbs +25 -0
  437. data/sig/ibex/table_artifact/validator/metadata.rbs +52 -0
  438. data/sig/ibex/table_artifact/validator/support.rbs +46 -0
  439. data/sig/ibex/table_artifact/validator/tables.rbs +63 -0
  440. data/sig/ibex/table_artifact/validator.rbs +66 -0
  441. data/sig/ibex/table_artifact.rbs +32 -0
  442. data/sig/ibex/table_simulation/result.rbs +8 -4
  443. data/sig/ibex/table_simulation/step.rbs +4 -2
  444. data/sig/ibex/tables.rbs +10 -9
  445. data/sig/ibex/verifiable_generation_bundle.rbs +24 -0
  446. data/sig/ibex/verification_report/builder.rbs +53 -0
  447. data/sig/ibex/verification_report/canonical_ir.rbs +41 -0
  448. data/sig/ibex/verification_report/logical_path.rbs +34 -0
  449. data/sig/ibex/verification_report/validator.rbs +114 -0
  450. data/sig/ibex/verification_report.rbs +44 -0
  451. data/sig/ibex/verify/action_correspondence.rbs +50 -0
  452. data/sig/ibex/verify/language_witness.rbs +112 -0
  453. data/sig/ibex/verify/reference_collection.rbs +63 -0
  454. data/sig/ibex/verify/result.rbs +52 -0
  455. data/sig/ibex/verify/verifier.rbs +170 -0
  456. data/sig/ibex/verify.rbs +6 -0
  457. data/sig/ibex/watch/runner.rbs +12 -2
  458. data/sig/ibex/watch/source_snapshot.rbs +13 -9
  459. metadata +254 -12
  460. data/lib/ibex/ir/migration.rb +0 -120
  461. data/sig/ibex/ir/migration.rbs +0 -34
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require "digest"
5
+ require "fileutils"
6
+ require "json"
7
+
8
+ module Ibex
9
+ # @rbs!
10
+ # type fuzz_external_description = {
11
+ # command: String,
12
+ # target_runtime: String,
13
+ # timeout_seconds: Integer,
14
+ # max_output_bytes: Integer,
15
+ # host_ruby_engine: String,
16
+ # host_ruby_version: String,
17
+ # host_platform: String
18
+ # }
19
+ # type fuzz_external_target = [
20
+ # ^(Array[String]) -> Symbol,
21
+ # fuzz_external_description
22
+ # ]
23
+
24
+ # Automatic bounded minimization and persistence for fuzz differences.
25
+ module CLIFuzzRegressions
26
+ # @rbs!
27
+ # private def atomic_write_ir: (String path, String source) -> void
28
+
29
+ private
30
+
31
+ # @rbs (Fuzz fuzzer, Fuzz::Mismatch mismatch, String grammar_path,
32
+ # fuzz_external_target? external) -> Integer
33
+ def write_minimized_fuzz_mismatch(fuzzer, mismatch, grammar_path, external)
34
+ details = minimized_fuzz_mismatch(fuzzer, mismatch, grammar_path, external)
35
+ report = {
36
+ ibex_report: "fuzz", schema_version: 1, result: "difference", mismatch: details
37
+ } #: Hash[Symbol, untyped]
38
+ report[:external] = external[1] if external
39
+ write_fuzz_report(report)
40
+ 1
41
+ end
42
+
43
+ # @rbs (Hash[Symbol, untyped] report) -> void
44
+ def write_fuzz_report(report)
45
+ if @options.fetch(:fuzz_format, "json") == "json"
46
+ @stdout.puts JSON.pretty_generate(report)
47
+ return
48
+ end
49
+
50
+ @stdout.puts("result=#{report.fetch(:result)}")
51
+ case report.fetch(:result)
52
+ when "no_difference_within_bounds"
53
+ @stdout.puts("seed=#{report.fetch(:seed)} bounds=#{report.fetch(:bounds).inspect}")
54
+ @stdout.puts("no difference found within the declared bounds; this is not a proof of equivalence")
55
+ when "difference"
56
+ mismatch = report.fetch(:mismatch) #: Hash[Symbol, untyped]
57
+ @stdout.puts("kind=#{mismatch.fetch(:kind)} tokens=#{mismatch.fetch(:tokens).inspect}")
58
+ @stdout.puts("minimized=#{mismatch.fetch(:minimized_tokens).inspect} " \
59
+ "reduction_complete=#{mismatch.dig(:reduction, :complete)}")
60
+ @stdout.puts("regression=#{mismatch.dig(:regression, :path)}") if mismatch[:regression]
61
+ when "budget_exhausted"
62
+ @stdout.puts("search incomplete: #{report.dig(:budget, :message)}")
63
+ end
64
+ external = report[:external] #: fuzz_external_description?
65
+ return unless external
66
+
67
+ @stdout.puts("target_runtime=#{external.fetch(:target_runtime)}")
68
+ @stdout.puts("target_command=#{external.fetch(:command)}")
69
+ end
70
+
71
+ # @rbs (Fuzz::BudgetExceeded error,
72
+ # fuzz_external_target? external, phase: String) -> Integer
73
+ def write_fuzz_budget_report(error, external, phase:)
74
+ report = {
75
+ ibex_report: "fuzz", schema_version: 1, result: "budget_exhausted",
76
+ budget: error.details.merge(phase: phase)
77
+ } #: Hash[Symbol, untyped]
78
+ report[:external] = external[1] if external
79
+ write_fuzz_report(report)
80
+ 2
81
+ end
82
+
83
+ # @rbs (Fuzz fuzzer, Fuzz::Mismatch mismatch, String grammar_path,
84
+ # fuzz_external_target? external) -> Hash[Symbol, untyped]
85
+ def minimized_fuzz_mismatch(fuzzer, mismatch, grammar_path, external)
86
+ result = fuzzer.minimize(
87
+ mismatch, max_trials: @options.fetch(:fuzz_max_reduction_trials, 1_000)
88
+ )
89
+ details = mismatch.details.dup #: Hash[Symbol, untyped]
90
+ details[:minimized_tokens] = result.items
91
+ details[:reduction] = {
92
+ original_size: result.original_size, minimized_size: result.items.length,
93
+ trials: result.trials, complete: result.complete
94
+ }
95
+ regression = persist_fuzz_regression(
96
+ mismatch.details, result, grammar_path, external&.[](1)
97
+ )
98
+ details[:regression] = regression if regression
99
+ details
100
+ end
101
+
102
+ # @rbs (fuzz_mismatch mismatch, DeltaReducer::Result result, String grammar_path,
103
+ # fuzz_external_description? external) -> Hash[Symbol, String]?
104
+ def persist_fuzz_regression(mismatch, result, grammar_path, external)
105
+ return if @options.fetch(:fuzz_save_regression, true) == false
106
+
107
+ directory = @options.fetch(:fuzz_regression_dir, "test/fuzz/regressions")
108
+ FileUtils.mkdir_p(directory)
109
+ document = fuzz_regression_document(mismatch, result, grammar_path, external)
110
+ source = "#{JSON.pretty_generate(document)}\n"
111
+ digest = Digest::SHA256.hexdigest(source)
112
+ seed = @options.fetch(:fuzz_seed, 0)
113
+ path = File.join(directory, "fuzz-seed-#{seed}-#{digest.slice(0, 16)}.json")
114
+ validate_fuzz_regression_target!(path)
115
+ atomic_write_ir(path, source)
116
+ { path: path, sha256: digest }
117
+ end
118
+
119
+ # @rbs (String path) -> void
120
+ def validate_fuzz_regression_target!(path)
121
+ return unless File.symlink?(path) || (File.exist?(path) && File.stat(path).nlink > 1)
122
+
123
+ raise Ibex::Error, "(fuzz):1:1: regression output refuses symlinks and files with multiple hard links"
124
+ end
125
+
126
+ # @rbs (fuzz_mismatch mismatch, DeltaReducer::Result result, String grammar_path,
127
+ # fuzz_external_description? external) -> Hash[Symbol, Object?]
128
+ def fuzz_regression_document(mismatch, result, grammar_path, external)
129
+ document = {
130
+ ibex_report: "fuzz-regression", schema_version: 1, grammar: grammar_path,
131
+ seed: @options.fetch(:fuzz_seed, 0), kind: mismatch[:kind],
132
+ sentence: mismatch[:sentence],
133
+ algorithms: mismatch[:outcomes].keys.reject { |name| name == :external }.map(&:to_s),
134
+ original_tokens: mismatch[:tokens], minimized_tokens: result.items,
135
+ bounds: mismatch[:bounds],
136
+ reduction: {
137
+ original_size: result.original_size, minimized_size: result.items.length,
138
+ trials: result.trials, complete: result.complete
139
+ }
140
+ } #: Hash[Symbol, Object?]
141
+ document[:external] = external if external
142
+ document
143
+ end
144
+ end
145
+ end
@@ -12,6 +12,8 @@ module Ibex
12
12
  # private def report_status: (String) -> void
13
13
  # private def verify_file: (String, String, String) -> void
14
14
  # private def default_output_path: (String, String) -> String
15
+ # private def configuration_value: (String) -> Object?
16
+ # private def effective_configuration: () -> Configuration::Resolver
15
17
 
16
18
  private
17
19
 
@@ -21,6 +23,7 @@ module Ibex
21
23
  @generation_statuses = [] #: Array[String]
22
24
  @generation_sources = [] #: Array[String]
23
25
  @generation_inputs = [] #: Array[GenerationInput]
26
+ @generation_automaton = nil
24
27
  end
25
28
 
26
29
  # @rbs (Symbol kind, String path, String content, ?mode: Integer?, ?status: bool) -> Artifact
@@ -120,19 +123,67 @@ module Ibex
120
123
  default_output_path(parser.path, ".ibex.json")
121
124
  end
122
125
 
123
- # @rbs () -> Hash[String, untyped]
126
+ # @rbs () -> Hash[String, Object?]
124
127
  def generation_manifest_options
125
128
  keys = %i[
126
129
  action_source algorithm counterexample_max_configurations counterexample_max_tokens debug
127
130
  embedded emit entry_isolation executable frozen line_convert line_convert_all messages mode omit_actions rbs
128
131
  superclass table
129
132
  ]
130
- options = {} #: Hash[String, untyped]
133
+ options = {} #: Hash[String, Object?]
131
134
  keys.each do |key|
132
135
  value = @options[key]
133
136
  options[key.to_s] = value unless value.nil?
134
137
  end
138
+ options["cst_trivia"] = effective_cst_trivia.to_s
139
+ append_ir_manifest_options(options)
135
140
  options
136
141
  end
142
+
143
+ # @rbs (Hash[String, Object?] options) -> void
144
+ def append_ir_manifest_options(options)
145
+ automaton = @generation_automaton
146
+ return unless automaton
147
+
148
+ grammar = automaton.grammar
149
+ contract = grammar.parser_contract
150
+ options["grammar_ir"] = {
151
+ "schema_version" => grammar.schema_version,
152
+ "digest" => automaton.grammar_digest,
153
+ "parser_contract" => stringify_contract(contract)
154
+ }
155
+ options["automaton_ir"] = {
156
+ "schema_version" => automaton.schema_version,
157
+ "algorithm" => automaton.algorithm,
158
+ "entry_construction" => automaton.entry_construction,
159
+ "construction_authority" => construction_authority
160
+ }
161
+ options["effective_configuration"] = manifest_effective_configuration
162
+ end
163
+
164
+ # @rbs () -> String
165
+ def construction_authority
166
+ @options[:from] == "automaton-ir" ? "embedded_automaton" : "grammar_contract"
167
+ end
168
+
169
+ # @rbs () -> Array[Hash[String, Object?]]
170
+ def manifest_effective_configuration
171
+ values = effective_configuration.to_h.fetch("configuration")
172
+ return values unless @options[:from] == "automaton-ir"
173
+
174
+ values.reject { |entry| %w[parser.algorithm parser.entries].include?(entry.fetch("key")) }
175
+ end
176
+
177
+ # @rbs (IR::ParserContract contract) -> Hash[String, Object?]
178
+ def stringify_contract(contract)
179
+ contract.to_h.to_h do |name, entry|
180
+ [name.to_s, entry.to_h { |key, value| [key.to_s, value] }]
181
+ end
182
+ end
183
+
184
+ # @rbs () -> Symbol
185
+ def effective_cst_trivia
186
+ configuration_value("cst.trivia") #: Symbol
187
+ end
137
188
  end
138
189
  end
@@ -16,7 +16,7 @@ module Ibex
16
16
  end
17
17
  end
18
18
 
19
- # @rbs (IR::Automaton automaton) -> Hash[Integer, untyped]
19
+ # @rbs (IR::Automaton automaton) -> Hash[Integer, String | { id: String, message: String }]
20
20
  def configured_error_messages(automaton)
21
21
  path = @options[:messages]
22
22
  return {} unless path
@@ -7,26 +7,19 @@ module Ibex
7
7
  # `%test` command parsing and human-readable result reporting.
8
8
  module CLIGrammarTests
9
9
  # @rbs!
10
- # type grammar_test_settings = {
11
- # mode: Symbol,
12
- # algorithm: Symbol,
13
- # entry_isolation: bool,
14
- # timeout: Integer,
15
- # coverage: Integer?,
16
- # ?help: bool
17
- # }
10
+ # type grammar_test_settings = Hash[Symbol, untyped]
18
11
  # private def print_help: (OptionParser) -> Integer
19
12
  # private def resolve_grammar_path: (String) -> Frontend::Resolution
20
13
  # private def handle_grammar_warnings: (IR::Grammar, String) -> void
21
14
  # private def build_automaton: (IR::Grammar, String) -> IR::Automaton
15
+ # private def configuration_value: (String) -> untyped
16
+ # private def mark_configuration_option: (Symbol) -> void
22
17
 
23
18
  private
24
19
 
25
20
  # @rbs (Array[String] arguments) -> Integer
26
21
  def run_grammar_tests_command(arguments)
27
- settings = {
28
- mode: :default, algorithm: :lalr, entry_isolation: false, timeout: GrammarTests::DEFAULT_TIMEOUT, coverage: nil
29
- } #: grammar_test_settings
22
+ settings = default_grammar_test_settings
30
23
  options = grammar_test_option_parser(settings)
31
24
  remaining = options.parse(arguments)
32
25
  return print_help(options) if settings[:help]
@@ -39,7 +32,7 @@ module Ibex
39
32
  @options[:algorithm] = settings[:algorithm]
40
33
  @options[:entry_isolation] = settings[:entry_isolation]
41
34
  resolution = resolve_grammar_path(path)
42
- grammar = Normalizer.new(resolution, mode: settings[:mode]).normalize
35
+ grammar = normalize_analysis_grammar(resolution)
43
36
  handle_grammar_warnings(grammar, path)
44
37
  automaton = build_automaton(grammar, path)
45
38
  runner = GrammarTests::Runner.new(automaton, timeout: settings[:timeout])
@@ -51,16 +44,31 @@ module Ibex
51
44
  render_grammar_test_coverage(runner.production_coverage(results), coverage, failures)
52
45
  end
53
46
 
54
- # @rbs (grammar_test_settings settings) -> OptionParser
47
+ # @rbs () -> Hash[Symbol, untyped]
48
+ def default_grammar_test_settings
49
+ {
50
+ mode: Configuration::Registry.fetch("grammar.mode").default,
51
+ algorithm: Configuration::Registry.fetch("parser.algorithm").default,
52
+ entry_isolation: Configuration::Registry.fetch("parser.entries").default == :isolated,
53
+ timeout: GrammarTests::DEFAULT_TIMEOUT, coverage: nil
54
+ }
55
+ end
56
+
57
+ # @rbs (Hash[Symbol, untyped] settings) -> OptionParser
55
58
  def grammar_test_option_parser(settings)
56
59
  OptionParser.new do |options|
57
60
  options.banner = "Usage: ibex test [options] grammarfile"
58
- options.on("--mode=MODE", %w[default extended], "grammar mode") { |value| settings[:mode] = value.to_sym }
61
+ options.on("--mode=MODE", %w[default extended], "grammar mode") do |value|
62
+ settings[:mode] = value.to_sym
63
+ mark_configuration_option(:mode)
64
+ end
59
65
  options.on("--algorithm=NAME", %w[slr lalr ielr lr1], "parser construction algorithm") do |value|
60
66
  settings[:algorithm] = value.to_sym
67
+ mark_configuration_option(:algorithm)
61
68
  end
62
69
  options.on("--entry-isolation", "build independent state sets for each start symbol") do
63
70
  settings[:entry_isolation] = true
71
+ mark_configuration_option(:entry_isolation)
64
72
  end
65
73
  options.on("--timeout=SECONDS", Integer, "whole-suite timeout (default: 10)") do |value|
66
74
  raise OptionParser::InvalidArgument, "timeout must be positive" unless value.positive?
@@ -83,6 +91,16 @@ module Ibex
83
91
  raise OptionParser::InvalidArgument, "test accepts exactly one grammarfile"
84
92
  end
85
93
 
94
+ # @rbs (Frontend::Resolution resolution) -> IR::Grammar
95
+ def normalize_analysis_grammar(resolution)
96
+ grammar = Normalizer.new(resolution, mode: configuration_value("grammar.mode")).normalize
97
+ activate_analysis_grammar(grammar)
98
+ end
99
+
100
+ # @rbs!
101
+ # private def activate_analysis_grammar: (IR::Grammar, ?options: Hash[Symbol, Object?],
102
+ # ?explicit_keys: Array[Symbol]) -> IR::Grammar
103
+
86
104
  # @rbs (Array[GrammarTests::Result] results) -> Integer
87
105
  def render_grammar_test_results(results)
88
106
  failures = 0