Skip to content

Commit

Permalink
Merge pull request #127 from liuxingbaoyu/modifiers
Browse files Browse the repository at this point in the history
feat: support modifiers proposal
  • Loading branch information
jviereck authored Jun 26, 2022
2 parents e66d3d0 + 9c14b21 commit 524fbd5
Show file tree
Hide file tree
Showing 6 changed files with 658 additions and 11 deletions.
39 changes: 30 additions & 9 deletions parser.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type Features = {
namedGroups?: boolean;
unicodePropertyEscape?: boolean;
unicodeSet?: boolean;
modifiers?: boolean;
};

export type AstNodeType =
Expand Down Expand Up @@ -98,15 +99,35 @@ export type CharacterClass<F extends Features = {}> = Base<"characterClass"> & {
kind: "union" | _If<F["unicodeSet"], "intersection" | "subtraction", never>;
};

export type NonCapturingGroup<F extends Features = {}> = Base<"group"> & {
behavior:
| "ignore"
| "lookahead"
| "lookbehind"
| "negativeLookahead"
| "negativeLookbehind";
body: RootNode<F>[];
};
export type ModifierFlags = {
enabling: string,
disabling: string
}

export type NonCapturingGroup<F extends Features = {}> = Base<"group"> &
(
| {
behavior:
| "lookahead"
| "lookbehind"
| "negativeLookahead"
| "negativeLookbehind";
body: RootNode<F>[];
}
| ({
behavior: "ignore";
body: RootNode<F>[];
} & _If<
F["modifiers"],
{
modifierFlags?: ModifierFlags;
},
{
modifierFlags: undefined;
}
>)
);


export type CapturingGroup<F extends Features = {}> = Base<"group"> & {
behavior: "normal";
Expand Down
60 changes: 59 additions & 1 deletion parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,16 @@
// ClassHalfOfDouble ::
// one of & - ! # % , : ; < = > @ _ ` ~
//
// --------------------------------------------------------------
// NOTE: The following productions refer to the
// "Regular Expression Pattern Modifiers for ECMAScript" proposal.
// https://github.com/tc39/proposal-regexp-modifiers
// --------------------------------------------------------------
//
// Atom ::
// ( ? RegularExpressionFlags : Disjunction )
// ( ? RegularExpressionFlags - RegularExpressionFlags : Disjunction )
//

"use strict";
(function() {
Expand Down Expand Up @@ -718,7 +728,8 @@
// \ AtomEscape
// CharacterClass
// ( GroupSpecifier Disjunction )
// ( ? : Disjunction )
// ( ? RegularExpressionFlags : Disjunction )
// ( ? RegularExpressionFlags - RegularExpressionFlags : Disjunction )
// ExtendedAtom ::
// ExtendedPatternCharacter
// ExtendedPatternCharacter ::
Expand Down Expand Up @@ -766,13 +777,60 @@
group.name = name;
return group;
}
else if (features.modifiers && str.indexOf("(?") == pos && str[pos+2] != ":") {
return parseModifiersGroup();
}
else {
// ( Disjunction )
// ( ? : Disjunction )
return parseGroup('(?:', 'ignore', '(', 'normal');
}
}

function parseModifiersGroup() {
function hasDupChar(str) {
var i = 0;
while (i < str.length) {
if (str.indexOf(str[i], i + 1) != -1) {
return true;
}
i++;
}
return false;
}

var from = pos;
incr(2);

var enablingFlags = matchReg(/^[sim]+/);
var disablingFlags;
if(match("-")){
disablingFlags = matchReg(/^[sim]+/);
if (!disablingFlags) {
bail('Invalid flags for modifiers group');
}
} else if(!enablingFlags){
bail('Invalid flags for modifiers group');
}

enablingFlags = enablingFlags ? enablingFlags[0] : "";
disablingFlags = disablingFlags ? disablingFlags[0] : "";

var flags = enablingFlags + disablingFlags;
if(flags.length > 3 || hasDupChar(flags)) {
bail('flags cannot be duplicated for modifiers group');
}

var modifiersGroup = finishGroup("ignore", from);

modifiersGroup.modifierFlags = {
enabling: enablingFlags,
disabling: disablingFlags
};

return modifiersGroup;
}

function parseUnicodeSurrogatePairEscape(firstEscape) {
if (isUnicodeMode) {
var first, second;
Expand Down
9 changes: 9 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ runTests('./test-data-unicode-set.json', 'v', {
unicodeSet: true,
unicodePropertyEscape: true
});
runTests('./test-data-modifiers-group.json', '', {
modifiers: true,
namedGroups: true,
});
runTests('./test-data-named-groups.json', '', {
modifiers: true,
namedGroups: true,
});


(function testUVError() {
var message = 'It should throw an error when using both the "u" and "v" flags.';
Expand Down
Loading

0 comments on commit 524fbd5

Please sign in to comment.