@@ -71,7 +71,8 @@ public List<Error> getErrors() {
7171 private List <Error > errors ;
7272 private List <BackReference > backrefs ;
7373 private int maxbackref ;
74- private String flags ;
74+ private Boolean vFlagEnabled = false ;
75+ private Boolean uFlagEnabled = false ;
7576
7677 /** Parse the given string as a regular expression. */
7778 public Result parse (String src ) {
@@ -88,7 +89,8 @@ public Result parse(String src) {
8889 }
8990
9091 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" );
9294 return parse (src );
9395 }
9496
@@ -300,7 +302,7 @@ private RegExpTerm parseDisjunctionInsideQuotedString() {
300302
301303 private RegExpTerm parseAlternativeInsideQuotedString () {
302304 SourceLocation loc = new SourceLocation (pos ());
303- StringBuilder sb = new StringBuilder () ;
305+ int startPos = this . pos ;
304306 boolean escaped = false ;
305307 while (true ) {
306308 // If we're at the end of the string, something went wrong.
@@ -316,13 +318,11 @@ private RegExpTerm parseAlternativeInsideQuotedString() {
316318 char c = this .nextChar ();
317319 // Track whether the character is an escape character.
318320 escaped = !escaped && (c == '\\' );
319- sb .append (c );
320321 }
321-
322- String literal = sb .toString ();
322+ String literal = src .substring (startPos , pos );
323323 loc .setEnd (pos ());
324324 loc .setSource (literal );
325-
325+
326326 return new Constant (loc , literal );
327327 }
328328
@@ -470,13 +470,13 @@ private RegExpTerm parseAtomEscape(SourceLocation loc, boolean inCharClass) {
470470 return this .finishTerm (new NamedBackReference (loc , name , "\\ k<" + name + ">" ));
471471 }
472472
473- if (this .match ("q{" )) {
473+ if (vFlagEnabled && this .match ("q{" )) {
474474 RegExpTerm term = parseDisjunctionInsideQuotedString ();
475475 this .expectRBrace ();
476476 return this .finishTerm (new CharacterClassQuotedString (loc , term ));
477477 }
478478
479- if (this .match ("p{" , "P{" )) {
479+ if (( vFlagEnabled || uFlagEnabled ) && this .match ("p{" , "P{" )) {
480480 String name = this .readIdentifier ();
481481 if (this .match ("=" )) {
482482 value = this .readIdentifier ();
@@ -548,7 +548,7 @@ private RegExpTerm parseAtomEscape(SourceLocation loc, boolean inCharClass) {
548548 }
549549
550550 private RegExpTerm parseCharacterClass () {
551- if (flags != null && flags . contains ( "v" ) ) return parseNestedCharacterClass ();
551+ if (vFlagEnabled ) return parseNestedCharacterClass ();
552552 SourceLocation loc = new SourceLocation (pos ());
553553 List <RegExpTerm > elements = new ArrayList <>();
554554
@@ -583,20 +583,10 @@ private RegExpTerm parseNestedCharacterClass() {
583583 this .error (Error .EXPECTED_RBRACKET );
584584 break ;
585585 }
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 ());
600590 }
601591
602592 // Create appropriate RegExpTerm based on the detected class type
0 commit comments