diff --git a/src/ast.ts b/src/ast.ts index 9925265..6628567 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -428,10 +428,21 @@ export interface Character extends NodeBase { * The backreference. * E.g. `\1`, `\k` */ -export interface Backreference extends NodeBase { +export type Backreference = AmbiguousBackreference | UnambiguousBackreference +interface BaseBackreference extends NodeBase { type: "Backreference" parent: Alternative | Quantifier ref: number | string + ambiguous: boolean + resolved: CapturingGroup | CapturingGroup[] +} +export interface AmbiguousBackreference extends BaseBackreference { + ref: string + ambiguous: true + resolved: CapturingGroup[] +} +export interface UnambiguousBackreference extends BaseBackreference { + ambiguous: false resolved: CapturingGroup } diff --git a/src/ecma-versions.ts b/src/ecma-versions.ts index 4ce2cb8..3a6b1d9 100644 --- a/src/ecma-versions.ts +++ b/src/ecma-versions.ts @@ -10,4 +10,5 @@ export type EcmaVersion = | 2022 | 2023 | 2024 -export const latestEcmaVersion = 2024 + | 2025 +export const latestEcmaVersion = 2025 diff --git a/src/group-specifiers.ts b/src/group-specifiers.ts new file mode 100644 index 0000000..e26329b --- /dev/null +++ b/src/group-specifiers.ts @@ -0,0 +1,167 @@ +/** + * Holds information for all GroupSpecifiers included in the pattern. + */ +export interface GroupSpecifiers { + /** + * @returns true if there are no GroupSpecifiers included in the pattern. + */ + isEmpty: () => boolean + clear: () => void + /** + * Called when visiting the Disjunction. + * For ES2025, manage nesting with new Disjunction scopes. + */ + enterDisjunction: () => void + /** + * Called when visiting the Alternative. + * For ES2025, manage nesting with new Alternative scopes. + */ + enterAlternative: (index: number) => void + /** + * Called when leaving the Disjunction. + */ + leaveDisjunction: () => unknown + /** + * Checks whether the given group name is within the pattern. + */ + hasInPattern: (name: string) => boolean + /** + * Checks whether the given group name is within the current scope. + */ + hasInScope: (name: string) => boolean + /** + * Adds the given group name to the current scope. + */ + addToScope: (name: string) => void +} + +export class GroupSpecifiersAsES2018 implements GroupSpecifiers { + private readonly groupName = new Set() + + public clear(): void { + this.groupName.clear() + } + + public isEmpty(): boolean { + return !this.groupName.size + } + + public hasInPattern(name: string): boolean { + return this.groupName.has(name) + } + + public hasInScope(name: string): boolean { + return this.hasInPattern(name) + } + + public addToScope(name: string): void { + this.groupName.add(name) + } + + // eslint-disable-next-line class-methods-use-this + public enterDisjunction(): void { + // Prior to ES2025, it does not manage disjunction scopes. + } + + // eslint-disable-next-line class-methods-use-this + public enterAlternative(): void { + // Prior to ES2025, it does not manage alternative scopes. + } + + // eslint-disable-next-line class-methods-use-this + public leaveDisjunction(): void { + // Prior to ES2025, it does not manage disjunction scopes. + } +} + +/** + * Track disjunction structure to determine whether a duplicate + * capture group name is allowed because it is in a separate branch. + */ +class BranchID { + public readonly parent: BranchID | null + private readonly base: BranchID + public constructor(parent: BranchID | null, base: BranchID | null) { + // Parent disjunction branch + this.parent = parent + // Identifies this set of sibling branches + this.base = base ?? this + } + + /** + * A branch is separate from another branch if they or any of + * their parents are siblings in a given disjunction + */ + public separatedFrom(other: BranchID): boolean { + if (this.base === other.base && this !== other) { + return true + } + if (other.parent && this.separatedFrom(other.parent)) { + return true + } + return this.parent?.separatedFrom(other) ?? false + } + + public child() { + return new BranchID(this, null) + } + + public sibling() { + return new BranchID(this.parent, this.base) + } +} + +export class GroupSpecifiersAsES2025 implements GroupSpecifiers { + private branchID = new BranchID(null, null) + private readonly groupNames = new Map() + + public clear(): void { + this.branchID = new BranchID(null, null) + this.groupNames.clear() + } + + public isEmpty(): boolean { + return !this.groupNames.size + } + + public enterDisjunction(): void { + this.branchID = this.branchID.child() + } + + public enterAlternative(index: number): void { + if (index === 0) { + return + } + this.branchID = this.branchID.sibling() + } + + public leaveDisjunction(): void { + this.branchID = this.branchID.parent! + } + + public hasInPattern(name: string): boolean { + return this.groupNames.has(name) + } + + public hasInScope(name: string): boolean { + const branches = this.groupNames.get(name) + if (!branches) { + return false + } + for (const branch of branches) { + if (!branch.separatedFrom(this.branchID)) { + return true + } + } + return false + } + + public addToScope(name: string): void { + const branches = this.groupNames.get(name) + if (branches) { + branches.push(this.branchID) + return + } + this.groupNames.set(name, [this.branchID]) + } +} diff --git a/src/parser.ts b/src/parser.ts index 6ba9fbc..61522af 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -148,12 +148,21 @@ class RegExpParserState { for (const reference of this._backreferences) { const ref = reference.ref - const group = + const groups = typeof ref === "number" - ? this._capturingGroups[ref - 1] - : this._capturingGroups.find((g) => g.name === ref)! - reference.resolved = group - group.references.push(reference) + ? [this._capturingGroups[ref - 1]] + : this._capturingGroups.filter((g) => g.name === ref) + if (groups.length === 1) { + const group = groups[0] + reference.ambiguous = false + reference.resolved = group + } else { + reference.ambiguous = true + reference.resolved = groups + } + for (const group of groups) { + group.references.push(reference) + } } } @@ -480,6 +489,7 @@ class RegExpParserState { end, raw: this.source.slice(start, end), ref, + ambiguous: false, resolved: DUMMY_CAPTURING_GROUP, } parent.elements.push(node) @@ -747,7 +757,7 @@ export namespace RegExpParser { strict?: boolean /** - * ECMAScript version. Default is `2024`. + * ECMAScript version. Default is `2025`. * - `2015` added `u` and `y` flags. * - `2018` added `s` flag, Named Capturing Group, Lookbehind Assertion, * and Unicode Property Escape. @@ -755,6 +765,7 @@ export namespace RegExpParser { * - `2022` added `d` flag. * - `2023` added more valid Unicode Property Escapes. * - `2024` added `v` flag. + * - `2025` added duplicate named capturing groups. */ ecmaVersion?: EcmaVersion } diff --git a/src/validator.ts b/src/validator.ts index 41901c9..72c5439 100644 --- a/src/validator.ts +++ b/src/validator.ts @@ -1,5 +1,10 @@ import type { EcmaVersion } from "./ecma-versions" import { latestEcmaVersion } from "./ecma-versions" +import type { GroupSpecifiers } from "./group-specifiers" +import { + GroupSpecifiersAsES2018, + GroupSpecifiersAsES2025, +} from "./group-specifiers" import { Reader } from "./reader" import { newRegExpSyntaxError } from "./regexp-syntax-error" import { @@ -231,7 +236,7 @@ export namespace RegExpValidator { strict?: boolean /** - * ECMAScript version. Default is `2024`. + * ECMAScript version. Default is `2025`. * - `2015` added `u` and `y` flags. * - `2018` added `s` flag, Named Capturing Group, Lookbehind Assertion, * and Unicode Property Escape. @@ -239,6 +244,7 @@ export namespace RegExpValidator { * - `2022` added `d` flag. * - `2023` added more valid Unicode Property Escapes. * - `2024` added `v` flag. + * - `2025` added duplicate named capturing groups. */ ecmaVersion?: EcmaVersion @@ -631,7 +637,7 @@ export class RegExpValidator { private _numCapturingParens = 0 - private _groupNames = new Set() + private _groupSpecifiers: GroupSpecifiers private _backreferenceNames = new Set() @@ -643,6 +649,10 @@ export class RegExpValidator { */ public constructor(options?: RegExpValidator.Options) { this._options = options ?? {} + this._groupSpecifiers = + this.ecmaVersion >= 2025 + ? new GroupSpecifiersAsES2025() + : new GroupSpecifiersAsES2018() } /** @@ -763,7 +773,7 @@ export class RegExpValidator { if ( !this._nFlag && this.ecmaVersion >= 2018 && - this._groupNames.size > 0 + !this._groupSpecifiers.isEmpty() ) { this._nFlag = true this.rewind(start) @@ -1301,7 +1311,7 @@ export class RegExpValidator { private consumePattern(): void { const start = this.index this._numCapturingParens = this.countCapturingParens() - this._groupNames.clear() + this._groupSpecifiers.clear() this._backreferenceNames.clear() this.onPatternEnter(start) @@ -1322,7 +1332,7 @@ export class RegExpValidator { this.raise(`Unexpected character '${c}'`) } for (const name of this._backreferenceNames) { - if (!this._groupNames.has(name)) { + if (!this._groupSpecifiers.hasInPattern(name)) { this.raise("Invalid named capture referenced") } } @@ -1378,6 +1388,7 @@ export class RegExpValidator { const start = this.index let i = 0 + this._groupSpecifiers.enterDisjunction() this.onDisjunctionEnter(start) do { this.consumeAlternative(i++) @@ -1390,6 +1401,7 @@ export class RegExpValidator { this.raise("Lone quantifier brackets") } this.onDisjunctionLeave(start, this.index) + this._groupSpecifiers.leaveDisjunction() } /** @@ -1403,6 +1415,7 @@ export class RegExpValidator { private consumeAlternative(i: number): void { const start = this.index + this._groupSpecifiers.enterAlternative(i) this.onAlternativeEnter(start, i) while (this.currentCodePoint !== -1 && this.consumeTerm()) { // do nothing. @@ -1846,8 +1859,8 @@ export class RegExpValidator { private consumeGroupSpecifier(): boolean { if (this.eat(QUESTION_MARK)) { if (this.eatGroupName()) { - if (!this._groupNames.has(this._lastStrValue)) { - this._groupNames.add(this._lastStrValue) + if (!this._groupSpecifiers.hasInScope(this._lastStrValue)) { + this._groupSpecifiers.addToScope(this._lastStrValue) return true } this.raise("Duplicate capture group name") diff --git a/test/fixtures/parser/literal/basic-valid-2015-u.json b/test/fixtures/parser/literal/basic-valid-2015-u.json index 5bc7306..963494d 100644 --- a/test/fixtures/parser/literal/basic-valid-2015-u.json +++ b/test/fixtures/parser/literal/basic-valid-2015-u.json @@ -1690,6 +1690,7 @@ "end": 6, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1741,6 +1742,7 @@ "end": 3, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -2104,6 +2106,7 @@ "end": 34, "raw": "\\10", "ref": 10, + "ambiguous": false, "resolved": "♻️../9" } ] @@ -2465,6 +2468,7 @@ "end": 37, "raw": "\\11", "ref": 11, + "ambiguous": false, "resolved": "♻️../10" } ] diff --git a/test/fixtures/parser/literal/basic-valid-2015.json b/test/fixtures/parser/literal/basic-valid-2015.json index fb85c3c..ed988e9 100644 --- a/test/fixtures/parser/literal/basic-valid-2015.json +++ b/test/fixtures/parser/literal/basic-valid-2015.json @@ -3800,6 +3800,7 @@ "end": 6, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -3851,6 +3852,7 @@ "end": 3, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -4444,6 +4446,7 @@ "end": 34, "raw": "\\10", "ref": 10, + "ambiguous": false, "resolved": "♻️../9" } ] @@ -5135,6 +5138,7 @@ "end": 37, "raw": "\\11", "ref": 11, + "ambiguous": false, "resolved": "♻️../10" } ] diff --git a/test/fixtures/parser/literal/basic-valid.json b/test/fixtures/parser/literal/basic-valid.json index 16341ee..e8b04da 100644 --- a/test/fixtures/parser/literal/basic-valid.json +++ b/test/fixtures/parser/literal/basic-valid.json @@ -3800,6 +3800,7 @@ "end": 6, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -3851,6 +3852,7 @@ "end": 3, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -4444,6 +4446,7 @@ "end": 34, "raw": "\\10", "ref": 10, + "ambiguous": false, "resolved": "♻️../9" } ] @@ -5135,6 +5138,7 @@ "end": 37, "raw": "\\11", "ref": 11, + "ambiguous": false, "resolved": "♻️../10" } ] diff --git a/test/fixtures/parser/literal/duplicate-named-capturing-group-invalid-2024.json b/test/fixtures/parser/literal/duplicate-named-capturing-group-invalid-2024.json new file mode 100644 index 0000000..e61353f --- /dev/null +++ b/test/fixtures/parser/literal/duplicate-named-capturing-group-invalid-2024.json @@ -0,0 +1,14 @@ +{ + "options": { + "strict": false, + "ecmaVersion": 2024 + }, + "patterns": { + "/(?[0-9]{4})-[0-9]{2}|[0-9]{2}-(?[0-9]{4})/": { + "error": { + "message": "Invalid regular expression: /(?[0-9]{4})-[0-9]{2}|[0-9]{2}-(?[0-9]{4})/: Duplicate capture group name", + "index": 45 + } + } + } +} \ No newline at end of file diff --git a/test/fixtures/parser/literal/duplicate-named-capturing-group-invalid-2025.json b/test/fixtures/parser/literal/duplicate-named-capturing-group-invalid-2025.json new file mode 100644 index 0000000..40c68ad --- /dev/null +++ b/test/fixtures/parser/literal/duplicate-named-capturing-group-invalid-2025.json @@ -0,0 +1,44 @@ +{ + "options": { + "strict": false, + "ecmaVersion": 2025 + }, + "patterns": { + "/(?[0-9]{4})-(?[0-9]{2})/": { + "error": { + "message": "Invalid regular expression: /(?[0-9]{4})-(?[0-9]{2})/: Duplicate capture group name", + "index": 27 + } + }, + "/(?a)|(?b)(?c)/": { + "error": { + "message": "Invalid regular expression: /(?a)|(?b)(?c)/: Duplicate capture group name", + "index": 21 + } + }, + "/(?:(?a)|(?b))(?c)/": { + "error": { + "message": "Invalid regular expression: /(?:(?a)|(?b))(?c)/: Duplicate capture group name", + "index": 25 + } + }, + "/(?a)(?:(?b)|(?c))/": { + "error": { + "message": "Invalid regular expression: /(?a)(?:(?b)|(?c))/: Duplicate capture group name", + "index": 16 + } + }, + "/(?:(?:(?a)|(?b)))(?c)/": { + "error": { + "message": "Invalid regular expression: /(?:(?:(?a)|(?b)))(?c)/: Duplicate capture group name", + "index": 29 + } + }, + "/(?:(?:(?a)|(?b))|(?:))(?c)/": { + "error": { + "message": "Invalid regular expression: /(?:(?:(?a)|(?b))|(?:))(?c)/: Duplicate capture group name", + "index": 34 + } + } + } +} \ No newline at end of file diff --git a/test/fixtures/parser/literal/duplicate-named-capturing-group-valid-2025.json b/test/fixtures/parser/literal/duplicate-named-capturing-group-valid-2025.json new file mode 100644 index 0000000..de6bca9 --- /dev/null +++ b/test/fixtures/parser/literal/duplicate-named-capturing-group-valid-2025.json @@ -0,0 +1,723 @@ +{ + "options": { + "strict": false, + "ecmaVersion": 2025 + }, + "patterns": { + "/(?[0-9]{4})-[0-9]{2}|[0-9]{2}-(?[0-9]{4})/": { + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 55, + "raw": "/(?[0-9]{4})-[0-9]{2}|[0-9]{2}-(?[0-9]{4})/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 54, + "raw": "(?[0-9]{4})-[0-9]{2}|[0-9]{2}-(?[0-9]{4})", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 27, + "raw": "(?[0-9]{4})-[0-9]{2}", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 1, + "end": 18, + "raw": "(?[0-9]{4})", + "name": "year", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 17, + "raw": "[0-9]{4}", + "elements": [ + { + "type": "Quantifier", + "parent": "♻️../..", + "start": 9, + "end": 17, + "raw": "[0-9]{4}", + "min": 4, + "max": 4, + "greedy": true, + "element": { + "type": "CharacterClass", + "parent": "♻️..", + "start": 9, + "end": 14, + "raw": "[0-9]", + "unicodeSets": false, + "negate": false, + "elements": [ + { + "type": "CharacterClassRange", + "parent": "♻️../..", + "start": 10, + "end": 13, + "raw": "0-9", + "min": { + "type": "Character", + "parent": "♻️..", + "start": 10, + "end": 11, + "raw": "0", + "value": 48 + }, + "max": { + "type": "Character", + "parent": "♻️..", + "start": 12, + "end": 13, + "raw": "9", + "value": 57 + } + } + ] + } + } + ] + } + ], + "references": [] + }, + { + "type": "Character", + "parent": "♻️../..", + "start": 18, + "end": 19, + "raw": "-", + "value": 45 + }, + { + "type": "Quantifier", + "parent": "♻️../..", + "start": 19, + "end": 27, + "raw": "[0-9]{2}", + "min": 2, + "max": 2, + "greedy": true, + "element": { + "type": "CharacterClass", + "parent": "♻️..", + "start": 19, + "end": 24, + "raw": "[0-9]", + "unicodeSets": false, + "negate": false, + "elements": [ + { + "type": "CharacterClassRange", + "parent": "♻️../..", + "start": 20, + "end": 23, + "raw": "0-9", + "min": { + "type": "Character", + "parent": "♻️..", + "start": 20, + "end": 21, + "raw": "0", + "value": 48 + }, + "max": { + "type": "Character", + "parent": "♻️..", + "start": 22, + "end": 23, + "raw": "9", + "value": 57 + } + } + ] + } + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 28, + "end": 54, + "raw": "[0-9]{2}-(?[0-9]{4})", + "elements": [ + { + "type": "Quantifier", + "parent": "♻️../..", + "start": 28, + "end": 36, + "raw": "[0-9]{2}", + "min": 2, + "max": 2, + "greedy": true, + "element": { + "type": "CharacterClass", + "parent": "♻️..", + "start": 28, + "end": 33, + "raw": "[0-9]", + "unicodeSets": false, + "negate": false, + "elements": [ + { + "type": "CharacterClassRange", + "parent": "♻️../..", + "start": 29, + "end": 32, + "raw": "0-9", + "min": { + "type": "Character", + "parent": "♻️..", + "start": 29, + "end": 30, + "raw": "0", + "value": 48 + }, + "max": { + "type": "Character", + "parent": "♻️..", + "start": 31, + "end": 32, + "raw": "9", + "value": 57 + } + } + ] + } + }, + { + "type": "Character", + "parent": "♻️../..", + "start": 36, + "end": 37, + "raw": "-", + "value": 45 + }, + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 37, + "end": 54, + "raw": "(?[0-9]{4})", + "name": "year", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 45, + "end": 53, + "raw": "[0-9]{4}", + "elements": [ + { + "type": "Quantifier", + "parent": "♻️../..", + "start": 45, + "end": 53, + "raw": "[0-9]{4}", + "min": 4, + "max": 4, + "greedy": true, + "element": { + "type": "CharacterClass", + "parent": "♻️..", + "start": 45, + "end": 50, + "raw": "[0-9]", + "unicodeSets": false, + "negate": false, + "elements": [ + { + "type": "CharacterClassRange", + "parent": "♻️../..", + "start": 46, + "end": 49, + "raw": "0-9", + "min": { + "type": "Character", + "parent": "♻️..", + "start": 46, + "end": 47, + "raw": "0", + "value": 48 + }, + "max": { + "type": "Character", + "parent": "♻️..", + "start": 48, + "end": 49, + "raw": "9", + "value": 57 + } + } + ] + } + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 55, + "end": 55, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } + } + }, + "/(?:(?:(?a)\\k|(?b)\\k)|(?:))\\k/": { + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 45, + "raw": "/(?:(?:(?a)\\k|(?b)\\k)|(?:))\\k/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 44, + "raw": "(?:(?:(?a)\\k|(?b)\\k)|(?:))\\k", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 44, + "raw": "(?:(?:(?a)\\k|(?b)\\k)|(?:))\\k", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 1, + "end": 39, + "raw": "(?:(?:(?a)\\k|(?b)\\k)|(?:))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 4, + "end": 33, + "raw": "(?:(?a)\\k|(?b)\\k)", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 4, + "end": 33, + "raw": "(?:(?a)\\k|(?b)\\k)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 7, + "end": 19, + "raw": "(?a)\\k", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 7, + "end": 14, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [ + "♻️../1", + "♻️../../../1/elements/1", + "♻️../../../../../../../../../1" + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 14, + "end": 19, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../0", + "♻️../../../1/elements/0" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 20, + "end": 32, + "raw": "(?b)\\k", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 20, + "end": 27, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 25, + "end": 26, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 25, + "end": 26, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [ + "♻️../../../0/elements/1", + "♻️../1", + "♻️../../../../../../../../../1" + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 27, + "end": 32, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../../../0/elements/0", + "♻️../0" + ] + } + ] + } + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 34, + "end": 38, + "raw": "(?:)", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 34, + "end": 38, + "raw": "(?:)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 37, + "end": 37, + "raw": "", + "elements": [] + } + ] + } + ] + } + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 39, + "end": 44, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0", + "♻️../0/alternatives/0/elements/0/alternatives/1/elements/0" + ] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 45, + "end": 45, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } + } + }, + "/(?:(?:(?a\\k)|(?b\\k))|(?:))\\k/": { + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 45, + "raw": "/(?:(?:(?a\\k)|(?b\\k))|(?:))\\k/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 44, + "raw": "(?:(?:(?a\\k)|(?b\\k))|(?:))\\k", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 44, + "raw": "(?:(?:(?a\\k)|(?b\\k))|(?:))\\k", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 1, + "end": 39, + "raw": "(?:(?:(?a\\k)|(?b\\k))|(?:))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 4, + "end": 33, + "raw": "(?:(?a\\k)|(?b\\k))", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 4, + "end": 33, + "raw": "(?:(?a\\k)|(?b\\k))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 7, + "end": 19, + "raw": "(?a\\k)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 7, + "end": 19, + "raw": "(?a\\k)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 12, + "end": 18, + "raw": "a\\k", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "value": 97 + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 13, + "end": 18, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../../../..", + "♻️../../../../../../../1/elements/0" + ] + } + ] + } + ], + "references": [ + "♻️alternatives/0/elements/1", + "♻️../../../1/elements/0/alternatives/0/elements/1", + "♻️../../../../../../../../../1" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 20, + "end": 32, + "raw": "(?b\\k)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 20, + "end": 32, + "raw": "(?b\\k)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 25, + "end": 31, + "raw": "b\\k", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 25, + "end": 26, + "raw": "b", + "value": 98 + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 26, + "end": 31, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../../../../../../../0/elements/0", + "♻️../../../.." + ] + } + ] + } + ], + "references": [ + "♻️../../../0/elements/0/alternatives/0/elements/1", + "♻️alternatives/0/elements/1", + "♻️../../../../../../../../../1" + ] + } + ] + } + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 34, + "end": 38, + "raw": "(?:)", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 34, + "end": 38, + "raw": "(?:)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 37, + "end": 37, + "raw": "", + "elements": [] + } + ] + } + ] + } + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 39, + "end": 44, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0", + "♻️../0/alternatives/0/elements/0/alternatives/1/elements/0" + ] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 45, + "end": 45, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } + } + } + } +} \ No newline at end of file diff --git a/test/fixtures/parser/literal/named-backreferences-valid-2023.json b/test/fixtures/parser/literal/named-backreferences-valid-2023.json index e1c52ef..051c04b 100644 --- a/test/fixtures/parser/literal/named-backreferences-valid-2023.json +++ b/test/fixtures/parser/literal/named-backreferences-valid-2023.json @@ -62,6 +62,7 @@ "end": 17, "raw": "\\k", "ref": "foo", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -143,6 +144,7 @@ "end": 17, "raw": "\\k", "ref": "foo", + "ambiguous": false, "resolved": "♻️../0" } ] diff --git a/test/fixtures/parser/literal/named-capturing-group-valid-2018.json b/test/fixtures/parser/literal/named-capturing-group-valid-2018.json index 880c323..169b435 100644 --- a/test/fixtures/parser/literal/named-capturing-group-valid-2018.json +++ b/test/fixtures/parser/literal/named-capturing-group-valid-2018.json @@ -385,6 +385,7 @@ "end": 13, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -466,6 +467,7 @@ "end": 13, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -547,6 +549,7 @@ "end": 10, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -628,6 +631,7 @@ "end": 10, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -953,6 +957,7 @@ "end": 6, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../1" }, { @@ -1034,6 +1039,7 @@ "end": 6, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../1" }, { @@ -1115,6 +1121,7 @@ "end": 3, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -1196,6 +1203,7 @@ "end": 3, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -1307,6 +1315,7 @@ "end": 19, "raw": "\\k<$abc>", "ref": "$abc", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1388,6 +1397,7 @@ "end": 13, "raw": "\\k<あ>", "ref": "あ", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1469,6 +1479,7 @@ "end": 22, "raw": "\\k<\\u{20bb7}>", "ref": "𠮷", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1550,6 +1561,7 @@ "end": 32, "raw": "\\k<\\u{20bb7}>", "ref": "𠮷", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1631,6 +1643,7 @@ "end": 32, "raw": "\\k<\\uD842\\uDFB7>", "ref": "𠮷", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1712,6 +1725,7 @@ "end": 32, "raw": "\\k<\\u0061\\u0062\\u0063>", "ref": "abc", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1793,6 +1807,7 @@ "end": 32, "raw": "\\k", "ref": "abc", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1874,6 +1889,7 @@ "end": 47, "raw": "\\k<\\u{61}\\u{62}\\u{63}>", "ref": "abc", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1955,6 +1971,7 @@ "end": 15, "raw": "\\k", "ref": "a1", + "ambiguous": false, "resolved": "♻️../0" } ] diff --git a/test/fixtures/parser/literal/test262/not-categorized.json b/test/fixtures/parser/literal/test262/not-categorized.json index 7674f27..75600ff 100644 --- a/test/fixtures/parser/literal/test262/not-categorized.json +++ b/test/fixtures/parser/literal/test262/not-categorized.json @@ -664,6 +664,7 @@ "end": 25, "raw": "\\10", "ref": 10, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -673,6 +674,7 @@ "end": 27, "raw": "\\9", "ref": 9, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -682,6 +684,7 @@ "end": 29, "raw": "\\8", "ref": 8, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -691,6 +694,7 @@ "end": 31, "raw": "\\7", "ref": 7, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -700,6 +704,7 @@ "end": 33, "raw": "\\6", "ref": 6, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -709,6 +714,7 @@ "end": 35, "raw": "\\5", "ref": 5, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -718,6 +724,7 @@ "end": 37, "raw": "\\4", "ref": 4, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -727,6 +734,7 @@ "end": 39, "raw": "\\3", "ref": 3, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -736,6 +744,7 @@ "end": 41, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0" }, { @@ -745,6 +754,7 @@ "end": 43, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -1024,6 +1034,7 @@ "end": 24, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" }, { @@ -1033,6 +1044,7 @@ "end": 26, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0" }, { @@ -1042,6 +1054,7 @@ "end": 28, "raw": "\\3", "ref": 3, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -1051,6 +1064,7 @@ "end": 30, "raw": "\\4", "ref": 4, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -1060,6 +1074,7 @@ "end": 32, "raw": "\\5", "ref": 5, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -1069,6 +1084,7 @@ "end": 34, "raw": "\\6", "ref": 6, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -1078,6 +1094,7 @@ "end": 36, "raw": "\\7", "ref": 7, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -1087,6 +1104,7 @@ "end": 38, "raw": "\\8", "ref": 8, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -1096,6 +1114,7 @@ "end": 40, "raw": "\\9", "ref": 9, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" }, { @@ -1105,6 +1124,7 @@ "end": 43, "raw": "\\10", "ref": 10, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0/alternatives/0/elements/0" } ] @@ -1997,6 +2017,7 @@ "end": 30, "raw": "\\9", "ref": 9, + "ambiguous": false, "resolved": "♻️../8" }, { @@ -2006,6 +2027,7 @@ "end": 32, "raw": "\\9", "ref": 9, + "ambiguous": false, "resolved": "♻️../8" } ] @@ -2284,6 +2306,7 @@ "end": 27, "raw": "\\8", "ref": 8, + "ambiguous": false, "resolved": "♻️../7" }, { @@ -2293,6 +2316,7 @@ "end": 29, "raw": "\\8", "ref": 8, + "ambiguous": false, "resolved": "♻️../7" } ] @@ -2493,6 +2517,7 @@ "end": 6, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -2655,6 +2680,7 @@ "end": 17, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../0" }, { @@ -2676,6 +2702,7 @@ "end": 21, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../2/alternatives/0/elements/0" }, { @@ -2823,6 +2850,7 @@ "end": 9, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -3018,6 +3046,7 @@ "end": 11, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -3347,6 +3376,7 @@ "end": 13, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0/element" } ] @@ -3944,6 +3974,7 @@ "end": 14, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0" } ] @@ -4151,6 +4182,7 @@ "end": 6, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" }, { @@ -4190,6 +4222,7 @@ "end": 11, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../2" } ] @@ -4271,6 +4304,7 @@ "end": 6, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -5643,6 +5677,7 @@ "end": 25, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -6270,6 +6305,7 @@ "end": 17, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" }, { @@ -6279,6 +6315,7 @@ "end": 19, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../1" } ] @@ -7087,6 +7124,7 @@ "end": 21, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/1" }, { @@ -7096,6 +7134,7 @@ "end": 23, "raw": "\\5", "ref": 5, + "ambiguous": false, "resolved": "♻️../1/alternatives/0/elements/1" } ] @@ -7400,6 +7439,7 @@ "end": 8, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../0" } } @@ -7508,6 +7548,7 @@ "end": 9, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -7621,6 +7662,7 @@ "end": 10, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -20455,6 +20497,7 @@ "end": 3, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -20524,6 +20567,7 @@ "end": 11, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../2" } ] @@ -20575,6 +20619,7 @@ "end": 3, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -22839,6 +22884,7 @@ "end": 11, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -29464,6 +29510,7 @@ "end": 9, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -29481,6 +29528,7 @@ "end": 12, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -29498,6 +29546,7 @@ "end": 15, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" } ] diff --git a/test/fixtures/parser/literal/test262/regexp-duplicate-named-groups-and-regexp-match-indices.json b/test/fixtures/parser/literal/test262/regexp-duplicate-named-groups-and-regexp-match-indices.json index 81e9e1d..44383fd 100644 --- a/test/fixtures/parser/literal/test262/regexp-duplicate-named-groups-and-regexp-match-indices.json +++ b/test/fixtures/parser/literal/test262/regexp-duplicate-named-groups-and-regexp-match-indices.json @@ -6,21 +6,533 @@ "options": {}, "patterns": { "/(?:(?:(?a)|(?b)|c)\\k){2}/d": { - "error": { - "message": "Invalid regular expression: /(?:(?:(?a)|(?b)|c)\\k){2}/d: Duplicate capture group name", - "index": 20 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 36, + "raw": "/(?:(?:(?a)|(?b)|c)\\k){2}/d", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 34, + "raw": "(?:(?:(?a)|(?b)|c)\\k){2}", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 34, + "raw": "(?:(?:(?a)|(?b)|c)\\k){2}", + "elements": [ + { + "type": "Quantifier", + "parent": "♻️../..", + "start": 1, + "end": 34, + "raw": "(?:(?:(?a)|(?b)|c)\\k){2}", + "min": 2, + "max": 2, + "greedy": true, + "element": { + "type": "Group", + "parent": "♻️..", + "start": 1, + "end": 31, + "raw": "(?:(?:(?a)|(?b)|c)\\k)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 4, + "end": 30, + "raw": "(?:(?a)|(?b)|c)\\k", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 4, + "end": 25, + "raw": "(?:(?a)|(?b)|c)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 7, + "end": 14, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 7, + "end": 14, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [ + "♻️../../../../../1" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 15, + "end": 22, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 15, + "end": 22, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 20, + "end": 21, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 20, + "end": 21, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [ + "♻️../../../../../1" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 23, + "end": 24, + "raw": "c", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 23, + "end": 24, + "raw": "c", + "value": 99 + } + ] + } + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 25, + "end": 30, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../0/alternatives/0/elements/0", + "♻️../0/alternatives/1/elements/0" + ] + } + ] + } + ] + } + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 35, + "end": 36, + "raw": "d", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": true, + "unicodeSets": false + } } }, "/(?:(?a)|(?a)(?b))(?:(?c)|(?d))/d": { - "error": { - "message": "Invalid regular expression: /(?:(?a)|(?a)(?b))(?:(?c)|(?d))/d: Duplicate capture group name", - "index": 24 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 48, + "raw": "/(?:(?a)|(?a)(?b))(?:(?c)|(?d))/d", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 46, + "raw": "(?:(?a)|(?a)(?b))(?:(?c)|(?d))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 46, + "raw": "(?:(?a)|(?a)(?b))(?:(?c)|(?d))", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 1, + "end": 27, + "raw": "(?:(?a)|(?a)(?b))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 4, + "end": 11, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 4, + "end": 11, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 10, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 9, + "end": 10, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 12, + "end": 26, + "raw": "(?a)(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 12, + "end": 19, + "raw": "(?a)", + "name": "y", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 17, + "end": 18, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 17, + "end": 18, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + }, + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 19, + "end": 26, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 24, + "end": 25, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 24, + "end": 25, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + { + "type": "Group", + "parent": "♻️../..", + "start": 27, + "end": 46, + "raw": "(?:(?c)|(?d))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 30, + "end": 37, + "raw": "(?c)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 30, + "end": 37, + "raw": "(?c)", + "name": "z", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 35, + "end": 36, + "raw": "c", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 35, + "end": 36, + "raw": "c", + "value": 99 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 38, + "end": 45, + "raw": "(?d)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 38, + "end": 45, + "raw": "(?d)", + "name": "z", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 43, + "end": 44, + "raw": "d", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 43, + "end": 44, + "raw": "d", + "value": 100 + } + ] + } + ], + "references": [] + } + ] + } + ] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 47, + "end": 48, + "raw": "d", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": true, + "unicodeSets": false + } } }, "/(?a)|(?b)/d": { - "error": { - "message": "Invalid regular expression: /(?a)|(?b)/d: Duplicate capture group name", - "index": 14 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 18, + "raw": "/(?a)|(?b)/d", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 16, + "raw": "(?a)|(?b)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 17, + "end": 18, + "raw": "d", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": true, + "unicodeSets": false + } } } } diff --git a/test/fixtures/parser/literal/test262/regexp-duplicate-named-groups.json b/test/fixtures/parser/literal/test262/regexp-duplicate-named-groups.json index ed7b5e0..1bafeb6 100644 --- a/test/fixtures/parser/literal/test262/regexp-duplicate-named-groups.json +++ b/test/fixtures/parser/literal/test262/regexp-duplicate-named-groups.json @@ -9,27 +9,738 @@ "options": {}, "patterns": { "/(?:(?:(?a)|(?b))\\k){2}/": { - "error": { - "message": "Invalid regular expression: /(?:(?:(?a)|(?b))\\k){2}/: Duplicate capture group name", - "index": 20 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 33, + "raw": "/(?:(?:(?a)|(?b))\\k){2}/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 32, + "raw": "(?:(?:(?a)|(?b))\\k){2}", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 32, + "raw": "(?:(?:(?a)|(?b))\\k){2}", + "elements": [ + { + "type": "Quantifier", + "parent": "♻️../..", + "start": 1, + "end": 32, + "raw": "(?:(?:(?a)|(?b))\\k){2}", + "min": 2, + "max": 2, + "greedy": true, + "element": { + "type": "Group", + "parent": "♻️..", + "start": 1, + "end": 29, + "raw": "(?:(?:(?a)|(?b))\\k)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 4, + "end": 28, + "raw": "(?:(?a)|(?b))\\k", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 4, + "end": 23, + "raw": "(?:(?a)|(?b))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 7, + "end": 14, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 7, + "end": 14, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [ + "♻️../../../../../1" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 15, + "end": 22, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 15, + "end": 22, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 20, + "end": 21, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 20, + "end": 21, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [ + "♻️../../../../../1" + ] + } + ] + } + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 23, + "end": 28, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../0/alternatives/0/elements/0", + "♻️../0/alternatives/1/elements/0" + ] + } + ] + } + ] + } + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 33, + "end": 33, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } } }, "/(?:(?:(?a)|(?b)|c)\\k){2}/": { - "error": { - "message": "Invalid regular expression: /(?:(?:(?a)|(?b)|c)\\k){2}/: Duplicate capture group name", - "index": 20 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 35, + "raw": "/(?:(?:(?a)|(?b)|c)\\k){2}/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 34, + "raw": "(?:(?:(?a)|(?b)|c)\\k){2}", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 34, + "raw": "(?:(?:(?a)|(?b)|c)\\k){2}", + "elements": [ + { + "type": "Quantifier", + "parent": "♻️../..", + "start": 1, + "end": 34, + "raw": "(?:(?:(?a)|(?b)|c)\\k){2}", + "min": 2, + "max": 2, + "greedy": true, + "element": { + "type": "Group", + "parent": "♻️..", + "start": 1, + "end": 31, + "raw": "(?:(?:(?a)|(?b)|c)\\k)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 4, + "end": 30, + "raw": "(?:(?a)|(?b)|c)\\k", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 4, + "end": 25, + "raw": "(?:(?a)|(?b)|c)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 7, + "end": 14, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 7, + "end": 14, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 12, + "end": 13, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [ + "♻️../../../../../1" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 15, + "end": 22, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 15, + "end": 22, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 20, + "end": 21, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 20, + "end": 21, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [ + "♻️../../../../../1" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 23, + "end": 24, + "raw": "c", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 23, + "end": 24, + "raw": "c", + "value": 99 + } + ] + } + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 25, + "end": 30, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../0/alternatives/0/elements/0", + "♻️../0/alternatives/1/elements/0" + ] + } + ] + } + ] + } + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 35, + "end": 35, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } } }, "/(?:(?a)|(?b))\\k/": { - "error": { - "message": "Invalid regular expression: /(?:(?a)|(?b))\\k/: Duplicate capture group name", - "index": 17 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 26, + "raw": "/(?:(?a)|(?b))\\k/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 25, + "raw": "(?:(?a)|(?b))\\k", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 25, + "raw": "(?:(?a)|(?b))\\k", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 1, + "end": 20, + "raw": "(?:(?a)|(?b))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 4, + "end": 11, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 4, + "end": 11, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 10, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 9, + "end": 10, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [ + "♻️../../../../../1" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 12, + "end": 19, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 12, + "end": 19, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 17, + "end": 18, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 17, + "end": 18, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [ + "♻️../../../../../1" + ] + } + ] + } + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 20, + "end": 25, + "raw": "\\k", + "ref": "x", + "ambiguous": true, + "resolved": [ + "♻️../0/alternatives/0/elements/0", + "♻️../0/alternatives/1/elements/0" + ] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 26, + "end": 26, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } } }, "/(?:(?a)|(?a)(?b))(?:(?c)|(?d))/": { - "error": { - "message": "Invalid regular expression: /(?:(?a)|(?a)(?b))(?:(?c)|(?d))/: Duplicate capture group name", - "index": 24 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 47, + "raw": "/(?:(?a)|(?a)(?b))(?:(?c)|(?d))/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 46, + "raw": "(?:(?a)|(?a)(?b))(?:(?c)|(?d))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 46, + "raw": "(?:(?a)|(?a)(?b))(?:(?c)|(?d))", + "elements": [ + { + "type": "Group", + "parent": "♻️../..", + "start": 1, + "end": 27, + "raw": "(?:(?a)|(?a)(?b))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 4, + "end": 11, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 4, + "end": 11, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 10, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 9, + "end": 10, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 12, + "end": 26, + "raw": "(?a)(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 12, + "end": 19, + "raw": "(?a)", + "name": "y", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 17, + "end": 18, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 17, + "end": 18, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + }, + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 19, + "end": 26, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 24, + "end": 25, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 24, + "end": 25, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + { + "type": "Group", + "parent": "♻️../..", + "start": 27, + "end": 46, + "raw": "(?:(?c)|(?d))", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 30, + "end": 37, + "raw": "(?c)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 30, + "end": 37, + "raw": "(?c)", + "name": "z", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 35, + "end": 36, + "raw": "c", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 35, + "end": 36, + "raw": "c", + "value": 99 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 38, + "end": 45, + "raw": "(?d)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 38, + "end": 45, + "raw": "(?d)", + "name": "z", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 43, + "end": 44, + "raw": "d", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 43, + "end": 44, + "raw": "d", + "value": 100 + } + ] + } + ], + "references": [] + } + ] + } + ] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 47, + "end": 47, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } } }, "/(?x)|(?:zy\\k)/": { @@ -129,6 +840,7 @@ "end": 19, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../../../../../../../0/elements/0" } ] @@ -157,70 +869,631 @@ } }, "/(?a)|(?b)/": { - "error": { - "message": "Invalid regular expression: /(?a)|(?b)/: Duplicate capture group name", - "index": 14 - } - }, - "/(?a)|(?b)/g": { - "error": { - "message": "Invalid regular expression: /(?a)|(?b)/g: Duplicate capture group name", - "index": 14 - } - }, - "/(?b)|(?a)/": { - "error": { - "message": "Invalid regular expression: /(?b)|(?a)/: Duplicate capture group name", - "index": 14 - } - }, - "/(?b)|(?a)/g": { - "error": { - "message": "Invalid regular expression: /(?b)|(?a)/g: Duplicate capture group name", - "index": 14 - } - }, - "/(?a)(?a)|(?b)(?b)/": { - "error": { - "message": "Invalid regular expression: /(?a)(?a)|(?b)(?b)/: Duplicate capture group name", - "index": 21 - } - }, - "/[ab]/": { "ast": { "type": "RegExpLiteral", "parent": null, "start": 0, - "end": 6, - "raw": "/[ab]/", + "end": 17, + "raw": "/(?a)|(?b)/", "pattern": { "type": "Pattern", "parent": "♻️..", "start": 1, - "end": 5, - "raw": "[ab]", + "end": 16, + "raw": "(?a)|(?b)", "alternatives": [ { "type": "Alternative", "parent": "♻️../..", "start": 1, - "end": 5, - "raw": "[ab]", + "end": 8, + "raw": "(?a)", "elements": [ { - "type": "CharacterClass", + "type": "CapturingGroup", "parent": "♻️../..", "start": 1, - "end": 5, - "raw": "[ab]", - "unicodeSets": false, - "negate": false, - "elements": [ + "end": 8, + "raw": "(?a)", + "name": "x", + "alternatives": [ { - "type": "Character", + "type": "Alternative", "parent": "♻️../..", - "start": 2, - "end": 3, + "start": 6, + "end": 7, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 17, + "end": 17, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } + } + }, + "/(?a)|(?b)/g": { + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 18, + "raw": "/(?a)|(?b)/g", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 16, + "raw": "(?a)|(?b)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 17, + "end": 18, + "raw": "g", + "global": true, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } + } + }, + "/(?b)|(?a)/": { + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 17, + "raw": "/(?b)|(?a)/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 16, + "raw": "(?b)|(?a)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 17, + "end": 17, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } + } + }, + "/(?b)|(?a)/g": { + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 18, + "raw": "/(?b)|(?a)/g", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 16, + "raw": "(?b)|(?a)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 9, + "end": 16, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 14, + "end": 15, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 17, + "end": 18, + "raw": "g", + "global": true, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } + } + }, + "/(?a)(?a)|(?b)(?b)/": { + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 31, + "raw": "/(?a)(?a)|(?b)(?b)/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 30, + "raw": "(?a)(?a)|(?b)(?b)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 15, + "raw": "(?a)(?a)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 1, + "end": 8, + "raw": "(?a)", + "name": "y", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 6, + "end": 7, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + }, + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 8, + "end": 15, + "raw": "(?a)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 13, + "end": 14, + "raw": "a", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 13, + "end": 14, + "raw": "a", + "value": 97 + } + ] + } + ], + "references": [] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 16, + "end": 30, + "raw": "(?b)(?b)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 16, + "end": 23, + "raw": "(?b)", + "name": "x", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 21, + "end": 22, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 21, + "end": 22, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + }, + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 23, + "end": 30, + "raw": "(?b)", + "name": "y", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 28, + "end": 29, + "raw": "b", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 28, + "end": 29, + "raw": "b", + "value": 98 + } + ] + } + ], + "references": [] + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 31, + "end": 31, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } + } + }, + "/[ab]/": { + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 6, + "raw": "/[ab]/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 5, + "raw": "[ab]", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 5, + "raw": "[ab]", + "elements": [ + { + "type": "CharacterClass", + "parent": "♻️../..", + "start": 1, + "end": 5, + "raw": "[ab]", + "unicodeSets": false, + "negate": false, + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 2, + "end": 3, "raw": "a", "value": 97 }, @@ -256,15 +1529,363 @@ } }, "/^(?:(?x)|(?y)|z)\\k$/": { - "error": { - "message": "Invalid regular expression: /^(?:(?x)|(?y)|z)\\k$/: Duplicate capture group name", - "index": 18 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 30, + "raw": "/^(?:(?x)|(?y)|z)\\k$/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 29, + "raw": "^(?:(?x)|(?y)|z)\\k$", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 29, + "raw": "^(?:(?x)|(?y)|z)\\k$", + "elements": [ + { + "type": "Assertion", + "parent": "♻️../..", + "start": 1, + "end": 2, + "raw": "^", + "kind": "start" + }, + { + "type": "Group", + "parent": "♻️../..", + "start": 2, + "end": 23, + "raw": "(?:(?x)|(?y)|z)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 5, + "end": 12, + "raw": "(?x)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 5, + "end": 12, + "raw": "(?x)", + "name": "a", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 10, + "end": 11, + "raw": "x", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 10, + "end": 11, + "raw": "x", + "value": 120 + } + ] + } + ], + "references": [ + "♻️../../../../../2" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 13, + "end": 20, + "raw": "(?y)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 13, + "end": 20, + "raw": "(?y)", + "name": "a", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 18, + "end": 19, + "raw": "y", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 18, + "end": 19, + "raw": "y", + "value": 121 + } + ] + } + ], + "references": [ + "♻️../../../../../2" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 21, + "end": 22, + "raw": "z", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 21, + "end": 22, + "raw": "z", + "value": 122 + } + ] + } + ] + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 23, + "end": 28, + "raw": "\\k", + "ref": "a", + "ambiguous": true, + "resolved": [ + "♻️../1/alternatives/0/elements/0", + "♻️../1/alternatives/1/elements/0" + ] + }, + { + "type": "Assertion", + "parent": "♻️../..", + "start": 28, + "end": 29, + "raw": "$", + "kind": "end" + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 30, + "end": 30, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } } }, "/^(?:(?x)|(?y)|z){2}\\k$/": { - "error": { - "message": "Invalid regular expression: /^(?:(?x)|(?y)|z){2}\\k$/: Duplicate capture group name", - "index": 18 + "ast": { + "type": "RegExpLiteral", + "parent": null, + "start": 0, + "end": 33, + "raw": "/^(?:(?x)|(?y)|z){2}\\k$/", + "pattern": { + "type": "Pattern", + "parent": "♻️..", + "start": 1, + "end": 32, + "raw": "^(?:(?x)|(?y)|z){2}\\k$", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 1, + "end": 32, + "raw": "^(?:(?x)|(?y)|z){2}\\k$", + "elements": [ + { + "type": "Assertion", + "parent": "♻️../..", + "start": 1, + "end": 2, + "raw": "^", + "kind": "start" + }, + { + "type": "Quantifier", + "parent": "♻️../..", + "start": 2, + "end": 26, + "raw": "(?:(?x)|(?y)|z){2}", + "min": 2, + "max": 2, + "greedy": true, + "element": { + "type": "Group", + "parent": "♻️..", + "start": 2, + "end": 23, + "raw": "(?:(?x)|(?y)|z)", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 5, + "end": 12, + "raw": "(?x)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 5, + "end": 12, + "raw": "(?x)", + "name": "a", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 10, + "end": 11, + "raw": "x", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 10, + "end": 11, + "raw": "x", + "value": 120 + } + ] + } + ], + "references": [ + "♻️../../../../../../2" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 13, + "end": 20, + "raw": "(?y)", + "elements": [ + { + "type": "CapturingGroup", + "parent": "♻️../..", + "start": 13, + "end": 20, + "raw": "(?y)", + "name": "a", + "alternatives": [ + { + "type": "Alternative", + "parent": "♻️../..", + "start": 18, + "end": 19, + "raw": "y", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 18, + "end": 19, + "raw": "y", + "value": 121 + } + ] + } + ], + "references": [ + "♻️../../../../../../2" + ] + } + ] + }, + { + "type": "Alternative", + "parent": "♻️../..", + "start": 21, + "end": 22, + "raw": "z", + "elements": [ + { + "type": "Character", + "parent": "♻️../..", + "start": 21, + "end": 22, + "raw": "z", + "value": 122 + } + ] + } + ] + } + }, + { + "type": "Backreference", + "parent": "♻️../..", + "start": 26, + "end": 31, + "raw": "\\k", + "ref": "a", + "ambiguous": true, + "resolved": [ + "♻️../1/element/alternatives/0/elements/0", + "♻️../1/element/alternatives/1/elements/0" + ] + }, + { + "type": "Assertion", + "parent": "♻️../..", + "start": 31, + "end": 32, + "raw": "$", + "kind": "end" + } + ] + } + ] + }, + "flags": { + "type": "Flags", + "parent": "♻️..", + "start": 33, + "end": 33, + "raw": "", + "global": false, + "ignoreCase": false, + "multiline": false, + "unicode": false, + "sticky": false, + "dotAll": false, + "hasIndices": false, + "unicodeSets": false + } } } } diff --git a/test/fixtures/parser/literal/test262/regexp-lookbehind.json b/test/fixtures/parser/literal/test262/regexp-lookbehind.json index a6bc9f9..0cfaf0d 100644 --- a/test/fixtures/parser/literal/test262/regexp-lookbehind.json +++ b/test/fixtures/parser/literal/test262/regexp-lookbehind.json @@ -431,6 +431,7 @@ "end": 15, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" }, { @@ -440,6 +441,7 @@ "end": 17, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../../../../../0/alternatives/0/elements/0" }, { @@ -449,6 +451,7 @@ "end": 19, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -566,6 +569,7 @@ "end": 11, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../../../../../0" }, { @@ -575,6 +579,7 @@ "end": 13, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../../../../../0" } ] @@ -697,6 +702,7 @@ "end": 11, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../../../../../0" }, { @@ -706,6 +712,7 @@ "end": 13, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../../../../../0" } ] @@ -814,6 +821,7 @@ "end": 10, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" }, { @@ -823,6 +831,7 @@ "end": 12, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" }, { @@ -832,6 +841,7 @@ "end": 14, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -943,6 +953,7 @@ "end": 11, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" }, { @@ -952,6 +963,7 @@ "end": 13, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" }, { @@ -961,6 +973,7 @@ "end": 15, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -3042,6 +3055,7 @@ "end": 19, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0/alternatives/0/elements/0" } ] @@ -3127,6 +3141,7 @@ "end": 10, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../1" }, { @@ -3270,6 +3285,7 @@ "end": 10, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../1" } ] @@ -3677,6 +3693,7 @@ "end": 17, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0/alternatives/0/elements/0" } ] @@ -4054,6 +4071,7 @@ "end": 12, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -5047,6 +5065,7 @@ "end": 7, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -5183,6 +5202,7 @@ "end": 7, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -5293,6 +5313,7 @@ "end": 7, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -7035,6 +7056,7 @@ "end": 10, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../../../../../3" } ] @@ -7074,6 +7096,7 @@ "end": 15, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../1" } ] @@ -7837,6 +7860,7 @@ "end": 9, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../../../../../3" } ] @@ -7892,6 +7916,7 @@ "end": 16, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../1" } ] @@ -9441,6 +9466,7 @@ "end": 16, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../../../../../0/alternatives/0/elements/0" } ] @@ -9623,6 +9649,7 @@ "end": 20, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0/alternatives/0/elements/0" } ] @@ -9848,6 +9875,7 @@ "end": 27, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0/alternatives/0/elements/0" } ] @@ -10081,6 +10109,7 @@ "end": 27, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0/alternatives/0/elements/0" } ] @@ -10223,6 +10252,7 @@ "end": 15, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" }, { @@ -10232,6 +10262,7 @@ "end": 17, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../../../../../0/alternatives/0/elements/1" }, { @@ -10241,6 +10272,7 @@ "end": 19, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -10335,6 +10367,7 @@ "end": 7, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../.." } ] @@ -10432,6 +10465,7 @@ "end": 7, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../.." } ] @@ -11719,6 +11753,7 @@ "end": 14, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../1" }, { @@ -11878,6 +11913,7 @@ "end": 14, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../1" }, { @@ -12037,6 +12073,7 @@ "end": 14, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../1" }, { diff --git a/test/fixtures/parser/literal/test262/regexp-match-indices-and-regexp-named-groups.json b/test/fixtures/parser/literal/test262/regexp-match-indices-and-regexp-named-groups.json index ceeba4c..32f9930 100644 --- a/test/fixtures/parser/literal/test262/regexp-match-indices-and-regexp-named-groups.json +++ b/test/fixtures/parser/literal/test262/regexp-match-indices-and-regexp-named-groups.json @@ -617,6 +617,7 @@ "end": 27, "raw": "\\k", "ref": "c", + "ambiguous": false, "resolved": "♻️../2" }, { @@ -626,6 +627,7 @@ "end": 32, "raw": "\\k", "ref": "b", + "ambiguous": false, "resolved": "♻️../1" }, { @@ -635,6 +637,7 @@ "end": 37, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -776,6 +779,7 @@ "end": 27, "raw": "\\k", "ref": "c", + "ambiguous": false, "resolved": "♻️../2" }, { @@ -785,6 +789,7 @@ "end": 32, "raw": "\\k", "ref": "b", + "ambiguous": false, "resolved": "♻️../1" }, { @@ -794,6 +799,7 @@ "end": 37, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] diff --git a/test/fixtures/parser/literal/test262/regexp-named-groups.json b/test/fixtures/parser/literal/test262/regexp-named-groups.json index 001ecda..5e03c4b 100644 --- a/test/fixtures/parser/literal/test262/regexp-named-groups.json +++ b/test/fixtures/parser/literal/test262/regexp-named-groups.json @@ -169,6 +169,7 @@ "end": 18, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -198,6 +199,7 @@ "end": 22, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../../../../../1" } ] @@ -329,6 +331,7 @@ "end": 18, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -358,6 +361,7 @@ "end": 22, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../../../../../1" } ] @@ -474,6 +478,7 @@ "end": 13, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" }, { @@ -483,6 +488,7 @@ "end": 15, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../1" } ] @@ -594,6 +600,7 @@ "end": 13, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" }, { @@ -603,6 +610,7 @@ "end": 15, "raw": "\\2", "ref": 2, + "ambiguous": false, "resolved": "♻️../1" } ] @@ -3624,6 +3632,7 @@ "end": 27, "raw": "\\k", "ref": "c", + "ambiguous": false, "resolved": "♻️../2" }, { @@ -3633,6 +3642,7 @@ "end": 32, "raw": "\\k", "ref": "b", + "ambiguous": false, "resolved": "♻️../1" }, { @@ -3642,6 +3652,7 @@ "end": 37, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -3783,6 +3794,7 @@ "end": 27, "raw": "\\k", "ref": "c", + "ambiguous": false, "resolved": "♻️../2" }, { @@ -3792,6 +3804,7 @@ "end": 32, "raw": "\\k", "ref": "b", + "ambiguous": false, "resolved": "♻️../1" }, { @@ -3801,6 +3814,7 @@ "end": 37, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -3991,6 +4005,7 @@ "end": 11, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../../../.." }, { @@ -4089,6 +4104,7 @@ "end": 11, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../../../.." }, { @@ -4638,6 +4654,7 @@ "end": 20, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -4747,6 +4764,7 @@ "end": 20, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -4856,6 +4874,7 @@ "end": 20, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -5002,6 +5021,7 @@ "end": 20, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -5857,6 +5877,7 @@ "end": 14, "raw": "\\k", "ref": "b", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -5946,6 +5967,7 @@ "end": 14, "raw": "\\k", "ref": "b", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -6035,6 +6057,7 @@ "end": 11, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -6124,6 +6147,7 @@ "end": 11, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../0" } ] @@ -6205,6 +6229,7 @@ "end": 13, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../2" }, { @@ -6244,6 +6269,7 @@ "end": 25, "raw": "\\k", "ref": "b", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -6325,6 +6351,7 @@ "end": 13, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../2" }, { @@ -6364,6 +6391,7 @@ "end": 25, "raw": "\\k", "ref": "b", + "ambiguous": false, "resolved": "♻️../0" } ] @@ -6514,6 +6542,7 @@ "end": 25, "raw": "\\k", "ref": "dog", + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -6669,6 +6698,7 @@ "end": 25, "raw": "\\k", "ref": "dog", + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -8207,6 +8237,7 @@ "end": 21, "raw": "\\k<狗>", "ref": "狗", + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -8362,6 +8393,7 @@ "end": 21, "raw": "\\k<狗>", "ref": "狗", + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -9325,6 +9357,7 @@ "end": 31, "raw": "\\k<𝓓𝓸𝓰>", "ref": "𝓓𝓸𝓰", + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -9480,6 +9513,7 @@ "end": 31, "raw": "\\k<𝓓𝓸𝓰>", "ref": "𝓓𝓸𝓰", + "ambiguous": false, "resolved": "♻️../../../../../0" } ] @@ -12494,6 +12528,7 @@ "end": 3, "raw": "\\1", "ref": 1, + "ambiguous": false, "resolved": "♻️../1" }, { @@ -12903,6 +12938,7 @@ "end": 6, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../1" }, { @@ -12952,6 +12988,7 @@ "end": 20, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../1" } ] @@ -13003,6 +13040,7 @@ "end": 6, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../1" }, { @@ -13052,6 +13090,7 @@ "end": 20, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../1" } ] @@ -13103,6 +13142,7 @@ "end": 6, "raw": "\\k", "ref": "a", + "ambiguous": false, "resolved": "♻️../1" }, {