Skip to content

Commit

Permalink
fix: error in expression with nested expression (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi authored Sep 25, 2023
1 parent 97c3ce6 commit 33e8203
Show file tree
Hide file tree
Showing 3 changed files with 593 additions and 11 deletions.
24 changes: 13 additions & 11 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ class RegExpParserState {

private _node: AppendableNode = DUMMY_PATTERN

private _expressionBuffer: ClassIntersection | ClassSubtraction | null =
null
private _expressionBufferMap = new Map<
CharacterClass | ExpressionCharacterClass,
ClassIntersection | ClassSubtraction
>()

private _flags: Flags = DUMMY_FLAGS

Expand Down Expand Up @@ -538,16 +540,14 @@ class RegExpParserState {
node.raw = this.source.slice(start, end)
this._node = parent

const expression = this._expressionBuffer
if (
expression?.parent !== (node as unknown as ExpressionCharacterClass)
) {
const expression = this._expressionBufferMap.get(node)
if (!expression) {
return
}
if (node.elements.length > 0) {
throw new Error("UnknownError")
}
this._expressionBuffer = null
this._expressionBufferMap.delete(node)

// Replace with ExpressionCharacterClass.
const newNode: ExpressionCharacterClass = {
Expand Down Expand Up @@ -614,7 +614,8 @@ class RegExpParserState {
}
// Replace the last two elements.
const right = parent.elements.pop()
const left = this._expressionBuffer ?? parent.elements.pop()
const left =
this._expressionBufferMap.get(parent) ?? parent.elements.pop()
if (
!left ||
!right ||
Expand All @@ -637,7 +638,7 @@ class RegExpParserState {
}
left.parent = node
right.parent = node
this._expressionBuffer = node
this._expressionBufferMap.set(parent, node)
}

public onClassSubtraction(start: number, end: number): void {
Expand All @@ -647,7 +648,8 @@ class RegExpParserState {
}
// Replace the last two elements.
const right = parent.elements.pop()
const left = this._expressionBuffer ?? parent.elements.pop()
const left =
this._expressionBufferMap.get(parent) ?? parent.elements.pop()
if (
!left ||
!right ||
Expand All @@ -670,7 +672,7 @@ class RegExpParserState {
}
left.parent = node
right.parent = node
this._expressionBuffer = node
this._expressionBufferMap.set(parent, node)
}

public onClassStringDisjunctionEnter(start: number): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2331,6 +2331,296 @@
"unicodeSets": true
}
}
},
"/[a&&b&&[c&&d&&e]]/v": {
"ast": {
"type": "RegExpLiteral",
"parent": null,
"start": 0,
"end": 20,
"raw": "/[a&&b&&[c&&d&&e]]/v",
"pattern": {
"type": "Pattern",
"parent": "♻️..",
"start": 1,
"end": 18,
"raw": "[a&&b&&[c&&d&&e]]",
"alternatives": [
{
"type": "Alternative",
"parent": "♻️../..",
"start": 1,
"end": 18,
"raw": "[a&&b&&[c&&d&&e]]",
"elements": [
{
"type": "ExpressionCharacterClass",
"parent": "♻️../..",
"start": 1,
"end": 18,
"raw": "[a&&b&&[c&&d&&e]]",
"negate": false,
"expression": {
"type": "ClassIntersection",
"parent": "♻️..",
"start": 2,
"end": 17,
"raw": "a&&b&&[c&&d&&e]",
"left": {
"type": "ClassIntersection",
"parent": "♻️..",
"start": 2,
"end": 6,
"raw": "a&&b",
"left": {
"type": "Character",
"parent": "♻️..",
"start": 2,
"end": 3,
"raw": "a",
"value": 97
},
"right": {
"type": "Character",
"parent": "♻️..",
"start": 5,
"end": 6,
"raw": "b",
"value": 98
}
},
"right": {
"type": "ExpressionCharacterClass",
"parent": "♻️..",
"start": 8,
"end": 17,
"raw": "[c&&d&&e]",
"negate": false,
"expression": {
"type": "ClassIntersection",
"parent": "♻️..",
"start": 9,
"end": 16,
"raw": "c&&d&&e",
"left": {
"type": "ClassIntersection",
"parent": "♻️..",
"start": 9,
"end": 13,
"raw": "c&&d",
"left": {
"type": "Character",
"parent": "♻️..",
"start": 9,
"end": 10,
"raw": "c",
"value": 99
},
"right": {
"type": "Character",
"parent": "♻️..",
"start": 12,
"end": 13,
"raw": "d",
"value": 100
}
},
"right": {
"type": "Character",
"parent": "♻️..",
"start": 15,
"end": 16,
"raw": "e",
"value": 101
}
}
}
}
}
]
}
]
},
"flags": {
"type": "Flags",
"parent": "♻️..",
"start": 19,
"end": 20,
"raw": "v",
"global": false,
"ignoreCase": false,
"multiline": false,
"unicode": false,
"sticky": false,
"dotAll": false,
"hasIndices": false,
"unicodeSets": true
}
}
},
"/[a&&b&&[c--d--[e&&f&&g]]]/v": {
"ast": {
"type": "RegExpLiteral",
"parent": null,
"start": 0,
"end": 28,
"raw": "/[a&&b&&[c--d--[e&&f&&g]]]/v",
"pattern": {
"type": "Pattern",
"parent": "♻️..",
"start": 1,
"end": 26,
"raw": "[a&&b&&[c--d--[e&&f&&g]]]",
"alternatives": [
{
"type": "Alternative",
"parent": "♻️../..",
"start": 1,
"end": 26,
"raw": "[a&&b&&[c--d--[e&&f&&g]]]",
"elements": [
{
"type": "ExpressionCharacterClass",
"parent": "♻️../..",
"start": 1,
"end": 26,
"raw": "[a&&b&&[c--d--[e&&f&&g]]]",
"negate": false,
"expression": {
"type": "ClassIntersection",
"parent": "♻️..",
"start": 2,
"end": 25,
"raw": "a&&b&&[c--d--[e&&f&&g]]",
"left": {
"type": "ClassIntersection",
"parent": "♻️..",
"start": 2,
"end": 6,
"raw": "a&&b",
"left": {
"type": "Character",
"parent": "♻️..",
"start": 2,
"end": 3,
"raw": "a",
"value": 97
},
"right": {
"type": "Character",
"parent": "♻️..",
"start": 5,
"end": 6,
"raw": "b",
"value": 98
}
},
"right": {
"type": "ExpressionCharacterClass",
"parent": "♻️..",
"start": 8,
"end": 25,
"raw": "[c--d--[e&&f&&g]]",
"negate": false,
"expression": {
"type": "ClassSubtraction",
"parent": "♻️..",
"start": 9,
"end": 24,
"raw": "c--d--[e&&f&&g]",
"left": {
"type": "ClassSubtraction",
"parent": "♻️..",
"start": 9,
"end": 13,
"raw": "c--d",
"left": {
"type": "Character",
"parent": "♻️..",
"start": 9,
"end": 10,
"raw": "c",
"value": 99
},
"right": {
"type": "Character",
"parent": "♻️..",
"start": 12,
"end": 13,
"raw": "d",
"value": 100
}
},
"right": {
"type": "ExpressionCharacterClass",
"parent": "♻️..",
"start": 15,
"end": 24,
"raw": "[e&&f&&g]",
"negate": false,
"expression": {
"type": "ClassIntersection",
"parent": "♻️..",
"start": 16,
"end": 23,
"raw": "e&&f&&g",
"left": {
"type": "ClassIntersection",
"parent": "♻️..",
"start": 16,
"end": 20,
"raw": "e&&f",
"left": {
"type": "Character",
"parent": "♻️..",
"start": 16,
"end": 17,
"raw": "e",
"value": 101
},
"right": {
"type": "Character",
"parent": "♻️..",
"start": 19,
"end": 20,
"raw": "f",
"value": 102
}
},
"right": {
"type": "Character",
"parent": "♻️..",
"start": 22,
"end": 23,
"raw": "g",
"value": 103
}
}
}
}
}
}
}
]
}
]
},
"flags": {
"type": "Flags",
"parent": "♻️..",
"start": 27,
"end": 28,
"raw": "v",
"global": false,
"ignoreCase": false,
"multiline": false,
"unicode": false,
"sticky": false,
"dotAll": false,
"hasIndices": false,
"unicodeSets": true
}
}
}
}
}
Loading

0 comments on commit 33e8203

Please sign in to comment.