lrama 0.7.0 → 0.7.1

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 (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/codespell.yaml +1 -1
  4. data/.github/workflows/gh-pages.yml +5 -6
  5. data/.github/workflows/test.yaml +25 -14
  6. data/Gemfile +4 -3
  7. data/NEWS.md +370 -35
  8. data/README.md +7 -88
  9. data/Rakefile +3 -2
  10. data/Steepfile +11 -5
  11. data/doc/Index.md +1 -1
  12. data/doc/development/compressed_state_table/parser.rb +2 -0
  13. data/doc/development/profiling.md +44 -0
  14. data/exe/lrama +1 -1
  15. data/lib/lrama/bitmap.rb +18 -5
  16. data/lib/lrama/command.rb +95 -43
  17. data/lib/lrama/context.rb +22 -24
  18. data/lib/lrama/counterexamples/derivation.rb +14 -4
  19. data/lib/lrama/counterexamples/example.rb +47 -22
  20. data/lib/lrama/counterexamples/node.rb +30 -0
  21. data/lib/lrama/counterexamples/path.rb +12 -14
  22. data/lib/lrama/counterexamples/state_item.rb +24 -1
  23. data/lib/lrama/counterexamples/triple.rb +27 -9
  24. data/lib/lrama/counterexamples.rb +216 -88
  25. data/lib/lrama/diagram.rb +77 -0
  26. data/lib/lrama/digraph.rb +28 -7
  27. data/lib/lrama/erb.rb +29 -0
  28. data/lib/lrama/grammar/auxiliary.rb +6 -1
  29. data/lib/lrama/grammar/binding.rb +37 -25
  30. data/lib/lrama/grammar/code/destructor_code.rb +11 -0
  31. data/lib/lrama/grammar/code/initial_action_code.rb +3 -0
  32. data/lib/lrama/grammar/code/no_reference_code.rb +3 -0
  33. data/lib/lrama/grammar/code/printer_code.rb +11 -0
  34. data/lib/lrama/grammar/code/rule_action.rb +17 -0
  35. data/lib/lrama/grammar/code.rb +16 -1
  36. data/lib/lrama/grammar/counter.rb +10 -0
  37. data/lib/lrama/grammar/destructor.rb +14 -1
  38. data/lib/lrama/grammar/error_token.rb +14 -1
  39. data/lib/lrama/grammar/inline/resolver.rb +80 -0
  40. data/lib/lrama/grammar/inline.rb +3 -0
  41. data/lib/lrama/grammar/{parameterizing_rule → parameterized}/resolver.rb +19 -8
  42. data/lib/lrama/grammar/{parameterizing_rule → parameterized}/rhs.rb +7 -2
  43. data/lib/lrama/grammar/parameterized/rule.rb +36 -0
  44. data/lib/lrama/grammar/parameterized.rb +5 -0
  45. data/lib/lrama/grammar/percent_code.rb +12 -1
  46. data/lib/lrama/grammar/precedence.rb +43 -1
  47. data/lib/lrama/grammar/printer.rb +9 -0
  48. data/lib/lrama/grammar/reference.rb +13 -0
  49. data/lib/lrama/grammar/rule.rb +61 -1
  50. data/lib/lrama/grammar/rule_builder.rb +84 -69
  51. data/lib/lrama/grammar/stdlib.y +68 -48
  52. data/lib/lrama/grammar/symbol.rb +63 -19
  53. data/lib/lrama/grammar/symbols/resolver.rb +64 -3
  54. data/lib/lrama/grammar/type.rb +13 -1
  55. data/lib/lrama/grammar/union.rb +12 -1
  56. data/lib/lrama/grammar.rb +231 -35
  57. data/lib/lrama/lexer/location.rb +25 -8
  58. data/lib/lrama/lexer/token/base.rb +73 -0
  59. data/lib/lrama/lexer/token/char.rb +15 -2
  60. data/lib/lrama/lexer/token/empty.rb +14 -0
  61. data/lib/lrama/lexer/token/ident.rb +2 -2
  62. data/lib/lrama/lexer/token/instantiate_rule.rb +4 -4
  63. data/lib/lrama/lexer/token/int.rb +14 -0
  64. data/lib/lrama/lexer/token/str.rb +11 -0
  65. data/lib/lrama/lexer/token/tag.rb +2 -2
  66. data/lib/lrama/lexer/token/token.rb +11 -0
  67. data/lib/lrama/lexer/token/user_code.rb +63 -37
  68. data/lib/lrama/lexer/token.rb +6 -56
  69. data/lib/lrama/lexer.rb +51 -23
  70. data/lib/lrama/logger.rb +12 -2
  71. data/lib/lrama/option_parser.rb +63 -9
  72. data/lib/lrama/options.rb +25 -7
  73. data/lib/lrama/output.rb +4 -11
  74. data/lib/lrama/parser.rb +854 -723
  75. data/lib/lrama/reporter/conflicts.rb +44 -0
  76. data/lib/lrama/reporter/grammar.rb +39 -0
  77. data/lib/lrama/reporter/precedences.rb +54 -0
  78. data/lib/lrama/reporter/profile/call_stack.rb +45 -0
  79. data/lib/lrama/reporter/profile/memory.rb +44 -0
  80. data/lib/lrama/reporter/profile.rb +4 -0
  81. data/lib/lrama/reporter/rules.rb +43 -0
  82. data/lib/lrama/reporter/states.rb +387 -0
  83. data/lib/lrama/reporter/terms.rb +44 -0
  84. data/lib/lrama/reporter.rb +39 -0
  85. data/lib/lrama/state/action/goto.rb +33 -0
  86. data/lib/lrama/state/action/reduce.rb +71 -0
  87. data/lib/lrama/state/action/shift.rb +39 -0
  88. data/lib/lrama/state/action.rb +5 -0
  89. data/lib/lrama/state/inadequacy_annotation.rb +140 -0
  90. data/lib/lrama/{states → state}/item.rb +33 -4
  91. data/lib/lrama/state/reduce_reduce_conflict.rb +14 -1
  92. data/lib/lrama/state/resolved_conflict.rb +38 -4
  93. data/lib/lrama/state/shift_reduce_conflict.rb +14 -1
  94. data/lib/lrama/state.rb +301 -200
  95. data/lib/lrama/states.rb +447 -175
  96. data/lib/lrama/tracer/actions.rb +22 -0
  97. data/lib/lrama/tracer/closure.rb +30 -0
  98. data/lib/lrama/tracer/duration.rb +38 -0
  99. data/lib/lrama/tracer/only_explicit_rules.rb +24 -0
  100. data/lib/lrama/tracer/rules.rb +23 -0
  101. data/lib/lrama/tracer/state.rb +33 -0
  102. data/lib/lrama/tracer.rb +51 -0
  103. data/lib/lrama/version.rb +2 -1
  104. data/lib/lrama/warnings/conflicts.rb +27 -0
  105. data/lib/lrama/warnings/implicit_empty.rb +29 -0
  106. data/lib/lrama/warnings/name_conflicts.rb +63 -0
  107. data/lib/lrama/warnings/redefined_rules.rb +23 -0
  108. data/lib/lrama/warnings/required.rb +23 -0
  109. data/lib/lrama/warnings/useless_precedence.rb +25 -0
  110. data/lib/lrama/warnings.rb +33 -0
  111. data/lib/lrama.rb +5 -5
  112. data/parser.y +495 -404
  113. data/rbs_collection.lock.yaml +27 -3
  114. data/rbs_collection.yaml +2 -0
  115. data/sig/generated/lrama/bitmap.rbs +12 -4
  116. data/sig/generated/lrama/counterexamples/derivation.rbs +36 -0
  117. data/sig/generated/lrama/counterexamples/example.rbs +58 -0
  118. data/sig/generated/lrama/counterexamples/node.rbs +18 -0
  119. data/sig/generated/lrama/counterexamples/path.rbs +23 -0
  120. data/sig/generated/lrama/counterexamples/state_item.rbs +19 -0
  121. data/sig/generated/lrama/counterexamples/triple.rbs +32 -0
  122. data/sig/generated/lrama/counterexamples.rbs +98 -0
  123. data/sig/generated/lrama/diagram.rbs +34 -0
  124. data/sig/generated/lrama/digraph.rbs +26 -6
  125. data/sig/generated/lrama/erb.rbs +14 -0
  126. data/sig/generated/lrama/grammar/auxiliary.rbs +16 -0
  127. data/sig/generated/lrama/grammar/binding.rbs +18 -12
  128. data/sig/generated/lrama/grammar/code/destructor_code.rbs +26 -0
  129. data/sig/{lrama → generated/lrama}/grammar/code/initial_action_code.rbs +6 -0
  130. data/sig/{lrama → generated/lrama}/grammar/code/no_reference_code.rbs +6 -0
  131. data/sig/generated/lrama/grammar/code/printer_code.rbs +26 -0
  132. data/sig/generated/lrama/grammar/code/rule_action.rbs +63 -0
  133. data/sig/generated/lrama/grammar/code.rbs +38 -0
  134. data/sig/{lrama → generated/lrama}/grammar/counter.rbs +4 -0
  135. data/sig/generated/lrama/grammar/destructor.rbs +19 -0
  136. data/sig/generated/lrama/grammar/error_token.rbs +19 -0
  137. data/sig/generated/lrama/grammar/inline/resolver.rbs +26 -0
  138. data/sig/generated/lrama/grammar/parameterized/resolver.rbs +42 -0
  139. data/sig/generated/lrama/grammar/parameterized/rhs.rbs +21 -0
  140. data/sig/generated/lrama/grammar/parameterized/rule.rbs +28 -0
  141. data/sig/{lrama → generated/lrama}/grammar/percent_code.rbs +8 -0
  142. data/sig/generated/lrama/grammar/precedence.rbs +45 -0
  143. data/sig/{lrama/grammar/error_token.rbs → generated/lrama/grammar/printer.rbs} +8 -3
  144. data/sig/generated/lrama/grammar/reference.rbs +31 -0
  145. data/sig/generated/lrama/grammar/rule.rbs +83 -0
  146. data/sig/generated/lrama/grammar/rule_builder.rbs +91 -0
  147. data/sig/generated/lrama/grammar/symbol.rbs +89 -0
  148. data/sig/generated/lrama/grammar/symbols/resolver.rbs +131 -0
  149. data/sig/generated/lrama/grammar/type.rbs +21 -0
  150. data/sig/generated/lrama/grammar/union.rbs +17 -0
  151. data/sig/generated/lrama/grammar.rbs +289 -0
  152. data/sig/generated/lrama/lexer/location.rbs +12 -3
  153. data/sig/generated/lrama/lexer/token/base.rbs +53 -0
  154. data/sig/generated/lrama/lexer/token/char.rbs +9 -2
  155. data/sig/generated/lrama/lexer/token/empty.rbs +11 -0
  156. data/sig/generated/lrama/lexer/token/ident.rbs +2 -2
  157. data/sig/generated/lrama/lexer/token/instantiate_rule.rbs +5 -5
  158. data/sig/generated/lrama/lexer/token/int.rbs +13 -0
  159. data/sig/generated/lrama/lexer/token/str.rbs +10 -0
  160. data/sig/generated/lrama/lexer/token/tag.rbs +2 -2
  161. data/sig/generated/lrama/lexer/token/token.rbs +10 -0
  162. data/sig/generated/lrama/lexer/token/user_code.rbs +2 -2
  163. data/sig/generated/lrama/lexer/token.rbs +1 -39
  164. data/sig/generated/lrama/lexer.rbs +54 -0
  165. data/sig/generated/lrama/logger.rbs +6 -0
  166. data/sig/generated/lrama/option_parser.rbs +52 -0
  167. data/sig/{lrama → generated/lrama}/options.rbs +27 -3
  168. data/sig/generated/lrama/reporter/conflicts.rbs +18 -0
  169. data/sig/generated/lrama/reporter/grammar.rbs +13 -0
  170. data/sig/generated/lrama/reporter/precedences.rbs +15 -0
  171. data/sig/generated/lrama/reporter/profile/call_stack.rbs +19 -0
  172. data/sig/generated/lrama/reporter/profile/memory.rbs +19 -0
  173. data/sig/generated/lrama/reporter/rules.rbs +13 -0
  174. data/sig/generated/lrama/reporter/states.rbs +69 -0
  175. data/sig/generated/lrama/reporter/terms.rbs +13 -0
  176. data/sig/generated/lrama/reporter.rbs +13 -0
  177. data/sig/generated/lrama/state/action/goto.rbs +28 -0
  178. data/sig/generated/lrama/state/action/reduce.rbs +49 -0
  179. data/sig/generated/lrama/state/action/shift.rbs +33 -0
  180. data/sig/generated/lrama/state/inadequacy_annotation.rbs +45 -0
  181. data/sig/generated/lrama/state/item.rbs +75 -0
  182. data/sig/generated/lrama/state/reduce_reduce_conflict.rbs +19 -0
  183. data/sig/generated/lrama/state/resolved_conflict.rbs +38 -0
  184. data/sig/generated/lrama/state/shift_reduce_conflict.rbs +19 -0
  185. data/sig/generated/lrama/state.rbs +231 -0
  186. data/sig/generated/lrama/states.rbs +215 -0
  187. data/sig/generated/lrama/tracer/actions.rbs +13 -0
  188. data/sig/generated/lrama/tracer/closure.rbs +13 -0
  189. data/sig/generated/lrama/tracer/duration.rbs +18 -0
  190. data/sig/generated/lrama/tracer/only_explicit_rules.rbs +13 -0
  191. data/sig/generated/lrama/tracer/rules.rbs +13 -0
  192. data/sig/generated/lrama/tracer/state.rbs +16 -0
  193. data/sig/generated/lrama/tracer.rbs +23 -0
  194. data/sig/generated/lrama/version.rbs +5 -0
  195. data/sig/generated/lrama/warnings/conflicts.rbs +13 -0
  196. data/sig/generated/lrama/warnings/implicit_empty.rbs +17 -0
  197. data/sig/generated/lrama/warnings/name_conflicts.rbs +31 -0
  198. data/sig/generated/lrama/warnings/redefined_rules.rbs +13 -0
  199. data/sig/generated/lrama/warnings/required.rbs +13 -0
  200. data/sig/generated/lrama/warnings/useless_precedence.rbs +13 -0
  201. data/sig/generated/lrama/warnings.rbs +11 -0
  202. data/sig/railroad_diagrams/railroad_diagrams.rbs +16 -0
  203. data/template/bison/_yacc.h +8 -0
  204. data/template/diagram/diagram.html +102 -0
  205. metadata +126 -66
  206. data/lib/lrama/counterexamples/production_path.rb +0 -19
  207. data/lib/lrama/counterexamples/start_path.rb +0 -23
  208. data/lib/lrama/counterexamples/transition_path.rb +0 -19
  209. data/lib/lrama/diagnostics.rb +0 -36
  210. data/lib/lrama/grammar/parameterizing_rule/rule.rb +0 -24
  211. data/lib/lrama/grammar/parameterizing_rule.rb +0 -5
  212. data/lib/lrama/grammar_validator.rb +0 -37
  213. data/lib/lrama/report/duration.rb +0 -27
  214. data/lib/lrama/report/profile.rb +0 -16
  215. data/lib/lrama/report.rb +0 -4
  216. data/lib/lrama/state/reduce.rb +0 -37
  217. data/lib/lrama/state/shift.rb +0 -15
  218. data/lib/lrama/states_reporter.rb +0 -362
  219. data/lib/lrama/trace_reporter.rb +0 -45
  220. data/sig/generated/lrama/trace_reporter.rbs +0 -25
  221. data/sig/lrama/counterexamples/derivation.rbs +0 -33
  222. data/sig/lrama/counterexamples/example.rbs +0 -45
  223. data/sig/lrama/counterexamples/path.rbs +0 -21
  224. data/sig/lrama/counterexamples/production_path.rbs +0 -11
  225. data/sig/lrama/counterexamples/start_path.rbs +0 -13
  226. data/sig/lrama/counterexamples/state_item.rbs +0 -10
  227. data/sig/lrama/counterexamples/transition_path.rbs +0 -11
  228. data/sig/lrama/counterexamples/triple.rbs +0 -20
  229. data/sig/lrama/counterexamples.rbs +0 -29
  230. data/sig/lrama/grammar/auxiliary.rbs +0 -10
  231. data/sig/lrama/grammar/code/destructor_code.rbs +0 -14
  232. data/sig/lrama/grammar/code/printer_code.rbs +0 -14
  233. data/sig/lrama/grammar/code/rule_action.rbs +0 -19
  234. data/sig/lrama/grammar/code.rbs +0 -24
  235. data/sig/lrama/grammar/destructor.rbs +0 -13
  236. data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +0 -24
  237. data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +0 -14
  238. data/sig/lrama/grammar/parameterizing_rule/rule.rbs +0 -16
  239. data/sig/lrama/grammar/parameterizing_rule.rbs +0 -6
  240. data/sig/lrama/grammar/precedence.rbs +0 -13
  241. data/sig/lrama/grammar/printer.rbs +0 -13
  242. data/sig/lrama/grammar/reference.rbs +0 -22
  243. data/sig/lrama/grammar/rule.rbs +0 -45
  244. data/sig/lrama/grammar/rule_builder.rbs +0 -47
  245. data/sig/lrama/grammar/symbol.rbs +0 -38
  246. data/sig/lrama/grammar/symbols/resolver.rbs +0 -60
  247. data/sig/lrama/grammar/type.rbs +0 -11
  248. data/sig/lrama/grammar/union.rbs +0 -12
  249. data/sig/lrama/grammar.rbs +0 -108
  250. data/sig/lrama/report/duration.rbs +0 -11
  251. data/sig/lrama/report/profile.rbs +0 -7
  252. data/sig/lrama/state/reduce.rbs +0 -20
  253. data/sig/lrama/state/reduce_reduce_conflict.rbs +0 -13
  254. data/sig/lrama/state/resolved_conflict.rbs +0 -14
  255. data/sig/lrama/state/shift.rbs +0 -14
  256. data/sig/lrama/state/shift_reduce_conflict.rbs +0 -13
  257. data/sig/lrama/state.rbs +0 -79
  258. data/sig/lrama/states/item.rbs +0 -30
  259. data/sig/lrama/states.rbs +0 -101
  260. data/sig/lrama/warning.rbs +0 -16
data/NEWS.md CHANGED
@@ -1,8 +1,343 @@
1
1
  # NEWS for Lrama
2
2
 
3
+ ## Lrama 0.7.1 (2025-12-24)
4
+
5
+ ### Optimize IELR
6
+
7
+ Optimized performance to a level that allows for IELR testing in practical applications.
8
+
9
+ https://github.com/ruby/lrama/pull/595
10
+ https://github.com/ruby/lrama/pull/605
11
+ https://github.com/ruby/lrama/pull/685
12
+ https://github.com/ruby/lrama/pull/700
13
+
14
+ ### Introduce counterexamples timeout
15
+
16
+ Counterexample searches can sometimes take a long time, so we've added a timeout to abort the process after a set period. The current limits are:
17
+
18
+ * 10 seconds per case
19
+ * 120 seconds total (cumulative)
20
+
21
+ Please note that these are hard-coded and cannot be modified by the user in the current version.
22
+
23
+ https://github.com/ruby/lrama/pull/623
24
+
25
+ ### Optimize Counterexamples
26
+
27
+ Optimized counterexample search performance.
28
+
29
+ https://github.com/ruby/lrama/pull/607
30
+ https://github.com/ruby/lrama/pull/610
31
+ https://github.com/ruby/lrama/pull/614
32
+ https://github.com/ruby/lrama/pull/622
33
+ https://github.com/ruby/lrama/pull/627
34
+ https://github.com/ruby/lrama/pull/629
35
+ https://github.com/ruby/lrama/pull/659
36
+
37
+ ### Support parameterized rule's arguments include inline
38
+
39
+ Allow to use %inline directive with Parameterized rules arguments. When an inline rule is used as an argument to a Parameterized rule, it expands inline at the point of use.
40
+
41
+ ```yacc
42
+ %rule %inline op : '+'
43
+ | '-'
44
+ ;
45
+ %%
46
+ operation : op?
47
+ ;
48
+ ```
49
+
50
+ This expands to:
51
+
52
+ ```yacc
53
+ operation : /* empty */
54
+ | '+'
55
+ | '-'
56
+ ;
57
+ ```
58
+
59
+ https://github.com/ruby/lrama/pull/637
60
+
61
+ ### Render conflicts of each state on output file
62
+
63
+ Added token information for conflicts in the output file.
64
+ These information are useful when a state has many actions.
65
+
66
+ ```
67
+ State 1
68
+
69
+ 4 class: keyword_class • tSTRING "end"
70
+ 5 $@1: ε • [tSTRING]
71
+ 7 class: keyword_class • $@1 tSTRING '!' "end" $@2
72
+ 8 $@3: ε • [tSTRING]
73
+ 10 class: keyword_class • $@3 tSTRING '?' "end" $@4
74
+
75
+ Conflict on tSTRING. shift/reduce($@1)
76
+ Conflict on tSTRING. shift/reduce($@3)
77
+ Conflict on tSTRING. reduce($@1)/reduce($@3)
78
+
79
+ tSTRING shift, and go to state 6
80
+
81
+ tSTRING reduce using rule 5 ($@1)
82
+ tSTRING reduce using rule 8 ($@3)
83
+
84
+ $@1 go to state 7
85
+ $@3 go to state 8
86
+ ```
87
+
88
+ https://github.com/ruby/lrama/pull/541
89
+
90
+ ### Render the origin of conflicted tokens on output file
91
+
92
+ For example, for the grammar file like below:
93
+
94
+ ```
95
+ %%
96
+
97
+ program: expr
98
+ ;
99
+
100
+ expr: expr '+' expr
101
+ | tNUMBER
102
+ ;
103
+
104
+ %%
105
+ ```
106
+
107
+ Lrama generates output file which describes where `"plus"` (`'+'`) look ahead tokens come from:
108
+
109
+ ```
110
+ State 6
111
+
112
+ 2 expr: expr • "plus" expr
113
+ 2 | expr "plus" expr • ["end of file", "plus"]
114
+
115
+ Conflict on "plus". shift/reduce(expr)
116
+ "plus" comes from state 0 goto by expr
117
+ "plus" comes from state 5 goto by expr
118
+ ```
119
+
120
+ state 0 and state 5 look like below:
121
+
122
+ ```
123
+ State 0
124
+
125
+ 0 $accept: • program "end of file"
126
+ 1 program: • expr
127
+ 2 expr: • expr "plus" expr
128
+ 3 | • tNUMBER
129
+
130
+ tNUMBER shift, and go to state 1
131
+
132
+ program go to state 2
133
+ expr go to state 3
134
+
135
+ State 5
136
+
137
+ 2 expr: • expr "plus" expr
138
+ 2 | expr "plus" • expr
139
+ 3 | • tNUMBER
140
+
141
+ tNUMBER shift, and go to state 1
142
+
143
+ expr go to state 6
144
+ ```
145
+
146
+ https://github.com/ruby/lrama/pull/726
147
+
148
+ ### Render precedences usage information on output file
149
+
150
+ For example, for the grammar file like below:
151
+
152
+ ```
153
+ %left tPLUS
154
+ %right tUPLUS
155
+
156
+ %%
157
+
158
+ program: expr ;
159
+
160
+ expr: tUPLUS expr
161
+ | expr tPLUS expr
162
+ | tNUMBER
163
+ ;
164
+
165
+ %%
166
+ ```
167
+
168
+ Lrama generates output file which describes where these precedences are used to resolve conflicts:
169
+
170
+ ```
171
+ Precedences
172
+ precedence on "unary+" is used to resolve conflict on
173
+ LALR
174
+ state 5. Conflict between reduce by "expr -> tUPLUS expr" and shift "+" resolved as reduce ("+" < "unary+").
175
+ precedence on "+" is used to resolve conflict on
176
+ LALR
177
+ state 5. Conflict between reduce by "expr -> tUPLUS expr" and shift "+" resolved as reduce ("+" < "unary+").
178
+ state 8. Conflict between reduce by "expr -> expr tPLUS expr" and shift "+" resolved as reduce (%left "+").
179
+ ```
180
+
181
+ https://github.com/ruby/lrama/pull/741
182
+
183
+ ### Add support for reporting Rule Usage Frequency
184
+
185
+ Support to report rule usage frequency statistics for analyzing grammar characteristics.
186
+ Run `exe/lrama --report=rules` to show how frequently each terminal and non-terminal symbol is used in the grammar rules.
187
+
188
+ ```console
189
+ $ exe/lrama --report=rules sample/calc.y
190
+ Rule Usage Frequency
191
+ 0 tSTRING (4 times)
192
+ 1 keyword_class (3 times)
193
+ 2 keyword_end (3 times)
194
+ 3 '+' (2 times)
195
+ 4 string (2 times)
196
+ 5 string_1 (2 times)
197
+ 6 '!' (1 times)
198
+ 7 '-' (1 times)
199
+ 8 '?' (1 times)
200
+ 9 EOI (1 times)
201
+ 10 class (1 times)
202
+ 11 program (1 times)
203
+ 12 string_2 (1 times)
204
+ 13 strings_1 (1 times)
205
+ 14 strings_2 (1 times)
206
+ 15 tNUMBER (1 times)
207
+ ```
208
+
209
+ This feature provides insights into the language characteristics by showing:
210
+ - Which symbols are most frequently used in the grammar
211
+ - The distribution of terminal and non-terminal usage
212
+ - Potential areas for grammar optimization or refactoring
213
+
214
+ The frequency statistics help developers understand the grammar structure and can be useful for:
215
+ - Grammar complexity analysis
216
+ - Performance optimization hints
217
+ - Language design decisions
218
+ - Documentation and educational purposes
219
+
220
+ https://github.com/ruby/lrama/pull/677
221
+
222
+ ### Render Split States information on output file
223
+
224
+ For example, for the grammar file like below:
225
+
226
+ ```
227
+ %token a
228
+ %token b
229
+ %token c
230
+ %define lr.type ielr
231
+
232
+ %precedence tLOWEST
233
+ %precedence a
234
+ %precedence tHIGHEST
235
+
236
+ %%
237
+
238
+ S: a A B a
239
+ | b A B b
240
+ ;
241
+
242
+ A: a C D E
243
+ ;
244
+
245
+ B: c
246
+ | // empty
247
+ ;
248
+
249
+ C: D
250
+ ;
251
+
252
+ D: a
253
+ ;
254
+
255
+ E: a
256
+ | %prec tHIGHEST // empty
257
+ ;
258
+
259
+ %%
260
+ ```
261
+
262
+ Lrama generates output file which describes where which new states are created when IELR is enabled:
263
+
264
+ ```
265
+ Split States
266
+
267
+ State 19 is split from state 4
268
+ State 20 is split from state 9
269
+ State 21 is split from state 14
270
+ ```
271
+
272
+ https://github.com/ruby/lrama/pull/624
273
+
274
+ ### Add ioption support to the Standard library
275
+
276
+ Support `ioption` (inline option) rule, which is expanded inline without creating intermediate rules.
277
+
278
+ Unlike the regular `option` rule that generates a separate rule, `ioption` directly expands at the point of use:
279
+
280
+ ```yacc
281
+ program: ioption(number) expr
282
+
283
+ // Expanded inline to:
284
+
285
+ program: expr
286
+ | number expr
287
+ ```
288
+
289
+ This differs from the regular `option` which would generate:
290
+
291
+ ```yacc
292
+ program: option(number) expr
293
+
294
+ // Expanded to:
295
+
296
+ program: option_number expr
297
+ option_number: %empty
298
+ | number
299
+ ```
300
+
301
+ The `ioption` rule provides more compact grammar generation by avoiding intermediate rule creation, which can be beneficial for reducing the parser's rule count and potentially improving performance.
302
+
303
+ This feature is inspired by Menhir's standard library and maintains compatibility with [Menhir's `ioption` behavior](https://github.com/let-def/menhir/blob/e8ba7bef219acd355798072c42abbd11335ecf09/src/standard.mly#L33-L41).
304
+
305
+ https://github.com/ruby/lrama/pull/666
306
+
307
+ ### Syntax Diagrams
308
+
309
+ Lrama provides an API for generating HTML syntax diagrams. These visual diagrams are highly useful as grammar development tools and can also serve as a form of automatic self-documentation.
310
+
311
+ ![Syntax Diagrams](https://github.com/user-attachments/assets/5d9bca77-93fd-4416-bc24-9a0f70693a22)
312
+
313
+ If you use syntax diagrams, you add `--diagram` option.
314
+
315
+ ```console
316
+ $ exe/lrama --diagram sample.y
317
+ ```
318
+
319
+ https://github.com/ruby/lrama/pull/523
320
+
321
+ ### Support `--profile` option
322
+
323
+ You can profile parser generation process without modification for Lrama source code.
324
+ Currently `--profile=call-stack` and `--profile=memory` are supported.
325
+
326
+ ```console
327
+ $ exe/lrama --profile=call-stack sample/calc.y
328
+ ```
329
+
330
+ Then "tmp/stackprof-cpu-myapp.dump" is generated.
331
+
332
+ https://github.com/ruby/lrama/pull/525
333
+
334
+ ### Add support Start-Symbol: `%start`
335
+
336
+ https://github.com/ruby/lrama/pull/576
337
+
3
338
  ## Lrama 0.7.0 (2025-01-21)
4
339
 
5
- ## [EXPERIMENTAL] Support the generation of the IELR(1) parser described in this paper
340
+ ### [EXPERIMENTAL] Support the generation of the IELR(1) parser described in this paper
6
341
 
7
342
  Support the generation of the IELR(1) parser described in this paper.
8
343
  https://www.sciencedirect.com/science/article/pii/S0167642309001191
@@ -15,12 +350,12 @@ If you use IELR(1) parser, you can write the following directive in your grammar
15
350
 
16
351
  But, currently IELR(1) parser is experimental feature. If you find any bugs, please report it to us. Thank you.
17
352
 
18
- ## Support `-t` option as same as `--debug` option
353
+ ### Support `-t` option as same as `--debug` option
19
354
 
20
355
  Support to `-t` option as same as `--debug` option.
21
356
  These options align with Bison behavior. So same as `--debug` option.
22
357
 
23
- ## Trace only explicit rules
358
+ ### Trace only explicit rules
24
359
 
25
360
  Support to trace only explicit rules.
26
361
  If you use `--trace=rules` option, it shows include mid-rule actions. If you want to show only explicit rules, you can use `--trace=only-explicit-rules` option.
@@ -97,9 +432,9 @@ nterm.y:6:7: symbol EOI redeclared as a nonterminal
97
432
 
98
433
  ## Lrama 0.6.10 (2024-09-11)
99
434
 
100
- ### Aliased Named References for actions of RHS in parameterizing rules
435
+ ### Aliased Named References for actions of RHS in Parameterizing rules
101
436
 
102
- Allow to use aliased named references for actions of RHS in parameterizing rules.
437
+ Allow to use aliased named references for actions of RHS in Parameterizing rules.
103
438
 
104
439
  ```yacc
105
440
  %rule sum(X, Y): X[summand] '+' Y[addend] { $$ = $summand + $addend }
@@ -109,9 +444,9 @@ Allow to use aliased named references for actions of RHS in parameterizing rules
109
444
  https://github.com/ruby/lrama/pull/410
110
445
 
111
446
 
112
- ### Named References for actions of RHS in parameterizing rules caller side
447
+ ### Named References for actions of RHS in Parameterizing rules caller side
113
448
 
114
- Allow to use named references for actions of RHS in parameterizing rules caller side.
449
+ Allow to use named references for actions of RHS in Parameterizing rules caller side.
115
450
 
116
451
  ```yacc
117
452
  opt_nl: '\n'?[nl] <str> { $$ = $nl; }
@@ -120,9 +455,9 @@ opt_nl: '\n'?[nl] <str> { $$ = $nl; }
120
455
 
121
456
  https://github.com/ruby/lrama/pull/414
122
457
 
123
- ### Widen the definable position of parameterizing rules
458
+ ### Widen the definable position of Parameterizing rules
124
459
 
125
- Allow to define parameterizing rules in the middle of the grammar.
460
+ Allow to define Parameterizing rules in the middle of the grammar.
126
461
 
127
462
  ```yacc
128
463
  %rule defined_option(X): /* empty */
@@ -186,15 +521,15 @@ Change to `%locations` directive not set by default.
186
521
 
187
522
  https://github.com/ruby/lrama/pull/446
188
523
 
189
- ### Diagnostics report for parameterizing rules redefine
524
+ ### Diagnostics report for parameterized rules redefine
190
525
 
191
- Support to warning redefined parameterizing rules.
192
- Run `exe/lrama -W` or `exe/lrama --warnings` to show redefined parameterizing rules.
526
+ Support to warning redefined parameterized rules.
527
+ Run `exe/lrama -W` or `exe/lrama --warnings` to show redefined parameterized rules.
193
528
 
194
529
  ```console
195
530
  $ exe/lrama -W sample/calc.y
196
- parameterizing rule redefined: redefined_method(X)
197
- parameterizing rule redefined: redefined_method(X)
531
+ parameterized rule redefined: redefined_method(X)
532
+ parameterized rule redefined: redefined_method(X)
198
533
  ```
199
534
 
200
535
  https://github.com/ruby/lrama/pull/448
@@ -208,9 +543,9 @@ https://github.com/ruby/lrama/pull/457
208
543
 
209
544
  ## Lrama 0.6.9 (2024-05-02)
210
545
 
211
- ### Callee side tag specification of parameterizing rules
546
+ ### Callee side tag specification of Parameterizing rules
212
547
 
213
- Allow to specify tag on callee side of parameterizing rules.
548
+ Allow to specify tag on callee side of Parameterizing rules.
214
549
 
215
550
  ```yacc
216
551
  %union {
@@ -221,9 +556,9 @@ Allow to specify tag on callee side of parameterizing rules.
221
556
  ;
222
557
  ```
223
558
 
224
- ### Named References for actions of RHS in parameterizing rules
559
+ ### Named References for actions of RHS in Parameterizing rules
225
560
 
226
- Allow to use named references for actions of RHS in parameterizing rules.
561
+ Allow to use named references for actions of RHS in Parameterizing rules.
227
562
 
228
563
  ```yacc
229
564
  %rule option(number): /* empty */
@@ -233,9 +568,9 @@ Allow to use named references for actions of RHS in parameterizing rules.
233
568
 
234
569
  ## Lrama 0.6.8 (2024-04-29)
235
570
 
236
- ### Nested parameterizing rules with tag
571
+ ### Nested Parameterizing rules with tag
237
572
 
238
- Allow to nested parameterizing rules with tag.
573
+ Allow to nested Parameterizing rules with tag.
239
574
 
240
575
  ```yacc
241
576
  %union {
@@ -257,9 +592,9 @@ Allow to nested parameterizing rules with tag.
257
592
 
258
593
  ## Lrama 0.6.7 (2024-04-28)
259
594
 
260
- ### RHS of user defined parameterizing rules contains `'symbol'?`, `'symbol'+` and `'symbol'*`.
595
+ ### RHS of user defined Parameterizing rules contains `'symbol'?`, `'symbol'+` and `'symbol'*`.
261
596
 
262
- User can use `'symbol'?`, `'symbol'+` and `'symbol'*` in RHS of user defined parameterizing rules.
597
+ User can use `'symbol'?`, `'symbol'+` and `'symbol'*` in RHS of user defined Parameterizing rules.
263
598
 
264
599
  ```
265
600
  %rule with_word_seps(X): /* empty */
@@ -319,7 +654,7 @@ expr : number { $$ = $1; }
319
654
 
320
655
  ### Typed Midrule Actions
321
656
 
322
- User can specify the type of mid rule action by tag (`<bar>`) instead of specifying it with in an action.
657
+ User can specify the type of mid-rule action by tag (`<bar>`) instead of specifying it with in an action.
323
658
 
324
659
  ```yacc
325
660
  primary: k_case expr_value terms?
@@ -394,7 +729,7 @@ https://github.com/ruby/lrama/pull/382
394
729
 
395
730
  User can set codes for freeing semantic value resources by using `%destructor`.
396
731
  In general, these resources are freed by actions or after parsing.
397
- However if syntax error happens in parsing, these codes may not be executed.
732
+ However, if syntax error happens in parsing, these codes may not be executed.
398
733
  Codes associated to `%destructor` are executed when semantic value is popped from the stack by an error.
399
734
 
400
735
  ```yacc
@@ -432,7 +767,7 @@ Lrama introduces two features to support another semantic value stack by parser
432
767
  1. Callback entry points
433
768
 
434
769
  User can emulate semantic value stack by these callbacks.
435
- Lrama provides these five callbacks. Registered functions are called when each event happen. For example %after-shift function is called when shift happens on original semantic value stack.
770
+ Lrama provides these five callbacks. Registered functions are called when each event happens. For example %after-shift function is called when shift happens on original semantic value stack.
436
771
 
437
772
  * `%after-shift` function_name
438
773
  * `%before-reduce` function_name
@@ -460,15 +795,15 @@ https://github.com/ruby/lrama/pull/367
460
795
  ### %no-stdlib directive
461
796
 
462
797
  If `%no-stdlib` directive is set, Lrama doesn't load Lrama standard library for
463
- parameterizing rules, stdlib.y.
798
+ parameterized rules, stdlib.y.
464
799
 
465
800
  https://github.com/ruby/lrama/pull/344
466
801
 
467
802
  ## Lrama 0.6.1 (2024-01-13)
468
803
 
469
- ### Nested parameterizing rules
804
+ ### Nested Parameterizing rules
470
805
 
471
- Allow to pass an instantiated rule to other parameterizing rules.
806
+ Allow to pass an instantiated rule to other Parameterizing rules.
472
807
 
473
808
  ```yacc
474
809
  %rule constant(X) : X
@@ -485,7 +820,7 @@ program : option(constant(number)) // Nested rule
485
820
  %%
486
821
  ```
487
822
 
488
- Allow to use nested parameterizing rules when define parameterizing rules.
823
+ Allow to use nested Parameterizing rules when define Parameterizing rules.
489
824
 
490
825
  ```yacc
491
826
  %rule option(x) : /* empty */
@@ -510,9 +845,9 @@ https://github.com/ruby/lrama/pull/337
510
845
 
511
846
  ## Lrama 0.6.0 (2023-12-25)
512
847
 
513
- ### User defined parameterizing rules
848
+ ### User defined Parameterizing rules
514
849
 
515
- Allow to define parameterizing rule by `%rule` directive.
850
+ Allow to define Parameterizing rule by `%rule` directive.
516
851
 
517
852
  ```yacc
518
853
  %rule pair(X, Y): X Y { $$ = $1 + $2; }
@@ -532,7 +867,7 @@ https://github.com/ruby/lrama/pull/285
532
867
 
533
868
  ## Lrama 0.5.11 (2023-12-02)
534
869
 
535
- ### Type specification of parameterizing rules
870
+ ### Type specification of Parameterizing rules
536
871
 
537
872
  Allow to specify type of rules by specifying tag, `<i>` in below example.
538
873
  Tag is post-modification style.
@@ -556,13 +891,13 @@ https://github.com/ruby/lrama/pull/272
556
891
 
557
892
  ### Parameterizing rules (option, nonempty_list, list)
558
893
 
559
- Support function call style parameterizing rules for `option`, `nonempty_list` and `list`.
894
+ Support function call style Parameterizing rules for `option`, `nonempty_list` and `list`.
560
895
 
561
896
  https://github.com/ruby/lrama/pull/197
562
897
 
563
898
  ### Parameterizing rules (separated_list)
564
899
 
565
- Support `separated_list` and `separated_nonempty_list` parameterizing rules.
900
+ Support `separated_list` and `separated_nonempty_list` Parameterizing rules.
566
901
 
567
902
  ```text
568
903
  program: separated_list(',', number)
@@ -618,7 +953,7 @@ https://github.com/ruby/lrama/pull/181
618
953
 
619
954
  ### Racc parser
620
955
 
621
- Replace Lrama's parser from hand written parser to LR parser generated by Racc.
956
+ Replace Lrama's parser from handwritten parser to LR parser generated by Racc.
622
957
  Lrama uses `--embedded` option to generate LR parser because Racc is changed from default gem to bundled gem by Ruby 3.3 (https://github.com/ruby/lrama/pull/132).
623
958
 
624
959
  https://github.com/ruby/lrama/pull/62
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![build](https://github.com/ruby/lrama/actions/workflows/test.yaml/badge.svg)](https://github.com/ruby/lrama/actions/workflows/test.yaml)
5
5
  [![RubyDoc](https://img.shields.io/badge/%F0%9F%93%9ARubyDoc-documentation-informational.svg)](https://www.rubydoc.info/gems/lrama)
6
6
 
7
- Lrama is LALR (1) parser generator written by Ruby. The first goal of this project is providing error tolerant parser for CRuby with minimal changes on CRuby parse.y file.
7
+ Lrama (pronounced in the same way as the noun “llama” in English) is LALR (1) parser generator written by Ruby. The first goal of this project is providing error tolerant parser for CRuby with minimal changes on CRuby parse.y file.
8
8
 
9
9
  - [Features](#features)
10
10
  - [Installation](#installation)
@@ -20,15 +20,6 @@ Lrama is LALR (1) parser generator written by Ruby. The first goal of this proje
20
20
  - [How to generate parser.rb](#how-to-generate-parserrb)
21
21
  - [How to Write a Type Signature](#how-to-write-a-type-signature)
22
22
  - [Test](#test)
23
- - [Call-stack Profiling Lrama](#call-stack-profiling-lrama)
24
- - [1. Create parse.tmp.y in ruby/ruby](#1-create-parsetmpy-in-rubyruby)
25
- - [2. Enable Profiler](#2-enable-profiler)
26
- - [3. Run Lrama](#3-run-lrama)
27
- - [4. Generate Flamegraph](#4-generate-flamegraph)
28
- - [Memory Profiling Lrama](#memory-profiling-lrama)
29
- - [1. Create parse.tmp.y in ruby/ruby](#1-create-parsetmpy-in-rubyruby-1)
30
- - [2. Enable Profiler](#2-enable-profiler-1)
31
- - [3. Run Lrama](#3-run-lrama-1)
32
23
  - [Build Ruby](#build-ruby)
33
24
  - [Release flow](#release-flow)
34
25
  - [License](#license)
@@ -44,10 +35,13 @@ Lrama is LALR (1) parser generator written by Ruby. The first goal of this proje
44
35
  * Subset of [Repairing Syntax Errors in LR Parsers (Corchuelo et al.)](https://idus.us.es/bitstream/handle/11441/65631/Repairing%20syntax%20errors.pdf) algorithm is supported
45
36
  * Parameterizing rules
46
37
  * The definition of a non-terminal symbol can be parameterized with other (terminal or non-terminal) symbols.
47
- * Providing a generic definition of parameterizing rules as a [standard library](lib/lrama/grammar/stdlib.y).
38
+ * Providing a generic definition of parameterized rules as a [standard library](lib/lrama/grammar/stdlib.y).
48
39
  * Inlining
49
40
  * The %inline directive causes all references to symbols to be replaced with its definition.
50
41
  * Resolve shift/reduce conflicts without artificially altering the grammar file.
42
+ * Syntax Diagrams
43
+ * Easily generate syntax diagrams from the grammar file.
44
+ * These visual diagrams are an useful development tool for grammar development and can also function as automatic self-documentation.
51
45
 
52
46
  ## Installation
53
47
 
@@ -62,7 +56,7 @@ $ cd "$(lrama root)"
62
56
  $ bundle install
63
57
  $ bundle exec rake install
64
58
  $ bundle exec lrama --version
65
- 0.5.0
59
+ lrama 0.7.0
66
60
  ```
67
61
 
68
62
  ## Usage
@@ -108,9 +102,7 @@ This branch generates "parse.c" compatible with Bison 3.8.2 for ruby 3.0, 3.1, 3
108
102
 
109
103
  ## Supported Ruby version
110
104
 
111
- Lrama is executed with BASERUBY when building ruby from source code. Therefore Lrama needs to support BASERUBY, currently 2.5, or later version.
112
-
113
- This also requires Lrama to be able to run with only default gems because BASERUBY runs with `--disable=gems` option.
105
+ See [Supported Ruby version](/doc/Index.md#supported-ruby-version) in doc.
114
106
 
115
107
  ## Development
116
108
 
@@ -159,79 +151,6 @@ $ bundle install
159
151
  $ bundle exec rake
160
152
  ```
161
153
 
162
- ### Call-stack Profiling Lrama
163
-
164
- #### 1. Create parse.tmp.y in ruby/ruby
165
-
166
- ```shell
167
- $ ruby tool/id2token.rb parse.y > parse.tmp.y
168
- $ cp parse.tmp.y dir/lrama/tmp
169
- ```
170
-
171
- #### 2. Enable Profiler
172
-
173
- ```diff
174
- diff --git a/exe/lrama b/exe/lrama
175
- index ba5fb06..2497178 100755
176
- --- a/exe/lrama
177
- +++ b/exe/lrama
178
- @@ -3,4 +3,6 @@
179
- $LOAD_PATH << File.join(__dir__, "../lib")
180
- require "lrama"
181
-
182
- -Lrama::Command.new.run(ARGV.dup)
183
- +Lrama::Report::Profile.report_profile do
184
- + Lrama::Command.new.run(ARGV.dup)
185
- +end
186
- ```
187
-
188
- #### 3. Run Lrama
189
-
190
- ```shell
191
- $ exe/lrama -o parse.tmp.c --header=parse.tmp.h tmp/parse.tmp.y
192
- ```
193
-
194
- #### 4. Generate Flamegraph
195
-
196
- ```shell
197
- $ stackprof --d3-flamegraph tmp/stackprof-cpu-myapp.dump > tmp/flamegraph.html
198
- ```
199
-
200
- ### Memory Profiling Lrama
201
-
202
- #### 1. Create parse.tmp.y in ruby/ruby
203
-
204
- ```shell
205
- $ ruby tool/id2token.rb parse.y > parse.tmp.y
206
- $ cp parse.tmp.y dir/lrama/tmp
207
- ```
208
-
209
- #### 2. Enable Profiler
210
-
211
- ```diff
212
- diff --git a/exe/lrama b/exe/lrama
213
- index 1aece5d141..f5f94cf7fa 100755
214
- --- a/exe/lrama
215
- +++ b/exe/lrama
216
- @@ -3,5 +3,9 @@
217
-
218
- $LOAD_PATH << File.join(__dir__, "../lib")
219
- require "lrama"
220
- +require 'memory_profiler'
221
-
222
- -Lrama::Command.new.run(ARGV.dup)
223
- +report = MemoryProfiler.report do
224
- + Lrama::Command.new.run(ARGV.dup)
225
- +end
226
- +report.pretty_print
227
- ```
228
-
229
- #### 3. Run Lrama
230
-
231
- ```shell
232
- $ exe/lrama -o parse.tmp.c --header=parse.tmp.h tmp/parse.tmp.y > report.txt
233
- ```
234
-
235
154
  ### Build Ruby
236
155
 
237
156
  1. Install Lrama