ibex 0.1.0 → 0.3.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 (603) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +89 -123
  3. data/docs/architecture.md +477 -31
  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 +106 -0
  12. data/docs/cst.md +237 -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 +262 -0
  40. data/docs/development.md +306 -0
  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 +26 -0
  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 +1581 -0
  49. data/docs/error-ux-round2.md +111 -0
  50. data/docs/error-ux.md +114 -0
  51. data/docs/getting-started.md +80 -0
  52. data/docs/grammar-reference.md +629 -18
  53. data/docs/ielr-design.md +43 -0
  54. data/docs/ielr.md +92 -0
  55. data/docs/ja/bison-import.md +51 -0
  56. data/docs/ja/stable-api.md +53 -0
  57. data/docs/lexer-construction-profile.md +109 -0
  58. data/docs/lexer-migration.md +56 -0
  59. data/docs/maturity.md +128 -0
  60. data/docs/project-site-strategy.md +54 -0
  61. data/docs/racc-migration-evidence.md +45 -0
  62. data/docs/racc-migration.md +45 -6
  63. data/docs/release-readiness.md +221 -0
  64. data/docs/repair-semantics.md +123 -0
  65. data/docs/runtime-abi-evolution.md +307 -0
  66. data/docs/stability.md +234 -0
  67. data/docs/status.md +43 -0
  68. data/docs/syntax-sessions.md +183 -0
  69. data/docs/table-artifact.md +125 -0
  70. data/docs/test-interactions.md +219 -0
  71. data/docs/verification-report.md +137 -0
  72. data/docs/verifier-trust-boundary.md +199 -0
  73. data/docs/workloads.md +132 -0
  74. data/examples/README.md +60 -0
  75. data/examples/calculator.y +44 -0
  76. data/examples/csv.y +32 -0
  77. data/examples/ini.y +70 -0
  78. data/examples/json.y +48 -0
  79. data/examples/tiny_language.y +75 -0
  80. data/lib/ibex/analysis/digraph.rb +128 -0
  81. data/lib/ibex/analysis/sets.rb +5 -4
  82. data/lib/ibex/analysis.rb +1 -0
  83. data/lib/ibex/artifact_set.rb +63 -0
  84. data/lib/ibex/bison_import/importer.rb +516 -0
  85. data/lib/ibex/bison_import/tokenizer.rb +260 -0
  86. data/lib/ibex/bison_import.rb +200 -0
  87. data/lib/ibex/bounded_subprocess.rb +171 -0
  88. data/lib/ibex/cli/ambiguity.rb +75 -0
  89. data/lib/ibex/cli/analysis.rb +134 -0
  90. data/lib/ibex/cli/bison_import.rb +121 -0
  91. data/lib/ibex/cli/config.rb +128 -0
  92. data/lib/ibex/cli/counterexample_options.rb +6 -2
  93. data/lib/ibex/cli/coverage.rb +173 -0
  94. data/lib/ibex/cli/debug.rb +106 -0
  95. data/lib/ibex/cli/diagnostics.rb +136 -0
  96. data/lib/ibex/cli/documentation.rb +70 -0
  97. data/lib/ibex/cli/equiv.rb +169 -0
  98. data/lib/ibex/cli/error_messages.rb +184 -0
  99. data/lib/ibex/cli/explain.rb +85 -0
  100. data/lib/ibex/cli/fix.rb +203 -0
  101. data/lib/ibex/cli/formatting.rb +387 -0
  102. data/lib/ibex/cli/fuzz.rb +200 -0
  103. data/lib/ibex/cli/fuzz_regressions.rb +145 -0
  104. data/lib/ibex/cli/generation_artifacts.rb +189 -0
  105. data/lib/ibex/cli/generation_error_messages.rb +39 -0
  106. data/lib/ibex/cli/grammar_tests.rb +140 -0
  107. data/lib/ibex/cli/ir_tools.rb +128 -0
  108. data/lib/ibex/cli/lsp.rb +33 -0
  109. data/lib/ibex/cli/outputs.rb +133 -23
  110. data/lib/ibex/cli/racc_migration.rb +87 -0
  111. data/lib/ibex/cli/reduce.rb +202 -0
  112. data/lib/ibex/cli/reduce_reporting.rb +71 -0
  113. data/lib/ibex/cli/samples.rb +118 -0
  114. data/lib/ibex/cli/verify.rb +116 -0
  115. data/lib/ibex/cli/watch.rb +104 -0
  116. data/lib/ibex/cli.rb +825 -55
  117. data/lib/ibex/codegen/action_locations.rb +103 -0
  118. data/lib/ibex/codegen/action_method_source.rb +209 -0
  119. data/lib/ibex/codegen/action_source.rb +119 -0
  120. data/lib/ibex/codegen/ambiguity.rb +174 -0
  121. data/lib/ibex/codegen/cst_metadata.rb +171 -0
  122. data/lib/ibex/codegen/documentation.rb +170 -0
  123. data/lib/ibex/codegen/explain.rb +380 -0
  124. data/lib/ibex/codegen/generated_action_abi.rb +293 -0
  125. data/lib/ibex/codegen/html.rb +94 -10
  126. data/lib/ibex/codegen/mermaid.rb +43 -0
  127. data/lib/ibex/codegen/railroad.rb +197 -0
  128. data/lib/ibex/codegen/railroad_documentation.rb +59 -0
  129. data/lib/ibex/codegen/rbs.rb +331 -2
  130. data/lib/ibex/codegen/report.rb +67 -15
  131. data/lib/ibex/codegen/ruby.rb +305 -66
  132. data/lib/ibex/codegen/ruby_actions.rb +146 -0
  133. data/lib/ibex/codegen/ruby_ast.rb +121 -0
  134. data/lib/ibex/codegen/ruby_error_messages.rb +28 -0
  135. data/lib/ibex/codegen/ruby_lexer.rb +83 -0
  136. data/lib/ibex/codegen/ruby_syntax.rb +96 -0
  137. data/lib/ibex/codegen/ruby_table_metadata.rb +57 -0
  138. data/lib/ibex/codegen/ruby_value_printers.rb +56 -0
  139. data/lib/ibex/codegen/symbol_labels.rb +1 -1
  140. data/lib/ibex/configuration/analysis_grammar.rb +35 -0
  141. data/lib/ibex/configuration/explanation.rb +421 -0
  142. data/lib/ibex/configuration/inspector.rb +232 -0
  143. data/lib/ibex/configuration.rb +580 -0
  144. data/lib/ibex/coverage/collector.rb +198 -0
  145. data/lib/ibex/coverage/event_stream.rb +103 -0
  146. data/lib/ibex/coverage/report.rb +267 -0
  147. data/lib/ibex/coverage/runtime_event_validator.rb +169 -0
  148. data/lib/ibex/coverage.rb +13 -0
  149. data/lib/ibex/delta_reducer.rb +99 -0
  150. data/lib/ibex/diff.rb +140 -0
  151. data/lib/ibex/equiv/machine.rb +135 -0
  152. data/lib/ibex/equiv.rb +373 -0
  153. data/lib/ibex/error_messages/parser.rb +159 -0
  154. data/lib/ibex/error_messages/parser_v2.rb +198 -0
  155. data/lib/ibex/error_messages/renderer.rb +65 -0
  156. data/lib/ibex/error_messages/sentence_search.rb +196 -0
  157. data/lib/ibex/error_messages/update.rb +169 -0
  158. data/lib/ibex/error_messages.rb +165 -0
  159. data/lib/ibex/fix.rb +557 -0
  160. data/lib/ibex/frontend/ast.rb +166 -7
  161. data/lib/ibex/frontend/bootstrap_parser.rb +40 -4
  162. data/lib/ibex/frontend/diagnostic.rb +81 -0
  163. data/lib/ibex/frontend/diagnostic_recovery.rb +268 -0
  164. data/lib/ibex/frontend/dsl.rb +66 -7
  165. data/lib/ibex/frontend/formatter.rb +453 -0
  166. data/lib/ibex/frontend/generated_parser.rb +644 -190
  167. data/lib/ibex/frontend/generated_parser_base.rb +170 -32
  168. data/lib/ibex/frontend/generated_parser_includes.rb +51 -0
  169. data/lib/ibex/frontend/generated_parser_metadata.rb +61 -0
  170. data/lib/ibex/frontend/generated_parser_parameters.rb +60 -0
  171. data/lib/ibex/frontend/generation.rb +33 -0
  172. data/lib/ibex/frontend/lexer.rb +162 -10
  173. data/lib/ibex/frontend/lexer_recovery.rb +84 -0
  174. data/lib/ibex/frontend/parser/declarations.rb +262 -11
  175. data/lib/ibex/frontend/parser/parameters.rb +82 -0
  176. data/lib/ibex/frontend/parser/rules.rb +43 -6
  177. data/lib/ibex/frontend/parser.rb +182 -4
  178. data/lib/ibex/frontend/parser_configuration_support.rb +56 -0
  179. data/lib/ibex/frontend/regenerator.rb +27 -1
  180. data/lib/ibex/frontend/resolution.rb +70 -0
  181. data/lib/ibex/frontend/resolver.rb +217 -0
  182. data/lib/ibex/frontend/rule_documentation.rb +104 -0
  183. data/lib/ibex/frontend/source_cursor.rb +133 -9
  184. data/lib/ibex/frontend/source_document.rb +229 -0
  185. data/lib/ibex/frontend/source_loader.rb +150 -0
  186. data/lib/ibex/frontend/source_span.rb +89 -0
  187. data/lib/ibex/frontend/token_adapter/declaration_document_state.rb +47 -0
  188. data/lib/ibex/frontend/token_adapter/declaration_lexer_state.rb +83 -0
  189. data/lib/ibex/frontend/token_adapter/declaration_state.rb +244 -22
  190. data/lib/ibex/frontend/token_adapter/delimiter_tracker.rb +8 -2
  191. data/lib/ibex/frontend/token_adapter/rule_state.rb +60 -2
  192. data/lib/ibex/frontend/token_adapter.rb +18 -3
  193. data/lib/ibex/frontend.rb +14 -2
  194. data/lib/ibex/fuzz.rb +219 -0
  195. data/lib/ibex/generation_input.rb +57 -0
  196. data/lib/ibex/generation_manifest.rb +211 -0
  197. data/lib/ibex/generation_transaction.rb +261 -0
  198. data/lib/ibex/generation_transaction_recovery.rb +109 -0
  199. data/lib/ibex/generation_transaction_validation.rb +196 -0
  200. data/lib/ibex/grammar_tests.rb +206 -0
  201. data/lib/ibex/ir/automaton_ir.rb +86 -11
  202. data/lib/ibex/ir/grammar_ir.rb +170 -26
  203. data/lib/ibex/ir/lexer_ir.rb +76 -0
  204. data/lib/ibex/ir/parser_contract.rb +135 -0
  205. data/lib/ibex/ir/serialize.rb +268 -50
  206. data/lib/ibex/ir/validator/automaton.rb +375 -0
  207. data/lib/ibex/ir/validator/base.rb +147 -0
  208. data/lib/ibex/ir/validator/grammar.rb +634 -0
  209. data/lib/ibex/ir/validator/lexer.rb +113 -0
  210. data/lib/ibex/ir/validator.rb +63 -0
  211. data/lib/ibex/ir.rb +71 -5
  212. data/lib/ibex/lalr/build_metrics.rb +71 -0
  213. data/lib/ibex/lalr/builder.rb +514 -52
  214. data/lib/ibex/lalr/conflict.rb +1 -0
  215. data/lib/ibex/lalr/conflict_search.rb +26 -9
  216. data/lib/ibex/lalr/counterexample.rb +38 -18
  217. data/lib/ibex/lalr/direct_lookaheads.rb +289 -0
  218. data/lib/ibex/lalr/goto_follows.rb +229 -0
  219. data/lib/ibex/lalr/ielr/annotator.rb +214 -0
  220. data/lib/ibex/lalr/ielr/bits.rb +28 -0
  221. data/lib/ibex/lalr/ielr/inadequacy.rb +47 -0
  222. data/lib/ibex/lalr/ielr/item_lookaheads.rb +78 -0
  223. data/lib/ibex/lalr/ielr/pipeline.rb +75 -0
  224. data/lib/ibex/lalr/ielr/split_stability.rb +78 -0
  225. data/lib/ibex/lalr/ielr/split_state.rb +20 -0
  226. data/lib/ibex/lalr/ielr/state_splitter.rb +258 -0
  227. data/lib/ibex/lalr/ielr_partition.rb +166 -0
  228. data/lib/ibex/lalr/inadequacy_report.rb +50 -0
  229. data/lib/ibex/lalr/lookahead_propagation.rb +111 -0
  230. data/lib/ibex/lalr/lr0_collection.rb +121 -0
  231. data/lib/ibex/lalr/on_error_reductions.rb +74 -0
  232. data/lib/ibex/lalr/unreachable_states.rb +80 -0
  233. data/lib/ibex/lalr.rb +59 -1
  234. data/lib/ibex/location.rb +129 -0
  235. data/lib/ibex/lsp/document_handlers.rb +68 -0
  236. data/lib/ibex/lsp/document_store.rb +264 -0
  237. data/lib/ibex/lsp/document_store_diagnostics.rb +44 -0
  238. data/lib/ibex/lsp/document_store_validation.rb +61 -0
  239. data/lib/ibex/lsp/initialization_handlers.rb +80 -0
  240. data/lib/ibex/lsp/navigation_handlers.rb +70 -0
  241. data/lib/ibex/lsp/parser_configuration_assistance.rb +149 -0
  242. data/lib/ibex/lsp/position_codec.rb +113 -0
  243. data/lib/ibex/lsp/protocol_error.rb +33 -0
  244. data/lib/ibex/lsp/request_handlers.rb +46 -0
  245. data/lib/ibex/lsp/request_support.rb +94 -0
  246. data/lib/ibex/lsp/server.rb +148 -0
  247. data/lib/ibex/lsp/symbol_index.rb +241 -0
  248. data/lib/ibex/lsp/symbol_index_builder.rb +277 -0
  249. data/lib/ibex/lsp/symbol_index_precedence_references.rb +44 -0
  250. data/lib/ibex/lsp/symbol_index_source_queries.rb +61 -0
  251. data/lib/ibex/lsp/symbol_occurrence.rb +23 -0
  252. data/lib/ibex/lsp/transport.rb +128 -0
  253. data/lib/ibex/lsp/workspace.rb +128 -0
  254. data/lib/ibex/lsp/workspace_analyzer.rb +199 -0
  255. data/lib/ibex/lsp.rb +33 -0
  256. data/lib/ibex/messages/en.yml +28 -0
  257. data/lib/ibex/messages/ja.yml +28 -0
  258. data/lib/ibex/messages.rb +68 -0
  259. data/lib/ibex/metrics.rb +175 -0
  260. data/lib/ibex/normalize/declarations.rb +142 -7
  261. data/lib/ibex/normalize/diagnostics.rb +94 -24
  262. data/lib/ibex/normalize/expander.rb +64 -59
  263. data/lib/ibex/normalize/expression.rb +63 -40
  264. data/lib/ibex/normalize/grammar_builder.rb +26 -0
  265. data/lib/ibex/normalize/inline_expansion.rb +465 -0
  266. data/lib/ibex/normalize/inline_validation.rb +174 -0
  267. data/lib/ibex/normalize/lexer.rb +131 -0
  268. data/lib/ibex/normalize/named_references.rb +60 -0
  269. data/lib/ibex/normalize/nodes.rb +46 -0
  270. data/lib/ibex/normalize/parameter_ebnf_lowering.rb +70 -0
  271. data/lib/ibex/normalize/parameter_lowering.rb +143 -0
  272. data/lib/ibex/normalize/parameter_substitution.rb +125 -0
  273. data/lib/ibex/normalize/parameter_validation.rb +140 -0
  274. data/lib/ibex/normalize/parameters.rb +226 -0
  275. data/lib/ibex/normalize/parser_configuration.rb +70 -0
  276. data/lib/ibex/normalize/recovery_declarations.rb +84 -0
  277. data/lib/ibex/normalize.rb +172 -17
  278. data/lib/ibex/racc_migration/checker.rb +122 -0
  279. data/lib/ibex/racc_migration/harness.rb +177 -0
  280. data/lib/ibex/racc_migration/report.rb +97 -0
  281. data/lib/ibex/racc_migration.rb +12 -0
  282. data/lib/ibex/rake_task.rb +116 -0
  283. data/lib/ibex/samples.rb +216 -0
  284. data/lib/ibex/table_artifact/builder.rb +266 -0
  285. data/lib/ibex/table_artifact/cst_projection.rb +70 -0
  286. data/lib/ibex/table_artifact/document.rb +39 -0
  287. data/lib/ibex/table_artifact/executor.rb +187 -0
  288. data/lib/ibex/table_artifact/serializer.rb +57 -0
  289. data/lib/ibex/table_artifact/validator/metadata.rb +179 -0
  290. data/lib/ibex/table_artifact/validator/support.rb +86 -0
  291. data/lib/ibex/table_artifact/validator/tables.rb +238 -0
  292. data/lib/ibex/table_artifact/validator.rb +253 -0
  293. data/lib/ibex/table_artifact.rb +88 -0
  294. data/lib/ibex/table_simulation/result.rb +55 -0
  295. data/lib/ibex/table_simulation/simulator.rb +253 -0
  296. data/lib/ibex/table_simulation/step.rb +62 -0
  297. data/lib/ibex/table_simulation/text.rb +31 -0
  298. data/lib/ibex/table_simulation.rb +13 -0
  299. data/lib/ibex/tables.rb +22 -69
  300. data/lib/ibex/verifiable_generation_bundle.rb +86 -0
  301. data/lib/ibex/verification_report/builder.rb +159 -0
  302. data/lib/ibex/verification_report/canonical_ir.rb +123 -0
  303. data/lib/ibex/verification_report/logical_path.rb +68 -0
  304. data/lib/ibex/verification_report/validator.rb +329 -0
  305. data/lib/ibex/verification_report.rb +69 -0
  306. data/lib/ibex/verify/action_correspondence.rb +138 -0
  307. data/lib/ibex/verify/language_witness.rb +295 -0
  308. data/lib/ibex/verify/reference_collection.rb +190 -0
  309. data/lib/ibex/verify/result.rb +73 -0
  310. data/lib/ibex/verify/verifier.rb +598 -0
  311. data/lib/ibex/verify.rb +15 -0
  312. data/lib/ibex/version.rb +1 -1
  313. data/lib/ibex/watch/runner.rb +181 -0
  314. data/lib/ibex/watch/source_snapshot.rb +98 -0
  315. data/lib/ibex/watch.rb +11 -0
  316. data/lib/ibex.rb +35 -1
  317. data/schema/automaton-ir-definitions.schema.json +401 -0
  318. data/schema/automaton-ir.schema.json +65 -0
  319. data/schema/benchmark-v1.schema.json +212 -0
  320. data/schema/benchmark-v2.schema.json +61 -0
  321. data/schema/bison-import-v1.schema.json +106 -0
  322. data/schema/conflict-explanation-review-v1.schema.json +196 -0
  323. data/schema/conflict-explanation-study-v1.schema.json +528 -0
  324. data/schema/construction-profile-v1.schema.json +779 -0
  325. data/schema/cst-v1.json +170 -0
  326. data/schema/diff-v1.schema.json +41 -0
  327. data/schema/direct-ielr-decision-v1.schema.json +200 -0
  328. data/schema/equiv-v1.schema.json +64 -0
  329. data/schema/error-ux-review-v1.schema.json +609 -0
  330. data/schema/error-ux-round2-review-v1.schema.json +191 -0
  331. data/schema/error-ux-round2-v1.schema.json +519 -0
  332. data/schema/error-ux-v1.schema.json +258 -0
  333. data/schema/explain-v1.schema.json +495 -0
  334. data/schema/fix-v1.schema.json +64 -0
  335. data/schema/fix-v2.schema.json +66 -0
  336. data/schema/fix-v3.schema.json +101 -0
  337. data/schema/frontend-diagnostics-v1.schema.json +154 -0
  338. data/schema/fuzz-regression-v1.schema.json +79 -0
  339. data/schema/fuzz-v1.schema.json +114 -0
  340. data/schema/generation-manifest-v1.schema.json +115 -0
  341. data/schema/grammar-ir-extensions.schema.json +734 -0
  342. data/schema/grammar-ir-foundation.schema.json +426 -0
  343. data/schema/grammar-ir.schema.json +271 -0
  344. data/schema/ielr-benchmark-v1.schema.json +85 -0
  345. data/schema/lexer-ir-v1.schema.json +215 -0
  346. data/schema/lexer-profile-v1.schema.json +491 -0
  347. data/schema/metrics-v1.schema.json +60 -0
  348. data/schema/migration-check-v1.schema.json +60 -0
  349. data/schema/performance-comparison-v1.schema.json +395 -0
  350. data/schema/public-performance-comparison-v1.schema.json +506 -0
  351. data/schema/public-performance-profile-v1.schema.json +360 -0
  352. data/schema/reduce-v1.schema.json +22 -0
  353. data/schema/reduce-v2.schema.json +63 -0
  354. data/schema/runtime-coverage-v1.schema.json +86 -0
  355. data/schema/runtime-event-v1.schema.json +308 -0
  356. data/schema/table-artifact-v1.schema.json +377 -0
  357. data/schema/table-simulation-v1.schema.json +70 -0
  358. data/schema/verification-report-v1.schema.json +222 -0
  359. data/schema/verify-v1.schema.json +42 -0
  360. data/sig/ibex/analysis/digraph.rbs +19 -0
  361. data/sig/ibex/artifact_set.rbs +37 -0
  362. data/sig/ibex/bison_import/importer.rbs +140 -0
  363. data/sig/ibex/bison_import/tokenizer.rbs +91 -0
  364. data/sig/ibex/bison_import.rbs +95 -0
  365. data/sig/ibex/bounded_subprocess.rbs +76 -0
  366. data/sig/ibex/cli/ambiguity.rbs +28 -0
  367. data/sig/ibex/cli/analysis.rbs +43 -0
  368. data/sig/ibex/cli/bison_import.rbs +32 -0
  369. data/sig/ibex/cli/config.rbs +35 -0
  370. data/sig/ibex/cli/counterexample_options.rbs +2 -0
  371. data/sig/ibex/cli/coverage.rbs +53 -0
  372. data/sig/ibex/cli/debug.rbs +28 -0
  373. data/sig/ibex/cli/diagnostics.rbs +51 -0
  374. data/sig/ibex/cli/documentation.rbs +29 -0
  375. data/sig/ibex/cli/equiv.rbs +49 -0
  376. data/sig/ibex/cli/error_messages.rbs +63 -0
  377. data/sig/ibex/cli/explain.rbs +31 -0
  378. data/sig/ibex/cli/fix.rbs +53 -0
  379. data/sig/ibex/cli/formatting.rbs +107 -0
  380. data/sig/ibex/cli/fuzz.rbs +47 -0
  381. data/sig/ibex/cli/fuzz_regressions.rbs +40 -0
  382. data/sig/ibex/cli/generation_artifacts.rbs +69 -0
  383. data/sig/ibex/cli/generation_error_messages.rbs +19 -0
  384. data/sig/ibex/cli/grammar_tests.rbs +48 -0
  385. data/sig/ibex/cli/ir_tools.rbs +39 -0
  386. data/sig/ibex/cli/lsp.rbs +14 -0
  387. data/sig/ibex/cli/outputs.rbs +26 -3
  388. data/sig/ibex/cli/racc_migration.rbs +30 -0
  389. data/sig/ibex/cli/reduce.rbs +60 -0
  390. data/sig/ibex/cli/reduce_reporting.rbs +27 -0
  391. data/sig/ibex/cli/samples.rbs +38 -0
  392. data/sig/ibex/cli/verify.rbs +28 -0
  393. data/sig/ibex/cli/watch.rbs +43 -0
  394. data/sig/ibex/cli.rbs +182 -9
  395. data/sig/ibex/codegen/action_locations.rbs +45 -0
  396. data/sig/ibex/codegen/action_method_source.rbs +65 -0
  397. data/sig/ibex/codegen/action_source.rbs +50 -0
  398. data/sig/ibex/codegen/ambiguity.rbs +60 -0
  399. data/sig/ibex/codegen/cst_metadata.rbs +59 -0
  400. data/sig/ibex/codegen/documentation.rbs +50 -0
  401. data/sig/ibex/codegen/explain.rbs +105 -0
  402. data/sig/ibex/codegen/generated_action_abi.rbs +105 -0
  403. data/sig/ibex/codegen/html.rbs +18 -2
  404. data/sig/ibex/codegen/mermaid.rbs +16 -0
  405. data/sig/ibex/codegen/railroad.rbs +82 -0
  406. data/sig/ibex/codegen/railroad_documentation.rbs +31 -0
  407. data/sig/ibex/codegen/rbs.rbs +86 -4
  408. data/sig/ibex/codegen/report.rbs +16 -8
  409. data/sig/ibex/codegen/ruby.rbs +105 -28
  410. data/sig/ibex/codegen/ruby_actions.rbs +54 -0
  411. data/sig/ibex/codegen/ruby_ast.rbs +34 -0
  412. data/sig/ibex/codegen/ruby_error_messages.rbs +16 -0
  413. data/sig/ibex/codegen/ruby_lexer.rbs +25 -0
  414. data/sig/ibex/codegen/ruby_syntax.rbs +27 -0
  415. data/sig/ibex/codegen/ruby_table_metadata.rbs +26 -0
  416. data/sig/ibex/codegen/ruby_value_printers.rbs +28 -0
  417. data/sig/ibex/configuration/analysis_grammar.rbs +13 -0
  418. data/sig/ibex/configuration/explanation.rbs +195 -0
  419. data/sig/ibex/configuration/inspector.rbs +53 -0
  420. data/sig/ibex/configuration.rbs +242 -0
  421. data/sig/ibex/coverage/collector.rbs +78 -0
  422. data/sig/ibex/coverage/event_stream.rbs +44 -0
  423. data/sig/ibex/coverage/report.rbs +102 -0
  424. data/sig/ibex/coverage/runtime_event_validator.rbs +70 -0
  425. data/sig/ibex/coverage.rbs +7 -0
  426. data/sig/ibex/delta_reducer.rbs +38 -0
  427. data/sig/ibex/diff.rbs +47 -0
  428. data/sig/ibex/equiv/machine.rbs +54 -0
  429. data/sig/ibex/equiv.rbs +129 -0
  430. data/sig/ibex/error_messages/parser.rbs +58 -0
  431. data/sig/ibex/error_messages/parser_v2.rbs +67 -0
  432. data/sig/ibex/error_messages/renderer.rbs +23 -0
  433. data/sig/ibex/error_messages/sentence_search.rbs +80 -0
  434. data/sig/ibex/error_messages/update.rbs +43 -0
  435. data/sig/ibex/error_messages.rbs +85 -0
  436. data/sig/ibex/fix.rbs +138 -0
  437. data/sig/ibex/frontend/ast.rbs +237 -22
  438. data/sig/ibex/frontend/bootstrap_parser.rbs +13 -0
  439. data/sig/ibex/frontend/diagnostic.rbs +53 -0
  440. data/sig/ibex/frontend/diagnostic_recovery.rbs +98 -0
  441. data/sig/ibex/frontend/dsl.rbs +33 -4
  442. data/sig/ibex/frontend/formatter.rbs +143 -0
  443. data/sig/ibex/frontend/generated_parser.rbs +228 -68
  444. data/sig/ibex/frontend/generated_parser_base.rbs +65 -12
  445. data/sig/ibex/frontend/generated_parser_includes.rbs +23 -0
  446. data/sig/ibex/frontend/generated_parser_metadata.rbs +23 -0
  447. data/sig/ibex/frontend/generated_parser_parameters.rbs +24 -0
  448. data/sig/ibex/frontend/generation.rbs +6 -0
  449. data/sig/ibex/frontend/lexer.rbs +49 -2
  450. data/sig/ibex/frontend/lexer_recovery.rbs +25 -0
  451. data/sig/ibex/frontend/parser/declarations.rbs +57 -0
  452. data/sig/ibex/frontend/parser/parameters.rbs +28 -0
  453. data/sig/ibex/frontend/parser/rules.rbs +3 -0
  454. data/sig/ibex/frontend/parser.rbs +66 -0
  455. data/sig/ibex/frontend/parser_configuration_support.rbs +27 -0
  456. data/sig/ibex/frontend/regenerator.rbs +11 -0
  457. data/sig/ibex/frontend/resolution.rbs +34 -0
  458. data/sig/ibex/frontend/resolver.rbs +91 -0
  459. data/sig/ibex/frontend/rule_documentation.rbs +42 -0
  460. data/sig/ibex/frontend/source_cursor.rbs +38 -5
  461. data/sig/ibex/frontend/source_document.rbs +119 -0
  462. data/sig/ibex/frontend/source_loader.rbs +66 -0
  463. data/sig/ibex/frontend/source_span.rbs +56 -0
  464. data/sig/ibex/frontend/token_adapter/declaration_document_state.rbs +21 -0
  465. data/sig/ibex/frontend/token_adapter/declaration_lexer_state.rbs +27 -0
  466. data/sig/ibex/frontend/token_adapter/declaration_state.rbs +83 -3
  467. data/sig/ibex/frontend/token_adapter/rule_state.rbs +20 -0
  468. data/sig/ibex/frontend/token_adapter.rbs +11 -2
  469. data/sig/ibex/frontend.rbs +1 -1
  470. data/sig/ibex/fuzz.rbs +71 -0
  471. data/sig/ibex/generation_input.rbs +37 -0
  472. data/sig/ibex/generation_manifest.rbs +70 -0
  473. data/sig/ibex/generation_transaction.rbs +82 -0
  474. data/sig/ibex/generation_transaction_recovery.rbs +36 -0
  475. data/sig/ibex/generation_transaction_validation.rbs +65 -0
  476. data/sig/ibex/grammar_tests.rbs +93 -0
  477. data/sig/ibex/ir/automaton_ir.rbs +35 -10
  478. data/sig/ibex/ir/grammar_ir.rbs +96 -22
  479. data/sig/ibex/ir/lexer_ir.rbs +57 -0
  480. data/sig/ibex/ir/parser_contract.rbs +69 -0
  481. data/sig/ibex/ir/serialize.rbs +75 -23
  482. data/sig/ibex/ir/validator/automaton.rbs +112 -0
  483. data/sig/ibex/ir/validator/base.rbs +69 -0
  484. data/sig/ibex/ir/validator/grammar.rbs +195 -0
  485. data/sig/ibex/ir/validator/lexer.rbs +37 -0
  486. data/sig/ibex/ir/validator.rbs +16 -0
  487. data/sig/ibex/ir.rbs +45 -5
  488. data/sig/ibex/lalr/build_metrics.rbs +60 -0
  489. data/sig/ibex/lalr/builder.rbs +150 -19
  490. data/sig/ibex/lalr/conflict_search.rbs +12 -5
  491. data/sig/ibex/lalr/counterexample.rbs +20 -14
  492. data/sig/ibex/lalr/direct_lookaheads.rbs +93 -0
  493. data/sig/ibex/lalr/goto_follows.rbs +89 -0
  494. data/sig/ibex/lalr/ielr/annotator.rbs +67 -0
  495. data/sig/ibex/lalr/ielr/bits.rbs +14 -0
  496. data/sig/ibex/lalr/ielr/inadequacy.rbs +24 -0
  497. data/sig/ibex/lalr/ielr/item_lookaheads.rbs +35 -0
  498. data/sig/ibex/lalr/ielr/pipeline.rbs +17 -0
  499. data/sig/ibex/lalr/ielr/split_stability.rbs +27 -0
  500. data/sig/ibex/lalr/ielr/split_state.rbs +14 -0
  501. data/sig/ibex/lalr/ielr/state_splitter.rbs +76 -0
  502. data/sig/ibex/lalr/ielr_partition.rbs +71 -0
  503. data/sig/ibex/lalr/inadequacy_report.rbs +21 -0
  504. data/sig/ibex/lalr/lookahead_propagation.rbs +38 -0
  505. data/sig/ibex/lalr/lr0_collection.rbs +50 -0
  506. data/sig/ibex/lalr/on_error_reductions.rbs +22 -0
  507. data/sig/ibex/lalr/unreachable_states.rbs +25 -0
  508. data/sig/ibex/lalr.rbs +17 -1
  509. data/sig/ibex/location.rbs +67 -0
  510. data/sig/ibex/lsp/document_handlers.rbs +24 -0
  511. data/sig/ibex/lsp/document_store.rbs +94 -0
  512. data/sig/ibex/lsp/document_store_diagnostics.rbs +20 -0
  513. data/sig/ibex/lsp/document_store_validation.rbs +26 -0
  514. data/sig/ibex/lsp/initialization_handlers.rbs +30 -0
  515. data/sig/ibex/lsp/navigation_handlers.rbs +33 -0
  516. data/sig/ibex/lsp/parser_configuration_assistance.rbs +49 -0
  517. data/sig/ibex/lsp/position_codec.rbs +44 -0
  518. data/sig/ibex/lsp/protocol_error.rbs +32 -0
  519. data/sig/ibex/lsp/request_handlers.rbs +26 -0
  520. data/sig/ibex/lsp/request_support.rbs +40 -0
  521. data/sig/ibex/lsp/server.rbs +55 -0
  522. data/sig/ibex/lsp/symbol_index.rbs +77 -0
  523. data/sig/ibex/lsp/symbol_index_builder.rbs +88 -0
  524. data/sig/ibex/lsp/symbol_index_precedence_references.rbs +18 -0
  525. data/sig/ibex/lsp/symbol_index_source_queries.rbs +26 -0
  526. data/sig/ibex/lsp/symbol_occurrence.rbs +31 -0
  527. data/sig/ibex/lsp/transport.rbs +47 -0
  528. data/sig/ibex/lsp/workspace.rbs +42 -0
  529. data/sig/ibex/lsp/workspace_analyzer.rbs +69 -0
  530. data/sig/ibex/lsp.rbs +7 -0
  531. data/sig/ibex/messages.rbs +26 -0
  532. data/sig/ibex/metrics.rbs +50 -0
  533. data/sig/ibex/normalize/declarations.rbs +31 -0
  534. data/sig/ibex/normalize/diagnostics.rbs +13 -4
  535. data/sig/ibex/normalize/expander.rbs +22 -16
  536. data/sig/ibex/normalize/expression.rbs +11 -9
  537. data/sig/ibex/normalize/grammar_builder.rbs +11 -0
  538. data/sig/ibex/normalize/inline_expansion.rbs +129 -0
  539. data/sig/ibex/normalize/inline_validation.rbs +40 -0
  540. data/sig/ibex/normalize/lexer.rbs +37 -0
  541. data/sig/ibex/normalize/named_references.rbs +20 -0
  542. data/sig/ibex/normalize/nodes.rbs +14 -0
  543. data/sig/ibex/normalize/parameter_ebnf_lowering.rbs +33 -0
  544. data/sig/ibex/normalize/parameter_lowering.rbs +35 -0
  545. data/sig/ibex/normalize/parameter_substitution.rbs +42 -0
  546. data/sig/ibex/normalize/parameter_validation.rbs +44 -0
  547. data/sig/ibex/normalize/parameters.rbs +51 -0
  548. data/sig/ibex/normalize/parser_configuration.rbs +23 -0
  549. data/sig/ibex/normalize/recovery_declarations.rbs +24 -0
  550. data/sig/ibex/normalize.rbs +129 -18
  551. data/sig/ibex/racc_migration/checker.rbs +36 -0
  552. data/sig/ibex/racc_migration/harness.rbs +16 -0
  553. data/sig/ibex/racc_migration/report.rbs +55 -0
  554. data/sig/ibex/racc_migration.rbs +8 -0
  555. data/sig/ibex/rake_task.rbs +51 -0
  556. data/sig/ibex/samples.rbs +60 -0
  557. data/sig/ibex/table_artifact/builder.rbs +93 -0
  558. data/sig/ibex/table_artifact/cst_projection.rbs +20 -0
  559. data/sig/ibex/table_artifact/document.rbs +27 -0
  560. data/sig/ibex/table_artifact/executor.rbs +66 -0
  561. data/sig/ibex/table_artifact/serializer.rbs +25 -0
  562. data/sig/ibex/table_artifact/validator/metadata.rbs +52 -0
  563. data/sig/ibex/table_artifact/validator/support.rbs +46 -0
  564. data/sig/ibex/table_artifact/validator/tables.rbs +63 -0
  565. data/sig/ibex/table_artifact/validator.rbs +66 -0
  566. data/sig/ibex/table_artifact.rbs +32 -0
  567. data/sig/ibex/table_simulation/result.rbs +36 -0
  568. data/sig/ibex/table_simulation/simulator.rbs +98 -0
  569. data/sig/ibex/table_simulation/step.rbs +42 -0
  570. data/sig/ibex/table_simulation/text.rbs +14 -0
  571. data/sig/ibex/table_simulation.rbs +7 -0
  572. data/sig/ibex/tables.rbs +10 -35
  573. data/sig/ibex/verifiable_generation_bundle.rbs +24 -0
  574. data/sig/ibex/verification_report/builder.rbs +53 -0
  575. data/sig/ibex/verification_report/canonical_ir.rbs +41 -0
  576. data/sig/ibex/verification_report/logical_path.rbs +34 -0
  577. data/sig/ibex/verification_report/validator.rbs +114 -0
  578. data/sig/ibex/verification_report.rbs +44 -0
  579. data/sig/ibex/verify/action_correspondence.rbs +50 -0
  580. data/sig/ibex/verify/language_witness.rbs +112 -0
  581. data/sig/ibex/verify/reference_collection.rbs +63 -0
  582. data/sig/ibex/verify/result.rbs +52 -0
  583. data/sig/ibex/verify/verifier.rbs +170 -0
  584. data/sig/ibex/verify.rbs +6 -0
  585. data/sig/ibex/watch/runner.rbs +58 -0
  586. data/sig/ibex/watch/source_snapshot.rbs +46 -0
  587. data/sig/ibex/watch.rbs +7 -0
  588. data/sig/ibex.rbs +2 -0
  589. metadata +524 -19
  590. data/.rubocop.yml +0 -43
  591. data/CHANGELOG.md +0 -30
  592. data/Rakefile +0 -25
  593. data/Steepfile +0 -10
  594. data/docs/compat-notes.md +0 -37
  595. data/docs/lexer-coverage.md +0 -14
  596. data/docs/phase10-extensions.md +0 -27
  597. data/gemfiles/Gemfile +0 -7
  598. data/gemfiles/Gemfile.lock +0 -98
  599. data/lib/ibex/frontend/grammar.y +0 -156
  600. data/lib/ibex/runtime/parser.rb +0 -360
  601. data/lib/ibex/runtime.rb +0 -8
  602. data/sig/ibex/runtime/parser.rbs +0 -167
  603. data/sig/ibex/runtime.rbs +0 -6
@@ -0,0 +1,253 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require_relative "../error"
5
+
6
+ module Ibex
7
+ module TableSimulation
8
+ # Deterministic, semantic-action-free table interpreter.
9
+ class Simulator
10
+ DEFAULT_MAX_STEPS = 100_000 #: Integer
11
+ DEFAULT_MAX_STACK = 10_000 #: Integer
12
+ EOF_NAME = "$eof" #: String
13
+ ERROR_NAME = "error" #: String
14
+ IMPLICIT_ERROR = { type: :error }.freeze #: IR::error_action
15
+
16
+ attr_reader :automaton #: IR::Automaton
17
+ attr_reader :max_steps #: Integer
18
+ attr_reader :max_stack #: Integer
19
+ attr_reader :eof #: IR::GrammarSymbol
20
+
21
+ # @rbs (IR::Automaton automaton, ?max_steps: Integer, ?max_stack: Integer) -> void
22
+ def initialize(automaton, max_steps: DEFAULT_MAX_STEPS, max_stack: DEFAULT_MAX_STACK)
23
+ raise ArgumentError, "max_steps must be positive" unless max_steps.positive?
24
+ raise ArgumentError, "max_stack must be positive" unless max_stack.positive?
25
+
26
+ @automaton = automaton
27
+ @max_steps = max_steps
28
+ @max_stack = max_stack
29
+ @terminals = automaton.grammar.terminals.to_h { |symbol| [symbol.name, symbol] }.freeze
30
+ @terminal_aliases = terminal_aliases(automaton.grammar.terminals).freeze
31
+ @eof = @terminals[EOF_NAME] || raise(Ibex::Error, "(debug):1:1: automaton has no $eof terminal")
32
+ end
33
+
34
+ # @rbs () -> Session
35
+ def start
36
+ Session.new(self)
37
+ end
38
+
39
+ # @rbs (Array[String] tokens) -> Result
40
+ def simulate(tokens)
41
+ session = start
42
+ tokens.each do |token|
43
+ session.push(token)
44
+ break if session.status
45
+ end
46
+ session.finish
47
+ end
48
+
49
+ # @rbs (String spelling) -> IR::GrammarSymbol
50
+ def terminal(spelling)
51
+ if [EOF_NAME, ERROR_NAME].include?(spelling)
52
+ raise Ibex::Error, "(debug):1:1: reserved terminal #{spelling.inspect} cannot be supplied"
53
+ end
54
+
55
+ terminal = @terminals[spelling]
56
+ return terminal if terminal
57
+
58
+ empty = [] #: Array[IR::GrammarSymbol]
59
+ aliases = @terminal_aliases.fetch(spelling, empty)
60
+ return aliases.first if aliases.length == 1
61
+
62
+ if aliases.length > 1
63
+ names = aliases.map(&:name).sort.join(", ")
64
+ raise Ibex::Error, "(debug):1:1: terminal display name #{spelling.inspect} is ambiguous: #{names}"
65
+ end
66
+
67
+ raise Ibex::Error, "(debug):1:1: unknown terminal #{spelling.inspect}"
68
+ end
69
+
70
+ private
71
+
72
+ # @rbs (Array[IR::GrammarSymbol] terminals) -> Hash[String, Array[IR::GrammarSymbol]]
73
+ def terminal_aliases(terminals)
74
+ aliases = Hash.new { |hash, key| hash[key] = [] } #: Hash[String, Array[IR::GrammarSymbol]]
75
+ terminals.each do |terminal|
76
+ aliases[terminal.display_name] << terminal if terminal.display_name
77
+ end
78
+ aliases.each_value(&:freeze)
79
+ aliases
80
+ end
81
+ end
82
+
83
+ # Stateful token-at-a-time table simulation session.
84
+ class Session
85
+ # @rbs @steps: Array[Step]
86
+ # @rbs @tokens: Array[String]
87
+
88
+ attr_reader :status #: Symbol?
89
+
90
+ # @rbs (Simulator simulator) -> void
91
+ def initialize(simulator)
92
+ @simulator = simulator
93
+ @state_stack = [0] #: Array[Integer]
94
+ @status = nil
95
+ @steps = []
96
+ @tokens = []
97
+ @finished = false
98
+ end
99
+
100
+ # @rbs (String spelling) -> Array[Step]
101
+ def push(spelling)
102
+ ensure_active!
103
+ terminal = @simulator.terminal(spelling)
104
+ @tokens << terminal.name
105
+ process(terminal, eof: false)
106
+ end
107
+
108
+ # @rbs () -> Array[Step]
109
+ def steps = @steps.dup.freeze
110
+
111
+ # @rbs () -> Array[String]
112
+ def tokens = @tokens.dup.freeze
113
+
114
+ # @rbs () -> Result
115
+ def finish
116
+ raise Ibex::Error, "(debug):1:1: simulation session is already finished" if @finished
117
+
118
+ @finished = true
119
+ process(@simulator.eof, eof: true) until @status
120
+ Result.new(
121
+ grammar_digest: @simulator.automaton.grammar_digest,
122
+ algorithm: @simulator.automaton.algorithm,
123
+ tokens: @tokens,
124
+ status: @status || raise(Ibex::Error, "(debug):1:1: simulation did not terminate"),
125
+ steps: @steps
126
+ )
127
+ end
128
+
129
+ private
130
+
131
+ # @rbs (IR::GrammarSymbol terminal, eof: bool) -> Array[Step]
132
+ def process(terminal, eof:)
133
+ first = @steps.length
134
+ loop do
135
+ state = current_state
136
+ action, source = action_for(state, terminal.id)
137
+ case action.fetch(:type)
138
+ when :shift
139
+ record_shift(state, terminal, action, source)
140
+ next if eof
141
+
142
+ break
143
+ when :reduce then record_reduce(state, terminal, action, source)
144
+ when :accept
145
+ record_terminal(state, terminal, "accept", source)
146
+ @status = :accepted
147
+ break
148
+ when :error
149
+ record_terminal(state, terminal, "error", source)
150
+ @status = :error
151
+ break
152
+ else raise Ibex::Error, "(debug):1:1: unknown table action #{action.inspect}"
153
+ end
154
+ end
155
+ @steps.drop(first).freeze
156
+ end
157
+
158
+ # @rbs (IR::AutomatonState state, Integer token_id) -> [IR::parser_action, String]
159
+ def action_for(state, token_id)
160
+ return [state.actions.fetch(token_id), "explicit"] if state.actions.key?(token_id)
161
+ return [state.default_action, "default"] if state.default_action
162
+
163
+ [Simulator::IMPLICIT_ERROR, "implicit"]
164
+ end
165
+
166
+ # @rbs (IR::AutomatonState state, IR::GrammarSymbol terminal, IR::parser_action action, String source) -> void
167
+ def record_shift(state, terminal, action, source)
168
+ shift = action #: IR::shift_action
169
+ before = @state_stack.length
170
+ target = shift.fetch(:state)
171
+ @state_stack << target
172
+ enforce_stack_budget!
173
+ append_step(state, terminal, "shift", source, target_state: target, before: before)
174
+ end
175
+
176
+ # @rbs (IR::AutomatonState state, IR::GrammarSymbol terminal, IR::parser_action action, String source) -> void
177
+ def record_reduce(state, terminal, action, source)
178
+ reduction = action #: IR::reduce_action
179
+ production_id = reduction.fetch(:production)
180
+ production = @simulator.automaton.grammar.productions.fetch(production_id)
181
+ length = production.rhs.length
182
+ before = @state_stack.length
183
+ if length >= before
184
+ raise Ibex::Error, "(debug):1:1: production #{production_id} underflows the simulated state stack"
185
+ end
186
+
187
+ @state_stack.pop(length)
188
+ goto = current_state.gotos[production.lhs]
189
+ unless goto
190
+ raise Ibex::Error, "(debug):1:1: missing goto for production #{production_id} from state #{current_state.id}"
191
+ end
192
+
193
+ @state_stack << goto
194
+ enforce_stack_budget!
195
+ lhs = @simulator.automaton.grammar.symbol_by_id(production.lhs)
196
+ raise Ibex::Error, "(debug):1:1: missing lhs symbol #{production.lhs}" unless lhs
197
+
198
+ append_step(
199
+ state, terminal, "reduce", source,
200
+ production_id: production_id, lhs: lhs.name, rhs_length: length,
201
+ target_state: goto, before: before
202
+ )
203
+ end
204
+
205
+ # @rbs (IR::AutomatonState state, IR::GrammarSymbol terminal, String action, String source) -> void
206
+ def record_terminal(state, terminal, action, source)
207
+ append_step(state, terminal, action, source, before: @state_stack.length)
208
+ end
209
+
210
+ # @rbs (IR::AutomatonState state, IR::GrammarSymbol terminal, String action, String source,
211
+ # before: Integer, ?production_id: Integer?, ?lhs: String?, ?rhs_length: Integer?,
212
+ # ?target_state: Integer?) -> void
213
+ def append_step(state, terminal, action, source, before:, production_id: nil, lhs: nil, rhs_length: nil,
214
+ target_state: nil)
215
+ raise Ibex::Error, "(debug):1:1: simulation exceeded #{@simulator.max_steps} actions" \
216
+ if @steps.length >= @simulator.max_steps
217
+
218
+ @steps << Step.new(
219
+ sequence: @steps.length + 1,
220
+ state: state.id,
221
+ token_id: terminal.id,
222
+ token: terminal.display_name || terminal.name,
223
+ action: action,
224
+ action_source: source,
225
+ production_id: production_id,
226
+ lhs: lhs,
227
+ rhs_length: rhs_length,
228
+ target_state: target_state,
229
+ stack_depth_before: before,
230
+ stack_depth_after: @state_stack.length
231
+ )
232
+ end
233
+
234
+ # @rbs () -> IR::AutomatonState
235
+ def current_state
236
+ id = @state_stack.last || raise(Ibex::Error, "(debug):1:1: simulated state stack is empty")
237
+ @simulator.automaton.states.fetch(id)
238
+ end
239
+
240
+ # @rbs () -> void
241
+ def enforce_stack_budget!
242
+ return if @state_stack.length <= @simulator.max_stack
243
+
244
+ raise Ibex::Error, "(debug):1:1: simulation exceeded stack depth #{@simulator.max_stack}"
245
+ end
246
+
247
+ # @rbs () -> void
248
+ def ensure_active!
249
+ raise Ibex::Error, "(debug):1:1: simulation session is already finished" if @finished || @status
250
+ end
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ module Ibex
5
+ module TableSimulation
6
+ # One immutable parser-table action.
7
+ class Step
8
+ # @rbs! type document_value = String | Integer | nil
9
+
10
+ attr_reader :sequence #: Integer
11
+ attr_reader :state #: Integer
12
+ attr_reader :token_id #: Integer
13
+ attr_reader :token #: String
14
+ attr_reader :action #: String
15
+ attr_reader :action_source #: String
16
+ attr_reader :production_id #: Integer?
17
+ attr_reader :lhs #: String?
18
+ attr_reader :rhs_length #: Integer?
19
+ attr_reader :target_state #: Integer?
20
+ attr_reader :stack_depth_before #: Integer
21
+ attr_reader :stack_depth_after #: Integer
22
+
23
+ # @rbs (sequence: Integer, state: Integer, token_id: Integer, token: String, action: String,
24
+ # action_source: String, production_id: Integer?, lhs: String?, rhs_length: Integer?,
25
+ # target_state: Integer?, stack_depth_before: Integer, stack_depth_after: Integer) -> void
26
+ def initialize(sequence:, state:, token_id:, token:, action:, action_source:, production_id:, lhs:, rhs_length:,
27
+ target_state:, stack_depth_before:, stack_depth_after:)
28
+ @sequence = sequence
29
+ @state = state
30
+ @token_id = token_id
31
+ @token = token.dup.freeze
32
+ @action = action.dup.freeze
33
+ @action_source = action_source.dup.freeze
34
+ @production_id = production_id
35
+ @lhs = lhs&.dup&.freeze
36
+ @rhs_length = rhs_length
37
+ @target_state = target_state
38
+ @stack_depth_before = stack_depth_before
39
+ @stack_depth_after = stack_depth_after
40
+ freeze
41
+ end
42
+
43
+ # @rbs () -> Hash[String, document_value]
44
+ def to_h
45
+ {
46
+ "sequence" => @sequence,
47
+ "state" => @state,
48
+ "token_id" => @token_id,
49
+ "token" => @token,
50
+ "action" => @action,
51
+ "action_source" => @action_source,
52
+ "production_id" => @production_id,
53
+ "lhs" => @lhs,
54
+ "rhs_length" => @rhs_length,
55
+ "target_state" => @target_state,
56
+ "stack_depth_before" => @stack_depth_before,
57
+ "stack_depth_after" => @stack_depth_after
58
+ }.freeze
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ module Ibex
5
+ module TableSimulation
6
+ # Stable one-line renderer for simulation steps.
7
+ module Text
8
+ class << self
9
+ # @rbs (Step step) -> String
10
+ def render_step(step)
11
+ detail = case step.action
12
+ when "shift" then " target=#{step.target_state}"
13
+ when "reduce"
14
+ " production=#{step.production_id} lhs=#{step.lhs} rhs=#{step.rhs_length} " \
15
+ "goto=#{step.target_state}"
16
+ else ""
17
+ end
18
+ "#{step.sequence}: state=#{step.state} token=#{step.token.inspect} action=#{step.action}" \
19
+ "#{detail} source=#{step.action_source} stack=#{step.stack_depth_before}->#{step.stack_depth_after}"
20
+ end
21
+
22
+ # @rbs (Result result) -> String
23
+ def render(result)
24
+ lines = result.steps.map { |step| render_step(step) }
25
+ lines << "status=#{result.status}"
26
+ "#{lines.join("\n")}\n"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -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,82 +1,31 @@
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
6
10
  # @rbs!
11
+ # type action_table = Array[Hash[Integer, IR::runtime_action]] | CompactActions
12
+ # type goto_table = Array[Hash[Integer, Integer]] | Compact
7
13
  # private def runtime_action: (IR::parser_action action) -> IR::runtime_action
8
14
  # private def self.runtime_action: (IR::parser_action action) -> IR::runtime_action
9
15
 
16
+ # @rbs skip
10
17
  TableSet = Struct.new(:actions, :gotos, :default_actions, keyword_init: true)
11
18
 
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
19
+ # @rbs!
20
+ # class TableSet < Struct[Object?]
21
+ # attr_accessor actions: action_table
22
+ # attr_accessor gotos: goto_table
23
+ # attr_accessor default_actions: Array[IR::runtime_action?]
24
+ # def self.new: (?actions: action_table, ?gotos: goto_table,
25
+ # ?default_actions: Array[IR::runtime_action?]) -> instance
26
+ # | ({ ?actions: action_table, ?gotos: goto_table,
27
+ # ?default_actions: Array[IR::runtime_action?] }) -> instance
28
+ # end
80
29
 
81
30
  # @rbs (IR::Automaton automaton, ?format: Symbol | String) -> TableSet
82
31
  def build(automaton, format: :compact)
@@ -95,7 +44,11 @@ module Ibex
95
44
  end
96
45
  raise ArgumentError, "unknown table format #{format.inspect}" unless format.to_sym == :compact
97
46
 
98
- TableSet.new(actions: Compact.build(action_rows), gotos: Compact.build(goto_rows), default_actions: defaults)
47
+ TableSet.new(
48
+ actions: CompactActions.build(action_rows),
49
+ gotos: Compact.build(goto_rows),
50
+ default_actions: defaults
51
+ )
99
52
  end
100
53
  module_function :build
101
54
 
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ require_relative "artifact_set"
5
+ require_relative "generation_manifest"
6
+ require_relative "generation_transaction"
7
+ require_relative "table_artifact"
8
+ require_relative "verification_report"
9
+
10
+ module Ibex
11
+ # Explicitly renders and publishes one manifest-bound verification bundle.
12
+ class VerifiableGenerationBundle
13
+ # rubocop:disable Metrics/ParameterLists -- persisted artifact paths and verification bounds are explicit inputs.
14
+ # @rbs (IR::Automaton automaton, wrapper_path: String, wrapper_source: String,
15
+ # table_path: String, report_path: String, manifest_path: String,
16
+ # source_records: Array[GenerationInput], ?manifest_options: Hash[String, Object?],
17
+ # ?wrapper_mode: Integer?, ?representation: Symbol | String, ?cst_trivia: Symbol | String?,
18
+ # ?omit_action_call: bool?, ?strict: bool, ?max_states: Integer, ?max_items: Integer) -> void
19
+ def initialize(automaton, wrapper_path:, wrapper_source:, table_path:, report_path:, manifest_path:,
20
+ source_records:, manifest_options: {}, wrapper_mode: nil, representation: :compact,
21
+ cst_trivia: nil, omit_action_call: nil, strict: false,
22
+ max_states: VerificationReport::DEFAULT_MAX_STATES,
23
+ max_items: VerificationReport::DEFAULT_MAX_ITEMS)
24
+ @automaton = automaton
25
+ @wrapper_path = wrapper_path
26
+ @wrapper_source = wrapper_source
27
+ @table_path = table_path
28
+ VerificationReport::LogicalPath.table(table_path)
29
+ if source_records.length > VerificationReport::LogicalPath::MAX_INPUT_FILES
30
+ raise ArgumentError,
31
+ "verification reports support at most #{VerificationReport::LogicalPath::MAX_INPUT_FILES} input files"
32
+ end
33
+ @report_path = report_path
34
+ @manifest_path = manifest_path
35
+ @source_records = source_records
36
+ @manifest_options = manifest_options
37
+ @wrapper_mode = wrapper_mode
38
+ @representation = representation
39
+ @cst_trivia = cst_trivia
40
+ @omit_action_call = omit_action_call
41
+ @strict = strict
42
+ @max_states = max_states
43
+ @max_items = max_items
44
+ end
45
+ # rubocop:enable Metrics/ParameterLists
46
+
47
+ # Render table, wrapper, and report before the non-cyclic manifest marker.
48
+ # @rbs () -> ArtifactSet
49
+ def render
50
+ canonical_automaton = VerificationReport.canonical_automaton(
51
+ @automaton, source_records: @source_records
52
+ )
53
+ table = TableArtifact.build(
54
+ canonical_automaton, representation: @representation, cst_trivia: @cst_trivia,
55
+ omit_action_call: @omit_action_call
56
+ )
57
+ artifacts = ArtifactSet.new
58
+ artifacts.add(kind: :parser_table, path: @table_path, content: table.dump)
59
+ artifacts.add(kind: :parser, path: @wrapper_path, content: @wrapper_source, mode: @wrapper_mode)
60
+ report = VerificationReport.render(
61
+ canonical_automaton, table: table, source_records: @source_records, table_path: @table_path,
62
+ strict: @strict, max_states: @max_states, max_items: @max_items
63
+ )
64
+ artifacts.add(kind: :verification_report, path: @report_path, content: report)
65
+ manifest = GenerationManifest.render(
66
+ artifacts, source_records: @source_records, options: @manifest_options
67
+ )
68
+ artifacts.add(kind: :manifest, path: @manifest_path, content: manifest)
69
+ artifacts
70
+ end
71
+
72
+ # @rbs (?warning: ^(String) -> void, ?stability_check: ^() -> bool) -> ArtifactSet
73
+ def publish(warning: ->(_message) {}, stability_check: -> { @source_records.all?(&:current?) })
74
+ artifacts = render
75
+ GenerationTransaction.new(
76
+ artifacts, warning: warning, stability_check: stability_check, source_records: @source_records
77
+ ).commit
78
+ artifacts
79
+ end
80
+
81
+ # @rbs (String manifest_path) -> Hash[String, VerificationReport::Validator::json_value]
82
+ def self.validate_file(manifest_path)
83
+ VerificationReport.validate_bundle_file(manifest_path)
84
+ end
85
+ end
86
+ end