nfa-from-regexp.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /**
  2. * The MIT License (MIT)
  3. * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
  4. */
  5. 'use strict';
  6. function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
  7. var parser = require('../../../parser');
  8. var _require = require('./builders'),
  9. alt = _require.alt,
  10. char = _require.char,
  11. or = _require.or,
  12. rep = _require.rep,
  13. plusRep = _require.plusRep,
  14. questionRep = _require.questionRep;
  15. /**
  16. * Helper `gen` function calls node type handler.
  17. */
  18. function gen(node) {
  19. if (node && !generator[node.type]) {
  20. throw new Error(node.type + ' is not supported in NFA/DFA interpreter.');
  21. }
  22. return node ? generator[node.type](node) : '';
  23. }
  24. /**
  25. * AST handler.
  26. */
  27. var generator = {
  28. RegExp: function RegExp(node) {
  29. if (node.flags !== '') {
  30. throw new Error('NFA/DFA: Flags are not supported yet.');
  31. }
  32. return gen(node.body);
  33. },
  34. Alternative: function Alternative(node) {
  35. var fragments = (node.expressions || []).map(gen);
  36. return alt.apply(undefined, _toConsumableArray(fragments));
  37. },
  38. Disjunction: function Disjunction(node) {
  39. return or(gen(node.left), gen(node.right));
  40. },
  41. Repetition: function Repetition(node) {
  42. switch (node.quantifier.kind) {
  43. case '*':
  44. return rep(gen(node.expression));
  45. case '+':
  46. return plusRep(gen(node.expression));
  47. case '?':
  48. return questionRep(gen(node.expression));
  49. default:
  50. throw new Error('Unknown repeatition: ' + node.quantifier.kind + '.');
  51. }
  52. },
  53. Char: function Char(node) {
  54. if (node.kind !== 'simple') {
  55. throw new Error('NFA/DFA: Only simple chars are supported yet.');
  56. }
  57. return char(node.value);
  58. },
  59. Group: function Group(node) {
  60. return gen(node.expression);
  61. }
  62. };
  63. module.exports = {
  64. /**
  65. * Builds an NFA from the passed regexp.
  66. */
  67. build: function build(regexp) {
  68. var ast = regexp;
  69. if (regexp instanceof RegExp) {
  70. regexp = '' + regexp;
  71. }
  72. if (typeof regexp === 'string') {
  73. ast = parser.parse(regexp, {
  74. captureLocations: true
  75. });
  76. }
  77. return gen(ast);
  78. }
  79. };