re2js 2.8.4 → 2.8.6
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.
- package/README.md +31 -0
- package/build/index.cjs +127 -178
- package/build/index.d.cts +16 -13
- package/build/index.d.ts +16 -13
- package/build/index.js +127 -178
- package/build/index.umd.js +127 -178
- package/package.json +3 -3
package/build/index.d.ts
CHANGED
|
@@ -221,10 +221,10 @@ export class Matcher {
|
|
|
221
221
|
anchorFlag: number;
|
|
222
222
|
/**
|
|
223
223
|
* Resets the {@code Matcher} and changes the input.
|
|
224
|
-
* @param {MatcherInputBase} input
|
|
224
|
+
* @param {string|number[]|Uint8Array|MatcherInputBase} input
|
|
225
225
|
* @returns {Matcher} the {@code Matcher} itself, for chained method calls
|
|
226
226
|
*/
|
|
227
|
-
resetMatcherInput(input: MatcherInputBase): Matcher;
|
|
227
|
+
resetMatcherInput(input: string | number[] | Uint8Array | MatcherInputBase): Matcher;
|
|
228
228
|
matcherInput: MatcherInputBase;
|
|
229
229
|
/**
|
|
230
230
|
* Returns the start of the named group of the most recent match, or -1 if the group was not
|
|
@@ -503,7 +503,7 @@ declare class RE2 {
|
|
|
503
503
|
prefixUTF8: any;
|
|
504
504
|
prefixComplete: boolean;
|
|
505
505
|
prefixRune: number;
|
|
506
|
-
|
|
506
|
+
machinePool: any[];
|
|
507
507
|
dfa: DFA;
|
|
508
508
|
onepass: {
|
|
509
509
|
start: any;
|
|
@@ -523,7 +523,7 @@ declare class RE2 {
|
|
|
523
523
|
numberOfInstructions(): any;
|
|
524
524
|
get(): any;
|
|
525
525
|
reset(): void;
|
|
526
|
-
put(m: any
|
|
526
|
+
put(m: any): void;
|
|
527
527
|
toString(): any;
|
|
528
528
|
doExecuteNFA(input: any, pos: any, anchor: any, ncap: any): any;
|
|
529
529
|
match(s: any): boolean;
|
|
@@ -699,13 +699,6 @@ declare class RE2 {
|
|
|
699
699
|
*/
|
|
700
700
|
findAllSubmatchIndex(s: any, n: any): any[];
|
|
701
701
|
}
|
|
702
|
-
declare class AtomicReference {
|
|
703
|
-
constructor(initialValue: any);
|
|
704
|
-
value: any;
|
|
705
|
-
get(): any;
|
|
706
|
-
set(newValue: any): void;
|
|
707
|
-
compareAndSet(expect: any, update: any): boolean;
|
|
708
|
-
}
|
|
709
702
|
/**
|
|
710
703
|
* Creates an RE2JS regex directly from a template literal.
|
|
711
704
|
* @overload
|
|
@@ -873,6 +866,16 @@ export class RE2JS {
|
|
|
873
866
|
* @returns {boolean} `true` if the exact input string fully matches the pattern, `false` otherwise.
|
|
874
867
|
*/
|
|
875
868
|
testExact(input: string | number[] | Uint8Array): boolean;
|
|
869
|
+
/**
|
|
870
|
+
* Executes a search for a match in a specified string.
|
|
871
|
+
* Returns a result array, or null if no match is found.
|
|
872
|
+
* The returned array perfectly mirrors standard JavaScript `RegExpExecArray`,
|
|
873
|
+
* including `.index`, `.input`, and `.groups` properties.
|
|
874
|
+
*
|
|
875
|
+
* @param {string|number[]|Uint8Array} input the input string or byte array
|
|
876
|
+
* @returns {Array|null} the match array with index, input, and groups properties, or null
|
|
877
|
+
*/
|
|
878
|
+
exec(input: string | number[] | Uint8Array): any[] | null;
|
|
876
879
|
/**
|
|
877
880
|
* Splits input around instances of the regular expression. It returns an array giving the strings
|
|
878
881
|
* that occur before, between, and after instances of the regular expression.
|
|
@@ -892,9 +895,9 @@ export class RE2JS {
|
|
|
892
895
|
* including capturing groups.
|
|
893
896
|
*
|
|
894
897
|
* @param {string|number[]|Uint8Array} input the input string or byte array
|
|
895
|
-
* @returns {IterableIterator<
|
|
898
|
+
* @returns {IterableIterator<RegExpMatchArray>}
|
|
896
899
|
*/
|
|
897
|
-
matchAll(input: string | number[] | Uint8Array): IterableIterator<
|
|
900
|
+
matchAll(input: string | number[] | Uint8Array): IterableIterator<RegExpMatchArray>;
|
|
898
901
|
/**
|
|
899
902
|
*
|
|
900
903
|
* @returns {string}
|
package/build/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* re2js
|
|
3
3
|
* RE2JS is the JavaScript port of RE2, a regular expression engine that provides linear time matching
|
|
4
4
|
*
|
|
5
|
-
* @version v2.8.
|
|
5
|
+
* @version v2.8.6
|
|
6
6
|
* @author Oleksii Vasyliev
|
|
7
7
|
* @homepage https://github.com/le0pard/re2js#readme
|
|
8
8
|
* @repository github:le0pard/re2js
|
|
@@ -707,7 +707,7 @@ var Utils = class Utils {
|
|
|
707
707
|
static stringToUtf8ByteArray(str) {
|
|
708
708
|
if (globalThis.TextEncoder) {
|
|
709
709
|
if (!cachedNativeEncoder) cachedNativeEncoder = new TextEncoder();
|
|
710
|
-
return
|
|
710
|
+
return cachedNativeEncoder.encode(str);
|
|
711
711
|
} else {
|
|
712
712
|
let out = [], p = 0;
|
|
713
713
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -1245,7 +1245,7 @@ var Matcher = class Matcher {
|
|
|
1245
1245
|
}
|
|
1246
1246
|
/**
|
|
1247
1247
|
* Resets the {@code Matcher} and changes the input.
|
|
1248
|
-
* @param {MatcherInputBase} input
|
|
1248
|
+
* @param {string|number[]|Uint8Array|MatcherInputBase} input
|
|
1249
1249
|
* @returns {Matcher} the {@code Matcher} itself, for chained method calls
|
|
1250
1250
|
*/
|
|
1251
1251
|
resetMatcherInput(input) {
|
|
@@ -1401,7 +1401,10 @@ var Matcher = class Matcher {
|
|
|
1401
1401
|
*/
|
|
1402
1402
|
genMatch(startByte, anchor) {
|
|
1403
1403
|
const res = this.patternInput.re2().matchMachineInput(this.matcherInput, startByte, this.matcherInputLength, anchor, 1);
|
|
1404
|
-
if (!res[0])
|
|
1404
|
+
if (!res[0]) {
|
|
1405
|
+
this.hasMatch = false;
|
|
1406
|
+
return false;
|
|
1407
|
+
}
|
|
1405
1408
|
this.groups = res[1];
|
|
1406
1409
|
this.hasMatch = true;
|
|
1407
1410
|
this.hasGroups = this.patternGroupCount === 0;
|
|
@@ -1464,43 +1467,47 @@ var Matcher = class Matcher {
|
|
|
1464
1467
|
let res = "";
|
|
1465
1468
|
let last = 0;
|
|
1466
1469
|
const m = replacement.length;
|
|
1467
|
-
|
|
1468
|
-
|
|
1470
|
+
let i = 0;
|
|
1471
|
+
while (i < m) {
|
|
1472
|
+
const cCode = replacement.codePointAt(i);
|
|
1473
|
+
if (cCode === Codepoint.CODES.get("\\")) {
|
|
1469
1474
|
if (last < i) res += replacement.substring(last, i);
|
|
1470
1475
|
i++;
|
|
1476
|
+
if (i >= m) throw new RE2JSGroupException("character to be escaped is missing");
|
|
1471
1477
|
last = i;
|
|
1478
|
+
i++;
|
|
1472
1479
|
continue;
|
|
1473
1480
|
}
|
|
1474
|
-
if (
|
|
1475
|
-
|
|
1476
|
-
if (
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1481
|
+
if (cCode === Codepoint.CODES.get("$")) {
|
|
1482
|
+
if (last < i) res += replacement.substring(last, i);
|
|
1483
|
+
if (i + 1 >= m) throw new RE2JSGroupException("Illegal group reference: group index is missing");
|
|
1484
|
+
const nextCode = replacement.codePointAt(i + 1);
|
|
1485
|
+
if (Codepoint.CODES.get("0") <= nextCode && nextCode <= Codepoint.CODES.get("9")) {
|
|
1486
|
+
let n = nextCode - Codepoint.CODES.get("0");
|
|
1487
|
+
let j = i + 2;
|
|
1488
|
+
for (; j < m; j++) {
|
|
1489
|
+
const digit = replacement.codePointAt(j);
|
|
1490
|
+
if (digit < Codepoint.CODES.get("0") || digit > Codepoint.CODES.get("9") || n * 10 + digit - Codepoint.CODES.get("0") > this.patternGroupCount) break;
|
|
1491
|
+
n = n * 10 + digit - Codepoint.CODES.get("0");
|
|
1483
1492
|
}
|
|
1484
1493
|
if (n > this.patternGroupCount) throw new RE2JSGroupException(`n > number of groups: ${n}`);
|
|
1485
1494
|
const group = this.group(n);
|
|
1486
1495
|
if (group !== null) res += group;
|
|
1496
|
+
i = j;
|
|
1487
1497
|
last = i;
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
if (
|
|
1492
|
-
i
|
|
1493
|
-
let j = i + 1;
|
|
1494
|
-
while (j < replacement.length && replacement.codePointAt(j) !== Codepoint.CODES.get("}") && replacement.codePointAt(j) !== Codepoint.CODES.get(" ")) j++;
|
|
1495
|
-
if (j === replacement.length || replacement.codePointAt(j) !== Codepoint.CODES.get("}")) throw new RE2JSGroupException("named capture group is missing trailing '}'");
|
|
1496
|
-
const groupName = replacement.substring(i + 1, j);
|
|
1498
|
+
} else if (nextCode === Codepoint.CODES.get("{")) {
|
|
1499
|
+
let j = i + 2;
|
|
1500
|
+
while (j < m && replacement.codePointAt(j) !== Codepoint.CODES.get("}")) j++;
|
|
1501
|
+
if (j >= m) throw new RE2JSGroupException("named capture group is missing trailing '}'");
|
|
1502
|
+
const groupName = replacement.substring(i + 2, j);
|
|
1497
1503
|
const groupVal = this.group(groupName);
|
|
1498
1504
|
if (groupVal !== null) res += groupVal;
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1505
|
+
i = j + 1;
|
|
1506
|
+
last = i;
|
|
1507
|
+
} else throw new RE2JSGroupException("Illegal group reference");
|
|
1508
|
+
continue;
|
|
1503
1509
|
}
|
|
1510
|
+
i++;
|
|
1504
1511
|
}
|
|
1505
1512
|
if (last < m) res += replacement.substring(last, m);
|
|
1506
1513
|
return res;
|
|
@@ -1811,18 +1818,18 @@ var Inst = class Inst {
|
|
|
1811
1818
|
};
|
|
1812
1819
|
//#endregion
|
|
1813
1820
|
//#region src/Machine.js
|
|
1814
|
-
var Thread = class {
|
|
1815
|
-
constructor() {
|
|
1816
|
-
this.inst = null;
|
|
1817
|
-
this.cap = null;
|
|
1818
|
-
}
|
|
1819
|
-
};
|
|
1820
1821
|
var Queue = class {
|
|
1821
1822
|
constructor(numInst) {
|
|
1822
1823
|
this.sparse = new Int32Array(numInst);
|
|
1823
1824
|
this.densePcs = new Int32Array(numInst);
|
|
1824
|
-
this.
|
|
1825
|
+
this.denseCaps = null;
|
|
1825
1826
|
this.size = 0;
|
|
1827
|
+
this.ncap = 0;
|
|
1828
|
+
}
|
|
1829
|
+
init(ncap) {
|
|
1830
|
+
this.ncap = ncap;
|
|
1831
|
+
const needed = this.densePcs.length * ncap;
|
|
1832
|
+
if (!this.denseCaps || this.denseCaps.length < needed) this.denseCaps = new Int32Array(needed);
|
|
1826
1833
|
}
|
|
1827
1834
|
contains(pc) {
|
|
1828
1835
|
const j = this.sparse[pc];
|
|
@@ -1834,12 +1841,10 @@ var Queue = class {
|
|
|
1834
1841
|
add(pc) {
|
|
1835
1842
|
const j = this.size++;
|
|
1836
1843
|
this.sparse[pc] = j;
|
|
1837
|
-
this.denseThreads[j] = null;
|
|
1838
1844
|
this.densePcs[j] = pc;
|
|
1839
1845
|
return j;
|
|
1840
1846
|
}
|
|
1841
1847
|
clear() {
|
|
1842
|
-
for (let i = 0; i < this.size; i++) this.denseThreads[i] = null;
|
|
1843
1848
|
this.size = 0;
|
|
1844
1849
|
}
|
|
1845
1850
|
toString() {
|
|
@@ -1853,15 +1858,12 @@ var Queue = class {
|
|
|
1853
1858
|
}
|
|
1854
1859
|
};
|
|
1855
1860
|
var Machine = class Machine {
|
|
1856
|
-
static THREADS_CHUNK_SIZE = 128;
|
|
1857
1861
|
static fromRE2(re2) {
|
|
1858
1862
|
const m = new Machine();
|
|
1859
1863
|
m.prog = re2.prog;
|
|
1860
1864
|
m.re2 = re2;
|
|
1861
1865
|
m.q0 = new Queue(m.prog.numInst());
|
|
1862
1866
|
m.q1 = new Queue(m.prog.numInst());
|
|
1863
|
-
m.pool = [];
|
|
1864
|
-
m.poolSize = 0;
|
|
1865
1867
|
m.matched = false;
|
|
1866
1868
|
m.matchcap = new Int32Array(m.prog.numCap < 2 ? 2 : m.prog.numCap);
|
|
1867
1869
|
m.ncap = 0;
|
|
@@ -1875,8 +1877,6 @@ var Machine = class Machine {
|
|
|
1875
1877
|
this.re2 = null;
|
|
1876
1878
|
this.q0 = null;
|
|
1877
1879
|
this.q1 = null;
|
|
1878
|
-
this.pool = [];
|
|
1879
|
-
this.poolSize = 0;
|
|
1880
1880
|
this.matched = false;
|
|
1881
1881
|
this.matchcap = null;
|
|
1882
1882
|
this.ncap = 0;
|
|
@@ -1884,51 +1884,19 @@ var Machine = class Machine {
|
|
|
1884
1884
|
}
|
|
1885
1885
|
init(ncap) {
|
|
1886
1886
|
this.ncap = ncap;
|
|
1887
|
-
if (ncap > this.matchcap.length) this.
|
|
1888
|
-
else this.
|
|
1887
|
+
if (ncap > this.matchcap.length) this.matchcap = new Int32Array(ncap).fill(-1);
|
|
1888
|
+
else this.matchcap.fill(-1);
|
|
1889
|
+
this.q0.init(ncap);
|
|
1890
|
+
this.q1.init(ncap);
|
|
1889
1891
|
if (this.prog.numLb > 0) {
|
|
1890
1892
|
if (!this.lbTable || this.lbTable.length < this.prog.numLb + 1) this.lbTable = new Int32Array(this.prog.numLb + 1);
|
|
1891
1893
|
this.lbTable.fill(-1);
|
|
1892
1894
|
}
|
|
1893
1895
|
}
|
|
1894
|
-
resetCap() {
|
|
1895
|
-
for (let i = 0; i < this.poolSize; i++) this.pool[i].cap.fill(-1);
|
|
1896
|
-
}
|
|
1897
|
-
initNewCap(ncap) {
|
|
1898
|
-
for (let i = 0; i < this.poolSize; i++) {
|
|
1899
|
-
const t = this.pool[i];
|
|
1900
|
-
t.cap = new Int32Array(ncap).fill(-1);
|
|
1901
|
-
}
|
|
1902
|
-
this.matchcap = new Int32Array(ncap).fill(-1);
|
|
1903
|
-
}
|
|
1904
1896
|
submatches() {
|
|
1905
1897
|
if (this.ncap === 0) return Utils.emptyInts();
|
|
1906
1898
|
return Utils.toArray(this.matchcap.subarray(0, this.ncap));
|
|
1907
1899
|
}
|
|
1908
|
-
alloc(inst) {
|
|
1909
|
-
if (this.poolSize === 0) {
|
|
1910
|
-
const capLen = this.matchcap.length;
|
|
1911
|
-
for (let i = 0; i < Machine.THREADS_CHUNK_SIZE; i++) {
|
|
1912
|
-
const t = new Thread();
|
|
1913
|
-
t.cap = new Int32Array(capLen);
|
|
1914
|
-
this.pool[this.poolSize++] = t;
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
this.poolSize--;
|
|
1918
|
-
const t = this.pool[this.poolSize];
|
|
1919
|
-
t.inst = inst;
|
|
1920
|
-
return t;
|
|
1921
|
-
}
|
|
1922
|
-
freeQueue(queue, from = 0) {
|
|
1923
|
-
for (let i = from; i < queue.size; i++) {
|
|
1924
|
-
const t = queue.denseThreads[i];
|
|
1925
|
-
if (t !== null) this.pool[this.poolSize++] = t;
|
|
1926
|
-
}
|
|
1927
|
-
queue.clear();
|
|
1928
|
-
}
|
|
1929
|
-
freeThread(t) {
|
|
1930
|
-
this.pool[this.poolSize++] = t;
|
|
1931
|
-
}
|
|
1932
1900
|
match(input, pos, anchor) {
|
|
1933
1901
|
const startCond = this.re2.cond;
|
|
1934
1902
|
if (startCond === Utils.EMPTY_ALL) return false;
|
|
@@ -1967,13 +1935,14 @@ var Machine = class Machine {
|
|
|
1967
1935
|
r = input.step(currentPos + width);
|
|
1968
1936
|
rune1 = r >> 3;
|
|
1969
1937
|
width1 = r & 7;
|
|
1938
|
+
flag = input.context(currentPos);
|
|
1970
1939
|
}
|
|
1971
1940
|
}
|
|
1972
|
-
if (currentPos === 0 && this.prog.numLb > 0) for (let i = 0; i < this.prog.lbStarts.length; i++) this.add(runq, this.prog.lbStarts[i], currentPos, this.matchcap,
|
|
1941
|
+
if (currentPos === 0 && this.prog.numLb > 0) for (let i = 0; i < this.prog.lbStarts.length; i++) this.add(runq, this.prog.lbStarts[i], currentPos, this.matchcap, 0, flag);
|
|
1973
1942
|
if (!this.matched && (currentPos === 0 || anchor === RE2Flags.UNANCHORED)) {
|
|
1974
1943
|
if (currentPos >= matchStartPos) {
|
|
1975
1944
|
if (this.ncap > 0) this.matchcap[0] = currentPos;
|
|
1976
|
-
this.add(runq, this.prog.start, currentPos, this.matchcap,
|
|
1945
|
+
this.add(runq, this.prog.start, currentPos, this.matchcap, 0, flag);
|
|
1977
1946
|
}
|
|
1978
1947
|
}
|
|
1979
1948
|
const nextPos = currentPos + width;
|
|
@@ -1993,7 +1962,7 @@ var Machine = class Machine {
|
|
|
1993
1962
|
runq = nextq;
|
|
1994
1963
|
nextq = tmpq;
|
|
1995
1964
|
}
|
|
1996
|
-
|
|
1965
|
+
nextq.clear();
|
|
1997
1966
|
return this.matched;
|
|
1998
1967
|
}
|
|
1999
1968
|
matchSet(input, pos, anchor) {
|
|
@@ -2021,16 +1990,16 @@ var Machine = class Machine {
|
|
|
2021
1990
|
if ((startCond & Utils.EMPTY_BEGIN_TEXT) !== 0 && currentPos !== 0) break;
|
|
2022
1991
|
if ((anchor === RE2Flags.ANCHOR_START || anchor === RE2Flags.ANCHOR_BOTH) && currentPos !== 0) break;
|
|
2023
1992
|
}
|
|
2024
|
-
if (currentPos === 0 && this.prog.numLb > 0) for (let i = 0; i < this.prog.lbStarts.length; i++) this.add(runq, this.prog.lbStarts[i], currentPos, this.matchcap,
|
|
1993
|
+
if (currentPos === 0 && this.prog.numLb > 0) for (let i = 0; i < this.prog.lbStarts.length; i++) this.add(runq, this.prog.lbStarts[i], currentPos, this.matchcap, 0, flag);
|
|
2025
1994
|
if (currentPos === 0 || anchor === RE2Flags.UNANCHORED) {
|
|
2026
|
-
if (currentPos >= matchStartPos) this.add(runq, this.prog.start, currentPos, this.matchcap,
|
|
1995
|
+
if (currentPos >= matchStartPos) this.add(runq, this.prog.start, currentPos, this.matchcap, 0, flag);
|
|
2027
1996
|
}
|
|
2028
1997
|
const nextPos = currentPos + width;
|
|
2029
1998
|
flag = input.context(nextPos);
|
|
2030
1999
|
for (let j = 0; j < runq.size; j++) {
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
const
|
|
2000
|
+
const pc = runq.densePcs[j];
|
|
2001
|
+
const i = this.prog.inst[pc];
|
|
2002
|
+
const capOffset = j * this.ncap;
|
|
2034
2003
|
let add = false;
|
|
2035
2004
|
switch (i.op) {
|
|
2036
2005
|
case Inst.MATCH:
|
|
@@ -2047,15 +2016,11 @@ var Machine = class Machine {
|
|
|
2047
2016
|
add = true;
|
|
2048
2017
|
break;
|
|
2049
2018
|
case Inst.RUNE_ANY_NOT_NL:
|
|
2050
|
-
add = rune !==
|
|
2019
|
+
add = rune !== 10;
|
|
2051
2020
|
break;
|
|
2052
|
-
default:
|
|
2053
|
-
}
|
|
2054
|
-
if (add) t = this.add(nextq, i.out, nextPos, t.cap, flag, t);
|
|
2055
|
-
if (t !== null) {
|
|
2056
|
-
this.freeThread(t);
|
|
2057
|
-
runq.denseThreads[j] = null;
|
|
2021
|
+
default: continue;
|
|
2058
2022
|
}
|
|
2023
|
+
if (add) this.add(nextq, i.out, nextPos, runq.denseCaps, capOffset, flag);
|
|
2059
2024
|
}
|
|
2060
2025
|
runq.clear();
|
|
2061
2026
|
if (width === 0) break;
|
|
@@ -2071,28 +2036,25 @@ var Machine = class Machine {
|
|
|
2071
2036
|
runq = nextq;
|
|
2072
2037
|
nextq = tmpq;
|
|
2073
2038
|
}
|
|
2074
|
-
|
|
2039
|
+
nextq.clear();
|
|
2075
2040
|
return Array.from(matches).sort((a, b) => a - b);
|
|
2076
2041
|
}
|
|
2077
2042
|
step(runq, nextq, pos, nextPos, c, nextCond, anchor, atEnd) {
|
|
2078
2043
|
const longest = this.re2.longest;
|
|
2079
2044
|
for (let j = 0; j < runq.size; j++) {
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
if (longest && this.matched && this.ncap > 0 && this.matchcap[0] <
|
|
2083
|
-
|
|
2084
|
-
continue;
|
|
2085
|
-
}
|
|
2086
|
-
const i = t.inst;
|
|
2045
|
+
const pc = runq.densePcs[j];
|
|
2046
|
+
const capOffset = j * this.ncap;
|
|
2047
|
+
if (longest && this.matched && this.ncap > 0 && this.matchcap[0] < runq.denseCaps[capOffset]) continue;
|
|
2048
|
+
const i = this.prog.inst[pc];
|
|
2087
2049
|
let add = false;
|
|
2088
2050
|
switch (i.op) {
|
|
2089
2051
|
case Inst.MATCH:
|
|
2090
2052
|
if (anchor === RE2Flags.ANCHOR_BOTH && !atEnd) break;
|
|
2091
2053
|
if (this.ncap > 0 && (!longest || !this.matched || this.matchcap[1] < pos)) {
|
|
2092
|
-
|
|
2093
|
-
|
|
2054
|
+
runq.denseCaps[capOffset + 1] = pos;
|
|
2055
|
+
for (let k = 0; k < this.ncap; k++) this.matchcap[k] = runq.denseCaps[capOffset + k];
|
|
2094
2056
|
}
|
|
2095
|
-
if (!longest)
|
|
2057
|
+
if (!longest) runq.size = 0;
|
|
2096
2058
|
this.matched = true;
|
|
2097
2059
|
break;
|
|
2098
2060
|
case Inst.RUNE:
|
|
@@ -2105,29 +2067,25 @@ var Machine = class Machine {
|
|
|
2105
2067
|
add = true;
|
|
2106
2068
|
break;
|
|
2107
2069
|
case Inst.RUNE_ANY_NOT_NL:
|
|
2108
|
-
add = c !==
|
|
2070
|
+
add = c !== 10;
|
|
2109
2071
|
break;
|
|
2110
|
-
default:
|
|
2111
|
-
}
|
|
2112
|
-
if (add) t = this.add(nextq, i.out, nextPos, t.cap, nextCond, t);
|
|
2113
|
-
if (t !== null) {
|
|
2114
|
-
this.freeThread(t);
|
|
2115
|
-
runq.denseThreads[j] = null;
|
|
2072
|
+
default: continue;
|
|
2116
2073
|
}
|
|
2074
|
+
if (add) this.add(nextq, i.out, nextPos, runq.denseCaps, capOffset, nextCond);
|
|
2117
2075
|
}
|
|
2118
2076
|
runq.clear();
|
|
2119
2077
|
}
|
|
2120
|
-
add(q, pc, pos,
|
|
2078
|
+
add(q, pc, pos, capArray, capOffset, cond) {
|
|
2121
2079
|
while (true) {
|
|
2122
|
-
if (pc === 0) return
|
|
2123
|
-
if (q.contains(pc)) return
|
|
2080
|
+
if (pc === 0) return;
|
|
2081
|
+
if (q.contains(pc)) return;
|
|
2124
2082
|
const d = q.add(pc);
|
|
2125
2083
|
const inst = this.prog.inst[pc];
|
|
2126
2084
|
switch (inst.op) {
|
|
2127
|
-
case Inst.FAIL: return
|
|
2085
|
+
case Inst.FAIL: return;
|
|
2128
2086
|
case Inst.ALT:
|
|
2129
2087
|
case Inst.ALT_MATCH:
|
|
2130
|
-
|
|
2088
|
+
this.add(q, inst.out, pos, capArray, capOffset, cond);
|
|
2131
2089
|
pc = inst.arg;
|
|
2132
2090
|
continue;
|
|
2133
2091
|
case Inst.EMPTY_WIDTH:
|
|
@@ -2135,16 +2093,16 @@ var Machine = class Machine {
|
|
|
2135
2093
|
pc = inst.out;
|
|
2136
2094
|
continue;
|
|
2137
2095
|
}
|
|
2138
|
-
return
|
|
2096
|
+
return;
|
|
2139
2097
|
case Inst.NOP:
|
|
2140
2098
|
pc = inst.out;
|
|
2141
2099
|
continue;
|
|
2142
2100
|
case Inst.CAPTURE: if (inst.arg < this.ncap) {
|
|
2143
|
-
const opos =
|
|
2144
|
-
|
|
2145
|
-
this.add(q, inst.out, pos,
|
|
2146
|
-
|
|
2147
|
-
return
|
|
2101
|
+
const opos = capArray[capOffset + inst.arg];
|
|
2102
|
+
capArray[capOffset + inst.arg] = pos;
|
|
2103
|
+
this.add(q, inst.out, pos, capArray, capOffset, cond);
|
|
2104
|
+
capArray[capOffset + inst.arg] = opos;
|
|
2105
|
+
return;
|
|
2148
2106
|
} else {
|
|
2149
2107
|
pc = inst.out;
|
|
2150
2108
|
continue;
|
|
@@ -2163,19 +2121,18 @@ var Machine = class Machine {
|
|
|
2163
2121
|
pc = inst.out;
|
|
2164
2122
|
continue;
|
|
2165
2123
|
}
|
|
2166
|
-
return
|
|
2124
|
+
return;
|
|
2167
2125
|
case Inst.MATCH:
|
|
2168
2126
|
case Inst.RUNE:
|
|
2169
2127
|
case Inst.RUNE1:
|
|
2170
2128
|
case Inst.RUNE_ANY:
|
|
2171
2129
|
case Inst.RUNE_ANY_NOT_NL:
|
|
2172
|
-
if (
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
default: throw new Error("unhandled");
|
|
2130
|
+
if (this.ncap > 0) {
|
|
2131
|
+
const destOffset = d * this.ncap;
|
|
2132
|
+
for (let c = 0; c < this.ncap; c++) q.denseCaps[destOffset + c] = capArray[capOffset + c];
|
|
2133
|
+
}
|
|
2134
|
+
return;
|
|
2135
|
+
default: throw new RE2JSInternalException("unhandled");
|
|
2179
2136
|
}
|
|
2180
2137
|
}
|
|
2181
2138
|
}
|
|
@@ -2772,7 +2729,9 @@ const makeOnePass = (p) => {
|
|
|
2772
2729
|
m[pc] = true;
|
|
2773
2730
|
inst.op = Inst.ALT_MATCH;
|
|
2774
2731
|
}
|
|
2775
|
-
const
|
|
2732
|
+
const leftRunes = onePassRunes[inst.out] || [];
|
|
2733
|
+
const rightRunes = onePassRunes[inst.arg] || [];
|
|
2734
|
+
const mergeRes = mergeRuneSets(leftRunes, rightRunes, inst.out, inst.arg);
|
|
2776
2735
|
if (!mergeRes) return false;
|
|
2777
2736
|
onePassRunes[pc] = mergeRes.merged;
|
|
2778
2737
|
inst.next = new Uint32Array(mergeRes.next);
|
|
@@ -5364,24 +5323,6 @@ var Parser = class Parser {
|
|
|
5364
5323
|
};
|
|
5365
5324
|
//#endregion
|
|
5366
5325
|
//#region src/RE2.js
|
|
5367
|
-
var AtomicReference = class {
|
|
5368
|
-
constructor(initialValue) {
|
|
5369
|
-
this.value = initialValue;
|
|
5370
|
-
}
|
|
5371
|
-
get() {
|
|
5372
|
-
return this.value;
|
|
5373
|
-
}
|
|
5374
|
-
set(newValue) {
|
|
5375
|
-
this.value = newValue;
|
|
5376
|
-
}
|
|
5377
|
-
compareAndSet(expect, update) {
|
|
5378
|
-
if (this.value === expect) {
|
|
5379
|
-
this.value = update;
|
|
5380
|
-
return true;
|
|
5381
|
-
}
|
|
5382
|
-
return false;
|
|
5383
|
-
}
|
|
5384
|
-
};
|
|
5385
5326
|
/**
|
|
5386
5327
|
* An RE2 class instance is a compiled representation of an RE2 regular expression, independent of
|
|
5387
5328
|
* the public Java-like Pattern/Matcher API.
|
|
@@ -5470,7 +5411,7 @@ var RE2 = class RE2 {
|
|
|
5470
5411
|
this.prefixUTF8 = null;
|
|
5471
5412
|
this.prefixComplete = false;
|
|
5472
5413
|
this.prefixRune = 0;
|
|
5473
|
-
this.
|
|
5414
|
+
this.machinePool = [];
|
|
5474
5415
|
this.dfa = new DFA(this.prog);
|
|
5475
5416
|
this.onepass = OnePass.compile(this.prog);
|
|
5476
5417
|
this.prefilter = null;
|
|
@@ -5534,42 +5475,23 @@ var RE2 = class RE2 {
|
|
|
5534
5475
|
return this.prog.numInst();
|
|
5535
5476
|
}
|
|
5536
5477
|
get() {
|
|
5537
|
-
|
|
5538
|
-
do
|
|
5539
|
-
head = this.pooled.get();
|
|
5540
|
-
while (head && !this.pooled.compareAndSet(head, head.next));
|
|
5541
|
-
return head;
|
|
5478
|
+
return this.machinePool.length > 0 ? this.machinePool.pop() : null;
|
|
5542
5479
|
}
|
|
5543
5480
|
reset() {
|
|
5544
|
-
this.
|
|
5545
|
-
}
|
|
5546
|
-
put(m
|
|
5547
|
-
|
|
5548
|
-
do {
|
|
5549
|
-
head = this.pooled.get();
|
|
5550
|
-
if (!isNew && head) {
|
|
5551
|
-
m = Machine.fromMachine(m);
|
|
5552
|
-
isNew = true;
|
|
5553
|
-
}
|
|
5554
|
-
if (m.next !== head) m.next = head;
|
|
5555
|
-
} while (!this.pooled.compareAndSet(head, m));
|
|
5481
|
+
this.machinePool.length = 0;
|
|
5482
|
+
}
|
|
5483
|
+
put(m) {
|
|
5484
|
+
this.machinePool.push(m);
|
|
5556
5485
|
}
|
|
5557
5486
|
toString() {
|
|
5558
5487
|
return this.expr;
|
|
5559
5488
|
}
|
|
5560
5489
|
doExecuteNFA(input, pos, anchor, ncap) {
|
|
5561
5490
|
let m = this.get();
|
|
5562
|
-
|
|
5563
|
-
if (!m) {
|
|
5564
|
-
m = Machine.fromRE2(this);
|
|
5565
|
-
isNew = true;
|
|
5566
|
-
} else if (m.next !== null) {
|
|
5567
|
-
m = Machine.fromMachine(m);
|
|
5568
|
-
isNew = true;
|
|
5569
|
-
}
|
|
5491
|
+
if (!m) m = Machine.fromRE2(this);
|
|
5570
5492
|
m.init(ncap);
|
|
5571
5493
|
const cap = m.match(input, pos, anchor) ? m.submatches() : null;
|
|
5572
|
-
this.put(m
|
|
5494
|
+
this.put(m);
|
|
5573
5495
|
return cap;
|
|
5574
5496
|
}
|
|
5575
5497
|
match(s) {
|
|
@@ -6365,6 +6287,33 @@ var RE2JS = class RE2JS {
|
|
|
6365
6287
|
return this.re2Input.executeEngine(machineInput, 0, RE2Flags.ANCHOR_BOTH, 0) !== null;
|
|
6366
6288
|
}
|
|
6367
6289
|
/**
|
|
6290
|
+
* Executes a search for a match in a specified string.
|
|
6291
|
+
* Returns a result array, or null if no match is found.
|
|
6292
|
+
* The returned array perfectly mirrors standard JavaScript `RegExpExecArray`,
|
|
6293
|
+
* including `.index`, `.input`, and `.groups` properties.
|
|
6294
|
+
*
|
|
6295
|
+
* @param {string|number[]|Uint8Array} input the input string or byte array
|
|
6296
|
+
* @returns {Array|null} the match array with index, input, and groups properties, or null
|
|
6297
|
+
*/
|
|
6298
|
+
exec(input) {
|
|
6299
|
+
const m = this.matcher(input);
|
|
6300
|
+
if (!m.find()) return null;
|
|
6301
|
+
const result = [m.group(0)];
|
|
6302
|
+
for (let i = 1; i <= m.groupCount(); i++) {
|
|
6303
|
+
const val = m.group(i);
|
|
6304
|
+
result.push(val === null ? void 0 : val);
|
|
6305
|
+
}
|
|
6306
|
+
result.index = m.start(0);
|
|
6307
|
+
result.input = input;
|
|
6308
|
+
const namedGroups = this.namedGroups();
|
|
6309
|
+
if (Object.keys(namedGroups).length > 0) {
|
|
6310
|
+
const parsedGroups = m.getNamedGroups();
|
|
6311
|
+
for (const key in parsedGroups) if (parsedGroups[key] === null) parsedGroups[key] = void 0;
|
|
6312
|
+
result.groups = parsedGroups;
|
|
6313
|
+
} else result.groups = void 0;
|
|
6314
|
+
return result;
|
|
6315
|
+
}
|
|
6316
|
+
/**
|
|
6368
6317
|
* Splits input around instances of the regular expression. It returns an array giving the strings
|
|
6369
6318
|
* that occur before, between, and after instances of the regular expression.
|
|
6370
6319
|
*
|
|
@@ -6408,7 +6357,7 @@ var RE2JS = class RE2JS {
|
|
|
6408
6357
|
}
|
|
6409
6358
|
result.push(m.substring(last, m.inputLength()));
|
|
6410
6359
|
}
|
|
6411
|
-
if (limit !== 0 || result.length === 0) result.push(m.substring(last, m.inputLength()));
|
|
6360
|
+
if (limit !== 0 || result.length === 0 && !(last === m.inputLength() && last > 0)) result.push(m.substring(last, m.inputLength()));
|
|
6412
6361
|
return result;
|
|
6413
6362
|
}
|
|
6414
6363
|
/**
|
|
@@ -6416,7 +6365,7 @@ var RE2JS = class RE2JS {
|
|
|
6416
6365
|
* including capturing groups.
|
|
6417
6366
|
*
|
|
6418
6367
|
* @param {string|number[]|Uint8Array} input the input string or byte array
|
|
6419
|
-
* @returns {IterableIterator<
|
|
6368
|
+
* @returns {IterableIterator<RegExpMatchArray>}
|
|
6420
6369
|
*/
|
|
6421
6370
|
*matchAll(input) {
|
|
6422
6371
|
const m = this.matcher(input);
|