internal void Run() { var next = charReader.Read(); while (next != '\0') { var encoded = Encode(next); charWriter.Write(encoded); next = charReader.Read(); } }
private char?GetUnicodeSymbol(ICharReader charReader) { var sb = new StringBuilder(8); for (var i = 0; i < 4; i++) { var c = charReader.Read(); if (!c.HasValue) { throw new JsonException("Unterminated string"); } if (char.IsDigit(c.Value) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { sb.Append(c.Value); } else { throw new JsonException($"Invalid character '{c.Value}' in hexidecimal unicode notation"); } } var hexString = sb.ToString(); var sChar = (ushort)(Convert.ToUInt16(hexString.Substring(0, 2), 16) << 8); sChar += Convert.ToUInt16(hexString.Substring(2, 2), 16); return(Convert.ToChar(sChar)); }
private JsonValue ParseObject(ICharReader charReader) { var members = new List <JsonObjectMember>(); if (!charReader.TrimRead('{')) { throw new JsonException("Expected '{' when parsing json object."); } var peek = charReader.TrimThenPeek(); if (!peek.HasValue) { throw new JsonException("Unterminated object"); } while (peek.Value != '}') { if (members.Any()) { if (!charReader.TrimRead(',')) { throw new JsonException("Missing comma separater between array items."); } } members.Add(ParseObjectMember(charReader)); peek = charReader.TrimThenPeek(); if (!peek.HasValue) { throw new JsonException("Unterminated object"); } } charReader.Read(); // } return(new JsonObject(members)); }
private static void AdvanceWhitespace(ICharReader charReader) { var peek = charReader.Peek(); while (peek.HasValue && char.IsWhiteSpace(peek.Value)) { charReader.Read(); peek = charReader.Peek(); } }
private JsonValue ParseNull(ICharReader charReader) { foreach (var c in _null) { if (c != charReader.Read()) { throw new JsonException($"Unexpected character '{c}' whilst parsing 'null'"); } } return(new JsonNull()); }
private JsonValue ParseFalse(ICharReader charReader) { foreach (var c in _false) { if (c != charReader.Read()) { throw new JsonException($"Unexpected character '{c}' whilst parsing 'false'"); } } return(new JsonFalse()); }
private char?GetNextStringCharacter(ICharReader charReader, char?delimiter) { var c = charReader.Read(); if (!c.HasValue) { throw new JsonException("Unterminated string"); } if (c == delimiter) { return(null); } if (CharRequiresEscapeInString(c.Value)) { throw new JsonException($"Unescaped '{c}' in string"); } if (c != '\\') { return(c); } c = charReader.Read(); if (!c.HasValue) { throw new JsonException("Unterminated string"); } char fromShortCode; if (ShortEscapeDecodables.TryGetValue(c.Value, out fromShortCode)) { return(fromShortCode); } if (c == 'u') { return(GetUnicodeSymbol(charReader)); } throw new JsonException($"Unrecognised escape sequence '\\{c}'"); }
private JsonValue ParseNumber(ICharReader charReader) { var sb = new StringBuilder(); var peek = charReader.Peek(); while (peek.HasValue && Numerics.Contains(peek.Value)) { sb.Append(charReader.Read()); peek = charReader.Peek(); } return(new JsonNumber(sb.ToString())); }
private JsonValue ParseArray(ICharReader charReader) { charReader.TrimRead(); // [ var items = new List <JsonValue>(); while (charReader.TrimThenPeek() != ']') { if (items.Any()) { if (!charReader.TrimRead(',')) { throw new JsonException("Missing comma separater between array items."); } } items.Add(ParseJsonValue(charReader)); } charReader.Read(); // ] return(new JsonArray(items)); }
public TokenMatch Read(ICharReader Reader) { char input; int? index; IState currentState; StringBuilder sb; IRule reductionRule; string lastGoodValue = null; long lastGoodPosition = 0; IRule lastGoodRule = null; TokenMatch result; if (Reader == null) { throw new ArgumentNullException("Reader"); } sb = new StringBuilder(); currentState = states[0]; while (true) { if (Reader.EOF) { if (lastGoodPosition != 0) { break; } throw new Exceptions.EndOfStreamException(Reader.Position); } else { input = Reader.Read(); index = currentState.GetNextStateIndex(input); } if (index == null) { if (lastGoodPosition != 0) { break; } throw new InvalidInputException(Reader.Position, input); } sb.Append(input); currentState = states[index.Value]; reductionRule = currentState.Reductions.FirstOrDefault(); if (reductionRule != null) { lastGoodPosition = Reader.Position; lastGoodRule = reductionRule; lastGoodValue = sb.ToString(); } } Reader.Seek(lastGoodPosition); result = new TokenMatch(); result.Success = true; result.Token = new Token(lastGoodRule.Name, lastGoodValue); result.Tags = lastGoodRule.Tags.ToArray(); return(result); }
public static bool TrimRead(this ICharReader charReader, char c) { AdvanceWhitespace(charReader); return(charReader.Read(c)); }
public static char?TrimRead(this ICharReader charReader) { AdvanceWhitespace(charReader); return(charReader.Read()); }
private Token ReadNew() { CommentMode comment = CommentMode.None; int readInt; Token tmpToken; while ((readInt = _source.Read()) >= 0) { // Handle comment mode if (comment == CommentMode.Line) { if (readInt == '\n' || readInt == '\r') { comment = CommentMode.None; } continue; } else if (comment == CommentMode.Block) { if (readInt == '*') { if ((readInt = _source.Read()) == '/') { comment = CommentMode.None; } else if (readInt >= 0) { _source.PushBack(readInt); } } continue; } // Skip whitespaces if (char.IsWhiteSpace((char)readInt)) { continue; } long position = _source.Position; switch (readInt) { case '+': switch (readInt = _source.Read()) { case '+': return(new Token(TokenType.OperatorIncrement, position)); case '=': return(new Token(TokenType.OperatorAssignPlus, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorPlus, position)); } case '-': switch (readInt = _source.Read()) { case '-': return(new Token(TokenType.OperatorDecrement, position)); case '=': return(new Token(TokenType.OperatorAssignMinus, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorMinus, position)); } case '*': switch (readInt = _source.Read()) { case '=': return(new Token(TokenType.OperatorAssignTimes, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorTimes, position)); } case '/': switch (readInt = _source.Read()) { case '=': return(new Token(TokenType.OperatorAssignDivide, position)); case '/': comment = CommentMode.Line; break; case '*': comment = CommentMode.Block; break; default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorDivide, position)); } break; case '%': switch (readInt = _source.Read()) { case '=': return(new Token(TokenType.OperatorAssignModulo, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorModulo, position)); } case '(': return(new Token(TokenType.BracketLeft, position)); case ')': return(new Token(TokenType.BracketRight, position)); case '[': return(new Token(TokenType.SquareBracketLeft, position)); case ']': return(new Token(TokenType.SquareBracketRight, position)); case '{': return(new Token(TokenType.CurlyBracketLeft, position)); case '}': return(new Token(TokenType.CurlyBracketRight, position)); case ';': return(new Token(TokenType.EndOfInstruction, position)); case ',': return(new Token(TokenType.Comma, position)); case '.': // It might be a floating point number (in fact, iff it is follows by a digit) int nextInt = _source.Read(); if (nextInt >= 0) { _source.PushBack(nextInt); if (char.IsDigit((char)nextInt)) { // Since the next character is a digit, ProcessNumber_Float() cannot return null return(ProcessNumber_Float(position, new StringBuilder(), readInt)); } } return(new Token(TokenType.Period, position)); case ':': switch (readInt = _source.Read()) { case ':': return(new Token(TokenType.DoubleColon, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.Colon, position)); } case '<': switch (readInt = _source.Read()) { case '<': if ((readInt = _source.Read()) == '=') { return(new Token(TokenType.OperatorAssignLeftShift, position)); } if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorLeftShift, position)); case '=': return(new Token(TokenType.OperatorLessThanEqual, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorLessThan, position)); } case '>': switch (readInt = _source.Read()) { case '>': if ((readInt = _source.Read()) == '=') { return(new Token(TokenType.OperatorAssignRightShift, position)); } if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorRightShift, position)); case '=': return(new Token(TokenType.OperatorMoreThanEqual, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorMoreThan, position)); } case '!': switch (readInt = _source.Read()) { case '=': return(new Token(TokenType.OperatorNotEqual, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorLogicalNot, position)); } case '~': return(new Token(TokenType.OperatorBitwiseNot, position)); case '&': switch (readInt = _source.Read()) { case '&': return(new Token(TokenType.OperatorLogicalAnd, position)); case '=': return(new Token(TokenType.OperatorAssignBitwiseAnd, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorBitwiseAnd, position)); } case '|': switch (readInt = _source.Read()) { case '|': return(new Token(TokenType.OperatorLogicalOr, position)); case '=': return(new Token(TokenType.OperatorAssignBitwiseOr, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorBitwiseOr, position)); } case '^': switch (readInt = _source.Read()) { case '=': return(new Token(TokenType.OperatorAssignBitwiseXor, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorBitwiseXor, position)); } case '=': switch (readInt = _source.Read()) { case '=': return(new Token(TokenType.OperatorEqual, position)); default: if (readInt >= 0) { _source.PushBack(readInt); } return(new Token(TokenType.OperatorAssign, position)); } case '\'': switch (readInt = _source.Read()) { case '\'': throw new SyntaxException(_source.Position, "Empty character"); case '\\': switch (readInt = _source.Read()) { case '0': readInt = 0; break; case '\'': break; case '\\': break; case 'n': readInt = '\n'; break; case 'r': readInt = '\r'; break; case 't': readInt = '\t'; break; default: throw new SyntaxException(_source.Position, "Unrecognized escape sequence"); } break; } if (_source.Read() != '\'') { throw new SyntaxException(_source.Position, "Too many characters"); } return(new ValuedToken <string>(TokenType.DecInt, position, readInt.ToString())); default: if ((tmpToken = ProcessNumber(readInt)) != null) { return(tmpToken); } if ((tmpToken = ProcessName(readInt)) != null) { return(tmpToken); } if ((tmpToken = ProcessString(readInt)) != null) { return(tmpToken); } throw new SyntaxException(_source.Position, "Unrecognized character: " + (char)readInt); } } // We reached the end return(new Token(TokenType.EndOfDocument, _source.Position + 1)); }