lrama 0.6.9 → 0.6.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yaml +19 -0
- data/.gitignore +2 -0
- data/Gemfile +6 -3
- data/NEWS.md +220 -0
- data/README.md +41 -4
- data/Rakefile +2 -0
- data/Steepfile +6 -17
- data/exe/lrama +1 -0
- data/lib/lrama/bitmap.rb +2 -0
- data/lib/lrama/command.rb +8 -14
- data/lib/lrama/context.rb +8 -6
- data/lib/lrama/counterexamples/derivation.rb +2 -0
- data/lib/lrama/counterexamples/example.rb +2 -0
- data/lib/lrama/counterexamples/path.rb +2 -0
- data/lib/lrama/counterexamples/production_path.rb +2 -0
- data/lib/lrama/counterexamples/start_path.rb +2 -0
- data/lib/lrama/counterexamples/state_item.rb +2 -0
- data/lib/lrama/counterexamples/transition_path.rb +2 -0
- data/lib/lrama/counterexamples/triple.rb +2 -0
- data/lib/lrama/counterexamples.rb +17 -15
- data/lib/lrama/diagnostics.rb +36 -0
- data/lib/lrama/digraph.rb +2 -0
- data/lib/lrama/grammar/auxiliary.rb +2 -0
- data/lib/lrama/grammar/binding.rb +12 -1
- data/lib/lrama/grammar/code/destructor_code.rb +2 -0
- data/lib/lrama/grammar/code/initial_action_code.rb +2 -0
- data/lib/lrama/grammar/code/no_reference_code.rb +2 -0
- data/lib/lrama/grammar/code/printer_code.rb +2 -0
- data/lib/lrama/grammar/code/rule_action.rb +7 -3
- data/lib/lrama/grammar/code.rb +7 -5
- data/lib/lrama/grammar/counter.rb +2 -0
- data/lib/lrama/grammar/destructor.rb +2 -0
- data/lib/lrama/grammar/error_token.rb +2 -0
- data/lib/lrama/grammar/parameterizing_rule/resolver.rb +7 -1
- data/lib/lrama/grammar/parameterizing_rule/rhs.rb +5 -2
- data/lib/lrama/grammar/parameterizing_rule/rule.rb +6 -0
- data/lib/lrama/grammar/parameterizing_rule.rb +2 -0
- data/lib/lrama/grammar/percent_code.rb +2 -0
- data/lib/lrama/grammar/precedence.rb +2 -0
- data/lib/lrama/grammar/printer.rb +2 -0
- data/lib/lrama/grammar/reference.rb +2 -0
- data/lib/lrama/grammar/rule.rb +10 -3
- data/lib/lrama/grammar/rule_builder.rb +64 -65
- data/lib/lrama/grammar/symbol.rb +2 -0
- data/lib/lrama/grammar/symbols/resolver.rb +5 -1
- data/lib/lrama/grammar/symbols.rb +2 -0
- data/lib/lrama/grammar/type.rb +2 -0
- data/lib/lrama/grammar/union.rb +2 -0
- data/lib/lrama/grammar.rb +51 -30
- data/lib/lrama/grammar_validator.rb +37 -0
- data/lib/lrama/lexer/grammar_file.rb +2 -0
- data/lib/lrama/lexer/location.rb +2 -0
- data/lib/lrama/lexer/token/char.rb +2 -0
- data/lib/lrama/lexer/token/ident.rb +2 -0
- data/lib/lrama/lexer/token/instantiate_rule.rb +2 -0
- data/lib/lrama/lexer/token/tag.rb +2 -0
- data/lib/lrama/lexer/token/user_code.rb +3 -1
- data/lib/lrama/lexer/token.rb +7 -5
- data/lib/lrama/lexer.rb +11 -8
- data/lib/lrama/{warning.rb → logger.rb} +5 -13
- data/lib/lrama/option_parser.rb +58 -33
- data/lib/lrama/options.rb +5 -2
- data/lib/lrama/output.rb +38 -69
- data/lib/lrama/parser.rb +650 -779
- data/lib/lrama/report/duration.rb +2 -0
- data/lib/lrama/report/profile.rb +2 -0
- data/lib/lrama/report.rb +4 -2
- data/lib/lrama/state/reduce.rb +3 -0
- data/lib/lrama/state/reduce_reduce_conflict.rb +2 -0
- data/lib/lrama/state/resolved_conflict.rb +3 -1
- data/lib/lrama/state/shift.rb +2 -0
- data/lib/lrama/state/shift_reduce_conflict.rb +2 -0
- data/lib/lrama/state.rb +7 -5
- data/lib/lrama/states/item.rb +5 -3
- data/lib/lrama/states.rb +18 -46
- data/lib/lrama/states_reporter.rb +60 -19
- data/lib/lrama/trace_reporter.rb +30 -0
- data/lib/lrama/version.rb +3 -1
- data/lib/lrama.rb +22 -17
- data/lrama.gemspec +3 -1
- data/parser.y +110 -229
- data/sig/lrama/grammar/auxiliary.rbs +10 -0
- data/sig/lrama/grammar/binding.rbs +4 -0
- data/sig/lrama/grammar/code/destructor_code.rbs +3 -4
- data/sig/lrama/grammar/code/initial_action_code.rbs +15 -0
- data/sig/lrama/grammar/code/no_reference_code.rbs +15 -0
- data/sig/lrama/grammar/code/printer_code.rbs +3 -4
- data/sig/lrama/grammar/code/rule_action.rbs +19 -0
- data/sig/lrama/grammar/code.rbs +3 -3
- data/sig/lrama/grammar/destructor.rbs +3 -1
- data/sig/lrama/grammar/error_token.rbs +4 -2
- data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +2 -1
- data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +1 -1
- data/sig/lrama/grammar/precedence.rbs +3 -1
- data/sig/lrama/grammar/printer.rbs +3 -1
- data/sig/lrama/grammar/rule.rbs +35 -3
- data/sig/lrama/grammar/rule_builder.rbs +10 -9
- data/sig/lrama/grammar/symbol.rbs +6 -6
- data/sig/lrama/grammar/symbols/resolver.rbs +22 -3
- data/sig/lrama/grammar/type.rbs +2 -2
- data/sig/lrama/grammar/union.rbs +12 -0
- data/sig/lrama/grammar.rbs +91 -1
- data/sig/lrama/options.rbs +3 -2
- data/sig/lrama/state/reduce.rbs +20 -0
- data/sig/lrama/state/reduce_reduce_conflict.rbs +13 -0
- data/sig/lrama/state/resolved_conflict.rbs +14 -0
- data/sig/lrama/state/shift.rbs +14 -0
- data/sig/lrama/state/shift_reduce_conflict.rbs +13 -0
- data/sig/lrama/states/item.rbs +30 -0
- data/template/bison/yacc.c +24 -19
- metadata +17 -6
- data/sample/calc.output +0 -263
- data/sample/calc.y +0 -101
- data/sample/parse.y +0 -59
data/lib/lrama/report/profile.rb
CHANGED
data/lib/lrama/report.rb
CHANGED
data/lib/lrama/state/reduce.rb
CHANGED
@@ -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
|
# * 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
|
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})"
|
data/lib/lrama/state/shift.rb
CHANGED
data/lib/lrama/state.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
data/lib/lrama/states/item.rb
CHANGED
@@ -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 =
|
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
|
-
|
3
|
-
|
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,
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
-
|
494
|
+
(0...count).each do |i|
|
496
495
|
reduce1 = state.reduces[i]
|
497
496
|
next if reduce1.look_ahead.nil?
|
498
497
|
|
499
|
-
|
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
|
-
|
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
|
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
|
-
|
19
|
-
|
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
|
-
|
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
|
-
|
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"
|
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"
|
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"
|
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"
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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"
|
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
data/lib/lrama.rb
CHANGED
@@ -1,17 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|