lrama 0.6.9 → 0.6.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +19 -0
  3. data/.gitignore +2 -0
  4. data/Gemfile +6 -3
  5. data/NEWS.md +220 -0
  6. data/README.md +41 -4
  7. data/Rakefile +2 -0
  8. data/Steepfile +6 -17
  9. data/exe/lrama +1 -0
  10. data/lib/lrama/bitmap.rb +2 -0
  11. data/lib/lrama/command.rb +8 -14
  12. data/lib/lrama/context.rb +8 -6
  13. data/lib/lrama/counterexamples/derivation.rb +2 -0
  14. data/lib/lrama/counterexamples/example.rb +2 -0
  15. data/lib/lrama/counterexamples/path.rb +2 -0
  16. data/lib/lrama/counterexamples/production_path.rb +2 -0
  17. data/lib/lrama/counterexamples/start_path.rb +2 -0
  18. data/lib/lrama/counterexamples/state_item.rb +2 -0
  19. data/lib/lrama/counterexamples/transition_path.rb +2 -0
  20. data/lib/lrama/counterexamples/triple.rb +2 -0
  21. data/lib/lrama/counterexamples.rb +17 -15
  22. data/lib/lrama/diagnostics.rb +36 -0
  23. data/lib/lrama/digraph.rb +2 -0
  24. data/lib/lrama/grammar/auxiliary.rb +2 -0
  25. data/lib/lrama/grammar/binding.rb +12 -1
  26. data/lib/lrama/grammar/code/destructor_code.rb +2 -0
  27. data/lib/lrama/grammar/code/initial_action_code.rb +2 -0
  28. data/lib/lrama/grammar/code/no_reference_code.rb +2 -0
  29. data/lib/lrama/grammar/code/printer_code.rb +2 -0
  30. data/lib/lrama/grammar/code/rule_action.rb +7 -3
  31. data/lib/lrama/grammar/code.rb +7 -5
  32. data/lib/lrama/grammar/counter.rb +2 -0
  33. data/lib/lrama/grammar/destructor.rb +2 -0
  34. data/lib/lrama/grammar/error_token.rb +2 -0
  35. data/lib/lrama/grammar/parameterizing_rule/resolver.rb +7 -1
  36. data/lib/lrama/grammar/parameterizing_rule/rhs.rb +5 -2
  37. data/lib/lrama/grammar/parameterizing_rule/rule.rb +6 -0
  38. data/lib/lrama/grammar/parameterizing_rule.rb +2 -0
  39. data/lib/lrama/grammar/percent_code.rb +2 -0
  40. data/lib/lrama/grammar/precedence.rb +2 -0
  41. data/lib/lrama/grammar/printer.rb +2 -0
  42. data/lib/lrama/grammar/reference.rb +2 -0
  43. data/lib/lrama/grammar/rule.rb +10 -3
  44. data/lib/lrama/grammar/rule_builder.rb +64 -65
  45. data/lib/lrama/grammar/symbol.rb +2 -0
  46. data/lib/lrama/grammar/symbols/resolver.rb +5 -1
  47. data/lib/lrama/grammar/symbols.rb +2 -0
  48. data/lib/lrama/grammar/type.rb +2 -0
  49. data/lib/lrama/grammar/union.rb +2 -0
  50. data/lib/lrama/grammar.rb +51 -30
  51. data/lib/lrama/grammar_validator.rb +37 -0
  52. data/lib/lrama/lexer/grammar_file.rb +2 -0
  53. data/lib/lrama/lexer/location.rb +2 -0
  54. data/lib/lrama/lexer/token/char.rb +2 -0
  55. data/lib/lrama/lexer/token/ident.rb +2 -0
  56. data/lib/lrama/lexer/token/instantiate_rule.rb +2 -0
  57. data/lib/lrama/lexer/token/tag.rb +2 -0
  58. data/lib/lrama/lexer/token/user_code.rb +3 -1
  59. data/lib/lrama/lexer/token.rb +7 -5
  60. data/lib/lrama/lexer.rb +11 -8
  61. data/lib/lrama/{warning.rb → logger.rb} +5 -13
  62. data/lib/lrama/option_parser.rb +58 -33
  63. data/lib/lrama/options.rb +5 -2
  64. data/lib/lrama/output.rb +38 -69
  65. data/lib/lrama/parser.rb +650 -779
  66. data/lib/lrama/report/duration.rb +2 -0
  67. data/lib/lrama/report/profile.rb +2 -0
  68. data/lib/lrama/report.rb +4 -2
  69. data/lib/lrama/state/reduce.rb +3 -0
  70. data/lib/lrama/state/reduce_reduce_conflict.rb +2 -0
  71. data/lib/lrama/state/resolved_conflict.rb +3 -1
  72. data/lib/lrama/state/shift.rb +2 -0
  73. data/lib/lrama/state/shift_reduce_conflict.rb +2 -0
  74. data/lib/lrama/state.rb +7 -5
  75. data/lib/lrama/states/item.rb +5 -3
  76. data/lib/lrama/states.rb +18 -46
  77. data/lib/lrama/states_reporter.rb +60 -19
  78. data/lib/lrama/trace_reporter.rb +30 -0
  79. data/lib/lrama/version.rb +3 -1
  80. data/lib/lrama.rb +22 -17
  81. data/lrama.gemspec +3 -1
  82. data/parser.y +110 -229
  83. data/sig/lrama/grammar/auxiliary.rbs +10 -0
  84. data/sig/lrama/grammar/binding.rbs +4 -0
  85. data/sig/lrama/grammar/code/destructor_code.rbs +3 -4
  86. data/sig/lrama/grammar/code/initial_action_code.rbs +15 -0
  87. data/sig/lrama/grammar/code/no_reference_code.rbs +15 -0
  88. data/sig/lrama/grammar/code/printer_code.rbs +3 -4
  89. data/sig/lrama/grammar/code/rule_action.rbs +19 -0
  90. data/sig/lrama/grammar/code.rbs +3 -3
  91. data/sig/lrama/grammar/destructor.rbs +3 -1
  92. data/sig/lrama/grammar/error_token.rbs +4 -2
  93. data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +2 -1
  94. data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +1 -1
  95. data/sig/lrama/grammar/precedence.rbs +3 -1
  96. data/sig/lrama/grammar/printer.rbs +3 -1
  97. data/sig/lrama/grammar/rule.rbs +35 -3
  98. data/sig/lrama/grammar/rule_builder.rbs +10 -9
  99. data/sig/lrama/grammar/symbol.rbs +6 -6
  100. data/sig/lrama/grammar/symbols/resolver.rbs +22 -3
  101. data/sig/lrama/grammar/type.rbs +2 -2
  102. data/sig/lrama/grammar/union.rbs +12 -0
  103. data/sig/lrama/grammar.rbs +91 -1
  104. data/sig/lrama/options.rbs +3 -2
  105. data/sig/lrama/state/reduce.rbs +20 -0
  106. data/sig/lrama/state/reduce_reduce_conflict.rbs +13 -0
  107. data/sig/lrama/state/resolved_conflict.rbs +14 -0
  108. data/sig/lrama/state/shift.rbs +14 -0
  109. data/sig/lrama/state/shift_reduce_conflict.rbs +13 -0
  110. data/sig/lrama/states/item.rbs +30 -0
  111. data/template/bison/yacc.c +24 -19
  112. metadata +17 -6
  113. data/sample/calc.output +0 -263
  114. data/sample/calc.y +0 -101
  115. data/sample/parse.y +0 -59
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Report
3
5
  module Duration
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Report
3
5
  module Profile
data/lib/lrama/report.rb CHANGED
@@ -1,2 +1,4 @@
1
- require 'lrama/report/duration'
2
- require 'lrama/report/profile'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'report/duration'
4
+ require_relative 'report/profile'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class State
3
5
  class Reduce
@@ -25,6 +27,7 @@ module Lrama
25
27
 
26
28
  def selected_look_ahead
27
29
  if @look_ahead
30
+ # @type ivar @look_ahead: Array<Grammar::Symbol>
28
31
  @look_ahead - @not_selected_symbols
29
32
  else
30
33
  []
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class State
3
5
  class ReduceReduceConflict < Struct.new(:symbols, :reduce1, :reduce2, keyword_init: true)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class State
3
5
  # * symbol: A symbol under discussion
@@ -6,7 +8,7 @@ module Lrama
6
8
  class ResolvedConflict < Struct.new(:symbol, :reduce, :which, :same_prec, keyword_init: true)
7
9
  def report_message
8
10
  s = symbol.display_name
9
- r = reduce.rule.precedence_sym.display_name
11
+ r = reduce.rule.precedence_sym&.display_name
10
12
  case
11
13
  when which == :shift && same_prec
12
14
  msg = "resolved as #{which} (%right #{s})"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class State
3
5
  class Shift
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class State
3
5
  class ShiftReduceConflict < Struct.new(:symbols, :shift, :reduce, keyword_init: true)
data/lib/lrama/state.rb CHANGED
@@ -1,8 +1,10 @@
1
- require "lrama/state/reduce"
2
- require "lrama/state/reduce_reduce_conflict"
3
- require "lrama/state/resolved_conflict"
4
- require "lrama/state/shift"
5
- require "lrama/state/shift_reduce_conflict"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "state/reduce"
4
+ require_relative "state/reduce_reduce_conflict"
5
+ require_relative "state/resolved_conflict"
6
+ require_relative "state/shift"
7
+ require_relative "state/shift_reduce_conflict"
6
8
 
7
9
  module Lrama
8
10
  class State
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # TODO: Validate position is not over rule rhs
2
4
 
3
5
  require "forwardable"
@@ -54,11 +56,11 @@ module Lrama
54
56
  Item.new(rule: rule, position: position + 1)
55
57
  end
56
58
 
57
- def symbols_before_dot
59
+ def symbols_before_dot # steep:ignore
58
60
  rhs[0...position]
59
61
  end
60
62
 
61
- def symbols_after_dot
63
+ def symbols_after_dot # steep:ignore
62
64
  rhs[position..-1]
63
65
  end
64
66
 
@@ -73,7 +75,7 @@ module Lrama
73
75
 
74
76
  # Right after position
75
77
  def display_rest
76
- r = rhs[position..-1].map(&:display_name).join(" ")
78
+ r = symbols_after_dot.map(&:display_name).join(" ")
77
79
  ". #{r} (rule #{rule_id})"
78
80
  end
79
81
  end
data/lib/lrama/states.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "forwardable"
2
- require "lrama/report/duration"
3
- require "lrama/states/item"
4
+ require_relative "report/duration"
5
+ require_relative "states/item"
4
6
 
5
7
  module Lrama
6
8
  # States is passed to a template file
@@ -16,9 +18,8 @@ module Lrama
16
18
 
17
19
  attr_reader :states, :reads_relation, :includes_relation, :lookback_relation
18
20
 
19
- def initialize(grammar, warning, trace_state: false)
21
+ def initialize(grammar, trace_state: false)
20
22
  @grammar = grammar
21
- @warning = warning
22
23
  @trace_state = trace_state
23
24
 
24
25
  @states = []
@@ -89,8 +90,6 @@ module Lrama
89
90
  report_duration(:compute_conflicts) { compute_conflicts }
90
91
 
91
92
  report_duration(:compute_default_reduction) { compute_default_reduction }
92
-
93
- check_conflicts
94
93
  end
95
94
 
96
95
  def reporter
@@ -125,16 +124,16 @@ module Lrama
125
124
  end
126
125
  end
127
126
 
128
- private
129
-
130
- def sr_conflicts
131
- @states.flat_map(&:sr_conflicts)
127
+ def sr_conflicts_count
128
+ @sr_conflicts_count ||= @states.flat_map(&:sr_conflicts).count
132
129
  end
133
130
 
134
- def rr_conflicts
135
- @states.flat_map(&:rr_conflicts)
131
+ def rr_conflicts_count
132
+ @rr_conflicts_count ||= @states.flat_map(&:rr_conflicts).count
136
133
  end
137
134
 
135
+ private
136
+
138
137
  def trace_state
139
138
  if @trace_state
140
139
  yield STDERR
@@ -350,7 +349,7 @@ module Lrama
350
349
  # TODO: need to omit if state == state2 ?
351
350
  @includes_relation[key] ||= []
352
351
  @includes_relation[key] << [state.id, nterm.token_id]
353
- break if !sym.nullable
352
+ break unless sym.nullable
354
353
  i -= 1
355
354
  end
356
355
  end
@@ -385,7 +384,7 @@ module Lrama
385
384
  @states.each do |state|
386
385
  rules.each do |rule|
387
386
  ary = @lookback_relation[[state.id, rule.id]]
388
- next if !ary
387
+ next unless ary
389
388
 
390
389
  ary.each do |state2_id, nterm_token_id|
391
390
  # q = state, A -> ω = rule, p = state2, A = nterm
@@ -428,7 +427,7 @@ module Lrama
428
427
  sym = shift.next_sym
429
428
 
430
429
  next unless reduce.look_ahead
431
- next if !reduce.look_ahead.include?(sym)
430
+ next unless reduce.look_ahead.include?(sym)
432
431
 
433
432
  # Shift/Reduce conflict
434
433
  shift_prec = sym.precedence
@@ -492,17 +491,17 @@ module Lrama
492
491
  states.each do |state|
493
492
  count = state.reduces.count
494
493
 
495
- for i in 0...count do
494
+ (0...count).each do |i|
496
495
  reduce1 = state.reduces[i]
497
496
  next if reduce1.look_ahead.nil?
498
497
 
499
- for j in (i+1)...count do
498
+ ((i+1)...count).each do |j|
500
499
  reduce2 = state.reduces[j]
501
500
  next if reduce2.look_ahead.nil?
502
501
 
503
502
  intersection = reduce1.look_ahead & reduce2.look_ahead
504
503
 
505
- if !intersection.empty?
504
+ unless intersection.empty?
506
505
  state.conflicts << State::ReduceReduceConflict.new(symbols: intersection, reduce1: reduce1, reduce2: reduce2)
507
506
  end
508
507
  end
@@ -514,7 +513,7 @@ module Lrama
514
513
  states.each do |state|
515
514
  next if state.reduces.empty?
516
515
  # Do not set, if conflict exist
517
- next if !state.conflicts.empty?
516
+ next unless state.conflicts.empty?
518
517
  # Do not set, if shift with `error` exists.
519
518
  next if state.shifts.map(&:next_sym).include?(@grammar.error_symbol)
520
519
 
@@ -525,32 +524,5 @@ module Lrama
525
524
  end.first
526
525
  end
527
526
  end
528
-
529
- def check_conflicts
530
- sr_count = sr_conflicts.count
531
- rr_count = rr_conflicts.count
532
-
533
- if @grammar.expect
534
-
535
- expected_sr_conflicts = @grammar.expect
536
- expected_rr_conflicts = 0
537
-
538
- if expected_sr_conflicts != sr_count
539
- @warning.error("shift/reduce conflicts: #{sr_count} found, #{expected_sr_conflicts} expected")
540
- end
541
-
542
- if expected_rr_conflicts != rr_count
543
- @warning.error("reduce/reduce conflicts: #{rr_count} found, #{expected_rr_conflicts} expected")
544
- end
545
- else
546
- if sr_count != 0
547
- @warning.warn("shift/reduce conflicts: #{sr_count} found")
548
- end
549
-
550
- if rr_count != 0
551
- @warning.warn("reduce/reduce conflicts: #{rr_count} found")
552
- end
553
- end
554
- end
555
527
  end
556
528
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class StatesReporter
3
5
  include Lrama::Report::Duration
@@ -14,15 +16,54 @@ module Lrama
14
16
 
15
17
  private
16
18
 
17
- def _report(io, grammar: false, states: false, itemsets: false, lookaheads: false, solved: false, counterexamples: false, verbose: false)
18
- # TODO: Unused terms
19
- # TODO: Unused rules
20
-
19
+ def _report(io, grammar: false, rules: false, terms: false, states: false, itemsets: false, lookaheads: false, solved: false, counterexamples: false, verbose: false)
20
+ report_unused_rules(io) if rules
21
+ report_unused_terms(io) if terms
21
22
  report_conflicts(io)
22
23
  report_grammar(io) if grammar
23
24
  report_states(io, itemsets, lookaheads, solved, counterexamples, verbose)
24
25
  end
25
26
 
27
+ def report_unused_terms(io)
28
+ look_aheads = @states.states.each do |state|
29
+ state.reduces.flat_map do |reduce|
30
+ reduce.look_ahead unless reduce.look_ahead.nil?
31
+ end
32
+ end
33
+
34
+ next_terms = @states.states.flat_map do |state|
35
+ state.shifts.map(&:next_sym).select(&:term?)
36
+ end
37
+
38
+ unused_symbols = @states.terms.select do |term|
39
+ !(look_aheads + next_terms).include?(term)
40
+ end
41
+
42
+ unless unused_symbols.empty?
43
+ io << "#{unused_symbols.count} Unused Terms\n\n"
44
+ unused_symbols.each_with_index do |term, index|
45
+ io << sprintf("%5d %s\n", index, term.id.s_value)
46
+ end
47
+ io << "\n\n"
48
+ end
49
+ end
50
+
51
+ def report_unused_rules(io)
52
+ used_rules = @states.rules.flat_map(&:rhs)
53
+
54
+ unused_rules = @states.rules.map(&:lhs).select do |rule|
55
+ !used_rules.include?(rule) && rule.token_id != 0
56
+ end
57
+
58
+ unless unused_rules.empty?
59
+ io << "#{unused_rules.count} Unused Rules\n\n"
60
+ unused_rules.each_with_index do |rule, index|
61
+ io << sprintf("%5d %s\n", index, rule.display_name)
62
+ end
63
+ io << "\n\n"
64
+ end
65
+ end
66
+
26
67
  def report_conflicts(io)
27
68
  has_conflict = false
28
69
 
@@ -37,7 +78,7 @@ module Lrama
37
78
  messages << "#{cs[:reduce_reduce].count} reduce/reduce"
38
79
  end
39
80
 
40
- if !messages.empty?
81
+ unless messages.empty?
41
82
  has_conflict = true
42
83
  io << "State #{state.id} conflicts: #{messages.join(', ')}\n"
43
84
  end
@@ -98,7 +139,7 @@ module Lrama
98
139
  if lookaheads && item.end_of_rule?
99
140
  reduce = state.find_reduce_by_item!(item)
100
141
  look_ahead = reduce.selected_look_ahead
101
- if !look_ahead.empty?
142
+ unless look_ahead.empty?
102
143
  la = " [#{look_ahead.map(&:display_name).join(", ")}]"
103
144
  end
104
145
  end
@@ -118,7 +159,7 @@ module Lrama
118
159
  tmp.each do |term, state_id|
119
160
  io << " #{term.display_name.ljust(max_len)} shift, and go to state #{state_id}\n"
120
161
  end
121
- io << "\n" if !tmp.empty?
162
+ io << "\n" unless tmp.empty?
122
163
 
123
164
  # Report error caused by %nonassoc
124
165
  nl = false
@@ -132,7 +173,7 @@ module Lrama
132
173
  nl = true
133
174
  io << " #{name.ljust(max_len)} error (nonassociative)\n"
134
175
  end
135
- io << "\n" if !tmp.empty?
176
+ io << "\n" unless tmp.empty?
136
177
 
137
178
  # Report reduces
138
179
  nl = false
@@ -181,14 +222,14 @@ module Lrama
181
222
  tmp.each do |nterm, state_id|
182
223
  io << " #{nterm.id.s_value.ljust(max_len)} go to state #{state_id}\n"
183
224
  end
184
- io << "\n" if !tmp.empty?
225
+ io << "\n" unless tmp.empty?
185
226
 
186
227
  if solved
187
228
  # Report conflict resolutions
188
229
  state.resolved_conflicts.each do |resolved|
189
230
  io << " #{resolved.report_message}\n"
190
231
  end
191
- io << "\n" if !state.resolved_conflicts.empty?
232
+ io << "\n" unless state.resolved_conflicts.empty?
192
233
  end
193
234
 
194
235
  if counterexamples && state.has_conflicts?
@@ -219,7 +260,7 @@ module Lrama
219
260
  direct_read_sets = @states.direct_read_sets
220
261
  @states.nterms.each do |nterm|
221
262
  terms = direct_read_sets[[state.id, nterm.token_id]]
222
- next if !terms
263
+ next unless terms
223
264
  next if terms.empty?
224
265
 
225
266
  str = terms.map {|sym| sym.id.s_value }.join(", ")
@@ -231,7 +272,7 @@ module Lrama
231
272
  io << " [Reads Relation]\n"
232
273
  @states.nterms.each do |nterm|
233
274
  a = @states.reads_relation[[state.id, nterm.token_id]]
234
- next if !a
275
+ next unless a
235
276
 
236
277
  a.each do |state_id2, nterm_id2|
237
278
  n = @states.nterms.find {|n| n.token_id == nterm_id2 }
@@ -245,7 +286,7 @@ module Lrama
245
286
  read_sets = @states.read_sets
246
287
  @states.nterms.each do |nterm|
247
288
  terms = read_sets[[state.id, nterm.token_id]]
248
- next if !terms
289
+ next unless terms
249
290
  next if terms.empty?
250
291
 
251
292
  terms.each do |sym|
@@ -258,7 +299,7 @@ module Lrama
258
299
  io << " [Includes Relation]\n"
259
300
  @states.nterms.each do |nterm|
260
301
  a = @states.includes_relation[[state.id, nterm.token_id]]
261
- next if !a
302
+ next unless a
262
303
 
263
304
  a.each do |state_id2, nterm_id2|
264
305
  n = @states.nterms.find {|n| n.token_id == nterm_id2 }
@@ -271,11 +312,11 @@ module Lrama
271
312
  io << " [Lookback Relation]\n"
272
313
  @states.rules.each do |rule|
273
314
  a = @states.lookback_relation[[state.id, rule.id]]
274
- next if !a
315
+ next unless a
275
316
 
276
317
  a.each do |state_id2, nterm_id2|
277
318
  n = @states.nterms.find {|n| n.token_id == nterm_id2 }
278
- io << " (Rule: #{rule}) -> (State #{state_id2}, #{n.id.s_value})\n"
319
+ io << " (Rule: #{rule.display_name}) -> (State #{state_id2}, #{n.id.s_value})\n"
279
320
  end
280
321
  end
281
322
  io << "\n"
@@ -286,7 +327,7 @@ module Lrama
286
327
  @states.nterms.each do |nterm|
287
328
  terms = follow_sets[[state.id, nterm.token_id]]
288
329
 
289
- next if !terms
330
+ next unless terms
290
331
 
291
332
  terms.each do |sym|
292
333
  io << " #{nterm.id.s_value} -> #{sym.id.s_value}\n"
@@ -300,7 +341,7 @@ module Lrama
300
341
  max_len = 0
301
342
  @states.rules.each do |rule|
302
343
  syms = @states.la[[state.id, rule.id]]
303
- next if !syms
344
+ next unless syms
304
345
 
305
346
  tmp << [rule, syms]
306
347
  max_len = ([max_len] + syms.map {|s| s.id.s_value.length }).max
@@ -310,7 +351,7 @@ module Lrama
310
351
  io << " #{sym.id.s_value.ljust(max_len)} reduce using rule #{rule.id} (#{rule.lhs.id.s_value})\n"
311
352
  end
312
353
  end
313
- io << "\n" if !tmp.empty?
354
+ io << "\n" unless tmp.empty?
314
355
  end
315
356
 
316
357
  # End of Report State
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lrama
4
+ class TraceReporter
5
+ def initialize(grammar)
6
+ @grammar = grammar
7
+ end
8
+
9
+ def report(**options)
10
+ _report(**options)
11
+ end
12
+
13
+ private
14
+
15
+ def _report(rules: false, actions: false, **_)
16
+ report_rules if rules
17
+ report_actions if actions
18
+ end
19
+
20
+ def report_rules
21
+ puts "Grammar rules:"
22
+ @grammar.rules.each { |rule| puts rule.display_name }
23
+ end
24
+
25
+ def report_actions
26
+ puts "Grammar rules with actions:"
27
+ @grammar.rules.each { |rule| puts rule.with_actions }
28
+ end
29
+ end
30
+ end
data/lib/lrama/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
- VERSION = "0.6.9".freeze
4
+ VERSION = "0.6.10".freeze
3
5
  end
data/lib/lrama.rb CHANGED
@@ -1,17 +1,22 @@
1
- require "lrama/bitmap"
2
- require "lrama/command"
3
- require "lrama/context"
4
- require "lrama/counterexamples"
5
- require "lrama/digraph"
6
- require "lrama/grammar"
7
- require "lrama/lexer"
8
- require "lrama/option_parser"
9
- require "lrama/options"
10
- require "lrama/output"
11
- require "lrama/parser"
12
- require "lrama/report"
13
- require "lrama/state"
14
- require "lrama/states"
15
- require "lrama/states_reporter"
16
- require "lrama/version"
17
- require "lrama/warning"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lrama/bitmap"
4
+ require_relative "lrama/command"
5
+ require_relative "lrama/context"
6
+ require_relative "lrama/counterexamples"
7
+ require_relative "lrama/diagnostics"
8
+ require_relative "lrama/digraph"
9
+ require_relative "lrama/grammar"
10
+ require_relative "lrama/grammar_validator"
11
+ require_relative "lrama/lexer"
12
+ require_relative "lrama/logger"
13
+ require_relative "lrama/option_parser"
14
+ require_relative "lrama/options"
15
+ require_relative "lrama/output"
16
+ require_relative "lrama/parser"
17
+ require_relative "lrama/report"
18
+ require_relative "lrama/state"
19
+ require_relative "lrama/states"
20
+ require_relative "lrama/states_reporter"
21
+ require_relative "lrama/trace_reporter"
22
+ require_relative "lrama/version"
data/lrama.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "lib/lrama/version.rb"
2
4
 
3
5
  Gem::Specification.new do |spec|
@@ -14,7 +16,7 @@ Gem::Specification.new do |spec|
14
16
  spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
15
17
 
16
18
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
17
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|sample)/}) }
18
20
  end
19
21
 
20
22
  spec.metadata["homepage_uri"] = spec.homepage