public void ScanBadEscapedUnicode() { var jsonList = new List<string> { @"""\u005X""", @"""\u00X5""", @"""\u0X05""", @"""\uX005""", @"""\u500""", @"""\u05""", @"""\u5""", @"""\u""" }; jsonList.Each(json => { using (var lex = new JsonLexicalAnalyzer(json)) { Assert.That(JsonLexicalType.Error == lex.Scan()); } }); }
public void CanScanGoogleTranslation() { var json = @"{""responseData"": {""translatedText"":""誰ですか?""}, ""responseDetails"": null, ""responseStatus"": 200}"; using (var lex = new JsonLexicalAnalyzer(json)) { JsonLexicalType lexType; while ((lexType = lex.Scan()) != JsonLexicalType.EndOfJson && lexType != JsonLexicalType.Error) { if (lexType == JsonLexicalType.Number) Log.Info("{0} {1}", lexType, lex.CurrentDouble); else if (lexType == JsonLexicalType.String) Log.Info("{0} {1}", lexType, lex.CurrentString); else Log.Info("{0}", lexType); } if (lexType == JsonLexicalType.Error) { Log.Info("Error at position: {0}", lex.Index); Assert.Fail(); } } }
public void ScanDoubleWithExponent() { var json = @"-1.063E-02"; using (var lex = new JsonLexicalAnalyzer(json)) { var lexType = lex.Scan(); Assert.That(JsonLexicalType.Number == lexType); Assert.That(-0.01063 == lex.CurrentDouble); } }
public void ScanIntegerWithExponent() { var json = @"1043E+04"; using (var lex = new JsonLexicalAnalyzer(json)) { var lexType = lex.Scan(); Assert.That(JsonLexicalType.Number == lexType); Assert.That(10430000L == lex.CurrentInt64); } }
public void ScanEscapedUnicode() { var json = @"""\u005C"""; using (var lex = new JsonLexicalAnalyzer(json)) { var lexType = lex.Scan(); Assert.That(JsonLexicalType.String == lexType); Assert.That(lex.CurrentString == @"\"); } }
private static void Shift(Stack<int> shiftReduceStack, JsonLexicalAnalyzer lex, JsonLexicalType currentLexeme, ShiftReduce shiftReduce, Stack<IJsonValue> inputStack) { shiftReduceStack.Push((int)currentLexeme); shiftReduceStack.Push(shiftReduce.Action); //if (Log.IsDebugEnabled) // Log.Debug("Shift {0} s{1}", currentLexeme, shiftReduce.Action); switch (currentLexeme) { case JsonLexicalType.Number: if (lex.CurrentDouble.HasValue) inputStack.Push(new JsonNumber(lex.CurrentDouble.Value)); else if (lex.CurrentInt64.HasValue) inputStack.Push(new JsonNumber(lex.CurrentInt64.Value)); break; case JsonLexicalType.String: inputStack.Push(new JsonString(lex.CurrentString)); break; case JsonLexicalType.True: inputStack.Push(new JsonBoolean(true)); break; case JsonLexicalType.False: inputStack.Push(new JsonBoolean(false)); break; case JsonLexicalType.Null: inputStack.Push(Singleton<JsonNull>.Instance); break; default: break; } }
private static void LogAndThrowJsonError(JsonLexicalAnalyzer lex, string json, bool isParseError) { var parseAnalysisError = isParseError ? "parsing" : "analyzing"; var errorMessage = string.Format("Error {3} JSON at line number {1} character {2}: {0}", json, lex.LineNumber, lex.Index, parseAnalysisError); if (Log.IsErrorEnabled) Log.Error(errorMessage); throw new JsonException(errorMessage); }
/// <summary> /// Parses a JSON string to create an IJsonValue representation of the JSON /// </summary> /// <param name="json">JSON string to parse</param> /// <returns>IJsonValue representation of the JSON</returns> public static IJsonValue Parse(string json) { if (string.IsNullOrEmpty(json)) { if (Log.IsErrorEnabled) Log.Error("Attempt to parse null or empty JSON string"); throw new JsonException("Attempt to parse null or empty JSON string"); } using (var lex = new JsonLexicalAnalyzer(json)) { return ShiftReduceParse(json, lex); } }
private static IJsonValue ShiftReduceParse(string json, JsonLexicalAnalyzer lex) { var inputStack = new Stack<IJsonValue>(); var parseStack = new Stack<ParseItem>(); var shiftReduceStack = new Stack<int>(); shiftReduceStack.Push(0); var currentLexeme = lex.Scan(); var done = false; while (!done) { if (currentLexeme == JsonLexicalType.Error) LogAndThrowJsonError(lex, json, false); var topOfStack = shiftReduceStack.Peek(); var shiftReduceAction = ActionGotoTable[topOfStack, (int)currentLexeme]; switch (shiftReduceAction.Type) { case ShiftReduceType.Shift: Shift(shiftReduceStack, lex, currentLexeme, shiftReduceAction, inputStack); currentLexeme = lex.Scan(); break; case ShiftReduceType.Reduce: Reduce(shiftReduceStack, shiftReduceAction, inputStack, parseStack); break; case ShiftReduceType.Accept: if (Log.IsDebugEnabled) Log.Debug("JSON Parser Accept State"); done = true; break; default: LogAndThrowJsonError(lex, json, true); break; } } // ParseRoot should always be left on the parseStack at this point (otherwise an error would have already occured) return parseStack.Pop().ToJsonValue(); }