/// <summary>
        /// 予約語(<c>true</c>, <c>false</c>, <c>null</c>)をパースします。<see cref="Parse(JsonScanner)" />で使用されます。
        /// </summary>
        /// <param name="scanner">指定するスキャナ。</param>
        /// <returns>予約語をそのまま返します。</returns>
        private static object ParseWord(JsonScanner scanner)
        {
            if (scanner.Check(IsSmallT))
            {
                if (!scanner.CheckAdvance("true"))
                {
                    throw new ArgumentMapParseException("word -> true required", scanner.Itext.PositionInfo);
                }

                return(true);
            }

            if (scanner.Check(IsSmallF))
            {
                if (!scanner.CheckAdvance("false"))
                {
                    throw new ArgumentMapParseException("word -> false required", scanner.Itext.PositionInfo);
                }

                return(false);
            }

            if (!scanner.Check(IsSmallN))
            {
                throw new ArgumentMapParseException("word -> unexpected character", scanner.Itext.PositionInfo);
            }
            if (!scanner.CheckAdvance("null"))
            {
                throw new ArgumentMapParseException("word -> null required", scanner.Itext.PositionInfo);
            }

            return(null);
        }
        /// <summary>
        /// 今までのパース引数を構文解析と共にまとめます。
        /// </summary>
        /// <param name="scanner">指定するスキャナ。</param>
        /// <returns>objectとして<see cref="Parse(JsonScanner)" />に渡します。</returns>
        private static object ParseValue(JsonScanner scanner)
        {
            ParseWhitespace(scanner);

            return(scanner.Check(IsLeftBrace) ? ParseObject(scanner) :
                   scanner.Check(IsLeftBracket) ? ParseArray(scanner) :
                   scanner.Check(IsDoubleQuote) ? ParseString(scanner) :
                   scanner.Check(IsSign) ? ParseNumber(scanner) :
                   scanner.Check(IsDigit) ? ParseNumber(scanner) : ParseWord(scanner));
        }
        /// <summary>
        /// Json文字列をパースします。これは<see cref="Parse(JsonScanner)"/>の一部で使用されます。
        /// </summary>
        /// <param name="scanner">指定するスキャナ。</param>
        /// <returns>パースに成功した場合文字列をさらに返します。</returns>
        private static string ParseString(JsonScanner scanner)
        {
            const string b = "\b";
            const string f = "\f";
            const string n = "\n";
            const string r = "\r";
            const string t = "\t";

            scanner.Empty();

            if (!scanner.CheckAdvance(IsDoubleQuote))
            {
                throw new ArgumentMapParseException("string -> double quotation mark required", scanner.Itext.PositionInfo);
            }

            while (!scanner.CheckAdvance(IsDoubleQuote))
            {
                if (scanner.CheckAdvance(IsBackslash))
                {
                    if (scanner.CheckAddAdvance(IsDoubleQuote))
                    {
                        continue;
                    }
                    if (scanner.CheckAddAdvance(IsBackslash))
                    {
                        continue;
                    }
                    if (scanner.CheckAddAdvance(IsSlash))
                    {
                        continue;
                    }
                    if (scanner.CheckAdvance(IsSmallB))
                    {
                        scanner.Add(b);
                    }
                    else if (scanner.CheckAdvance(IsSmallF))
                    {
                        scanner.Add(f);
                    }
                    else if (scanner.CheckAdvance(IsSmallN))
                    {
                        scanner.Add(n);
                    }
                    else if (scanner.CheckAdvance(IsSmallR))
                    {
                        scanner.Add(r);
                    }
                    else if (scanner.CheckAdvance(IsSmallT))
                    {
                        scanner.Add(t);
                    }
                    else if (scanner.CheckAdvance(IsSmallU))
                    {
                        var codepoint = 0;

                        for (var i = 0; i < 4; i++)
                        {
                            try
                            {
                                codepoint = codepoint * 16 + scanner.Current.ToHexValue();

                                scanner.Advance();
                            }
                            catch (Exception)
                            {
                                break;
                            }
                        }

                        scanner.Add(Convert.ToChar(codepoint).ToString());
                    }
                    else
                    {
                        throw new ArgumentMapParseException("string -> not supported escape", scanner.Itext.PositionInfo);
                    }
                }
                else if (scanner.Check(IsControl))
                {
                    throw new ArgumentMapParseException("string -> control character", scanner.Itext.PositionInfo);
                }
                else
                {
                    scanner.AddAdvance();
                }
            }

            return(scanner.Scan);
        }