You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							109 lines
						
					
					
						
							2.4 KiB
						
					
					
				
			
		
		
	
	
							109 lines
						
					
					
						
							2.4 KiB
						
					
					
				| const types = require('./types');
 | |
| const sets  = require('./sets');
 | |
| 
 | |
| 
 | |
| const CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?';
 | |
| const 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 = (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 = (regexp, msg) => {
 | |
|   throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg);
 | |
| };
 |