private static CharSet doParseString(String s){
  CharSet result=new CharSet();
  int p=0;
  boolean haveDash=false;
  boolean haveTilde=false;
  boolean wIsReal=false;
  int w=0x0000;
  while (p < s.length()) {
    int c=s.codePointAt(p);
    if (c == '[') {
      if (wIsReal) {
        result.internalUnion(new CharSet(w));
      }
      int bracketLevel=1;
      int q=p + 1;
      while (bracketLevel != 0) {
        if (q >= s.length()) {
          throw new IllegalArgumentException("Parse error at position " + p + " in "+ s);
        }
        int ch=s.codePointAt(q);
switch (ch) {
case '\\':
          ch=s.codePointAt(++q);
        break;
case '[':
      ++bracketLevel;
    break;
case ']':
  --bracketLevel;
break;
}
q+=Character.charCount(ch);
}
--q;
if (!haveTilde) {
result.internalUnion(CharSet.parseString(s.substring(p + 1,q)));
}
 else {
result.internalDifference(CharSet.parseString(s.substring(p + 1,q)));
}
haveTilde=false;
haveDash=false;
wIsReal=false;
p=q + 1;
}
 else if (c == ':') {
if (wIsReal) {
result.internalUnion(new CharSet(w));
}
int q=s.indexOf(':',p + 1);
if (q == -1) {
throw new IllegalArgumentException("Parse error at position " + p + " in "+ s);
}
if (!haveTilde) {
result.internalUnion(charSetForCategory(s.substring(p + 1,q)));
}
 else {
result.internalDifference(charSetForCategory(s.substring(p + 1,q)));
}
haveTilde=false;
haveDash=false;
wIsReal=false;
p=q + 1;
}
 else if (c == '-') {
if (wIsReal) {
haveDash=true;
}
++p;
}
 else if (c == '^') {
if (wIsReal) {
result.internalUnion(new CharSet(w));
wIsReal=false;
}
haveTilde=true;
++p;
if (result.empty()) {
result.internalComplement();
}
}
 else if (c >= ' ' && c < '\u007f' && !Character.isLetter((char)c) && !Character.isDigit((char)c) && c != '\\') {
throw new IllegalArgumentException("Parse error at position " + p + " in "+ s);
}
 else {
if (c == '\\') {
++p;
}
if (haveDash) {
if (s.codePointAt(p) < w) {
throw new IllegalArgumentException("U+" + Integer.toHexString(s.codePointAt(p)) + " is less than U+"+ Integer.toHexString(w)+ ".  Dash expressions "+ "can't have their endpoints in reverse order.");
}
int ch=s.codePointAt(p);
if (!haveTilde) {
result.internalUnion(new CharSet(w,ch));
}
 else {
result.internalDifference(new CharSet(w,ch));
}
p+=Character.charCount(ch);
haveDash=false;
haveTilde=false;
wIsReal=false;
}
 else if (haveTilde) {
w=s.codePointAt(p);
result.internalDifference(new CharSet(w));
p+=Character.charCount(w);
haveTilde=false;
wIsReal=false;
}
 else if (wIsReal) {
result.internalUnion(new CharSet(w));
w=s.codePointAt(p);
p+=Character.charCount(w);
wIsReal=true;
}
 else {
w=s.codePointAt(p);
p+=Character.charCount(w);
wIsReal=true;
}
}
}
if (wIsReal) {
result.internalUnion(new CharSet(w));
}
return result;
}

private static CharSet doParseString ( String s ) { CharSet result = new CharSet ( ) ; int p = 0 ; boolean haveDash = false ; boolean haveTilde = false ; boolean wIsReal = false ; int w = 0x0000 ; while ( p < s . length ( ) ) { int c = s . codePointAt ( p ) ; if ( c == '[' ) { if ( wIsReal ) { result . internalUnion ( new CharSet ( w ) ) ; } int bracketLevel = 1 ; int q = p + 1 ; while ( bracketLevel != 0 ) { if ( q >= s . length ( ) ) { throw new IllegalArgumentException ( "Parse error at position " + p + " in " + s ) ; } int ch = s . codePointAt ( q ) ; switch ( ch ) { case '\\' : ch = s . codePointAt ( ++ q ) ; break ; case '[' : ++ bracketLevel ; break ; case ']' : -- bracketLevel ; break ; } q += Character . charCount ( ch ) ; } -- q ; if ( ! haveTilde ) { result . internalUnion ( CharSet . parseString ( s . substring ( p + 1 , q ) ) ) ; } else { result . internalDifference ( CharSet . parseString ( s . substring ( p + 1 , q ) ) ) ; } haveTilde = false ; haveDash = false ; wIsReal = false ; p = q + 1 ; } else if ( c == ':' ) { if ( wIsReal ) { result . internalUnion ( new CharSet ( w ) ) ; } int q = s . indexOf ( ':' , p + 1 ) ; if ( q == - 1 ) { throw new IllegalArgumentException ( "Parse error at position " + p + " in " + s ) ; } if ( ! haveTilde ) { result . internalUnion ( charSetForCategory ( s . substring ( p + 1 , q ) ) ) ; } else { result . internalDifference ( charSetForCategory ( s . substring ( p + 1 , q ) ) ) ; } haveTilde = false ; haveDash = false ; wIsReal = false ; p = q + 1 ; } else if ( c == '-' ) { if ( wIsReal ) { haveDash = true ; } ++ p ; } else if ( c == '^' ) { if ( wIsReal ) { result . internalUnion ( new CharSet ( w ) ) ; wIsReal = false ; } haveTilde = true ; ++ p ; if ( result . empty ( ) ) { result . internalComplement ( ) ; } } else if ( c >= ' ' && c < '' && ! Character . isLetter ( ( char ) c ) && ! Character . isDigit ( ( char ) c ) && c != '\\' ) { throw new IllegalArgumentException ( "Parse error at position " + p + " in " + s ) ; } else { if ( c == '\\' ) { ++ p ; } if ( haveDash ) { if ( s . codePointAt ( p ) < w ) { throw new IllegalArgumentException ( "U+" + Integer . toHexString ( s . codePointAt ( p ) ) + " is less than U+" + Integer . toHexString ( w ) + ".  Dash expressions " + "can't have their endpoints in reverse order." ) ; } int ch = s . codePointAt ( p ) ; if ( ! haveTilde ) { result . internalUnion ( new CharSet ( w , ch ) ) ; } else { result . internalDifference ( new CharSet ( w , ch ) ) ; } p += Character . charCount ( ch ) ; haveDash = false ; haveTilde = false ; wIsReal = false ; } else if ( haveTilde ) { w = s . codePointAt ( p ) ; result . internalDifference ( new CharSet ( w ) ) ; p += Character . charCount ( w ) ; haveTilde = false ; wIsReal = false ; } else if ( wIsReal ) { result . internalUnion ( new CharSet ( w ) ) ; w = s . codePointAt ( p ) ; p += Character . charCount ( w ) ; wIsReal = true ; } else { w = s . codePointAt ( p ) ; p += Character . charCount ( w ) ; wIsReal = true ; } } } if ( wIsReal ) { result . internalUnion ( new CharSet ( w ) ) ; } return result ; }
this function is used by parsestring ( ) to actually parse the string
