parsanol 1.3.82 → 1.3.83

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c56435897ed6f65bc101a9df1cdb0c0510917824295fa003893cdf7e447a32a4
4
- data.tar.gz: 8308c7b4bc8179fbf7867ab1769c53b1f6759ce6ad8cd7ca2dc9362e8c5a3c58
3
+ metadata.gz: 3667a0a79c8a6c710e44bd1c337fe5f378751b288e549f0fd06729c8e75661c5
4
+ data.tar.gz: d8c8878b8134f21a117437d3ffbd7a021d472d2d73dadf5227884f1b5e7caee8
5
5
  SHA512:
6
- metadata.gz: 7ad6958bee6a30a11ce020e95a1b084bd26155f7293c2c127c2ff264850da1df22bbde4eb1f321f8e442448492d5612adc25fc3ccd19fe8a65b3e9ea7a2f9731
7
- data.tar.gz: 4e353b492c5113f197822c528bf37622b54bc6eae4d2a4bb73f171cbce7edadd00c96ed55928eda73a9d2746d68e14fb4fd212ec2c768bca30a733123a32c1c8
6
+ metadata.gz: c4440f0939c2a1cf950841762d423c1308650610ebcfc55c6567f49ff13fbe4e339c296b9d2969a8d6ced4b55a7ad80bfc29bc6d7028d8ca2e232571bc83c1cf
7
+ data.tar.gz: b8bdb2be3e3ccca384aac6a5d66d1a7727ead18fc83667d236aac0f870dbbc4bf6c745083e32828ef34cd06be291dab3f555c84b878759b7739e523b81b6193f
data/lib/parsanol/skip.rb CHANGED
@@ -107,12 +107,15 @@ module Parsanol
107
107
  @markers = markers
108
108
  @whitespace_kind = whitespace_kind
109
109
  @wrapper_ids = {}.compare_by_identity
110
- @memo = {}.compare_by_identity
111
- @in_progress = {}.compare_by_identity
110
+ # Results keyed per injection context: the same shared atom
111
+ # can be reached both inside and outside repetition interiors,
112
+ # and the refinement injects differently there.
113
+ @memo = { true => {}.compare_by_identity, false => {}.compare_by_identity }
114
+ @in_progress = { true => {}.compare_by_identity, false => {}.compare_by_identity }
112
115
  end
113
116
 
114
117
  def inject(atom, entry: false)
115
- injected = walk(atom)
118
+ injected = walk(atom, false)
116
119
  return injected unless entry
117
120
 
118
121
  Atoms::Sequence.new(maybe, injected, maybe)
@@ -139,55 +142,66 @@ module Parsanol
139
142
  @wrapper_ids.key?(atom)
140
143
  end
141
144
 
142
- def walk(atom)
143
- cached = @memo[atom]
145
+ # +rep_interior+: the d54a29e refinement (PARG's owner-set
146
+ # semantics, now aligned for the DSL): no injection inside
147
+ # repetition interiors except through rule references — their
148
+ # bodies are fresh injection scopes. Wrapping char-level
149
+ # terminals inside a repetition consumes trivia within the
150
+ # ENCLOSING capture's scope and mis-attaches recorded units when
151
+ # the iteration fails.
152
+ def walk(atom, rep_interior)
153
+ cached = @memo[rep_interior][atom]
144
154
  return cached if cached
145
- return atom if @in_progress.key?(atom)
155
+ return atom if @in_progress[rep_interior].key?(atom)
146
156
  return atom if atom.equal?(@skip_atom)
147
157
 
148
- @in_progress[atom] = true
158
+ @in_progress[rep_interior][atom] = true
149
159
  injected =
150
160
  case atom
151
161
  when Atoms::Sequence
152
162
  out = []
153
163
  atom.parslets.each do |child|
154
- injected = walk(child)
155
- out << maybe unless wrapper?(injected) || injected.is_a?(Atoms::Trivia)
156
- out << injected
164
+ walked = walk(child, rep_interior)
165
+ unless rep_interior || wrapper?(walked) || walked.is_a?(Atoms::Trivia)
166
+ out << maybe
167
+ end
168
+ out << walked
157
169
  end
158
170
  out.length == 1 ? out.first : Atoms::Sequence.new(*out)
159
171
  when Atoms::Alternative
160
- Atoms::Alternative.new(*atom.alternatives.map { |a| walk(a) })
172
+ Atoms::Alternative.new(*atom.alternatives.map { |a| walk(a, rep_interior) })
161
173
  when Atoms::Repetition
162
174
  if wrapper?(atom)
163
175
  atom
164
176
  else
165
- Atoms::Repetition.new(walk(atom.parslet), atom.min, atom.max,
177
+ Atoms::Repetition.new(walk(atom.parslet, true), atom.min, atom.max,
166
178
  atom.result_tag)
167
179
  end
168
180
  when Atoms::Named
169
- Atoms::Named.new(walk(atom.parslet), atom.name)
181
+ Atoms::Named.new(walk(atom.parslet, rep_interior), atom.name)
170
182
  when Atoms::Lookahead
171
- Atoms::Lookahead.new(walk(atom.bound_parslet), atom.positive)
183
+ Atoms::Lookahead.new(walk(atom.bound_parslet, rep_interior), atom.positive)
172
184
  when Atoms::Ignored
173
- Atoms::Ignored.new(walk(atom.wrapped_atom))
185
+ Atoms::Ignored.new(walk(atom.wrapped_atom, rep_interior))
174
186
  when Atoms::Entity
175
187
  # Rule bodies own their injection when the grammar declares
176
188
  # skip on every rule (PARG); in the DSL surface the root tree
177
- # is walked once, so descend through resolved bodies with the
178
- # identity visited-set guarding recursion.
189
+ # is walked once, so descend through resolved bodies with
190
+ # the in-progress set guarding recursion. A rule body is a
191
+ # fresh injection scope even inside a repetition interior —
192
+ # the d54a29e exception is for rule-reference children.
179
193
  begin
180
- walk(atom.parslet)
194
+ walk(atom.parslet, false)
181
195
  rescue StandardError
182
196
  atom
183
197
  end
184
198
  when Atoms::Str, Atoms::Re
185
- Atoms::Sequence.new(maybe, atom)
199
+ rep_interior ? atom : Atoms::Sequence.new(maybe, atom)
186
200
  else
187
201
  atom
188
202
  end
189
- @in_progress.delete(atom)
190
- @memo[atom] = injected
203
+ @in_progress[rep_interior].delete(atom)
204
+ @memo[rep_interior][atom] = injected
191
205
  injected
192
206
  end
193
207
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parsanol
4
- VERSION = "1.3.82"
4
+ VERSION = "1.3.83"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parsanol
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.82
4
+ version: 1.3.83
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.