コード例 #1
0
        /// <summary>
        /// Escape characters inside a text literal
        /// </summary>
        private string PELEscape(TextPortion SourcePosition, char EscapeChar)
        {
            StringBuilder sb = new StringBuilder(SourcePosition.Length);

            //Last position in the string
            var old_pos = SourcePosition.Begin;
            //Caret for finding \
            var crt = new Caret();
            crt.Source = SourcePosition.Text;
            string esc_char = EscapeChar.ToString(), esc_chars = esc_char + esc_char;

            for (var pos = SourcePosition.Text.IndexOf('\\', SourcePosition.Begin, SourcePosition.Length); pos >= 0; pos = SourcePosition.Text.IndexOf('\\', pos, SourcePosition.End - pos))
            {
                //Append in-between text
                if (pos != old_pos)
                    sb.Append(SourcePosition.Text.Substring(old_pos, pos - old_pos).Replace(esc_chars, esc_char));

                if (pos == SourcePosition.End)
                {
                    ThrowParseError("Expected a character to escape", new TextPortion(pos, 1));
                    break;
                }

                pos++;

                //End of file
                if (pos >= SourcePosition.End)
                    break;

                switch (SourcePosition.Text[pos])
                {
                case '\\':
                    sb.Append('\\');
                    pos++;
                    break;
                case 'r':
                case 'R':
                    sb.Append('\r');
                    pos++;
                    break;
                case 'n':
                case 'N':
                    sb.Append('\n');
                    pos++;
                    break;
                case 't':
                case 'T':
                    sb.Append('\t');
                    pos++;
                    break;
                case 'x':
                case 'X':
                    pos++;
                    crt.Position = pos;
                    if (!crt.Match(@"(?<cap>([0-9a-fA-F]{2})+)\\"))
                        ThrowParseError(
                            "Expected one or more consecutive 2-digit hexadecimal values, followed by a \\ (eg \\x2A\\, or \\x02A5F2\\)",
                            new TextPortion(pos, 1));
                    else
                    {
                        var cap = crt.LastMatch.Groups["cap"].Value;

                        for (int i = 0; i < cap.Length; i += 2)
                            sb.Append((char) Int16.Parse(cap.Substring(i, 2), NumberStyles.HexNumber));

                        pos = crt.Position;
                    }
                    break;
                case 'u':
                case 'U':
                    pos++;
                    crt.Position = pos;
                    if (!crt.Match(@"(?<cap>([0-9a-fA-F]{4})+)\\"))
                        ThrowParseError(
                            "Expected one or more consecutive 4-digit hexadecimal values, followed by a \\ (eg \\u002A\\, or \\u000200A510F2\\)",
                            new TextPortion(pos, 1));
                    else
                    {
                        var cap = crt.LastMatch.Groups["cap"].Value;

                        for (int i = 0; i < cap.Length; i += 4)
                            sb.Append((char) Int16.Parse(cap.Substring(i, 4), NumberStyles.HexNumber));

                        pos = crt.Position;
                    }
                    break;
                default:
                    ThrowParseError("Unexpected escape character", new TextPortion(pos, 1));
                    break;
                }

                old_pos = pos;
            }

            //Append remaining text
            if (old_pos != SourcePosition.End)
                sb.Append(SourcePosition.Text, old_pos, SourcePosition.End - old_pos);

            return sb.ToString();
        }