@@ -71,7 +71,8 @@ public List<Error> getErrors() {
71
71
private List <Error > errors ;
72
72
private List <BackReference > backrefs ;
73
73
private int maxbackref ;
74
- private String flags ;
74
+ private Boolean vFlagEnabled = false ;
75
+ private Boolean uFlagEnabled = false ;
75
76
76
77
/** Parse the given string as a regular expression. */
77
78
public Result parse (String src ) {
@@ -88,7 +89,8 @@ public Result parse(String src) {
88
89
}
89
90
90
91
public Result parse (String src , String flags ) {
91
- this .flags = flags ;
92
+ vFlagEnabled = flags != null && flags .contains ("v" );
93
+ uFlagEnabled = flags != null && flags .contains ("u" );
92
94
return parse (src );
93
95
}
94
96
@@ -300,7 +302,7 @@ private RegExpTerm parseDisjunctionInsideQuotedString() {
300
302
301
303
private RegExpTerm parseAlternativeInsideQuotedString () {
302
304
SourceLocation loc = new SourceLocation (pos ());
303
- StringBuilder sb = new StringBuilder () ;
305
+ int startPos = this . pos ;
304
306
boolean escaped = false ;
305
307
while (true ) {
306
308
// If we're at the end of the string, something went wrong.
@@ -316,13 +318,11 @@ private RegExpTerm parseAlternativeInsideQuotedString() {
316
318
char c = this .nextChar ();
317
319
// Track whether the character is an escape character.
318
320
escaped = !escaped && (c == '\\' );
319
- sb .append (c );
320
321
}
321
-
322
- String literal = sb .toString ();
322
+ String literal = src .substring (startPos , pos );
323
323
loc .setEnd (pos ());
324
324
loc .setSource (literal );
325
-
325
+
326
326
return new Constant (loc , literal );
327
327
}
328
328
@@ -470,13 +470,13 @@ private RegExpTerm parseAtomEscape(SourceLocation loc, boolean inCharClass) {
470
470
return this .finishTerm (new NamedBackReference (loc , name , "\\ k<" + name + ">" ));
471
471
}
472
472
473
- if (this .match ("q{" )) {
473
+ if (vFlagEnabled && this .match ("q{" )) {
474
474
RegExpTerm term = parseDisjunctionInsideQuotedString ();
475
475
this .expectRBrace ();
476
476
return this .finishTerm (new CharacterClassQuotedString (loc , term ));
477
477
}
478
478
479
- if (this .match ("p{" , "P{" )) {
479
+ if (( vFlagEnabled || uFlagEnabled ) && this .match ("p{" , "P{" )) {
480
480
String name = this .readIdentifier ();
481
481
if (this .match ("=" )) {
482
482
value = this .readIdentifier ();
@@ -548,7 +548,7 @@ private RegExpTerm parseAtomEscape(SourceLocation loc, boolean inCharClass) {
548
548
}
549
549
550
550
private RegExpTerm parseCharacterClass () {
551
- if (flags != null && flags . contains ( "v" ) ) return parseNestedCharacterClass ();
551
+ if (vFlagEnabled ) return parseNestedCharacterClass ();
552
552
SourceLocation loc = new SourceLocation (pos ());
553
553
List <RegExpTerm > elements = new ArrayList <>();
554
554
@@ -583,20 +583,10 @@ private RegExpTerm parseNestedCharacterClass() {
583
583
this .error (Error .EXPECTED_RBRACKET );
584
584
break ;
585
585
}
586
- if (lookahead ("[" )) {
587
- elements .add (parseNestedCharacterClass ());
588
- }
589
- else if (lookahead ("&&" )) {
590
- this .match ("&&" );
591
- classType = CharacterClassType .INTERSECTION ;
592
- }
593
- else if (lookahead ("--" )) {
594
- this .match ("--" );
595
- classType = CharacterClassType .SUBTRACTION ;
596
- }
597
- else {
598
- elements .add (this .parseCharacterClassElement ());
599
- }
586
+ if (lookahead ("[" )) elements .add (parseNestedCharacterClass ());
587
+ else if (this .match ("&&" )) classType = CharacterClassType .INTERSECTION ;
588
+ else if (this .match ("--" )) classType = CharacterClassType .SUBTRACTION ;
589
+ else elements .add (this .parseCharacterClassElement ());
600
590
}
601
591
602
592
// Create appropriate RegExpTerm based on the detected class type
0 commit comments