123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- /**
- * The MIT License (MIT)
- * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
- */
- 'use strict';
- var _require = require('../../transform/utils'),
- increaseQuantifierByOne = _require.increaseQuantifierByOne;
- /**
- * A regexp-tree plugin to merge quantifiers
- *
- * a+a+ -> a{2,}
- * a{2}a{3} -> a{5}
- * a{1,2}a{2,3} -> a{3,5}
- */
- module.exports = {
- Repetition: function Repetition(path) {
- var node = path.node,
- parent = path.parent;
- if (parent.type !== 'Alternative' || !path.index) {
- return;
- }
- var previousSibling = path.getPreviousSibling();
- if (!previousSibling) {
- return;
- }
- if (previousSibling.node.type === 'Repetition') {
- if (!previousSibling.getChild().hasEqualSource(path.getChild())) {
- return;
- }
- var _extractFromTo = extractFromTo(previousSibling.node.quantifier),
- previousSiblingFrom = _extractFromTo.from,
- previousSiblingTo = _extractFromTo.to;
- var _extractFromTo2 = extractFromTo(node.quantifier),
- nodeFrom = _extractFromTo2.from,
- nodeTo = _extractFromTo2.to;
- // It's does not seem reliable to merge quantifiers with different greediness
- // when none of both is a greedy open range
- if (previousSibling.node.quantifier.greedy !== node.quantifier.greedy && !isGreedyOpenRange(previousSibling.node.quantifier) && !isGreedyOpenRange(node.quantifier)) {
- return;
- }
- // a*a* -> a*
- // a*a+ -> a+
- // a+a+ -> a{2,}
- // a{2}a{4} -> a{6}
- // a{1,2}a{2,3} -> a{3,5}
- // a{1,}a{2,} -> a{3,}
- // a+a{2,} -> a{3,}
- // a??a{2,} -> a{2,}
- // a*?a{2,} -> a{2,}
- // a+?a{2,} -> a{3,}
- node.quantifier.kind = 'Range';
- node.quantifier.from = previousSiblingFrom + nodeFrom;
- if (previousSiblingTo && nodeTo) {
- node.quantifier.to = previousSiblingTo + nodeTo;
- } else {
- delete node.quantifier.to;
- }
- if (isGreedyOpenRange(previousSibling.node.quantifier) || isGreedyOpenRange(node.quantifier)) {
- node.quantifier.greedy = true;
- }
- previousSibling.remove();
- } else {
- if (!previousSibling.hasEqualSource(path.getChild())) {
- return;
- }
- increaseQuantifierByOne(node.quantifier);
- previousSibling.remove();
- }
- }
- };
- function isGreedyOpenRange(quantifier) {
- return quantifier.greedy && (quantifier.kind === '+' || quantifier.kind === '*' || quantifier.kind === 'Range' && !quantifier.to);
- }
- function extractFromTo(quantifier) {
- var from = void 0,
- to = void 0;
- if (quantifier.kind === '*') {
- from = 0;
- } else if (quantifier.kind === '+') {
- from = 1;
- } else if (quantifier.kind === '?') {
- from = 0;
- to = 1;
- } else {
- from = quantifier.from;
- if (quantifier.to) {
- to = quantifier.to;
- }
- }
- return { from: from, to: to };
- }
|