regexp-tree.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /**
  2. * The MIT License (MIT)
  3. * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
  4. */
  5. 'use strict';
  6. var compatTranspiler = require('./compat-transpiler');
  7. var generator = require('./generator');
  8. var optimizer = require('./optimizer');
  9. var parser = require('./parser');
  10. var _transform = require('./transform');
  11. var _traverse = require('./traverse');
  12. var fa = require('./interpreter/finite-automaton');
  13. var _require = require('./compat-transpiler/runtime'),
  14. RegExpTree = _require.RegExpTree;
  15. /**
  16. * An API object for RegExp processing (parsing/transform/generation).
  17. */
  18. var regexpTree = {
  19. /**
  20. * Parser module exposed.
  21. */
  22. parser: parser,
  23. /**
  24. * Expose finite-automaton module.
  25. */
  26. fa: fa,
  27. /**
  28. * `TransformResult` exposed.
  29. */
  30. TransformResult: _transform.TransformResult,
  31. /**
  32. * Parses a regexp string, producing an AST.
  33. *
  34. * @param string regexp
  35. *
  36. * a regular expression in different formats: string, AST, RegExp.
  37. *
  38. * @param Object options
  39. *
  40. * parsing options for this parse call. Default are:
  41. *
  42. * - captureLocations: boolean
  43. * - any other custom options
  44. *
  45. * @return Object AST
  46. */
  47. parse: function parse(regexp, options) {
  48. return parser.parse('' + regexp, options);
  49. },
  50. /**
  51. * Traverses a RegExp AST.
  52. *
  53. * @param Object ast
  54. * @param Object | Array<Object> handlers
  55. *
  56. * Each `handler` is an object containing handler function for needed
  57. * node types. Example:
  58. *
  59. * regexpTree.traverse(ast, {
  60. * onChar(node) {
  61. * ...
  62. * },
  63. * });
  64. *
  65. * The value for a node type may also be an object with functions pre and post.
  66. * This enables more context-aware analyses, e.g. measuring star height.
  67. */
  68. traverse: function traverse(ast, handlers, options) {
  69. return _traverse.traverse(ast, handlers, options);
  70. },
  71. /**
  72. * Transforms a regular expression.
  73. *
  74. * A regexp can be passed in different formats (string, regexp or AST),
  75. * applying a set of transformations. It is a convenient wrapper
  76. * on top of "parse-traverse-generate" tool chain.
  77. *
  78. * @param string | AST | RegExp regexp - a regular expression;
  79. * @param Object | Array<Object> handlers - a list of handlers.
  80. *
  81. * @return TransformResult - a transformation result.
  82. */
  83. transform: function transform(regexp, handlers) {
  84. return _transform.transform(regexp, handlers);
  85. },
  86. /**
  87. * Generates a RegExp string from an AST.
  88. *
  89. * @param Object ast
  90. *
  91. * Invariant:
  92. *
  93. * regexpTree.generate(regexpTree.parse('/[a-z]+/i')); // '/[a-z]+/i'
  94. */
  95. generate: function generate(ast) {
  96. return generator.generate(ast);
  97. },
  98. /**
  99. * Creates a RegExp object from a regexp string.
  100. *
  101. * @param string regexp
  102. */
  103. toRegExp: function toRegExp(regexp) {
  104. var compat = this.compatTranspile(regexp);
  105. return new RegExp(compat.getSource(), compat.getFlags());
  106. },
  107. /**
  108. * Optimizes a regular expression by replacing some
  109. * sub-expressions with their idiomatic patterns.
  110. *
  111. * @param string regexp
  112. *
  113. * @return TransformResult object
  114. */
  115. optimize: function optimize(regexp, whitelist) {
  116. var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
  117. blacklist = _ref.blacklist;
  118. return optimizer.optimize(regexp, { whitelist: whitelist, blacklist: blacklist });
  119. },
  120. /**
  121. * Translates a regular expression in new syntax or in new format
  122. * into equivalent expressions in old syntax.
  123. *
  124. * @param string regexp
  125. *
  126. * @return TransformResult object
  127. */
  128. compatTranspile: function compatTranspile(regexp, whitelist) {
  129. return compatTranspiler.transform(regexp, whitelist);
  130. },
  131. /**
  132. * Executes a regular expression on a string.
  133. *
  134. * @param RegExp|string re - a regular expression.
  135. * @param string string - a testing string.
  136. */
  137. exec: function exec(re, string) {
  138. if (typeof re === 'string') {
  139. var compat = this.compatTranspile(re);
  140. var extra = compat.getExtra();
  141. if (extra.namedCapturingGroups) {
  142. re = new RegExpTree(compat.toRegExp(), {
  143. flags: compat.getFlags(),
  144. source: compat.getSource(),
  145. groups: extra.namedCapturingGroups
  146. });
  147. } else {
  148. re = compat.toRegExp();
  149. }
  150. }
  151. return re.exec(string);
  152. }
  153. };
  154. module.exports = regexpTree;