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,44 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class Reporter
6
+ class Terms
7
+ # @rbs (?terms: bool, **bool _) -> void
8
+ def initialize(terms: false, **_)
9
+ @terms = terms
10
+ end
11
+
12
+ # @rbs (IO io, Lrama::States states) -> void
13
+ def report(io, states)
14
+ return unless @terms
15
+
16
+ look_aheads = states.states.each do |state|
17
+ state.reduces.flat_map do |reduce|
18
+ reduce.look_ahead unless reduce.look_ahead.nil?
19
+ end
20
+ end
21
+
22
+ next_terms = states.states.flat_map do |state|
23
+ state.term_transitions.map {|shift| shift.next_sym }
24
+ end
25
+
26
+ unused_symbols = states.terms.reject do |term|
27
+ (look_aheads + next_terms).include?(term)
28
+ end
29
+
30
+ io << states.terms.count << " Terms\n\n"
31
+
32
+ io << states.nterms.count << " Non-Terminals\n\n"
33
+
34
+ unless unused_symbols.empty?
35
+ io << "#{unused_symbols.count} Unused Terms\n\n"
36
+ unused_symbols.each_with_index do |term, index|
37
+ io << sprintf("%5d %s", index, term.id.s_value) << "\n"
38
+ end
39
+ io << "\n\n"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,39 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'reporter/conflicts'
5
+ require_relative 'reporter/grammar'
6
+ require_relative 'reporter/precedences'
7
+ require_relative 'reporter/profile'
8
+ require_relative 'reporter/rules'
9
+ require_relative 'reporter/states'
10
+ require_relative 'reporter/terms'
11
+
12
+ module Lrama
13
+ class Reporter
14
+ include Lrama::Tracer::Duration
15
+
16
+ # @rbs (**bool options) -> void
17
+ def initialize(**options)
18
+ @options = options
19
+ @rules = Rules.new(**options)
20
+ @terms = Terms.new(**options)
21
+ @conflicts = Conflicts.new
22
+ @precedences = Precedences.new
23
+ @grammar = Grammar.new(**options)
24
+ @states = States.new(**options)
25
+ end
26
+
27
+ # @rbs (File io, Lrama::States states) -> void
28
+ def report(io, states)
29
+ report_duration(:report) do
30
+ report_duration(:report_rules) { @rules.report(io, states) }
31
+ report_duration(:report_terms) { @terms.report(io, states) }
32
+ report_duration(:report_conflicts) { @conflicts.report(io, states) }
33
+ report_duration(:report_precedences) { @precedences.report(io, states) }
34
+ report_duration(:report_grammar) { @grammar.report(io, states) }
35
+ report_duration(:report_states) { @states.report(io, states, ielr: states.ielr_defined?) }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class State
6
+ class Action
7
+ class Goto
8
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
9
+ # Move these type declarations above instance variable definitions, once it's supported.
10
+ # see: https://github.com/soutaro/rbs-inline/pull/149
11
+ #
12
+ # @rbs!
13
+ # @from_state: State
14
+ # @next_sym: Grammar::Symbol
15
+ # @to_items: Array[Item]
16
+ # @to_state: State
17
+
18
+ attr_reader :from_state #: State
19
+ attr_reader :next_sym #: Grammar::Symbol
20
+ attr_reader :to_items #: Array[Item]
21
+ attr_reader :to_state #: State
22
+
23
+ # @rbs (State from_state, Grammar::Symbol next_sym, Array[Item] to_items, State to_state) -> void
24
+ def initialize(from_state, next_sym, to_items, to_state)
25
+ @from_state = from_state
26
+ @next_sym = next_sym
27
+ @to_items = to_items
28
+ @to_state = to_state
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,71 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class State
6
+ class Action
7
+ class Reduce
8
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
9
+ # Move these type declarations above instance variable definitions, once it's supported.
10
+ # see: https://github.com/soutaro/rbs-inline/pull/149
11
+ #
12
+ # @rbs!
13
+ # @item: Item
14
+ # @look_ahead: Array[Grammar::Symbol]?
15
+ # @look_ahead_sources: Hash[Grammar::Symbol, Array[Action::Goto]]?
16
+ # @not_selected_symbols: Array[Grammar::Symbol]
17
+
18
+ attr_reader :item #: Item
19
+ attr_reader :look_ahead #: Array[Grammar::Symbol]?
20
+ attr_reader :look_ahead_sources #: Hash[Grammar::Symbol, Array[Action::Goto]]?
21
+ attr_reader :not_selected_symbols #: Array[Grammar::Symbol]
22
+
23
+ # https://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html
24
+ attr_accessor :default_reduction #: bool
25
+
26
+ # @rbs (Item item) -> void
27
+ def initialize(item)
28
+ @item = item
29
+ @look_ahead = nil
30
+ @look_ahead_sources = nil
31
+ @not_selected_symbols = []
32
+ end
33
+
34
+ # @rbs () -> Grammar::Rule
35
+ def rule
36
+ @item.rule
37
+ end
38
+
39
+ # @rbs (Array[Grammar::Symbol] look_ahead) -> Array[Grammar::Symbol]
40
+ def look_ahead=(look_ahead)
41
+ @look_ahead = look_ahead.freeze
42
+ end
43
+
44
+ # @rbs (Hash[Grammar::Symbol, Array[Action::Goto]] sources) -> Hash[Grammar::Symbol, Array[Action::Goto]]
45
+ def look_ahead_sources=(sources)
46
+ @look_ahead_sources = sources.freeze
47
+ end
48
+
49
+ # @rbs (Grammar::Symbol sym) -> Array[Grammar::Symbol]
50
+ def add_not_selected_symbol(sym)
51
+ @not_selected_symbols << sym
52
+ end
53
+
54
+ # @rbs () -> (::Array[Grammar::Symbol?])
55
+ def selected_look_ahead
56
+ if look_ahead
57
+ look_ahead - @not_selected_symbols
58
+ else
59
+ []
60
+ end
61
+ end
62
+
63
+ # @rbs () -> void
64
+ def clear_conflicts
65
+ @not_selected_symbols = []
66
+ @default_reduction = nil
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,39 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class State
6
+ class Action
7
+ class Shift
8
+ # TODO: rbs-inline 0.11.0 doesn't support instance variables.
9
+ # Move these type declarations above instance variable definitions, once it's supported.
10
+ # see: https://github.com/soutaro/rbs-inline/pull/149
11
+ #
12
+ # @rbs!
13
+ # @from_state: State
14
+ # @next_sym: Grammar::Symbol
15
+ # @to_items: Array[Item]
16
+ # @to_state: State
17
+
18
+ attr_reader :from_state #: State
19
+ attr_reader :next_sym #: Grammar::Symbol
20
+ attr_reader :to_items #: Array[Item]
21
+ attr_reader :to_state #: State
22
+ attr_accessor :not_selected #: bool
23
+
24
+ # @rbs (State from_state, Grammar::Symbol next_sym, Array[Item] to_items, State to_state) -> void
25
+ def initialize(from_state, next_sym, to_items, to_state)
26
+ @from_state = from_state
27
+ @next_sym = next_sym
28
+ @to_items = to_items
29
+ @to_state = to_state
30
+ end
31
+
32
+ # @rbs () -> void
33
+ def clear_conflicts
34
+ @not_selected = nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "action/goto"
4
+ require_relative "action/reduce"
5
+ require_relative "action/shift"
@@ -0,0 +1,140 @@
1
+ # rbs_inline: enabled
2
+ # frozen_string_literal: true
3
+
4
+ module Lrama
5
+ class State
6
+ class InadequacyAnnotation
7
+ # @rbs!
8
+ # type action = Action::Shift | Action::Reduce
9
+
10
+ attr_accessor :state #: State
11
+ attr_accessor :token #: Grammar::Symbol
12
+ attr_accessor :actions #: Array[action]
13
+ attr_accessor :contribution_matrix #: Hash[action, Hash[Item, bool]]
14
+
15
+ # @rbs (State state, Grammar::Symbol token, Array[action] actions, Hash[action, Hash[Item, bool]] contribution_matrix) -> void
16
+ def initialize(state, token, actions, contribution_matrix)
17
+ @state = state
18
+ @token = token
19
+ @actions = actions
20
+ @contribution_matrix = contribution_matrix
21
+ end
22
+
23
+ # @rbs (Item item) -> bool
24
+ def contributed?(item)
25
+ @contribution_matrix.any? {|action, contributions| !contributions.nil? && contributions[item] }
26
+ end
27
+
28
+ # @rbs (Array[Hash[action, Hash[Item, bool]]] another_matrixes) -> void
29
+ def merge_matrix(another_matrixes)
30
+ another_matrixes.each do |another_matrix|
31
+ @contribution_matrix.merge!(another_matrix) {|action, contributions, another_contributions|
32
+ next contributions if another_contributions.nil?
33
+ next another_contributions if contributions.nil?
34
+
35
+ contributions.merge!(another_contributions) {|_, contributed, another_contributed| contributed || another_contributed }
36
+ }
37
+ end
38
+ end
39
+
40
+ # Definition 3.42 (dominant_contribution)
41
+ #
42
+ # @rbs (State::lookahead_set lookaheads) -> Array[action]?
43
+ def dominant_contribution(lookaheads)
44
+ actions = @actions.select {|action|
45
+ contribution_matrix[action].nil? || contribution_matrix[action].any? {|item, contributed| contributed && lookaheads[item].include?(@token) }
46
+ }
47
+ return nil if actions.empty?
48
+
49
+ resolve_conflict(actions)
50
+ end
51
+
52
+ # @rbs (Array[action] actions) -> Array[action]
53
+ def resolve_conflict(actions)
54
+ # @type var shifts: Array[Action::Shift]
55
+ # @type var reduces: Array[Action::Reduce]
56
+ shifts = actions.select {|action| action.is_a?(Action::Shift)}
57
+ reduces = actions.select {|action| action.is_a?(Action::Reduce) }
58
+
59
+ shifts.each do |shift|
60
+ reduces.each do |reduce|
61
+ sym = shift.next_sym
62
+
63
+ shift_prec = sym.precedence
64
+ reduce_prec = reduce.item.rule.precedence
65
+
66
+ # Can resolve only when both have prec
67
+ unless shift_prec && reduce_prec
68
+ next
69
+ end
70
+
71
+ case
72
+ when shift_prec < reduce_prec
73
+ # Reduce is selected
74
+ actions.delete(shift)
75
+ next
76
+ when shift_prec > reduce_prec
77
+ # Shift is selected
78
+ actions.delete(reduce)
79
+ next
80
+ end
81
+
82
+ # shift_prec == reduce_prec, then check associativity
83
+ case sym.precedence&.type
84
+ when :precedence
85
+ # %precedence only specifies precedence and not specify associativity
86
+ # then a conflict is unresolved if precedence is same.
87
+ next
88
+ when :right
89
+ # Shift is selected
90
+ actions.delete(reduce)
91
+ next
92
+ when :left
93
+ # Reduce is selected
94
+ actions.delete(shift)
95
+ next
96
+ when :nonassoc
97
+ # Can not resolve
98
+ #
99
+ # nonassoc creates "run-time" error, precedence creates "compile-time" error.
100
+ # Then omit both the shift and reduce.
101
+ #
102
+ # https://www.gnu.org/software/bison/manual/html_node/Using-Precedence.html
103
+ actions.delete(shift)
104
+ actions.delete(reduce)
105
+ else
106
+ raise "Unknown precedence type. #{sym}"
107
+ end
108
+ end
109
+ end
110
+
111
+ actions
112
+ end
113
+
114
+ # @rbs () -> String
115
+ def to_s
116
+ "State: #{@state.id}, Token: #{@token.id.s_value}, Actions: #{actions_to_s}, Contributions: #{contribution_matrix_to_s}"
117
+ end
118
+
119
+ private
120
+
121
+ # @rbs () -> String
122
+ def actions_to_s
123
+ '[' + @actions.map {|action|
124
+ if action.is_a?(Action::Shift) || action.is_a?(Action::Goto)
125
+ action.class.name
126
+ elsif action.is_a?(Action::Reduce)
127
+ "#{action.class.name}: (#{action.item})"
128
+ end
129
+ }.join(', ') + ']'
130
+ end
131
+
132
+ # @rbs () -> String
133
+ def contribution_matrix_to_s
134
+ '[' + @contribution_matrix.map {|action, contributions|
135
+ "#{(action.is_a?(Action::Shift) || action.is_a?(Action::Goto)) ? action.class.name : "#{action.class.name}: (#{action.item})"}: " + contributions&.transform_keys(&:to_s).to_s
136
+ }.join(', ') + ']'
137
+ end
138
+ end
139
+ end
140
+ end
@@ -1,3 +1,4 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  # TODO: Validate position is not over rule rhs
@@ -5,84 +6,112 @@
5
6
  require "forwardable"
6
7
 
7
8
  module Lrama
8
- class States
9
+ class State
9
10
  class Item < Struct.new(:rule, :position, keyword_init: true)
11
+ # @rbs!
12
+ # include Grammar::Rule::_DelegatedMethods
13
+ #
14
+ # attr_accessor rule: Grammar::Rule
15
+ # attr_accessor position: Integer
16
+ #
17
+ # def initialize: (?rule: Grammar::Rule, ?position: Integer) -> void
18
+
10
19
  extend Forwardable
11
20
 
12
21
  def_delegators "rule", :lhs, :rhs
13
22
 
14
23
  # Optimization for States#setup_state
24
+ #
25
+ # @rbs () -> Integer
15
26
  def hash
16
27
  [rule_id, position].hash
17
28
  end
18
29
 
30
+ # @rbs () -> Integer
19
31
  def rule_id
20
32
  rule.id
21
33
  end
22
34
 
35
+ # @rbs () -> bool
23
36
  def empty_rule?
24
37
  rule.empty_rule?
25
38
  end
26
39
 
40
+ # @rbs () -> Integer
27
41
  def number_of_rest_symbols
28
- rhs.count - position
42
+ @number_of_rest_symbols ||= rhs.count - position
29
43
  end
30
44
 
45
+ # @rbs () -> Grammar::Symbol
31
46
  def next_sym
32
47
  rhs[position]
33
48
  end
34
49
 
50
+ # @rbs () -> Grammar::Symbol
35
51
  def next_next_sym
36
- rhs[position + 1]
52
+ @next_next_sym ||= rhs[position + 1]
37
53
  end
38
54
 
55
+ # @rbs () -> Grammar::Symbol
39
56
  def previous_sym
40
57
  rhs[position - 1]
41
58
  end
42
59
 
60
+ # @rbs () -> bool
43
61
  def end_of_rule?
44
62
  rhs.count == position
45
63
  end
46
64
 
65
+ # @rbs () -> bool
47
66
  def beginning_of_rule?
48
67
  position == 0
49
68
  end
50
69
 
70
+ # @rbs () -> bool
51
71
  def start_item?
52
72
  rule.initial_rule? && beginning_of_rule?
53
73
  end
54
74
 
75
+ # @rbs () -> State::Item
55
76
  def new_by_next_position
56
77
  Item.new(rule: rule, position: position + 1)
57
78
  end
58
79
 
80
+ # @rbs () -> Array[Grammar::Symbol]
59
81
  def symbols_before_dot # steep:ignore
60
82
  rhs[0...position]
61
83
  end
62
84
 
85
+ # @rbs () -> Array[Grammar::Symbol]
63
86
  def symbols_after_dot # steep:ignore
64
87
  rhs[position..-1]
65
88
  end
66
89
 
67
- def symbols_after_transition
90
+ # @rbs () -> Array[Grammar::Symbol]
91
+ def symbols_after_transition # steep:ignore
68
92
  rhs[position+1..-1]
69
93
  end
70
94
 
95
+ # @rbs () -> ::String
71
96
  def to_s
72
97
  "#{lhs.id.s_value}: #{display_name}"
73
98
  end
74
99
 
100
+ # @rbs () -> ::String
75
101
  def display_name
76
102
  r = rhs.map(&:display_name).insert(position, "•").join(" ")
77
103
  "#{r} (rule #{rule_id})"
78
104
  end
79
105
 
80
106
  # Right after position
107
+ #
108
+ # @rbs () -> ::String
81
109
  def display_rest
82
110
  r = symbols_after_dot.map(&:display_name).join(" ")
83
111
  ". #{r} (rule #{rule_id})"
84
112
  end
85
113
 
114
+ # @rbs (State::Item other_item) -> bool
86
115
  def predecessor_item_of?(other_item)
87
116
  rule == other_item.rule && position == other_item.position - 1
88
117
  end
@@ -1,8 +1,21 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class State
5
- class ReduceReduceConflict < Struct.new(:symbols, :reduce1, :reduce2, keyword_init: true)
6
+ class ReduceReduceConflict
7
+ attr_reader :symbols #: Array[Grammar::Symbol]
8
+ attr_reader :reduce1 #: State::Action::Reduce
9
+ attr_reader :reduce2 #: State::Action::Reduce
10
+
11
+ # @rbs (symbols: Array[Grammar::Symbol], reduce1: State::Action::Reduce, reduce2: State::Action::Reduce) -> void
12
+ def initialize(symbols:, reduce1:, reduce2:)
13
+ @symbols = symbols
14
+ @reduce1 = reduce1
15
+ @reduce2 = reduce2
16
+ end
17
+
18
+ # @rbs () -> :reduce_reduce
6
19
  def type
7
20
  :reduce_reduce
8
21
  end
@@ -1,20 +1,54 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class State
6
+ # * state: A state on which the conflct is resolved
5
7
  # * symbol: A symbol under discussion
6
8
  # * reduce: A reduce under discussion
7
9
  # * which: For which a conflict is resolved. :shift, :reduce or :error (for nonassociative)
8
- class ResolvedConflict < Struct.new(:symbol, :reduce, :which, :same_prec, keyword_init: true)
10
+ # * resolved_by_precedence: If the conflict is resolved by precedence definition or not
11
+ class ResolvedConflict
12
+ # @rbs!
13
+ # type which_enum = :reduce | :shift | :error
14
+
15
+ attr_reader :state #: State
16
+ attr_reader :symbol #: Grammar::Symbol
17
+ attr_reader :reduce #: State::Action::Reduce
18
+ attr_reader :which #: which_enum
19
+ attr_reader :resolved_by_precedence #: bool
20
+
21
+ # @rbs (state: State, symbol: Grammar::Symbol, reduce: State::Action::Reduce, which: which_enum, resolved_by_precedence: bool) -> void
22
+ def initialize(state:, symbol:, reduce:, which:, resolved_by_precedence:)
23
+ @state = state
24
+ @symbol = symbol
25
+ @reduce = reduce
26
+ @which = which
27
+ @resolved_by_precedence = resolved_by_precedence
28
+ end
29
+
30
+ # @rbs () -> (::String | bot)
9
31
  def report_message
32
+ "Conflict between rule #{reduce.rule.id} and token #{symbol.display_name} #{how_resolved}."
33
+ end
34
+
35
+ # @rbs () -> (::String | bot)
36
+ def report_precedences_message
37
+ "Conflict between reduce by \"#{reduce.rule.display_name}\" and shift #{symbol.display_name} #{how_resolved}."
38
+ end
39
+
40
+ private
41
+
42
+ # @rbs () -> (::String | bot)
43
+ def how_resolved
10
44
  s = symbol.display_name
11
45
  r = reduce.rule.precedence_sym&.display_name
12
46
  case
13
- when which == :shift && same_prec
47
+ when which == :shift && resolved_by_precedence
14
48
  msg = "resolved as #{which} (%right #{s})"
15
49
  when which == :shift
16
50
  msg = "resolved as #{which} (#{r} < #{s})"
17
- when which == :reduce && same_prec
51
+ when which == :reduce && resolved_by_precedence
18
52
  msg = "resolved as #{which} (%left #{s})"
19
53
  when which == :reduce
20
54
  msg = "resolved as #{which} (#{s} < #{r})"
@@ -24,7 +58,7 @@ module Lrama
24
58
  raise "Unknown direction. #{self}"
25
59
  end
26
60
 
27
- "Conflict between rule #{reduce.rule.id} and token #{s} #{msg}."
61
+ msg
28
62
  end
29
63
  end
30
64
  end
@@ -1,8 +1,21 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class State
5
- class ShiftReduceConflict < Struct.new(:symbols, :shift, :reduce, keyword_init: true)
6
+ class ShiftReduceConflict
7
+ attr_reader :symbols #: Array[Grammar::Symbol]
8
+ attr_reader :shift #: State::Action::Shift
9
+ attr_reader :reduce #: State::Action::Reduce
10
+
11
+ # @rbs (symbols: Array[Grammar::Symbol], shift: State::Action::Shift, reduce: State::Action::Reduce) -> void
12
+ def initialize(symbols:, shift:, reduce:)
13
+ @symbols = symbols
14
+ @shift = shift
15
+ @reduce = reduce
16
+ end
17
+
18
+ # @rbs () -> :shift_reduce
6
19
  def type
7
20
  :shift_reduce
8
21
  end