[Pkg-javascript-commits] [acorn] 01/03: New upstream version 5.5.0+ds1
Julien Puydt
julien.puydt at laposte.net
Sun Mar 4 22:26:22 UTC 2018
This is an automated email from the git hooks/post-receive script.
jpuydt-guest pushed a commit to branch master
in repository acorn.
commit 056988d400eaee214f51e6bebcb792bfb7573f35
Author: Julien Puydt <julien.puydt at laposte.net>
Date: Sun Mar 4 23:20:05 2018 +0100
New upstream version 5.5.0+ds1
---
AUTHORS | 1 -
CHANGELOG.md | 12 +
README.md | 5 +-
bin/generate-identifier-regex.js | 8 +-
bin/run_test262.js | 6 +-
bin/test262.whitelist | 12 -
bin/update_authors.sh | 9 +-
package.json | 8 +-
src/identifier.js | 8 +-
src/index.js | 2 +-
src/loose/state.js | 4 +
src/regexp.js | 1042 +++++++++++++++++++++++++++++
src/state.js | 3 +
src/tokenize.js | 79 +--
src/unicode-property-data.js | 463 +++++++++++++
src/walk/index.js | 9 +-
test/run.js | 2 +
test/tests-regexp-2018.js | 150 +++++
test/tests-regexp.js | 1353 ++++++++++++++++++++++++++++++++++++++
19 files changed, 3075 insertions(+), 101 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 59d1d0a..86c8d9b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,7 +1,6 @@
List of Acorn contributors. Updated before every release.
Adrian Heine
-Adrian Heine né Lang
Adrian Rakovsky
Alistair Braidwood
Amila Welihinda
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66a7aad..0deb736 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 5.5.0 (2018-02-27)
+
+### Bug fixes
+
+Support object spread in the AST walker.
+
+### New features
+
+The identifier character categorization is now based on Unicode version 10.
+
+Acorn will not validate the content of regular expressions, including new ES9 features.
+
## 5.4.1 (2018-02-02)
### Bug fixes
diff --git a/README.md b/README.md
index 98c3fe0..276dab3 100644
--- a/README.md
+++ b/README.md
@@ -28,10 +28,13 @@ The easiest way to install acorn is with [`npm`][npm].
npm install acorn
```
-Alternately, download the source.
+Alternately, you can download the source and build acorn yourself:
```sh
git clone https://github.com/acornjs/acorn.git
+cd acorn
+npm install
+npm run build
```
## Components
diff --git a/bin/generate-identifier-regex.js b/bin/generate-identifier-regex.js
index 100e8cf..f79c874 100644
--- a/bin/generate-identifier-regex.js
+++ b/bin/generate-identifier-regex.js
@@ -1,12 +1,14 @@
'use strict';
// Which Unicode version should be used?
-var version = '9.0.0';
+var pkg = require('../package.json');
+var dependencies = Object.keys(pkg.devDependencies);
+var unicodeVersion = dependencies.find((name) => /^unicode-\d/.test(name));
-var start = require('unicode-' + version + '/Binary_Property/ID_Start/code-points.js')
+var start = require(unicodeVersion + '/Binary_Property/ID_Start/code-points.js')
.filter(function(ch) { return ch > 0x7f; });
var last = -1;
-var cont = [0x200c, 0x200d].concat(require('unicode-' + version + '/Binary_Property/ID_Continue/code-points.js')
+var cont = [0x200c, 0x200d].concat(require(unicodeVersion + '/Binary_Property/ID_Continue/code-points.js')
.filter(function(ch) { return ch > 0x7f && search(start, ch, last + 1) == -1; }));
function search(arr, ch, starting) {
diff --git a/bin/run_test262.js b/bin/run_test262.js
index 880ffa2..f52a478 100644
--- a/bin/run_test262.js
+++ b/bin/run_test262.js
@@ -8,10 +8,8 @@ const unsupportedFeatures = [
"class-fields",
"class-fields-private",
"class-fields-public",
- "optional-catch-binding",
- "regexp-lookbehind",
- "regexp-named-groups",
- "regexp-unicode-property-escapes"
+ "numeric-separator-literal",
+ "optional-catch-binding"
];
run(
diff --git a/bin/test262.whitelist b/bin/test262.whitelist
index 4eaa642..b00d340 100644
--- a/bin/test262.whitelist
+++ b/bin/test262.whitelist
@@ -212,18 +212,6 @@ language/module-code/early-export-global.js (default)
language/module-code/early-export-global.js (strict mode)
language/module-code/early-export-unresolvable.js (default)
language/module-code/early-export-unresolvable.js (strict mode)
-language/module-code/instn-resolve-empty-export.js (default)
-language/module-code/instn-resolve-empty-export.js (strict mode)
-language/module-code/instn-resolve-empty-import.js (default)
-language/module-code/instn-resolve-empty-import.js (strict mode)
-language/module-code/instn-resolve-err-reference.js (default)
-language/module-code/instn-resolve-err-reference.js (strict mode)
-language/module-code/instn-resolve-err-syntax.js (default)
-language/module-code/instn-resolve-err-syntax.js (strict mode)
-language/module-code/instn-resolve-order-depth.js (default)
-language/module-code/instn-resolve-order-depth.js (strict mode)
-language/module-code/instn-resolve-order-src.js (default)
-language/module-code/instn-resolve-order-src.js (strict mode)
language/module-code/parse-err-hoist-lex-fun.js (default)
language/module-code/parse-err-hoist-lex-fun.js (strict mode)
language/module-code/parse-err-hoist-lex-gen.js (default)
diff --git a/bin/update_authors.sh b/bin/update_authors.sh
index e08f572..7533226 100755
--- a/bin/update_authors.sh
+++ b/bin/update_authors.sh
@@ -1,6 +1,3 @@
-# Combine existing list of authors with everyone known in git, sort, add header.
-tail --lines=+3 AUTHORS > AUTHORS.tmp
-git log --format='%aN' | grep -v abraidwood | grep -v Rich-Harris | grep -v ForbesLindesay >> AUTHORS.tmp
-echo -e "List of Acorn contributors. Updated before every release.\n" > AUTHORS
-sort -u AUTHORS.tmp >> AUTHORS
-rm -f AUTHORS.tmp
+echo "List of Acorn contributors. Updated before every release." > AUTHORS
+echo >> AUTHORS
+git log --format='%aN' | grep -v 'Adrian Heine né Lang' | grep -v abraidwood | grep -v Rich-Harris | grep -v ForbesLindesay | sort -u >> AUTHORS
diff --git a/package.json b/package.json
index 5011ada..d57c317 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"homepage": "https://github.com/acornjs/acorn",
"main": "dist/acorn.js",
"module": "dist/acorn.es.js",
- "version": "5.4.1",
+ "version": "5.5.0",
"engines": {
"node": ">=0.4.0"
},
@@ -49,8 +49,8 @@
"eslint-plugin-standard": "^3.0.1",
"rollup": "^0.45.0",
"rollup-plugin-buble": "^0.16.0",
- "test262-parser-runner": "^0.2.0",
- "test262": "git+https://github.com/tc39/test262.git#51553973738063f457e248f7f1e643c561c8a64c",
- "unicode-9.0.0": "^0.7.0"
+ "test262": "git+https://github.com/tc39/test262.git#18c1e799a01cc976695983b61e225ce7959bdd91",
+ "test262-parser-runner": "^0.3.1",
+ "unicode-10.0.0": "^0.7.5"
}
}
diff --git a/src/identifier.js b/src/identifier.js
index 3d19f63..5b6553b 100644
--- a/src/identifier.js
+++ b/src/identifier.js
@@ -27,8 +27,8 @@ export const keywordRelationalOperator = /^in(stanceof)?$/
// code point above 128.
// Generated by `bin/generate-identifier-regex.js`.
-let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u08 [...]
-let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09 [...]
+let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u08 [...]
+let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09 [...]
const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]")
const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]")
@@ -42,10 +42,10 @@ nonASCIIidentifierStartChars = nonASCIIidentifierChars = null
// generated by bin/generate-identifier-regex.js
// eslint-disable-next-line comma-spacing
-const astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185, [...]
+const astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185, [...]
// eslint-disable-next-line comma-spacing
-const astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239]
+const astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,19719,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,13 [...]
// This has a complexity linear to the value of the code. The
// assumption is that looking up astral identifier characters is
diff --git a/src/index.js b/src/index.js
index 0d9141d..7dfb3aa 100644
--- a/src/index.js
+++ b/src/index.js
@@ -37,7 +37,7 @@ export {isIdentifierChar, isIdentifierStart} from "./identifier"
export {Token} from "./tokenize"
export {isNewLine, lineBreak, lineBreakG, nonASCIIwhitespace} from "./whitespace"
-export const version = "5.4.1"
+export const version = "5.5.0"
// The main exported interface (under `self.acorn` when in the
// browser) is a `parse` function that takes a code string and
diff --git a/src/loose/state.js b/src/loose/state.js
index 571f472..da068ed 100644
--- a/src/loose/state.js
+++ b/src/loose/state.js
@@ -1,5 +1,7 @@
import {tokenizer, SourceLocation, tokTypes as tt, Node, lineBreak, isNewLine} from "../index"
+function noop() {}
+
// Registered plugins
export const pluginsLoose = {}
@@ -9,6 +11,8 @@ export class LooseParser {
this.options = this.toks.options
this.input = this.toks.input
this.tok = this.last = {type: tt.eof, start: 0, end: 0}
+ this.tok.validateRegExpFlags = noop
+ this.tok.validateRegExpPattern = noop
if (this.options.locations) {
let here = this.toks.curPosition()
this.tok.loc = new SourceLocation(this.toks, here, here)
diff --git a/src/regexp.js b/src/regexp.js
new file mode 100644
index 0000000..c5953e3
--- /dev/null
+++ b/src/regexp.js
@@ -0,0 +1,1042 @@
+import {isIdentifierStart, isIdentifierChar} from "./identifier.js"
+import {Parser} from "./state.js"
+import UNICODE_PROPERTY_VALUES from "./unicode-property-data.js"
+
+const pp = Parser.prototype
+
+export class RegExpValidationState {
+ constructor(parser) {
+ this.parser = parser
+ this.validFlags = `gim${parser.options.ecmaVersion >= 6 ? "uy" : ""}${parser.options.ecmaVersion >= 9 ? "s" : ""}`
+ this.source = ""
+ this.flags = ""
+ this.start = 0
+ this.switchU = false
+ this.switchN = false
+ this.pos = 0
+ this.lastIntValue = 0
+ this.lastStringValue = ""
+ this.lastAssertionIsQuantifiable = false
+ this.numCapturingParens = 0
+ this.maxBackReference = 0
+ this.groupNames = []
+ this.backReferenceNames = []
+ }
+
+ reset(start, pattern, flags) {
+ const unicode = flags.indexOf("u") !== -1
+ this.start = start | 0
+ this.source = pattern + ""
+ this.flags = flags
+ this.switchU = unicode && this.parser.options.ecmaVersion >= 6
+ this.switchN = unicode && this.parser.options.ecmaVersion >= 9
+ }
+
+ raise(message) {
+ this.parser.raiseRecoverable(this.start, `Invalid regular expression: /${this.source}/: ${message}`)
+ }
+
+ // If u flag is given, this returns the code point at the index (it combines a surrogate pair).
+ // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
+ at(i) {
+ const s = this.source
+ const l = s.length
+ if (i >= l) {
+ return -1
+ }
+ const c = s.charCodeAt(i)
+ if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
+ return c
+ }
+ return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00
+ }
+
+ nextIndex(i) {
+ const s = this.source
+ const l = s.length
+ if (i >= l) {
+ return l
+ }
+ const c = s.charCodeAt(i)
+ if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
+ return i + 1
+ }
+ return i + 2
+ }
+
+ current() {
+ return this.at(this.pos)
+ }
+
+ lookahead() {
+ return this.at(this.nextIndex(this.pos))
+ }
+
+ advance() {
+ this.pos = this.nextIndex(this.pos)
+ }
+
+ eat(ch) {
+ if (this.current() === ch) {
+ this.advance()
+ return true
+ }
+ return false
+ }
+}
+
+function codePointToString(ch) {
+ if (ch <= 0xFFFF) return String.fromCharCode(ch)
+ ch -= 0x10000
+ return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)
+}
+
+/**
+ * Validate the flags part of a given RegExpLiteral.
+ *
+ * @param {RegExpValidationState} state The state to validate RegExp.
+ * @returns {void}
+ */
+pp.validateRegExpFlags = function(state) {
+ const validFlags = state.validFlags
+ const flags = state.flags
+
+ for (let i = 0; i < flags.length; i++) {
+ const flag = flags.charAt(i)
+ if (validFlags.indexOf(flag) == -1) {
+ this.raise(state.start, "Invalid regular expression flag")
+ }
+ if (flags.indexOf(flag, i + 1) > -1) {
+ this.raise(state.start, "Duplicate regular expression flag")
+ }
+ }
+}
+
+/**
+ * Validate the pattern part of a given RegExpLiteral.
+ *
+ * @param {RegExpValidationState} state The state to validate RegExp.
+ * @returns {void}
+ */
+pp.validateRegExpPattern = function(state) {
+ this.regexp_pattern(state)
+
+ // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
+ // parsing contains a |GroupName|, reparse with the goal symbol
+ // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
+ // exception if _P_ did not conform to the grammar, if any elements of _P_
+ // were not matched by the parse, or if any Early Error conditions exist.
+ if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {
+ state.switchN = true
+ this.regexp_pattern(state)
+ }
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
+pp.regexp_pattern = function(state) {
+ state.pos = 0
+ state.lastIntValue = 0
+ state.lastStringValue = ""
+ state.lastAssertionIsQuantifiable = false
+ state.numCapturingParens = 0
+ state.maxBackReference = 0
+ state.groupNames.length = 0
+ state.backReferenceNames.length = 0
+
+ this.regexp_disjunction(state)
+
+ if (state.pos !== state.source.length) {
+ // Make the same messages as V8.
+ if (state.eat(0x29 /* ) */)) {
+ state.raise("Unmatched ')'")
+ }
+ if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) {
+ state.raise("Lone quantifier brackets")
+ }
+ }
+ if (state.maxBackReference > state.numCapturingParens) {
+ state.raise("Invalid escape")
+ }
+ for (const name of state.backReferenceNames) {
+ if (state.groupNames.indexOf(name) === -1) {
+ state.raise("Invalid named capture referenced")
+ }
+ }
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
+pp.regexp_disjunction = function(state) {
+ this.regexp_alternative(state)
+ while (state.eat(0x7C /* | */)) {
+ this.regexp_alternative(state)
+ }
+
+ // Make the same message as V8.
+ if (this.regexp_eatQuantifier(state, true)) {
+ state.raise("Nothing to repeat")
+ }
+ if (state.eat(0x7B /* { */)) {
+ state.raise("Lone quantifier brackets")
+ }
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
+pp.regexp_alternative = function(state) {
+ while (state.pos < state.source.length && this.regexp_eatTerm(state))
+ ;
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
+pp.regexp_eatTerm = function(state) {
+ if (this.regexp_eatAssertion(state)) {
+ // Handle `QuantifiableAssertion Quantifier` alternative.
+ // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
+ // is a QuantifiableAssertion.
+ if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
+ // Make the same message as V8.
+ if (state.switchU) {
+ state.raise("Invalid quantifier")
+ }
+ }
+ return true
+ }
+
+ if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
+ this.regexp_eatQuantifier(state)
+ return true
+ }
+
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
+pp.regexp_eatAssertion = function(state) {
+ const start = state.pos
+ state.lastAssertionIsQuantifiable = false
+
+ // ^, $
+ if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
+ return true
+ }
+
+ // \b \B
+ if (state.eat(0x5C /* \ */)) {
+ if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
+ return true
+ }
+ state.pos = start
+ }
+
+ // Lookahead / Lookbehind
+ if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
+ let lookbehind = false
+ if (this.options.ecmaVersion >= 9) {
+ lookbehind = state.eat(0x3C /* < */)
+ }
+ if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
+ this.regexp_disjunction(state)
+ if (!state.eat(0x29 /* ) */)) {
+ state.raise("Unterminated group")
+ }
+ state.lastAssertionIsQuantifiable = !lookbehind
+ return true
+ }
+ }
+
+ state.pos = start
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
+pp.regexp_eatQuantifier = function(state, noError = false) {
+ if (this.regexp_eatQuantifierPrefix(state, noError)) {
+ state.eat(0x3F /* ? */)
+ return true
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
+pp.regexp_eatQuantifierPrefix = function(state, noError) {
+ return (
+ state.eat(0x2A /* * */) ||
+ state.eat(0x2B /* + */) ||
+ state.eat(0x3F /* ? */) ||
+ this.regexp_eatBracedQuantifier(state, noError)
+ )
+}
+pp.regexp_eatBracedQuantifier = function(state, noError) {
+ const start = state.pos
+ if (state.eat(0x7B /* { */)) {
+ let min = 0, max = -1
+ if (this.regexp_eatDecimalDigits(state)) {
+ min = state.lastIntValue
+ if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
+ max = state.lastIntValue
+ }
+ if (state.eat(0x7D /* } */)) {
+ // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
+ if (max !== -1 && max < min && !noError) {
+ state.raise("numbers out of order in {} quantifier")
+ }
+ return true
+ }
+ }
+ if (state.switchU && !noError) {
+ state.raise("Incomplete quantifier")
+ }
+ state.pos = start
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
+pp.regexp_eatAtom = function(state) {
+ return (
+ this.regexp_eatPatternCharacters(state) ||
+ state.eat(0x2E /* . */) ||
+ this.regexp_eatReverseSolidusAtomEscape(state) ||
+ this.regexp_eatCharacterClass(state) ||
+ this.regexp_eatUncapturingGroup(state) ||
+ this.regexp_eatCapturingGroup(state)
+ )
+}
+pp.regexp_eatReverseSolidusAtomEscape = function(state) {
+ const start = state.pos
+ if (state.eat(0x5C /* \ */)) {
+ if (this.regexp_eatAtomEscape(state)) {
+ return true
+ }
+ state.pos = start
+ }
+ return false
+}
+pp.regexp_eatUncapturingGroup = function(state) {
+ const start = state.pos
+ if (state.eat(0x28 /* ( */)) {
+ if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {
+ this.regexp_disjunction(state)
+ if (state.eat(0x29 /* ) */)) {
+ return true
+ }
+ state.raise("Unterminated group")
+ }
+ state.pos = start
+ }
+ return false
+}
+pp.regexp_eatCapturingGroup = function(state) {
+ if (state.eat(0x28 /* ( */)) {
+ if (this.options.ecmaVersion >= 9) {
+ this.regexp_groupSpecifier(state)
+ } else if (state.current() === 0x3F /* ? */) {
+ state.raise("Invalid group")
+ }
+ this.regexp_disjunction(state)
+ if (state.eat(0x29 /* ) */)) {
+ state.numCapturingParens += 1
+ return true
+ }
+ state.raise("Unterminated group")
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
+pp.regexp_eatExtendedAtom = function(state) {
+ return (
+ state.eat(0x2E /* . */) ||
+ this.regexp_eatReverseSolidusAtomEscape(state) ||
+ this.regexp_eatCharacterClass(state) ||
+ this.regexp_eatUncapturingGroup(state) ||
+ this.regexp_eatCapturingGroup(state) ||
+ this.regexp_eatInvalidBracedQuantifier(state) ||
+ this.regexp_eatExtendedPatternCharacter(state)
+ )
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
+pp.regexp_eatInvalidBracedQuantifier = function(state) {
+ if (this.regexp_eatBracedQuantifier(state, true)) {
+ state.raise("Nothing to repeat")
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
+pp.regexp_eatSyntaxCharacter = function(state) {
+ const ch = state.current()
+ if (isSyntaxCharacter(ch)) {
+ state.lastIntValue = ch
+ state.advance()
+ return true
+ }
+ return false
+}
+function isSyntaxCharacter(ch) {
+ return (
+ ch === 0x24 /* $ */ ||
+ ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
+ ch === 0x2E /* . */ ||
+ ch === 0x3F /* ? */ ||
+ ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
+ ch >= 0x7B /* { */ && ch <= 0x7D /* } */
+ )
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
+// But eat eager.
+pp.regexp_eatPatternCharacters = function(state) {
+ const start = state.pos
+ let ch = 0
+ while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
+ state.advance()
+ }
+ return state.pos !== start
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
+pp.regexp_eatExtendedPatternCharacter = function(state) {
+ const ch = state.current()
+ if (
+ ch !== -1 &&
+ ch !== 0x24 /* $ */ &&
+ !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
+ ch !== 0x2E /* . */ &&
+ ch !== 0x3F /* ? */ &&
+ ch !== 0x5B /* [ */ &&
+ ch !== 0x5E /* ^ */ &&
+ ch !== 0x7C /* | */
+ ) {
+ state.advance()
+ return true
+ }
+ return false
+}
+
+// GroupSpecifier[U] ::
+// [empty]
+// `?` GroupName[?U]
+pp.regexp_groupSpecifier = function(state) {
+ if (state.eat(0x3F /* ? */)) {
+ if (this.regexp_eatGroupName(state)) {
+ if (state.groupNames.indexOf(state.lastStringValue) !== -1) {
+ state.raise("Duplicate capture group name")
+ }
+ state.groupNames.push(state.lastStringValue)
+ return
+ }
+ state.raise("Invalid group")
+ }
+}
+
+// GroupName[U] ::
+// `<` RegExpIdentifierName[?U] `>`
+// Note: this updates `state.lastStringValue` property with the eaten name.
+pp.regexp_eatGroupName = function(state) {
+ state.lastStringValue = ""
+ if (state.eat(0x3C /* < */)) {
+ if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
+ return true
+ }
+ state.raise("Invalid capture group name")
+ }
+ return false
+}
+
+// RegExpIdentifierName[U] ::
+// RegExpIdentifierStart[?U]
+// RegExpIdentifierName[?U] RegExpIdentifierPart[?U]
+// Note: this updates `state.lastStringValue` property with the eaten name.
+pp.regexp_eatRegExpIdentifierName = function(state) {
+ state.lastStringValue = ""
+ if (this.regexp_eatRegExpIdentifierStart(state)) {
+ state.lastStringValue += codePointToString(state.lastIntValue)
+ while (this.regexp_eatRegExpIdentifierPart(state)) {
+ state.lastStringValue += codePointToString(state.lastIntValue)
+ }
+ return true
+ }
+ return false
+}
+
+// RegExpIdentifierStart[U] ::
+// UnicodeIDStart
+// `$`
+// `_`
+// `\` RegExpUnicodeEscapeSequence[?U]
+pp.regexp_eatRegExpIdentifierStart = function(state) {
+ const start = state.pos
+ let ch = state.current()
+ state.advance()
+
+ if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {
+ ch = state.lastIntValue
+ }
+ if (isRegExpIdentifierStart(ch)) {
+ state.lastIntValue = ch
+ return true
+ }
+
+ state.pos = start
+ return false
+}
+function isRegExpIdentifierStart(ch) {
+ return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
+}
+
+// RegExpIdentifierPart[U] ::
+// UnicodeIDContinue
+// `$`
+// `_`
+// `\` RegExpUnicodeEscapeSequence[?U]
+// <ZWNJ>
+// <ZWJ>
+pp.regexp_eatRegExpIdentifierPart = function(state) {
+ const start = state.pos
+ let ch = state.current()
+ state.advance()
+
+ if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {
+ ch = state.lastIntValue
+ }
+ if (isRegExpIdentifierPart(ch)) {
+ state.lastIntValue = ch
+ return true
+ }
+
+ state.pos = start
+ return false
+}
+function isRegExpIdentifierPart(ch) {
+ return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
+pp.regexp_eatAtomEscape = function(state) {
+ if (
+ this.regexp_eatBackReference(state) ||
+ this.regexp_eatCharacterClassEscape(state) ||
+ this.regexp_eatCharacterEscape(state) ||
+ (state.switchN && this.regexp_eatKGroupName(state))
+ ) {
+ return true
+ }
+ if (state.switchU) {
+ // Make the same message as V8.
+ if (state.current() === 0x63 /* c */) {
+ state.raise("Invalid unicode escape")
+ }
+ state.raise("Invalid escape")
+ }
+ return false
+}
+pp.regexp_eatBackReference = function(state) {
+ const start = state.pos
+ if (this.regexp_eatDecimalEscape(state)) {
+ const n = state.lastIntValue
+ if (state.switchU) {
+ // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
+ if (n > state.maxBackReference) {
+ state.maxBackReference = n
+ }
+ return true
+ }
+ if (n <= state.numCapturingParens) {
+ return true
+ }
+ state.pos = start
+ }
+ return false
+}
+pp.regexp_eatKGroupName = function(state) {
+ if (state.eat(0x6B /* k */)) {
+ if (this.regexp_eatGroupName(state)) {
+ state.backReferenceNames.push(state.lastStringValue)
+ return true
+ }
+ state.raise("Invalid named reference")
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
+pp.regexp_eatCharacterEscape = function(state) {
+ return (
+ this.regexp_eatControlEscape(state) ||
+ this.regexp_eatCControlLetter(state) ||
+ this.regexp_eatZero(state) ||
+ this.regexp_eatHexEscapeSequence(state) ||
+ this.regexp_eatRegExpUnicodeEscapeSequence(state) ||
+ (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
+ this.regexp_eatIdentityEscape(state)
+ )
+}
+pp.regexp_eatCControlLetter = function(state) {
+ const start = state.pos
+ if (state.eat(0x63 /* c */)) {
+ if (this.regexp_eatControlLetter(state)) {
+ return true
+ }
+ state.pos = start
+ }
+ return false
+}
+pp.regexp_eatZero = function(state) {
+ if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
+ state.lastIntValue = 0
+ state.advance()
+ return true
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
+pp.regexp_eatControlEscape = function(state) {
+ const ch = state.current()
+ if (ch === 0x74 /* t */) {
+ state.lastIntValue = 0x09 /* \t */
+ state.advance()
+ return true
+ }
+ if (ch === 0x6E /* n */) {
+ state.lastIntValue = 0x0A /* \n */
+ state.advance()
+ return true
+ }
+ if (ch === 0x76 /* v */) {
+ state.lastIntValue = 0x0B /* \v */
+ state.advance()
+ return true
+ }
+ if (ch === 0x66 /* f */) {
+ state.lastIntValue = 0x0C /* \f */
+ state.advance()
+ return true
+ }
+ if (ch === 0x72 /* r */) {
+ state.lastIntValue = 0x0D /* \r */
+ state.advance()
+ return true
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
+pp.regexp_eatControlLetter = function(state) {
+ const ch = state.current()
+ if (isControlLetter(ch)) {
+ state.lastIntValue = ch % 0x20
+ state.advance()
+ return true
+ }
+ return false
+}
+function isControlLetter(ch) {
+ return (
+ (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
+ (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
+ )
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
+pp.regexp_eatRegExpUnicodeEscapeSequence = function(state) {
+ const start = state.pos
+
+ if (state.eat(0x75 /* u */)) {
+ if (this.regexp_eatFixedHexDigits(state, 4)) {
+ const lead = state.lastIntValue
+ if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) {
+ const leadSurrogateEnd = state.pos
+ if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
+ const trail = state.lastIntValue
+ if (trail >= 0xDC00 && trail <= 0xDFFF) {
+ state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000
+ return true
+ }
+ }
+ state.pos = leadSurrogateEnd
+ state.lastIntValue = lead
+ }
+ return true
+ }
+ if (
+ state.switchU &&
+ state.eat(0x7B /* { */) &&
+ this.regexp_eatHexDigits(state) &&
+ state.eat(0x7D /* } */) &&
+ isValidUnicode(state.lastIntValue)
+ ) {
+ return true
+ }
+ if (state.switchU) {
+ state.raise("Invalid unicode escape")
+ }
+ state.pos = start
+ }
+
+ return false
+}
+function isValidUnicode(ch) {
+ return ch >= 0 && ch <= 0x10FFFF
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
+pp.regexp_eatIdentityEscape = function(state) {
+ if (state.switchU) {
+ if (this.regexp_eatSyntaxCharacter(state)) {
+ return true
+ }
+ if (state.eat(0x2F /* / */)) {
+ state.lastIntValue = 0x2F /* / */
+ return true
+ }
+ return false
+ }
+
+ const ch = state.current()
+ if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
+ state.lastIntValue = ch
+ state.advance()
+ return true
+ }
+
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
+pp.regexp_eatDecimalEscape = function(state) {
+ state.lastIntValue = 0
+ let ch = state.current()
+ if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
+ do {
+ state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */)
+ state.advance()
+ } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
+ return true
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
+pp.regexp_eatCharacterClassEscape = function(state) {
+ const ch = state.current()
+
+ if (isCharacterClassEscape(ch)) {
+ state.lastIntValue = -1
+ state.advance()
+ return true
+ }
+
+ if (
+ state.switchU &&
+ this.options.ecmaVersion >= 9 &&
+ (ch === 0x50 /* P */ || ch === 0x70 /* p */)
+ ) {
+ state.lastIntValue = -1
+ state.advance()
+ if (
+ state.eat(0x7B /* { */) &&
+ this.regexp_eatUnicodePropertyValueExpression(state) &&
+ state.eat(0x7D /* } */)
+ ) {
+ return true
+ }
+ state.raise("Invalid property name")
+ }
+
+ return false
+}
+function isCharacterClassEscape(ch) {
+ return (
+ ch === 0x64 /* d */ ||
+ ch === 0x44 /* D */ ||
+ ch === 0x73 /* s */ ||
+ ch === 0x53 /* S */ ||
+ ch === 0x77 /* w */ ||
+ ch === 0x57 /* W */
+ )
+}
+
+// UnicodePropertyValueExpression ::
+// UnicodePropertyName `=` UnicodePropertyValue
+// LoneUnicodePropertyNameOrValue
+pp.regexp_eatUnicodePropertyValueExpression = function(state) {
+ const start = state.pos
+
+ // UnicodePropertyName `=` UnicodePropertyValue
+ if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
+ const name = state.lastStringValue
+ if (this.regexp_eatUnicodePropertyValue(state)) {
+ const value = state.lastStringValue
+ this.regexp_validateUnicodePropertyNameAndValue(state, name, value)
+ return true
+ }
+ }
+ state.pos = start
+
+ // LoneUnicodePropertyNameOrValue
+ if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
+ const nameOrValue = state.lastStringValue
+ this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue)
+ return true
+ }
+ return false
+}
+pp.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
+ if (!UNICODE_PROPERTY_VALUES.hasOwnProperty(name) || UNICODE_PROPERTY_VALUES[name].indexOf(value) === -1) {
+ state.raise("Invalid property name")
+ }
+}
+pp.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
+ if (UNICODE_PROPERTY_VALUES.$LONE.indexOf(nameOrValue) === -1) {
+ state.raise("Invalid property name")
+ }
+}
+
+// UnicodePropertyName ::
+// UnicodePropertyNameCharacters
+pp.regexp_eatUnicodePropertyName = function(state) {
+ let ch = 0
+ state.lastStringValue = ""
+ while (isUnicodePropertyNameCharacter(ch = state.current())) {
+ state.lastStringValue += codePointToString(ch)
+ state.advance()
+ }
+ return state.lastStringValue !== ""
+}
+function isUnicodePropertyNameCharacter(ch) {
+ return isControlLetter(ch) || ch === 0x5F /* _ */
+}
+
+// UnicodePropertyValue ::
+// UnicodePropertyValueCharacters
+pp.regexp_eatUnicodePropertyValue = function(state) {
+ let ch = 0
+ state.lastStringValue = ""
+ while (isUnicodePropertyValueCharacter(ch = state.current())) {
+ state.lastStringValue += codePointToString(ch)
+ state.advance()
+ }
+ return state.lastStringValue !== ""
+}
+function isUnicodePropertyValueCharacter(ch) {
+ return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
+}
+
+// LoneUnicodePropertyNameOrValue ::
+// UnicodePropertyValueCharacters
+pp.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
+ return this.regexp_eatUnicodePropertyValue(state)
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
+pp.regexp_eatCharacterClass = function(state) {
+ if (state.eat(0x5B /* [ */)) {
+ state.eat(0x5E /* ^ */)
+ this.regexp_classRanges(state)
+ if (state.eat(0x5D /* [ */)) {
+ return true
+ }
+ // Unreachable since it threw "unterminated regular expression" error before.
+ state.raise("Unterminated character class")
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
+// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
+// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
+pp.regexp_classRanges = function(state) {
+ while (this.regexp_eatClassAtom(state)) {
+ const left = state.lastIntValue
+ if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {
+ const right = state.lastIntValue
+ if (state.switchU && (left === -1 || right === -1)) {
+ state.raise("Invalid character class")
+ }
+ if (left !== -1 && right !== -1 && left > right) {
+ state.raise("Range out of order in character class")
+ }
+ }
+ }
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
+// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
+pp.regexp_eatClassAtom = function(state) {
+ const start = state.pos
+
+ if (state.eat(0x5C /* \ */)) {
+ if (this.regexp_eatClassEscape(state)) {
+ return true
+ }
+ if (state.switchU) {
+ // Make the same message as V8.
+ const ch = state.current()
+ if (ch === 0x63 /* c */ || isOctalDigit(ch)) {
+ state.raise("Invalid class escape")
+ }
+ state.raise("Invalid escape")
+ }
+ state.pos = start
+ }
+
+ const ch = state.current()
+ if (ch !== 0x5D /* [ */) {
+ state.lastIntValue = ch
+ state.advance()
+ return true
+ }
+
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
+pp.regexp_eatClassEscape = function(state) {
+ const start = state.pos
+
+ if (state.eat(0x62 /* b */)) {
+ state.lastIntValue = 0x08 /* <BS> */
+ return true
+ }
+
+ if (state.switchU && state.eat(0x2D /* - */)) {
+ state.lastIntValue = 0x2D /* - */
+ return true
+ }
+
+ if (!state.switchU && state.eat(0x63 /* c */)) {
+ if (this.regexp_eatClassControlLetter(state)) {
+ return true
+ }
+ state.pos = start
+ }
+
+ return (
+ this.regexp_eatCharacterClassEscape(state) ||
+ this.regexp_eatCharacterEscape(state)
+ )
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
+pp.regexp_eatClassControlLetter = function(state) {
+ const ch = state.current()
+ if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
+ state.lastIntValue = ch % 0x20
+ state.advance()
+ return true
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
+pp.regexp_eatHexEscapeSequence = function(state) {
+ const start = state.pos
+ if (state.eat(0x78 /* x */)) {
+ if (this.regexp_eatFixedHexDigits(state, 2)) {
+ return true
+ }
+ if (state.switchU) {
+ state.raise("Invalid escape")
+ }
+ state.pos = start
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
+pp.regexp_eatDecimalDigits = function(state) {
+ const start = state.pos
+ let ch = 0
+ state.lastIntValue = 0
+ while (isDecimalDigit(ch = state.current())) {
+ state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */)
+ state.advance()
+ }
+ return state.pos !== start
+}
+function isDecimalDigit(ch) {
+ return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
+pp.regexp_eatHexDigits = function(state) {
+ const start = state.pos
+ let ch = 0
+ state.lastIntValue = 0
+ while (isHexDigit(ch = state.current())) {
+ state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch)
+ state.advance()
+ }
+ return state.pos !== start
+}
+function isHexDigit(ch) {
+ return (
+ (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
+ (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
+ (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
+ )
+}
+function hexToInt(ch) {
+ if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
+ return 10 + (ch - 0x41 /* A */)
+ }
+ if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
+ return 10 + (ch - 0x61 /* a */)
+ }
+ return ch - 0x30 /* 0 */
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
+// Allows only 0-377(octal) i.e. 0-255(decimal).
+pp.regexp_eatLegacyOctalEscapeSequence = function(state) {
+ if (this.regexp_eatOctalDigit(state)) {
+ const n1 = state.lastIntValue
+ if (this.regexp_eatOctalDigit(state)) {
+ const n2 = state.lastIntValue
+ if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
+ state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue
+ } else {
+ state.lastIntValue = n1 * 8 + n2
+ }
+ } else {
+ state.lastIntValue = n1
+ }
+ return true
+ }
+ return false
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
+pp.regexp_eatOctalDigit = function(state) {
+ const ch = state.current()
+ if (isOctalDigit(ch)) {
+ state.lastIntValue = ch - 0x30 /* 0 */
+ state.advance()
+ return true
+ }
+ state.lastIntValue = 0
+ return false
+}
+function isOctalDigit(ch) {
+ return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
+}
+
+// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
+// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
+// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
+pp.regexp_eatFixedHexDigits = function(state, length) {
+ const start = state.pos
+ state.lastIntValue = 0
+ for (let i = 0; i < length; ++i) {
+ const ch = state.current()
+ if (!isHexDigit(ch)) {
+ state.pos = start
+ return false
+ }
+ state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch)
+ state.advance()
+ }
+ return true
+}
diff --git a/src/state.js b/src/state.js
index b90403f..185fe28 100644
--- a/src/state.js
+++ b/src/state.js
@@ -89,6 +89,9 @@ export class Parser {
// Scope tracking for duplicate variable names (see scope.js)
this.scopeStack = []
this.enterFunctionScope()
+
+ // For RegExp validation
+ this.regexpState = null
}
// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them
diff --git a/src/tokenize.js b/src/tokenize.js
index 71dd840..3dbaf67 100644
--- a/src/tokenize.js
+++ b/src/tokenize.js
@@ -2,6 +2,7 @@ import {isIdentifierStart, isIdentifierChar} from "./identifier"
import {types as tt, keywords as keywordTypes} from "./tokentype"
import {Parser} from "./state"
import {SourceLocation} from "./locutil"
+import {RegExpValidationState} from "./regexp"
import {lineBreak, lineBreakG, isNewLine, nonASCIIwhitespace} from "./whitespace"
// Object type used to represent tokens. Note that normally, tokens
@@ -25,9 +26,6 @@ export class Token {
const pp = Parser.prototype
-// Are we running under Rhino?
-const isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]"
-
// Move to the next token
pp.next = function() {
@@ -369,22 +367,6 @@ pp.finishOp = function(type, size) {
return this.finishToken(type, str)
}
-// Parse a regular expression. Some context-awareness is necessary,
-// since a '/' inside a '[]' set does not end the expression.
-
-function tryCreateRegexp(src, flags, throwErrorAt, parser) {
- try {
- return new RegExp(src, flags)
- } catch (e) {
- if (throwErrorAt !== undefined) {
- if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message)
- throw e
- }
- }
-}
-
-const regexpUnicodeSupport = !!tryCreateRegexp("\uffff", "u")
-
pp.readRegexp = function() {
let escaped, inClass, start = this.pos
for (;;) {
@@ -399,55 +381,28 @@ pp.readRegexp = function() {
} else escaped = false
++this.pos
}
- let content = this.input.slice(start, this.pos)
+ let pattern = this.input.slice(start, this.pos)
++this.pos
let flagsStart = this.pos
- let mods = this.readWord1()
+ let flags = this.readWord1()
if (this.containsEsc) this.unexpected(flagsStart)
- let tmp = content, tmpFlags = ""
- if (mods) {
- let validFlags = "gim"
- if (this.options.ecmaVersion >= 6) validFlags += "uy"
- if (this.options.ecmaVersion >= 9) validFlags += "s"
- for (let i = 0; i < mods.length; i++) {
- let mod = mods.charAt(i)
- if (validFlags.indexOf(mod) == -1) this.raise(start, "Invalid regular expression flag")
- if (mods.indexOf(mod, i + 1) > -1) this.raise(start, "Duplicate regular expression flag")
- }
- if (mods.indexOf("u") >= 0) {
- if (regexpUnicodeSupport) {
- tmpFlags = "u"
- } else {
- // Replace each astral symbol and every Unicode escape sequence that
- // possibly represents an astral symbol or a paired surrogate with a
- // single ASCII symbol to avoid throwing on regular expressions that
- // are only valid in combination with the `/u` flag.
- // Note: replacing with the ASCII symbol `x` might cause false
- // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
- // perfectly valid pattern that is equivalent to `[a-b]`, but it would
- // be replaced by `[x-b]` which throws an error.
- tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, (_match, code, offset) => {
- code = Number("0x" + code)
- if (code > 0x10FFFF) this.raise(start + offset + 3, "Code point out of bounds")
- return "x"
- })
- tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
- tmpFlags = tmpFlags.replace("u", "")
- }
- }
- }
- // Detect invalid regular expressions.
+ // Validate pattern
+ const state = this.regexpState || (this.regexpState = new RegExpValidationState(this))
+ state.reset(start, pattern, flags)
+ this.validateRegExpFlags(state)
+ this.validateRegExpPattern(state)
+
+ // Create Literal#value property value.
let value = null
- // Rhino's regular expression parser is flaky and throws uncatchable exceptions,
- // so don't do detection if we are running under Rhino
- if (!isRhino) {
- tryCreateRegexp(tmp, tmpFlags, start, this)
- // Get a regular expression object for this pattern-flag pair, or `null` in
- // case the current environment doesn't support the flags it uses.
- value = tryCreateRegexp(content, mods)
+ try {
+ value = new RegExp(pattern, flags)
+ } catch (e) {
+ // ESTree requires null if it failed to instantiate RegExp object.
+ // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
}
- return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value})
+
+ return this.finishToken(tt.regexp, {pattern, flags, value})
}
// Read an integer in the given radix. Return null if zero digits
diff --git a/src/unicode-property-data.js b/src/unicode-property-data.js
new file mode 100644
index 0000000..d44f1a2
--- /dev/null
+++ b/src/unicode-property-data.js
@@ -0,0 +1,463 @@
+const data = {
+ "$LONE": [
+ "ASCII",
+ "ASCII_Hex_Digit",
+ "AHex",
+ "Alphabetic",
+ "Alpha",
+ "Any",
+ "Assigned",
+ "Bidi_Control",
+ "Bidi_C",
+ "Bidi_Mirrored",
+ "Bidi_M",
+ "Case_Ignorable",
+ "CI",
+ "Cased",
+ "Changes_When_Casefolded",
+ "CWCF",
+ "Changes_When_Casemapped",
+ "CWCM",
+ "Changes_When_Lowercased",
+ "CWL",
+ "Changes_When_NFKC_Casefolded",
+ "CWKCF",
+ "Changes_When_Titlecased",
+ "CWT",
+ "Changes_When_Uppercased",
+ "CWU",
+ "Dash",
+ "Default_Ignorable_Code_Point",
+ "DI",
+ "Deprecated",
+ "Dep",
+ "Diacritic",
+ "Dia",
+ "Emoji",
+ "Emoji_Component",
+ "Emoji_Modifier",
+ "Emoji_Modifier_Base",
+ "Emoji_Presentation",
+ "Extender",
+ "Ext",
+ "Grapheme_Base",
+ "Gr_Base",
+ "Grapheme_Extend",
+ "Gr_Ext",
+ "Hex_Digit",
+ "Hex",
+ "IDS_Binary_Operator",
+ "IDSB",
+ "IDS_Trinary_Operator",
+ "IDST",
+ "ID_Continue",
+ "IDC",
+ "ID_Start",
+ "IDS",
+ "Ideographic",
+ "Ideo",
+ "Join_Control",
+ "Join_C",
+ "Logical_Order_Exception",
+ "LOE",
+ "Lowercase",
+ "Lower",
+ "Math",
+ "Noncharacter_Code_Point",
+ "NChar",
+ "Pattern_Syntax",
+ "Pat_Syn",
+ "Pattern_White_Space",
+ "Pat_WS",
+ "Quotation_Mark",
+ "QMark",
+ "Radical",
+ "Regional_Indicator",
+ "RI",
+ "Sentence_Terminal",
+ "STerm",
+ "Soft_Dotted",
+ "SD",
+ "Terminal_Punctuation",
+ "Term",
+ "Unified_Ideograph",
+ "UIdeo",
+ "Uppercase",
+ "Upper",
+ "Variation_Selector",
+ "VS",
+ "White_Space",
+ "space",
+ "XID_Continue",
+ "XIDC",
+ "XID_Start",
+ "XIDS"
+ ],
+ "General_Category": [
+ "Cased_Letter",
+ "LC",
+ "Close_Punctuation",
+ "Pe",
+ "Connector_Punctuation",
+ "Pc",
+ "Control",
+ "Cc",
+ "cntrl",
+ "Currency_Symbol",
+ "Sc",
+ "Dash_Punctuation",
+ "Pd",
+ "Decimal_Number",
+ "Nd",
+ "digit",
+ "Enclosing_Mark",
+ "Me",
+ "Final_Punctuation",
+ "Pf",
+ "Format",
+ "Cf",
+ "Initial_Punctuation",
+ "Pi",
+ "Letter",
+ "L",
+ "Letter_Number",
+ "Nl",
+ "Line_Separator",
+ "Zl",
+ "Lowercase_Letter",
+ "Ll",
+ "Mark",
+ "M",
+ "Combining_Mark",
+ "Math_Symbol",
+ "Sm",
+ "Modifier_Letter",
+ "Lm",
+ "Modifier_Symbol",
+ "Sk",
+ "Nonspacing_Mark",
+ "Mn",
+ "Number",
+ "N",
+ "Open_Punctuation",
+ "Ps",
+ "Other",
+ "C",
+ "Other_Letter",
+ "Lo",
+ "Other_Number",
+ "No",
+ "Other_Punctuation",
+ "Po",
+ "Other_Symbol",
+ "So",
+ "Paragraph_Separator",
+ "Zp",
+ "Private_Use",
+ "Co",
+ "Punctuation",
+ "P",
+ "punct",
+ "Separator",
+ "Z",
+ "Space_Separator",
+ "Zs",
+ "Spacing_Mark",
+ "Mc",
+ "Surrogate",
+ "Cs",
+ "Symbol",
+ "S",
+ "Titlecase_Letter",
+ "Lt",
+ "Unassigned",
+ "Cn",
+ "Uppercase_Letter",
+ "Lu"
+ ],
+ "Script": [
+ "Adlam",
+ "Adlm",
+ "Ahom",
+ "Anatolian_Hieroglyphs",
+ "Hluw",
+ "Arabic",
+ "Arab",
+ "Armenian",
+ "Armn",
+ "Avestan",
+ "Avst",
+ "Balinese",
+ "Bali",
+ "Bamum",
+ "Bamu",
+ "Bassa_Vah",
+ "Bass",
+ "Batak",
+ "Batk",
+ "Bengali",
+ "Beng",
+ "Bhaiksuki",
+ "Bhks",
+ "Bopomofo",
+ "Bopo",
+ "Brahmi",
+ "Brah",
+ "Braille",
+ "Brai",
+ "Buginese",
+ "Bugi",
+ "Buhid",
+ "Buhd",
+ "Canadian_Aboriginal",
+ "Cans",
+ "Carian",
+ "Cari",
+ "Caucasian_Albanian",
+ "Aghb",
+ "Chakma",
+ "Cakm",
+ "Cham",
+ "Cherokee",
+ "Cher",
+ "Common",
+ "Zyyy",
+ "Coptic",
+ "Copt",
+ "Qaac",
+ "Cuneiform",
+ "Xsux",
+ "Cypriot",
+ "Cprt",
+ "Cyrillic",
+ "Cyrl",
+ "Deseret",
+ "Dsrt",
+ "Devanagari",
+ "Deva",
+ "Duployan",
+ "Dupl",
+ "Egyptian_Hieroglyphs",
+ "Egyp",
+ "Elbasan",
+ "Elba",
+ "Ethiopic",
+ "Ethi",
+ "Georgian",
+ "Geor",
+ "Glagolitic",
+ "Glag",
+ "Gothic",
+ "Goth",
+ "Grantha",
+ "Gran",
+ "Greek",
+ "Grek",
+ "Gujarati",
+ "Gujr",
+ "Gurmukhi",
+ "Guru",
+ "Han",
+ "Hani",
+ "Hangul",
+ "Hang",
+ "Hanunoo",
+ "Hano",
+ "Hatran",
+ "Hatr",
+ "Hebrew",
+ "Hebr",
+ "Hiragana",
+ "Hira",
+ "Imperial_Aramaic",
+ "Armi",
+ "Inherited",
+ "Zinh",
+ "Qaai",
+ "Inscriptional_Pahlavi",
+ "Phli",
+ "Inscriptional_Parthian",
+ "Prti",
+ "Javanese",
+ "Java",
+ "Kaithi",
+ "Kthi",
+ "Kannada",
+ "Knda",
+ "Katakana",
+ "Kana",
+ "Kayah_Li",
+ "Kali",
+ "Kharoshthi",
+ "Khar",
+ "Khmer",
+ "Khmr",
+ "Khojki",
+ "Khoj",
+ "Khudawadi",
+ "Sind",
+ "Lao",
+ "Laoo",
+ "Latin",
+ "Latn",
+ "Lepcha",
+ "Lepc",
+ "Limbu",
+ "Limb",
+ "Linear_A",
+ "Lina",
+ "Linear_B",
+ "Linb",
+ "Lisu",
+ "Lycian",
+ "Lyci",
+ "Lydian",
+ "Lydi",
+ "Mahajani",
+ "Mahj",
+ "Malayalam",
+ "Mlym",
+ "Mandaic",
+ "Mand",
+ "Manichaean",
+ "Mani",
+ "Marchen",
+ "Marc",
+ "Masaram_Gondi",
+ "Gonm",
+ "Meetei_Mayek",
+ "Mtei",
+ "Mende_Kikakui",
+ "Mend",
+ "Meroitic_Cursive",
+ "Merc",
+ "Meroitic_Hieroglyphs",
+ "Mero",
+ "Miao",
+ "Plrd",
+ "Modi",
+ "Mongolian",
+ "Mong",
+ "Mro",
+ "Mroo",
+ "Multani",
+ "Mult",
+ "Myanmar",
+ "Mymr",
+ "Nabataean",
+ "Nbat",
+ "New_Tai_Lue",
+ "Talu",
+ "Newa",
+ "Nko",
+ "Nkoo",
+ "Nushu",
+ "Nshu",
+ "Ogham",
+ "Ogam",
+ "Ol_Chiki",
+ "Olck",
+ "Old_Hungarian",
+ "Hung",
+ "Old_Italic",
+ "Ital",
+ "Old_North_Arabian",
+ "Narb",
+ "Old_Permic",
+ "Perm",
+ "Old_Persian",
+ "Xpeo",
+ "Old_South_Arabian",
+ "Sarb",
+ "Old_Turkic",
+ "Orkh",
+ "Oriya",
+ "Orya",
+ "Osage",
+ "Osge",
+ "Osmanya",
+ "Osma",
+ "Pahawh_Hmong",
+ "Hmng",
+ "Palmyrene",
+ "Palm",
+ "Pau_Cin_Hau",
+ "Pauc",
+ "Phags_Pa",
+ "Phag",
+ "Phoenician",
+ "Phnx",
+ "Psalter_Pahlavi",
+ "Phlp",
+ "Rejang",
+ "Rjng",
+ "Runic",
+ "Runr",
+ "Samaritan",
+ "Samr",
+ "Saurashtra",
+ "Saur",
+ "Sharada",
+ "Shrd",
+ "Shavian",
+ "Shaw",
+ "Siddham",
+ "Sidd",
+ "SignWriting",
+ "Sgnw",
+ "Sinhala",
+ "Sinh",
+ "Sora_Sompeng",
+ "Sora",
+ "Soyombo",
+ "Soyo",
+ "Sundanese",
+ "Sund",
+ "Syloti_Nagri",
+ "Sylo",
+ "Syriac",
+ "Syrc",
+ "Tagalog",
+ "Tglg",
+ "Tagbanwa",
+ "Tagb",
+ "Tai_Le",
+ "Tale",
+ "Tai_Tham",
+ "Lana",
+ "Tai_Viet",
+ "Tavt",
+ "Takri",
+ "Takr",
+ "Tamil",
+ "Taml",
+ "Tangut",
+ "Tang",
+ "Telugu",
+ "Telu",
+ "Thaana",
+ "Thaa",
+ "Thai",
+ "Tibetan",
+ "Tibt",
+ "Tifinagh",
+ "Tfng",
+ "Tirhuta",
+ "Tirh",
+ "Ugaritic",
+ "Ugar",
+ "Vai",
+ "Vaii",
+ "Warang_Citi",
+ "Wara",
+ "Yi",
+ "Yiii",
+ "Zanabazar_Square",
+ "Zanb"
+ ]
+}
+Array.prototype.push.apply(data.$LONE, data.General_Category)
+data.gc = data.General_Category
+data.sc = data.Script_Extensions = data.scx = data.Script
+
+export default data
diff --git a/src/walk/index.js b/src/walk/index.js
index ac46692..741eb48 100644
--- a/src/walk/index.js
+++ b/src/walk/index.js
@@ -293,7 +293,7 @@ base.ArrayPattern = (node, st, c) => {
}
base.ObjectPattern = (node, st, c) => {
for (let prop of node.properties)
- c(prop.value, st, "Pattern")
+ c(prop, st, "Pattern")
}
base.Expression = skipThrough
@@ -361,8 +361,11 @@ base.ClassDeclaration = base.ClassExpression = (node, st, c) => c(node, st, "Cla
base.Class = (node, st, c) => {
if (node.id) c(node.id, st, "Pattern")
if (node.superClass) c(node.superClass, st, "Expression")
- for (let item of node.body.body)
- c(item, st)
+ c(node.body, st)
+}
+base.ClassBody = (node, st, c) => {
+ for (let elt of node.body)
+ c(elt, st)
}
base.MethodDefinition = base.Property = (node, st, c) => {
if (node.computed) c(node.key, st, "Expression")
diff --git a/test/run.js b/test/run.js
index 91ad384..025f650 100644
--- a/test/run.js
+++ b/test/run.js
@@ -12,6 +12,8 @@
require("./tests-directive.js");
require("./tests-rest-spread-properties.js");
require("./tests-async-iteration.js");
+ require("./tests-regexp.js");
+ require("./tests-regexp-2018.js");
acorn = require("../dist/acorn")
require("../dist/acorn_loose")
} else {
diff --git a/test/tests-regexp-2018.js b/test/tests-regexp-2018.js
new file mode 100644
index 0000000..0a48fab
--- /dev/null
+++ b/test/tests-regexp-2018.js
@@ -0,0 +1,150 @@
+if (typeof exports != "undefined") {
+ var test = require("./driver.js").test
+ var testFail = require("./driver.js").testFail
+}
+
+//------------------------------------------------------------------------------
+// Named capture groups
+//------------------------------------------------------------------------------
+
+test("/(a)/", {}, { ecmaVersion: 2018 })
+test("/(?:a)/", {}, { ecmaVersion: 2018 })
+testFail("/(?a/", "Invalid regular expression: /(?a/: Invalid group (1:1)", { ecmaVersion: 2018 })
+testFail("/(?a)/", "Invalid regular expression: /(?a)/: Invalid group (1:1)", { ecmaVersion: 2018 })
+testFail("/(?</", "Invalid regular expression: /(?</: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<)/", "Invalid regular expression: /(?<)/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a)/", "Invalid regular expression: /(?<a)/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+test("/(?<a>)/", {}, { ecmaVersion: 2018 })
+test("/\\k/", {}, { ecmaVersion: 2017 })
+test("/\\k/", {}, { ecmaVersion: 2018 })
+testFail("/\\k/u", "Invalid regular expression: /\\k/: Invalid escape (1:1)", { ecmaVersion: 2017 })
+testFail("/\\k/u", "Invalid regular expression: /\\k/: Invalid named reference (1:1)", { ecmaVersion: 2018 })
+test("/\\k<a>/", {}, { ecmaVersion: 2017 })
+test("/\\k<a>/", {}, { ecmaVersion: 2018 })
+testFail("/\\k<a>/u", "Invalid regular expression: /\\k<a>/: Invalid escape (1:1)", { ecmaVersion: 2017 })
+testFail("/\\k<a>/u", "Invalid regular expression: /\\k<a>/: Invalid named capture referenced (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\k</", "Invalid regular expression: /(?<a>a)\\k</: Invalid group (1:1)", { ecmaVersion: 2017 })
+testFail("/(?<a>a)\\k</", "Invalid regular expression: /(?<a>a)\\k</: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\k</u", "Invalid regular expression: /(?<a>a)\\k</: Invalid group (1:1)", { ecmaVersion: 2017 })
+testFail("/(?<a>a)\\k</u", "Invalid regular expression: /(?<a>a)\\k</: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\k<a/", "Invalid regular expression: /(?<a>a)\\k<a/: Invalid group (1:1)", { ecmaVersion: 2017 })
+testFail("/(?<a>a)\\k<a/", "Invalid regular expression: /(?<a>a)\\k<a/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\k<a/u", "Invalid regular expression: /(?<a>a)\\k<a/: Invalid group (1:1)", { ecmaVersion: 2017 })
+testFail("/(?<a>a)\\k<a/u", "Invalid regular expression: /(?<a>a)\\k<a/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\k<a>/", "Invalid regular expression: /(?<a>a)\\k<a>/: Invalid group (1:1)", { ecmaVersion: 2017 })
+test("/(?<a>a)\\k<a>/", {}, { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\k<a>/u", "Invalid regular expression: /(?<a>a)\\k<a>/: Invalid group (1:1)", { ecmaVersion: 2017 })
+test("/(?<a>a)\\k<a>/u", {}, { ecmaVersion: 2018 })
+
+test("/(?<a>a)\\1/", {}, { ecmaVersion: 2018 })
+test("/(?<a>a)\\1/u", {}, { ecmaVersion: 2018 })
+test("/(?<a>a)\\2/", {}, { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\2/u", "Invalid regular expression: /(?<a>a)\\2/: Invalid escape (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\k<b>/", "Invalid regular expression: /(?<a>a)\\k<b>/: Invalid named capture referenced (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)\\k<b>/u", "Invalid regular expression: /(?<a>a)\\k<b>/: Invalid named capture referenced (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)(?<a>a)/", "Invalid regular expression: /(?<a>a)(?<a>a)/: Duplicate capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)(?<a>a)/u", "Invalid regular expression: /(?<a>a)(?<a>a)/: Duplicate capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)(?<\\u{61}>a)/u", "Invalid regular expression: /(?<a>a)(?<\\u{61}>a)/: Duplicate capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a>a)(?<\\u0061>a)/u", "Invalid regular expression: /(?<a>a)(?<\\u0061>a)/: Duplicate capture group name (1:1)", { ecmaVersion: 2018 })
+test("/(?<a>a)(?<b>a)/", {}, { ecmaVersion: 2018 })
+test("/(?<a>a)(?<b>a)/u", {}, { ecmaVersion: 2018 })
+
+test("/\\k<a>(?<a>a)/", {}, { ecmaVersion: 2018 })
+test("/\\k<a>(?<a>a)/u", {}, { ecmaVersion: 2018 })
+test("/\\1(?<a>a)/", {}, { ecmaVersion: 2018 })
+test("/\\1(?<a>a)/u", {}, { ecmaVersion: 2018 })
+
+test("/(?<$abc>a)\\k<$abc>/u", {}, { ecmaVersion: 2018 })
+test("/(?<あ>a)\\k<あ>/u", {}, { ecmaVersion: 2018 })
+test("/(?<𠮷>a)\\k<\\u{20bb7}>/u", {}, { ecmaVersion: 2018 })
+test("/(?<\\uD842\\uDFB7>a)\\k<\\u{20bb7}>/u", {}, { ecmaVersion: 2018 })
+test("/(?<\\u{20bb7}>a)\\k<\\uD842\\uDFB7>/u", {}, { ecmaVersion: 2018 })
+testFail("/(?<☀>a)\\k<☀>/u", "Invalid regular expression: /(?<☀>a)\\k<☀>/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<\\u0020>a)\\k<\\u0020>/u", "Invalid regular expression: /(?<\\u0020>a)\\k<\\u0020>/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+test("/(?<abc>a)\\k<\\u0061\\u0062\\u0063>/u", {}, { ecmaVersion: 2018 })
+test("/(?<\\u0061\\u0062\\u0063>a)\\k<abc>/u", {}, { ecmaVersion: 2018 })
+test("/(?<\\u0061\\u0062\\u0063>a)\\k<\\u{61}\\u{62}\\u{63}>/u", {}, { ecmaVersion: 2018 })
+testFail("/(?<\\u0061\\u0062\\u0063>a)\\k<abd>/u", "Invalid regular expression: /(?<\\u0061\\u0062\\u0063>a)\\k<abd>/: Invalid named capture referenced (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<11>a)\\k<11>/u", "Invalid regular expression: /(?<11>a)\\k<11>/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+test("/(?<a1>a)\\k<a1>/u", {}, { ecmaVersion: 2018 })
+
+//------------------------------------------------------------------------------
+// Unicode property escapes
+//------------------------------------------------------------------------------
+
+test("/\\p/", {}, { ecmaVersion: 2017 })
+testFail("/\\p/u", "Invalid regular expression: /\\p/: Invalid escape (1:1)", { ecmaVersion: 2017 })
+test("/\\p/", {}, { ecmaVersion: 2018 })
+testFail("/\\p/u", "Invalid regular expression: /\\p/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+test("/\\p{/", {}, { ecmaVersion: 2017 })
+testFail("/\\p{/u", "Invalid regular expression: /\\p{/: Invalid escape (1:1)", { ecmaVersion: 2017 })
+test("/\\p{/", {}, { ecmaVersion: 2018 })
+testFail("/\\p{/u", "Invalid regular expression: /\\p{/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+test("/\\p{ASCII/", {}, { ecmaVersion: 2017 })
+testFail("/\\p{ASCII/u", "Invalid regular expression: /\\p{ASCII/: Invalid escape (1:1)", { ecmaVersion: 2017 })
+test("/\\p{ASCII/", {}, { ecmaVersion: 2018 })
+testFail("/\\p{ASCII/u", "Invalid regular expression: /\\p{ASCII/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+test("/\\p{ASCII}/", {}, { ecmaVersion: 2017 })
+testFail("/\\p{ASCII}/u", "Invalid regular expression: /\\p{ASCII}/: Invalid escape (1:1)", { ecmaVersion: 2017 })
+test("/\\p{ASCII}/", {}, { ecmaVersion: 2018 })
+test("/\\p{ASCII}/u", {}, { ecmaVersion: 2018 })
+
+test("/\\p{Emoji}/u", {}, { ecmaVersion: 2018 })
+testFail("/\\p{General_Category}/u", "Invalid regular expression: /\\p{General_Category}/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+testFail("/\\p{General_Category=}/u", "Invalid regular expression: /\\p{General_Category=}/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+testFail("/\\p{General_Category/u", "Invalid regular expression: /\\p{General_Category/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+testFail("/\\p{General_Category=/u", "Invalid regular expression: /\\p{General_Category=/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+testFail("/\\p{General_Category=Letter/u", "Invalid regular expression: /\\p{General_Category=Letter/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+test("/\\p{General_Category=Letter}/u", {}, { ecmaVersion: 2018 })
+testFail("/\\p{General_Category=Hiragana}/u", "Invalid regular expression: /\\p{General_Category=Hiragana}/: Invalid property name (1:1)", { ecmaVersion: 2018 })
+test("/\\p{Script=Hiragana}/u", {}, { ecmaVersion: 2018 })
+testFail("/[\\p{Script=Hiragana}-\\p{Script=Katakana}]/u", "Invalid regular expression: /[\\p{Script=Hiragana}-\\p{Script=Katakana}]/: Invalid character class (1:1)", { ecmaVersion: 2018 })
+test("/[\\p{Script=Hiragana}\\-\\p{Script=Katakana}]/u", {}, { ecmaVersion: 2018 })
+
+//------------------------------------------------------------------------------
+// Lookbehind assertions
+//------------------------------------------------------------------------------
+
+testFail("/(?<a)/", "Invalid regular expression: /(?<a)/: Invalid group (1:1)", { ecmaVersion: 2017 })
+testFail("/(?<a)/u", "Invalid regular expression: /(?<a)/: Invalid group (1:1)", { ecmaVersion: 2017 })
+testFail("/(?<a)/", "Invalid regular expression: /(?<a)/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<a)/u", "Invalid regular expression: /(?<a)/: Invalid capture group name (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<=a)/", "Invalid regular expression: /(?<=a)/: Invalid group (1:1)", { ecmaVersion: 2017 })
+testFail("/(?<=a)/u", "Invalid regular expression: /(?<=a)/: Invalid group (1:1)", { ecmaVersion: 2017 })
+test("/(?<=a)/", {}, { ecmaVersion: 2018 })
+test("/(?<=a)/u", {}, { ecmaVersion: 2018 })
+testFail("/(?<!a)/", "Invalid regular expression: /(?<!a)/: Invalid group (1:1)", { ecmaVersion: 2017 })
+testFail("/(?<!a)/u", "Invalid regular expression: /(?<!a)/: Invalid group (1:1)", { ecmaVersion: 2017 })
+test("/(?<!a)/", {}, { ecmaVersion: 2018 })
+test("/(?<!a)/u", {}, { ecmaVersion: 2018 })
+
+testFail("/(?<=a)?/", "Invalid regular expression: /(?<=a)?/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<=a)?/u", "Invalid regular expression: /(?<=a)?/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<=a)+/", "Invalid regular expression: /(?<=a)+/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<=a)+/u", "Invalid regular expression: /(?<=a)+/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<=a)*/", "Invalid regular expression: /(?<=a)*/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<=a)*/u", "Invalid regular expression: /(?<=a)*/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<=a){1}/", "Invalid regular expression: /(?<=a){1}/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<=a){1}/u", "Invalid regular expression: /(?<=a){1}/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+
+testFail("/(?<!a)?/", "Invalid regular expression: /(?<!a)?/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<!a)?/u", "Invalid regular expression: /(?<!a)?/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<!a)+/", "Invalid regular expression: /(?<!a)+/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<!a)+/u", "Invalid regular expression: /(?<!a)+/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<!a)*/", "Invalid regular expression: /(?<!a)*/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<!a)*/u", "Invalid regular expression: /(?<!a)*/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<!a){1}/", "Invalid regular expression: /(?<!a){1}/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+testFail("/(?<!a){1}/u", "Invalid regular expression: /(?<!a){1}/: Nothing to repeat (1:1)", { ecmaVersion: 2018 })
+
+test("/(?<=(?<a>\\w){3})f/u", {}, { ecmaVersion: 2018 })
+test("/((?<=\\w{3}))f/u", {}, { ecmaVersion: 2018 })
+test("/(?<a>(?<=\\w{3}))f/u", {}, { ecmaVersion: 2018 })
+test("/(?<!(?<a>\\d){3})f/u", {}, { ecmaVersion: 2018 })
+test("/(?<!(?<a>\\D){3})f|f/u", {}, { ecmaVersion: 2018 })
+test("/(?<a>(?<!\\D{3}))f|f/u", {}, { ecmaVersion: 2018 })
+test("/(?<=(?<a>\\w){3})f/", {}, { ecmaVersion: 2018 })
+test("/((?<=\\w{3}))f/", {}, { ecmaVersion: 2018 })
+test("/(?<a>(?<=\\w{3}))f/", {}, { ecmaVersion: 2018 })
+test("/(?<!(?<a>\\d){3})f/", {}, { ecmaVersion: 2018 })
+test("/(?<a>(?<!\\D{3}))f|f/", {}, { ecmaVersion: 2018 })
+test("/(?<=(?<fst>.)|(?<snd>.))/u", {}, { ecmaVersion: 2018 })
diff --git a/test/tests-regexp.js b/test/tests-regexp.js
new file mode 100644
index 0000000..6c47194
--- /dev/null
+++ b/test/tests-regexp.js
@@ -0,0 +1,1353 @@
+if (typeof exports != "undefined") {
+ var test = require("./driver.js").test
+ var testFail = require("./driver.js").testFail
+}
+
+test("/foo/", {}, { ecmaVersion: 5 })
+test("/foo/", {}, { ecmaVersion: 2015 })
+testFail("/foo/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/foo/u", {}, { ecmaVersion: 2015 })
+test("/foo|bar/", {}, { ecmaVersion: 5 })
+test("/foo|bar/", {}, { ecmaVersion: 2015 })
+testFail("/foo|bar/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/foo|bar/u", {}, { ecmaVersion: 2015 })
+test("/||||/", {}, { ecmaVersion: 5 })
+test("/||||/", {}, { ecmaVersion: 2015 })
+testFail("/||||/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/||||/u", {}, { ecmaVersion: 2015 })
+test("/^|$|\\b|\\B/", {}, { ecmaVersion: 5 })
+test("/^|$|\\b|\\B/", {}, { ecmaVersion: 2015 })
+testFail("/^|$|\\b|\\B/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^|$|\\b|\\B/u", {}, { ecmaVersion: 2015 })
+testFail("/(/", "Invalid regular expression: /(/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(/", "Invalid regular expression: /(/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(/u", "Invalid regular expression: /(/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?/", "Invalid regular expression: /(?/: Invalid group (1:1)", { ecmaVersion: 5 })
+testFail("/(?/", "Invalid regular expression: /(?/: Invalid group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?/u", "Invalid regular expression: /(?/: Invalid group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?=/", "Invalid regular expression: /(?=/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(?=/", "Invalid regular expression: /(?=/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?=/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=/u", "Invalid regular expression: /(?=/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+test("/(?=)/", {}, { ecmaVersion: 5 })
+test("/(?=)/", {}, { ecmaVersion: 2015 })
+testFail("/(?=)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/(?=)/u", {}, { ecmaVersion: 2015 })
+testFail("/(?=foo/", "Invalid regular expression: /(?=foo/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(?=foo/", "Invalid regular expression: /(?=foo/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?=foo/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=foo/u", "Invalid regular expression: /(?=foo/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+test("/(?=foo)/", {}, { ecmaVersion: 5 })
+test("/(?=foo)/", {}, { ecmaVersion: 2015 })
+testFail("/(?=foo)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/(?=foo)/u", {}, { ecmaVersion: 2015 })
+testFail("/(?!/", "Invalid regular expression: /(?!/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(?!/", "Invalid regular expression: /(?!/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?!/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?!/u", "Invalid regular expression: /(?!/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+test("/(?!)/", {}, { ecmaVersion: 5 })
+test("/(?!)/", {}, { ecmaVersion: 2015 })
+testFail("/(?!)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/(?!)/u", {}, { ecmaVersion: 2015 })
+testFail("/(?!foo/", "Invalid regular expression: /(?!foo/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(?!foo/", "Invalid regular expression: /(?!foo/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?!foo/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?!foo/u", "Invalid regular expression: /(?!foo/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+test("/(?!foo)/", {}, { ecmaVersion: 5 })
+test("/(?!foo)/", {}, { ecmaVersion: 2015 })
+testFail("/(?!foo)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/(?!foo)/u", {}, { ecmaVersion: 2015 })
+test("/(?=a)*/", {}, { ecmaVersion: 5 })
+test("/(?=a)*/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a)*/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a)*/u", "Invalid regular expression: /(?=a)*/: Invalid quantifier (1:1)", { ecmaVersion: 2015 })
+test("/(?=a)+/", {}, { ecmaVersion: 5 })
+test("/(?=a)+/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a)+/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a)+/u", "Invalid regular expression: /(?=a)+/: Invalid quantifier (1:1)", { ecmaVersion: 2015 })
+test("/(?=a)?/", {}, { ecmaVersion: 5 })
+test("/(?=a)?/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a)?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a)?/u", "Invalid regular expression: /(?=a)?/: Invalid quantifier (1:1)", { ecmaVersion: 2015 })
+test("/(?=a){/", {}, { ecmaVersion: 5 })
+test("/(?=a){/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a){/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a){/u", "Invalid regular expression: /(?=a){/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/(?=a){}/", {}, { ecmaVersion: 5 })
+test("/(?=a){}/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a){}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a){}/u", "Invalid regular expression: /(?=a){}/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/(?=a){a}/", {}, { ecmaVersion: 5 })
+test("/(?=a){a}/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a){a}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a){a}/u", "Invalid regular expression: /(?=a){a}/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/(?=a){1}/", {}, { ecmaVersion: 5 })
+test("/(?=a){1}/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a){1}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a){1}/u", "Invalid regular expression: /(?=a){1}/: Invalid quantifier (1:1)", { ecmaVersion: 2015 })
+test("/(?=a){1,}/", {}, { ecmaVersion: 5 })
+test("/(?=a){1,}/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a){1,}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a){1,}/u", "Invalid regular expression: /(?=a){1,}/: Invalid quantifier (1:1)", { ecmaVersion: 2015 })
+test("/(?=a){1,2}/", {}, { ecmaVersion: 5 })
+test("/(?=a){1,2}/", {}, { ecmaVersion: 2015 })
+testFail("/(?=a){1,2}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?=a){1,2}/u", "Invalid regular expression: /(?=a){1,2}/: Invalid quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a*/", {}, { ecmaVersion: 5 })
+test("/a*/", {}, { ecmaVersion: 2015 })
+testFail("/a*/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a*/u", {}, { ecmaVersion: 2015 })
+test("/a+/", {}, { ecmaVersion: 5 })
+test("/a+/", {}, { ecmaVersion: 2015 })
+testFail("/a+/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a+/u", {}, { ecmaVersion: 2015 })
+test("/a?/", {}, { ecmaVersion: 5 })
+test("/a?/", {}, { ecmaVersion: 2015 })
+testFail("/a?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a?/u", {}, { ecmaVersion: 2015 })
+test("/a{/", {}, { ecmaVersion: 5 })
+test("/a{/", {}, { ecmaVersion: 2015 })
+testFail("/a{/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{/u", "Invalid regular expression: /a{/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{}/", {}, { ecmaVersion: 5 })
+test("/a{}/", {}, { ecmaVersion: 2015 })
+testFail("/a{}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{}/u", "Invalid regular expression: /a{}/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{a}/", {}, { ecmaVersion: 5 })
+test("/a{a}/", {}, { ecmaVersion: 2015 })
+testFail("/a{a}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{a}/u", "Invalid regular expression: /a{a}/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{1}/", {}, { ecmaVersion: 5 })
+test("/a{1}/", {}, { ecmaVersion: 2015 })
+testFail("/a{1}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a{1}/u", {}, { ecmaVersion: 2015 })
+test("/a{1/", {}, { ecmaVersion: 5 })
+test("/a{1/", {}, { ecmaVersion: 2015 })
+testFail("/a{1/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{1/u", "Invalid regular expression: /a{1/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{1,}/", {}, { ecmaVersion: 5 })
+test("/a{1,}/", {}, { ecmaVersion: 2015 })
+testFail("/a{1,}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a{1,}/u", {}, { ecmaVersion: 2015 })
+test("/a{1,/", {}, { ecmaVersion: 5 })
+test("/a{1,/", {}, { ecmaVersion: 2015 })
+testFail("/a{1,/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{1,/u", "Invalid regular expression: /a{1,/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{1,2}/", {}, { ecmaVersion: 5 })
+test("/a{1,2}/", {}, { ecmaVersion: 2015 })
+testFail("/a{1,2}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a{1,2}/u", {}, { ecmaVersion: 2015 })
+test("/a{1,2/", {}, { ecmaVersion: 5 })
+test("/a{1,2/", {}, { ecmaVersion: 2015 })
+testFail("/a{1,2/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{1,2/u", "Invalid regular expression: /a{1,2/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+testFail("/a{2,1}/", "Invalid regular expression: /a{2,1}/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 5 })
+testFail("/a{2,1}/", "Invalid regular expression: /a{2,1}/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 2015 })
+testFail("/a{2,1}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{2,1}/u", "Invalid regular expression: /a{2,1}/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{2,1/", {}, { ecmaVersion: 5 })
+test("/a{2,1/", {}, { ecmaVersion: 2015 })
+testFail("/a{2,1/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{2,1/u", "Invalid regular expression: /a{2,1/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+testFail("/(a{2,1}/", "Invalid regular expression: /(a{2,1}/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 5 })
+testFail("/(a{2,1}/", "Invalid regular expression: /(a{2,1}/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 2015 })
+testFail("/(a{2,1}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(a{2,1}/u", "Invalid regular expression: /(a{2,1}/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a*?/", {}, { ecmaVersion: 5 })
+test("/a*?/", {}, { ecmaVersion: 2015 })
+testFail("/a*?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a*?/u", {}, { ecmaVersion: 2015 })
+test("/a+?/", {}, { ecmaVersion: 5 })
+test("/a+?/", {}, { ecmaVersion: 2015 })
+testFail("/a+?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a+?/u", {}, { ecmaVersion: 2015 })
+test("/a??/", {}, { ecmaVersion: 5 })
+test("/a??/", {}, { ecmaVersion: 2015 })
+testFail("/a??/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a??/u", {}, { ecmaVersion: 2015 })
+test("/a{?/", {}, { ecmaVersion: 5 })
+test("/a{?/", {}, { ecmaVersion: 2015 })
+testFail("/a{?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{?/u", "Invalid regular expression: /a{?/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{}?/", {}, { ecmaVersion: 5 })
+test("/a{}?/", {}, { ecmaVersion: 2015 })
+testFail("/a{}?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{}?/u", "Invalid regular expression: /a{}?/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{a}?/", {}, { ecmaVersion: 5 })
+test("/a{a}?/", {}, { ecmaVersion: 2015 })
+testFail("/a{a}?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{a}?/u", "Invalid regular expression: /a{a}?/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{1}?/", {}, { ecmaVersion: 5 })
+test("/a{1}?/", {}, { ecmaVersion: 2015 })
+testFail("/a{1}?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a{1}?/u", {}, { ecmaVersion: 2015 })
+test("/a{1?/", {}, { ecmaVersion: 5 })
+test("/a{1?/", {}, { ecmaVersion: 2015 })
+testFail("/a{1?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{1?/u", "Invalid regular expression: /a{1?/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{1,}?/", {}, { ecmaVersion: 5 })
+test("/a{1,}?/", {}, { ecmaVersion: 2015 })
+testFail("/a{1,}?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a{1,}?/u", {}, { ecmaVersion: 2015 })
+test("/a{1,?/", {}, { ecmaVersion: 5 })
+test("/a{1,?/", {}, { ecmaVersion: 2015 })
+testFail("/a{1,?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{1,?/u", "Invalid regular expression: /a{1,?/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{1,2}?/", {}, { ecmaVersion: 5 })
+test("/a{1,2}?/", {}, { ecmaVersion: 2015 })
+testFail("/a{1,2}?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/a{1,2}?/u", {}, { ecmaVersion: 2015 })
+test("/a{1,2?/", {}, { ecmaVersion: 5 })
+test("/a{1,2?/", {}, { ecmaVersion: 2015 })
+testFail("/a{1,2?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{1,2?/u", "Invalid regular expression: /a{1,2?/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+testFail("/a{2,1}?/", "Invalid regular expression: /a{2,1}?/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 5 })
+testFail("/a{2,1}?/", "Invalid regular expression: /a{2,1}?/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 2015 })
+testFail("/a{2,1}?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{2,1}?/u", "Invalid regular expression: /a{2,1}?/: numbers out of order in {} quantifier (1:1)", { ecmaVersion: 2015 })
+test("/a{2,1?/", {}, { ecmaVersion: 5 })
+test("/a{2,1?/", {}, { ecmaVersion: 2015 })
+testFail("/a{2,1?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/a{2,1?/u", "Invalid regular expression: /a{2,1?/: Incomplete quantifier (1:1)", { ecmaVersion: 2015 })
+test("/👍🚀❇️/", {}, { ecmaVersion: 5 })
+test("/👍🚀❇️/", {}, { ecmaVersion: 2015 })
+testFail("/👍🚀❇️/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/👍🚀❇️/u", {}, { ecmaVersion: 2015 })
+test("/^/", {}, { ecmaVersion: 5 })
+test("/^/", {}, { ecmaVersion: 2015 })
+testFail("/^/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^/u", {}, { ecmaVersion: 2015 })
+test("/$/", {}, { ecmaVersion: 5 })
+test("/$/", {}, { ecmaVersion: 2015 })
+testFail("/$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/$/u", {}, { ecmaVersion: 2015 })
+test("/./", {}, { ecmaVersion: 5 })
+test("/./", {}, { ecmaVersion: 2015 })
+testFail("/./u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/./u", {}, { ecmaVersion: 2015 })
+testFail("/(*)/", "Invalid regular expression: /(*)/: Nothing to repeat (1:1)", { ecmaVersion: 5 })
+testFail("/(*)/", "Invalid regular expression: /(*)/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/(*)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(*)/u", "Invalid regular expression: /(*)/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/+/", "Invalid regular expression: /+/: Nothing to repeat (1:1)", { ecmaVersion: 5 })
+testFail("/+/", "Invalid regular expression: /+/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/+/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/+/u", "Invalid regular expression: /+/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/?/", "Invalid regular expression: /?/: Nothing to repeat (1:1)", { ecmaVersion: 5 })
+testFail("/?/", "Invalid regular expression: /?/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/?/u", "Invalid regular expression: /?/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/(/", "Invalid regular expression: /(/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(/", "Invalid regular expression: /(/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(/u", "Invalid regular expression: /(/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/)/", "Invalid regular expression: /)/: Unmatched ')' (1:1)", { ecmaVersion: 5 })
+testFail("/)/", "Invalid regular expression: /)/: Unmatched ')' (1:1)", { ecmaVersion: 2015 })
+testFail("/)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/)/u", "Invalid regular expression: /)/: Unmatched ')' (1:1)", { ecmaVersion: 2015 })
+testFail("/[/", "Unterminated regular expression (1:1)", { ecmaVersion: 5 })
+testFail("/[/", "Unterminated regular expression (1:1)", { ecmaVersion: 2015 })
+testFail("/[/u", "Unterminated regular expression (1:1)", { ecmaVersion: 5 })
+testFail("/[/u", "Unterminated regular expression (1:1)", { ecmaVersion: 2015 })
+test("/]/", {}, { ecmaVersion: 5 })
+test("/]/", {}, { ecmaVersion: 2015 })
+testFail("/]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/]/u", "Invalid regular expression: /]/: Lone quantifier brackets (1:1)", { ecmaVersion: 2015 })
+test("/{/", {}, { ecmaVersion: 5 })
+test("/{/", {}, { ecmaVersion: 2015 })
+testFail("/{/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/{/u", "Invalid regular expression: /{/: Lone quantifier brackets (1:1)", { ecmaVersion: 2015 })
+test("/}/", {}, { ecmaVersion: 5 })
+test("/}/", {}, { ecmaVersion: 2015 })
+testFail("/}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/}/u", "Invalid regular expression: /}/: Lone quantifier brackets (1:1)", { ecmaVersion: 2015 })
+test("/|/", {}, { ecmaVersion: 5 })
+test("/|/", {}, { ecmaVersion: 2015 })
+testFail("/|/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/|/u", {}, { ecmaVersion: 2015 })
+testFail("/^*/", "Invalid regular expression: /^*/: Nothing to repeat (1:1)", { ecmaVersion: 5 })
+testFail("/^*/", "Invalid regular expression: /^*/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/^*/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/^*/u", "Invalid regular expression: /^*/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/$*/", "Invalid regular expression: /$*/: Nothing to repeat (1:1)", { ecmaVersion: 5 })
+testFail("/$*/", "Invalid regular expression: /$*/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/$*/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/$*/u", "Invalid regular expression: /$*/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+test("/${1,2/", {}, { ecmaVersion: 5 })
+test("/${1,2/", {}, { ecmaVersion: 2015 })
+testFail("/${1,2/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/${1,2/u", "Invalid regular expression: /${1,2/: Lone quantifier brackets (1:1)", { ecmaVersion: 2015 })
+testFail("/${1,2}/", "Invalid regular expression: /${1,2}/: Nothing to repeat (1:1)", { ecmaVersion: 5 })
+testFail("/${1,2}/", "Invalid regular expression: /${1,2}/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/${1,2}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/${1,2}/u", "Invalid regular expression: /${1,2}/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/${2,1}/", "Invalid regular expression: /${2,1}/: Nothing to repeat (1:1)", { ecmaVersion: 5 })
+testFail("/${2,1}/", "Invalid regular expression: /${2,1}/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+testFail("/${2,1}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/${2,1}/u", "Invalid regular expression: /${2,1}/: Nothing to repeat (1:1)", { ecmaVersion: 2015 })
+test("/\\1/", {}, { ecmaVersion: 5 })
+test("/\\1/", {}, { ecmaVersion: 2015 })
+testFail("/\\1/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\1/u", "Invalid regular expression: /\\1/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/(a)\\1/", {}, { ecmaVersion: 5 })
+test("/(a)\\1/", {}, { ecmaVersion: 2015 })
+testFail("/(a)\\1/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/(a)\\1/u", {}, { ecmaVersion: 2015 })
+test("/\\1(a)/", {}, { ecmaVersion: 5 })
+test("/\\1(a)/", {}, { ecmaVersion: 2015 })
+testFail("/\\1(a)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\1(a)/u", {}, { ecmaVersion: 2015 })
+testFail("/\\2(a)(/", "Invalid regular expression: /\\2(a)(/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/\\2(a)(/", "Invalid regular expression: /\\2(a)(/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/\\2(a)(/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\2(a)(/u", "Invalid regular expression: /\\2(a)(/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+test("/(?:a)\\1/", {}, { ecmaVersion: 5 })
+test("/(?:a)\\1/", {}, { ecmaVersion: 2015 })
+testFail("/(?:a)\\1/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?:a)\\1/u", "Invalid regular expression: /(?:a)\\1/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/(a)\\2/", {}, { ecmaVersion: 5 })
+test("/(a)\\2/", {}, { ecmaVersion: 2015 })
+testFail("/(a)\\2/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(a)\\2/u", "Invalid regular expression: /(a)\\2/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/(?:a)\\2/", {}, { ecmaVersion: 5 })
+test("/(?:a)\\2/", {}, { ecmaVersion: 2015 })
+testFail("/(?:a)\\2/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?:a)\\2/u", "Invalid regular expression: /(?:a)\\2/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\10/", {}, { ecmaVersion: 5 })
+test("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\10/", {}, { ecmaVersion: 2015 })
+testFail("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\10/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\10/u", {}, { ecmaVersion: 2015 })
+test("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/", {}, { ecmaVersion: 5 })
+test("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/", {}, { ecmaVersion: 2015 })
+testFail("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/u", "Invalid regular expression: /(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/", {}, { ecmaVersion: 5 })
+test("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/", {}, { ecmaVersion: 2015 })
+testFail("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11/u", {}, { ecmaVersion: 2015 })
+testFail("/(?/", "Invalid regular expression: /(?/: Invalid group (1:1)", { ecmaVersion: 5 })
+testFail("/(?/", "Invalid regular expression: /(?/: Invalid group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?/u", "Invalid regular expression: /(?/: Invalid group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?a/", "Invalid regular expression: /(?a/: Invalid group (1:1)", { ecmaVersion: 5 })
+testFail("/(?a/", "Invalid regular expression: /(?a/: Invalid group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?a/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?a/u", "Invalid regular expression: /(?a/: Invalid group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?a)/", "Invalid regular expression: /(?a)/: Invalid group (1:1)", { ecmaVersion: 5 })
+testFail("/(?a)/", "Invalid regular expression: /(?a)/: Invalid group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?a)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?a)/u", "Invalid regular expression: /(?a)/: Invalid group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?:/", "Invalid regular expression: /(?:/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(?:/", "Invalid regular expression: /(?:/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?:/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?:/u", "Invalid regular expression: /(?:/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?:a/", "Invalid regular expression: /(?:a/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(?:a/", "Invalid regular expression: /(?:a/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(?:a/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(?:a/u", "Invalid regular expression: /(?:a/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+test("/(?:a)/", {}, { ecmaVersion: 5 })
+test("/(?:a)/", {}, { ecmaVersion: 2015 })
+testFail("/(?:a)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/(?:a)/u", {}, { ecmaVersion: 2015 })
+testFail("/(:a/", "Invalid regular expression: /(:a/: Unterminated group (1:1)", { ecmaVersion: 5 })
+testFail("/(:a/", "Invalid regular expression: /(:a/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+testFail("/(:a/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/(:a/u", "Invalid regular expression: /(:a/: Unterminated group (1:1)", { ecmaVersion: 2015 })
+test("/\\d/", {}, { ecmaVersion: 5 })
+test("/\\d/", {}, { ecmaVersion: 2015 })
+testFail("/\\d/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\d/u", {}, { ecmaVersion: 2015 })
+test("/\\D/", {}, { ecmaVersion: 5 })
+test("/\\D/", {}, { ecmaVersion: 2015 })
+testFail("/\\D/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\D/u", {}, { ecmaVersion: 2015 })
+test("/\\s/", {}, { ecmaVersion: 5 })
+test("/\\s/", {}, { ecmaVersion: 2015 })
+testFail("/\\s/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\s/u", {}, { ecmaVersion: 2015 })
+test("/\\S/", {}, { ecmaVersion: 5 })
+test("/\\S/", {}, { ecmaVersion: 2015 })
+testFail("/\\S/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\S/u", {}, { ecmaVersion: 2015 })
+test("/\\w/", {}, { ecmaVersion: 5 })
+test("/\\w/", {}, { ecmaVersion: 2015 })
+testFail("/\\w/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\w/u", {}, { ecmaVersion: 2015 })
+test("/\\W/", {}, { ecmaVersion: 5 })
+test("/\\W/", {}, { ecmaVersion: 2015 })
+testFail("/\\W/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\W/u", {}, { ecmaVersion: 2015 })
+test("/\\f/", {}, { ecmaVersion: 5 })
+test("/\\f/", {}, { ecmaVersion: 2015 })
+testFail("/\\f/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\f/u", {}, { ecmaVersion: 2015 })
+test("/\\n/", {}, { ecmaVersion: 5 })
+test("/\\n/", {}, { ecmaVersion: 2015 })
+testFail("/\\n/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\n/u", {}, { ecmaVersion: 2015 })
+test("/\\r/", {}, { ecmaVersion: 5 })
+test("/\\r/", {}, { ecmaVersion: 2015 })
+testFail("/\\r/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\r/u", {}, { ecmaVersion: 2015 })
+test("/\\t/", {}, { ecmaVersion: 5 })
+test("/\\t/", {}, { ecmaVersion: 2015 })
+testFail("/\\t/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\t/u", {}, { ecmaVersion: 2015 })
+test("/\\v/", {}, { ecmaVersion: 5 })
+test("/\\v/", {}, { ecmaVersion: 2015 })
+testFail("/\\v/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\v/u", {}, { ecmaVersion: 2015 })
+test("/\\cA/", {}, { ecmaVersion: 5 })
+test("/\\cA/", {}, { ecmaVersion: 2015 })
+testFail("/\\cA/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\cA/u", {}, { ecmaVersion: 2015 })
+test("/\\cz/", {}, { ecmaVersion: 5 })
+test("/\\cz/", {}, { ecmaVersion: 2015 })
+testFail("/\\cz/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\cz/u", {}, { ecmaVersion: 2015 })
+test("/\\c1/", {}, { ecmaVersion: 5 })
+test("/\\c1/", {}, { ecmaVersion: 2015 })
+testFail("/\\c1/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\c1/u", "Invalid regular expression: /\\c1/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\c/", {}, { ecmaVersion: 5 })
+test("/\\c/", {}, { ecmaVersion: 2015 })
+testFail("/\\c/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\c/u", "Invalid regular expression: /\\c/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\0/", {}, { ecmaVersion: 5 })
+test("/\\0/", {}, { ecmaVersion: 2015 })
+testFail("/\\0/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\0/u", {}, { ecmaVersion: 2015 })
+test("/\\u/", {}, { ecmaVersion: 5 })
+test("/\\u/", {}, { ecmaVersion: 2015 })
+testFail("/\\u/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\u/u", "Invalid regular expression: /\\u/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\u1/", {}, { ecmaVersion: 5 })
+test("/\\u1/", {}, { ecmaVersion: 2015 })
+testFail("/\\u1/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\u1/u", "Invalid regular expression: /\\u1/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\u12/", {}, { ecmaVersion: 5 })
+test("/\\u12/", {}, { ecmaVersion: 2015 })
+testFail("/\\u12/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\u12/u", "Invalid regular expression: /\\u12/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\u123/", {}, { ecmaVersion: 5 })
+test("/\\u123/", {}, { ecmaVersion: 2015 })
+testFail("/\\u123/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\u123/u", "Invalid regular expression: /\\u123/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\u1234/", {}, { ecmaVersion: 5 })
+test("/\\u1234/", {}, { ecmaVersion: 2015 })
+testFail("/\\u1234/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\u1234/u", {}, { ecmaVersion: 2015 })
+test("/\\u12345/", {}, { ecmaVersion: 5 })
+test("/\\u12345/", {}, { ecmaVersion: 2015 })
+testFail("/\\u12345/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\u12345/u", {}, { ecmaVersion: 2015 })
+test("/\\u{/", {}, { ecmaVersion: 5 })
+test("/\\u{/", {}, { ecmaVersion: 2015 })
+testFail("/\\u{/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\u{/u", "Invalid regular expression: /\\u{/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\u{z/", {}, { ecmaVersion: 5 })
+test("/\\u{z/", {}, { ecmaVersion: 2015 })
+testFail("/\\u{z/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\u{z/u", "Invalid regular expression: /\\u{z/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\u{a}/", {}, { ecmaVersion: 5 })
+test("/\\u{a}/", {}, { ecmaVersion: 2015 })
+testFail("/\\u{a}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\u{a}/u", {}, { ecmaVersion: 2015 })
+test("/\\u{20/", {}, { ecmaVersion: 5 })
+test("/\\u{20/", {}, { ecmaVersion: 2015 })
+testFail("/\\u{20/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\u{20/u", "Invalid regular expression: /\\u{20/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\u{20}/", {}, { ecmaVersion: 5 })
+test("/\\u{20}/", {}, { ecmaVersion: 2015 })
+testFail("/\\u{20}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\u{20}/u", {}, { ecmaVersion: 2015 })
+test("/\\u{10FFFF}/", {}, { ecmaVersion: 5 })
+test("/\\u{10FFFF}/", {}, { ecmaVersion: 2015 })
+testFail("/\\u{10FFFF}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\u{10FFFF}/u", {}, { ecmaVersion: 2015 })
+test("/\\u{110000}/", {}, { ecmaVersion: 5 })
+test("/\\u{110000}/", {}, { ecmaVersion: 2015 })
+testFail("/\\u{110000}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\u{110000}/u", "Invalid regular expression: /\\u{110000}/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/\\u{00000001}/", {}, { ecmaVersion: 5 })
+test("/\\u{00000001}/", {}, { ecmaVersion: 2015 })
+testFail("/\\u{00000001}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\u{00000001}/u", {}, { ecmaVersion: 2015 })
+test("/\\377/", {}, { ecmaVersion: 5 })
+test("/\\377/", {}, { ecmaVersion: 2015 })
+testFail("/\\377/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\377/u", "Invalid regular expression: /\\377/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/\\400/", {}, { ecmaVersion: 5 })
+test("/\\400/", {}, { ecmaVersion: 2015 })
+testFail("/\\400/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\400/u", "Invalid regular expression: /\\400/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/\\^/", {}, { ecmaVersion: 5 })
+test("/\\^/", {}, { ecmaVersion: 2015 })
+testFail("/\\^/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\^/u", {}, { ecmaVersion: 2015 })
+test("/\\$/", {}, { ecmaVersion: 5 })
+test("/\\$/", {}, { ecmaVersion: 2015 })
+testFail("/\\$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\$/u", {}, { ecmaVersion: 2015 })
+test("/\\./", {}, { ecmaVersion: 5 })
+test("/\\./", {}, { ecmaVersion: 2015 })
+testFail("/\\./u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\./u", {}, { ecmaVersion: 2015 })
+test("/\\+/", {}, { ecmaVersion: 5 })
+test("/\\+/", {}, { ecmaVersion: 2015 })
+testFail("/\\+/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\+/u", {}, { ecmaVersion: 2015 })
+test("/\\?/", {}, { ecmaVersion: 5 })
+test("/\\?/", {}, { ecmaVersion: 2015 })
+testFail("/\\?/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\?/u", {}, { ecmaVersion: 2015 })
+test("/\\(/", {}, { ecmaVersion: 5 })
+test("/\\(/", {}, { ecmaVersion: 2015 })
+testFail("/\\(/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\(/u", {}, { ecmaVersion: 2015 })
+test("/\\)/", {}, { ecmaVersion: 5 })
+test("/\\)/", {}, { ecmaVersion: 2015 })
+testFail("/\\)/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\)/u", {}, { ecmaVersion: 2015 })
+test("/\\[/", {}, { ecmaVersion: 5 })
+test("/\\[/", {}, { ecmaVersion: 2015 })
+testFail("/\\[/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\[/u", {}, { ecmaVersion: 2015 })
+test("/\\]/", {}, { ecmaVersion: 5 })
+test("/\\]/", {}, { ecmaVersion: 2015 })
+testFail("/\\]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\]/u", {}, { ecmaVersion: 2015 })
+test("/\\{/", {}, { ecmaVersion: 5 })
+test("/\\{/", {}, { ecmaVersion: 2015 })
+testFail("/\\{/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\{/u", {}, { ecmaVersion: 2015 })
+test("/\\}/", {}, { ecmaVersion: 5 })
+test("/\\}/", {}, { ecmaVersion: 2015 })
+testFail("/\\}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\}/u", {}, { ecmaVersion: 2015 })
+test("/\\|/", {}, { ecmaVersion: 5 })
+test("/\\|/", {}, { ecmaVersion: 2015 })
+testFail("/\\|/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\|/u", {}, { ecmaVersion: 2015 })
+test("/\\//", {}, { ecmaVersion: 5 })
+test("/\\//", {}, { ecmaVersion: 2015 })
+testFail("/\\//u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\//u", {}, { ecmaVersion: 2015 })
+test("/\\a/", {}, { ecmaVersion: 5 })
+test("/\\a/", {}, { ecmaVersion: 2015 })
+testFail("/\\a/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/\\a/u", "Invalid regular expression: /\\a/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/\\s/", {}, { ecmaVersion: 5 })
+test("/\\s/", {}, { ecmaVersion: 2015 })
+testFail("/\\s/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/\\s/u", {}, { ecmaVersion: 2015 })
+test("/[]/", {}, { ecmaVersion: 5 })
+test("/[]/", {}, { ecmaVersion: 2015 })
+testFail("/[]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[]/u", {}, { ecmaVersion: 2015 })
+test("/[^-a-b-]/", {}, { ecmaVersion: 5 })
+test("/[^-a-b-]/", {}, { ecmaVersion: 2015 })
+testFail("/[^-a-b-]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[^-a-b-]/u", {}, { ecmaVersion: 2015 })
+test("/[-]/", {}, { ecmaVersion: 5 })
+test("/[-]/", {}, { ecmaVersion: 2015 })
+testFail("/[-]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[-]/u", {}, { ecmaVersion: 2015 })
+test("/[a]/", {}, { ecmaVersion: 5 })
+test("/[a]/", {}, { ecmaVersion: 2015 })
+testFail("/[a]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[a]/u", {}, { ecmaVersion: 2015 })
+test("/[--]/", {}, { ecmaVersion: 5 })
+test("/[--]/", {}, { ecmaVersion: 2015 })
+testFail("/[--]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[--]/u", {}, { ecmaVersion: 2015 })
+test("/[-a]/", {}, { ecmaVersion: 5 })
+test("/[-a]/", {}, { ecmaVersion: 2015 })
+testFail("/[-a]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[-a]/u", {}, { ecmaVersion: 2015 })
+test("/[-a-]/", {}, { ecmaVersion: 5 })
+test("/[-a-]/", {}, { ecmaVersion: 2015 })
+testFail("/[-a-]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[-a-]/u", {}, { ecmaVersion: 2015 })
+test("/[a-]/", {}, { ecmaVersion: 5 })
+test("/[a-]/", {}, { ecmaVersion: 2015 })
+testFail("/[a-]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[a-]/u", {}, { ecmaVersion: 2015 })
+test("/[a-b]/", {}, { ecmaVersion: 5 })
+test("/[a-b]/", {}, { ecmaVersion: 2015 })
+testFail("/[a-b]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[a-b]/u", {}, { ecmaVersion: 2015 })
+test("/[-a-b-]/", {}, { ecmaVersion: 5 })
+test("/[-a-b-]/", {}, { ecmaVersion: 2015 })
+testFail("/[-a-b-]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[-a-b-]/u", {}, { ecmaVersion: 2015 })
+test("/[---]/", {}, { ecmaVersion: 5 })
+test("/[---]/", {}, { ecmaVersion: 2015 })
+testFail("/[---]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[---]/u", {}, { ecmaVersion: 2015 })
+testFail("/[b-a]/", "Invalid regular expression: /[b-a]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[b-a]/", "Invalid regular expression: /[b-a]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[b-a]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[b-a]/u", "Invalid regular expression: /[b-a]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+test("/[a-b--/]/", {}, { ecmaVersion: 5 })
+test("/[a-b--/]/", {}, { ecmaVersion: 2015 })
+testFail("/[a-b--/]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[a-b--/]/u", {}, { ecmaVersion: 2015 })
+testFail("/[a-b--+]/", "Invalid regular expression: /[a-b--+]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[a-b--+]/", "Invalid regular expression: /[a-b--+]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[a-b--+]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[a-b--+]/u", "Invalid regular expression: /[a-b--+]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\b-\\n]/", {}, { ecmaVersion: 5 })
+test("/[\\b-\\n]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\b-\\n]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\b-\\n]/u", {}, { ecmaVersion: 2015 })
+test("/[b\\-a]/", {}, { ecmaVersion: 5 })
+test("/[b\\-a]/", {}, { ecmaVersion: 2015 })
+testFail("/[b\\-a]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[b\\-a]/u", {}, { ecmaVersion: 2015 })
+test("/[\\d]/", {}, { ecmaVersion: 5 })
+test("/[\\d]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\d]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\d]/u", {}, { ecmaVersion: 2015 })
+test("/[\\D]/", {}, { ecmaVersion: 5 })
+test("/[\\D]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\D]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\D]/u", {}, { ecmaVersion: 2015 })
+test("/[\\s]/", {}, { ecmaVersion: 5 })
+test("/[\\s]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\s]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\s]/u", {}, { ecmaVersion: 2015 })
+test("/[\\S]/", {}, { ecmaVersion: 5 })
+test("/[\\S]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\S]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\S]/u", {}, { ecmaVersion: 2015 })
+test("/[\\w]/", {}, { ecmaVersion: 5 })
+test("/[\\w]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\w]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\w]/u", {}, { ecmaVersion: 2015 })
+test("/[\\W]/", {}, { ecmaVersion: 5 })
+test("/[\\W]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\W]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\W]/u", {}, { ecmaVersion: 2015 })
+test("/[\\d]/", {}, { ecmaVersion: 5 })
+test("/[\\d]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\d]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\d]/u", {}, { ecmaVersion: 2015 })
+test("/[\\D]/", {}, { ecmaVersion: 5 })
+test("/[\\D]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\D]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\D]/u", {}, { ecmaVersion: 2015 })
+test("/[\\s]/", {}, { ecmaVersion: 5 })
+test("/[\\s]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\s]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\s]/u", {}, { ecmaVersion: 2015 })
+test("/[\\S]/", {}, { ecmaVersion: 5 })
+test("/[\\S]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\S]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\S]/u", {}, { ecmaVersion: 2015 })
+test("/[\\w]/", {}, { ecmaVersion: 5 })
+test("/[\\w]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\w]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\w]/u", {}, { ecmaVersion: 2015 })
+test("/[\\W]/", {}, { ecmaVersion: 5 })
+test("/[\\W]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\W]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\W]/u", {}, { ecmaVersion: 2015 })
+test("/[\\f]/", {}, { ecmaVersion: 5 })
+test("/[\\f]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\f]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\f]/u", {}, { ecmaVersion: 2015 })
+test("/[\\n]/", {}, { ecmaVersion: 5 })
+test("/[\\n]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\n]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\n]/u", {}, { ecmaVersion: 2015 })
+test("/[\\r]/", {}, { ecmaVersion: 5 })
+test("/[\\r]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\r]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\r]/u", {}, { ecmaVersion: 2015 })
+test("/[\\t]/", {}, { ecmaVersion: 5 })
+test("/[\\t]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\t]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\t]/u", {}, { ecmaVersion: 2015 })
+test("/[\\v]/", {}, { ecmaVersion: 5 })
+test("/[\\v]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\v]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\v]/u", {}, { ecmaVersion: 2015 })
+test("/[\\cA]/", {}, { ecmaVersion: 5 })
+test("/[\\cA]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\cA]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\cA]/u", {}, { ecmaVersion: 2015 })
+test("/[\\cz]/", {}, { ecmaVersion: 5 })
+test("/[\\cz]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\cz]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\cz]/u", {}, { ecmaVersion: 2015 })
+test("/[\\c1]/", {}, { ecmaVersion: 5 })
+test("/[\\c1]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\c1]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\c1]/u", "Invalid regular expression: /[\\c1]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\c]/", {}, { ecmaVersion: 5 })
+test("/[\\c]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\c]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\c]/u", "Invalid regular expression: /[\\c]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\0]/", {}, { ecmaVersion: 5 })
+test("/[\\0]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\0]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\0]/u", {}, { ecmaVersion: 2015 })
+test("/[\\x]/", {}, { ecmaVersion: 5 })
+test("/[\\x]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\x]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\x]/u", "Invalid regular expression: /[\\x]/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\xz]/", {}, { ecmaVersion: 5 })
+test("/[\\xz]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\xz]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\xz]/u", "Invalid regular expression: /[\\xz]/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\x1]/", {}, { ecmaVersion: 5 })
+test("/[\\x1]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\x1]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\x1]/u", "Invalid regular expression: /[\\x1]/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\x12]/", {}, { ecmaVersion: 5 })
+test("/[\\x12]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\x12]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\x12]/u", {}, { ecmaVersion: 2015 })
+test("/[\\x123]/", {}, { ecmaVersion: 5 })
+test("/[\\x123]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\x123]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\x123]/u", {}, { ecmaVersion: 2015 })
+test("/[\\u]/", {}, { ecmaVersion: 5 })
+test("/[\\u]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u]/u", "Invalid regular expression: /[\\u]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\u1]/", {}, { ecmaVersion: 5 })
+test("/[\\u1]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u1]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u1]/u", "Invalid regular expression: /[\\u1]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\u12]/", {}, { ecmaVersion: 5 })
+test("/[\\u12]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u12]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u12]/u", "Invalid regular expression: /[\\u12]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\u123]/", {}, { ecmaVersion: 5 })
+test("/[\\u123]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u123]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u123]/u", "Invalid regular expression: /[\\u123]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\u1234]/", {}, { ecmaVersion: 5 })
+test("/[\\u1234]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u1234]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\u1234]/u", {}, { ecmaVersion: 2015 })
+test("/[\\u12345]/", {}, { ecmaVersion: 5 })
+test("/[\\u12345]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u12345]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\u12345]/u", {}, { ecmaVersion: 2015 })
+test("/[\\u{]/", {}, { ecmaVersion: 5 })
+test("/[\\u{]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u{]/u", "Invalid regular expression: /[\\u{]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\u{z]/", {}, { ecmaVersion: 5 })
+test("/[\\u{z]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{z]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u{z]/u", "Invalid regular expression: /[\\u{z]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\u{a}]/", {}, { ecmaVersion: 5 })
+test("/[\\u{a}]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{a}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\u{a}]/u", {}, { ecmaVersion: 2015 })
+test("/[\\u{20]/", {}, { ecmaVersion: 5 })
+test("/[\\u{20]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{20]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u{20]/u", "Invalid regular expression: /[\\u{20]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\u{20}]/", {}, { ecmaVersion: 5 })
+test("/[\\u{20}]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{20}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\u{20}]/u", {}, { ecmaVersion: 2015 })
+test("/[\\u{10FFFF}]/", {}, { ecmaVersion: 5 })
+test("/[\\u{10FFFF}]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{10FFFF}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\u{10FFFF}]/u", {}, { ecmaVersion: 2015 })
+test("/[\\u{110000}]/", {}, { ecmaVersion: 5 })
+test("/[\\u{110000}]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{110000}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u{110000}]/u", "Invalid regular expression: /[\\u{110000}]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\u{00000001}]/", {}, { ecmaVersion: 5 })
+test("/[\\u{00000001}]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{00000001}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\u{00000001}]/u", {}, { ecmaVersion: 2015 })
+test("/[\\77]/", {}, { ecmaVersion: 5 })
+test("/[\\77]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\77]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\77]/u", "Invalid regular expression: /[\\77]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\377]/", {}, { ecmaVersion: 5 })
+test("/[\\377]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\377]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\377]/u", "Invalid regular expression: /[\\377]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\400]/", {}, { ecmaVersion: 5 })
+test("/[\\400]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\400]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\400]/u", "Invalid regular expression: /[\\400]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\^]/", {}, { ecmaVersion: 5 })
+test("/[\\^]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\^]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\^]/u", {}, { ecmaVersion: 2015 })
+test("/[\\$]/", {}, { ecmaVersion: 5 })
+test("/[\\$]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\$]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\$]/u", {}, { ecmaVersion: 2015 })
+test("/[\\.]/", {}, { ecmaVersion: 5 })
+test("/[\\.]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\.]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\.]/u", {}, { ecmaVersion: 2015 })
+test("/[\\+]/", {}, { ecmaVersion: 5 })
+test("/[\\+]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\+]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\+]/u", {}, { ecmaVersion: 2015 })
+test("/[\\?]/", {}, { ecmaVersion: 5 })
+test("/[\\?]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\?]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\?]/u", {}, { ecmaVersion: 2015 })
+test("/[\\(]/", {}, { ecmaVersion: 5 })
+test("/[\\(]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\(]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\(]/u", {}, { ecmaVersion: 2015 })
+test("/[\\)]/", {}, { ecmaVersion: 5 })
+test("/[\\)]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\)]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\)]/u", {}, { ecmaVersion: 2015 })
+test("/[\\[]/", {}, { ecmaVersion: 5 })
+test("/[\\[]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\[]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\[]/u", {}, { ecmaVersion: 2015 })
+test("/[\\]]/", {}, { ecmaVersion: 5 })
+test("/[\\]]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\]]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\]]/u", {}, { ecmaVersion: 2015 })
+test("/[\\{]/", {}, { ecmaVersion: 5 })
+test("/[\\{]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\{]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\{]/u", {}, { ecmaVersion: 2015 })
+test("/[\\}]/", {}, { ecmaVersion: 5 })
+test("/[\\}]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\}]/u", {}, { ecmaVersion: 2015 })
+test("/[\\|]/", {}, { ecmaVersion: 5 })
+test("/[\\|]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\|]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\|]/u", {}, { ecmaVersion: 2015 })
+test("/[\\/]/", {}, { ecmaVersion: 5 })
+test("/[\\/]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\/]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\/]/u", {}, { ecmaVersion: 2015 })
+test("/[\\a]/", {}, { ecmaVersion: 5 })
+test("/[\\a]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\a]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\a]/u", "Invalid regular expression: /[\\a]/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\s]/", {}, { ecmaVersion: 5 })
+test("/[\\s]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\s]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\s]/u", {}, { ecmaVersion: 2015 })
+test("/[\\d-\\uFFFF]/", {}, { ecmaVersion: 5 })
+test("/[\\d-\\uFFFF]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\d-\\uFFFF]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\d-\\uFFFF]/u", "Invalid regular expression: /[\\d-\\uFFFF]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\D-\\uFFFF]/", {}, { ecmaVersion: 5 })
+test("/[\\D-\\uFFFF]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\D-\\uFFFF]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\D-\\uFFFF]/u", "Invalid regular expression: /[\\D-\\uFFFF]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\s-\\uFFFF]/", {}, { ecmaVersion: 5 })
+test("/[\\s-\\uFFFF]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\s-\\uFFFF]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\s-\\uFFFF]/u", "Invalid regular expression: /[\\s-\\uFFFF]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\S-\\uFFFF]/", {}, { ecmaVersion: 5 })
+test("/[\\S-\\uFFFF]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\S-\\uFFFF]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\S-\\uFFFF]/u", "Invalid regular expression: /[\\S-\\uFFFF]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\w-\\uFFFF]/", {}, { ecmaVersion: 5 })
+test("/[\\w-\\uFFFF]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\w-\\uFFFF]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\w-\\uFFFF]/u", "Invalid regular expression: /[\\w-\\uFFFF]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\W-\\uFFFF]/", {}, { ecmaVersion: 5 })
+test("/[\\W-\\uFFFF]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\W-\\uFFFF]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\W-\\uFFFF]/u", "Invalid regular expression: /[\\W-\\uFFFF]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u0000-\\d]/", {}, { ecmaVersion: 5 })
+test("/[\\u0000-\\d]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0000-\\d]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u0000-\\d]/u", "Invalid regular expression: /[\\u0000-\\d]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u0000-\\D]/", {}, { ecmaVersion: 5 })
+test("/[\\u0000-\\D]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0000-\\D]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u0000-\\D]/u", "Invalid regular expression: /[\\u0000-\\D]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u0000-\\s]/", {}, { ecmaVersion: 5 })
+test("/[\\u0000-\\s]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0000-\\s]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u0000-\\s]/u", "Invalid regular expression: /[\\u0000-\\s]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u0000-\\S]/", {}, { ecmaVersion: 5 })
+test("/[\\u0000-\\S]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0000-\\S]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u0000-\\S]/u", "Invalid regular expression: /[\\u0000-\\S]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u0000-\\w]/", {}, { ecmaVersion: 5 })
+test("/[\\u0000-\\w]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0000-\\w]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u0000-\\w]/u", "Invalid regular expression: /[\\u0000-\\w]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u0000-\\W]/", {}, { ecmaVersion: 5 })
+test("/[\\u0000-\\W]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0000-\\W]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u0000-\\W]/u", "Invalid regular expression: /[\\u0000-\\W]/: Invalid character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u0000-\\u0001]/", {}, { ecmaVersion: 5 })
+test("/[\\u0000-\\u0001]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0000-\\u0001]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\u0000-\\u0001]/u", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0001-\\u0000]/", "Invalid regular expression: /[\\u0001-\\u0000]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u0001-\\u0000]/", "Invalid regular expression: /[\\u0001-\\u0000]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\u0001-\\u0000]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u0001-\\u0000]/u", "Invalid regular expression: /[\\u0001-\\u0000]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\u{1}-\\u{2}]/", "Invalid regular expression: /[\\u{1}-\\u{2}]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u{1}-\\u{2}]/", "Invalid regular expression: /[\\u{1}-\\u{2}]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\u{1}-\\u{2}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\u{1}-\\u{2}]/u", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{2}-\\u{1}]/", "Invalid regular expression: /[\\u{2}-\\u{1}]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u{2}-\\u{1}]/", "Invalid regular expression: /[\\u{2}-\\u{1}]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\u{2}-\\u{1}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u{2}-\\u{1}]/u", "Invalid regular expression: /[\\u{2}-\\u{1}]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u{2-\\u{1}]/", {}, { ecmaVersion: 5 })
+test("/[\\u{2-\\u{1}]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\u{2-\\u{1}]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\u{2-\\u{1}]/u", "Invalid regular expression: /[\\u{2-\\u{1}]/: Invalid unicode escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\a-\\z]/", {}, { ecmaVersion: 5 })
+test("/[\\a-\\z]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\a-\\z]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\a-\\z]/u", "Invalid regular expression: /[\\a-\\z]/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\z-\\a]/", "Invalid regular expression: /[\\z-\\a]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[\\z-\\a]/", "Invalid regular expression: /[\\z-\\a]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\z-\\a]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\z-\\a]/u", "Invalid regular expression: /[\\z-\\a]/: Invalid escape (1:1)", { ecmaVersion: 2015 })
+test("/[0-9--/]/", {}, { ecmaVersion: 5 })
+test("/[0-9--/]/", {}, { ecmaVersion: 2015 })
+testFail("/[0-9--/]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[0-9--/]/u", {}, { ecmaVersion: 2015 })
+testFail("/[0-9--+]/", "Invalid regular expression: /[0-9--+]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[0-9--+]/", "Invalid regular expression: /[0-9--+]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[0-9--+]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[0-9--+]/u", "Invalid regular expression: /[0-9--+]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\c-a]/", "Invalid regular expression: /[\\c-a]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[\\c-a]/", "Invalid regular expression: /[\\c-a]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\c-a]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\c-a]/u", "Invalid regular expression: /[\\c-a]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\c0-]/", {}, { ecmaVersion: 5 })
+test("/[\\c0-]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\c0-]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\c0-]/u", "Invalid regular expression: /[\\c0-]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+test("/[\\c_]/", {}, { ecmaVersion: 5 })
+test("/[\\c_]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\c_]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\c_]/u", "Invalid regular expression: /[\\c_]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+testFail("/[🌷-🌸]/", "Invalid regular expression: /[🌷-🌸]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[🌷-🌸]/", "Invalid regular expression: /[🌷-🌸]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[🌷-🌸]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[🌷-🌸]/u", {}, { ecmaVersion: 2015 })
+testFail("/[\\u0000-🌸-\\u0000]/", "Invalid regular expression: /[\\u0000-🌸-\\u0000]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\u0000-\\ud83c\\udf38-\\u0000]/", "Invalid regular expression: /[\\u0000-\\ud83c\\udf38-\\u0000]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+test("/[\\u0000-🌸-\\u0000]/u", {}, { ecmaVersion: 2015 })
+test("/[\\u0000-\\u{1f338}-\\u0000]/u", {}, { ecmaVersion: 2015 })
+test("/[\\u0000-\\ud83c\\udf38-\\u0000]/u", {}, { ecmaVersion: 2015 })
+testFail("/[🌸-🌷]/", "Invalid regular expression: /[🌸-🌷]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[🌸-🌷]/", "Invalid regular expression: /[🌸-🌷]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[🌸-🌷]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[🌸-🌷]/u", "Invalid regular expression: /[🌸-🌷]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\uD834\\uDF06-\\uD834\\uDF08a-z]/", "Invalid regular expression: /[\\uD834\\uDF06-\\uD834\\uDF08a-z]/: Range out of order in character class (1:1)", { ecmaVersion: 5 })
+testFail("/[\\uD834\\uDF06-\\uD834\\uDF08a-z]/", "Invalid regular expression: /[\\uD834\\uDF06-\\uD834\\uDF08a-z]/: Range out of order in character class (1:1)", { ecmaVersion: 2015 })
+testFail("/[\\uD834\\uDF06-\\uD834\\uDF08a-z]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/[\\uD834\\uDF06-\\uD834\\uDF08a-z]/u", {}, { ecmaVersion: 2015 })
+test("/^[0-9]*$/", {}, { ecmaVersion: 5 })
+test("/^[0-9]*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[0-9]*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[0-9]*$/u", {}, { ecmaVersion: 2015 })
+test("/^[0-9]+$/", {}, { ecmaVersion: 5 })
+test("/^[0-9]+$/", {}, { ecmaVersion: 2015 })
+testFail("/^[0-9]+$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[0-9]+$/u", {}, { ecmaVersion: 2015 })
+test("/^[a-zA-Z]*$/", {}, { ecmaVersion: 5 })
+test("/^[a-zA-Z]*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[a-zA-Z]*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[a-zA-Z]*$/u", {}, { ecmaVersion: 2015 })
+test("/^[a-zA-Z]+$/", {}, { ecmaVersion: 5 })
+test("/^[a-zA-Z]+$/", {}, { ecmaVersion: 2015 })
+testFail("/^[a-zA-Z]+$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[a-zA-Z]+$/u", {}, { ecmaVersion: 2015 })
+test("/^[0-9a-zA-Z]*$/", {}, { ecmaVersion: 5 })
+test("/^[0-9a-zA-Z]*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[0-9a-zA-Z]*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[0-9a-zA-Z]*$/u", {}, { ecmaVersion: 2015 })
+test("/^[a-zA-Z0-9!-/:-@\\[-`{-~]*$/", {}, { ecmaVersion: 5 })
+test("/^[a-zA-Z0-9!-/:-@\\[-`{-~]*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[a-zA-Z0-9!-/:-@\\[-`{-~]*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[a-zA-Z0-9!-/:-@\\[-`{-~]*$/u", {}, { ecmaVersion: 2015 })
+test("/^([a-zA-Z0-9]{8,})$/", {}, { ecmaVersion: 5 })
+test("/^([a-zA-Z0-9]{8,})$/", {}, { ecmaVersion: 2015 })
+testFail("/^([a-zA-Z0-9]{8,})$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^([a-zA-Z0-9]{8,})$/u", {}, { ecmaVersion: 2015 })
+test("/^([a-zA-Z0-9]{6,8})$/", {}, { ecmaVersion: 5 })
+test("/^([a-zA-Z0-9]{6,8})$/", {}, { ecmaVersion: 2015 })
+testFail("/^([a-zA-Z0-9]{6,8})$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^([a-zA-Z0-9]{6,8})$/u", {}, { ecmaVersion: 2015 })
+test("/^([0-9]{0,8})$/", {}, { ecmaVersion: 5 })
+test("/^([0-9]{0,8})$/", {}, { ecmaVersion: 2015 })
+testFail("/^([0-9]{0,8})$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^([0-9]{0,8})$/u", {}, { ecmaVersion: 2015 })
+test("/^[0-9]{8}$/", {}, { ecmaVersion: 5 })
+test("/^[0-9]{8}$/", {}, { ecmaVersion: 2015 })
+testFail("/^[0-9]{8}$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[0-9]{8}$/u", {}, { ecmaVersion: 2015 })
+test("/^https?:\\/\\//", {}, { ecmaVersion: 5 })
+test("/^https?:\\/\\//", {}, { ecmaVersion: 2015 })
+testFail("/^https?:\\/\\//u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^https?:\\/\\//u", {}, { ecmaVersion: 2015 })
+test("/^\\d{3}-\\d{4}$/", {}, { ecmaVersion: 5 })
+test("/^\\d{3}-\\d{4}$/", {}, { ecmaVersion: 2015 })
+testFail("/^\\d{3}-\\d{4}$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^\\d{3}-\\d{4}$/u", {}, { ecmaVersion: 2015 })
+test("/^\\d{1,3}(.\\d{1,3}){3}$/", {}, { ecmaVersion: 5 })
+test("/^\\d{1,3}(.\\d{1,3}){3}$/", {}, { ecmaVersion: 2015 })
+testFail("/^\\d{1,3}(.\\d{1,3}){3}$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^\\d{1,3}(.\\d{1,3}){3}$/u", {}, { ecmaVersion: 2015 })
+test("/^([1-9][0-9]*|0)(\\.[0-9]+)?$/", {}, { ecmaVersion: 5 })
+test("/^([1-9][0-9]*|0)(\\.[0-9]+)?$/", {}, { ecmaVersion: 2015 })
+testFail("/^([1-9][0-9]*|0)(\\.[0-9]+)?$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^([1-9][0-9]*|0)(\\.[0-9]+)?$/u", {}, { ecmaVersion: 2015 })
+test("/^-?([1-9][0-9]*|0)(\\.[0-9]+)?$/", {}, { ecmaVersion: 5 })
+test("/^-?([1-9][0-9]*|0)(\\.[0-9]+)?$/", {}, { ecmaVersion: 2015 })
+testFail("/^-?([1-9][0-9]*|0)(\\.[0-9]+)?$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^-?([1-9][0-9]*|0)(\\.[0-9]+)?$/u", {}, { ecmaVersion: 2015 })
+test("/^[ぁ-んー]*$/", {}, { ecmaVersion: 5 })
+test("/^[ぁ-んー]*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[ぁ-んー]*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[ぁ-んー]*$/u", {}, { ecmaVersion: 2015 })
+test("/^[ァ-ンヴー]*$/", {}, { ecmaVersion: 5 })
+test("/^[ァ-ンヴー]*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[ァ-ンヴー]*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[ァ-ンヴー]*$/u", {}, { ecmaVersion: 2015 })
+test("/^[ァ-ン゙゚\\-]*$/", {}, { ecmaVersion: 5 })
+test("/^[ァ-ン゙゚\\-]*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[ァ-ン゙゚\\-]*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[ァ-ン゙゚\\-]*$/u", {}, { ecmaVersion: 2015 })
+test("/^[^\\x20-\\x7e]*$/", {}, { ecmaVersion: 5 })
+test("/^[^\\x20-\\x7e]*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[^\\x20-\\x7e]*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[^\\x20-\\x7e]*$/u", {}, { ecmaVersion: 2015 })
+test("/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$/", {}, { ecmaVersion: 5 })
+test("/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$/", {}, { ecmaVersion: 2015 })
+testFail("/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$/u", {}, { ecmaVersion: 2015 })
+test("/^((4\\d{3})|(5[1-5]\\d{2})|(6011))([- ])?\\d{4}([- ])?\\d{4}([- ])?\\d{4}|3[4,7]\\d{13}$/", {}, { ecmaVersion: 5 })
+test("/^((4\\d{3})|(5[1-5]\\d{2})|(6011))([- ])?\\d{4}([- ])?\\d{4}([- ])?\\d{4}|3[4,7]\\d{13}$/", {}, { ecmaVersion: 2015 })
+testFail("/^((4\\d{3})|(5[1-5]\\d{2})|(6011))([- ])?\\d{4}([- ])?\\d{4}([- ])?\\d{4}|3[4,7]\\d{13}$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^((4\\d{3})|(5[1-5]\\d{2})|(6011))([- ])?\\d{4}([- ])?\\d{4}([- ])?\\d{4}|3[4,7]\\d{13}$/u", {}, { ecmaVersion: 2015 })
+test("/^\\s*|\\s*$/", {}, { ecmaVersion: 5 })
+test("/^\\s*|\\s*$/", {}, { ecmaVersion: 2015 })
+testFail("/^\\s*|\\s*$/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+test("/^\\s*|\\s*$/u", {}, { ecmaVersion: 2015 })
+test("/[\\d][\\12-\\14]{1,}[^\\d]/", {}, { ecmaVersion: 5 })
+test("/[\\d][\\12-\\14]{1,}[^\\d]/", {}, { ecmaVersion: 2015 })
+testFail("/[\\d][\\12-\\14]{1,}[^\\d]/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })
+testFail("/[\\d][\\12-\\14]{1,}[^\\d]/u", "Invalid regular expression: /[\\d][\\12-\\14]{1,}[^\\d]/: Invalid class escape (1:1)", { ecmaVersion: 2015 })
+test("/([a ]\\b)*\\b/", {}, { ecmaVersion: 5 })
+
+/*
+// This is test case generator.
+// The tests check whether those results are same as V8 native.
+
+function getErrorMessage(pattern, flags) {
+ try {
+ new RegExp(pattern, flags)
+ return undefined
+ } catch (err) {
+ return err.message
+ }
+}
+
+const patterns = [
+ ["foo"],
+ ["foo|bar"],
+ ["||||"],
+ ["^|$|\\b|\\B"],
+ ["("],
+ ["(?"],
+ ["(?="],
+ ["(?=)"],
+ ["(?=foo"],
+ ["(?=foo)"],
+ ["(?!"],
+ ["(?!)"],
+ ["(?!foo"],
+ ["(?!foo)"],
+ ["(?=a)*"],
+ ["(?=a)+"],
+ ["(?=a)?"],
+ ["(?=a){"],
+ ["(?=a){}"],
+ ["(?=a){a}"],
+ ["(?=a){1}"],
+ ["(?=a){1,}"],
+ ["(?=a){1,2}"],
+ ["a*"],
+ ["a+"],
+ ["a?"],
+ ["a{"],
+ ["a{}"],
+ ["a{a}"],
+ ["a{1}"],
+ ["a{1"],
+ ["a{1,}"],
+ ["a{1,"],
+ ["a{1,2}"],
+ ["a{1,2"],
+ ["a{2,1}"],
+ ["a{2,1"],
+ ["(a{2,1}"],
+ ["a*?"],
+ ["a+?"],
+ ["a??"],
+ ["a{?"],
+ ["a{}?"],
+ ["a{a}?"],
+ ["a{1}?"],
+ ["a{1?"],
+ ["a{1,}?"],
+ ["a{1,?"],
+ ["a{1,2}?"],
+ ["a{1,2?"],
+ ["a{2,1}?"],
+ ["a{2,1?"],
+ ["👍🚀❇️"],
+ ["^"],
+ ["$"],
+ ["."],
+ ["(*)"],
+ ["+"],
+ ["?"],
+ ["("],
+ [")"],
+ ["[", "Unterminated regular expression", "Unterminated regular expression"],
+ ["]"],
+ ["{"],
+ ["}"],
+ ["|"],
+ ["^*"],
+ ["$*"],
+ ["${1,2"],
+ ["${1,2}"],
+ ["${2,1}"],
+ ["\\1"],
+ ["(a)\\1"],
+ ["\\1(a)"],
+ ["\\2(a)("],
+ ["(?:a)\\1"],
+ ["(a)\\2"],
+ ["(?:a)\\2"],
+ ["(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\10"],
+ ["(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11"],
+ ["(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)\\11"],
+ ["(?"],
+ ["(?a"],
+ ["(?a)"],
+ ["(?:"],
+ ["(?:a"],
+ ["(?:a)"],
+ ["(:a"],
+ ["\\d"],
+ ["\\D"],
+ ["\\s"],
+ ["\\S"],
+ ["\\w"],
+ ["\\W"],
+ ["\\f"],
+ ["\\n"],
+ ["\\r"],
+ ["\\t"],
+ ["\\v"],
+ ["\\cA"],
+ ["\\cz"],
+ ["\\c1"],
+ ["\\c"],
+ ["\\0"],
+ ["\\u"],
+ ["\\u1"],
+ ["\\u12"],
+ ["\\u123"],
+ ["\\u1234"],
+ ["\\u12345"],
+ ["\\u{"],
+ ["\\u{z"],
+ ["\\u{a}"],
+ ["\\u{20"],
+ ["\\u{20}"],
+ ["\\u{10FFFF}"],
+ ["\\u{110000}"],
+ ["\\u{00000001}"],
+ ["\\377"],
+ ["\\400"],
+ ["\\^"],
+ ["\\$"],
+ ["\\."],
+ ["\\+"],
+ ["\\?"],
+ ["\\("],
+ ["\\)"],
+ ["\\["],
+ ["\\]"],
+ ["\\{"],
+ ["\\}"],
+ ["\\|"],
+ ["\\/"],
+ ["\\a"],
+ ["\\s"],
+ ["[]"],
+ ["[^-a-b-]"],
+ ["[-]"],
+ ["[a]"],
+ ["[--]"],
+ ["[-a]"],
+ ["[-a-]"],
+ ["[a-]"],
+ ["[a-b]"],
+ ["[-a-b-]"],
+ ["[---]"],
+ ["[b-a]"],
+ ["[a-b--/]"],
+ ["[a-b--+]"],
+ ["[\\b-\\n]"],
+ ["[b\\-a]"],
+ ["[\\d]"],
+ ["[\\D]"],
+ ["[\\s]"],
+ ["[\\S]"],
+ ["[\\w]"],
+ ["[\\W]"],
+ ["[\\d]"],
+ ["[\\D]"],
+ ["[\\s]"],
+ ["[\\S]"],
+ ["[\\w]"],
+ ["[\\W]"],
+ ["[\\f]"],
+ ["[\\n]"],
+ ["[\\r]"],
+ ["[\\t]"],
+ ["[\\v]"],
+ ["[\\cA]"],
+ ["[\\cz]"],
+ ["[\\c1]"],
+ ["[\\c]"],
+ ["[\\0]"],
+ ["[\\x]"],
+ ["[\\xz]"],
+ ["[\\x1]"],
+ ["[\\x12]"],
+ ["[\\x123]"],
+ ["[\\u]"],
+ ["[\\u1]"],
+ ["[\\u12]"],
+ ["[\\u123]"],
+ ["[\\u1234]"],
+ ["[\\u12345]"],
+ ["[\\u{]"],
+ ["[\\u{z]"],
+ ["[\\u{a}]"],
+ ["[\\u{20]"],
+ ["[\\u{20}]"],
+ ["[\\u{10FFFF}]"],
+ ["[\\u{110000}]"],
+ ["[\\u{00000001}]"],
+ ["[\\77]"],
+ ["[\\377]"],
+ ["[\\400]"],
+ ["[\\^]"],
+ ["[\\$]"],
+ ["[\\.]"],
+ ["[\\+]"],
+ ["[\\?]"],
+ ["[\\(]"],
+ ["[\\)]"],
+ ["[\\[]"],
+ ["[\\]]"],
+ ["[\\{]"],
+ ["[\\}]"],
+ ["[\\|]"],
+ ["[\\/]"],
+ ["[\\a]"],
+ ["[\\s]"],
+ ["[\\d-\\uFFFF]"],
+ ["[\\D-\\uFFFF]"],
+ ["[\\s-\\uFFFF]"],
+ ["[\\S-\\uFFFF]"],
+ ["[\\w-\\uFFFF]"],
+ ["[\\W-\\uFFFF]"],
+ ["[\\u0000-\\d]"],
+ ["[\\u0000-\\D]"],
+ ["[\\u0000-\\s]"],
+ ["[\\u0000-\\S]"],
+ ["[\\u0000-\\w]"],
+ ["[\\u0000-\\W]"],
+ ["[\\u0000-\\u0001]"],
+ ["[\\u0001-\\u0000]"],
+ ["[\\u{1}-\\u{2}]"],
+ ["[\\u{2}-\\u{1}]"],
+ ["[\\u{2-\\u{1}]"],
+ ["[\\a-\\z]"],
+ ["[\\z-\\a]"],
+ ["[0-9--/]"],
+ ["[0-9--+]"],
+ ["[\\c-a]"],
+ ["[\\c0-\u001F]"],
+ ["[\\c_]"],
+ ["[🌷-🌸]"],
+ ["[🌸-🌷]"],
+ ["[\\uD834\\uDF06-\\uD834\\uDF08a-z]"],
+ ["^[0-9]*$"],
+ ["^[0-9]+$"],
+ ["^[a-zA-Z]*$"],
+ ["^[a-zA-Z]+$"],
+ ["^[0-9a-zA-Z]*$"],
+ ["^[a-zA-Z0-9!-/:-@\\[-`{-~]*$"],
+ ["^([a-zA-Z0-9]{8,})$"],
+ ["^([a-zA-Z0-9]{6,8})$"],
+ ["^([0-9]{0,8})$"],
+ ["^[0-9]{8}$"],
+ ["^https?:\\/\\/"],
+ ["^\\d{3}-\\d{4}$"],
+ ["^\\d{1,3}(\.\\d{1,3}){3}$"],
+ ["^([1-9][0-9]*|0)(\\.[0-9]+)?$"],
+ ["^-?([1-9][0-9]*|0)(\\.[0-9]+)?$"],
+ ["^[ぁ-んー]*$"],
+ ["^[ァ-ンヴー]*$"],
+ ["^[ァ-ン゙゚\\-]*$"],
+ ["^[^\\x20-\\x7e]*$"],
+ ["^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$"],
+ ["^((4\\d{3})|(5[1-5]\\d{2})|(6011))([- ])?\\d{4}([- ])?\\d{4}([- ])?\\d{4}|3[4,7]\\d{13}$"],
+ ["^\\s*|\\s*$"],
+ ["[\\d][\\12-\\14]{1,}[^\\d]"]
+]
+
+const tests = []
+for (const [pattern, message, messageU] of patterns) {
+ // Without u flag
+ let msg = message || getErrorMessage(pattern, "")
+ if (msg === undefined) {
+ tests.push(`test("/${pattern.replace(/\\/g, "\\\\")}/", {}, { ecmaVersion: 5 })`)
+ tests.push(`test("/${pattern.replace(/\\/g, "\\\\")}/", {}, { ecmaVersion: 2015 })`)
+ } else {
+ tests.push(`testFail("/${pattern.replace(/\\/g, "\\\\")}/", "${msg.replace(/\\/g, "\\\\")} (1:1)", { ecmaVersion: 5 })`)
+ tests.push(`testFail("/${pattern.replace(/\\/g, "\\\\")}/", "${msg.replace(/\\/g, "\\\\")} (1:1)", { ecmaVersion: 2015 })`)
+ }
+
+ // With u flag
+ msg = messageU || getErrorMessage(pattern, "u")
+ tests.push(`testFail("/${pattern.replace(/\\/g, "\\\\")}/u", "Invalid regular expression flag (1:1)", { ecmaVersion: 5 })`)
+ if (msg === undefined) {
+ tests.push(`test("/${pattern.replace(/\\/g, "\\\\")}/u", {}, { ecmaVersion: 2015 })`)
+ } else {
+ tests.push(`testFail("/${pattern.replace(/\\/g, "\\\\")}/u", "${msg.replace(/\\/g, "\\\\")} (1:1)", { ecmaVersion: 2015 })`)
+ }
+}
+
+require("fs").writeFileSync("a.txt", tests.join("\n"))
+
+*/
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/acorn.git
More information about the Pkg-javascript-commits
mailing list