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
@@ -0,0 +1,22 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Tracer
6
+ class Actions
7
+ # @rbs (IO io, ?actions: bool, **bool options) -> void
8
+ def initialize(io, actions: false, **options)
9
+ @io = io
10
+ @actions = actions
11
+ end
12
+
13
+ # @rbs (Lrama::Grammar grammar) -> void
14
+ def trace(grammar)
15
+ return unless @actions
16
+
17
+ @io << "Grammar rules with actions:" << "\n"
18
+ grammar.rules.each { |rule| @io << rule.with_actions << "\n" }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Tracer
6
+ class Closure
7
+ # @rbs (IO io, ?automaton: bool, ?closure: bool, **bool) -> void
8
+ def initialize(io, automaton: false, closure: false, **_)
9
+ @io = io
10
+ @closure = automaton || closure
11
+ end
12
+
13
+ # @rbs (Lrama::State state) -> void
14
+ def trace(state)
15
+ return unless @closure
16
+
17
+ @io << "Closure: input" << "\n"
18
+ state.kernels.each do |item|
19
+ @io << " #{item.display_rest}" << "\n"
20
+ end
21
+ @io << "\n\n"
22
+ @io << "Closure: output" << "\n"
23
+ state.items.each do |item|
24
+ @io << " #{item.display_rest}" << "\n"
25
+ end
26
+ @io << "\n\n"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Tracer
6
+ module Duration
7
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
8
+ # Move these type declarations above instance variable definitions, once it's supported.
9
+ # see: https://github.com/soutaro/rbs-inline/pull/149
10
+ #
11
+ # @rbs!
12
+ # @_report_duration_enabled: bool
13
+
14
+ # @rbs () -> void
15
+ def self.enable
16
+ @_report_duration_enabled = true
17
+ end
18
+
19
+ # @rbs () -> bool
20
+ def self.enabled?
21
+ !!@_report_duration_enabled
22
+ end
23
+
24
+ # @rbs [T] (_ToS message) { -> T } -> T
25
+ def report_duration(message)
26
+ time1 = Time.now.to_f
27
+ result = yield
28
+ time2 = Time.now.to_f
29
+
30
+ if Duration.enabled?
31
+ STDERR.puts sprintf("%s %10.5f s", message, time2 - time1)
32
+ end
33
+
34
+ return result
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,24 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Tracer
6
+ class OnlyExplicitRules
7
+ # @rbs (IO io, ?only_explicit: bool, **bool) -> void
8
+ def initialize(io, only_explicit: false, **_)
9
+ @io = io
10
+ @only_explicit = only_explicit
11
+ end
12
+
13
+ # @rbs (Lrama::Grammar grammar) -> void
14
+ def trace(grammar)
15
+ return unless @only_explicit
16
+
17
+ @io << "Grammar rules:" << "\n"
18
+ grammar.rules.each do |rule|
19
+ @io << rule.display_name_without_action << "\n" if rule.lhs.first_set.any?
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Tracer
6
+ class Rules
7
+ # @rbs (IO io, ?rules: bool, ?only_explicit: bool, **bool) -> void
8
+ def initialize(io, rules: false, only_explicit: false, **_)
9
+ @io = io
10
+ @rules = rules
11
+ @only_explicit = only_explicit
12
+ end
13
+
14
+ # @rbs (Lrama::Grammar grammar) -> void
15
+ def trace(grammar)
16
+ return if !@rules || @only_explicit
17
+
18
+ @io << "Grammar rules:" << "\n"
19
+ grammar.rules.each { |rule| @io << rule.display_name << "\n" }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Tracer
6
+ class State
7
+ # @rbs (IO io, ?automaton: bool, ?closure: bool, **bool) -> void
8
+ def initialize(io, automaton: false, closure: false, **_)
9
+ @io = io
10
+ @state = automaton || closure
11
+ end
12
+
13
+ # @rbs (Lrama::State state) -> void
14
+ def trace(state)
15
+ return unless @state
16
+
17
+ # Bison 3.8.2 renders "(reached by "end-of-input")" for State 0 but
18
+ # I think it is not correct...
19
+ previous = state.kernels.first.previous_sym
20
+ @io << "Processing state #{state.id} (reached by #{previous.display_name})" << "\n"
21
+ end
22
+
23
+ # @rbs (Integer state_count, Lrama::State state) -> void
24
+ def trace_list_append(state_count, state)
25
+ return unless @state
26
+
27
+ previous = state.kernels.first.previous_sym
28
+ @io << sprintf("state_list_append (state = %d, symbol = %d (%s))",
29
+ state_count, previous.number, previous.display_name) << "\n"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,51 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "tracer/actions"
5
+ require_relative "tracer/closure"
6
+ require_relative "tracer/duration"
7
+ require_relative "tracer/only_explicit_rules"
8
+ require_relative "tracer/rules"
9
+ require_relative "tracer/state"
10
+
11
+ module Lrama
12
+ class Tracer
13
+ # @rbs (IO io, **bool options) -> void
14
+ def initialize(io, **options)
15
+ @io = io
16
+ @options = options
17
+ @only_explicit_rules = OnlyExplicitRules.new(io, **options)
18
+ @rules = Rules.new(io, **options)
19
+ @actions = Actions.new(io, **options)
20
+ @closure = Closure.new(io, **options)
21
+ @state = State.new(io, **options)
22
+ end
23
+
24
+ # @rbs (Lrama::Grammar grammar) -> void
25
+ def trace(grammar)
26
+ @only_explicit_rules.trace(grammar)
27
+ @rules.trace(grammar)
28
+ @actions.trace(grammar)
29
+ end
30
+
31
+ # @rbs (Lrama::State state) -> void
32
+ def trace_closure(state)
33
+ @closure.trace(state)
34
+ end
35
+
36
+ # @rbs (Lrama::State state) -> void
37
+ def trace_state(state)
38
+ @state.trace(state)
39
+ end
40
+
41
+ # @rbs (Integer state_count, Lrama::State state) -> void
42
+ def trace_state_list_append(state_count, state)
43
+ @state.trace_list_append(state_count, state)
44
+ end
45
+
46
+ # @rbs () -> void
47
+ def enable_duration
48
+ Duration.enable if @options[:time]
49
+ end
50
+ end
51
+ end
data/lib/lrama/version.rb CHANGED
@@ -1,5 +1,6 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
- VERSION = "0.7.0".freeze
5
+ VERSION = "0.7.1".freeze #: String
5
6
  end
@@ -0,0 +1,27 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Warnings
6
+ class Conflicts
7
+ # @rbs (Lrama::Logger logger, bool warnings) -> void
8
+ def initialize(logger, warnings)
9
+ @logger = logger
10
+ @warnings = warnings
11
+ end
12
+
13
+ # @rbs (Lrama::States states) -> void
14
+ def warn(states)
15
+ return unless @warnings
16
+
17
+ if states.sr_conflicts_count != 0
18
+ @logger.warn("shift/reduce conflicts: #{states.sr_conflicts_count} found")
19
+ end
20
+
21
+ if states.rr_conflicts_count != 0
22
+ @logger.warn("reduce/reduce conflicts: #{states.rr_conflicts_count} found")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Warnings
6
+ # Warning rationale: Empty rules are easily overlooked and ambiguous
7
+ # - Empty alternatives like `rule: | "token";` can be missed during code reading
8
+ # - Difficult to distinguish between intentional empty rules vs. omissions
9
+ # - Explicit marking with %empty directive comment improves clarity
10
+ class ImplicitEmpty
11
+ # @rbs (Lrama::Logger logger, bool warnings) -> void
12
+ def initialize(logger, warnings)
13
+ @logger = logger
14
+ @warnings = warnings
15
+ end
16
+
17
+ # @rbs (Lrama::Grammar grammar) -> void
18
+ def warn(grammar)
19
+ return unless @warnings
20
+
21
+ grammar.rule_builders.each do |builder|
22
+ if builder.rhs.empty?
23
+ @logger.warn("warning: empty rule without %empty")
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Warnings
6
+ # Warning rationale: Parameterized rule names conflicting with symbol names
7
+ # - When a %rule name is identical to a terminal or non-terminal symbol name,
8
+ # it reduces grammar readability and may cause unintended behavior
9
+ # - Detecting these conflicts helps improve grammar definition quality
10
+ class NameConflicts
11
+ # @rbs (Lrama::Logger logger, bool warnings) -> void
12
+ def initialize(logger, warnings)
13
+ @logger = logger
14
+ @warnings = warnings
15
+ end
16
+
17
+ # @rbs (Lrama::Grammar grammar) -> void
18
+ def warn(grammar)
19
+ return unless @warnings
20
+ return if grammar.parameterized_rules.empty?
21
+
22
+ symbol_names = collect_symbol_names(grammar)
23
+ check_conflicts(grammar.parameterized_rules, symbol_names)
24
+ end
25
+
26
+ private
27
+
28
+ # @rbs (Lrama::Grammar grammar) -> Set[String]
29
+ def collect_symbol_names(grammar)
30
+ symbol_names = Set.new
31
+
32
+ collect_term_names(grammar.terms, symbol_names)
33
+ collect_nterm_names(grammar.nterms, symbol_names)
34
+
35
+ symbol_names
36
+ end
37
+
38
+ # @rbs (Array[untyped] terms, Set[String] symbol_names) -> void
39
+ def collect_term_names(terms, symbol_names)
40
+ terms.each do |term|
41
+ symbol_names.add(term.id.s_value)
42
+ symbol_names.add(term.alias_name) if term.alias_name
43
+ end
44
+ end
45
+
46
+ # @rbs (Array[untyped] nterms, Set[String] symbol_names) -> void
47
+ def collect_nterm_names(nterms, symbol_names)
48
+ nterms.each do |nterm|
49
+ symbol_names.add(nterm.id.s_value)
50
+ end
51
+ end
52
+
53
+ # @rbs (Array[untyped] parameterized_rules, Set[String] symbol_names) -> void
54
+ def check_conflicts(parameterized_rules, symbol_names)
55
+ parameterized_rules.each do |param_rule|
56
+ next unless symbol_names.include?(param_rule.name)
57
+
58
+ @logger.warn("warning: parameterized rule name \"#{param_rule.name}\" conflicts with symbol name")
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,23 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Warnings
6
+ class RedefinedRules
7
+ # @rbs (Lrama::Logger logger, bool warnings) -> void
8
+ def initialize(logger, warnings)
9
+ @logger = logger
10
+ @warnings = warnings
11
+ end
12
+
13
+ # @rbs (Lrama::Grammar grammar) -> void
14
+ def warn(grammar)
15
+ return unless @warnings
16
+
17
+ grammar.parameterized_resolver.redefined_rules.each do |rule|
18
+ @logger.warn("parameterized rule redefined: #{rule}")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Warnings
6
+ class Required
7
+ # @rbs (Lrama::Logger logger, bool warnings) -> void
8
+ def initialize(logger, warnings = false, **_)
9
+ @logger = logger
10
+ @warnings = warnings
11
+ end
12
+
13
+ # @rbs (Lrama::Grammar grammar) -> void
14
+ def warn(grammar)
15
+ return unless @warnings
16
+
17
+ if grammar.required
18
+ @logger.warn("currently, %require is simply valid as a grammar but does nothing")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Warnings
6
+ class UselessPrecedence
7
+ # @rbs (Lrama::Logger logger, bool warnings) -> void
8
+ def initialize(logger, warnings)
9
+ @logger = logger
10
+ @warnings = warnings
11
+ end
12
+
13
+ # @rbs (Lrama::Grammar grammar, Lrama::States states) -> void
14
+ def warn(grammar, states)
15
+ return unless @warnings
16
+
17
+ grammar.precedences.each do |precedence|
18
+ unless precedence.used_by?
19
+ @logger.warn("Precedence #{precedence.s_value} (line: #{precedence.lineno}) is defined but not used in any rule.")
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'warnings/conflicts'
5
+ require_relative 'warnings/implicit_empty'
6
+ require_relative 'warnings/name_conflicts'
7
+ require_relative 'warnings/redefined_rules'
8
+ require_relative 'warnings/required'
9
+ require_relative 'warnings/useless_precedence'
10
+
11
+ module Lrama
12
+ class Warnings
13
+ # @rbs (Logger logger, bool warnings) -> void
14
+ def initialize(logger, warnings)
15
+ @conflicts = Conflicts.new(logger, warnings)
16
+ @implicit_empty = ImplicitEmpty.new(logger, warnings)
17
+ @name_conflicts = NameConflicts.new(logger, warnings)
18
+ @redefined_rules = RedefinedRules.new(logger, warnings)
19
+ @required = Required.new(logger, warnings)
20
+ @useless_precedence = UselessPrecedence.new(logger, warnings)
21
+ end
22
+
23
+ # @rbs (Lrama::Grammar grammar, Lrama::States states) -> void
24
+ def warn(grammar, states)
25
+ @conflicts.warn(states)
26
+ @implicit_empty.warn(grammar)
27
+ @name_conflicts.warn(grammar)
28
+ @redefined_rules.warn(grammar)
29
+ @required.warn(grammar)
30
+ @useless_precedence.warn(grammar, states)
31
+ end
32
+ end
33
+ end
data/lib/lrama.rb CHANGED
@@ -4,19 +4,19 @@ require_relative "lrama/bitmap"
4
4
  require_relative "lrama/command"
5
5
  require_relative "lrama/context"
6
6
  require_relative "lrama/counterexamples"
7
- require_relative "lrama/diagnostics"
7
+ require_relative "lrama/diagram"
8
8
  require_relative "lrama/digraph"
9
+ require_relative "lrama/erb"
9
10
  require_relative "lrama/grammar"
10
- require_relative "lrama/grammar_validator"
11
11
  require_relative "lrama/lexer"
12
12
  require_relative "lrama/logger"
13
13
  require_relative "lrama/option_parser"
14
14
  require_relative "lrama/options"
15
15
  require_relative "lrama/output"
16
16
  require_relative "lrama/parser"
17
- require_relative "lrama/report"
17
+ require_relative "lrama/reporter"
18
18
  require_relative "lrama/state"
19
19
  require_relative "lrama/states"
20
- require_relative "lrama/states_reporter"
21
- require_relative "lrama/trace_reporter"
20
+ require_relative "lrama/tracer"
22
21
  require_relative "lrama/version"
22
+ require_relative "lrama/warnings"