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
@@ -1,15 +1,38 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  class Grammar
5
6
  class RuleBuilder
6
- attr_accessor :lhs, :line
7
- attr_reader :lhs_tag, :rhs, :user_code, :precedence_sym
8
-
9
- def initialize(rule_counter, midrule_action_counter, parameterizing_rule_resolver, position_in_original_rule_rhs = nil, lhs_tag: nil, skip_preprocess_references: false)
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
+ # @position_in_original_rule_rhs: Integer?
13
+ # @skip_preprocess_references: bool
14
+ # @rules: Array[Rule]
15
+ # @rule_builders_for_parameterized: Array[RuleBuilder]
16
+ # @rule_builders_for_derived_rules: Array[RuleBuilder]
17
+ # @parameterized_rules: Array[Rule]
18
+ # @midrule_action_rules: Array[Rule]
19
+ # @replaced_rhs: Array[Lexer::Token::Base]?
20
+
21
+ attr_accessor :lhs #: Lexer::Token::Base?
22
+ attr_accessor :line #: Integer?
23
+ attr_reader :rule_counter #: Counter
24
+ attr_reader :midrule_action_counter #: Counter
25
+ attr_reader :parameterized_resolver #: Grammar::Parameterized::Resolver
26
+ attr_reader :lhs_tag #: Lexer::Token::Tag?
27
+ attr_reader :rhs #: Array[Lexer::Token::Base]
28
+ attr_reader :user_code #: Lexer::Token::UserCode?
29
+ attr_reader :precedence_sym #: Grammar::Symbol?
30
+
31
+ # @rbs (Counter rule_counter, Counter midrule_action_counter, Grammar::Parameterized::Resolver parameterized_resolver, ?Integer position_in_original_rule_rhs, ?lhs_tag: Lexer::Token::Tag?, ?skip_preprocess_references: bool) -> void
32
+ def initialize(rule_counter, midrule_action_counter, parameterized_resolver, position_in_original_rule_rhs = nil, lhs_tag: nil, skip_preprocess_references: false)
10
33
  @rule_counter = rule_counter
11
34
  @midrule_action_counter = midrule_action_counter
12
- @parameterizing_rule_resolver = parameterizing_rule_resolver
35
+ @parameterized_resolver = parameterized_resolver
13
36
  @position_in_original_rule_rhs = position_in_original_rule_rhs
14
37
  @skip_preprocess_references = skip_preprocess_references
15
38
 
@@ -20,12 +43,13 @@ module Lrama
20
43
  @precedence_sym = nil
21
44
  @line = nil
22
45
  @rules = []
23
- @rule_builders_for_parameterizing_rules = []
46
+ @rule_builders_for_parameterized = []
24
47
  @rule_builders_for_derived_rules = []
25
- @parameterizing_rules = []
48
+ @parameterized_rules = []
26
49
  @midrule_action_rules = []
27
50
  end
28
51
 
52
+ # @rbs (Lexer::Token::Base rhs) -> void
29
53
  def add_rhs(rhs)
30
54
  @line ||= rhs.line
31
55
 
@@ -34,6 +58,7 @@ module Lrama
34
58
  @rhs << rhs
35
59
  end
36
60
 
61
+ # @rbs (Lexer::Token::UserCode? user_code) -> void
37
62
  def user_code=(user_code)
38
63
  @line ||= user_code&.line
39
64
 
@@ -42,72 +67,59 @@ module Lrama
42
67
  @user_code = user_code
43
68
  end
44
69
 
70
+ # @rbs (Grammar::Symbol? precedence_sym) -> void
45
71
  def precedence_sym=(precedence_sym)
46
72
  flush_user_code
47
73
 
48
74
  @precedence_sym = precedence_sym
49
75
  end
50
76
 
77
+ # @rbs () -> void
51
78
  def complete_input
52
79
  freeze_rhs
53
80
  end
54
81
 
82
+ # @rbs () -> void
55
83
  def setup_rules
56
84
  preprocess_references unless @skip_preprocess_references
57
85
  process_rhs
86
+ resolve_inline_rules
58
87
  build_rules
59
88
  end
60
89
 
90
+ # @rbs () -> Array[Grammar::Rule]
61
91
  def rules
62
- @parameterizing_rules + @midrule_action_rules + @rules
92
+ @parameterized_rules + @midrule_action_rules + @rules
63
93
  end
64
94
 
95
+ # @rbs () -> bool
65
96
  def has_inline_rules?
66
- rhs.any? { |token| @parameterizing_rule_resolver.find_inline(token) }
67
- end
68
-
69
- def resolve_inline_rules
70
- resolved_builders = [] #: Array[RuleBuilder]
71
- rhs.each_with_index do |token, i|
72
- if (inline_rule = @parameterizing_rule_resolver.find_inline(token))
73
- inline_rule.rhs_list.each do |inline_rhs|
74
- rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: lhs_tag)
75
- if token.is_a?(Lexer::Token::InstantiateRule)
76
- resolve_inline_rhs(rule_builder, inline_rhs, i, Binding.new(inline_rule.parameters, token.args))
77
- else
78
- resolve_inline_rhs(rule_builder, inline_rhs, i)
79
- end
80
- rule_builder.lhs = lhs
81
- rule_builder.line = line
82
- rule_builder.precedence_sym = precedence_sym
83
- rule_builder.user_code = replace_inline_user_code(inline_rhs, i)
84
- resolved_builders << rule_builder
85
- end
86
- break
87
- end
88
- end
89
- resolved_builders
97
+ rhs.any? { |token| @parameterized_resolver.find_inline(token) }
90
98
  end
91
99
 
92
100
  private
93
101
 
102
+ # @rbs () -> void
94
103
  def freeze_rhs
95
104
  @rhs.freeze
96
105
  end
97
106
 
107
+ # @rbs () -> void
98
108
  def preprocess_references
99
109
  numberize_references
100
110
  end
101
111
 
112
+ # @rbs () -> void
102
113
  def build_rules
103
- tokens = @replaced_rhs
114
+ tokens = @replaced_rhs #: Array[Lexer::Token::Base]
115
+ return if tokens.any? { |t| @parameterized_resolver.find_inline(t) }
104
116
 
105
117
  rule = Rule.new(
106
118
  id: @rule_counter.increment, _lhs: lhs, _rhs: tokens, lhs_tag: lhs_tag, token_code: user_code,
107
119
  position_in_original_rule_rhs: @position_in_original_rule_rhs, precedence_sym: precedence_sym, lineno: line
108
120
  )
109
121
  @rules = [rule]
110
- @parameterizing_rules = @rule_builders_for_parameterizing_rules.map do |rule_builder|
122
+ @parameterized_rules = @rule_builders_for_parameterized.map do |rule_builder|
111
123
  rule_builder.rules
112
124
  end.flatten
113
125
  @midrule_action_rules = @rule_builders_for_derived_rules.map do |rule_builder|
@@ -120,31 +132,33 @@ module Lrama
120
132
 
121
133
  # rhs is a mixture of variety type of tokens like `Ident`, `InstantiateRule`, `UserCode` and so on.
122
134
  # `#process_rhs` replaces some kind of tokens to `Ident` so that all `@replaced_rhs` are `Ident` or `Char`.
135
+ #
136
+ # @rbs () -> void
123
137
  def process_rhs
124
138
  return if @replaced_rhs
125
139
 
126
- @replaced_rhs = []
140
+ replaced_rhs = [] #: Array[Lexer::Token::Base]
127
141
 
128
142
  rhs.each_with_index do |token, i|
129
143
  case token
130
144
  when Lrama::Lexer::Token::Char
131
- @replaced_rhs << token
145
+ replaced_rhs << token
132
146
  when Lrama::Lexer::Token::Ident
133
- @replaced_rhs << token
147
+ replaced_rhs << token
134
148
  when Lrama::Lexer::Token::InstantiateRule
135
- parameterizing_rule = @parameterizing_rule_resolver.find_rule(token)
136
- raise "Unexpected token. #{token}" unless parameterizing_rule
149
+ parameterized_rule = @parameterized_resolver.find_rule(token)
150
+ raise "Unexpected token. #{token}" unless parameterized_rule
137
151
 
138
- bindings = Binding.new(parameterizing_rule.parameters, token.args)
152
+ bindings = Binding.new(parameterized_rule.parameters, token.args)
139
153
  lhs_s_value = bindings.concatenated_args_str(token)
140
- if (created_lhs = @parameterizing_rule_resolver.created_lhs(lhs_s_value))
141
- @replaced_rhs << created_lhs
154
+ if (created_lhs = @parameterized_resolver.created_lhs(lhs_s_value))
155
+ replaced_rhs << created_lhs
142
156
  else
143
157
  lhs_token = Lrama::Lexer::Token::Ident.new(s_value: lhs_s_value, location: token.location)
144
- @replaced_rhs << lhs_token
145
- @parameterizing_rule_resolver.created_lhs_list << lhs_token
146
- parameterizing_rule.rhs_list.each do |r|
147
- rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: token.lhs_tag || parameterizing_rule.tag)
158
+ replaced_rhs << lhs_token
159
+ @parameterized_resolver.created_lhs_list << lhs_token
160
+ parameterized_rule.rhs.each do |r|
161
+ rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterized_resolver, lhs_tag: token.lhs_tag || parameterized_rule.tag)
148
162
  rule_builder.lhs = lhs_token
149
163
  r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) }
150
164
  rule_builder.line = line
@@ -152,51 +166,48 @@ module Lrama
152
166
  rule_builder.user_code = r.resolve_user_code(bindings)
153
167
  rule_builder.complete_input
154
168
  rule_builder.setup_rules
155
- @rule_builders_for_parameterizing_rules << rule_builder
169
+ @rule_builders_for_parameterized << rule_builder
156
170
  end
157
171
  end
158
172
  when Lrama::Lexer::Token::UserCode
159
173
  prefix = token.referred ? "@" : "$@"
160
174
  tag = token.tag || lhs_tag
161
175
  new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + @midrule_action_counter.increment.to_s)
162
- @replaced_rhs << new_token
176
+ replaced_rhs << new_token
163
177
 
164
- rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, i, lhs_tag: tag, skip_preprocess_references: true)
178
+ rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterized_resolver, i, lhs_tag: tag, skip_preprocess_references: true)
165
179
  rule_builder.lhs = new_token
166
180
  rule_builder.user_code = token
167
181
  rule_builder.complete_input
168
182
  rule_builder.setup_rules
169
183
 
170
184
  @rule_builders_for_derived_rules << rule_builder
185
+ when Lrama::Lexer::Token::Empty
186
+ # Noop
171
187
  else
172
188
  raise "Unexpected token. #{token}"
173
189
  end
174
190
  end
175
- end
176
191
 
177
- def resolve_inline_rhs(rule_builder, inline_rhs, index, bindings = nil)
178
- rhs.each_with_index do |token, i|
179
- if index == i
180
- inline_rhs.symbols.each { |sym| rule_builder.add_rhs(bindings.nil? ? sym : bindings.resolve_symbol(sym)) }
181
- else
182
- rule_builder.add_rhs(token)
183
- end
184
- end
192
+ @replaced_rhs = replaced_rhs
185
193
  end
186
194
 
187
- def replace_inline_user_code(inline_rhs, index)
188
- return user_code if inline_rhs.user_code.nil?
189
- return user_code if user_code.nil?
190
-
191
- code = user_code.s_value.gsub(/\$#{index + 1}/, inline_rhs.user_code.s_value)
192
- user_code.references.each do |ref|
193
- next if ref.index.nil? || ref.index <= index # nil is a case for `$$`
194
- code = code.gsub(/\$#{ref.index}/, "$#{ref.index + (inline_rhs.symbols.count-1)}")
195
- code = code.gsub(/@#{ref.index}/, "@#{ref.index + (inline_rhs.symbols.count-1)}")
195
+ # @rbs () -> void
196
+ def resolve_inline_rules
197
+ while @rule_builders_for_parameterized.any?(&:has_inline_rules?) do
198
+ @rule_builders_for_parameterized = @rule_builders_for_parameterized.flat_map do |rule_builder|
199
+ if rule_builder.has_inline_rules?
200
+ inlined_builders = Inline::Resolver.new(rule_builder).resolve
201
+ inlined_builders.each { |builder| builder.setup_rules }
202
+ inlined_builders
203
+ else
204
+ rule_builder
205
+ end
206
+ end
196
207
  end
197
- Lrama::Lexer::Token::UserCode.new(s_value: code, location: user_code.location)
198
208
  end
199
209
 
210
+ # @rbs () -> void
200
211
  def numberize_references
201
212
  # Bison n'th component is 1-origin
202
213
  (rhs + [user_code]).compact.each.with_index(1) do |token, i|
@@ -209,7 +220,10 @@ module Lrama
209
220
  if ref_name == '$'
210
221
  ref.name = '$'
211
222
  else
212
- candidates = ([lhs] + rhs).each_with_index.select {|token, _i| token.referred_by?(ref_name) }
223
+ candidates = ([lhs] + rhs).each_with_index.select do |token, _i|
224
+ # @type var token: Lexer::Token::Base
225
+ token.referred_by?(ref_name)
226
+ end
213
227
 
214
228
  if candidates.size >= 2
215
229
  token.invalid_ref(ref, "Referring symbol `#{ref_name}` is duplicated.")
@@ -244,6 +258,7 @@ module Lrama
244
258
  end
245
259
  end
246
260
 
261
+ # @rbs () -> void
247
262
  def flush_user_code
248
263
  if (c = @user_code)
249
264
  @rhs << c
@@ -3,26 +3,43 @@
3
3
  stdlib.y
4
4
 
5
5
  This is lrama's standard library. It provides a number of
6
- parameterizing rule definitions, such as options and lists,
6
+ parameterized rule definitions, such as options and lists,
7
7
  that should be useful in a number of situations.
8
8
 
9
9
  **********************************************************************/
10
10
 
11
+ %%
12
+
11
13
  // -------------------------------------------------------------------
12
14
  // Options
13
15
 
14
16
  /*
15
- * program: option(number)
17
+ * program: option(X)
18
+ *
19
+ * =>
20
+ *
21
+ * program: option_X
22
+ * option_X: %empty
23
+ * option_X: X
24
+ */
25
+ %rule option(X)
26
+ : /* empty */
27
+ | X
28
+ ;
29
+
30
+
31
+ /*
32
+ * program: ioption(X)
16
33
  *
17
34
  * =>
18
35
  *
19
- * program: option_number
20
- * option_number: %empty
21
- * option_number: number
36
+ * program: %empty
37
+ * program: X
22
38
  */
23
- %rule option(X): /* empty */
24
- | X
25
- ;
39
+ %rule %inline ioption(X)
40
+ : /* empty */
41
+ | X
42
+ ;
26
43
 
27
44
  // -------------------------------------------------------------------
28
45
  // Sequences
@@ -35,8 +52,9 @@
35
52
  * program: preceded_opening_X
36
53
  * preceded_opening_X: opening X
37
54
  */
38
- %rule preceded(opening, X): opening X { $$ = $2; }
39
- ;
55
+ %rule preceded(opening, X)
56
+ : opening X { $$ = $2; }
57
+ ;
40
58
 
41
59
  /*
42
60
  * program: terminated(X, closing)
@@ -46,8 +64,9 @@
46
64
  * program: terminated_X_closing
47
65
  * terminated_X_closing: X closing
48
66
  */
49
- %rule terminated(X, closing): X closing { $$ = $1; }
50
- ;
67
+ %rule terminated(X, closing)
68
+ : X closing { $$ = $1; }
69
+ ;
51
70
 
52
71
  /*
53
72
  * program: delimited(opening, X, closing)
@@ -57,66 +76,67 @@
57
76
  * program: delimited_opening_X_closing
58
77
  * delimited_opening_X_closing: opening X closing
59
78
  */
60
- %rule delimited(opening, X, closing): opening X closing { $$ = $2; }
61
- ;
79
+ %rule delimited(opening, X, closing)
80
+ : opening X closing { $$ = $2; }
81
+ ;
62
82
 
63
83
  // -------------------------------------------------------------------
64
84
  // Lists
65
85
 
66
86
  /*
67
- * program: list(number)
87
+ * program: list(X)
68
88
  *
69
89
  * =>
70
90
  *
71
- * program: list_number
72
- * list_number: %empty
73
- * list_number: list_number number
91
+ * program: list_X
92
+ * list_X: %empty
93
+ * list_X: list_X X
74
94
  */
75
- %rule list(X): /* empty */
76
- | list(X) X
77
- ;
95
+ %rule list(X)
96
+ : /* empty */
97
+ | list(X) X
98
+ ;
78
99
 
79
100
  /*
80
- * program: nonempty_list(number)
101
+ * program: nonempty_list(X)
81
102
  *
82
103
  * =>
83
104
  *
84
- * program: nonempty_list_number
85
- * nonempty_list_number: number
86
- * nonempty_list_number: nonempty_list_number number
105
+ * program: nonempty_list_X
106
+ * nonempty_list_X: X
107
+ * nonempty_list_X: nonempty_list_X X
87
108
  */
88
- %rule nonempty_list(X): X
89
- | nonempty_list(X) X
90
- ;
109
+ %rule nonempty_list(X)
110
+ : X
111
+ | nonempty_list(X) X
112
+ ;
91
113
 
92
114
  /*
93
- * program: separated_nonempty_list(comma, number)
115
+ * program: separated_nonempty_list(separator, X)
94
116
  *
95
117
  * =>
96
118
  *
97
- * program: separated_nonempty_list_comma_number
98
- * separated_nonempty_list_comma_number: number
99
- * separated_nonempty_list_comma_number: separated_nonempty_list_comma_number comma number
119
+ * program: separated_nonempty_list_separator_X
120
+ * separated_nonempty_list_separator_X: X
121
+ * separated_nonempty_list_separator_X: separated_nonempty_list_separator_X separator X
100
122
  */
101
- %rule separated_nonempty_list(separator, X): X
102
- | separated_nonempty_list(separator, X) separator X
103
- ;
123
+ %rule separated_nonempty_list(separator, X)
124
+ : X
125
+ | separated_nonempty_list(separator, X) separator X
126
+ ;
104
127
 
105
128
  /*
106
- * program: separated_list(comma, number)
129
+ * program: separated_list(separator, X)
107
130
  *
108
131
  * =>
109
132
  *
110
- * program: separated_list_comma_number
111
- * separated_list_comma_number: option_separated_nonempty_list_comma_number
112
- * option_separated_nonempty_list_comma_number: %empty
113
- * option_separated_nonempty_list_comma_number: separated_nonempty_list_comma_number
114
- * separated_nonempty_list_comma_number: number
115
- * separated_nonempty_list_comma_number: comma separated_nonempty_list_comma_number number
133
+ * program: separated_list_separator_X
134
+ * separated_list_separator_X: option_separated_nonempty_list_separator_X
135
+ * option_separated_nonempty_list_separator_X: %empty
136
+ * option_separated_nonempty_list_separator_X: separated_nonempty_list_separator_X
137
+ * separated_nonempty_list_separator_X: X
138
+ * separated_nonempty_list_separator_X: separator separated_nonempty_list_separator_X X
116
139
  */
117
- %rule separated_list(separator, X): option(separated_nonempty_list(separator, X))
118
- ;
119
-
120
- %%
121
-
122
- %union{};
140
+ %rule separated_list(separator, X)
141
+ : option(separated_nonempty_list(separator, X))
142
+ ;
@@ -1,19 +1,35 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  # Symbol is both of nterm and term
4
5
  # `number` is both for nterm and term
5
6
  # `token_id` is tokentype for term, internal sequence number for nterm
6
7
  #
7
- # TODO: Add validation for ASCII code range for Token::Char
8
8
 
9
9
  module Lrama
10
10
  class Grammar
11
11
  class Symbol
12
- attr_accessor :id, :alias_name, :tag, :number, :token_id, :nullable, :precedence,
13
- :printer, :destructor, :error_token, :first_set, :first_set_bitmap
14
- attr_reader :term
15
- attr_writer :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol
12
+ attr_accessor :id #: Lexer::Token::Base
13
+ attr_accessor :alias_name #: String?
14
+ attr_reader :number #: Integer
15
+ attr_accessor :number_bitmap #: Bitmap::bitmap
16
+ attr_accessor :tag #: Lexer::Token::Tag?
17
+ attr_accessor :token_id #: Integer
18
+ attr_accessor :nullable #: bool
19
+ attr_accessor :precedence #: Precedence?
20
+ attr_accessor :printer #: Printer?
21
+ attr_accessor :destructor #: Destructor?
22
+ attr_accessor :error_token #: ErrorToken
23
+ attr_accessor :first_set #: Set[Grammar::Symbol]
24
+ attr_accessor :first_set_bitmap #: Bitmap::bitmap
25
+ attr_reader :term #: bool
26
+ attr_writer :eof_symbol #: bool
27
+ attr_writer :error_symbol #: bool
28
+ attr_writer :undef_symbol #: bool
29
+ attr_writer :accept_symbol #: bool
16
30
 
31
+ # @rbs (id: Lexer::Token::Base, term: bool, ?alias_name: String?, ?number: Integer?, ?tag: Lexer::Token::Tag?,
32
+ # ?token_id: Integer?, ?nullable: bool?, ?precedence: Precedence?, ?printer: Printer?) -> void
17
33
  def initialize(id:, term:, alias_name: nil, number: nil, tag: nil, token_id: nil, nullable: nil, precedence: nil, printer: nil, destructor: nil)
18
34
  @id = id
19
35
  @alias_name = alias_name
@@ -27,77 +43,105 @@ module Lrama
27
43
  @destructor = destructor
28
44
  end
29
45
 
46
+ # @rbs (Integer) -> void
47
+ def number=(number)
48
+ @number = number
49
+ @number_bitmap = Bitmap::from_integer(number)
50
+ end
51
+
52
+ # @rbs () -> bool
30
53
  def term?
31
54
  term
32
55
  end
33
56
 
57
+ # @rbs () -> bool
34
58
  def nterm?
35
59
  !term
36
60
  end
37
61
 
62
+ # @rbs () -> bool
38
63
  def eof_symbol?
39
64
  !!@eof_symbol
40
65
  end
41
66
 
67
+ # @rbs () -> bool
42
68
  def error_symbol?
43
69
  !!@error_symbol
44
70
  end
45
71
 
72
+ # @rbs () -> bool
46
73
  def undef_symbol?
47
74
  !!@undef_symbol
48
75
  end
49
76
 
77
+ # @rbs () -> bool
50
78
  def accept_symbol?
51
79
  !!@accept_symbol
52
80
  end
53
81
 
82
+ # @rbs () -> bool
83
+ def midrule?
84
+ return false if term?
85
+
86
+ name.include?("$") || name.include?("@")
87
+ end
88
+
89
+ # @rbs () -> String
90
+ def name
91
+ id.s_value
92
+ end
93
+
94
+ # @rbs () -> String
54
95
  def display_name
55
- alias_name || id.s_value
96
+ alias_name || name
56
97
  end
57
98
 
58
99
  # name for yysymbol_kind_t
59
100
  #
60
101
  # See: b4_symbol_kind_base
61
102
  # @type var name: String
103
+ # @rbs () -> String
62
104
  def enum_name
63
105
  case
64
106
  when accept_symbol?
65
- name = "YYACCEPT"
107
+ res = "YYACCEPT"
66
108
  when eof_symbol?
67
- name = "YYEOF"
109
+ res = "YYEOF"
68
110
  when term? && id.is_a?(Lrama::Lexer::Token::Char)
69
- name = number.to_s + display_name
111
+ res = number.to_s + display_name
70
112
  when term? && id.is_a?(Lrama::Lexer::Token::Ident)
71
- name = id.s_value
72
- when nterm? && (id.s_value.include?("$") || id.s_value.include?("@"))
73
- name = number.to_s + id.s_value
113
+ res = name
114
+ when midrule?
115
+ res = number.to_s + name
74
116
  when nterm?
75
- name = id.s_value
117
+ res = name
76
118
  else
77
119
  raise "Unexpected #{self}"
78
120
  end
79
121
 
80
- "YYSYMBOL_" + name.gsub(/\W+/, "_")
122
+ "YYSYMBOL_" + res.gsub(/\W+/, "_")
81
123
  end
82
124
 
83
125
  # comment for yysymbol_kind_t
126
+ #
127
+ # @rbs () -> String?
84
128
  def comment
85
129
  case
86
130
  when accept_symbol?
87
131
  # YYSYMBOL_YYACCEPT
88
- id.s_value
132
+ name
89
133
  when eof_symbol?
90
134
  # YYEOF
91
135
  alias_name
92
136
  when (term? && 0 < token_id && token_id < 128)
93
137
  # YYSYMBOL_3_backslash_, YYSYMBOL_14_
94
- alias_name || id.s_value
95
- when id.s_value.include?("$") || id.s_value.include?("@")
138
+ display_name
139
+ when midrule?
96
140
  # YYSYMBOL_21_1
97
- id.s_value
141
+ name
98
142
  else
99
143
  # YYSYMBOL_keyword_class, YYSYMBOL_strings_1
100
- alias_name || id.s_value
144
+ display_name
101
145
  end
102
146
  end
103
147
  end