public JsonToken ReadToken() { if (BackToken.Count > 0) return BackToken.Pop(); TokenType tokenType = TokenType.Unidentified; string token = string.Empty; bool endToken = false; while(!endToken) { int read = _textReader.Read(); if (read == -1) break; switch ((char)read) { case '\t': case '\r': case '\n': case ' ': if (token != string.Empty) endToken = true; break; case ',': case ':': case '{': case '}': case '[': case ']': var nextToken = new JsonToken(TokenType.SpecialChar, ((char)read).ToString()); if (token != string.Empty) { endToken = true; BackToken.Push(nextToken); break; } return nextToken; case '\"': if (token != string.Empty) throw new LexicalException("Unexpected char '\"' while reading \"" + token + "\""); while(true) { int tokenChar = _textReader.Read(); if (tokenChar == -1) break; if (tokenChar != '\"') { if (tokenChar != '\\') token += (char)tokenChar; else { tokenChar = _textReader.Read(); if (tokenChar == -1) break; switch (tokenChar) { case 'b': token += "\b"; break; case 'f': token += "\f"; break; case 'n': token += "\n"; break; case 'r': token += "\r"; break; case 't': token += "\t"; break; case 'v': token += "\v"; break; case '\"': token += "\""; break; case '\\': token += "\\"; break; case '/': token += "/"; break; case 'u': var code = new StringBuilder(); for(int i = 0; i < 4; i++) { tokenChar = _textReader.Read(); if (tokenChar == -1) break; code.Append((char)tokenChar); } if(code.Length < 4) break; token += (char)int.Parse(code.ToString(), NumberStyles.HexNumber); break; default: throw new LexicalException("Bad escape sequence: \'\\" + tokenChar + "\'"); } } } else { return new JsonToken(TokenType.String, token); } } throw new LexicalException("End quote not found"); default: if (token == string.Empty) { if (char.IsNumber((char)read) || read == '+' || read == '-') tokenType = TokenType.Number; } else if (tokenType == TokenType.Number && !char.IsNumber((char)read) && (read != '.' || token.Contains("."))) tokenType = TokenType.String; token += (char)read; break; } } if (tokenType == TokenType.Unidentified) { switch (token) { case "true": case "false": case "null": tokenType = TokenType.KeyWord; break; default: tokenType = TokenType.String; break; } } return new JsonToken(tokenType, token); }
public void PutBack(JsonToken token) { BackToken.Push(token); }