UNPKG

incr-regex-package

Version:

An incremental regular expression parser in JavaScript; useful for input validation, RegExp

277 lines (231 loc) 8.06 kB
/** * Copyright (c) 2016, Nurul Choudhury * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ // "use strict"; // import {gtPrec,sprefix,rprefix,shead,stail,sRightMerge, // stringToList, listToArray, listToString, StackDedup, n_cons, // n_head, n_tail, n_filter, n_reduce, n_map, n_concat, // n_removeAll, flatten,arr_push , arr_uniq } from "./utils"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IREGEX = exports.isOptional = exports.isMeta = exports.convertMask = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _regexUtils = require("./regex-utils"); Object.defineProperty(exports, "convertMask", { enumerable: true, get: function get() { return _regexUtils.convertMask; } }); Object.defineProperty(exports, "isMeta", { enumerable: true, get: function get() { return _regexUtils.isMeta; } }); Object.defineProperty(exports, "isOptional", { enumerable: true, get: function get() { return _regexUtils.isOptional; } }); exports.incrRegEx = incrRegEx; var _utils = require("./utils"); var _rxtree = require("./rxtree"); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } //import {RxParser} from './regexp-parser'; function isLowerCase(ch) { var code = ch.charCodeAt(0); return code >= 97 && code <= 122; } // New Regexp /** * */ var IREGEX = exports.IREGEX = function (_BaseIncRegEx) { _inherits(IREGEX, _BaseIncRegEx); function IREGEX() { _classCallCheck(this, IREGEX); return _possibleConstructorReturn(this, (IREGEX.__proto__ || Object.getPrototypeOf(IREGEX)).apply(this, arguments)); } _createClass(IREGEX, [{ key: "toString", /** * [toString description] * @return {[type]} [description] */ value: function toString() { return this.str; } /* public */ /** * [getInputLength description] * @return {[type]} [description] */ }, { key: "getInputLength", value: function getInputLength() { return this.tracker.length; } /** * [isDone description] * @param {[type]} ix [description] * @return {Boolean} [description] */ }, { key: "isDone", value: function isDone(ix) { if (ix >= this.tracker.length || ix === undefined) { return this.state() === _rxtree.DONE; } return false; } /** * [getTree description] * @return {[type]} [description] */ }, { key: "getTree", value: function getTree() { return this.base; } /* public */ // Get the parse tree from the regular expression /** * [minChars description] * @return {[type]} [description] */ }, { key: "minChars", value: function minChars() { /* public */ // get a ask for the regular expression from the current state of the match this._mask = (0, _regexUtils.getArrayMask)(this.current); return this._mask; } /** * [match description] * @param {singleCharacterString} ch the characted to match * @return {boolean} */ }, { key: "match", value: function match(ch) { /* public */ var fixed = (0, _rxtree.getArrayFixedAt)(this.current); var res = this.test(ch === _rxtree.HOLDER_ANY ? undefined : ch); if (res === undefined && ch && isLowerCase(ch)) { res = this.test(ch.toUpperCase()); ch = ch.toUpperCase(); } return this._update(res, ch, fixed); } /** * matchStr will match as much of the input string as possible, * return the result as rray with the following values * [ * matchFlag : boolean - true if the entire string matched, false otherwise * count : integer - the lenght of the substring that matched * matchingStr : string - the substring that matched * ] * @param {string} str [description] * @return {[totalMatch: boolean, howManyMatched: int32, strThatMatched: string]} */ }, { key: "matchStr", value: function matchStr(str) { /* public */ var len = str.length; var b1 = true, b2 = 0; //,b3=[]; var i = 0; for (i = 0; i < len; i++) { var ch = str[i]; if (!this.match(ch)) { b1 = false;break; } this.lastCh = ch; b2++; } return [b1, b2, str.substring(0, i)]; } /** * [state description] * @return {[type]} [description] */ }, { key: "state", value: function state() { /* public */ this._state = this._state || this._stateCompute(); return this._state; } /** * [stateStr description] * @return {[type]} [description] */ }, { key: "stateStr", value: function stateStr() { var s = this.state(); if (s === _rxtree.MORE) return "MORE"; // match is not complete but good so far if (s === _rxtree.MAYBE) return "OK"; // match is complete but could have more return "DONE"; } /** * [inputStr description] * @return {[type]} [description] */ }, { key: "inputStr", value: function inputStr() { return this.tracker.map(function (a) { return a[0]; }).join(''); } /** * [fixed description] * @return {[type]} [description] */ }, { key: "fixed", value: function fixed() { return (0, _rxtree.getArrayFixedAt)(this.current); } /** * [getCurrentStates description] * @return {[type]} [description] */ }, { key: "getCurrentStates", value: function getCurrentStates() { return this.current.map(_utils.ID); } }, { key: "length", /** * [length description] * @return {[type]} [description] */ get: function get() { return this._len; } }]); return IREGEX; }(_regexUtils.BaseIncRegEx); function incrRegEx(str, v) { return new IREGEX(str, v); }