/// <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); }