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