lrama 0.6.9 → 0.6.10
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/.github/workflows/test.yaml +19 -0
- data/.gitignore +2 -0
- data/Gemfile +6 -3
- data/NEWS.md +220 -0
- data/README.md +41 -4
- data/Rakefile +2 -0
- data/Steepfile +6 -17
- data/exe/lrama +1 -0
- data/lib/lrama/bitmap.rb +2 -0
- data/lib/lrama/command.rb +8 -14
- data/lib/lrama/context.rb +8 -6
- data/lib/lrama/counterexamples/derivation.rb +2 -0
- data/lib/lrama/counterexamples/example.rb +2 -0
- data/lib/lrama/counterexamples/path.rb +2 -0
- data/lib/lrama/counterexamples/production_path.rb +2 -0
- data/lib/lrama/counterexamples/start_path.rb +2 -0
- data/lib/lrama/counterexamples/state_item.rb +2 -0
- data/lib/lrama/counterexamples/transition_path.rb +2 -0
- data/lib/lrama/counterexamples/triple.rb +2 -0
- data/lib/lrama/counterexamples.rb +17 -15
- data/lib/lrama/diagnostics.rb +36 -0
- data/lib/lrama/digraph.rb +2 -0
- data/lib/lrama/grammar/auxiliary.rb +2 -0
- data/lib/lrama/grammar/binding.rb +12 -1
- data/lib/lrama/grammar/code/destructor_code.rb +2 -0
- data/lib/lrama/grammar/code/initial_action_code.rb +2 -0
- data/lib/lrama/grammar/code/no_reference_code.rb +2 -0
- data/lib/lrama/grammar/code/printer_code.rb +2 -0
- data/lib/lrama/grammar/code/rule_action.rb +7 -3
- data/lib/lrama/grammar/code.rb +7 -5
- data/lib/lrama/grammar/counter.rb +2 -0
- data/lib/lrama/grammar/destructor.rb +2 -0
- data/lib/lrama/grammar/error_token.rb +2 -0
- data/lib/lrama/grammar/parameterizing_rule/resolver.rb +7 -1
- data/lib/lrama/grammar/parameterizing_rule/rhs.rb +5 -2
- data/lib/lrama/grammar/parameterizing_rule/rule.rb +6 -0
- data/lib/lrama/grammar/parameterizing_rule.rb +2 -0
- data/lib/lrama/grammar/percent_code.rb +2 -0
- data/lib/lrama/grammar/precedence.rb +2 -0
- data/lib/lrama/grammar/printer.rb +2 -0
- data/lib/lrama/grammar/reference.rb +2 -0
- data/lib/lrama/grammar/rule.rb +10 -3
- data/lib/lrama/grammar/rule_builder.rb +64 -65
- data/lib/lrama/grammar/symbol.rb +2 -0
- data/lib/lrama/grammar/symbols/resolver.rb +5 -1
- data/lib/lrama/grammar/symbols.rb +2 -0
- data/lib/lrama/grammar/type.rb +2 -0
- data/lib/lrama/grammar/union.rb +2 -0
- data/lib/lrama/grammar.rb +51 -30
- data/lib/lrama/grammar_validator.rb +37 -0
- data/lib/lrama/lexer/grammar_file.rb +2 -0
- data/lib/lrama/lexer/location.rb +2 -0
- data/lib/lrama/lexer/token/char.rb +2 -0
- data/lib/lrama/lexer/token/ident.rb +2 -0
- data/lib/lrama/lexer/token/instantiate_rule.rb +2 -0
- data/lib/lrama/lexer/token/tag.rb +2 -0
- data/lib/lrama/lexer/token/user_code.rb +3 -1
- data/lib/lrama/lexer/token.rb +7 -5
- data/lib/lrama/lexer.rb +11 -8
- data/lib/lrama/{warning.rb → logger.rb} +5 -13
- data/lib/lrama/option_parser.rb +58 -33
- data/lib/lrama/options.rb +5 -2
- data/lib/lrama/output.rb +38 -69
- data/lib/lrama/parser.rb +650 -779
- data/lib/lrama/report/duration.rb +2 -0
- data/lib/lrama/report/profile.rb +2 -0
- data/lib/lrama/report.rb +4 -2
- data/lib/lrama/state/reduce.rb +3 -0
- data/lib/lrama/state/reduce_reduce_conflict.rb +2 -0
- data/lib/lrama/state/resolved_conflict.rb +3 -1
- data/lib/lrama/state/shift.rb +2 -0
- data/lib/lrama/state/shift_reduce_conflict.rb +2 -0
- data/lib/lrama/state.rb +7 -5
- data/lib/lrama/states/item.rb +5 -3
- data/lib/lrama/states.rb +18 -46
- data/lib/lrama/states_reporter.rb +60 -19
- data/lib/lrama/trace_reporter.rb +30 -0
- data/lib/lrama/version.rb +3 -1
- data/lib/lrama.rb +22 -17
- data/lrama.gemspec +3 -1
- data/parser.y +110 -229
- data/sig/lrama/grammar/auxiliary.rbs +10 -0
- data/sig/lrama/grammar/binding.rbs +4 -0
- data/sig/lrama/grammar/code/destructor_code.rbs +3 -4
- data/sig/lrama/grammar/code/initial_action_code.rbs +15 -0
- data/sig/lrama/grammar/code/no_reference_code.rbs +15 -0
- data/sig/lrama/grammar/code/printer_code.rbs +3 -4
- data/sig/lrama/grammar/code/rule_action.rbs +19 -0
- data/sig/lrama/grammar/code.rbs +3 -3
- data/sig/lrama/grammar/destructor.rbs +3 -1
- data/sig/lrama/grammar/error_token.rbs +4 -2
- data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +2 -1
- data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +1 -1
- data/sig/lrama/grammar/precedence.rbs +3 -1
- data/sig/lrama/grammar/printer.rbs +3 -1
- data/sig/lrama/grammar/rule.rbs +35 -3
- data/sig/lrama/grammar/rule_builder.rbs +10 -9
- data/sig/lrama/grammar/symbol.rbs +6 -6
- data/sig/lrama/grammar/symbols/resolver.rbs +22 -3
- data/sig/lrama/grammar/type.rbs +2 -2
- data/sig/lrama/grammar/union.rbs +12 -0
- data/sig/lrama/grammar.rbs +91 -1
- data/sig/lrama/options.rbs +3 -2
- data/sig/lrama/state/reduce.rbs +20 -0
- data/sig/lrama/state/reduce_reduce_conflict.rbs +13 -0
- data/sig/lrama/state/resolved_conflict.rbs +14 -0
- data/sig/lrama/state/shift.rbs +14 -0
- data/sig/lrama/state/shift_reduce_conflict.rbs +13 -0
- data/sig/lrama/states/item.rbs +30 -0
- data/template/bison/yacc.c +24 -19
- metadata +17 -6
- data/sample/calc.output +0 -263
- data/sample/calc.y +0 -101
- data/sample/parse.y +0 -59
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lrama
|
2
4
|
class Grammar
|
3
5
|
class Binding
|
@@ -16,8 +18,17 @@ module Lrama
|
|
16
18
|
resolved_args = symbol.args.map { |arg| resolve_symbol(arg) }
|
17
19
|
Lrama::Lexer::Token::InstantiateRule.new(s_value: symbol.s_value, location: symbol.location, args: resolved_args, lhs_tag: symbol.lhs_tag)
|
18
20
|
else
|
19
|
-
|
21
|
+
parameter_to_arg(symbol) || symbol
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parameter_to_arg(symbol)
|
28
|
+
if (arg = @parameter_to_arg[symbol.s_value].dup)
|
29
|
+
arg.alias_name = symbol.alias_name
|
20
30
|
end
|
31
|
+
arg
|
21
32
|
end
|
22
33
|
end
|
23
34
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lrama
|
2
4
|
class Grammar
|
3
5
|
class Code
|
@@ -41,6 +43,7 @@ module Lrama
|
|
41
43
|
when ref.type == :dollar && ref.name == "$" # $$
|
42
44
|
tag = ref.ex_tag || lhs.tag
|
43
45
|
raise_tag_not_found_error(ref) unless tag
|
46
|
+
# @type var tag: Lexer::Token::Tag
|
44
47
|
"(yyval.#{tag.member})"
|
45
48
|
when ref.type == :at && ref.name == "$" # @$
|
46
49
|
"(yyloc)"
|
@@ -50,6 +53,7 @@ module Lrama
|
|
50
53
|
i = -position_in_rhs + ref.index
|
51
54
|
tag = ref.ex_tag || rhs[ref.index - 1].tag
|
52
55
|
raise_tag_not_found_error(ref) unless tag
|
56
|
+
# @type var tag: Lexer::Token::Tag
|
53
57
|
"(yyvsp[#{i}].#{tag.member})"
|
54
58
|
when ref.type == :at # @n
|
55
59
|
i = -position_in_rhs + ref.index
|
@@ -69,18 +73,18 @@ module Lrama
|
|
69
73
|
@rule.position_in_original_rule_rhs || @rule.rhs.count
|
70
74
|
end
|
71
75
|
|
72
|
-
# If this is midrule action, RHS is
|
76
|
+
# If this is midrule action, RHS is an RHS of the original rule.
|
73
77
|
def rhs
|
74
78
|
(@rule.original_rule || @rule).rhs
|
75
79
|
end
|
76
80
|
|
77
|
-
# Unlike `rhs`, LHS is always
|
81
|
+
# Unlike `rhs`, LHS is always an LHS of the rule.
|
78
82
|
def lhs
|
79
83
|
@rule.lhs
|
80
84
|
end
|
81
85
|
|
82
86
|
def raise_tag_not_found_error(ref)
|
83
|
-
raise "Tag is not specified for '$#{ref.value}' in '#{@rule}'"
|
87
|
+
raise "Tag is not specified for '$#{ref.value}' in '#{@rule.display_name}'"
|
84
88
|
end
|
85
89
|
end
|
86
90
|
end
|
data/lib/lrama/grammar/code.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "forwardable"
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
require_relative "code/destructor_code"
|
5
|
+
require_relative "code/initial_action_code"
|
6
|
+
require_relative "code/no_reference_code"
|
7
|
+
require_relative "code/printer_code"
|
8
|
+
require_relative "code/rule_action"
|
7
9
|
|
8
10
|
module Lrama
|
9
11
|
class Grammar
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lrama
|
2
4
|
class Grammar
|
3
5
|
class ParameterizingRule
|
@@ -18,13 +20,17 @@ module Lrama
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def find_inline(token)
|
21
|
-
@rules.
|
23
|
+
@rules.reverse.find { |rule| rule.name == token.s_value && rule.is_inline }
|
22
24
|
end
|
23
25
|
|
24
26
|
def created_lhs(lhs_s_value)
|
25
27
|
@created_lhs_list.reverse.find { |created_lhs| created_lhs.s_value == lhs_s_value }
|
26
28
|
end
|
27
29
|
|
30
|
+
def redefined_rules
|
31
|
+
@rules.select { |rule| @rules.count { |r| r.name == rule.name && r.required_parameters_count == rule.required_parameters_count } > 1 }
|
32
|
+
end
|
33
|
+
|
28
34
|
private
|
29
35
|
|
30
36
|
def select_rules(rules, token)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lrama
|
2
4
|
class Grammar
|
3
5
|
class ParameterizingRule
|
@@ -13,6 +15,7 @@ module Lrama
|
|
13
15
|
def resolve_user_code(bindings)
|
14
16
|
return unless user_code
|
15
17
|
|
18
|
+
resolved = Lexer::Token::UserCode.new(s_value: user_code.s_value, location: user_code.location)
|
16
19
|
var_to_arg = {}
|
17
20
|
symbols.each do |sym|
|
18
21
|
resolved_sym = bindings.resolve_symbol(sym)
|
@@ -22,14 +25,14 @@ module Lrama
|
|
22
25
|
end
|
23
26
|
|
24
27
|
var_to_arg.each do |var, arg|
|
25
|
-
|
28
|
+
resolved.references.each do |ref|
|
26
29
|
if ref.name == var
|
27
30
|
ref.name = arg
|
28
31
|
end
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
32
|
-
return
|
35
|
+
return resolved
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lrama
|
2
4
|
class Grammar
|
3
5
|
class ParameterizingRule
|
@@ -12,6 +14,10 @@ module Lrama
|
|
12
14
|
@is_inline = is_inline
|
13
15
|
@required_parameters_count = parameters.count
|
14
16
|
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"#{@name}(#{@parameters.map(&:s_value).join(', ')})"
|
20
|
+
end
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
data/lib/lrama/grammar/rule.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lrama
|
2
4
|
class Grammar
|
3
5
|
# _rhs holds original RHS element. Use rhs to refer to Symbol.
|
@@ -16,8 +18,7 @@ module Lrama
|
|
16
18
|
self.lineno == other.lineno
|
17
19
|
end
|
18
20
|
|
19
|
-
|
20
|
-
def to_s
|
21
|
+
def display_name
|
21
22
|
l = lhs.id.s_value
|
22
23
|
r = empty_rule? ? "ε" : rhs.map {|r| r.id.s_value }.join(" ")
|
23
24
|
|
@@ -33,7 +34,7 @@ module Lrama
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def with_actions
|
36
|
-
"#{
|
37
|
+
"#{display_name} {#{token_code&.s_value}}"
|
37
38
|
end
|
38
39
|
|
39
40
|
# opt_nl: ε <-- empty_rule
|
@@ -55,6 +56,12 @@ module Lrama
|
|
55
56
|
|
56
57
|
Code::RuleAction.new(type: :rule_action, token_code: token_code, rule: self).translated_code
|
57
58
|
end
|
59
|
+
|
60
|
+
def contains_at_reference?
|
61
|
+
return false unless token_code
|
62
|
+
|
63
|
+
token_code.references.any? {|r| r.type == :at }
|
64
|
+
end
|
58
65
|
end
|
59
66
|
end
|
60
67
|
end
|
@@ -1,12 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lrama
|
2
4
|
class Grammar
|
3
5
|
class RuleBuilder
|
4
6
|
attr_accessor :lhs, :line
|
5
7
|
attr_reader :lhs_tag, :rhs, :user_code, :precedence_sym
|
6
8
|
|
7
|
-
def initialize(rule_counter, midrule_action_counter, position_in_original_rule_rhs = nil, lhs_tag: nil, skip_preprocess_references: false)
|
9
|
+
def initialize(rule_counter, midrule_action_counter, parameterizing_rule_resolver, position_in_original_rule_rhs = nil, lhs_tag: nil, skip_preprocess_references: false)
|
8
10
|
@rule_counter = rule_counter
|
9
11
|
@midrule_action_counter = midrule_action_counter
|
12
|
+
@parameterizing_rule_resolver = parameterizing_rule_resolver
|
10
13
|
@position_in_original_rule_rhs = position_in_original_rule_rhs
|
11
14
|
@skip_preprocess_references = skip_preprocess_references
|
12
15
|
|
@@ -19,16 +22,12 @@ module Lrama
|
|
19
22
|
@rules = []
|
20
23
|
@rule_builders_for_parameterizing_rules = []
|
21
24
|
@rule_builders_for_derived_rules = []
|
22
|
-
@rule_builders_for_inline_rules = []
|
23
25
|
@parameterizing_rules = []
|
24
|
-
@inline_rules = []
|
25
26
|
@midrule_action_rules = []
|
26
27
|
end
|
27
28
|
|
28
29
|
def add_rhs(rhs)
|
29
|
-
|
30
|
-
@line = rhs.line
|
31
|
-
end
|
30
|
+
@line ||= rhs.line
|
32
31
|
|
33
32
|
flush_user_code
|
34
33
|
|
@@ -36,9 +35,7 @@ module Lrama
|
|
36
35
|
end
|
37
36
|
|
38
37
|
def user_code=(user_code)
|
39
|
-
|
40
|
-
@line = user_code&.line
|
41
|
-
end
|
38
|
+
@line ||= user_code&.line
|
42
39
|
|
43
40
|
flush_user_code
|
44
41
|
|
@@ -55,18 +52,41 @@ module Lrama
|
|
55
52
|
freeze_rhs
|
56
53
|
end
|
57
54
|
|
58
|
-
def setup_rules
|
55
|
+
def setup_rules
|
59
56
|
preprocess_references unless @skip_preprocess_references
|
60
|
-
|
61
|
-
resolve_inline(parameterizing_rule_resolver)
|
62
|
-
else
|
63
|
-
process_rhs(parameterizing_rule_resolver)
|
64
|
-
end
|
57
|
+
process_rhs
|
65
58
|
build_rules
|
66
59
|
end
|
67
60
|
|
68
61
|
def rules
|
69
|
-
@parameterizing_rules + @
|
62
|
+
@parameterizing_rules + @midrule_action_rules + @rules
|
63
|
+
end
|
64
|
+
|
65
|
+
def has_inline_rules?
|
66
|
+
rhs.any? { |token| @parameterizing_rule_resolver.find_inline(token) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def resolve_inline_rules
|
70
|
+
resolved_builders = []
|
71
|
+
rhs.each_with_index do |token, i|
|
72
|
+
if (inline_rule = @parameterizing_rule_resolver.find_inline(token))
|
73
|
+
inline_rule.rhs_list.each do |inline_rhs|
|
74
|
+
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: lhs_tag)
|
75
|
+
if token.is_a?(Lexer::Token::InstantiateRule)
|
76
|
+
resolve_inline_rhs(rule_builder, inline_rhs, i, Binding.new(inline_rule, token.args))
|
77
|
+
else
|
78
|
+
resolve_inline_rhs(rule_builder, inline_rhs, i)
|
79
|
+
end
|
80
|
+
rule_builder.lhs = lhs
|
81
|
+
rule_builder.line = line
|
82
|
+
rule_builder.precedence_sym = precedence_sym
|
83
|
+
rule_builder.user_code = replace_inline_user_code(inline_rhs, i)
|
84
|
+
resolved_builders << rule_builder
|
85
|
+
end
|
86
|
+
break
|
87
|
+
end
|
88
|
+
end
|
89
|
+
resolved_builders
|
70
90
|
end
|
71
91
|
|
72
92
|
private
|
@@ -82,31 +102,25 @@ module Lrama
|
|
82
102
|
def build_rules
|
83
103
|
tokens = @replaced_rhs
|
84
104
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
r.original_rule = rule
|
99
|
-
end
|
100
|
-
else
|
101
|
-
@inline_rules = @rule_builders_for_inline_rules.map do |rule_builder|
|
102
|
-
rule_builder.rules
|
103
|
-
end.flatten
|
105
|
+
rule = Rule.new(
|
106
|
+
id: @rule_counter.increment, _lhs: lhs, _rhs: tokens, lhs_tag: lhs_tag, token_code: user_code,
|
107
|
+
position_in_original_rule_rhs: @position_in_original_rule_rhs, precedence_sym: precedence_sym, lineno: line
|
108
|
+
)
|
109
|
+
@rules = [rule]
|
110
|
+
@parameterizing_rules = @rule_builders_for_parameterizing_rules.map do |rule_builder|
|
111
|
+
rule_builder.rules
|
112
|
+
end.flatten
|
113
|
+
@midrule_action_rules = @rule_builders_for_derived_rules.map do |rule_builder|
|
114
|
+
rule_builder.rules
|
115
|
+
end.flatten
|
116
|
+
@midrule_action_rules.each do |r|
|
117
|
+
r.original_rule = rule
|
104
118
|
end
|
105
119
|
end
|
106
120
|
|
107
121
|
# rhs is a mixture of variety type of tokens like `Ident`, `InstantiateRule`, `UserCode` and so on.
|
108
122
|
# `#process_rhs` replaces some kind of tokens to `Ident` so that all `@replaced_rhs` are `Ident` or `Char`.
|
109
|
-
def process_rhs
|
123
|
+
def process_rhs
|
110
124
|
return if @replaced_rhs
|
111
125
|
|
112
126
|
@replaced_rhs = []
|
@@ -118,26 +132,26 @@ module Lrama
|
|
118
132
|
when Lrama::Lexer::Token::Ident
|
119
133
|
@replaced_rhs << token
|
120
134
|
when Lrama::Lexer::Token::InstantiateRule
|
121
|
-
parameterizing_rule = parameterizing_rule_resolver.find_rule(token)
|
135
|
+
parameterizing_rule = @parameterizing_rule_resolver.find_rule(token)
|
122
136
|
raise "Unexpected token. #{token}" unless parameterizing_rule
|
123
137
|
|
124
138
|
bindings = Binding.new(parameterizing_rule, token.args)
|
125
139
|
lhs_s_value = lhs_s_value(token, bindings)
|
126
|
-
if (created_lhs = parameterizing_rule_resolver.created_lhs(lhs_s_value))
|
140
|
+
if (created_lhs = @parameterizing_rule_resolver.created_lhs(lhs_s_value))
|
127
141
|
@replaced_rhs << created_lhs
|
128
142
|
else
|
129
143
|
lhs_token = Lrama::Lexer::Token::Ident.new(s_value: lhs_s_value, location: token.location)
|
130
144
|
@replaced_rhs << lhs_token
|
131
|
-
parameterizing_rule_resolver.created_lhs_list << lhs_token
|
145
|
+
@parameterizing_rule_resolver.created_lhs_list << lhs_token
|
132
146
|
parameterizing_rule.rhs_list.each do |r|
|
133
|
-
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: token.lhs_tag || parameterizing_rule.tag)
|
147
|
+
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: token.lhs_tag || parameterizing_rule.tag)
|
134
148
|
rule_builder.lhs = lhs_token
|
135
149
|
r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) }
|
136
150
|
rule_builder.line = line
|
137
151
|
rule_builder.precedence_sym = r.precedence_sym
|
138
152
|
rule_builder.user_code = r.resolve_user_code(bindings)
|
139
153
|
rule_builder.complete_input
|
140
|
-
rule_builder.setup_rules
|
154
|
+
rule_builder.setup_rules
|
141
155
|
@rule_builders_for_parameterizing_rules << rule_builder
|
142
156
|
end
|
143
157
|
end
|
@@ -147,11 +161,11 @@ module Lrama
|
|
147
161
|
new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + @midrule_action_counter.increment.to_s)
|
148
162
|
@replaced_rhs << new_token
|
149
163
|
|
150
|
-
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, i, lhs_tag: tag, skip_preprocess_references: true)
|
164
|
+
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, i, lhs_tag: tag, skip_preprocess_references: true)
|
151
165
|
rule_builder.lhs = new_token
|
152
166
|
rule_builder.user_code = token
|
153
167
|
rule_builder.complete_input
|
154
|
-
rule_builder.setup_rules
|
168
|
+
rule_builder.setup_rules
|
155
169
|
|
156
170
|
@rule_builders_for_derived_rules << rule_builder
|
157
171
|
else
|
@@ -172,27 +186,10 @@ module Lrama
|
|
172
186
|
"#{token.rule_name}_#{s_values.join('_')}"
|
173
187
|
end
|
174
188
|
|
175
|
-
def
|
176
|
-
rhs.each_with_index do |token, i|
|
177
|
-
if inline_rule = parameterizing_rule_resolver.find_inline(token)
|
178
|
-
inline_rule.rhs_list.each_with_index do |inline_rhs|
|
179
|
-
rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: lhs_tag, skip_preprocess_references: true)
|
180
|
-
resolve_inline_rhs(rule_builder, inline_rhs, i)
|
181
|
-
rule_builder.lhs = lhs
|
182
|
-
rule_builder.line = line
|
183
|
-
rule_builder.user_code = replace_inline_user_code(inline_rhs, i)
|
184
|
-
rule_builder.complete_input
|
185
|
-
rule_builder.setup_rules(parameterizing_rule_resolver)
|
186
|
-
@rule_builders_for_inline_rules << rule_builder
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
def resolve_inline_rhs(rule_builder, inline_rhs, index)
|
189
|
+
def resolve_inline_rhs(rule_builder, inline_rhs, index, bindings = nil)
|
193
190
|
rhs.each_with_index do |token, i|
|
194
191
|
if index == i
|
195
|
-
inline_rhs.symbols.each { |sym| rule_builder.add_rhs(sym) }
|
192
|
+
inline_rhs.symbols.each { |sym| rule_builder.add_rhs(bindings.nil? ? sym : bindings.resolve_symbol(sym)) }
|
196
193
|
else
|
197
194
|
rule_builder.add_rhs(token)
|
198
195
|
end
|
@@ -204,6 +201,11 @@ module Lrama
|
|
204
201
|
return user_code if user_code.nil?
|
205
202
|
|
206
203
|
code = user_code.s_value.gsub(/\$#{index + 1}/, inline_rhs.user_code.s_value)
|
204
|
+
user_code.references.each do |ref|
|
205
|
+
next if ref.index.nil? || ref.index <= index # nil is a case for `$$`
|
206
|
+
code = code.gsub(/\$#{ref.index}/, "$#{ref.index + (inline_rhs.symbols.count-1)}")
|
207
|
+
code = code.gsub(/@#{ref.index}/, "@#{ref.index + (inline_rhs.symbols.count-1)}")
|
208
|
+
end
|
207
209
|
Lrama::Lexer::Token::UserCode.new(s_value: code, location: user_code.location)
|
208
210
|
end
|
209
211
|
|
@@ -238,9 +240,6 @@ module Lrama
|
|
238
240
|
end
|
239
241
|
|
240
242
|
if ref.number
|
241
|
-
# TODO: When Inlining is implemented, for example, if `$1` is expanded to multiple RHS tokens,
|
242
|
-
# `$2` needs to access `$2 + n` to actually access it. So, after the Inlining implementation,
|
243
|
-
# it needs resolves from number to index.
|
244
243
|
ref.index = ref.number
|
245
244
|
end
|
246
245
|
|
data/lib/lrama/grammar/symbol.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lrama
|
2
4
|
class Grammar
|
3
5
|
class Symbols
|
@@ -42,7 +44,9 @@ module Lrama
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def add_nterm(id:, alias_name: nil, tag: nil)
|
45
|
-
|
47
|
+
if (sym = find_symbol_by_id(id))
|
48
|
+
return sym
|
49
|
+
end
|
46
50
|
|
47
51
|
@symbols = nil
|
48
52
|
nterm = Symbol.new(
|
data/lib/lrama/grammar/type.rb
CHANGED