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.
- checksums.yaml +4 -4
- data/.gitattributes +2 -0
- data/.github/workflows/codespell.yaml +1 -1
- data/.github/workflows/gh-pages.yml +5 -6
- data/.github/workflows/test.yaml +25 -14
- data/Gemfile +4 -3
- data/NEWS.md +370 -35
- data/README.md +7 -88
- data/Rakefile +3 -2
- data/Steepfile +11 -5
- data/doc/Index.md +1 -1
- data/doc/development/compressed_state_table/parser.rb +2 -0
- data/doc/development/profiling.md +44 -0
- data/exe/lrama +1 -1
- data/lib/lrama/bitmap.rb +18 -5
- data/lib/lrama/command.rb +95 -43
- data/lib/lrama/context.rb +22 -24
- data/lib/lrama/counterexamples/derivation.rb +14 -4
- data/lib/lrama/counterexamples/example.rb +47 -22
- data/lib/lrama/counterexamples/node.rb +30 -0
- data/lib/lrama/counterexamples/path.rb +12 -14
- data/lib/lrama/counterexamples/state_item.rb +24 -1
- data/lib/lrama/counterexamples/triple.rb +27 -9
- data/lib/lrama/counterexamples.rb +216 -88
- data/lib/lrama/diagram.rb +77 -0
- data/lib/lrama/digraph.rb +28 -7
- data/lib/lrama/erb.rb +29 -0
- data/lib/lrama/grammar/auxiliary.rb +6 -1
- data/lib/lrama/grammar/binding.rb +37 -25
- data/lib/lrama/grammar/code/destructor_code.rb +11 -0
- data/lib/lrama/grammar/code/initial_action_code.rb +3 -0
- data/lib/lrama/grammar/code/no_reference_code.rb +3 -0
- data/lib/lrama/grammar/code/printer_code.rb +11 -0
- data/lib/lrama/grammar/code/rule_action.rb +17 -0
- data/lib/lrama/grammar/code.rb +16 -1
- data/lib/lrama/grammar/counter.rb +10 -0
- data/lib/lrama/grammar/destructor.rb +14 -1
- data/lib/lrama/grammar/error_token.rb +14 -1
- data/lib/lrama/grammar/inline/resolver.rb +80 -0
- data/lib/lrama/grammar/inline.rb +3 -0
- data/lib/lrama/grammar/{parameterizing_rule → parameterized}/resolver.rb +19 -8
- data/lib/lrama/grammar/{parameterizing_rule → parameterized}/rhs.rb +7 -2
- data/lib/lrama/grammar/parameterized/rule.rb +36 -0
- data/lib/lrama/grammar/parameterized.rb +5 -0
- data/lib/lrama/grammar/percent_code.rb +12 -1
- data/lib/lrama/grammar/precedence.rb +43 -1
- data/lib/lrama/grammar/printer.rb +9 -0
- data/lib/lrama/grammar/reference.rb +13 -0
- data/lib/lrama/grammar/rule.rb +61 -1
- data/lib/lrama/grammar/rule_builder.rb +84 -69
- data/lib/lrama/grammar/stdlib.y +68 -48
- data/lib/lrama/grammar/symbol.rb +63 -19
- data/lib/lrama/grammar/symbols/resolver.rb +64 -3
- data/lib/lrama/grammar/type.rb +13 -1
- data/lib/lrama/grammar/union.rb +12 -1
- data/lib/lrama/grammar.rb +231 -35
- data/lib/lrama/lexer/location.rb +25 -8
- data/lib/lrama/lexer/token/base.rb +73 -0
- data/lib/lrama/lexer/token/char.rb +15 -2
- data/lib/lrama/lexer/token/empty.rb +14 -0
- data/lib/lrama/lexer/token/ident.rb +2 -2
- data/lib/lrama/lexer/token/instantiate_rule.rb +4 -4
- data/lib/lrama/lexer/token/int.rb +14 -0
- data/lib/lrama/lexer/token/str.rb +11 -0
- data/lib/lrama/lexer/token/tag.rb +2 -2
- data/lib/lrama/lexer/token/token.rb +11 -0
- data/lib/lrama/lexer/token/user_code.rb +63 -37
- data/lib/lrama/lexer/token.rb +6 -56
- data/lib/lrama/lexer.rb +51 -23
- data/lib/lrama/logger.rb +12 -2
- data/lib/lrama/option_parser.rb +63 -9
- data/lib/lrama/options.rb +25 -7
- data/lib/lrama/output.rb +4 -11
- data/lib/lrama/parser.rb +854 -723
- data/lib/lrama/reporter/conflicts.rb +44 -0
- data/lib/lrama/reporter/grammar.rb +39 -0
- data/lib/lrama/reporter/precedences.rb +54 -0
- data/lib/lrama/reporter/profile/call_stack.rb +45 -0
- data/lib/lrama/reporter/profile/memory.rb +44 -0
- data/lib/lrama/reporter/profile.rb +4 -0
- data/lib/lrama/reporter/rules.rb +43 -0
- data/lib/lrama/reporter/states.rb +387 -0
- data/lib/lrama/reporter/terms.rb +44 -0
- data/lib/lrama/reporter.rb +39 -0
- data/lib/lrama/state/action/goto.rb +33 -0
- data/lib/lrama/state/action/reduce.rb +71 -0
- data/lib/lrama/state/action/shift.rb +39 -0
- data/lib/lrama/state/action.rb +5 -0
- data/lib/lrama/state/inadequacy_annotation.rb +140 -0
- data/lib/lrama/{states → state}/item.rb +33 -4
- data/lib/lrama/state/reduce_reduce_conflict.rb +14 -1
- data/lib/lrama/state/resolved_conflict.rb +38 -4
- data/lib/lrama/state/shift_reduce_conflict.rb +14 -1
- data/lib/lrama/state.rb +301 -200
- data/lib/lrama/states.rb +447 -175
- data/lib/lrama/tracer/actions.rb +22 -0
- data/lib/lrama/tracer/closure.rb +30 -0
- data/lib/lrama/tracer/duration.rb +38 -0
- data/lib/lrama/tracer/only_explicit_rules.rb +24 -0
- data/lib/lrama/tracer/rules.rb +23 -0
- data/lib/lrama/tracer/state.rb +33 -0
- data/lib/lrama/tracer.rb +51 -0
- data/lib/lrama/version.rb +2 -1
- data/lib/lrama/warnings/conflicts.rb +27 -0
- data/lib/lrama/warnings/implicit_empty.rb +29 -0
- data/lib/lrama/warnings/name_conflicts.rb +63 -0
- data/lib/lrama/warnings/redefined_rules.rb +23 -0
- data/lib/lrama/warnings/required.rb +23 -0
- data/lib/lrama/warnings/useless_precedence.rb +25 -0
- data/lib/lrama/warnings.rb +33 -0
- data/lib/lrama.rb +5 -5
- data/parser.y +495 -404
- data/rbs_collection.lock.yaml +27 -3
- data/rbs_collection.yaml +2 -0
- data/sig/generated/lrama/bitmap.rbs +12 -4
- data/sig/generated/lrama/counterexamples/derivation.rbs +36 -0
- data/sig/generated/lrama/counterexamples/example.rbs +58 -0
- data/sig/generated/lrama/counterexamples/node.rbs +18 -0
- data/sig/generated/lrama/counterexamples/path.rbs +23 -0
- data/sig/generated/lrama/counterexamples/state_item.rbs +19 -0
- data/sig/generated/lrama/counterexamples/triple.rbs +32 -0
- data/sig/generated/lrama/counterexamples.rbs +98 -0
- data/sig/generated/lrama/diagram.rbs +34 -0
- data/sig/generated/lrama/digraph.rbs +26 -6
- data/sig/generated/lrama/erb.rbs +14 -0
- data/sig/generated/lrama/grammar/auxiliary.rbs +16 -0
- data/sig/generated/lrama/grammar/binding.rbs +18 -12
- data/sig/generated/lrama/grammar/code/destructor_code.rbs +26 -0
- data/sig/{lrama → generated/lrama}/grammar/code/initial_action_code.rbs +6 -0
- data/sig/{lrama → generated/lrama}/grammar/code/no_reference_code.rbs +6 -0
- data/sig/generated/lrama/grammar/code/printer_code.rbs +26 -0
- data/sig/generated/lrama/grammar/code/rule_action.rbs +63 -0
- data/sig/generated/lrama/grammar/code.rbs +38 -0
- data/sig/{lrama → generated/lrama}/grammar/counter.rbs +4 -0
- data/sig/generated/lrama/grammar/destructor.rbs +19 -0
- data/sig/generated/lrama/grammar/error_token.rbs +19 -0
- data/sig/generated/lrama/grammar/inline/resolver.rbs +26 -0
- data/sig/generated/lrama/grammar/parameterized/resolver.rbs +42 -0
- data/sig/generated/lrama/grammar/parameterized/rhs.rbs +21 -0
- data/sig/generated/lrama/grammar/parameterized/rule.rbs +28 -0
- data/sig/{lrama → generated/lrama}/grammar/percent_code.rbs +8 -0
- data/sig/generated/lrama/grammar/precedence.rbs +45 -0
- data/sig/{lrama/grammar/error_token.rbs → generated/lrama/grammar/printer.rbs} +8 -3
- data/sig/generated/lrama/grammar/reference.rbs +31 -0
- data/sig/generated/lrama/grammar/rule.rbs +83 -0
- data/sig/generated/lrama/grammar/rule_builder.rbs +91 -0
- data/sig/generated/lrama/grammar/symbol.rbs +89 -0
- data/sig/generated/lrama/grammar/symbols/resolver.rbs +131 -0
- data/sig/generated/lrama/grammar/type.rbs +21 -0
- data/sig/generated/lrama/grammar/union.rbs +17 -0
- data/sig/generated/lrama/grammar.rbs +289 -0
- data/sig/generated/lrama/lexer/location.rbs +12 -3
- data/sig/generated/lrama/lexer/token/base.rbs +53 -0
- data/sig/generated/lrama/lexer/token/char.rbs +9 -2
- data/sig/generated/lrama/lexer/token/empty.rbs +11 -0
- data/sig/generated/lrama/lexer/token/ident.rbs +2 -2
- data/sig/generated/lrama/lexer/token/instantiate_rule.rbs +5 -5
- data/sig/generated/lrama/lexer/token/int.rbs +13 -0
- data/sig/generated/lrama/lexer/token/str.rbs +10 -0
- data/sig/generated/lrama/lexer/token/tag.rbs +2 -2
- data/sig/generated/lrama/lexer/token/token.rbs +10 -0
- data/sig/generated/lrama/lexer/token/user_code.rbs +2 -2
- data/sig/generated/lrama/lexer/token.rbs +1 -39
- data/sig/generated/lrama/lexer.rbs +54 -0
- data/sig/generated/lrama/logger.rbs +6 -0
- data/sig/generated/lrama/option_parser.rbs +52 -0
- data/sig/{lrama → generated/lrama}/options.rbs +27 -3
- data/sig/generated/lrama/reporter/conflicts.rbs +18 -0
- data/sig/generated/lrama/reporter/grammar.rbs +13 -0
- data/sig/generated/lrama/reporter/precedences.rbs +15 -0
- data/sig/generated/lrama/reporter/profile/call_stack.rbs +19 -0
- data/sig/generated/lrama/reporter/profile/memory.rbs +19 -0
- data/sig/generated/lrama/reporter/rules.rbs +13 -0
- data/sig/generated/lrama/reporter/states.rbs +69 -0
- data/sig/generated/lrama/reporter/terms.rbs +13 -0
- data/sig/generated/lrama/reporter.rbs +13 -0
- data/sig/generated/lrama/state/action/goto.rbs +28 -0
- data/sig/generated/lrama/state/action/reduce.rbs +49 -0
- data/sig/generated/lrama/state/action/shift.rbs +33 -0
- data/sig/generated/lrama/state/inadequacy_annotation.rbs +45 -0
- data/sig/generated/lrama/state/item.rbs +75 -0
- data/sig/generated/lrama/state/reduce_reduce_conflict.rbs +19 -0
- data/sig/generated/lrama/state/resolved_conflict.rbs +38 -0
- data/sig/generated/lrama/state/shift_reduce_conflict.rbs +19 -0
- data/sig/generated/lrama/state.rbs +231 -0
- data/sig/generated/lrama/states.rbs +215 -0
- data/sig/generated/lrama/tracer/actions.rbs +13 -0
- data/sig/generated/lrama/tracer/closure.rbs +13 -0
- data/sig/generated/lrama/tracer/duration.rbs +18 -0
- data/sig/generated/lrama/tracer/only_explicit_rules.rbs +13 -0
- data/sig/generated/lrama/tracer/rules.rbs +13 -0
- data/sig/generated/lrama/tracer/state.rbs +16 -0
- data/sig/generated/lrama/tracer.rbs +23 -0
- data/sig/generated/lrama/version.rbs +5 -0
- data/sig/generated/lrama/warnings/conflicts.rbs +13 -0
- data/sig/generated/lrama/warnings/implicit_empty.rbs +17 -0
- data/sig/generated/lrama/warnings/name_conflicts.rbs +31 -0
- data/sig/generated/lrama/warnings/redefined_rules.rbs +13 -0
- data/sig/generated/lrama/warnings/required.rbs +13 -0
- data/sig/generated/lrama/warnings/useless_precedence.rbs +13 -0
- data/sig/generated/lrama/warnings.rbs +11 -0
- data/sig/railroad_diagrams/railroad_diagrams.rbs +16 -0
- data/template/bison/_yacc.h +8 -0
- data/template/diagram/diagram.html +102 -0
- metadata +126 -66
- data/lib/lrama/counterexamples/production_path.rb +0 -19
- data/lib/lrama/counterexamples/start_path.rb +0 -23
- data/lib/lrama/counterexamples/transition_path.rb +0 -19
- data/lib/lrama/diagnostics.rb +0 -36
- data/lib/lrama/grammar/parameterizing_rule/rule.rb +0 -24
- data/lib/lrama/grammar/parameterizing_rule.rb +0 -5
- data/lib/lrama/grammar_validator.rb +0 -37
- data/lib/lrama/report/duration.rb +0 -27
- data/lib/lrama/report/profile.rb +0 -16
- data/lib/lrama/report.rb +0 -4
- data/lib/lrama/state/reduce.rb +0 -37
- data/lib/lrama/state/shift.rb +0 -15
- data/lib/lrama/states_reporter.rb +0 -362
- data/lib/lrama/trace_reporter.rb +0 -45
- data/sig/generated/lrama/trace_reporter.rbs +0 -25
- data/sig/lrama/counterexamples/derivation.rbs +0 -33
- data/sig/lrama/counterexamples/example.rbs +0 -45
- data/sig/lrama/counterexamples/path.rbs +0 -21
- data/sig/lrama/counterexamples/production_path.rbs +0 -11
- data/sig/lrama/counterexamples/start_path.rbs +0 -13
- data/sig/lrama/counterexamples/state_item.rbs +0 -10
- data/sig/lrama/counterexamples/transition_path.rbs +0 -11
- data/sig/lrama/counterexamples/triple.rbs +0 -20
- data/sig/lrama/counterexamples.rbs +0 -29
- data/sig/lrama/grammar/auxiliary.rbs +0 -10
- data/sig/lrama/grammar/code/destructor_code.rbs +0 -14
- data/sig/lrama/grammar/code/printer_code.rbs +0 -14
- data/sig/lrama/grammar/code/rule_action.rbs +0 -19
- data/sig/lrama/grammar/code.rbs +0 -24
- data/sig/lrama/grammar/destructor.rbs +0 -13
- data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +0 -24
- data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +0 -14
- data/sig/lrama/grammar/parameterizing_rule/rule.rbs +0 -16
- data/sig/lrama/grammar/parameterizing_rule.rbs +0 -6
- data/sig/lrama/grammar/precedence.rbs +0 -13
- data/sig/lrama/grammar/printer.rbs +0 -13
- data/sig/lrama/grammar/reference.rbs +0 -22
- data/sig/lrama/grammar/rule.rbs +0 -45
- data/sig/lrama/grammar/rule_builder.rbs +0 -47
- data/sig/lrama/grammar/symbol.rbs +0 -38
- data/sig/lrama/grammar/symbols/resolver.rbs +0 -60
- data/sig/lrama/grammar/type.rbs +0 -11
- data/sig/lrama/grammar/union.rbs +0 -12
- data/sig/lrama/grammar.rbs +0 -108
- data/sig/lrama/report/duration.rbs +0 -11
- data/sig/lrama/report/profile.rbs +0 -7
- data/sig/lrama/state/reduce.rbs +0 -20
- data/sig/lrama/state/reduce_reduce_conflict.rbs +0 -13
- data/sig/lrama/state/resolved_conflict.rbs +0 -14
- data/sig/lrama/state/shift.rbs +0 -14
- data/sig/lrama/state/shift_reduce_conflict.rbs +0 -13
- data/sig/lrama/state.rbs +0 -79
- data/sig/lrama/states/item.rbs +0 -30
- data/sig/lrama/states.rbs +0 -101
- data/sig/lrama/warning.rbs +0 -16
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Lrama
|
|
5
|
+
class Reporter
|
|
6
|
+
class Terms
|
|
7
|
+
# @rbs (?terms: bool, **bool _) -> void
|
|
8
|
+
def initialize(terms: false, **_)
|
|
9
|
+
@terms = terms
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @rbs (IO io, Lrama::States states) -> void
|
|
13
|
+
def report(io, states)
|
|
14
|
+
return unless @terms
|
|
15
|
+
|
|
16
|
+
look_aheads = states.states.each do |state|
|
|
17
|
+
state.reduces.flat_map do |reduce|
|
|
18
|
+
reduce.look_ahead unless reduce.look_ahead.nil?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
next_terms = states.states.flat_map do |state|
|
|
23
|
+
state.term_transitions.map {|shift| shift.next_sym }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
unused_symbols = states.terms.reject do |term|
|
|
27
|
+
(look_aheads + next_terms).include?(term)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
io << states.terms.count << " Terms\n\n"
|
|
31
|
+
|
|
32
|
+
io << states.nterms.count << " Non-Terminals\n\n"
|
|
33
|
+
|
|
34
|
+
unless unused_symbols.empty?
|
|
35
|
+
io << "#{unused_symbols.count} Unused Terms\n\n"
|
|
36
|
+
unused_symbols.each_with_index do |term, index|
|
|
37
|
+
io << sprintf("%5d %s", index, term.id.s_value) << "\n"
|
|
38
|
+
end
|
|
39
|
+
io << "\n\n"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative 'reporter/conflicts'
|
|
5
|
+
require_relative 'reporter/grammar'
|
|
6
|
+
require_relative 'reporter/precedences'
|
|
7
|
+
require_relative 'reporter/profile'
|
|
8
|
+
require_relative 'reporter/rules'
|
|
9
|
+
require_relative 'reporter/states'
|
|
10
|
+
require_relative 'reporter/terms'
|
|
11
|
+
|
|
12
|
+
module Lrama
|
|
13
|
+
class Reporter
|
|
14
|
+
include Lrama::Tracer::Duration
|
|
15
|
+
|
|
16
|
+
# @rbs (**bool options) -> void
|
|
17
|
+
def initialize(**options)
|
|
18
|
+
@options = options
|
|
19
|
+
@rules = Rules.new(**options)
|
|
20
|
+
@terms = Terms.new(**options)
|
|
21
|
+
@conflicts = Conflicts.new
|
|
22
|
+
@precedences = Precedences.new
|
|
23
|
+
@grammar = Grammar.new(**options)
|
|
24
|
+
@states = States.new(**options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @rbs (File io, Lrama::States states) -> void
|
|
28
|
+
def report(io, states)
|
|
29
|
+
report_duration(:report) do
|
|
30
|
+
report_duration(:report_rules) { @rules.report(io, states) }
|
|
31
|
+
report_duration(:report_terms) { @terms.report(io, states) }
|
|
32
|
+
report_duration(:report_conflicts) { @conflicts.report(io, states) }
|
|
33
|
+
report_duration(:report_precedences) { @precedences.report(io, states) }
|
|
34
|
+
report_duration(:report_grammar) { @grammar.report(io, states) }
|
|
35
|
+
report_duration(:report_states) { @states.report(io, states, ielr: states.ielr_defined?) }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Lrama
|
|
5
|
+
class State
|
|
6
|
+
class Action
|
|
7
|
+
class Goto
|
|
8
|
+
# TODO: rbs-inline 0.11.0 doesn't support instance variables.
|
|
9
|
+
# Move these type declarations above instance variable definitions, once it's supported.
|
|
10
|
+
# see: https://github.com/soutaro/rbs-inline/pull/149
|
|
11
|
+
#
|
|
12
|
+
# @rbs!
|
|
13
|
+
# @from_state: State
|
|
14
|
+
# @next_sym: Grammar::Symbol
|
|
15
|
+
# @to_items: Array[Item]
|
|
16
|
+
# @to_state: State
|
|
17
|
+
|
|
18
|
+
attr_reader :from_state #: State
|
|
19
|
+
attr_reader :next_sym #: Grammar::Symbol
|
|
20
|
+
attr_reader :to_items #: Array[Item]
|
|
21
|
+
attr_reader :to_state #: State
|
|
22
|
+
|
|
23
|
+
# @rbs (State from_state, Grammar::Symbol next_sym, Array[Item] to_items, State to_state) -> void
|
|
24
|
+
def initialize(from_state, next_sym, to_items, to_state)
|
|
25
|
+
@from_state = from_state
|
|
26
|
+
@next_sym = next_sym
|
|
27
|
+
@to_items = to_items
|
|
28
|
+
@to_state = to_state
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Lrama
|
|
5
|
+
class State
|
|
6
|
+
class Action
|
|
7
|
+
class Reduce
|
|
8
|
+
# TODO: rbs-inline 0.11.0 doesn't support instance variables.
|
|
9
|
+
# Move these type declarations above instance variable definitions, once it's supported.
|
|
10
|
+
# see: https://github.com/soutaro/rbs-inline/pull/149
|
|
11
|
+
#
|
|
12
|
+
# @rbs!
|
|
13
|
+
# @item: Item
|
|
14
|
+
# @look_ahead: Array[Grammar::Symbol]?
|
|
15
|
+
# @look_ahead_sources: Hash[Grammar::Symbol, Array[Action::Goto]]?
|
|
16
|
+
# @not_selected_symbols: Array[Grammar::Symbol]
|
|
17
|
+
|
|
18
|
+
attr_reader :item #: Item
|
|
19
|
+
attr_reader :look_ahead #: Array[Grammar::Symbol]?
|
|
20
|
+
attr_reader :look_ahead_sources #: Hash[Grammar::Symbol, Array[Action::Goto]]?
|
|
21
|
+
attr_reader :not_selected_symbols #: Array[Grammar::Symbol]
|
|
22
|
+
|
|
23
|
+
# https://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html
|
|
24
|
+
attr_accessor :default_reduction #: bool
|
|
25
|
+
|
|
26
|
+
# @rbs (Item item) -> void
|
|
27
|
+
def initialize(item)
|
|
28
|
+
@item = item
|
|
29
|
+
@look_ahead = nil
|
|
30
|
+
@look_ahead_sources = nil
|
|
31
|
+
@not_selected_symbols = []
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @rbs () -> Grammar::Rule
|
|
35
|
+
def rule
|
|
36
|
+
@item.rule
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @rbs (Array[Grammar::Symbol] look_ahead) -> Array[Grammar::Symbol]
|
|
40
|
+
def look_ahead=(look_ahead)
|
|
41
|
+
@look_ahead = look_ahead.freeze
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @rbs (Hash[Grammar::Symbol, Array[Action::Goto]] sources) -> Hash[Grammar::Symbol, Array[Action::Goto]]
|
|
45
|
+
def look_ahead_sources=(sources)
|
|
46
|
+
@look_ahead_sources = sources.freeze
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @rbs (Grammar::Symbol sym) -> Array[Grammar::Symbol]
|
|
50
|
+
def add_not_selected_symbol(sym)
|
|
51
|
+
@not_selected_symbols << sym
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @rbs () -> (::Array[Grammar::Symbol?])
|
|
55
|
+
def selected_look_ahead
|
|
56
|
+
if look_ahead
|
|
57
|
+
look_ahead - @not_selected_symbols
|
|
58
|
+
else
|
|
59
|
+
[]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @rbs () -> void
|
|
64
|
+
def clear_conflicts
|
|
65
|
+
@not_selected_symbols = []
|
|
66
|
+
@default_reduction = nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Lrama
|
|
5
|
+
class State
|
|
6
|
+
class Action
|
|
7
|
+
class Shift
|
|
8
|
+
# TODO: rbs-inline 0.11.0 doesn't support instance variables.
|
|
9
|
+
# Move these type declarations above instance variable definitions, once it's supported.
|
|
10
|
+
# see: https://github.com/soutaro/rbs-inline/pull/149
|
|
11
|
+
#
|
|
12
|
+
# @rbs!
|
|
13
|
+
# @from_state: State
|
|
14
|
+
# @next_sym: Grammar::Symbol
|
|
15
|
+
# @to_items: Array[Item]
|
|
16
|
+
# @to_state: State
|
|
17
|
+
|
|
18
|
+
attr_reader :from_state #: State
|
|
19
|
+
attr_reader :next_sym #: Grammar::Symbol
|
|
20
|
+
attr_reader :to_items #: Array[Item]
|
|
21
|
+
attr_reader :to_state #: State
|
|
22
|
+
attr_accessor :not_selected #: bool
|
|
23
|
+
|
|
24
|
+
# @rbs (State from_state, Grammar::Symbol next_sym, Array[Item] to_items, State to_state) -> void
|
|
25
|
+
def initialize(from_state, next_sym, to_items, to_state)
|
|
26
|
+
@from_state = from_state
|
|
27
|
+
@next_sym = next_sym
|
|
28
|
+
@to_items = to_items
|
|
29
|
+
@to_state = to_state
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @rbs () -> void
|
|
33
|
+
def clear_conflicts
|
|
34
|
+
@not_selected = nil
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Lrama
|
|
5
|
+
class State
|
|
6
|
+
class InadequacyAnnotation
|
|
7
|
+
# @rbs!
|
|
8
|
+
# type action = Action::Shift | Action::Reduce
|
|
9
|
+
|
|
10
|
+
attr_accessor :state #: State
|
|
11
|
+
attr_accessor :token #: Grammar::Symbol
|
|
12
|
+
attr_accessor :actions #: Array[action]
|
|
13
|
+
attr_accessor :contribution_matrix #: Hash[action, Hash[Item, bool]]
|
|
14
|
+
|
|
15
|
+
# @rbs (State state, Grammar::Symbol token, Array[action] actions, Hash[action, Hash[Item, bool]] contribution_matrix) -> void
|
|
16
|
+
def initialize(state, token, actions, contribution_matrix)
|
|
17
|
+
@state = state
|
|
18
|
+
@token = token
|
|
19
|
+
@actions = actions
|
|
20
|
+
@contribution_matrix = contribution_matrix
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @rbs (Item item) -> bool
|
|
24
|
+
def contributed?(item)
|
|
25
|
+
@contribution_matrix.any? {|action, contributions| !contributions.nil? && contributions[item] }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @rbs (Array[Hash[action, Hash[Item, bool]]] another_matrixes) -> void
|
|
29
|
+
def merge_matrix(another_matrixes)
|
|
30
|
+
another_matrixes.each do |another_matrix|
|
|
31
|
+
@contribution_matrix.merge!(another_matrix) {|action, contributions, another_contributions|
|
|
32
|
+
next contributions if another_contributions.nil?
|
|
33
|
+
next another_contributions if contributions.nil?
|
|
34
|
+
|
|
35
|
+
contributions.merge!(another_contributions) {|_, contributed, another_contributed| contributed || another_contributed }
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Definition 3.42 (dominant_contribution)
|
|
41
|
+
#
|
|
42
|
+
# @rbs (State::lookahead_set lookaheads) -> Array[action]?
|
|
43
|
+
def dominant_contribution(lookaheads)
|
|
44
|
+
actions = @actions.select {|action|
|
|
45
|
+
contribution_matrix[action].nil? || contribution_matrix[action].any? {|item, contributed| contributed && lookaheads[item].include?(@token) }
|
|
46
|
+
}
|
|
47
|
+
return nil if actions.empty?
|
|
48
|
+
|
|
49
|
+
resolve_conflict(actions)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @rbs (Array[action] actions) -> Array[action]
|
|
53
|
+
def resolve_conflict(actions)
|
|
54
|
+
# @type var shifts: Array[Action::Shift]
|
|
55
|
+
# @type var reduces: Array[Action::Reduce]
|
|
56
|
+
shifts = actions.select {|action| action.is_a?(Action::Shift)}
|
|
57
|
+
reduces = actions.select {|action| action.is_a?(Action::Reduce) }
|
|
58
|
+
|
|
59
|
+
shifts.each do |shift|
|
|
60
|
+
reduces.each do |reduce|
|
|
61
|
+
sym = shift.next_sym
|
|
62
|
+
|
|
63
|
+
shift_prec = sym.precedence
|
|
64
|
+
reduce_prec = reduce.item.rule.precedence
|
|
65
|
+
|
|
66
|
+
# Can resolve only when both have prec
|
|
67
|
+
unless shift_prec && reduce_prec
|
|
68
|
+
next
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
case
|
|
72
|
+
when shift_prec < reduce_prec
|
|
73
|
+
# Reduce is selected
|
|
74
|
+
actions.delete(shift)
|
|
75
|
+
next
|
|
76
|
+
when shift_prec > reduce_prec
|
|
77
|
+
# Shift is selected
|
|
78
|
+
actions.delete(reduce)
|
|
79
|
+
next
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# shift_prec == reduce_prec, then check associativity
|
|
83
|
+
case sym.precedence&.type
|
|
84
|
+
when :precedence
|
|
85
|
+
# %precedence only specifies precedence and not specify associativity
|
|
86
|
+
# then a conflict is unresolved if precedence is same.
|
|
87
|
+
next
|
|
88
|
+
when :right
|
|
89
|
+
# Shift is selected
|
|
90
|
+
actions.delete(reduce)
|
|
91
|
+
next
|
|
92
|
+
when :left
|
|
93
|
+
# Reduce is selected
|
|
94
|
+
actions.delete(shift)
|
|
95
|
+
next
|
|
96
|
+
when :nonassoc
|
|
97
|
+
# Can not resolve
|
|
98
|
+
#
|
|
99
|
+
# nonassoc creates "run-time" error, precedence creates "compile-time" error.
|
|
100
|
+
# Then omit both the shift and reduce.
|
|
101
|
+
#
|
|
102
|
+
# https://www.gnu.org/software/bison/manual/html_node/Using-Precedence.html
|
|
103
|
+
actions.delete(shift)
|
|
104
|
+
actions.delete(reduce)
|
|
105
|
+
else
|
|
106
|
+
raise "Unknown precedence type. #{sym}"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
actions
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# @rbs () -> String
|
|
115
|
+
def to_s
|
|
116
|
+
"State: #{@state.id}, Token: #{@token.id.s_value}, Actions: #{actions_to_s}, Contributions: #{contribution_matrix_to_s}"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
# @rbs () -> String
|
|
122
|
+
def actions_to_s
|
|
123
|
+
'[' + @actions.map {|action|
|
|
124
|
+
if action.is_a?(Action::Shift) || action.is_a?(Action::Goto)
|
|
125
|
+
action.class.name
|
|
126
|
+
elsif action.is_a?(Action::Reduce)
|
|
127
|
+
"#{action.class.name}: (#{action.item})"
|
|
128
|
+
end
|
|
129
|
+
}.join(', ') + ']'
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @rbs () -> String
|
|
133
|
+
def contribution_matrix_to_s
|
|
134
|
+
'[' + @contribution_matrix.map {|action, contributions|
|
|
135
|
+
"#{(action.is_a?(Action::Shift) || action.is_a?(Action::Goto)) ? action.class.name : "#{action.class.name}: (#{action.item})"}: " + contributions&.transform_keys(&:to_s).to_s
|
|
136
|
+
}.join(', ') + ']'
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
1
2
|
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
# TODO: Validate position is not over rule rhs
|
|
@@ -5,84 +6,112 @@
|
|
|
5
6
|
require "forwardable"
|
|
6
7
|
|
|
7
8
|
module Lrama
|
|
8
|
-
class
|
|
9
|
+
class State
|
|
9
10
|
class Item < Struct.new(:rule, :position, keyword_init: true)
|
|
11
|
+
# @rbs!
|
|
12
|
+
# include Grammar::Rule::_DelegatedMethods
|
|
13
|
+
#
|
|
14
|
+
# attr_accessor rule: Grammar::Rule
|
|
15
|
+
# attr_accessor position: Integer
|
|
16
|
+
#
|
|
17
|
+
# def initialize: (?rule: Grammar::Rule, ?position: Integer) -> void
|
|
18
|
+
|
|
10
19
|
extend Forwardable
|
|
11
20
|
|
|
12
21
|
def_delegators "rule", :lhs, :rhs
|
|
13
22
|
|
|
14
23
|
# Optimization for States#setup_state
|
|
24
|
+
#
|
|
25
|
+
# @rbs () -> Integer
|
|
15
26
|
def hash
|
|
16
27
|
[rule_id, position].hash
|
|
17
28
|
end
|
|
18
29
|
|
|
30
|
+
# @rbs () -> Integer
|
|
19
31
|
def rule_id
|
|
20
32
|
rule.id
|
|
21
33
|
end
|
|
22
34
|
|
|
35
|
+
# @rbs () -> bool
|
|
23
36
|
def empty_rule?
|
|
24
37
|
rule.empty_rule?
|
|
25
38
|
end
|
|
26
39
|
|
|
40
|
+
# @rbs () -> Integer
|
|
27
41
|
def number_of_rest_symbols
|
|
28
|
-
rhs.count - position
|
|
42
|
+
@number_of_rest_symbols ||= rhs.count - position
|
|
29
43
|
end
|
|
30
44
|
|
|
45
|
+
# @rbs () -> Grammar::Symbol
|
|
31
46
|
def next_sym
|
|
32
47
|
rhs[position]
|
|
33
48
|
end
|
|
34
49
|
|
|
50
|
+
# @rbs () -> Grammar::Symbol
|
|
35
51
|
def next_next_sym
|
|
36
|
-
rhs[position + 1]
|
|
52
|
+
@next_next_sym ||= rhs[position + 1]
|
|
37
53
|
end
|
|
38
54
|
|
|
55
|
+
# @rbs () -> Grammar::Symbol
|
|
39
56
|
def previous_sym
|
|
40
57
|
rhs[position - 1]
|
|
41
58
|
end
|
|
42
59
|
|
|
60
|
+
# @rbs () -> bool
|
|
43
61
|
def end_of_rule?
|
|
44
62
|
rhs.count == position
|
|
45
63
|
end
|
|
46
64
|
|
|
65
|
+
# @rbs () -> bool
|
|
47
66
|
def beginning_of_rule?
|
|
48
67
|
position == 0
|
|
49
68
|
end
|
|
50
69
|
|
|
70
|
+
# @rbs () -> bool
|
|
51
71
|
def start_item?
|
|
52
72
|
rule.initial_rule? && beginning_of_rule?
|
|
53
73
|
end
|
|
54
74
|
|
|
75
|
+
# @rbs () -> State::Item
|
|
55
76
|
def new_by_next_position
|
|
56
77
|
Item.new(rule: rule, position: position + 1)
|
|
57
78
|
end
|
|
58
79
|
|
|
80
|
+
# @rbs () -> Array[Grammar::Symbol]
|
|
59
81
|
def symbols_before_dot # steep:ignore
|
|
60
82
|
rhs[0...position]
|
|
61
83
|
end
|
|
62
84
|
|
|
85
|
+
# @rbs () -> Array[Grammar::Symbol]
|
|
63
86
|
def symbols_after_dot # steep:ignore
|
|
64
87
|
rhs[position..-1]
|
|
65
88
|
end
|
|
66
89
|
|
|
67
|
-
|
|
90
|
+
# @rbs () -> Array[Grammar::Symbol]
|
|
91
|
+
def symbols_after_transition # steep:ignore
|
|
68
92
|
rhs[position+1..-1]
|
|
69
93
|
end
|
|
70
94
|
|
|
95
|
+
# @rbs () -> ::String
|
|
71
96
|
def to_s
|
|
72
97
|
"#{lhs.id.s_value}: #{display_name}"
|
|
73
98
|
end
|
|
74
99
|
|
|
100
|
+
# @rbs () -> ::String
|
|
75
101
|
def display_name
|
|
76
102
|
r = rhs.map(&:display_name).insert(position, "•").join(" ")
|
|
77
103
|
"#{r} (rule #{rule_id})"
|
|
78
104
|
end
|
|
79
105
|
|
|
80
106
|
# Right after position
|
|
107
|
+
#
|
|
108
|
+
# @rbs () -> ::String
|
|
81
109
|
def display_rest
|
|
82
110
|
r = symbols_after_dot.map(&:display_name).join(" ")
|
|
83
111
|
". #{r} (rule #{rule_id})"
|
|
84
112
|
end
|
|
85
113
|
|
|
114
|
+
# @rbs (State::Item other_item) -> bool
|
|
86
115
|
def predecessor_item_of?(other_item)
|
|
87
116
|
rule == other_item.rule && position == other_item.position - 1
|
|
88
117
|
end
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
1
2
|
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
module Lrama
|
|
4
5
|
class State
|
|
5
|
-
class ReduceReduceConflict
|
|
6
|
+
class ReduceReduceConflict
|
|
7
|
+
attr_reader :symbols #: Array[Grammar::Symbol]
|
|
8
|
+
attr_reader :reduce1 #: State::Action::Reduce
|
|
9
|
+
attr_reader :reduce2 #: State::Action::Reduce
|
|
10
|
+
|
|
11
|
+
# @rbs (symbols: Array[Grammar::Symbol], reduce1: State::Action::Reduce, reduce2: State::Action::Reduce) -> void
|
|
12
|
+
def initialize(symbols:, reduce1:, reduce2:)
|
|
13
|
+
@symbols = symbols
|
|
14
|
+
@reduce1 = reduce1
|
|
15
|
+
@reduce2 = reduce2
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @rbs () -> :reduce_reduce
|
|
6
19
|
def type
|
|
7
20
|
:reduce_reduce
|
|
8
21
|
end
|
|
@@ -1,20 +1,54 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
1
2
|
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
module Lrama
|
|
4
5
|
class State
|
|
6
|
+
# * state: A state on which the conflct is resolved
|
|
5
7
|
# * symbol: A symbol under discussion
|
|
6
8
|
# * reduce: A reduce under discussion
|
|
7
9
|
# * which: For which a conflict is resolved. :shift, :reduce or :error (for nonassociative)
|
|
8
|
-
|
|
10
|
+
# * resolved_by_precedence: If the conflict is resolved by precedence definition or not
|
|
11
|
+
class ResolvedConflict
|
|
12
|
+
# @rbs!
|
|
13
|
+
# type which_enum = :reduce | :shift | :error
|
|
14
|
+
|
|
15
|
+
attr_reader :state #: State
|
|
16
|
+
attr_reader :symbol #: Grammar::Symbol
|
|
17
|
+
attr_reader :reduce #: State::Action::Reduce
|
|
18
|
+
attr_reader :which #: which_enum
|
|
19
|
+
attr_reader :resolved_by_precedence #: bool
|
|
20
|
+
|
|
21
|
+
# @rbs (state: State, symbol: Grammar::Symbol, reduce: State::Action::Reduce, which: which_enum, resolved_by_precedence: bool) -> void
|
|
22
|
+
def initialize(state:, symbol:, reduce:, which:, resolved_by_precedence:)
|
|
23
|
+
@state = state
|
|
24
|
+
@symbol = symbol
|
|
25
|
+
@reduce = reduce
|
|
26
|
+
@which = which
|
|
27
|
+
@resolved_by_precedence = resolved_by_precedence
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @rbs () -> (::String | bot)
|
|
9
31
|
def report_message
|
|
32
|
+
"Conflict between rule #{reduce.rule.id} and token #{symbol.display_name} #{how_resolved}."
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @rbs () -> (::String | bot)
|
|
36
|
+
def report_precedences_message
|
|
37
|
+
"Conflict between reduce by \"#{reduce.rule.display_name}\" and shift #{symbol.display_name} #{how_resolved}."
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# @rbs () -> (::String | bot)
|
|
43
|
+
def how_resolved
|
|
10
44
|
s = symbol.display_name
|
|
11
45
|
r = reduce.rule.precedence_sym&.display_name
|
|
12
46
|
case
|
|
13
|
-
when which == :shift &&
|
|
47
|
+
when which == :shift && resolved_by_precedence
|
|
14
48
|
msg = "resolved as #{which} (%right #{s})"
|
|
15
49
|
when which == :shift
|
|
16
50
|
msg = "resolved as #{which} (#{r} < #{s})"
|
|
17
|
-
when which == :reduce &&
|
|
51
|
+
when which == :reduce && resolved_by_precedence
|
|
18
52
|
msg = "resolved as #{which} (%left #{s})"
|
|
19
53
|
when which == :reduce
|
|
20
54
|
msg = "resolved as #{which} (#{s} < #{r})"
|
|
@@ -24,7 +58,7 @@ module Lrama
|
|
|
24
58
|
raise "Unknown direction. #{self}"
|
|
25
59
|
end
|
|
26
60
|
|
|
27
|
-
|
|
61
|
+
msg
|
|
28
62
|
end
|
|
29
63
|
end
|
|
30
64
|
end
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
1
2
|
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
module Lrama
|
|
4
5
|
class State
|
|
5
|
-
class ShiftReduceConflict
|
|
6
|
+
class ShiftReduceConflict
|
|
7
|
+
attr_reader :symbols #: Array[Grammar::Symbol]
|
|
8
|
+
attr_reader :shift #: State::Action::Shift
|
|
9
|
+
attr_reader :reduce #: State::Action::Reduce
|
|
10
|
+
|
|
11
|
+
# @rbs (symbols: Array[Grammar::Symbol], shift: State::Action::Shift, reduce: State::Action::Reduce) -> void
|
|
12
|
+
def initialize(symbols:, shift:, reduce:)
|
|
13
|
+
@symbols = symbols
|
|
14
|
+
@shift = shift
|
|
15
|
+
@reduce = reduce
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @rbs () -> :shift_reduce
|
|
6
19
|
def type
|
|
7
20
|
:shift_reduce
|
|
8
21
|
end
|