1
0
mirror of https://github.com/pdemian/human2regex.git synced 2025-05-15 20:10:19 -07:00

more bug fixes

This commit is contained in:
Patrick Demian 2021-01-19 15:23:04 -05:00
parent efa41ff249
commit 0026264eef
6 changed files with 46 additions and 16 deletions

View File

@ -6,6 +6,7 @@ docs/
src/ src/
tests/ tests/
jest.config.ts jest.config.ts
config.json
webpack.config.js webpack.config.js
tsconfig.json tsconfig.json
tslintconfig.json tslintconfig.json

2
docs/bundle.min.js vendored

File diff suppressed because one or more lines are too long

2
lib/generator.d.ts vendored
View File

@ -244,7 +244,7 @@ export declare class CountSubStatementCST extends H2RCST {
*/ */
constructor(tokens: IToken[], from: number, to?: number | null, opt?: "inclusive" | "exclusive" | "+" | null); constructor(tokens: IToken[], from: number, to?: number | null, opt?: "inclusive" | "exclusive" | "+" | null);
validate(language: RegexDialect, context: GeneratorContext): ISemanticError[]; validate(language: RegexDialect, context: GeneratorContext): ISemanticError[];
toRegex(language: RegexDialect): string; toRegex(language: RegexDialect, args: GeneratorArguments | null): string;
} }
/** /**
* Concrete Syntax Tree for a Match statement * Concrete Syntax Tree for a Match statement

View File

@ -365,7 +365,7 @@ class MatchSubStatementCST extends H2RCST {
} }
} }
let ret = ""; let ret = "";
if (args !== null && args.has_neighbours === true) { if (args === null || args === void 0 ? void 0 : args.has_neighbours) {
ret = generator_helper_1.minimizeMatchString(matches, true); ret = generator_helper_1.minimizeMatchString(matches, true);
} }
else { else {
@ -375,10 +375,13 @@ class MatchSubStatementCST extends H2RCST {
if (matches.length === 1) { if (matches.length === 1) {
// we don't group if there's only 1 element // we don't group if there's only 1 element
// but we need to make sure we don't add an additional + or * // but we need to make sure we don't add an additional + or *
ret = generator_helper_1.dontClobberRepetition(ret, this.count.toRegex(language)); ret = generator_helper_1.dontClobberRepetition(ret, this.count.toRegex(language, null));
} }
else { else {
ret = generator_helper_1.groupIfRequired(ret) + this.count.toRegex(language); const count_string = this.count.toRegex(language, { "dont_loop_one": true });
if (count_string !== "") {
ret = generator_helper_1.groupIfRequired(ret) + count_string;
}
} }
} }
return ret; return ret;
@ -468,14 +471,19 @@ class CountSubStatementCST extends H2RCST {
} }
return errors; return errors;
} }
toRegex(language) { toRegex(language, args) {
utilities_1.unusedParameter(language, "Count does not change from language"); utilities_1.unusedParameter(language, "Count does not change from language");
const from = this.from; const from = this.from;
let to = this.to; let to = this.to;
// if we only have a count of 1, we can ignore adding any extra text // if we only have a count of 1, we can ignore adding any extra text
if (to === null) { if (to === null) {
if (from === 1) { if (from === 1) {
return this.opt === "+" ? "+" : "*"; if (args === null || args === void 0 ? void 0 : args.dont_loop_one) {
return this.opt === "+" ? "+" : "";
}
else {
return this.opt === "+" ? "+" : "*";
}
} }
else if (from === 0) { else if (from === 0) {
return this.opt === "+" ? "*" : "{0}"; return this.opt === "+" ? "*" : "{0}";
@ -568,7 +576,7 @@ class RepeatStatementCST extends StatementCST {
toRegex(language) { toRegex(language) {
let str = generator_helper_1.groupIfRequired(this.statements.map((x) => x.toRegex(language, null)).join("")); let str = generator_helper_1.groupIfRequired(this.statements.map((x) => x.toRegex(language, null)).join(""));
if (this.count) { if (this.count) {
str += this.count.toRegex(language); str += this.count.toRegex(language, null);
// group for optionality because count would be incorrect otherwise // group for optionality because count would be incorrect otherwise
if (this.optional) { if (this.optional) {
str = "(?:" + str + ")?"; str = "(?:" + str + ")?";
@ -683,7 +691,7 @@ class BackrefStatementCST extends StatementCST {
break; break;
} }
if (this.count) { if (this.count) {
str += this.count.toRegex(language); str += this.count.toRegex(language, null);
// group for optionality because count would be incorrect otherwise // group for optionality because count would be incorrect otherwise
if (this.optional) { if (this.optional) {
str = "(?:" + str + ")?"; str = "(?:" + str + ")?";

View File

@ -425,7 +425,7 @@ export class MatchSubStatementCST extends H2RCST {
} }
let ret = ""; let ret = "";
if (args !== null && args.has_neighbours === true) { if (args?.has_neighbours) {
ret = minimizeMatchString(matches, true); ret = minimizeMatchString(matches, true);
} }
else { else {
@ -436,10 +436,14 @@ export class MatchSubStatementCST extends H2RCST {
if (matches.length === 1) { if (matches.length === 1) {
// we don't group if there's only 1 element // we don't group if there's only 1 element
// but we need to make sure we don't add an additional + or * // but we need to make sure we don't add an additional + or *
ret = dontClobberRepetition(ret, this.count.toRegex(language)); ret = dontClobberRepetition(ret, this.count.toRegex(language, null));
} }
else { else {
ret = groupIfRequired(ret) + this.count.toRegex(language); const count_string = this.count.toRegex(language, { "dont_loop_one": true });
if (count_string !== "") {
ret = groupIfRequired(ret) + count_string;
}
} }
} }
@ -541,7 +545,7 @@ export class CountSubStatementCST extends H2RCST {
return errors; return errors;
} }
public toRegex(language: RegexDialect): string { public toRegex(language: RegexDialect, args: GeneratorArguments | null): string {
unusedParameter(language, "Count does not change from language"); unusedParameter(language, "Count does not change from language");
const from = this.from; const from = this.from;
@ -551,7 +555,12 @@ export class CountSubStatementCST extends H2RCST {
// if we only have a count of 1, we can ignore adding any extra text // if we only have a count of 1, we can ignore adding any extra text
if (to === null) { if (to === null) {
if (from === 1) { if (from === 1) {
return this.opt === "+" ? "+" : "*"; if (args?.dont_loop_one) {
return this.opt === "+" ? "+" : "";
}
else {
return this.opt === "+" ? "+" : "*";
}
} }
else if (from === 0) { else if (from === 0) {
return this.opt === "+" ? "*" : "{0}"; return this.opt === "+" ? "*" : "{0}";
@ -654,7 +663,7 @@ export class RepeatStatementCST extends StatementCST {
let str = groupIfRequired(this.statements.map((x) => x.toRegex(language, null)).join("")); let str = groupIfRequired(this.statements.map((x) => x.toRegex(language, null)).join(""));
if (this.count) { if (this.count) {
str += this.count.toRegex(language); str += this.count.toRegex(language, null);
// group for optionality because count would be incorrect otherwise // group for optionality because count would be incorrect otherwise
if (this.optional) { if (this.optional) {
@ -788,7 +797,7 @@ export class BackrefStatementCST extends StatementCST {
} }
if (this.count) { if (this.count) {
str += this.count.toRegex(language); str += this.count.toRegex(language, null);
// group for optionality because count would be incorrect otherwise // group for optionality because count would be incorrect otherwise
if (this.optional) { if (this.optional) {

View File

@ -139,6 +139,18 @@ describe("Generator functionality", function() {
// should be (?!hello) not (?:(?!hello)) // should be (?!hello) not (?:(?!hello))
expect(reg1.toRegex(RegexDialect.JS)).toBe("/(?!hello){1,6}/"); expect(reg1.toRegex(RegexDialect.JS)).toBe("/(?!hello){1,6}/");
const toks2 = lexer.tokenize('match 1 words or "_" or "-"').tokens;
const reg2 = parser.parse(toks2);
expect(reg2.validate(RegexDialect.JS).length).toBe(0);
// should be /\w+|_|\-/ not /(?:\w+|_|\-)*/
expect(reg2.toRegex(RegexDialect.JS)).toBe("/\\w+|_|\\-/");
const toks3 = lexer.tokenize('repeat 1\n\tmatch "http"').tokens;
const reg3 = parser.parse(toks3);
expect(reg3.validate(RegexDialect.JS).length).toBe(0);
expect(reg3.toRegex(RegexDialect.JS)).toBe("/(?:http)*/");
}); });
it("optimizes correctly", function() { it("optimizes correctly", function() {