Skip to content

Commit d194ed5

Browse files
committed
Capture transfer uses from array
1 parent 1b26a32 commit d194ed5

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

spec/recursion-spec.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ describe('recursion', () => {
168168
captureTransfers: new Map([[1, [2]]]),
169169
})).toEqual({
170170
pattern: '(a)(?:(a)(?:)?(b))?(b)',
171-
captureTransfers: new Map([[1, [4]]]),
171+
captureTransfers: new Map([[1, [3, 4]]]),
172172
hiddenCaptures: [2, 3],
173173
});
174174
});
@@ -179,15 +179,15 @@ describe('recursion', () => {
179179
hiddenCaptures: [4],
180180
})).toEqual({
181181
pattern: '()(()(a)()(?:()(a)()(?:)?b)?b)',
182-
captureTransfers: new Map([[1, [7]]]),
182+
captureTransfers: new Map([[1, [4, 7]]]),
183183
hiddenCaptures: [4, 6, 7, 8],
184184
});
185185
expect(recursion(r`()(a\g<2&R=2>?()(b)())`, {
186186
captureTransfers: new Map([[1, [4]]]),
187187
hiddenCaptures: [4],
188188
})).toEqual({
189189
pattern: '()(a(?:a(?:)?()(b)())?()(b)())',
190-
captureTransfers: new Map([[1, [7]]]),
190+
captureTransfers: new Map([[1, [4, 7]]]),
191191
hiddenCaptures: [7, 3, 4, 5], // unsorted
192192
});
193193
});
@@ -197,7 +197,7 @@ describe('recursion', () => {
197197
captureTransfers: new Map([[1, [3]]]),
198198
})).toEqual({
199199
pattern: '((a)(?:(a)(?:)?(b))?(b))',
200-
captureTransfers: new Map([[1, [5]]]),
200+
captureTransfers: new Map([[1, [4, 5]]]),
201201
hiddenCaptures: [3, 4],
202202
});
203203
});
@@ -208,23 +208,23 @@ describe('recursion', () => {
208208
captureTransfers: new Map([[1, [3]], [2, [4]]]),
209209
})).toEqual({
210210
pattern: '(?<r>(a)(?:(a)(?:)?b)?b) ((a)(?:(a)(?:)?b)?b)',
211-
captureTransfers: new Map([[1, [4]], [2, [6]]]),
211+
captureTransfers: new Map([[1, [4]], [2, [5, 6]]]),
212212
hiddenCaptures: [3, 6],
213213
});
214214
// Capture in right contents of recursions
215215
expect(recursion(r`(?<r>a\g<r&R=2>?(b)) (a\g<3&R=2>?(b))`, {
216216
captureTransfers: new Map([[1, [3]], [2, [4]]]),
217217
})).toEqual({
218218
pattern: '(?<r>a(?:a(?:)?(b))?(b)) (a(?:a(?:)?(b))?(b))',
219-
captureTransfers: new Map([[1, [4]], [3, [6]]]),
219+
captureTransfers: new Map([[1, [4]], [3, [5, 6]]]),
220220
hiddenCaptures: [2, 5],
221221
});
222222
// Capture in left and right contents of recursions
223223
expect(recursion(r`(?<r>(a)\g<r&R=2>?(b)) ((a)\g<4&R=2>?(b))`, {
224224
captureTransfers: new Map([[1, [4]], [2, [5]], [3, [6]]]),
225225
})).toEqual({
226226
pattern: '(?<r>(a)(?:(a)(?:)?(b))?(b)) ((a)(?:(a)(?:)?(b))?(b))',
227-
captureTransfers: new Map([[1, [6]], [2, [8]], [5, [10]]]),
227+
captureTransfers: new Map([[1, [6]], [2, [7, 8]], [5, [9, 10]]]),
228228
hiddenCaptures: [3, 4, 8, 9],
229229
});
230230
// Triple recursion with capture transfer to middle (Oniguruma: `\g<a> (?<a>a\g<b>?b) (?<b>c\g<a>?d)`)
@@ -233,7 +233,7 @@ describe('recursion', () => {
233233
hiddenCaptures: [1, 2, 4, 6],
234234
})).toEqual({
235235
pattern: '(a(c(?:a(c(?:)?d)?b)?d)?b) (?<a>a(c(?:a(c(?:)?d)?b)?d)?b) (?<b>c(a(?:c(a(?:)?b)?d)?b)?d)',
236-
captureTransfers: new Map([[4, [9]]]),
236+
captureTransfers: new Map([[4, [8, 9]]]),
237237
hiddenCaptures: [1, 2, 5, 8, 3, 6, 9], // unsorted
238238
});
239239
// Same as above but with depth 3
@@ -242,7 +242,7 @@ describe('recursion', () => {
242242
hiddenCaptures: [1, 2, 4, 6],
243243
})).toEqual({
244244
pattern: '(a(c(?:a(c(?:a(c(?:)?d)?b)?d)?b)?d)?b) (?<a>a(c(?:a(c(?:a(c(?:)?d)?b)?d)?b)?d)?b) (?<b>c(a(?:c(a(?:c(a(?:)?b)?d)?b)?d)?b)?d)',
245-
captureTransfers: new Map([[5, [12]]]),
245+
captureTransfers: new Map([[5, [10, 11, 12]]]),
246246
hiddenCaptures: [1, 2, 6, 10, 3, 4, 7, 8, 11, 12], // unsorted
247247
});
248248
});

src/index.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -326,25 +326,36 @@ function mapCaptureTransfers(captureTransfers, numCapturesPassed, left, reps, nu
326326
if (captureTransfers.size && numCapturesAddedInExpansion) {
327327
let numCapturesInLeft = 0;
328328
forEachUnescaped(left, captureDelim, () => numCapturesInLeft++, Context.DEFAULT);
329-
// 0 for global recursion
329+
// Is 0 for global recursion
330330
const recursionDelimCaptureNum = numCapturesPassed - numCapturesInLeft + numAddedHiddenCapturesPreExpansion;
331331
const newCaptureTransfers = new Map();
332332
captureTransfers.forEach((from, to) => {
333-
if (to > (numCapturesPassed + numAddedHiddenCapturesPreExpansion)) {
334-
to += numCapturesAddedInExpansion;
335-
}
336-
from = from.map(f => {
337-
if (f > recursionDelimCaptureNum) {
338-
f += (
339-
// if the capture is on the left side of the expanded subpattern
340-
f <= (recursionDelimCaptureNum + numCapturesInLeft) ?
341-
numCapturesInLeft * reps :
342-
numCapturesAddedInExpansion
343-
);
333+
const newTo = to > (numCapturesPassed + numAddedHiddenCapturesPreExpansion) ?
334+
to + numCapturesAddedInExpansion :
335+
to;
336+
const newFrom = [];
337+
for (const f of from) {
338+
// Before the recursed subpattern
339+
if (f <= recursionDelimCaptureNum) {
340+
newFrom.push(f);
341+
// After the recursed subpattern
342+
} else if (f > (recursionDelimCaptureNum + numCapturesAddedInExpansion)) {
343+
newFrom.push(f + numCapturesAddedInExpansion);
344+
// Within the recursed subpattern, on the left of the recursion token
345+
} else if (f <= (recursionDelimCaptureNum + numCapturesInLeft)) {
346+
for (let i = 0; i <= reps; i++) {
347+
newFrom.push(f + (numCapturesInLeft * i));
348+
}
349+
// Within the recursed subpattern, on the right of the recursion token
350+
} else {
351+
const numCapturesInRight = (numCapturesAddedInExpansion - (numCapturesInLeft * reps)) / reps;
352+
const numCapturesAddedInLeft = numCapturesInLeft * reps;
353+
for (let i = 0; i <= reps; i++) {
354+
newFrom.push(f + numCapturesAddedInLeft + (numCapturesInRight * i));
355+
}
344356
}
345-
return f;
346-
});
347-
newCaptureTransfers.set(to, from);
357+
}
358+
newCaptureTransfers.set(newTo, newFrom);
348359
});
349360
return newCaptureTransfers;
350361
}

0 commit comments

Comments
 (0)