1 var types = require('./types');
2 var sets = require('./sets');
5 // All of these are private and only used by randexp.
6 // It's assumed that they will always be called with the correct input.
8 var CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?';
9 var SLSH = { '0': 0, 't': 9, 'n': 10, 'v': 11, 'f': 12, 'r': 13 };
12 * Finds character representations in str and convert all to
13 * their respective characters
18 exports.strToChars = function(str) {
19 /* jshint maxlen: false */
20 var chars_regex = /(\[\\b\])|(\\)?\\(?:u([A-F0-9]{4})|x([A-F0-9]{2})|(0?[0-7]{2})|c([@A-Z\[\\\]\^?])|([0tnvfr]))/g;
21 str = str.replace(chars_regex, function(s, b, lbs, a16, b16, c8, dctrl, eslsh) {
27 a16 ? parseInt(a16, 16) :
28 b16 ? parseInt(b16, 16) :
29 c8 ? parseInt(c8, 8) :
30 dctrl ? CTRL.indexOf(dctrl) :
33 var c = String.fromCharCode(code);
35 // Escape special regex characters.
36 if (/[\[\]{}\^$.|?*+()]/.test(c)) {
48 * turns class into tokens
49 * reads str until it encounters a ] not preceeded by a \
52 * @param {String} regexpStr
53 * @return {Array.<Array.<Object>, Number>}
55 exports.tokenizeClass = function(str, regexpStr) {
56 /* jshint maxlen: false */
58 var regexp = /\\(?:(w)|(d)|(s)|(W)|(D)|(S))|((?:(?:\\)(.)|([^\]\\]))-(?:\\)?([^\]]))|(\])|(?:\\)?(.)/g;
62 while ((rs = regexp.exec(str)) != null) {
64 tokens.push(sets.words());
67 tokens.push(sets.ints());
70 tokens.push(sets.whitespace());
73 tokens.push(sets.notWords());
76 tokens.push(sets.notInts());
79 tokens.push(sets.notWhitespace());
84 from: (rs[8] || rs[9]).charCodeAt(0),
85 to: rs[10].charCodeAt(0),
88 } else if (c = rs[12]) {
91 value: c.charCodeAt(0),
95 return [tokens, regexp.lastIndex];
99 exports.error(regexpStr, 'Unterminated character class');
104 * Shortcut to throw errors.
106 * @param {String} regexp
107 * @param {String} msg
109 exports.error = function(regexp, msg) {
110 throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg);