123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /**
- * The MIT License (MIT)
- * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
- */
- 'use strict';
- /**
- * Helper `gen` function calls node type handler.
- */
- function gen(node) {
- return node ? generator[node.type](node) : '';
- }
- /**
- * AST handler.
- */
- var generator = {
- RegExp: function RegExp(node) {
- return '/' + gen(node.body) + '/' + node.flags;
- },
- Alternative: function Alternative(node) {
- return (node.expressions || []).map(gen).join('');
- },
- Disjunction: function Disjunction(node) {
- return gen(node.left) + '|' + gen(node.right);
- },
- Group: function Group(node) {
- var expression = gen(node.expression);
- if (node.capturing) {
- // A named group.
- if (node.name) {
- return '(?<' + (node.nameRaw || node.name) + '>' + expression + ')';
- }
- return '(' + expression + ')';
- }
- return '(?:' + expression + ')';
- },
- Backreference: function Backreference(node) {
- switch (node.kind) {
- case 'number':
- return '\\' + node.reference;
- case 'name':
- return '\\k<' + (node.referenceRaw || node.reference) + '>';
- default:
- throw new TypeError('Unknown Backreference kind: ' + node.kind);
- }
- },
- Assertion: function Assertion(node) {
- switch (node.kind) {
- case '^':
- case '$':
- case '\\b':
- case '\\B':
- return node.kind;
- case 'Lookahead':
- {
- var assertion = gen(node.assertion);
- if (node.negative) {
- return '(?!' + assertion + ')';
- }
- return '(?=' + assertion + ')';
- }
- case 'Lookbehind':
- {
- var _assertion = gen(node.assertion);
- if (node.negative) {
- return '(?<!' + _assertion + ')';
- }
- return '(?<=' + _assertion + ')';
- }
- default:
- throw new TypeError('Unknown Assertion kind: ' + node.kind);
- }
- },
- CharacterClass: function CharacterClass(node) {
- var expressions = node.expressions.map(gen).join('');
- if (node.negative) {
- return '[^' + expressions + ']';
- }
- return '[' + expressions + ']';
- },
- ClassRange: function ClassRange(node) {
- return gen(node.from) + '-' + gen(node.to);
- },
- Repetition: function Repetition(node) {
- return '' + gen(node.expression) + gen(node.quantifier);
- },
- Quantifier: function Quantifier(node) {
- var quantifier = void 0;
- var greedy = node.greedy ? '' : '?';
- switch (node.kind) {
- case '+':
- case '?':
- case '*':
- quantifier = node.kind;
- break;
- case 'Range':
- // Exact: {1}
- if (node.from === node.to) {
- quantifier = '{' + node.from + '}';
- }
- // Open: {1,}
- else if (!node.to) {
- quantifier = '{' + node.from + ',}';
- }
- // Closed: {1,3}
- else {
- quantifier = '{' + node.from + ',' + node.to + '}';
- }
- break;
- default:
- throw new TypeError('Unknown Quantifier kind: ' + node.kind);
- }
- return '' + quantifier + greedy;
- },
- Char: function Char(node) {
- var value = node.value;
- switch (node.kind) {
- case 'simple':
- {
- if (node.escaped) {
- return '\\' + value;
- }
- return value;
- }
- case 'hex':
- case 'unicode':
- case 'oct':
- case 'decimal':
- case 'control':
- case 'meta':
- return value;
- default:
- throw new TypeError('Unknown Char kind: ' + node.kind);
- }
- },
- UnicodeProperty: function UnicodeProperty(node) {
- var escapeChar = node.negative ? 'P' : 'p';
- var namePart = void 0;
- if (!node.shorthand && !node.binary) {
- namePart = node.name + '=';
- } else {
- namePart = '';
- }
- return '\\' + escapeChar + '{' + namePart + node.value + '}';
- }
- };
- module.exports = {
- /**
- * Generates a regexp string from an AST.
- *
- * @param Object ast - an AST node
- */
- generate: gen
- };
|