summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/regexp_parse
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/regexp_parse')
-rw-r--r--js/src/jit-test/tests/regexp_parse/Assertion.js20
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom.js54
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js118
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js19
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js13
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js87
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js19
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js55
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom_Null.js7
-rw-r--r--js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js108
-rw-r--r--js/src/jit-test/tests/regexp_parse/Capture.js21
-rw-r--r--js/src/jit-test/tests/regexp_parse/CharacterClass.js74
-rw-r--r--js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js118
-rw-r--r--js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js13
-rw-r--r--js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js29
-rw-r--r--js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js35
-rw-r--r--js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js39
-rw-r--r--js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js9
-rw-r--r--js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js162
-rw-r--r--js/src/jit-test/tests/regexp_parse/Disjunction.js42
-rw-r--r--js/src/jit-test/tests/regexp_parse/Empty.js7
-rw-r--r--js/src/jit-test/tests/regexp_parse/Everything.js21
-rw-r--r--js/src/jit-test/tests/regexp_parse/Group.js15
-rw-r--r--js/src/jit-test/tests/regexp_parse/Lookahead.js31
-rw-r--r--js/src/jit-test/tests/regexp_parse/MatchOnly.js35
-rw-r--r--js/src/jit-test/tests/regexp_parse/Quantifier.js58
26 files changed, 1209 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/regexp_parse/Assertion.js b/js/src/jit-test/tests/regexp_parse/Assertion.js
new file mode 100644
index 000000000..774f43471
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Assertion.js
@@ -0,0 +1,20 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("^", no_multiline_flags,
+ Assertion("START_OF_INPUT"));
+test_mix("^", multiline_flags,
+ Assertion("START_OF_LINE"));
+
+test_mix("$", no_multiline_flags,
+ Assertion("END_OF_INPUT"));
+test_mix("$", multiline_flags,
+ Assertion("END_OF_LINE"));
+
+test_mix("\\b", all_flags,
+ Assertion("BOUNDARY"));
+
+test_mix("\\B", all_flags,
+ Assertion("NON_BOUNDARY"));
diff --git a/js/src/jit-test/tests/regexp_parse/Atom.js b/js/src/jit-test/tests/regexp_parse/Atom.js
new file mode 100644
index 000000000..c9c3ad52d
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom.js
@@ -0,0 +1,54 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("a", all_flags,
+ Atom("a"));
+test_mix("abc\u3042\u3044\u3046", all_flags,
+ Atom("abc\u3042\u3044\u3046"));
+
+// raw brace
+
+test("{", no_unicode_flags,
+ Atom("{"));
+test("{a", no_unicode_flags,
+ Atom("{a"));
+test("a{b", no_unicode_flags,
+ Atom("a{b"));
+
+test("}", no_unicode_flags,
+ Atom("}"));
+test("}a", no_unicode_flags,
+ Atom("}a"));
+test("a}b", no_unicode_flags,
+ Atom("a}b"));
+
+// raw surrogate pair
+
+test("X\uD83D\uDC38Y", unicode_flags,
+ Text([
+ Atom("X"),
+ Atom("\uD83D\uDC38"),
+ Atom("Y")
+ ]));
+
+test("X\uD83DY", unicode_flags,
+ Alternative([
+ Atom("X"),
+ Alternative([
+ Atom("\uD83D"),
+ NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]]))
+ ]),
+ Atom("Y")
+ ]));
+
+test("X\uDC38Y", unicode_flags,
+ Alternative([
+ Atom("X"),
+ Alternative([
+ Assertion("NOT_AFTER_LEAD_SURROGATE"),
+ Atom("\uDC38"),
+ ]),
+ Atom("Y")
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js b/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js
new file mode 100644
index 000000000..62bb736f8
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom_CharacterClassEscape.js
@@ -0,0 +1,118 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("\\d", all_flags,
+ CharacterClass([["0", "9"]]));
+
+test_mix("\\D", no_unicode_flags,
+ CharacterClass([
+ ["\u0000", "/"],
+ [":", "\uFFFF"]
+ ]));
+test_mix("\\D", unicode_flags,
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "/"],
+ [":", "\uD7FF"],
+ ["\uE000", "\uFFFF"]
+ ]));
+
+test_mix("\\s", all_flags,
+ CharacterClass([
+ ["\t", "\r"],
+ [" ", " "],
+ ["\u00A0", "\u00A0"],
+ ["\u1680", "\u1680"],
+ ["\u180E", "\u180E"],
+ ["\u2000", "\u200A"],
+ ["\u2028", "\u2029"],
+ ["\u202F", "\u202F"],
+ ["\u205F", "\u205F"],
+ ["\u3000", "\u3000"],
+ ["\uFEFF", "\uFEFF"]
+ ]));
+test_mix("\\S", no_unicode_flags,
+ CharacterClass([
+ ["\u0000", "\u0008"],
+ ["\u000E", "\u001F"],
+ ["!", "\u009F"],
+ ["\u00A1", "\u167F"],
+ ["\u1681", "\u180D"],
+ ["\u180F", "\u1FFF"],
+ ["\u200B", "\u2027"],
+ ["\u202A", "\u202E"],
+ ["\u2030", "\u205E"],
+ ["\u2060", "\u2FFF"],
+ ["\u3001", "\uFEFE"],
+ ["\uFF00", "\uFFFF"]
+ ]));
+test_mix("\\S", unicode_flags,
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "\u0008"],
+ ["\u000E", "\u001F"],
+ ["!", "\u009F"],
+ ["\u00A1", "\u167F"],
+ ["\u1681", "\u180D"],
+ ["\u180F", "\u1FFF"],
+ ["\u200B", "\u2027"],
+ ["\u202A", "\u202E"],
+ ["\u2030", "\u205E"],
+ ["\u2060", "\u2FFF"],
+ ["\u3001", "\uD7FF"],
+ ["\uE000", "\uFEFE"],
+ ["\uFF00", "\uFFFF"]
+ ]));
+
+test_mix("\\w", no_unicode_flags,
+ CharacterClass([
+ ["0", "9"],
+ ["A", "Z"],
+ ["_", "_"],
+ ["a", "z"]
+ ]));
+test_mix("\\w", ["u", "mu"],
+ CharacterClass([
+ ["0", "9"],
+ ["A", "Z"],
+ ["_", "_"],
+ ["a", "z"]
+ ]));
+test_mix("\\w", ["iu", "imu"],
+ CharacterClass([
+ ["0", "9"],
+ ["A", "Z"],
+ ["_", "_"],
+ ["a", "z"],
+ ["\u017F", "\u017F"],
+ ["\u212A", "\u212A"]
+ ]));
+
+test_mix("\\W", no_unicode_flags,
+ CharacterClass([
+ ["\u0000", "/"],
+ [":", "@"],
+ ["[", "^"],
+ ["`", "`"],
+ ["{", "\uFFFF"]
+ ]));
+test_mix("\\W", ["u", "mu"],
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "/"],
+ [":", "@"],
+ ["[", "^"],
+ ["`", "`"],
+ ["{", "\uD7FF"],
+ ["\uE000", "\uFFFF"]
+ ]));
+test_mix("\\W", ["iu", "imu"],
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "/"],
+ [":", "@"],
+ ["[", "^"],
+ ["`", "`"],
+ ["{", "\u017E"],
+ ["\u0180", "\u2129"],
+ ["\u212B", "\uD7FF"],
+ ["\uE000", "\uFFFF"]
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js b/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js
new file mode 100644
index 000000000..8be9cdb5a
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom_ControlEscape.js
@@ -0,0 +1,19 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("\\f", all_flags,
+ Atom("\u000c"));
+
+test_mix("\\n", all_flags,
+ Atom("\u000a"));
+
+test_mix("\\r", all_flags,
+ Atom("\u000d"));
+
+test_mix("\\t", all_flags,
+ Atom("\u0009"));
+
+test_mix("\\v", all_flags,
+ Atom("\u000b"));
diff --git a/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js b/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js
new file mode 100644
index 000000000..eec877465
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom_ControlLetter.js
@@ -0,0 +1,13 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("\\ca", all_flags,
+ Atom("\u0001"));
+test_mix("\\cz", all_flags,
+ Atom("\u001a"));
+test_mix("\\cA", all_flags,
+ Atom("\u0001"));
+test_mix("\\cZ", all_flags,
+ Atom("\u001a"));
diff --git a/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js b/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js
new file mode 100644
index 000000000..aa5c09f75
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom_DecimalEscape.js
@@ -0,0 +1,87 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+// LegacyOctalEscapeSequence
+
+test_mix("\\1", no_unicode_flags,
+ Atom("\u0001"));
+test_mix("\\2", no_unicode_flags,
+ Atom("\u0002"));
+test_mix("\\3", no_unicode_flags,
+ Atom("\u0003"));
+test_mix("\\4", no_unicode_flags,
+ Atom("\u0004"));
+test_mix("\\5", no_unicode_flags,
+ Atom("\u0005"));
+test_mix("\\6", no_unicode_flags,
+ Atom("\u0006"));
+test_mix("\\7", no_unicode_flags,
+ Atom("\u0007"));
+test_mix("\\8", no_unicode_flags,
+ Atom("8"));
+test_mix("\\9", no_unicode_flags,
+ Atom("9"));
+
+test_mix("\\10", no_unicode_flags,
+ Atom("\u0008"));
+test_mix("\\11", no_unicode_flags,
+ Atom("\u0009"));
+
+test_mix("\\189", no_unicode_flags,
+ Atom("\u{0001}89"));
+test_mix("\\1089", no_unicode_flags,
+ Atom("\u{0008}89"));
+test_mix("\\10189", no_unicode_flags,
+ Atom("A89"));
+test_mix("\\101189", no_unicode_flags,
+ Atom("A189"));
+
+// BackReference
+
+test_mix("()\\1", no_unicode_flags,
+ Alternative([
+ Capture(1, Empty()),
+ BackReference(1)
+ ]));
+test_mix("()\\1", unicode_flags,
+ Alternative([
+ Capture(1, Empty()),
+ Alternative([
+ BackReference(1),
+ Assertion("NOT_IN_SURROGATE_PAIR")
+ ])
+ ]));
+
+test_mix("()()()()()()()()()()\\10", no_unicode_flags,
+ Alternative([
+ Capture(1, Empty()),
+ Capture(2, Empty()),
+ Capture(3, Empty()),
+ Capture(4, Empty()),
+ Capture(5, Empty()),
+ Capture(6, Empty()),
+ Capture(7, Empty()),
+ Capture(8, Empty()),
+ Capture(9, Empty()),
+ Capture(10, Empty()),
+ BackReference(10)
+ ]));
+test_mix("()()()()()()()()()()\\10", unicode_flags,
+ Alternative([
+ Capture(1, Empty()),
+ Capture(2, Empty()),
+ Capture(3, Empty()),
+ Capture(4, Empty()),
+ Capture(5, Empty()),
+ Capture(6, Empty()),
+ Capture(7, Empty()),
+ Capture(8, Empty()),
+ Capture(9, Empty()),
+ Capture(10, Empty()),
+ Alternative([
+ BackReference(10),
+ Assertion("NOT_IN_SURROGATE_PAIR")
+ ])
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js b/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js
new file mode 100644
index 000000000..d041a3b90
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom_HexEscapeSequence.js
@@ -0,0 +1,19 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("\\x00", all_flags,
+ Atom("\u0000"));
+test_mix("\\xFF", all_flags,
+ Atom("\u00FF"));
+
+test_mix("\\x0", no_unicode_flags,
+ Atom("x0"));
+test_mix("\\x000", all_flags,
+ Atom("\u{0000}0"));
+
+test_mix("\\xG", no_unicode_flags,
+ Atom("xG"));
+test_mix("\\x0G", no_unicode_flags,
+ Atom("x0G"));
diff --git a/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js b/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js
new file mode 100644
index 000000000..aeb84526a
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom_IdentityEscape.js
@@ -0,0 +1,55 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+// SyntaxCharacter
+
+test("\\^", all_flags,
+ Atom("^"));
+test("\\$", all_flags,
+ Atom("$"));
+test("\\\\", all_flags,
+ Atom("\\"));
+test("\\.", all_flags,
+ Atom("."));
+test("\\*", all_flags,
+ Atom("*"));
+test("\\+", all_flags,
+ Atom("+"));
+test("\\?", all_flags,
+ Atom("?"));
+test("\\(", all_flags,
+ Atom("("));
+test("\\)", all_flags,
+ Atom(")"));
+test("\\[", all_flags,
+ Atom("["));
+test("\\]", all_flags,
+ Atom("]"));
+test("\\{", all_flags,
+ Atom("{"));
+test("\\}", all_flags,
+ Atom("}"));
+test("\\|", all_flags,
+ Atom("|"));
+
+// Slash
+
+test("\\/", all_flags,
+ Atom("/"));
+
+// SourceCharacter
+
+test("\\P", no_unicode_flags,
+ Atom("P"));
+
+test("\\uX", no_unicode_flags,
+ Atom("uX"));
+
+test("\\u{0000}", no_unicode_flags,
+ Quantifier(0, 0, "GREEDY", Atom("u")));
+
+test("\\c_", no_unicode_flags,
+ Atom("\\c_"));
+
diff --git a/js/src/jit-test/tests/regexp_parse/Atom_Null.js b/js/src/jit-test/tests/regexp_parse/Atom_Null.js
new file mode 100644
index 000000000..26f3eb679
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom_Null.js
@@ -0,0 +1,7 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("\\0", all_flags,
+ Atom("\u0000"));
diff --git a/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js b/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js
new file mode 100644
index 000000000..a4171ebb8
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Atom_RegExpUnicodeEscapeSequence.js
@@ -0,0 +1,108 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+// LeadSurrogate TrailSurrogate
+
+test("\\uD83D\\uDC38", all_flags,
+ Atom("\uD83D\uDC38"));
+test("X\\uD83D\\uDC38Y", no_unicode_flags,
+ Atom("X\uD83D\uDC38Y"));
+test("X\\uD83D\\uDC38Y", unicode_flags,
+ Text([
+ Atom("X"),
+ Atom("\uD83D\uDC38"),
+ Atom("Y")
+ ]));
+
+// LeadSurrogate
+
+test_mix("\\uD83D", no_unicode_flags,
+ Atom("\uD83D"));
+test("\\uD83D", unicode_flags,
+ Alternative([
+ Atom("\uD83D"),
+ NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]]))
+ ]));
+test("X\\uD83DY", unicode_flags,
+ Alternative([
+ Atom("X"),
+ Alternative([
+ Atom("\uD83D"),
+ NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]]))
+ ]),
+ Atom("Y")
+ ]));
+
+// TrailSurrogate
+
+test_mix("\\uDC38", no_unicode_flags,
+ Atom("\uDC38"));
+test("\\uDC38", unicode_flags,
+ Alternative([
+ Assertion("NOT_AFTER_LEAD_SURROGATE"),
+ Atom("\uDC38"),
+ ]));
+test("X\\uDC38Y", unicode_flags,
+ Alternative([
+ Atom("X"),
+ Alternative([
+ Assertion("NOT_AFTER_LEAD_SURROGATE"),
+ Atom("\uDC38"),
+ ]),
+ Atom("Y")
+ ]));
+
+// NonSurrogate / Hex4Digits
+
+test_mix("\\u0000", all_flags,
+ Atom("\u0000"));
+test_mix("\\uFFFF", all_flags,
+ Atom("\uFFFF"));
+
+// braced HexDigits
+
+test_mix("\\u{0000}", unicode_flags,
+ Atom("\u0000"));
+test_mix("\\u{FFFF}", unicode_flags,
+ Atom("\uFFFF"));
+
+test("\\u{1F438}", unicode_flags,
+ Atom("\uD83D\uDC38"));
+test("X\\u{1F438}Y", unicode_flags,
+ Text([
+ Atom("X"),
+ Atom("\uD83D\uDC38"),
+ Atom("Y")
+ ]));
+
+test("\\u{D83D}", unicode_flags,
+ Alternative([
+ Atom("\uD83D"),
+ NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]]))
+ ]));
+test("X\\u{D83D}Y", unicode_flags,
+ Alternative([
+ Atom("X"),
+ Alternative([
+ Atom("\uD83D"),
+ NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]]))
+ ]),
+ Atom("Y")
+ ]));
+
+test("\\u{DC38}", unicode_flags,
+ Alternative([
+ Assertion("NOT_AFTER_LEAD_SURROGATE"),
+ Atom("\uDC38"),
+ ]));
+test("X\\u{DC38}Y", unicode_flags,
+ Alternative([
+ Atom("X"),
+ Alternative([
+ Assertion("NOT_AFTER_LEAD_SURROGATE"),
+ Atom("\uDC38"),
+ ]),
+ Atom("Y")
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Capture.js b/js/src/jit-test/tests/regexp_parse/Capture.js
new file mode 100644
index 000000000..1dcb7a4fa
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Capture.js
@@ -0,0 +1,21 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("()", all_flags,
+ Capture(1, Empty()));
+
+test("(a)", all_flags,
+ Capture(1, Atom("a")));
+
+test("((a()b))c(d)", all_flags,
+ Alternative([
+ Capture(1, Capture(2, Alternative([
+ Atom("a"),
+ Capture(3, Empty()),
+ Atom("b")
+ ]))),
+ Atom("c"),
+ Capture(4, Atom("d"))
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/CharacterClass.js b/js/src/jit-test/tests/regexp_parse/CharacterClass.js
new file mode 100644
index 000000000..fb7367b1f
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/CharacterClass.js
@@ -0,0 +1,74 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("[]", all_flags,
+ NegativeCharacterClass([
+ ["\u0000", "\uFFFF"]
+ ]));
+
+test("[a]", all_flags,
+ CharacterClass([
+ ["a", "a"]
+ ]));
+
+test("[abc\u3042\u3044\u3046]", all_flags,
+ CharacterClass([
+ ["a", "a"],
+ ["b", "b"],
+ ["c", "c"],
+ ["\u3042", "\u3042"],
+ ["\u3044", "\u3044"],
+ ["\u3046", "\u3046"],
+ ]));
+
+test("[a-c\u3042-\u3046]", all_flags,
+ CharacterClass([
+ ["a", "c"],
+ ["\u3042", "\u3046"]
+ ]));
+
+test("[-]", all_flags,
+ CharacterClass([
+ ["-", "-"]
+ ]));
+
+// raw surrogate pair
+
+test("[X\uD83D\uDC38Y]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"],
+ ]),
+ Atom("\uD83D\uDC38")
+ ]));
+
+test("[X\uD83DY]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"]
+ ]),
+ Alternative([
+ CharacterClass([
+ ["\uD83D", "\uD83D"]
+ ]),
+ NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]]))
+ ])
+ ]));
+
+test("[X\uDC38Y]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"]
+ ]),
+ Alternative([
+ Assertion("NOT_AFTER_LEAD_SURROGATE"),
+ CharacterClass([
+ ["\uDC38", "\uDC38"]
+ ])
+ ])
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js b/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js
new file mode 100644
index 000000000..543f50b17
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/CharacterClass_CharacterClassEscape.js
@@ -0,0 +1,118 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("[\\d]", all_flags,
+ CharacterClass([["0", "9"]]));
+
+test("[\\D]", no_unicode_flags,
+ CharacterClass([
+ ["\u0000", "/"],
+ [":", "\uFFFF"]
+ ]));
+test("[\\D]", unicode_flags,
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "/"],
+ [":", "\uD7FF"],
+ ["\uE000", "\uFFFF"]
+ ]));
+
+test("[\\s]", all_flags,
+ CharacterClass([
+ ["\t", "\r"],
+ [" ", " "],
+ ["\u00A0", "\u00A0"],
+ ["\u1680", "\u1680"],
+ ["\u180E", "\u180E"],
+ ["\u2000", "\u200A"],
+ ["\u2028", "\u2029"],
+ ["\u202F", "\u202F"],
+ ["\u205F", "\u205F"],
+ ["\u3000", "\u3000"],
+ ["\uFEFF", "\uFEFF"]
+ ]));
+test("[\\S]", no_unicode_flags,
+ CharacterClass([
+ ["\u0000", "\u0008"],
+ ["\u000E", "\u001F"],
+ ["!", "\u009F"],
+ ["\u00A1", "\u167F"],
+ ["\u1681", "\u180D"],
+ ["\u180F", "\u1FFF"],
+ ["\u200B", "\u2027"],
+ ["\u202A", "\u202E"],
+ ["\u2030", "\u205E"],
+ ["\u2060", "\u2FFF"],
+ ["\u3001", "\uFEFE"],
+ ["\uFF00", "\uFFFF"]
+ ]));
+test("[\\S]", unicode_flags,
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "\u0008"],
+ ["\u000E", "\u001F"],
+ ["!", "\u009F"],
+ ["\u00A1", "\u167F"],
+ ["\u1681", "\u180D"],
+ ["\u180F", "\u1FFF"],
+ ["\u200B", "\u2027"],
+ ["\u202A", "\u202E"],
+ ["\u2030", "\u205E"],
+ ["\u2060", "\u2FFF"],
+ ["\u3001", "\uD7FF"],
+ ["\uE000", "\uFEFE"],
+ ["\uFF00", "\uFFFF"]
+ ]));
+
+test("[\\w]", no_unicode_flags,
+ CharacterClass([
+ ["0", "9"],
+ ["A", "Z"],
+ ["_", "_"],
+ ["a", "z"]
+ ]));
+test("[\\w]", ["u", "mu"],
+ CharacterClass([
+ ["0", "9"],
+ ["A", "Z"],
+ ["_", "_"],
+ ["a", "z"]
+ ]));
+test("[\\w]", ["iu", "imu"],
+ CharacterClass([
+ ["0", "9"],
+ ["A", "Z"],
+ ["_", "_"],
+ ["a", "z"],
+ ["\u017F", "\u017F"],
+ ["\u212A", "\u212A"]
+ ]));
+
+test("[\\W]", no_unicode_flags,
+ CharacterClass([
+ ["\u0000", "/"],
+ [":", "@"],
+ ["[", "^"],
+ ["`", "`"],
+ ["{", "\uFFFF"]
+ ]));
+test("[\\W]", ["u", "mu"],
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "/"],
+ [":", "@"],
+ ["[", "^"],
+ ["`", "`"],
+ ["{", "\uD7FF"],
+ ["\uE000", "\uFFFF"]
+ ]));
+test("[\\W]", ["iu", "imu"],
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "/"],
+ [":", "@"],
+ ["[", "^"],
+ ["`", "`"],
+ ["{", "\u017E"],
+ ["\u0180", "\u2129"],
+ ["\u212B", "\uD7FF"],
+ ["\uE000", "\uFFFF"]
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js b/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js
new file mode 100644
index 000000000..abb342fc2
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/CharacterClass_ClassEscape.js
@@ -0,0 +1,13 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("[\b]", all_flags,
+ CharacterClass([
+ ["\u0008", "\u0008"]
+ ]));
+test("[\-]", all_flags,
+ CharacterClass([
+ ["-", "-"]
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js b/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js
new file mode 100644
index 000000000..bf0194423
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlEscape.js
@@ -0,0 +1,29 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("[\\f]", all_flags,
+ CharacterClass([
+ ["\u000c", "\u000c"]
+ ]));
+
+test("[\\n]", all_flags,
+ CharacterClass([
+ ["\u000a", "\u000a"]
+ ]));
+
+test("[\\r]", all_flags,
+ CharacterClass([
+ ["\u000d", "\u000d"]
+ ]));
+
+test("[\\t]", all_flags,
+ CharacterClass([
+ ["\u0009", "\u0009"]
+ ]));
+
+test("[\\v]", all_flags,
+ CharacterClass([
+ ["\u000b", "\u000b"]
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js b/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js
new file mode 100644
index 000000000..d9109e911
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/CharacterClass_ControlLetter.js
@@ -0,0 +1,35 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("[\\ca]", all_flags,
+ CharacterClass([
+ ["\u0001", "\u0001"]
+ ]));
+test("[\\cz]", all_flags,
+ CharacterClass([
+ ["\u001a", "\u001a"]
+ ]));
+test("[\\cA]", all_flags,
+ CharacterClass([
+ ["\u0001", "\u0001"]
+ ]));
+test("[\\cZ]", all_flags,
+ CharacterClass([
+ ["\u001a", "\u001a"]
+ ]));
+
+// Invalid
+
+test("[\\c]", no_unicode_flags,
+ CharacterClass([
+ ["\\", "\\"],
+ ["c", "c"]
+ ]));
+test("[\\c=]", no_unicode_flags,
+ CharacterClass([
+ ["\\", "\\"],
+ ["c", "c"],
+ ["=", "="]
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js b/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js
new file mode 100644
index 000000000..2421d2364
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/CharacterClass_HexEscapeSequence.js
@@ -0,0 +1,39 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("[\\x00]", all_flags,
+ CharacterClass([
+ ["\u0000", "\u0000"]
+ ]));
+test("[\\xff]", all_flags,
+ CharacterClass([
+ ["\u00FF", "\u00FF"]
+ ]));
+
+// Invalid
+
+test("[\\x]", no_unicode_flags,
+ CharacterClass([
+ ["x", "x"]
+ ]));
+
+test("[\\xG]", no_unicode_flags,
+ CharacterClass([
+ ["x", "x"],
+ ["G", "G"]
+ ]));
+
+test("[\\x0]", no_unicode_flags,
+ CharacterClass([
+ ["x", "x"],
+ ["0", "0"]
+ ]));
+
+test("[\\x0G]", no_unicode_flags,
+ CharacterClass([
+ ["x", "x"],
+ ["0", "0"],
+ ["G", "G"],
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js b/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js
new file mode 100644
index 000000000..c3128d416
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/CharacterClass_Null.js
@@ -0,0 +1,9 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("[\\0]", all_flags,
+ CharacterClass([
+ ["\u0000", "\u0000"]
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js b/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js
new file mode 100644
index 000000000..ee111973d
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/CharacterClass_RegExpUnicodeEscapeSequence.js
@@ -0,0 +1,162 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+// LeadSurrogate TrailSurrogate
+
+test("[X\\uD83D\\uDC38Y]", no_unicode_flags,
+ CharacterClass([
+ ["X", "X"],
+ ["\uD83D", "\uD83D"],
+ ["\uDC38", "\uDC38"],
+ ["Y", "Y"]
+ ]));
+test("[X\\uD83D\\uDC38Y]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"],
+ ]),
+ Atom("\uD83D\uDC38")
+ ]));
+
+// LeadSurrogate
+
+test("[X\\uD83DY]", no_unicode_flags,
+ CharacterClass([
+ ["X", "X"],
+ ["\uD83D", "\uD83D"],
+ ["Y", "Y"]
+ ]));
+test("[X\\uD83DY]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"]
+ ]),
+ Alternative([
+ CharacterClass([
+ ["\uD83D", "\uD83D"]
+ ]),
+ NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]]))
+ ])
+ ]));
+
+// TrailSurrogate
+
+test("[X\\uDC38Y]", no_unicode_flags,
+ CharacterClass([
+ ["X", "X"],
+ ["\uDC38", "\uDC38"],
+ ["Y", "Y"]
+ ]));
+test("[X\\uDC38Y]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"]
+ ]),
+ Alternative([
+ Assertion("NOT_AFTER_LEAD_SURROGATE"),
+ CharacterClass([
+ ["\uDC38", "\uDC38"]
+ ])
+ ])
+ ]));
+
+// NonSurrogate / Hex4Digits
+
+test("[X\\u0000Y]", all_flags,
+ CharacterClass([
+ ["X", "X"],
+ ["\u0000", "\u0000"],
+ ["Y", "Y"]
+ ]));
+test("[X\\uFFFFY]", all_flags,
+ CharacterClass([
+ ["X", "X"],
+ ["\uFFFF", "\uFFFF"],
+ ["Y", "Y"]
+ ]));
+
+// braced HexDigits
+
+test("[X\\u{0000}Y]", unicode_flags,
+ CharacterClass([
+ ["X", "X"],
+ ["\u0000", "\u0000"],
+ ["Y", "Y"]
+ ]));
+test("[X\\uFFFFY]", unicode_flags,
+ CharacterClass([
+ ["X", "X"],
+ ["\uFFFF", "\uFFFF"],
+ ["Y", "Y"]
+ ]));
+
+test("[X\\u{1F438}Y]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"],
+ ]),
+ Atom("\uD83D\uDC38")
+ ]));
+
+test("[X\\u{D83D}Y]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"]
+ ]),
+ Alternative([
+ CharacterClass([
+ ["\uD83D", "\uD83D"]
+ ]),
+ NegativeLookahead(CharacterClass([["\uDC00", "\uDFFF"]]))
+ ])
+ ]));
+test("[X\\u{DC38}Y]", unicode_flags,
+ Disjunction([
+ CharacterClass([
+ ["X", "X"],
+ ["Y", "Y"]
+ ]),
+ Alternative([
+ Assertion("NOT_AFTER_LEAD_SURROGATE"),
+ CharacterClass([
+ ["\uDC38", "\uDC38"]
+ ])
+ ])
+ ]));
+
+// Invalid
+
+test("[\\u]", no_unicode_flags,
+ CharacterClass([
+ ["u", "u"]
+ ]));
+
+test("[\\uG]", no_unicode_flags,
+ CharacterClass([
+ ["u", "u"],
+ ["G", "G"]
+ ]));
+
+test("[\\uD83]", no_unicode_flags,
+ CharacterClass([
+ ["u", "u"],
+ ["D", "D"],
+ ["8", "8"],
+ ["3", "3"]
+ ]));
+
+test("[\\uD83G]", no_unicode_flags,
+ CharacterClass([
+ ["u", "u"],
+ ["D", "D"],
+ ["8", "8"],
+ ["3", "3"],
+ ["G", "G"]
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Disjunction.js b/js/src/jit-test/tests/regexp_parse/Disjunction.js
new file mode 100644
index 000000000..55d5d2b7e
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Disjunction.js
@@ -0,0 +1,42 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("a|\u3042", all_flags,
+ Disjunction([
+ Atom("a"),
+ Atom("\u3042")
+ ]));
+
+test("a|\u3042|abc", all_flags,
+ Disjunction([
+ Atom("a"),
+ Atom("\u3042"),
+ Atom("abc")
+ ]));
+
+test("|", all_flags,
+ Disjunction([
+ Empty(),
+ Empty()
+ ]));
+
+test("||", all_flags,
+ Disjunction([
+ Empty(),
+ Empty(),
+ Empty()
+ ]));
+
+test("abc|", all_flags,
+ Disjunction([
+ Atom("abc"),
+ Empty()
+ ]));
+
+test("|abc", all_flags,
+ Disjunction([
+ Empty(),
+ Atom("abc")
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Empty.js b/js/src/jit-test/tests/regexp_parse/Empty.js
new file mode 100644
index 000000000..56d0d890d
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Empty.js
@@ -0,0 +1,7 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("", all_flags,
+ Empty());
diff --git a/js/src/jit-test/tests/regexp_parse/Everything.js b/js/src/jit-test/tests/regexp_parse/Everything.js
new file mode 100644
index 000000000..c1539a58b
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Everything.js
@@ -0,0 +1,21 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix(".", no_unicode_flags,
+ CharacterClass([
+ ["\u0000", "\u0009"],
+ ["\u000b", "\u000c"],
+ ["\u000e", "\u2027"],
+ ["\u202A", "\uFFFF"]
+ ]));
+
+test_mix(".", unicode_flags,
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "\u0009"],
+ ["\u000b", "\u000c"],
+ ["\u000e", "\u2027"],
+ ["\u202A", "\uD7FF"],
+ ["\uE000", "\uFFFF"]
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Group.js b/js/src/jit-test/tests/regexp_parse/Group.js
new file mode 100644
index 000000000..ea930c9d3
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Group.js
@@ -0,0 +1,15 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test("(?:)", all_flags,
+ Empty());
+test("(?:a)", all_flags,
+ Atom("a"));
+test("X(?:a)Y", all_flags,
+ Text([
+ Atom("X"),
+ Atom("a"),
+ Atom("Y")
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Lookahead.js b/js/src/jit-test/tests/regexp_parse/Lookahead.js
new file mode 100644
index 000000000..96fc20fe9
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Lookahead.js
@@ -0,0 +1,31 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("(?=abc)", all_flags,
+ Lookahead(Atom("abc")));
+
+test_mix("(?!abc)", all_flags,
+ NegativeLookahead(Atom("abc")));
+
+test_mix("(?=abc)+", no_unicode_flags,
+ Lookahead(Atom("abc")));
+
+// Lookahead becomes Empty because max_match of Lookahead is 0 and the min vaue
+// of Quantifier is also 0.
+test("(?=abc)*", no_unicode_flags,
+ Empty());
+test("X(?=abc)*Y", no_unicode_flags,
+ Alternative([
+ Atom("X"),
+ Atom("Y"),
+ ]));
+
+test("(?=abc)?", no_unicode_flags,
+ Empty());
+test("X(?=abc)?Y", no_unicode_flags,
+ Alternative([
+ Atom("X"),
+ Atom("Y"),
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/MatchOnly.js b/js/src/jit-test/tests/regexp_parse/MatchOnly.js
new file mode 100644
index 000000000..c2586dd0b
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/MatchOnly.js
@@ -0,0 +1,35 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+// Leading and trailing .* are ignored if match_only==true.
+
+test_match_only(".*abc", all_flags,
+ Atom("abc"));
+test_match_only("abc.*", all_flags,
+ Atom("abc"));
+
+test_match_only(".*?abc", no_unicode_flags,
+ Alternative([
+ Quantifier(0, kInfinity, "NON_GREEDY",
+ CharacterClass([
+ ["\u0000", "\u0009"],
+ ["\u000b", "\u000c"],
+ ["\u000e", "\u2027"],
+ ["\u202A", "\uFFFF"]
+ ])),
+ Atom("abc")
+ ]));
+test_match_only(".*?abc", unicode_flags,
+ Alternative([
+ Quantifier(0, kInfinity, "NON_GREEDY",
+ AllSurrogateAndCharacterClass([
+ ["\u0000", "\u0009"],
+ ["\u000b", "\u000c"],
+ ["\u000e", "\u2027"],
+ ["\u202A", "\uD7FF"],
+ ["\uE000", "\uFFFF"]
+ ])),
+ Atom("abc")
+ ]));
diff --git a/js/src/jit-test/tests/regexp_parse/Quantifier.js b/js/src/jit-test/tests/regexp_parse/Quantifier.js
new file mode 100644
index 000000000..abf14e561
--- /dev/null
+++ b/js/src/jit-test/tests/regexp_parse/Quantifier.js
@@ -0,0 +1,58 @@
+if (typeof parseRegExp === 'undefined')
+ quit();
+
+load(libdir + "regexp_parse.js");
+
+test_mix("a*", all_flags,
+ Quantifier(0, kInfinity, "GREEDY", Atom("a")));
+test_mix("a*?", all_flags,
+ Quantifier(0, kInfinity, "NON_GREEDY", Atom("a")));
+
+test_mix("a+", all_flags,
+ Quantifier(1, kInfinity, "GREEDY", Atom("a")));
+test_mix("a+?", all_flags,
+ Quantifier(1, kInfinity, "NON_GREEDY", Atom("a")));
+
+test_mix("a?", all_flags,
+ Quantifier(0, 1, "GREEDY", Atom("a")));
+test_mix("a??", all_flags,
+ Quantifier(0, 1, "NON_GREEDY", Atom("a")));
+
+test_mix("a{3}", all_flags,
+ Quantifier(3, 3, "GREEDY", Atom("a")));
+test_mix("a{3}?", all_flags,
+ Quantifier(3, 3, "NON_GREEDY", Atom("a")));
+
+test_mix("a{3,}", all_flags,
+ Quantifier(3, kInfinity, "GREEDY", Atom("a")));
+test_mix("a{3,}?", all_flags,
+ Quantifier(3, kInfinity, "NON_GREEDY", Atom("a")));
+
+test_mix("a{3,5}", all_flags,
+ Quantifier(3, 5, "GREEDY", Atom("a")));
+test_mix("a{3,5}?", all_flags,
+ Quantifier(3, 5, "NON_GREEDY", Atom("a")));
+
+// Surrogate Pair and Quantifier
+
+test("\\uD83D\\uDC38+", no_unicode_flags,
+ Alternative([
+ Atom("\uD83D"),
+ Quantifier(1, kInfinity, "GREEDY", Atom("\uDC38"))
+ ]));
+test("\\uD83D\\uDC38+", unicode_flags,
+ Quantifier(1, kInfinity, "GREEDY", Atom("\uD83D\uDC38")));
+
+// Invalid
+
+test_mix("a{", no_unicode_flags,
+ Atom("a{"));
+test_mix("a{1", no_unicode_flags,
+ Atom("a{1"));
+test_mix("a{1,", no_unicode_flags,
+ Atom("a{1,"));
+test_mix("a{1,2", no_unicode_flags,
+ Atom("a{1,2"));
+
+test_mix("a{,", no_unicode_flags,
+ Atom("a{,"));