lrama 0.5.3 → 0.5.5

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.
@@ -12,20 +12,56 @@ module Lrama
12
12
  rule.id
13
13
  end
14
14
 
15
+ def empty_rule?
16
+ rule.empty_rule?
17
+ end
18
+
19
+ def number_of_rest_symbols
20
+ rule.rhs.count - position
21
+ end
22
+
23
+ def lhs
24
+ rule.lhs
25
+ end
26
+
15
27
  def next_sym
16
28
  rule.rhs[position]
17
29
  end
18
30
 
31
+ def next_next_sym
32
+ rule.rhs[position + 1]
33
+ end
34
+
35
+ def previous_sym
36
+ rule.rhs[position - 1]
37
+ end
38
+
19
39
  def end_of_rule?
20
40
  rule.rhs.count == position
21
41
  end
22
42
 
43
+ def beginning_of_rule?
44
+ position == 0
45
+ end
46
+
47
+ def start_item?
48
+ rule.id == 0 && position == 0
49
+ end
50
+
23
51
  def new_by_next_position
24
52
  Item.new(rule: rule, position: position + 1)
25
53
  end
26
54
 
27
- def previous_sym
28
- rule.rhs[position - 1]
55
+ def symbols_before_dot
56
+ rule.rhs[0...position]
57
+ end
58
+
59
+ def symbols_after_dot
60
+ rule.rhs[position..-1]
61
+ end
62
+
63
+ def to_s
64
+ "#{lhs.id.s_value}: #{display_name}"
29
65
  end
30
66
 
31
67
  def display_name
data/lib/lrama/states.rb CHANGED
@@ -102,43 +102,27 @@ module Lrama
102
102
  end
103
103
 
104
104
  def direct_read_sets
105
- h = {}
106
-
107
- @direct_read_sets.each do |k, v|
108
- h[k] = bitmap_to_terms(v)
105
+ @direct_read_sets.transform_values do |v|
106
+ bitmap_to_terms(v)
109
107
  end
110
-
111
- return h
112
108
  end
113
109
 
114
110
  def read_sets
115
- h = {}
116
-
117
- @read_sets.each do |k, v|
118
- h[k] = bitmap_to_terms(v)
111
+ @read_sets.transform_values do |v|
112
+ bitmap_to_terms(v)
119
113
  end
120
-
121
- return h
122
114
  end
123
115
 
124
116
  def follow_sets
125
- h = {}
126
-
127
- @follow_sets.each do |k, v|
128
- h[k] = bitmap_to_terms(v)
117
+ @follow_sets.transform_values do |v|
118
+ bitmap_to_terms(v)
129
119
  end
130
-
131
- return h
132
120
  end
133
121
 
134
122
  def la
135
- h = {}
136
-
137
- @la.each do |k, v|
138
- h[k] = bitmap_to_terms(v)
123
+ @la.transform_values do |v|
124
+ bitmap_to_terms(v)
139
125
  end
140
-
141
- return h
142
126
  end
143
127
 
144
128
  private
@@ -452,7 +436,7 @@ module Lrama
452
436
 
453
437
  # Can resolve only when both have prec
454
438
  unless shift_prec && reduce_prec
455
- state.conflicts << State::Conflict.new(symbols: [sym], reduce: reduce, type: :shift_reduce)
439
+ state.conflicts << State::ShiftReduceConflict.new(symbols: [sym], shift: shift, reduce: reduce)
456
440
  next
457
441
  end
458
442
 
@@ -471,6 +455,11 @@ module Lrama
471
455
 
472
456
  # shift_prec == reduce_prec, then check associativity
473
457
  case sym.precedence.type
458
+ when :precedence
459
+ # %precedence only specifies precedence and not specify associativity
460
+ # then a conflict is unresolved if precedence is same.
461
+ state.conflicts << State::ShiftReduceConflict.new(symbols: [sym], shift: shift, reduce: reduce)
462
+ next
474
463
  when :right
475
464
  # Shift is selected
476
465
  state.resolved_conflicts << State::ResolvedConflict.new(symbol: sym, reduce: reduce, which: :shift, same_prec: true)
@@ -501,16 +490,21 @@ module Lrama
501
490
 
502
491
  def compute_reduce_reduce_conflicts
503
492
  states.each do |state|
504
- a = []
493
+ count = state.reduces.count
505
494
 
506
- state.reduces.each do |reduce|
507
- next if reduce.look_ahead.nil?
495
+ for i in 0...count do
496
+ reduce1 = state.reduces[i]
497
+ next if reduce1.look_ahead.nil?
508
498
 
509
- intersection = a & reduce.look_ahead
510
- a += reduce.look_ahead
499
+ for j in (i+1)...count do
500
+ reduce2 = state.reduces[j]
501
+ next if reduce2.look_ahead.nil?
511
502
 
512
- if !intersection.empty?
513
- state.conflicts << State::Conflict.new(symbols: intersection.dup, reduce: reduce, type: :reduce_reduce)
503
+ intersection = reduce1.look_ahead & reduce2.look_ahead
504
+
505
+ if !intersection.empty?
506
+ state.conflicts << State::ReduceReduceConflict.new(symbols: intersection, reduce1: reduce1, reduce2: reduce2)
507
+ end
514
508
  end
515
509
  end
516
510
  end
@@ -526,9 +520,9 @@ module Lrama
526
520
 
527
521
  state.default_reduction_rule = state.reduces.map do |r|
528
522
  [r.rule, r.rule.id, (r.look_ahead || []).count]
529
- end.sort_by do |rule, rule_id, count|
523
+ end.min_by do |rule, rule_id, count|
530
524
  [-count, rule_id]
531
- end.first.first
525
+ end.first
532
526
  end
533
527
  end
534
528
 
@@ -14,13 +14,13 @@ module Lrama
14
14
 
15
15
  private
16
16
 
17
- def _report(io, grammar: false, states: false, itemsets: false, lookaheads: false, solved: false, verbose: false)
17
+ def _report(io, grammar: false, states: false, itemsets: false, lookaheads: false, solved: false, counterexamples: false, verbose: false)
18
18
  # TODO: Unused terms
19
19
  # TODO: Unused rules
20
20
 
21
21
  report_conflicts(io)
22
22
  report_grammar(io) if grammar
23
- report_states(io, itemsets, lookaheads, solved, verbose)
23
+ report_states(io, itemsets, lookaheads, solved, counterexamples, verbose)
24
24
  end
25
25
 
26
26
  def report_conflicts(io)
@@ -71,7 +71,11 @@ module Lrama
71
71
  io << "\n\n"
72
72
  end
73
73
 
74
- def report_states(io, itemsets, lookaheads, solved, verbose)
74
+ def report_states(io, itemsets, lookaheads, solved, counterexamples, verbose)
75
+ if counterexamples
76
+ cex = Counterexamples.new(@states)
77
+ end
78
+
75
79
  @states.states.each do |state|
76
80
  # Report State
77
81
  io << "State #{state.id}\n\n"
@@ -106,7 +110,6 @@ module Lrama
106
110
  end
107
111
  io << "\n"
108
112
 
109
-
110
113
  # Report shifts
111
114
  tmp = state.term_transitions.select do |shift, _|
112
115
  !shift.not_selected
@@ -119,7 +122,6 @@ module Lrama
119
122
  end
120
123
  io << "\n" if !tmp.empty?
121
124
 
122
-
123
125
  # Report error caused by %nonassoc
124
126
  nl = false
125
127
  tmp = state.resolved_conflicts.select do |resolved|
@@ -134,7 +136,6 @@ module Lrama
134
136
  end
135
137
  io << "\n" if !tmp.empty?
136
138
 
137
-
138
139
  # Report reduces
139
140
  nl = false
140
141
  max_len = state.non_default_reduces.flat_map(&:look_ahead).compact.map(&:display_name).map(&:length).max || 0
@@ -167,7 +168,6 @@ module Lrama
167
168
  end
168
169
  io << "\n" if nl
169
170
 
170
-
171
171
  # Report nonterminal transitions
172
172
  tmp = []
173
173
  max_len = 0
@@ -185,7 +185,6 @@ module Lrama
185
185
  end
186
186
  io << "\n" if !tmp.empty?
187
187
 
188
-
189
188
  if solved
190
189
  # Report conflict resolutions
191
190
  state.resolved_conflicts.each do |resolved|
@@ -194,6 +193,27 @@ module Lrama
194
193
  io << "\n" if !state.resolved_conflicts.empty?
195
194
  end
196
195
 
196
+ if counterexamples && state.has_conflicts?
197
+ # Report counterexamples
198
+ examples = cex.compute(state)
199
+ examples.each do |example|
200
+ label0 = example.type == :shift_reduce ? "shift/reduce" : "reduce/reduce"
201
+ label1 = example.type == :shift_reduce ? "Shift derivation" : "First Reduce derivation"
202
+ label2 = example.type == :shift_reduce ? "Reduce derivation" : "Second Reduce derivation"
203
+
204
+ io << " #{label0} conflict on token #{example.conflict_symbol.id.s_value}:\n"
205
+ io << " #{example.path1_item}\n"
206
+ io << " #{example.path2_item}\n"
207
+ io << " #{label1}\n"
208
+ example.derivations1.render_strings_for_report.each do |str|
209
+ io << " #{str}\n"
210
+ end
211
+ io << " #{label2}\n"
212
+ example.derivations2.render_strings_for_report.each do |str|
213
+ io << " #{str}\n"
214
+ end
215
+ end
216
+ end
197
217
 
198
218
  if verbose
199
219
  # Report direct_read_sets
@@ -209,7 +229,6 @@ module Lrama
209
229
  end
210
230
  io << "\n"
211
231
 
212
-
213
232
  # Report reads_relation
214
233
  io << " [Reads Relation]\n"
215
234
  @states.nterms.each do |nterm|
@@ -223,7 +242,6 @@ module Lrama
223
242
  end
224
243
  io << "\n"
225
244
 
226
-
227
245
  # Report read_sets
228
246
  io << " [Read sets]\n"
229
247
  read_sets = @states.read_sets
@@ -238,7 +256,6 @@ module Lrama
238
256
  end
239
257
  io << "\n"
240
258
 
241
-
242
259
  # Report includes_relation
243
260
  io << " [Includes Relation]\n"
244
261
  @states.nterms.each do |nterm|
@@ -252,7 +269,6 @@ module Lrama
252
269
  end
253
270
  io << "\n"
254
271
 
255
-
256
272
  # Report lookback_relation
257
273
  io << " [Lookback Relation]\n"
258
274
  @states.rules.each do |rule|
@@ -261,12 +277,11 @@ module Lrama
261
277
 
262
278
  a.each do |state_id2, nterm_id2|
263
279
  n = @states.nterms.find {|n| n.token_id == nterm_id2 }
264
- io << " (Rule: #{rule.to_s}) -> (State #{state_id2}, #{n.id.s_value})\n"
280
+ io << " (Rule: #{rule}) -> (State #{state_id2}, #{n.id.s_value})\n"
265
281
  end
266
282
  end
267
283
  io << "\n"
268
284
 
269
-
270
285
  # Report follow_sets
271
286
  io << " [Follow sets]\n"
272
287
  follow_sets = @states.follow_sets
@@ -281,7 +296,6 @@ module Lrama
281
296
  end
282
297
  io << "\n"
283
298
 
284
-
285
299
  # Report LA
286
300
  io << " [Look-Ahead Sets]\n"
287
301
  tmp = []
@@ -301,7 +315,6 @@ module Lrama
301
315
  io << "\n" if !tmp.empty?
302
316
  end
303
317
 
304
-
305
318
  # End of Report State
306
319
  io << "\n"
307
320
  end
data/lib/lrama/type.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Lrama
2
+ class Type < Struct.new(:id, :tag, keyword_init: true)
3
+ end
4
+ end
data/lib/lrama/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lrama
2
- VERSION = "0.5.3".freeze
2
+ VERSION = "0.5.5".freeze
3
3
  end
data/lib/lrama.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "lrama/bitmap"
2
2
  require "lrama/command"
3
3
  require "lrama/context"
4
+ require "lrama/counterexamples"
4
5
  require "lrama/digraph"
5
6
  require "lrama/grammar"
6
7
  require "lrama/lexer"
@@ -10,5 +11,6 @@ require "lrama/report"
10
11
  require "lrama/state"
11
12
  require "lrama/states"
12
13
  require "lrama/states_reporter"
14
+ require "lrama/type"
13
15
  require "lrama/version"
14
16
  require "lrama/warning"