Skip to content

Commit

Permalink
Normative: allow duplicate named capture groups
Browse files Browse the repository at this point in the history
  • Loading branch information
bakkot committed May 25, 2022
1 parent 7ae3ecf commit 2140ce7
Showing 1 changed file with 41 additions and 13 deletions.
54 changes: 41 additions & 13 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -34639,7 +34639,7 @@ <h1>Static Semantics: Early Errors</h1>
It is a Syntax Error if CountLeftCapturingParensWithin(|Pattern|) &ge; 2<sup>32</sup> - 1.
</li>
<li>
It is a Syntax Error if |Pattern| contains two or more |GroupSpecifier|s for which CapturingGroupName of |GroupSpecifier| is the same.
It is a Syntax Error if |Pattern| contains two distinct |GroupSpecifier|s _x_ and _y_ for which CapturingGroupName(_x_) is the same as CapturingGroupName(_y_) and such that CanBothParticipate(_x_, _y_) is *true*.
</li>
</ul>
<emu-grammar>QuantifierPrefix :: `{` DecimalDigits `,` DecimalDigits `}`</emu-grammar>
Expand Down Expand Up @@ -34758,6 +34758,22 @@ <h1>
</emu-alg>
</emu-clause>

<emu-clause id="sec-patterns-static-semantics-can-both-participate" type="abstract operation">
<h1>
Static Semantics: CanBothParticipate (
_x_: a Parse Node,
_y_: a Parse Node,
): a Boolean
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: _x_ and _y_ have the same enclosing |Pattern|.
1. If the enclosing |Pattern| contains a <emu-grammar>Disjunction :: Alternative `|` Disjunction</emu-grammar> Parse Node such that either _x_ is contained within the |Alternative| and _y_ is contained within the derived |Disjunction|, or _x_ is contained within the derived |Disjunction| and _y_ is contained within the |Alternative|, return *false*.
1. Return *true*.
</emu-alg>
</emu-clause>

<emu-clause id="sec-patterns-static-semantics-capturing-group-number" type="sdo">
<h1>Static Semantics: CapturingGroupNumber ( ): a positive integer</h1>
<dl class="header">
Expand Down Expand Up @@ -35023,7 +35039,7 @@ <h1>
1. Let _pattern_ be the |Pattern| containing _thisGroupName_.
1. Let _result_ be a new empty List.
1. For each |GroupSpecifier| _gs_ that _pattern_ contains, do
1. If the CapturingGroupName of _gs_ is the same value as _name_, then
1. If the CapturingGroupName of _gs_ is the same value as _name_, and CanBothParticipate(_thisGroupName_, _gs_) is *true*, then
1. Append _gs_ to _result_.
1. Return _result_.
</emu-alg>
Expand Down Expand Up @@ -35598,7 +35614,7 @@ <h1>
<emu-alg>
1. Let _n_ be the CapturingGroupNumber of |DecimalEscape|.
1. Assert: _n_ &le; _NcapturingParens_.
1. Return BackreferenceMatcher(_n_, _direction_).
1. Return BackreferenceMatcher(&laquo; _n_ &raquo;, _direction_).
</emu-alg>
<emu-note>
<p>An escape sequence of the form `\\` followed by a non-zero decimal number _n_ matches the result of the _n_<sup>th</sup> set of capturing parentheses (<emu-xref href="#sec-notation"></emu-xref>). It is an error if the regular expression has fewer than _n_ capturing parentheses. If the regular expression has _n_ or more capturing parentheses but the _n_<sup>th</sup> one is *undefined* because it has not captured anything, then the backreference always succeeds.</p>
Expand All @@ -35618,10 +35634,11 @@ <h1>
<emu-grammar>AtomEscape :: `k` GroupName</emu-grammar>
<emu-alg>
1. Let _matchingGroupSpecifiers_ be GroupSpecifiersThatMatch(|GroupName|).
1. Assert: _matchingGroupSpecifiers_ contains a single |GroupSpecifier|.
1. Let _groupSpecifier_ be the sole element of _matchingGroupSpecifiers_.
1. Let _parenIndex_ be CountLeftCapturingParensBefore(_groupSpecifier_).
1. Return BackreferenceMatcher(_parenIndex_, _direction_).
1. Let _parenIndices_ be a new empty List.
1. For each |GroupSpecifier| _groupSpecifier_ of _matchingGroupSpecifiers_, do
1. Let _parenIndex_ be CountLeftCapturingParensBefore(_groupSpecifier_).
1. Append _parenIndex_ to _parenIndices_.
1. Return BackreferenceMatcher(_parenIndices_, _direction_).
</emu-alg>

<emu-clause id="sec-runtime-semantics-charactersetmatcher-abstract-operation" type="abstract operation">
Expand Down Expand Up @@ -35657,19 +35674,22 @@ <h1>
<emu-clause id="sec-backreference-matcher" type="abstract operation">
<h1>
BackreferenceMatcher (
_n_: a positive integer,
_ns_: a List of positive integers,
_direction_: ~forward~ or ~backward~,
): a Matcher
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: _n_ &ge; 1.
1. Return a new Matcher with parameters (_x_, _c_) that captures _n_ and _direction_ and performs the following steps when called:
1. Return a new Matcher with parameters (_x_, _c_) that captures _ns_ and _direction_ and performs the following steps when called:
1. Assert: _x_ is a State.
1. Assert: _c_ is a Continuation.
1. Let _cap_ be _x_'s _captures_ List.
1. Let _r_ be _cap_[_n_].
1. Let _r_ be *undefined*.
1. For each integer _n_ of _ns_, do
1. If _cap_[_n_] is not *undefined*, then
1. Assert: _r_ is *undefined*.
1. Set _r_ to _cap_[_n_].
1. If _r_ is *undefined*, return _c_(_x_).
1. Let _e_ be _x_'s _endIndex_.
1. Let _rs_ be _r_'s _startIndex_.
Expand Down Expand Up @@ -36262,8 +36282,16 @@ <h1>
1. Perform ! CreateDataPropertyOrThrow(_A_, ! ToString(𝔽(_i_)), _capturedValue_).
1. If the _i_<sup>th</sup> capture of _R_ was defined with a |GroupName|, then
1. Let _s_ be the CapturingGroupName of that |GroupName|.
1. Perform ! CreateDataPropertyOrThrow(_groups_, _s_, _capturedValue_).
1. Append _s_ to _groupNames_.
1. Let _isMatchedElsewhere_ be *false*.
1. For each integer _j_ such that _j_ &ne; _i_, _j_ &ge; 1, and _j_ &le; _n_, do
1. If the _j_<sup>th</sup> capture of _R_ was defined with a |GroupName|, then
1. Let _sj_ be the CapturingGroupName of that |GroupName|.
1. If _sj_ equals _s_ and the _j_<sup>th</sup> capture of _R_ is not *undefined*, set _isMatchedElsewhere_ to *true*.
1. If _isMatchedElsewhere_ is *false*, then
1. Perform ! CreateDataPropertyOrThrow(_groups_, _s_, _capturedValue_).
1. Append _s_ to _groupNames_.
1. Else,
1. Append *undefined* to _groupNames_.
1. Else,
1. Append *undefined* to _groupNames_.
1. If _hasIndices_ is *true*, then
Expand Down

0 comments on commit 2140ce7

Please sign in to comment.