@@ -60,7 +60,7 @@ class PatternAcceptorState {
6060 this . pattern = pattern ;
6161 this . unicode = unicode ;
6262 this . index = 0 ;
63- this . backreferences = [ ] ;
63+ this . largestBackreference = 0 ;
6464 this . backreferenceNames = [ ] ;
6565 this . groupingNames = [ ] ;
6666 this . capturingGroups = 0 ;
@@ -70,6 +70,12 @@ class PatternAcceptorState {
7070 return this . index >= this . pattern . length ;
7171 }
7272
73+ backreference ( ref ) {
74+ if ( ref > this . largestBackreference ) {
75+ this . largestBackreference = ref ;
76+ }
77+ }
78+
7379 nextCodePoint ( ) {
7480 if ( this . empty ( ) ) {
7581 return null ;
@@ -190,10 +196,8 @@ export default (pattern, { unicode = false } = {}) => {
190196 let accepted = acceptDisjunction ( state ) ;
191197 if ( accepted . matched ) {
192198 if ( state . unicode ) {
193- for ( let backreference of state . backreferences ) {
194- if ( backreference > state . capturingGroups ) {
195- return false ;
196- }
199+ if ( state . largestBackreference > state . capturingGroups ) {
200+ return false ;
197201 }
198202 }
199203 if ( state . groupingNames . length > 0 || state . unicode ) {
@@ -209,12 +213,12 @@ export default (pattern, { unicode = false } = {}) => {
209213
210214const backtrackOnFailure = func => state => {
211215 let savedIndex = state . index ;
212- let oldBackreferences = state . backreferences . slice ( 0 ) ;
216+ let oldBackreference = state . largestBackreference ;
213217 let oldCapturingGroups = state . capturingGroups ;
214218 let val = func ( state ) ;
215219 if ( ! val . matched ) {
216220 state . index = savedIndex ;
217- state . backreferences = oldBackreferences ;
221+ state . largestBackreference = oldBackreference ;
218222 state . capturingGroups = oldCapturingGroups ;
219223 }
220224 return val ;
@@ -428,13 +432,16 @@ const acceptGrouping = backtrackOnFailure(state => {
428432} ) ;
429433
430434const acceptDecimalEscape = backtrackOnFailure ( state => {
431- let firstDecimal = state . eatAny ( ...decimalDigits . slice ( 1 ) ) ;
435+ let firstDecimal = state . eatAny ( ...decimalDigits ) ;
432436 if ( firstDecimal === null ) {
433437 return { matched : false } ;
434438 }
439+ if ( firstDecimal === '0' ) {
440+ return { matched : true } ;
441+ }
435442 // we also accept octal escapes here, but it is impossible to tell if it is a octal escape until all parsing is complete.
436443 // octal escapes are handled in acceptCharacterEscape for classes
437- state . backreferences . push ( parseInt ( firstDecimal + ( state . eatNaturalNumber ( ) || '' ) ) ) ;
444+ state . backreference ( parseInt ( firstDecimal + ( state . eatNaturalNumber ( ) || '' ) ) ) ;
438445 return { matched : true } ;
439446} ) ;
440447
@@ -648,12 +655,6 @@ const acceptCharacterClass = backtrackOnFailure(state => {
648655 subState => {
649656 return { matched : ! ! subState . eat ( 'b' ) , value : 0x0008 } ;
650657 } ,
651- subState => {
652- if ( ! subState . unicode ) {
653- return { matched : false } ;
654- }
655- return acceptDecimalEscape ( subState ) ;
656- } ,
657658 subState => {
658659 return { matched : subState . unicode && ! ! subState . eat ( '-' ) , value : '-' . charCodeAt ( 0 ) } ;
659660 } ,
0 commit comments