lrama 0.6.9 → 0.6.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +24 -1
  3. data/.gitignore +2 -0
  4. data/Gemfile +6 -3
  5. data/NEWS.md +269 -14
  6. data/README.md +41 -4
  7. data/Rakefile +2 -0
  8. data/Steepfile +9 -17
  9. data/doc/development/compressed_state_table/main.md +635 -0
  10. data/doc/development/compressed_state_table/parse.output +174 -0
  11. data/doc/development/compressed_state_table/parse.y +22 -0
  12. data/doc/development/compressed_state_table/parser.rb +282 -0
  13. data/exe/lrama +1 -0
  14. data/lib/lrama/bitmap.rb +3 -1
  15. data/lib/lrama/command.rb +8 -14
  16. data/lib/lrama/context.rb +11 -9
  17. data/lib/lrama/counterexamples/derivation.rb +8 -5
  18. data/lib/lrama/counterexamples/example.rb +9 -4
  19. data/lib/lrama/counterexamples/path.rb +6 -0
  20. data/lib/lrama/counterexamples/production_path.rb +2 -0
  21. data/lib/lrama/counterexamples/start_path.rb +2 -0
  22. data/lib/lrama/counterexamples/state_item.rb +2 -0
  23. data/lib/lrama/counterexamples/transition_path.rb +2 -0
  24. data/lib/lrama/counterexamples/triple.rb +2 -0
  25. data/lib/lrama/counterexamples.rb +36 -24
  26. data/lib/lrama/diagnostics.rb +36 -0
  27. data/lib/lrama/digraph.rb +2 -0
  28. data/lib/lrama/grammar/auxiliary.rb +2 -0
  29. data/lib/lrama/grammar/binding.rb +12 -1
  30. data/lib/lrama/grammar/code/destructor_code.rb +2 -0
  31. data/lib/lrama/grammar/code/initial_action_code.rb +2 -0
  32. data/lib/lrama/grammar/code/no_reference_code.rb +2 -0
  33. data/lib/lrama/grammar/code/printer_code.rb +2 -0
  34. data/lib/lrama/grammar/code/rule_action.rb +7 -3
  35. data/lib/lrama/grammar/code.rb +7 -5
  36. data/lib/lrama/grammar/counter.rb +2 -0
  37. data/lib/lrama/grammar/destructor.rb +2 -0
  38. data/lib/lrama/grammar/error_token.rb +2 -0
  39. data/lib/lrama/grammar/parameterizing_rule/resolver.rb +7 -1
  40. data/lib/lrama/grammar/parameterizing_rule/rhs.rb +6 -3
  41. data/lib/lrama/grammar/parameterizing_rule/rule.rb +6 -0
  42. data/lib/lrama/grammar/parameterizing_rule.rb +2 -0
  43. data/lib/lrama/grammar/percent_code.rb +2 -0
  44. data/lib/lrama/grammar/precedence.rb +2 -0
  45. data/lib/lrama/grammar/printer.rb +2 -0
  46. data/lib/lrama/grammar/reference.rb +2 -0
  47. data/lib/lrama/grammar/rule.rb +10 -3
  48. data/lib/lrama/grammar/rule_builder.rb +64 -65
  49. data/lib/lrama/grammar/symbol.rb +2 -0
  50. data/lib/lrama/grammar/symbols/resolver.rb +9 -1
  51. data/lib/lrama/grammar/symbols.rb +2 -0
  52. data/lib/lrama/grammar/type.rb +2 -0
  53. data/lib/lrama/grammar/union.rb +2 -0
  54. data/lib/lrama/grammar.rb +53 -32
  55. data/lib/lrama/grammar_validator.rb +37 -0
  56. data/lib/lrama/lexer/grammar_file.rb +2 -0
  57. data/lib/lrama/lexer/location.rb +2 -0
  58. data/lib/lrama/lexer/token/char.rb +2 -0
  59. data/lib/lrama/lexer/token/ident.rb +2 -0
  60. data/lib/lrama/lexer/token/instantiate_rule.rb +2 -0
  61. data/lib/lrama/lexer/token/tag.rb +2 -0
  62. data/lib/lrama/lexer/token/user_code.rb +4 -2
  63. data/lib/lrama/lexer/token.rb +7 -5
  64. data/lib/lrama/lexer.rb +12 -8
  65. data/lib/lrama/{warning.rb → logger.rb} +5 -13
  66. data/lib/lrama/option_parser.rb +58 -33
  67. data/lib/lrama/options.rb +5 -2
  68. data/lib/lrama/output.rb +38 -69
  69. data/lib/lrama/parser.rb +677 -773
  70. data/lib/lrama/report/duration.rb +2 -0
  71. data/lib/lrama/report/profile.rb +2 -0
  72. data/lib/lrama/report.rb +4 -2
  73. data/lib/lrama/state/reduce.rb +4 -2
  74. data/lib/lrama/state/reduce_reduce_conflict.rb +2 -0
  75. data/lib/lrama/state/resolved_conflict.rb +3 -1
  76. data/lib/lrama/state/shift.rb +2 -0
  77. data/lib/lrama/state/shift_reduce_conflict.rb +2 -0
  78. data/lib/lrama/state.rb +7 -5
  79. data/lib/lrama/states/item.rb +5 -3
  80. data/lib/lrama/states.rb +18 -46
  81. data/lib/lrama/states_reporter.rb +60 -19
  82. data/lib/lrama/trace_reporter.rb +30 -0
  83. data/lib/lrama/version.rb +3 -1
  84. data/lib/lrama.rb +22 -17
  85. data/lrama.gemspec +3 -1
  86. data/parser.y +129 -237
  87. data/rbs_collection.lock.yaml +10 -2
  88. data/sig/lrama/counterexamples/derivation.rbs +33 -0
  89. data/sig/lrama/counterexamples/example.rbs +45 -0
  90. data/sig/lrama/counterexamples/path.rbs +21 -0
  91. data/sig/lrama/counterexamples/production_path.rbs +11 -0
  92. data/sig/lrama/counterexamples/start_path.rbs +13 -0
  93. data/sig/lrama/counterexamples/state_item.rbs +10 -0
  94. data/sig/lrama/counterexamples/transition_path.rbs +11 -0
  95. data/sig/lrama/counterexamples/triple.rbs +20 -0
  96. data/sig/lrama/counterexamples.rbs +29 -0
  97. data/sig/lrama/grammar/auxiliary.rbs +10 -0
  98. data/sig/lrama/grammar/binding.rbs +4 -0
  99. data/sig/lrama/grammar/code/destructor_code.rbs +3 -4
  100. data/sig/lrama/grammar/code/initial_action_code.rbs +15 -0
  101. data/sig/lrama/grammar/code/no_reference_code.rbs +15 -0
  102. data/sig/lrama/grammar/code/printer_code.rbs +3 -4
  103. data/sig/lrama/grammar/code/rule_action.rbs +19 -0
  104. data/sig/lrama/grammar/code.rbs +3 -3
  105. data/sig/lrama/grammar/destructor.rbs +3 -1
  106. data/sig/lrama/grammar/error_token.rbs +4 -2
  107. data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +2 -1
  108. data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +1 -1
  109. data/sig/lrama/grammar/precedence.rbs +3 -1
  110. data/sig/lrama/grammar/printer.rbs +3 -1
  111. data/sig/lrama/grammar/rule.rbs +35 -3
  112. data/sig/lrama/grammar/rule_builder.rbs +10 -9
  113. data/sig/lrama/grammar/symbol.rbs +6 -6
  114. data/sig/lrama/grammar/symbols/resolver.rbs +24 -5
  115. data/sig/lrama/grammar/type.rbs +2 -2
  116. data/sig/lrama/grammar/union.rbs +12 -0
  117. data/sig/lrama/grammar.rbs +104 -1
  118. data/sig/lrama/options.rbs +3 -2
  119. data/sig/lrama/state/reduce.rbs +20 -0
  120. data/sig/lrama/state/reduce_reduce_conflict.rbs +13 -0
  121. data/sig/lrama/state/resolved_conflict.rbs +14 -0
  122. data/sig/lrama/state/shift.rbs +14 -0
  123. data/sig/lrama/state/shift_reduce_conflict.rbs +13 -0
  124. data/sig/lrama/state.rbs +79 -0
  125. data/sig/lrama/states/item.rbs +30 -0
  126. data/sig/lrama/states.rbs +101 -0
  127. data/template/bison/yacc.c +24 -19
  128. metadata +32 -6
  129. data/sample/calc.output +0 -263
  130. data/sample/calc.y +0 -101
  131. data/sample/parse.y +0 -59
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class Path
@@ -18,6 +20,10 @@ module Lrama
18
20
  "#<Path(#{type})>"
19
21
  end
20
22
  alias :inspect :to_s
23
+
24
+ def type
25
+ raise NotImplementedError
26
+ end
21
27
  end
22
28
  end
23
29
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class ProductionPath < Path
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class StartPath < Path
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class StateItem < Struct.new(:state, :item)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class TransitionPath < Path
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  # s: state
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
 
3
- require "lrama/counterexamples/derivation"
4
- require "lrama/counterexamples/example"
5
- require "lrama/counterexamples/path"
6
- require "lrama/counterexamples/production_path"
7
- require "lrama/counterexamples/start_path"
8
- require "lrama/counterexamples/state_item"
9
- require "lrama/counterexamples/transition_path"
10
- require "lrama/counterexamples/triple"
5
+ require_relative "counterexamples/derivation"
6
+ require_relative "counterexamples/example"
7
+ require_relative "counterexamples/path"
8
+ require_relative "counterexamples/production_path"
9
+ require_relative "counterexamples/start_path"
10
+ require_relative "counterexamples/state_item"
11
+ require_relative "counterexamples/transition_path"
12
+ require_relative "counterexamples/triple"
11
13
 
12
14
  module Lrama
13
15
  # See: https://www.cs.cornell.edu/andru/papers/cupex/cupex.pdf
@@ -30,8 +32,10 @@ module Lrama
30
32
  conflict_state.conflicts.flat_map do |conflict|
31
33
  case conflict.type
32
34
  when :shift_reduce
35
+ # @type var conflict: State::ShiftReduceConflict
33
36
  shift_reduce_example(conflict_state, conflict)
34
37
  when :reduce_reduce
38
+ # @type var conflict: State::ReduceReduceConflict
35
39
  reduce_reduce_examples(conflict_state, conflict)
36
40
  end
37
41
  end.compact
@@ -46,7 +50,7 @@ module Lrama
46
50
  @reverse_transitions = {}
47
51
 
48
52
  @states.states.each do |src_state|
49
- trans = {}
53
+ trans = {} #: Hash[Grammar::Symbol, State]
50
54
 
51
55
  src_state.transitions.each do |shift, next_state|
52
56
  trans[shift.next_sym] = next_state
@@ -64,6 +68,7 @@ module Lrama
64
68
 
65
69
  @transitions[[src_state_item, sym]] = dest_state_item
66
70
 
71
+ # @type var key: [StateItem, Grammar::Symbol]
67
72
  key = [dest_state_item, sym]
68
73
  @reverse_transitions[key] ||= Set.new
69
74
  @reverse_transitions[key] << src_state_item
@@ -80,7 +85,7 @@ module Lrama
80
85
 
81
86
  @states.states.each do |state|
82
87
  # LHS => Set(Item)
83
- h = {}
88
+ h = {} #: Hash[Grammar::Symbol, Set[States::Item]]
84
89
 
85
90
  state.closure.each do |item|
86
91
  sym = item.lhs
@@ -95,6 +100,7 @@ module Lrama
95
100
 
96
101
  sym = item.next_sym
97
102
  state_item = StateItem.new(state, item)
103
+ # @type var key: [State, Grammar::Symbol]
98
104
  key = [state, sym]
99
105
 
100
106
  @productions[state_item] = h[sym]
@@ -107,6 +113,7 @@ module Lrama
107
113
 
108
114
  def shift_reduce_example(conflict_state, conflict)
109
115
  conflict_symbol = conflict.symbols.first
116
+ # @type var shift_conflict_item: ::Lrama::States::Item
110
117
  shift_conflict_item = conflict_state.items.find { |item| item.next_sym == conflict_symbol }
111
118
  path2 = shortest_path(conflict_state, conflict.reduce.item, conflict_symbol)
112
119
  path1 = find_shift_conflict_shortest_path(path2, conflict_state, shift_conflict_item)
@@ -151,12 +158,14 @@ module Lrama
151
158
  prev_state_item = prev_path&.to
152
159
 
153
160
  if target_state_item == state_item || target_state_item.item.start_item?
154
- result.concat(reversed_reduce_path[_j..-1].map(&:to))
161
+ result.concat(
162
+ reversed_reduce_path[_j..-1] #: Array[StartPath|TransitionPath|ProductionPath]
163
+ .map(&:to))
155
164
  break
156
165
  end
157
166
 
158
167
  if target_state_item.item.beginning_of_rule?
159
- queue = []
168
+ queue = [] #: Array[Array[StateItem]]
160
169
  queue << [target_state_item]
161
170
 
162
171
  # Find reverse production
@@ -171,10 +180,18 @@ module Lrama
171
180
  break
172
181
  end
173
182
 
174
- if !si.item.beginning_of_rule?
183
+ if si.item.beginning_of_rule?
184
+ # @type var key: [State, Grammar::Symbol]
185
+ key = [si.state, si.item.lhs]
186
+ @reverse_productions[key].each do |item|
187
+ state_item = StateItem.new(si.state, item)
188
+ queue << (sis + [state_item])
189
+ end
190
+ else
191
+ # @type var key: [StateItem, Grammar::Symbol]
175
192
  key = [si, si.item.previous_sym]
176
193
  @reverse_transitions[key].each do |prev_target_state_item|
177
- next if prev_target_state_item.state != prev_state_item.state
194
+ next if prev_target_state_item.state != prev_state_item&.state
178
195
  sis.shift
179
196
  result.concat(sis)
180
197
  result << prev_target_state_item
@@ -183,19 +200,14 @@ module Lrama
183
200
  queue.clear
184
201
  break
185
202
  end
186
- else
187
- key = [si.state, si.item.lhs]
188
- @reverse_productions[key].each do |item|
189
- state_item = StateItem.new(si.state, item)
190
- queue << (sis + [state_item])
191
- end
192
203
  end
193
204
  end
194
205
  else
195
206
  # Find reverse transition
207
+ # @type var key: [StateItem, Grammar::Symbol]
196
208
  key = [target_state_item, target_state_item.item.previous_sym]
197
209
  @reverse_transitions[key].each do |prev_target_state_item|
198
- next if prev_target_state_item.state != prev_state_item.state
210
+ next if prev_target_state_item.state != prev_state_item&.state
199
211
  result << prev_target_state_item
200
212
  target_state_item = prev_target_state_item
201
213
  i = j
@@ -222,9 +234,9 @@ module Lrama
222
234
 
223
235
  def shortest_path(conflict_state, conflict_reduce_item, conflict_term)
224
236
  # queue: is an array of [Triple, [Path]]
225
- queue = []
226
- visited = {}
227
- start_state = @states.states.first
237
+ queue = [] #: Array[[Triple, Array[StartPath|TransitionPath|ProductionPath]]]
238
+ visited = {} #: Hash[Triple, true]
239
+ start_state = @states.states.first #: Lrama::State
228
240
  raise "BUG: Start state should be just one kernel." if start_state.kernels.count != 1
229
241
 
230
242
  start = Triple.new(start_state, start_state.kernels.first, Set.new([@states.eof_symbol]))
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lrama
4
+ class Diagnostics
5
+ def initialize(grammar, states, logger)
6
+ @grammar = grammar
7
+ @states = states
8
+ @logger = logger
9
+ end
10
+
11
+ def run(diagnostic)
12
+ if diagnostic
13
+ diagnose_conflict
14
+ diagnose_parameterizing_redefined
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def diagnose_conflict
21
+ if @states.sr_conflicts_count != 0
22
+ @logger.warn("shift/reduce conflicts: #{@states.sr_conflicts_count} found")
23
+ end
24
+
25
+ if @states.rr_conflicts_count != 0
26
+ @logger.warn("reduce/reduce conflicts: #{@states.rr_conflicts_count} found")
27
+ end
28
+ end
29
+
30
+ def diagnose_parameterizing_redefined
31
+ @grammar.parameterizing_rule_resolver.redefined_rules.each do |rule|
32
+ @logger.warn("parameterizing rule redefined: #{rule}")
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/lrama/digraph.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  # Algorithm Digraph of https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 625)
3
5
  class Digraph
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  # Grammar file information not used by States but by Output
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Binding
@@ -16,8 +18,17 @@ module Lrama
16
18
  resolved_args = symbol.args.map { |arg| resolve_symbol(arg) }
17
19
  Lrama::Lexer::Token::InstantiateRule.new(s_value: symbol.s_value, location: symbol.location, args: resolved_args, lhs_tag: symbol.lhs_tag)
18
20
  else
19
- @parameter_to_arg[symbol.s_value] || symbol
21
+ parameter_to_arg(symbol) || symbol
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def parameter_to_arg(symbol)
28
+ if (arg = @parameter_to_arg[symbol.s_value].dup)
29
+ arg.alias_name = symbol.alias_name
20
30
  end
31
+ arg
21
32
  end
22
33
  end
23
34
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Code
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Code
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Code
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Code
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Code
@@ -41,6 +43,7 @@ module Lrama
41
43
  when ref.type == :dollar && ref.name == "$" # $$
42
44
  tag = ref.ex_tag || lhs.tag
43
45
  raise_tag_not_found_error(ref) unless tag
46
+ # @type var tag: Lexer::Token::Tag
44
47
  "(yyval.#{tag.member})"
45
48
  when ref.type == :at && ref.name == "$" # @$
46
49
  "(yyloc)"
@@ -50,6 +53,7 @@ module Lrama
50
53
  i = -position_in_rhs + ref.index
51
54
  tag = ref.ex_tag || rhs[ref.index - 1].tag
52
55
  raise_tag_not_found_error(ref) unless tag
56
+ # @type var tag: Lexer::Token::Tag
53
57
  "(yyvsp[#{i}].#{tag.member})"
54
58
  when ref.type == :at # @n
55
59
  i = -position_in_rhs + ref.index
@@ -69,18 +73,18 @@ module Lrama
69
73
  @rule.position_in_original_rule_rhs || @rule.rhs.count
70
74
  end
71
75
 
72
- # If this is midrule action, RHS is a RHS of the original rule.
76
+ # If this is midrule action, RHS is an RHS of the original rule.
73
77
  def rhs
74
78
  (@rule.original_rule || @rule).rhs
75
79
  end
76
80
 
77
- # Unlike `rhs`, LHS is always a LHS of the rule.
81
+ # Unlike `rhs`, LHS is always an LHS of the rule.
78
82
  def lhs
79
83
  @rule.lhs
80
84
  end
81
85
 
82
86
  def raise_tag_not_found_error(ref)
83
- raise "Tag is not specified for '$#{ref.value}' in '#{@rule}'"
87
+ raise "Tag is not specified for '$#{ref.value}' in '#{@rule.display_name}'"
84
88
  end
85
89
  end
86
90
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "forwardable"
2
- require "lrama/grammar/code/destructor_code"
3
- require "lrama/grammar/code/initial_action_code"
4
- require "lrama/grammar/code/no_reference_code"
5
- require "lrama/grammar/code/printer_code"
6
- require "lrama/grammar/code/rule_action"
4
+ require_relative "code/destructor_code"
5
+ require_relative "code/initial_action_code"
6
+ require_relative "code/no_reference_code"
7
+ require_relative "code/printer_code"
8
+ require_relative "code/rule_action"
7
9
 
8
10
  module Lrama
9
11
  class Grammar
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Counter
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Destructor < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class ErrorToken < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class ParameterizingRule
@@ -18,13 +20,17 @@ module Lrama
18
20
  end
19
21
 
20
22
  def find_inline(token)
21
- @rules.select { |rule| rule.name == token.s_value && rule.is_inline }.last
23
+ @rules.reverse.find { |rule| rule.name == token.s_value && rule.is_inline }
22
24
  end
23
25
 
24
26
  def created_lhs(lhs_s_value)
25
27
  @created_lhs_list.reverse.find { |created_lhs| created_lhs.s_value == lhs_s_value }
26
28
  end
27
29
 
30
+ def redefined_rules
31
+ @rules.select { |rule| @rules.count { |r| r.name == rule.name && r.required_parameters_count == rule.required_parameters_count } > 1 }
32
+ end
33
+
28
34
  private
29
35
 
30
36
  def select_rules(rules, token)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class ParameterizingRule
@@ -13,7 +15,8 @@ module Lrama
13
15
  def resolve_user_code(bindings)
14
16
  return unless user_code
15
17
 
16
- var_to_arg = {}
18
+ resolved = Lexer::Token::UserCode.new(s_value: user_code.s_value, location: user_code.location)
19
+ var_to_arg = {} #: Hash[String, String]
17
20
  symbols.each do |sym|
18
21
  resolved_sym = bindings.resolve_symbol(sym)
19
22
  if resolved_sym != sym
@@ -22,14 +25,14 @@ module Lrama
22
25
  end
23
26
 
24
27
  var_to_arg.each do |var, arg|
25
- user_code.references.each do |ref|
28
+ resolved.references.each do |ref|
26
29
  if ref.name == var
27
30
  ref.name = arg
28
31
  end
29
32
  end
30
33
  end
31
34
 
32
- return user_code
35
+ return resolved
33
36
  end
34
37
  end
35
38
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class ParameterizingRule
@@ -12,6 +14,10 @@ module Lrama
12
14
  @is_inline = is_inline
13
15
  @required_parameters_count = parameters.count
14
16
  end
17
+
18
+ def to_s
19
+ "#{@name}(#{@parameters.map(&:s_value).join(', ')})"
20
+ end
15
21
  end
16
22
  end
17
23
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'parameterizing_rule/resolver'
2
4
  require_relative 'parameterizing_rule/rhs'
3
5
  require_relative 'parameterizing_rule/rule'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class PercentCode
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Precedence < Struct.new(:type, :precedence, keyword_init: true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  class Printer < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  # type: :dollar or :at
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Grammar
3
5
  # _rhs holds original RHS element. Use rhs to refer to Symbol.
@@ -16,8 +18,7 @@ module Lrama
16
18
  self.lineno == other.lineno
17
19
  end
18
20
 
19
- # TODO: Change this to display_name
20
- def to_s
21
+ def display_name
21
22
  l = lhs.id.s_value
22
23
  r = empty_rule? ? "ε" : rhs.map {|r| r.id.s_value }.join(" ")
23
24
 
@@ -33,7 +34,7 @@ module Lrama
33
34
  end
34
35
 
35
36
  def with_actions
36
- "#{to_s} {#{token_code&.s_value}}"
37
+ "#{display_name} {#{token_code&.s_value}}"
37
38
  end
38
39
 
39
40
  # opt_nl: ε <-- empty_rule
@@ -55,6 +56,12 @@ module Lrama
55
56
 
56
57
  Code::RuleAction.new(type: :rule_action, token_code: token_code, rule: self).translated_code
57
58
  end
59
+
60
+ def contains_at_reference?
61
+ return false unless token_code
62
+
63
+ token_code.references.any? {|r| r.type == :at }
64
+ end
58
65
  end
59
66
  end
60
67
  end