public override string ToString()
        {
            StringBuilder rslt = new StringBuilder();

            rslt.Append('[');
            if (invert)
            {
                rslt.Append('^');
            }
            if (!isCanonical)
            {
                Canonicalize();
            }
            foreach (CharRange range in ranges)
            {
                if (range.minChr == range.maxChr)
                {
                    rslt.Append(CharacterUtilities.MapForCharSet(range.minChr));
                }
                else
                {
                    rslt.Append(CharacterUtilities.MapForCharSet(range.minChr));
                    rslt.Append('-');
                    rslt.Append(CharacterUtilities.MapForCharSet(range.maxChr));
                }
            }
            rslt.Append(']');
            return(rslt.ToString());
        }
 public override string ToString()
 {
     if (minChr == maxChr)
     {
         return(String.Format(CultureInfo.InvariantCulture, "singleton char {0}", CharacterUtilities.Map(minChr)));
     }
     else
     {
         return(String.Format(CultureInfo.InvariantCulture, "char range {0} .. {1}, {2} chars",
                              CharacterUtilities.Map(minChr), CharacterUtilities.Map(maxChr), maxChr - minChr + 1));
     }
 }
        internal override void Op(RegExTree tree)
        {
            Leaf leaf = tree as Leaf;

            if (leaf != null)
            {
                switch (leaf.op)
                {
                case RegOp.primitive:
                    DoSingleton(leaf.chVal);
                    break;

                case RegOp.litStr:
                    for (int index = 0; ;)
                    {
                        // Use CodePoint in case string has surrogate pairs.
                        int code = CharacterUtilities.CodePoint(leaf.str, ref index);
                        if (code == -1)
                        {
                            break;
                        }
                        else
                        {
                            DoSingleton(code);
                        }
                    }
                    break;

                case RegOp.charClass:
                    DoLiteral(leaf.rangeLit);
                    break;

                case RegOp.eof:     // no action required
                    break;

                default:
                    throw new GplexInternalException("Unknown RegOp");
                }
            }
            else if (tree.op == RegOp.rightAnchor)
            {
                DoLiteral(RangeLiteral.RightAnchors);
            }
        }
        /// <summary>
        /// This static method expands characters in a literal
        /// string, returning a modified string with character
        /// escapes replaced by the character which they denote.
        /// This includes characters outside the BMP which
        /// return a pair of surrogate characters.
        /// </summary>
        /// <param name="str">the input string</param>
        /// <returns>interpreted version of the string</returns>
        public static string InterpretCharacterEscapes(string source)
        {
            int sLen = source.Length;

            if (sLen == 0)
            {
                return(source);
            }
            char[] arr  = new char[sLen];
            int    sNxt = 0;
            int    aNxt = 0;
            char   chr  = source[sNxt++];

            for (; ; chr = source[sNxt++])
            {
                if (chr != '\\')
                {
                    arr[aNxt++] = chr;
                }
                else
                {
                    int codePoint = EscapedChar(source, ref sNxt);
                    if (codePoint > 0xFFFF)
                    {
                        arr[aNxt++] = CharacterUtilities.HiSurrogate(codePoint);
                        arr[aNxt++] = CharacterUtilities.LoSurrogate(codePoint);
                    }
                    else
                    {
                        arr[aNxt++] = (char)codePoint;
                    }
                }
                if (sNxt == sLen)
                {
                    return(new String(arr, 0, aNxt));
                }
            }
        }