123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- /*!
- * RegJSGen
- * Copyright 2014 Benjamin Tan <https://d10.github.io/>
- * Available under MIT license <http://d10.mit-license.org/>
- */
- ;(function() {
- 'use strict';
- /** Used to determine if values are of the language type `Object` */
- var objectTypes = {
- 'function': true,
- 'object': true
- };
- /** Used as a reference to the global object */
- var root = (objectTypes[typeof window] && window) || this;
- /** Backup possible global object */
- var oldRoot = root;
- /** Detect free variable `exports` */
- var freeExports = objectTypes[typeof exports] && exports;
- /** Detect free variable `module` */
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
- /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
- var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
- if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
- root = freeGlobal;
- }
- /*--------------------------------------------------------------------------*/
- /*! Based on https://mths.be/fromcodepoint v0.2.0 by @mathias */
- var stringFromCharCode = String.fromCharCode;
- var floor = Math.floor;
- function fromCodePoint() {
- var MAX_SIZE = 0x4000;
- var codeUnits = [];
- var highSurrogate;
- var lowSurrogate;
- var index = -1;
- var length = arguments.length;
- if (!length) {
- return '';
- }
- var result = '';
- while (++index < length) {
- var codePoint = Number(arguments[index]);
- if (
- !isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
- codePoint < 0 || // not a valid Unicode code point
- codePoint > 0x10FFFF || // not a valid Unicode code point
- floor(codePoint) != codePoint // not an integer
- ) {
- throw RangeError('Invalid code point: ' + codePoint);
- }
- if (codePoint <= 0xFFFF) {
- // BMP code point
- codeUnits.push(codePoint);
- } else {
- // Astral code point; split in surrogate halves
- // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
- codePoint -= 0x10000;
- highSurrogate = (codePoint >> 10) + 0xD800;
- lowSurrogate = (codePoint % 0x400) + 0xDC00;
- codeUnits.push(highSurrogate, lowSurrogate);
- }
- if (index + 1 == length || codeUnits.length > MAX_SIZE) {
- result += stringFromCharCode.apply(null, codeUnits);
- codeUnits.length = 0;
- }
- }
- return result;
- }
- function assertType(type, expected) {
- if (expected.indexOf('|') == -1) {
- if (type == expected) {
- return;
- }
- throw Error('Invalid node type: ' + type);
- }
- expected = assertType.hasOwnProperty(expected)
- ? assertType[expected]
- : (assertType[expected] = RegExp('^(?:' + expected + ')$'));
- if (expected.test(type)) {
- return;
- }
- throw Error('Invalid node type: ' + type);
- }
- /*--------------------------------------------------------------------------*/
- function generate(node) {
- var type = node.type;
- if (generate.hasOwnProperty(type) && typeof generate[type] == 'function') {
- return generate[type](node);
- }
- throw Error('Invalid node type: ' + type);
- }
- /*--------------------------------------------------------------------------*/
- function generateAlternative(node) {
- assertType(node.type, 'alternative');
- var terms = node.body,
- length = terms ? terms.length : 0;
- if (length == 1) {
- return generateTerm(terms[0]);
- } else {
- var i = -1,
- result = '';
- while (++i < length) {
- result += generateTerm(terms[i]);
- }
- return result;
- }
- }
- function generateAnchor(node) {
- assertType(node.type, 'anchor');
- switch (node.kind) {
- case 'start':
- return '^';
- case 'end':
- return '$';
- case 'boundary':
- return '\\b';
- case 'not-boundary':
- return '\\B';
- default:
- throw Error('Invalid assertion');
- }
- }
- function generateAtom(node) {
- assertType(node.type, 'anchor|characterClass|characterClassEscape|dot|group|reference|value');
- return generate(node);
- }
- function generateCharacterClass(node) {
- assertType(node.type, 'characterClass');
- var classRanges = node.body,
- length = classRanges ? classRanges.length : 0;
- var i = -1,
- result = '[';
- if (node.negative) {
- result += '^';
- }
- while (++i < length) {
- result += generateClassAtom(classRanges[i]);
- }
- result += ']';
- return result;
- }
- function generateCharacterClassEscape(node) {
- assertType(node.type, 'characterClassEscape');
- return '\\' + node.value;
- }
- function generateCharacterClassRange(node) {
- assertType(node.type, 'characterClassRange');
- var min = node.min,
- max = node.max;
- if (min.type == 'characterClassRange' || max.type == 'characterClassRange') {
- throw Error('Invalid character class range');
- }
- return generateClassAtom(min) + '-' + generateClassAtom(max);
- }
- function generateClassAtom(node) {
- assertType(node.type, 'anchor|characterClassEscape|characterClassRange|dot|value');
- return generate(node);
- }
- function generateDisjunction(node) {
- assertType(node.type, 'disjunction');
- var body = node.body,
- length = body ? body.length : 0;
- if (length == 0) {
- throw Error('No body');
- } else if (length == 1) {
- return generate(body[0]);
- } else {
- var i = -1,
- result = '';
- while (++i < length) {
- if (i != 0) {
- result += '|';
- }
- result += generate(body[i]);
- }
- return result;
- }
- }
- function generateDot(node) {
- assertType(node.type, 'dot');
- return '.';
- }
- function generateGroup(node) {
- assertType(node.type, 'group');
- var result = '(';
- switch (node.behavior) {
- case 'normal':
- break;
- case 'ignore':
- result += '?:';
- break;
- case 'lookahead':
- result += '?=';
- break;
- case 'negativeLookahead':
- result += '?!';
- break;
- default:
- throw Error('Invalid behaviour: ' + node.behaviour);
- }
- var body = node.body,
- length = body ? body.length : 0;
- if (length == 1) {
- result += generate(body[0]);
- } else {
- var i = -1;
- while (++i < length) {
- result += generate(body[i]);
- }
- }
- result += ')';
- return result;
- }
- function generateQuantifier(node) {
- assertType(node.type, 'quantifier');
- var quantifier = '',
- min = node.min,
- max = node.max;
- switch (max) {
- case undefined:
- case null:
- switch (min) {
- case 0:
- quantifier = '*'
- break;
- case 1:
- quantifier = '+';
- break;
- default:
- quantifier = '{' + min + ',}';
- break;
- }
- break;
- default:
- if (min == max) {
- quantifier = '{' + min + '}';
- }
- else if (min == 0 && max == 1) {
- quantifier = '?';
- } else {
- quantifier = '{' + min + ',' + max + '}';
- }
- break;
- }
- if (!node.greedy) {
- quantifier += '?';
- }
- return generateAtom(node.body[0]) + quantifier;
- }
- function generateReference(node) {
- assertType(node.type, 'reference');
- return '\\' + node.matchIndex;
- }
- function generateTerm(node) {
- assertType(node.type, 'anchor|characterClass|characterClassEscape|empty|group|quantifier|reference|value');
- return generate(node);
- }
- function generateValue(node) {
- assertType(node.type, 'value');
- var kind = node.kind,
- codePoint = node.codePoint;
- switch (kind) {
- case 'controlLetter':
- return '\\c' + fromCodePoint(codePoint + 64);
- case 'hexadecimalEscape':
- return '\\x' + ('00' + codePoint.toString(16).toUpperCase()).slice(-2);
- case 'identifier':
- return '\\' + fromCodePoint(codePoint);
- case 'null':
- return '\\' + codePoint;
- case 'octal':
- return '\\' + codePoint.toString(8);
- case 'singleEscape':
- switch (codePoint) {
- case 0x0008:
- return '\\b';
- case 0x009:
- return '\\t';
- case 0x00A:
- return '\\n';
- case 0x00B:
- return '\\v';
- case 0x00C:
- return '\\f';
- case 0x00D:
- return '\\r';
- default:
- throw Error('Invalid codepoint: ' + codePoint);
- }
- case 'symbol':
- return fromCodePoint(codePoint);
- case 'unicodeEscape':
- return '\\u' + ('0000' + codePoint.toString(16).toUpperCase()).slice(-4);
- case 'unicodeCodePointEscape':
- return '\\u{' + codePoint.toString(16).toUpperCase() + '}';
- default:
- throw Error('Unsupported node kind: ' + kind);
- }
- }
- /*--------------------------------------------------------------------------*/
- generate.alternative = generateAlternative;
- generate.anchor = generateAnchor;
- generate.characterClass = generateCharacterClass;
- generate.characterClassEscape = generateCharacterClassEscape;
- generate.characterClassRange = generateCharacterClassRange;
- generate.disjunction = generateDisjunction;
- generate.dot = generateDot;
- generate.group = generateGroup;
- generate.quantifier = generateQuantifier;
- generate.reference = generateReference;
- generate.value = generateValue;
- /*--------------------------------------------------------------------------*/
- // export regjsgen
- // some AMD build optimizers, like r.js, check for condition patterns like the following:
- if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
- // define as an anonymous module so, through path mapping, it can be aliased
- define(function() {
- return {
- 'generate': generate
- };
- });
- }
- // check for `exports` after `define` in case a build optimizer adds an `exports` object
- else if (freeExports && freeModule) {
- // in Narwhal, Node.js, Rhino -require, or RingoJS
- freeExports.generate = generate;
- }
- // in a browser or Rhino
- else {
- root.regjsgen = {
- 'generate': generate
- };
- }
- }.call(this));
|