Blame view

node_modules/ret/lib/util.js 2.55 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  var types = require('./types');
  var sets  = require('./sets');
  
  
  // All of these are private and only used by randexp.
  // It's assumed that they will always be called with the correct input.
  
  var CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?';
  var SLSH = { '0': 0, 't': 9, 'n': 10, 'v': 11, 'f': 12, 'r': 13 };
  
  /**
   * Finds character representations in str and convert all to
   * their respective characters
   *
   * @param {String} str
   * @return {String}
   */
  exports.strToChars = function(str) {
    /* jshint maxlen: false */
    var chars_regex = /(\[\\b\])|(\\)?\\(?:u([A-F0-9]{4})|x([A-F0-9]{2})|(0?[0-7]{2})|c([@A-Z\[\\\]\^?])|([0tnvfr]))/g;
    str = str.replace(chars_regex, function(s, b, lbs, a16, b16, c8, dctrl, eslsh) {
      if (lbs) {
        return s;
      }
  
      var code = b     ? 8 :
                 a16   ? parseInt(a16, 16) :
                 b16   ? parseInt(b16, 16) :
                 c8    ? parseInt(c8,   8) :
                 dctrl ? CTRL.indexOf(dctrl) :
                 SLSH[eslsh];
  
      var c = String.fromCharCode(code);
  
      // Escape special regex characters.
      if (/[\[\]{}\^$.|?*+()]/.test(c)) {
        c = '\\' + c;
      }
  
      return c;
    });
  
    return str;
  };
  
  
  /**
   * turns class into tokens
   * reads str until it encounters a ] not preceeded by a \
   *
   * @param {String} str
   * @param {String} regexpStr
   * @return {Array.<Array.<Object>, Number>}
   */
  exports.tokenizeClass = function(str, regexpStr) {
    /* jshint maxlen: false */
    var tokens = [];
    var regexp = /\\(?:(w)|(d)|(s)|(W)|(D)|(S))|((?:(?:\\)(.)|([^\]\\]))-(?:\\)?([^\]]))|(\])|(?:\\)?(.)/g;
    var rs, c;
  
  
    while ((rs = regexp.exec(str)) != null) {
      if (rs[1]) {
        tokens.push(sets.words());
  
      } else if (rs[2]) {
        tokens.push(sets.ints());
  
      } else if (rs[3]) {
        tokens.push(sets.whitespace());
  
      } else if (rs[4]) {
        tokens.push(sets.notWords());
  
      } else if (rs[5]) {
        tokens.push(sets.notInts());
  
      } else if (rs[6]) {
        tokens.push(sets.notWhitespace());
  
      } else if (rs[7]) {
        tokens.push({
          type: types.RANGE,
          from: (rs[8] || rs[9]).charCodeAt(0),
            to: rs[10].charCodeAt(0),
        });
  
      } else if (c = rs[12]) {
        tokens.push({
          type: types.CHAR,
          value: c.charCodeAt(0),
        });
  
      } else {
        return [tokens, regexp.lastIndex];
      }
    }
  
    exports.error(regexpStr, 'Unterminated character class');
  };
  
  
  /**
   * Shortcut to throw errors.
   *
   * @param {String} regexp
   * @param {String} msg
   */
  exports.error = function(regexp, msg) {
    throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg);
  };