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
data/lib/lrama/state.rb
CHANGED
|
@@ -1,17 +1,62 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
1
2
|
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require_relative "state/
|
|
4
|
+
require_relative "state/action"
|
|
5
|
+
require_relative "state/inadequacy_annotation"
|
|
6
|
+
require_relative "state/item"
|
|
4
7
|
require_relative "state/reduce_reduce_conflict"
|
|
5
8
|
require_relative "state/resolved_conflict"
|
|
6
|
-
require_relative "state/shift"
|
|
7
9
|
require_relative "state/shift_reduce_conflict"
|
|
8
10
|
|
|
9
11
|
module Lrama
|
|
10
12
|
class State
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# TODO: rbs-inline 0.11.0 doesn't support instance variables.
|
|
14
|
+
# Move these type declarations above instance variable definitions, once it's supported.
|
|
15
|
+
# see: https://github.com/soutaro/rbs-inline/pull/149
|
|
16
|
+
#
|
|
17
|
+
# @rbs!
|
|
18
|
+
# type conflict = State::ShiftReduceConflict | State::ReduceReduceConflict
|
|
19
|
+
# type transition = Action::Shift | Action::Goto
|
|
20
|
+
# type lookahead_set = Hash[Item, Array[Grammar::Symbol]]
|
|
21
|
+
#
|
|
22
|
+
# @id: Integer
|
|
23
|
+
# @accessing_symbol: Grammar::Symbol
|
|
24
|
+
# @kernels: Array[Item]
|
|
25
|
+
# @items: Array[Item]
|
|
26
|
+
# @items_to_state: Hash[Array[Item], State]
|
|
27
|
+
# @conflicts: Array[conflict]
|
|
28
|
+
# @resolved_conflicts: Array[ResolvedConflict]
|
|
29
|
+
# @default_reduction_rule: Grammar::Rule?
|
|
30
|
+
# @closure: Array[Item]
|
|
31
|
+
# @nterm_transitions: Array[Action::Goto]
|
|
32
|
+
# @term_transitions: Array[Action::Shift]
|
|
33
|
+
# @transitions: Array[transition]
|
|
34
|
+
# @internal_dependencies: Hash[Action::Goto, Array[Action::Goto]]
|
|
35
|
+
# @successor_dependencies: Hash[Action::Goto, Array[Action::Goto]]
|
|
36
|
+
|
|
37
|
+
attr_reader :id #: Integer
|
|
38
|
+
attr_reader :accessing_symbol #: Grammar::Symbol
|
|
39
|
+
attr_reader :kernels #: Array[Item]
|
|
40
|
+
attr_reader :conflicts #: Array[conflict]
|
|
41
|
+
attr_reader :resolved_conflicts #: Array[ResolvedConflict]
|
|
42
|
+
attr_reader :default_reduction_rule #: Grammar::Rule?
|
|
43
|
+
attr_reader :closure #: Array[Item]
|
|
44
|
+
attr_reader :items #: Array[Item]
|
|
45
|
+
attr_reader :annotation_list #: Array[InadequacyAnnotation]
|
|
46
|
+
attr_reader :predecessors #: Array[State]
|
|
47
|
+
attr_reader :items_to_state #: Hash[Array[Item], State]
|
|
48
|
+
attr_reader :lane_items #: Hash[State, Array[[Item, Item]]]
|
|
49
|
+
|
|
50
|
+
attr_accessor :_transitions #: Array[[Grammar::Symbol, Array[Item]]]
|
|
51
|
+
attr_accessor :reduces #: Array[Action::Reduce]
|
|
52
|
+
attr_accessor :ielr_isocores #: Array[State]
|
|
53
|
+
attr_accessor :lalr_isocore #: State
|
|
54
|
+
attr_accessor :lookaheads_recomputed #: bool
|
|
55
|
+
attr_accessor :follow_kernel_items #: Hash[Action::Goto, Hash[Item, bool]]
|
|
56
|
+
attr_accessor :always_follows #: Hash[Action::Goto, Array[Grammar::Symbol]]
|
|
57
|
+
attr_accessor :goto_follows #: Hash[Action::Goto, Array[Grammar::Symbol]]
|
|
58
|
+
|
|
59
|
+
# @rbs (Integer id, Grammar::Symbol accessing_symbol, Array[Item] kernels) -> void
|
|
15
60
|
def initialize(id, accessing_symbol, kernels)
|
|
16
61
|
@id = id
|
|
17
62
|
@accessing_symbol = accessing_symbol
|
|
@@ -28,48 +73,72 @@ module Lrama
|
|
|
28
73
|
@ielr_isocores = [self]
|
|
29
74
|
@internal_dependencies = {}
|
|
30
75
|
@successor_dependencies = {}
|
|
76
|
+
@annotation_list = []
|
|
77
|
+
@lookaheads_recomputed = false
|
|
78
|
+
@follow_kernel_items = {}
|
|
31
79
|
@always_follows = {}
|
|
80
|
+
@goto_follows = {}
|
|
81
|
+
@lhs_contributions = {}
|
|
82
|
+
@lane_items = {}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @rbs (State other) -> bool
|
|
86
|
+
def ==(other)
|
|
87
|
+
self.id == other.id
|
|
32
88
|
end
|
|
33
89
|
|
|
90
|
+
# @rbs (Array[Item] closure) -> void
|
|
34
91
|
def closure=(closure)
|
|
35
92
|
@closure = closure
|
|
36
93
|
@items = @kernels + @closure
|
|
37
94
|
end
|
|
38
95
|
|
|
96
|
+
# @rbs () -> Array[Action::Reduce]
|
|
39
97
|
def non_default_reduces
|
|
40
98
|
reduces.reject do |reduce|
|
|
41
99
|
reduce.rule == @default_reduction_rule
|
|
42
100
|
end
|
|
43
101
|
end
|
|
44
102
|
|
|
45
|
-
|
|
46
|
-
|
|
103
|
+
# @rbs () -> void
|
|
104
|
+
def compute_transitions_and_reduces
|
|
105
|
+
_transitions = {}
|
|
106
|
+
@_lane_items ||= {}
|
|
47
107
|
reduces = []
|
|
48
108
|
items.each do |item|
|
|
49
109
|
# TODO: Consider what should be pushed
|
|
50
110
|
if item.end_of_rule?
|
|
51
|
-
reduces << Reduce.new(item)
|
|
111
|
+
reduces << Action::Reduce.new(item)
|
|
52
112
|
else
|
|
53
113
|
key = item.next_sym
|
|
54
|
-
|
|
55
|
-
|
|
114
|
+
_transitions[key] ||= []
|
|
115
|
+
@_lane_items[key] ||= []
|
|
116
|
+
next_item = item.new_by_next_position
|
|
117
|
+
_transitions[key] << next_item
|
|
118
|
+
@_lane_items[key] << [item, next_item]
|
|
56
119
|
end
|
|
57
120
|
end
|
|
58
121
|
|
|
59
122
|
# It seems Bison 3.8.2 iterates transitions order by symbol number
|
|
60
|
-
|
|
123
|
+
transitions = _transitions.sort_by do |next_sym, to_items|
|
|
61
124
|
next_sym.number
|
|
62
|
-
end.map do |next_sym, new_items|
|
|
63
|
-
Shift.new(next_sym, new_items.flatten)
|
|
64
125
|
end
|
|
65
|
-
|
|
126
|
+
|
|
127
|
+
self._transitions = transitions.freeze
|
|
66
128
|
self.reduces = reduces.freeze
|
|
67
129
|
end
|
|
68
130
|
|
|
131
|
+
# @rbs (Grammar::Symbol next_sym, State next_state) -> void
|
|
132
|
+
def set_lane_items(next_sym, next_state)
|
|
133
|
+
@lane_items[next_state] = @_lane_items[next_sym]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# @rbs (Array[Item] items, State next_state) -> void
|
|
69
137
|
def set_items_to_state(items, next_state)
|
|
70
138
|
@items_to_state[items] = next_state
|
|
71
139
|
end
|
|
72
140
|
|
|
141
|
+
# @rbs (Grammar::Rule rule, Array[Grammar::Symbol] look_ahead) -> void
|
|
73
142
|
def set_look_ahead(rule, look_ahead)
|
|
74
143
|
reduce = reduces.find do |r|
|
|
75
144
|
r.rule == rule
|
|
@@ -78,50 +147,78 @@ module Lrama
|
|
|
78
147
|
reduce.look_ahead = look_ahead
|
|
79
148
|
end
|
|
80
149
|
|
|
81
|
-
|
|
82
|
-
|
|
150
|
+
# @rbs (Grammar::Rule rule, Hash[Grammar::Symbol, Array[Action::Goto]] sources) -> void
|
|
151
|
+
def set_look_ahead_sources(rule, sources)
|
|
152
|
+
reduce = reduces.find do |r|
|
|
153
|
+
r.rule == rule
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
reduce.look_ahead_sources = sources
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# @rbs () -> Array[Action::Goto]
|
|
160
|
+
def nterm_transitions # steep:ignore
|
|
161
|
+
@nterm_transitions ||= transitions.select {|transition| transition.is_a?(Action::Goto) }
|
|
83
162
|
end
|
|
84
163
|
|
|
85
|
-
|
|
86
|
-
|
|
164
|
+
# @rbs () -> Array[Action::Shift]
|
|
165
|
+
def term_transitions # steep:ignore
|
|
166
|
+
@term_transitions ||= transitions.select {|transition| transition.is_a?(Action::Shift) }
|
|
87
167
|
end
|
|
88
168
|
|
|
169
|
+
# @rbs () -> Array[transition]
|
|
89
170
|
def transitions
|
|
90
|
-
@transitions ||=
|
|
171
|
+
@transitions ||= _transitions.map do |next_sym, to_items|
|
|
172
|
+
if next_sym.term?
|
|
173
|
+
Action::Shift.new(self, next_sym, to_items.flatten, @items_to_state[to_items])
|
|
174
|
+
else
|
|
175
|
+
Action::Goto.new(self, next_sym, to_items.flatten, @items_to_state[to_items])
|
|
176
|
+
end
|
|
177
|
+
end
|
|
91
178
|
end
|
|
92
179
|
|
|
93
|
-
|
|
94
|
-
|
|
180
|
+
# @rbs (transition transition, State next_state) -> void
|
|
181
|
+
def update_transition(transition, next_state)
|
|
182
|
+
set_items_to_state(transition.to_items, next_state)
|
|
95
183
|
next_state.append_predecessor(self)
|
|
96
|
-
|
|
184
|
+
update_transitions_caches(transition)
|
|
97
185
|
end
|
|
98
186
|
|
|
99
|
-
|
|
187
|
+
# @rbs () -> void
|
|
188
|
+
def update_transitions_caches(transition)
|
|
189
|
+
new_transition =
|
|
190
|
+
if transition.next_sym.term?
|
|
191
|
+
Action::Shift.new(self, transition.next_sym, transition.to_items, @items_to_state[transition.to_items])
|
|
192
|
+
else
|
|
193
|
+
Action::Goto.new(self, transition.next_sym, transition.to_items, @items_to_state[transition.to_items])
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
@transitions.delete(transition)
|
|
197
|
+
@transitions << new_transition
|
|
100
198
|
@nterm_transitions = nil
|
|
101
199
|
@term_transitions = nil
|
|
102
|
-
|
|
200
|
+
|
|
201
|
+
@follow_kernel_items[new_transition] = @follow_kernel_items.delete(transition)
|
|
202
|
+
@always_follows[new_transition] = @always_follows.delete(transition)
|
|
103
203
|
end
|
|
104
204
|
|
|
205
|
+
# @rbs () -> Array[Action::Shift]
|
|
105
206
|
def selected_term_transitions
|
|
106
|
-
term_transitions.reject do |shift
|
|
207
|
+
term_transitions.reject do |shift|
|
|
107
208
|
shift.not_selected
|
|
108
209
|
end
|
|
109
210
|
end
|
|
110
211
|
|
|
111
212
|
# Move to next state by sym
|
|
213
|
+
#
|
|
214
|
+
# @rbs (Grammar::Symbol sym) -> State
|
|
112
215
|
def transition(sym)
|
|
113
216
|
result = nil
|
|
114
217
|
|
|
115
218
|
if sym.term?
|
|
116
|
-
term_transitions.
|
|
117
|
-
term = shift.next_sym
|
|
118
|
-
result = next_state if term == sym
|
|
119
|
-
end
|
|
219
|
+
result = term_transitions.find {|shift| shift.next_sym == sym }.to_state
|
|
120
220
|
else
|
|
121
|
-
nterm_transitions.
|
|
122
|
-
nterm = shift.next_sym
|
|
123
|
-
result = next_state if nterm == sym
|
|
124
|
-
end
|
|
221
|
+
result = nterm_transitions.find {|goto| goto.next_sym == sym }.to_state
|
|
125
222
|
end
|
|
126
223
|
|
|
127
224
|
raise "Can not transit by #{sym} #{self}" if result.nil?
|
|
@@ -129,12 +226,14 @@ module Lrama
|
|
|
129
226
|
result
|
|
130
227
|
end
|
|
131
228
|
|
|
229
|
+
# @rbs (Item item) -> Action::Reduce
|
|
132
230
|
def find_reduce_by_item!(item)
|
|
133
231
|
reduces.find do |r|
|
|
134
232
|
r.item == item
|
|
135
233
|
end || (raise "reduce is not found. #{item}")
|
|
136
234
|
end
|
|
137
235
|
|
|
236
|
+
# @rbs (Grammar::Rule default_reduction_rule) -> void
|
|
138
237
|
def default_reduction_rule=(default_reduction_rule)
|
|
139
238
|
@default_reduction_rule = default_reduction_rule
|
|
140
239
|
|
|
@@ -145,200 +244,219 @@ module Lrama
|
|
|
145
244
|
end
|
|
146
245
|
end
|
|
147
246
|
|
|
247
|
+
# @rbs () -> bool
|
|
148
248
|
def has_conflicts?
|
|
149
249
|
!@conflicts.empty?
|
|
150
250
|
end
|
|
151
251
|
|
|
252
|
+
# @rbs () -> Array[conflict]
|
|
152
253
|
def sr_conflicts
|
|
153
254
|
@conflicts.select do |conflict|
|
|
154
255
|
conflict.type == :shift_reduce
|
|
155
256
|
end
|
|
156
257
|
end
|
|
157
258
|
|
|
259
|
+
# @rbs () -> Array[conflict]
|
|
158
260
|
def rr_conflicts
|
|
159
261
|
@conflicts.select do |conflict|
|
|
160
262
|
conflict.type == :reduce_reduce
|
|
161
263
|
end
|
|
162
264
|
end
|
|
163
265
|
|
|
266
|
+
# Clear information related to conflicts.
|
|
267
|
+
# IELR computation re-calculates conflicts and default reduction of states
|
|
268
|
+
# after LALR computation.
|
|
269
|
+
# Call this method before IELR computation to avoid duplicated conflicts information
|
|
270
|
+
# is stored.
|
|
271
|
+
#
|
|
272
|
+
# @rbs () -> void
|
|
273
|
+
def clear_conflicts
|
|
274
|
+
@conflicts = []
|
|
275
|
+
@resolved_conflicts = []
|
|
276
|
+
@default_reduction_rule = nil
|
|
277
|
+
|
|
278
|
+
term_transitions.each(&:clear_conflicts)
|
|
279
|
+
reduces.each(&:clear_conflicts)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# @rbs () -> bool
|
|
283
|
+
def split_state?
|
|
284
|
+
@lalr_isocore != self
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Definition 3.40 (propagate_lookaheads)
|
|
288
|
+
#
|
|
289
|
+
# @rbs (State next_state) -> lookahead_set
|
|
164
290
|
def propagate_lookaheads(next_state)
|
|
165
|
-
next_state.kernels.map {|
|
|
291
|
+
next_state.kernels.map {|next_kernel|
|
|
166
292
|
lookahead_sets =
|
|
167
|
-
if
|
|
168
|
-
|
|
169
|
-
else
|
|
170
|
-
kernel = kernels.find {|k| k.predecessor_item_of?(item) }
|
|
293
|
+
if next_kernel.position > 1
|
|
294
|
+
kernel = kernels.find {|k| k.predecessor_item_of?(next_kernel) }
|
|
171
295
|
item_lookahead_set[kernel]
|
|
296
|
+
else
|
|
297
|
+
goto_follow_set(next_kernel.lhs)
|
|
172
298
|
end
|
|
173
299
|
|
|
174
|
-
[
|
|
300
|
+
[next_kernel, lookahead_sets & next_state.lookahead_set_filters[next_kernel]]
|
|
175
301
|
}.to_h
|
|
176
302
|
end
|
|
177
303
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
def compatible_lookahead?(filtered_lookahead)
|
|
304
|
+
# Definition 3.43 (is_compatible)
|
|
305
|
+
#
|
|
306
|
+
# @rbs (lookahead_set filtered_lookahead) -> bool
|
|
307
|
+
def is_compatible?(filtered_lookahead)
|
|
183
308
|
!lookaheads_recomputed ||
|
|
184
|
-
@lalr_isocore.annotation_list.all? {|
|
|
185
|
-
a = dominant_contribution(
|
|
186
|
-
b = dominant_contribution(
|
|
309
|
+
@lalr_isocore.annotation_list.all? {|annotation|
|
|
310
|
+
a = annotation.dominant_contribution(item_lookahead_set)
|
|
311
|
+
b = annotation.dominant_contribution(filtered_lookahead)
|
|
187
312
|
a.nil? || b.nil? || a == b
|
|
188
313
|
}
|
|
189
314
|
end
|
|
190
315
|
|
|
316
|
+
# Definition 3.38 (lookahead_set_filters)
|
|
317
|
+
#
|
|
318
|
+
# @rbs () -> lookahead_set
|
|
191
319
|
def lookahead_set_filters
|
|
192
|
-
kernels.map {|kernel|
|
|
193
|
-
[kernel,
|
|
194
|
-
@lalr_isocore.annotation_list.select {|token, actions|
|
|
195
|
-
token.term? && actions.any? {|action, contributions|
|
|
196
|
-
!contributions.nil? && contributions.key?(kernel) && contributions[kernel]
|
|
197
|
-
}
|
|
198
|
-
}.map {|token, _| token }
|
|
199
|
-
]
|
|
320
|
+
@lookahead_set_filters ||= kernels.map {|kernel|
|
|
321
|
+
[kernel, @lalr_isocore.annotation_list.select {|annotation| annotation.contributed?(kernel) }.map(&:token)]
|
|
200
322
|
}.to_h
|
|
201
323
|
end
|
|
202
324
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}.map {|action, _| action }
|
|
207
|
-
return nil if a.empty?
|
|
208
|
-
a.reject {|action|
|
|
209
|
-
if action.is_a?(State::Shift)
|
|
210
|
-
action.not_selected
|
|
211
|
-
elsif action.is_a?(State::Reduce)
|
|
212
|
-
action.not_selected_symbols.include?(token)
|
|
213
|
-
end
|
|
214
|
-
}
|
|
215
|
-
end
|
|
216
|
-
|
|
325
|
+
# Definition 3.27 (inadequacy_lists)
|
|
326
|
+
#
|
|
327
|
+
# @rbs () -> Hash[Grammar::Symbol, Array[Action::Shift | Action::Reduce]]
|
|
217
328
|
def inadequacy_list
|
|
218
329
|
return @inadequacy_list if @inadequacy_list
|
|
219
330
|
|
|
220
|
-
|
|
221
|
-
[shift.next_sym, [shift]]
|
|
222
|
-
}.to_h
|
|
223
|
-
reduce_contributions = reduces.map {|reduce|
|
|
224
|
-
(reduce.look_ahead || []).map {|sym|
|
|
225
|
-
[sym, [reduce]]
|
|
226
|
-
}.to_h
|
|
227
|
-
}.reduce(Hash.new([])) {|hash, cont|
|
|
228
|
-
hash.merge(cont) {|_, a, b| a | b }
|
|
229
|
-
}
|
|
331
|
+
inadequacy_list = {}
|
|
230
332
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
actions_a.merge(actions_b) {|_, contributions_a, contributions_b|
|
|
246
|
-
if contributions_a.nil? || contributions_b.nil?
|
|
247
|
-
next contributions_a || contributions_b
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
contributions_a.merge(contributions_b) {|_, contributed_a, contributed_b|
|
|
251
|
-
contributed_a || contributed_b
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
end
|
|
255
|
-
}
|
|
256
|
-
}
|
|
333
|
+
term_transitions.each do |shift|
|
|
334
|
+
inadequacy_list[shift.next_sym] ||= []
|
|
335
|
+
inadequacy_list[shift.next_sym] << shift.dup
|
|
336
|
+
end
|
|
337
|
+
reduces.each do |reduce|
|
|
338
|
+
next if reduce.look_ahead.nil?
|
|
339
|
+
|
|
340
|
+
reduce.look_ahead.each do |token|
|
|
341
|
+
inadequacy_list[token] ||= []
|
|
342
|
+
inadequacy_list[token] << reduce.dup
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
@inadequacy_list = inadequacy_list.select {|token, actions| actions.size > 1 }
|
|
257
347
|
end
|
|
258
348
|
|
|
349
|
+
# Definition 3.30 (annotate_manifestation)
|
|
350
|
+
#
|
|
351
|
+
# @rbs () -> void
|
|
259
352
|
def annotate_manifestation
|
|
260
|
-
inadequacy_list.
|
|
261
|
-
actions.map {|action|
|
|
262
|
-
if action.is_a?(Shift)
|
|
353
|
+
inadequacy_list.each {|token, actions|
|
|
354
|
+
contribution_matrix = actions.map {|action|
|
|
355
|
+
if action.is_a?(Action::Shift)
|
|
263
356
|
[action, nil]
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
[action, lhs_contributions(action.rule.lhs, inadequacy_list.key(actions))]
|
|
267
|
-
else
|
|
268
|
-
contributions = kernels.map {|kernel| [kernel, kernel.rule == action.rule && kernel.end_of_rule?] }.to_h
|
|
269
|
-
[action, contributions]
|
|
270
|
-
end
|
|
357
|
+
else
|
|
358
|
+
[action, action.rule.empty_rule? ? lhs_contributions(action.rule.lhs, token) : kernels.map {|k| [k, k.rule == action.item.rule && k.end_of_rule?] }.to_h]
|
|
271
359
|
end
|
|
272
360
|
}.to_h
|
|
361
|
+
@annotation_list << InadequacyAnnotation.new(self, token, actions, contribution_matrix)
|
|
273
362
|
}
|
|
274
363
|
end
|
|
275
364
|
|
|
365
|
+
# Definition 3.32 (annotate_predecessor)
|
|
366
|
+
#
|
|
367
|
+
# @rbs (State predecessor) -> void
|
|
276
368
|
def annotate_predecessor(predecessor)
|
|
277
|
-
annotation_list.
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
if lhs_adequacy
|
|
285
|
-
next nil
|
|
369
|
+
propagating_list = annotation_list.map {|annotation|
|
|
370
|
+
contribution_matrix = annotation.contribution_matrix.map {|action, contributions|
|
|
371
|
+
if contributions.nil?
|
|
372
|
+
[action, nil]
|
|
373
|
+
elsif first_kernels.any? {|kernel| contributions[kernel] && predecessor.lhs_contributions(kernel.lhs, annotation.token).empty? }
|
|
374
|
+
[action, nil]
|
|
286
375
|
else
|
|
287
|
-
predecessor.
|
|
288
|
-
[
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}]
|
|
376
|
+
cs = predecessor.lane_items[self].map {|pred_kernel, kernel|
|
|
377
|
+
c = contributions[kernel] && (
|
|
378
|
+
(kernel.position > 1 && predecessor.item_lookahead_set[pred_kernel].include?(annotation.token)) ||
|
|
379
|
+
(kernel.position == 1 && predecessor.lhs_contributions(kernel.lhs, annotation.token)[pred_kernel])
|
|
380
|
+
)
|
|
381
|
+
[pred_kernel, c]
|
|
294
382
|
}.to_h
|
|
383
|
+
[action, cs]
|
|
295
384
|
end
|
|
296
|
-
}
|
|
297
|
-
|
|
385
|
+
}.to_h
|
|
386
|
+
|
|
387
|
+
# Observation 3.33 (Simple Split-Stable Dominance)
|
|
388
|
+
#
|
|
389
|
+
# If all of contributions in the contribution_matrix are
|
|
390
|
+
# always contribution or never contribution, we can stop annotate propagations
|
|
391
|
+
# to the predecessor state.
|
|
392
|
+
next nil if contribution_matrix.all? {|_, contributions| contributions.nil? || contributions.all? {|_, contributed| !contributed } }
|
|
393
|
+
|
|
394
|
+
InadequacyAnnotation.new(annotation.state, annotation.token, annotation.actions, contribution_matrix)
|
|
395
|
+
}.compact
|
|
396
|
+
predecessor.append_annotation_list(propagating_list)
|
|
298
397
|
end
|
|
299
398
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
nil
|
|
304
|
-
else
|
|
305
|
-
kernels.map {|kernel| [kernel, follow_kernel_items(shift, next_state, kernel) && item_lookahead_set[kernel].include?(token)] }.to_h
|
|
306
|
-
end
|
|
399
|
+
# @rbs () -> Array[Item]
|
|
400
|
+
def first_kernels
|
|
401
|
+
@first_kernels ||= kernels.select {|kernel| kernel.position == 1 }
|
|
307
402
|
end
|
|
308
403
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
404
|
+
# @rbs (Array[InadequacyAnnotation] propagating_list) -> void
|
|
405
|
+
def append_annotation_list(propagating_list)
|
|
406
|
+
annotation_list.each do |annotation|
|
|
407
|
+
merging_list = propagating_list.select {|a| a.state == annotation.state && a.token == annotation.token && a.actions == annotation.actions }
|
|
408
|
+
annotation.merge_matrix(merging_list.map(&:contribution_matrix))
|
|
409
|
+
propagating_list -= merging_list
|
|
315
410
|
end
|
|
316
|
-
|
|
411
|
+
|
|
412
|
+
@annotation_list += propagating_list
|
|
317
413
|
end
|
|
318
414
|
|
|
415
|
+
# Definition 3.31 (compute_lhs_contributions)
|
|
416
|
+
#
|
|
417
|
+
# @rbs (Grammar::Symbol sym, Grammar::Symbol token) -> (nil | Hash[Item, bool])
|
|
418
|
+
def lhs_contributions(sym, token)
|
|
419
|
+
return @lhs_contributions[sym][token] unless @lhs_contributions.dig(sym, token).nil?
|
|
420
|
+
|
|
421
|
+
transition = nterm_transitions.find {|goto| goto.next_sym == sym }
|
|
422
|
+
@lhs_contributions[sym] ||= {}
|
|
423
|
+
@lhs_contributions[sym][token] =
|
|
424
|
+
if always_follows[transition].include?(token)
|
|
425
|
+
{}
|
|
426
|
+
else
|
|
427
|
+
kernels.map {|kernel| [kernel, follow_kernel_items[transition][kernel] && item_lookahead_set[kernel].include?(token)] }.to_h
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
# Definition 3.26 (item_lookahead_sets)
|
|
432
|
+
#
|
|
433
|
+
# @rbs () -> lookahead_set
|
|
319
434
|
def item_lookahead_set
|
|
320
435
|
return @item_lookahead_set if @item_lookahead_set
|
|
321
436
|
|
|
322
|
-
kernels.map {|
|
|
437
|
+
@item_lookahead_set = kernels.map {|k| [k, []] }.to_h
|
|
438
|
+
@item_lookahead_set = kernels.map {|kernel|
|
|
323
439
|
value =
|
|
324
|
-
if
|
|
440
|
+
if kernel.lhs.accept_symbol?
|
|
325
441
|
[]
|
|
326
|
-
elsif
|
|
327
|
-
prev_items = predecessors_with_item(
|
|
442
|
+
elsif kernel.position > 1
|
|
443
|
+
prev_items = predecessors_with_item(kernel)
|
|
328
444
|
prev_items.map {|st, i| st.item_lookahead_set[i] }.reduce([]) {|acc, syms| acc |= syms }
|
|
329
|
-
elsif
|
|
330
|
-
prev_state = @predecessors.find {|p| p.
|
|
331
|
-
|
|
332
|
-
prev_state.goto_follows
|
|
445
|
+
elsif kernel.position == 1
|
|
446
|
+
prev_state = @predecessors.find {|p| p.transitions.any? {|transition| transition.next_sym == kernel.lhs } }
|
|
447
|
+
goto = prev_state.nterm_transitions.find {|goto| goto.next_sym == kernel.lhs }
|
|
448
|
+
prev_state.goto_follows[goto]
|
|
333
449
|
end
|
|
334
|
-
[
|
|
450
|
+
[kernel, value]
|
|
335
451
|
}.to_h
|
|
336
452
|
end
|
|
337
453
|
|
|
454
|
+
# @rbs (lookahead_set k) -> void
|
|
338
455
|
def item_lookahead_set=(k)
|
|
339
456
|
@item_lookahead_set = k
|
|
340
457
|
end
|
|
341
458
|
|
|
459
|
+
# @rbs (Item item) -> Array[[State, Item]]
|
|
342
460
|
def predecessors_with_item(item)
|
|
343
461
|
result = []
|
|
344
462
|
@predecessors.each do |pre|
|
|
@@ -349,69 +467,53 @@ module Lrama
|
|
|
349
467
|
result
|
|
350
468
|
end
|
|
351
469
|
|
|
470
|
+
# @rbs (State prev_state) -> void
|
|
352
471
|
def append_predecessor(prev_state)
|
|
353
472
|
@predecessors << prev_state
|
|
354
473
|
@predecessors.uniq!
|
|
355
474
|
end
|
|
356
475
|
|
|
476
|
+
# Definition 3.39 (compute_goto_follow_set)
|
|
477
|
+
#
|
|
478
|
+
# @rbs (Grammar::Symbol nterm_token) -> Array[Grammar::Symbol]
|
|
357
479
|
def goto_follow_set(nterm_token)
|
|
358
480
|
return [] if nterm_token.accept_symbol?
|
|
359
|
-
|
|
481
|
+
goto = @lalr_isocore.nterm_transitions.find {|g| g.next_sym == nterm_token }
|
|
360
482
|
|
|
361
483
|
@kernels
|
|
362
|
-
.select {|kernel| follow_kernel_items
|
|
484
|
+
.select {|kernel| @lalr_isocore.follow_kernel_items[goto][kernel] }
|
|
363
485
|
.map {|kernel| item_lookahead_set[kernel] }
|
|
364
|
-
.reduce(always_follows
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
def goto_follows(shift, next_state)
|
|
368
|
-
queue = internal_dependencies(shift, next_state) + predecessor_dependencies(shift, next_state)
|
|
369
|
-
terms = always_follows(shift, next_state)
|
|
370
|
-
until queue.empty?
|
|
371
|
-
st, sh, next_st = queue.pop
|
|
372
|
-
terms |= st.always_follows(sh, next_st)
|
|
373
|
-
st.internal_dependencies(sh, next_st).each {|v| queue << v }
|
|
374
|
-
st.predecessor_dependencies(sh, next_st).each {|v| queue << v }
|
|
375
|
-
end
|
|
376
|
-
terms
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
def always_follows(shift, next_state)
|
|
380
|
-
return @always_follows[[shift, next_state]] if @always_follows[[shift, next_state]]
|
|
381
|
-
|
|
382
|
-
queue = internal_dependencies(shift, next_state) + successor_dependencies(shift, next_state)
|
|
383
|
-
terms = []
|
|
384
|
-
until queue.empty?
|
|
385
|
-
st, sh, next_st = queue.pop
|
|
386
|
-
terms |= next_st.term_transitions.map {|sh, _| sh.next_sym }
|
|
387
|
-
st.internal_dependencies(sh, next_st).each {|v| queue << v }
|
|
388
|
-
st.successor_dependencies(sh, next_st).each {|v| queue << v }
|
|
389
|
-
end
|
|
390
|
-
@always_follows[[shift, next_state]] = terms
|
|
486
|
+
.reduce(@lalr_isocore.always_follows[goto]) {|result, terms| result |= terms }
|
|
391
487
|
end
|
|
392
488
|
|
|
393
|
-
|
|
394
|
-
|
|
489
|
+
# Definition 3.8 (Goto Follows Internal Relation)
|
|
490
|
+
#
|
|
491
|
+
# @rbs (Action::Goto goto) -> Array[Action::Goto]
|
|
492
|
+
def internal_dependencies(goto)
|
|
493
|
+
return @internal_dependencies[goto] if @internal_dependencies[goto]
|
|
395
494
|
|
|
396
495
|
syms = @items.select {|i|
|
|
397
|
-
i.next_sym ==
|
|
496
|
+
i.next_sym == goto.next_sym && i.symbols_after_transition.all?(&:nullable) && i.position == 0
|
|
398
497
|
}.map(&:lhs).uniq
|
|
399
|
-
@internal_dependencies[
|
|
498
|
+
@internal_dependencies[goto] = nterm_transitions.select {|goto2| syms.include?(goto2.next_sym) }
|
|
400
499
|
end
|
|
401
500
|
|
|
402
|
-
|
|
403
|
-
|
|
501
|
+
# Definition 3.5 (Goto Follows Successor Relation)
|
|
502
|
+
#
|
|
503
|
+
# @rbs (Action::Goto goto) -> Array[Action::Goto]
|
|
504
|
+
def successor_dependencies(goto)
|
|
505
|
+
return @successor_dependencies[goto] if @successor_dependencies[goto]
|
|
404
506
|
|
|
405
|
-
@successor_dependencies[
|
|
406
|
-
next_state.nterm_transitions
|
|
407
|
-
.select {|next_shift, _| next_shift.next_sym.nullable }
|
|
408
|
-
.map {|transition| [next_state, *transition] }
|
|
507
|
+
@successor_dependencies[goto] = goto.to_state.nterm_transitions.select {|next_goto| next_goto.next_sym.nullable }
|
|
409
508
|
end
|
|
410
509
|
|
|
411
|
-
|
|
510
|
+
# Definition 3.9 (Goto Follows Predecessor Relation)
|
|
511
|
+
#
|
|
512
|
+
# @rbs (Action::Goto goto) -> Array[Action::Goto]
|
|
513
|
+
def predecessor_dependencies(goto)
|
|
412
514
|
state_items = []
|
|
413
515
|
@kernels.select {|kernel|
|
|
414
|
-
kernel.next_sym ==
|
|
516
|
+
kernel.next_sym == goto.next_sym && kernel.symbols_after_transition.all?(&:nullable)
|
|
415
517
|
}.each do |item|
|
|
416
518
|
queue = predecessors_with_item(item)
|
|
417
519
|
until queue.empty?
|
|
@@ -425,8 +527,7 @@ module Lrama
|
|
|
425
527
|
end
|
|
426
528
|
|
|
427
529
|
state_items.map {|state, item|
|
|
428
|
-
|
|
429
|
-
[state, sh, next_st]
|
|
530
|
+
state.nterm_transitions.find {|goto2| goto2.next_sym == item.lhs }
|
|
430
531
|
}
|
|
431
532
|
end
|
|
432
533
|
end
|