lrama 0.6.11 → 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 +45 -0
- data/.github/workflows/test.yaml +57 -18
- data/.gitignore +1 -0
- data/.rdoc_options +2 -0
- data/Gemfile +6 -3
- data/NEWS.md +427 -32
- data/README.md +43 -95
- data/Rakefile +14 -1
- data/Steepfile +12 -4
- data/doc/Index.md +58 -0
- 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 +19 -3
- data/lib/lrama/command.rb +96 -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 +52 -1
- data/lib/lrama/erb.rb +29 -0
- data/lib/lrama/grammar/auxiliary.rb +6 -1
- data/lib/lrama/grammar/binding.rb +60 -16
- 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 +69 -1
- data/lib/lrama/grammar/rule_builder.rb +84 -81
- 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 +236 -35
- data/lib/lrama/lexer/grammar_file.rb +8 -1
- data/lib/lrama/lexer/location.rb +42 -9
- data/lib/lrama/lexer/token/base.rb +73 -0
- data/lib/lrama/lexer/token/char.rb +16 -2
- data/lib/lrama/lexer/token/empty.rb +14 -0
- data/lib/lrama/lexer/token/ident.rb +3 -2
- data/lib/lrama/lexer/token/instantiate_rule.rb +8 -3
- 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 +5 -3
- data/lib/lrama/lexer/token/token.rb +11 -0
- data/lib/lrama/lexer/token/user_code.rb +68 -38
- data/lib/lrama/lexer/token.rb +7 -45
- data/lib/lrama/lexer.rb +55 -28
- data/lib/lrama/logger.rb +16 -2
- data/lib/lrama/option_parser.rb +71 -15
- data/lib/lrama/options.rb +26 -7
- data/lib/lrama/output.rb +4 -11
- data/lib/lrama/parser.rb +858 -721
- 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 +40 -3
- 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 +416 -28
- data/lib/lrama/states.rb +483 -144
- 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/lrama.gemspec +1 -1
- data/parser.y +496 -404
- data/rbs_collection.lock.yaml +27 -3
- data/rbs_collection.yaml +2 -0
- data/sig/generated/lrama/bitmap.rbs +19 -0
- 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 +59 -0
- data/sig/generated/lrama/erb.rbs +14 -0
- data/sig/generated/lrama/grammar/auxiliary.rbs +16 -0
- data/sig/generated/lrama/grammar/binding.rbs +40 -0
- 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/grammar_file.rbs +28 -0
- data/sig/generated/lrama/lexer/location.rbs +61 -0
- data/sig/generated/lrama/lexer/token/base.rbs +53 -0
- data/sig/generated/lrama/lexer/token/char.rbs +17 -0
- data/sig/generated/lrama/lexer/token/empty.rbs +11 -0
- data/sig/generated/lrama/lexer/token/ident.rbs +10 -0
- data/sig/generated/lrama/lexer/token/instantiate_rule.rbs +22 -0
- 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 +12 -0
- data/sig/generated/lrama/lexer/token/token.rbs +10 -0
- data/sig/{lrama → generated/lrama}/lexer/token/user_code.rbs +8 -3
- data/sig/generated/lrama/lexer/token.rbs +8 -0
- data/sig/generated/lrama/lexer.rbs +54 -0
- data/sig/generated/lrama/logger.rbs +20 -0
- data/sig/generated/lrama/option_parser.rbs +52 -0
- data/sig/{lrama → generated/lrama}/options.rbs +27 -2
- 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 +142 -77
- 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 -30
- data/sig/lrama/bitmap.rbs +0 -7
- 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/digraph.rbs +0 -23
- data/sig/lrama/grammar/auxiliary.rbs +0 -10
- data/sig/lrama/grammar/binding.rbs +0 -19
- 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 -48
- 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/lexer/grammar_file.rbs +0 -17
- data/sig/lrama/lexer/location.rbs +0 -26
- data/sig/lrama/lexer/token/char.rbs +0 -8
- data/sig/lrama/lexer/token/ident.rbs +0 -8
- data/sig/lrama/lexer/token/instantiate_rule.rbs +0 -14
- data/sig/lrama/lexer/token/tag.rbs +0 -9
- data/sig/lrama/lexer/token.rbs +0 -23
- 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
|
-
|
|
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]]
|
|
14
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
|
|
@@ -23,47 +68,77 @@ module Lrama
|
|
|
23
68
|
@conflicts = []
|
|
24
69
|
@resolved_conflicts = []
|
|
25
70
|
@default_reduction_rule = nil
|
|
71
|
+
@predecessors = []
|
|
72
|
+
@lalr_isocore = self
|
|
73
|
+
@ielr_isocores = [self]
|
|
74
|
+
@internal_dependencies = {}
|
|
75
|
+
@successor_dependencies = {}
|
|
76
|
+
@annotation_list = []
|
|
77
|
+
@lookaheads_recomputed = false
|
|
78
|
+
@follow_kernel_items = {}
|
|
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
|
|
26
88
|
end
|
|
27
89
|
|
|
90
|
+
# @rbs (Array[Item] closure) -> void
|
|
28
91
|
def closure=(closure)
|
|
29
92
|
@closure = closure
|
|
30
93
|
@items = @kernels + @closure
|
|
31
94
|
end
|
|
32
95
|
|
|
96
|
+
# @rbs () -> Array[Action::Reduce]
|
|
33
97
|
def non_default_reduces
|
|
34
98
|
reduces.reject do |reduce|
|
|
35
99
|
reduce.rule == @default_reduction_rule
|
|
36
100
|
end
|
|
37
101
|
end
|
|
38
102
|
|
|
39
|
-
|
|
40
|
-
|
|
103
|
+
# @rbs () -> void
|
|
104
|
+
def compute_transitions_and_reduces
|
|
105
|
+
_transitions = {}
|
|
106
|
+
@_lane_items ||= {}
|
|
41
107
|
reduces = []
|
|
42
108
|
items.each do |item|
|
|
43
109
|
# TODO: Consider what should be pushed
|
|
44
110
|
if item.end_of_rule?
|
|
45
|
-
reduces << Reduce.new(item)
|
|
111
|
+
reduces << Action::Reduce.new(item)
|
|
46
112
|
else
|
|
47
113
|
key = item.next_sym
|
|
48
|
-
|
|
49
|
-
|
|
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]
|
|
50
119
|
end
|
|
51
120
|
end
|
|
52
121
|
|
|
53
122
|
# It seems Bison 3.8.2 iterates transitions order by symbol number
|
|
54
|
-
|
|
123
|
+
transitions = _transitions.sort_by do |next_sym, to_items|
|
|
55
124
|
next_sym.number
|
|
56
|
-
end.map do |next_sym, new_items|
|
|
57
|
-
Shift.new(next_sym, new_items.flatten)
|
|
58
125
|
end
|
|
59
|
-
|
|
126
|
+
|
|
127
|
+
self._transitions = transitions.freeze
|
|
60
128
|
self.reduces = reduces.freeze
|
|
61
129
|
end
|
|
62
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
|
|
63
137
|
def set_items_to_state(items, next_state)
|
|
64
138
|
@items_to_state[items] = next_state
|
|
65
139
|
end
|
|
66
140
|
|
|
141
|
+
# @rbs (Grammar::Rule rule, Array[Grammar::Symbol] look_ahead) -> void
|
|
67
142
|
def set_look_ahead(rule, look_ahead)
|
|
68
143
|
reduce = reduces.find do |r|
|
|
69
144
|
r.rule == rule
|
|
@@ -72,38 +147,78 @@ module Lrama
|
|
|
72
147
|
reduce.look_ahead = look_ahead
|
|
73
148
|
end
|
|
74
149
|
|
|
75
|
-
|
|
76
|
-
|
|
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) }
|
|
77
162
|
end
|
|
78
163
|
|
|
79
|
-
|
|
80
|
-
|
|
164
|
+
# @rbs () -> Array[Action::Shift]
|
|
165
|
+
def term_transitions # steep:ignore
|
|
166
|
+
@term_transitions ||= transitions.select {|transition| transition.is_a?(Action::Shift) }
|
|
81
167
|
end
|
|
82
168
|
|
|
169
|
+
# @rbs () -> Array[transition]
|
|
83
170
|
def transitions
|
|
84
|
-
@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
|
|
178
|
+
end
|
|
179
|
+
|
|
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)
|
|
183
|
+
next_state.append_predecessor(self)
|
|
184
|
+
update_transitions_caches(transition)
|
|
185
|
+
end
|
|
186
|
+
|
|
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
|
|
198
|
+
@nterm_transitions = nil
|
|
199
|
+
@term_transitions = nil
|
|
200
|
+
|
|
201
|
+
@follow_kernel_items[new_transition] = @follow_kernel_items.delete(transition)
|
|
202
|
+
@always_follows[new_transition] = @always_follows.delete(transition)
|
|
85
203
|
end
|
|
86
204
|
|
|
205
|
+
# @rbs () -> Array[Action::Shift]
|
|
87
206
|
def selected_term_transitions
|
|
88
|
-
term_transitions.reject do |shift
|
|
207
|
+
term_transitions.reject do |shift|
|
|
89
208
|
shift.not_selected
|
|
90
209
|
end
|
|
91
210
|
end
|
|
92
211
|
|
|
93
212
|
# Move to next state by sym
|
|
213
|
+
#
|
|
214
|
+
# @rbs (Grammar::Symbol sym) -> State
|
|
94
215
|
def transition(sym)
|
|
95
216
|
result = nil
|
|
96
217
|
|
|
97
218
|
if sym.term?
|
|
98
|
-
term_transitions.
|
|
99
|
-
term = shift.next_sym
|
|
100
|
-
result = next_state if term == sym
|
|
101
|
-
end
|
|
219
|
+
result = term_transitions.find {|shift| shift.next_sym == sym }.to_state
|
|
102
220
|
else
|
|
103
|
-
nterm_transitions.
|
|
104
|
-
nterm = shift.next_sym
|
|
105
|
-
result = next_state if nterm == sym
|
|
106
|
-
end
|
|
221
|
+
result = nterm_transitions.find {|goto| goto.next_sym == sym }.to_state
|
|
107
222
|
end
|
|
108
223
|
|
|
109
224
|
raise "Can not transit by #{sym} #{self}" if result.nil?
|
|
@@ -111,12 +226,14 @@ module Lrama
|
|
|
111
226
|
result
|
|
112
227
|
end
|
|
113
228
|
|
|
229
|
+
# @rbs (Item item) -> Action::Reduce
|
|
114
230
|
def find_reduce_by_item!(item)
|
|
115
231
|
reduces.find do |r|
|
|
116
232
|
r.item == item
|
|
117
233
|
end || (raise "reduce is not found. #{item}")
|
|
118
234
|
end
|
|
119
235
|
|
|
236
|
+
# @rbs (Grammar::Rule default_reduction_rule) -> void
|
|
120
237
|
def default_reduction_rule=(default_reduction_rule)
|
|
121
238
|
@default_reduction_rule = default_reduction_rule
|
|
122
239
|
|
|
@@ -127,20 +244,291 @@ module Lrama
|
|
|
127
244
|
end
|
|
128
245
|
end
|
|
129
246
|
|
|
247
|
+
# @rbs () -> bool
|
|
130
248
|
def has_conflicts?
|
|
131
249
|
!@conflicts.empty?
|
|
132
250
|
end
|
|
133
251
|
|
|
252
|
+
# @rbs () -> Array[conflict]
|
|
134
253
|
def sr_conflicts
|
|
135
254
|
@conflicts.select do |conflict|
|
|
136
255
|
conflict.type == :shift_reduce
|
|
137
256
|
end
|
|
138
257
|
end
|
|
139
258
|
|
|
259
|
+
# @rbs () -> Array[conflict]
|
|
140
260
|
def rr_conflicts
|
|
141
261
|
@conflicts.select do |conflict|
|
|
142
262
|
conflict.type == :reduce_reduce
|
|
143
263
|
end
|
|
144
264
|
end
|
|
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
|
|
290
|
+
def propagate_lookaheads(next_state)
|
|
291
|
+
next_state.kernels.map {|next_kernel|
|
|
292
|
+
lookahead_sets =
|
|
293
|
+
if next_kernel.position > 1
|
|
294
|
+
kernel = kernels.find {|k| k.predecessor_item_of?(next_kernel) }
|
|
295
|
+
item_lookahead_set[kernel]
|
|
296
|
+
else
|
|
297
|
+
goto_follow_set(next_kernel.lhs)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
[next_kernel, lookahead_sets & next_state.lookahead_set_filters[next_kernel]]
|
|
301
|
+
}.to_h
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# Definition 3.43 (is_compatible)
|
|
305
|
+
#
|
|
306
|
+
# @rbs (lookahead_set filtered_lookahead) -> bool
|
|
307
|
+
def is_compatible?(filtered_lookahead)
|
|
308
|
+
!lookaheads_recomputed ||
|
|
309
|
+
@lalr_isocore.annotation_list.all? {|annotation|
|
|
310
|
+
a = annotation.dominant_contribution(item_lookahead_set)
|
|
311
|
+
b = annotation.dominant_contribution(filtered_lookahead)
|
|
312
|
+
a.nil? || b.nil? || a == b
|
|
313
|
+
}
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Definition 3.38 (lookahead_set_filters)
|
|
317
|
+
#
|
|
318
|
+
# @rbs () -> lookahead_set
|
|
319
|
+
def lookahead_set_filters
|
|
320
|
+
@lookahead_set_filters ||= kernels.map {|kernel|
|
|
321
|
+
[kernel, @lalr_isocore.annotation_list.select {|annotation| annotation.contributed?(kernel) }.map(&:token)]
|
|
322
|
+
}.to_h
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# Definition 3.27 (inadequacy_lists)
|
|
326
|
+
#
|
|
327
|
+
# @rbs () -> Hash[Grammar::Symbol, Array[Action::Shift | Action::Reduce]]
|
|
328
|
+
def inadequacy_list
|
|
329
|
+
return @inadequacy_list if @inadequacy_list
|
|
330
|
+
|
|
331
|
+
inadequacy_list = {}
|
|
332
|
+
|
|
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 }
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# Definition 3.30 (annotate_manifestation)
|
|
350
|
+
#
|
|
351
|
+
# @rbs () -> void
|
|
352
|
+
def annotate_manifestation
|
|
353
|
+
inadequacy_list.each {|token, actions|
|
|
354
|
+
contribution_matrix = actions.map {|action|
|
|
355
|
+
if action.is_a?(Action::Shift)
|
|
356
|
+
[action, nil]
|
|
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]
|
|
359
|
+
end
|
|
360
|
+
}.to_h
|
|
361
|
+
@annotation_list << InadequacyAnnotation.new(self, token, actions, contribution_matrix)
|
|
362
|
+
}
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Definition 3.32 (annotate_predecessor)
|
|
366
|
+
#
|
|
367
|
+
# @rbs (State predecessor) -> void
|
|
368
|
+
def annotate_predecessor(predecessor)
|
|
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]
|
|
375
|
+
else
|
|
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]
|
|
382
|
+
}.to_h
|
|
383
|
+
[action, cs]
|
|
384
|
+
end
|
|
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)
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# @rbs () -> Array[Item]
|
|
400
|
+
def first_kernels
|
|
401
|
+
@first_kernels ||= kernels.select {|kernel| kernel.position == 1 }
|
|
402
|
+
end
|
|
403
|
+
|
|
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
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
@annotation_list += propagating_list
|
|
413
|
+
end
|
|
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
|
|
434
|
+
def item_lookahead_set
|
|
435
|
+
return @item_lookahead_set if @item_lookahead_set
|
|
436
|
+
|
|
437
|
+
@item_lookahead_set = kernels.map {|k| [k, []] }.to_h
|
|
438
|
+
@item_lookahead_set = kernels.map {|kernel|
|
|
439
|
+
value =
|
|
440
|
+
if kernel.lhs.accept_symbol?
|
|
441
|
+
[]
|
|
442
|
+
elsif kernel.position > 1
|
|
443
|
+
prev_items = predecessors_with_item(kernel)
|
|
444
|
+
prev_items.map {|st, i| st.item_lookahead_set[i] }.reduce([]) {|acc, syms| acc |= syms }
|
|
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]
|
|
449
|
+
end
|
|
450
|
+
[kernel, value]
|
|
451
|
+
}.to_h
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# @rbs (lookahead_set k) -> void
|
|
455
|
+
def item_lookahead_set=(k)
|
|
456
|
+
@item_lookahead_set = k
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
# @rbs (Item item) -> Array[[State, Item]]
|
|
460
|
+
def predecessors_with_item(item)
|
|
461
|
+
result = []
|
|
462
|
+
@predecessors.each do |pre|
|
|
463
|
+
pre.items.each do |i|
|
|
464
|
+
result << [pre, i] if i.predecessor_item_of?(item)
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
result
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
# @rbs (State prev_state) -> void
|
|
471
|
+
def append_predecessor(prev_state)
|
|
472
|
+
@predecessors << prev_state
|
|
473
|
+
@predecessors.uniq!
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
# Definition 3.39 (compute_goto_follow_set)
|
|
477
|
+
#
|
|
478
|
+
# @rbs (Grammar::Symbol nterm_token) -> Array[Grammar::Symbol]
|
|
479
|
+
def goto_follow_set(nterm_token)
|
|
480
|
+
return [] if nterm_token.accept_symbol?
|
|
481
|
+
goto = @lalr_isocore.nterm_transitions.find {|g| g.next_sym == nterm_token }
|
|
482
|
+
|
|
483
|
+
@kernels
|
|
484
|
+
.select {|kernel| @lalr_isocore.follow_kernel_items[goto][kernel] }
|
|
485
|
+
.map {|kernel| item_lookahead_set[kernel] }
|
|
486
|
+
.reduce(@lalr_isocore.always_follows[goto]) {|result, terms| result |= terms }
|
|
487
|
+
end
|
|
488
|
+
|
|
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]
|
|
494
|
+
|
|
495
|
+
syms = @items.select {|i|
|
|
496
|
+
i.next_sym == goto.next_sym && i.symbols_after_transition.all?(&:nullable) && i.position == 0
|
|
497
|
+
}.map(&:lhs).uniq
|
|
498
|
+
@internal_dependencies[goto] = nterm_transitions.select {|goto2| syms.include?(goto2.next_sym) }
|
|
499
|
+
end
|
|
500
|
+
|
|
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]
|
|
506
|
+
|
|
507
|
+
@successor_dependencies[goto] = goto.to_state.nterm_transitions.select {|next_goto| next_goto.next_sym.nullable }
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
# Definition 3.9 (Goto Follows Predecessor Relation)
|
|
511
|
+
#
|
|
512
|
+
# @rbs (Action::Goto goto) -> Array[Action::Goto]
|
|
513
|
+
def predecessor_dependencies(goto)
|
|
514
|
+
state_items = []
|
|
515
|
+
@kernels.select {|kernel|
|
|
516
|
+
kernel.next_sym == goto.next_sym && kernel.symbols_after_transition.all?(&:nullable)
|
|
517
|
+
}.each do |item|
|
|
518
|
+
queue = predecessors_with_item(item)
|
|
519
|
+
until queue.empty?
|
|
520
|
+
st, i = queue.pop
|
|
521
|
+
if i.position == 0
|
|
522
|
+
state_items << [st, i]
|
|
523
|
+
else
|
|
524
|
+
st.predecessors_with_item(i).each {|v| queue << v }
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
state_items.map {|state, item|
|
|
530
|
+
state.nterm_transitions.find {|goto2| goto2.next_sym == item.lhs }
|
|
531
|
+
}
|
|
532
|
+
end
|
|
145
533
|
end
|
|
146
534
|
end
|