mirror of
https://github.com/pdemian/human2regex.git
synced 2025-05-15 20:10:19 -07:00
249 lines
7.6 KiB
JavaScript
249 lines
7.6 KiB
JavaScript
"use strict";
|
|
/*! Copyright (c) 2021 Patrick Demian; Licensed under MIT */
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.CommonError = exports.append = exports.regexEscape = exports.removeQuotes = exports.findLastIndex = exports.last = exports.first = exports.isRangeRegex = exports.isSingleRegexCharacter = exports.combineFlags = exports.hasFlag = exports.makeFlag = exports.usefulConditional = exports.unusedParameter = void 0;
|
|
/**
|
|
* The following section is used because the linter is set up to warn about certain operations
|
|
* and for good reason! I'd much rather have these functions than accidently use bitwise operations, or
|
|
* create a bunch of usless conditionals
|
|
* Plus, it signifies exactly what you wish to do (ex, calling hasFlag means you want to check if the
|
|
* bitpattern matches a given flag)
|
|
*/
|
|
/**
|
|
* Fixes linter warnings about unused variables, however requires a reason why it's unused
|
|
*
|
|
* @param value the value you want to specify that is unused
|
|
* @param reason the reason this value is required but unused in this context
|
|
* @internal
|
|
*/
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
function unusedParameter(value, reason) {
|
|
/* empty on purpose */
|
|
}
|
|
exports.unusedParameter = unusedParameter;
|
|
/**
|
|
* Fixes linter warnings about useless conditionals, however requires a reason why it's useless
|
|
*
|
|
* @param conditional the supposedly useless conditional
|
|
* @param reason the reason this value is required but considered useless
|
|
* @internal
|
|
*/
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
function usefulConditional(conditional, reason) {
|
|
return Boolean(conditional);
|
|
}
|
|
exports.usefulConditional = usefulConditional;
|
|
/* eslint-disable no-bitwise */
|
|
/**
|
|
* Generates a bitwise flag based on the value provided
|
|
*
|
|
* @param value the number of bits to shift
|
|
* @returns 1 << value
|
|
* @internal
|
|
*/
|
|
function makeFlag(value) {
|
|
return 1 << value;
|
|
}
|
|
exports.makeFlag = makeFlag;
|
|
/**
|
|
* Checks if value has the given flag
|
|
*
|
|
* @param value First flag to compare
|
|
* @param flag Second flag to compare
|
|
* @returns value & flag
|
|
* @internal
|
|
*/
|
|
function hasFlag(value, flag) {
|
|
return (value & flag) !== 0;
|
|
}
|
|
exports.hasFlag = hasFlag;
|
|
/**
|
|
* Appends the flag to the value
|
|
*
|
|
* @param value First flag
|
|
* @param flag Second flag
|
|
* @returns value | flag
|
|
* @internal
|
|
*/
|
|
function combineFlags(value, flag) {
|
|
return (value | flag);
|
|
}
|
|
exports.combineFlags = combineFlags;
|
|
/* eslint-enable no-bitwise */
|
|
/**
|
|
* Checks to see if the character is a single regex character
|
|
*
|
|
* @remarks unicode and escape characters count as a single character
|
|
*
|
|
* @param char the character to check
|
|
* @returns if the value is exactly 1 character
|
|
* @internal
|
|
*/
|
|
function isSingleRegexCharacter(char) {
|
|
return (char.startsWith("\\u") && char.length === 6) ||
|
|
(char.startsWith("\\U") && char.length === 8) ||
|
|
(char.startsWith("\\") && char.length === 2) ||
|
|
char.length === 1;
|
|
}
|
|
exports.isSingleRegexCharacter = isSingleRegexCharacter;
|
|
/**
|
|
* Checks to see if the character is a range
|
|
*
|
|
* @remarks a range is in the format of [X-Y] where X and Y are valid single regex characters
|
|
*
|
|
* @param str the string to check
|
|
* @returns if the value is a regex range
|
|
* @internal
|
|
*/
|
|
function isRangeRegex(str) {
|
|
if (!str.startsWith("[") && !str.endsWith("]")) {
|
|
return false;
|
|
}
|
|
const split = str.substring(1, str.length - 1).split("-");
|
|
if (split.length !== 2) {
|
|
return false;
|
|
}
|
|
//hack: check to ensure that we aren't escaped
|
|
if (split[0].endsWith("\\") && split[0] !== "\\\\") {
|
|
return false;
|
|
}
|
|
// ensure the "-" wasn't escaped
|
|
return isSingleRegexCharacter(split[0]) && isSingleRegexCharacter(split[1]);
|
|
}
|
|
exports.isRangeRegex = isRangeRegex;
|
|
/**
|
|
* Gets the first element of an array
|
|
* @remarks does not validate if array has any elements
|
|
*
|
|
* @param array an array
|
|
* @returns first element of an array
|
|
* @internal
|
|
*/
|
|
function first(array) {
|
|
return array[0];
|
|
}
|
|
exports.first = first;
|
|
/**
|
|
* Gets the last element of an array
|
|
* @remarks does not validate if array has any elements
|
|
*
|
|
* @param array an array
|
|
* @returns last element of an array
|
|
* @internal
|
|
*/
|
|
function last(array) {
|
|
return array[array.length - 1];
|
|
}
|
|
exports.last = last;
|
|
/**
|
|
* Find the last index of a given value in an array
|
|
*
|
|
* @param array an array
|
|
* @param value the value to find
|
|
* @returns an index if found or -1 if not found
|
|
* @internal
|
|
*/
|
|
function findLastIndex(array, value) {
|
|
for (let index = array.length - 1; index >= 0; index--) {
|
|
if (array[index] === value) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
exports.findLastIndex = findLastIndex;
|
|
/**
|
|
* Removes start and end quotes from a string
|
|
*
|
|
* @param input the string to remove quotes from
|
|
* @returns a string without quote characters
|
|
* @internal
|
|
*/
|
|
function removeQuotes(input) {
|
|
return input.substring(1, input.length - 1);
|
|
}
|
|
exports.removeQuotes = removeQuotes;
|
|
/**
|
|
* Escapes a string so it may be used literally in a regular expression
|
|
*
|
|
* @param input the string to escape
|
|
* @returns a regex escaped string
|
|
* @internal
|
|
*/
|
|
function regexEscape(input) {
|
|
return input.replace('\\"', '"').replace(/([:\\\-\.\[\]\^\|\(\)\*\+\?\{\}\$\/])/g, "\\$1");
|
|
}
|
|
exports.regexEscape = regexEscape;
|
|
/**
|
|
* Append a list of arrays to an array
|
|
*
|
|
* @param array the array to append to
|
|
* @param arrays the list of arrays that you want to add to array
|
|
* @internal
|
|
*/
|
|
function append(array, ...arrays) {
|
|
for (const list of arrays) {
|
|
for (const item of list) {
|
|
array.push(item);
|
|
}
|
|
}
|
|
}
|
|
exports.append = append;
|
|
/**
|
|
* Common Error class that encapsulates information from the lexer, parser, and generator
|
|
*/
|
|
class CommonError {
|
|
constructor(type, start_line, start_column, length, message) {
|
|
this.type = type;
|
|
this.start_line = start_line;
|
|
this.start_column = start_column;
|
|
this.length = length;
|
|
this.message = message;
|
|
/* empty */
|
|
}
|
|
/**
|
|
* Creates a common error from a lexing error
|
|
*
|
|
* @param error The lexing error
|
|
* @returns a new CommonError
|
|
* @internal
|
|
*/
|
|
static fromLexError(error) {
|
|
// not really fond of --> and <--
|
|
const new_msg = error.message.replace(/(--?>|<--?)/g, "");
|
|
return new CommonError("Lexer Error", error.line, error.column, error.length, new_msg);
|
|
}
|
|
/**
|
|
* Creates a common error from a parsing error
|
|
*
|
|
* @param error The parsing error
|
|
* @returns a new CommonError
|
|
* @internal
|
|
*/
|
|
static fromParseError(error) {
|
|
var _a, _b, _c;
|
|
// not really fond of --> and <--
|
|
const new_msg = error.name + " - " + error.message.replace(/(--?>|<--?)/g, "");
|
|
return new CommonError("Parser Error", (_a = error.token.startLine) !== null && _a !== void 0 ? _a : NaN, (_b = error.token.startColumn) !== null && _b !== void 0 ? _b : NaN, (_c = error.token.endOffset) !== null && _c !== void 0 ? _c : NaN - error.token.startOffset, new_msg);
|
|
}
|
|
/**
|
|
* Creates a common error from a semantic error
|
|
*
|
|
* @param error The semantic error
|
|
* @returns a new CommonError
|
|
* @internal
|
|
*/
|
|
static fromSemanticError(error) {
|
|
return new CommonError("Semantic Error", error.startLine, error.startColumn, error.length, error.message);
|
|
}
|
|
/**
|
|
* Generates a string representation of a CommonError
|
|
*
|
|
* @returns a string representation
|
|
*/
|
|
toString() {
|
|
return `${this.type} @ (${this.start_line}, ${this.start_column}): ${this.message}`;
|
|
}
|
|
}
|
|
exports.CommonError = CommonError;
|