Пример #1
0
 private void AssertExpected(AllowedToken match)
 {
     if ((_expected & match) == 0)
     {
         ParseException("Expected a " + string.Join(", ", Definition(_expected).ToArray())
                        + ", but found a "
                        + string.Join(", ", Definition(match).ToArray()));
     }
 }
Пример #2
0
        private static IEnumerable <string> Definition(AllowedToken match)
        {
            var parts = new List <string>();

            if ((match & AllowedToken.Array) != 0)
            {
                parts.Add("`[`");
            }
            if ((match & AllowedToken.Boolean) != 0)
            {
                parts.Add("boolean");
            }
            if ((match & AllowedToken.Colon) != 0)
            {
                parts.Add("`:`");
            }
            if ((match & AllowedToken.Comma) != 0)
            {
                parts.Add("`,`");
            }
            if ((match & AllowedToken.EndObject) != 0)
            {
                parts.Add("`}`");
            }
            if ((match & AllowedToken.EndArray) != 0)
            {
                parts.Add("`]`");
            }
            if ((match & AllowedToken.Null) != 0)
            {
                parts.Add("`null`");
            }
            if ((match & AllowedToken.Number) != 0)
            {
                parts.Add("number");
            }
            if ((match & AllowedToken.Object) != 0)
            {
                parts.Add("`{`");
            }
            if ((match & AllowedToken.Property) != 0)
            {
                parts.Add("property name");
            }
            if ((match & AllowedToken.String) != 0)
            {
                parts.Add("string");
            }

            return(parts);
        }
Пример #3
0
        public bool Read()
        {
            SkipWhitespace();

            var next = Peek();

            if (next == ':' && (_expected & AllowedToken.Colon) != 0)
            {
                ReadChar();
                _expected = AllowedToken.Value;
                SkipWhitespace();
                next = Peek();
            }
            else if (next == ',' && (_expected & AllowedToken.Comma) != 0 && _groups.Count > 0)
            {
                ReadChar();
                _expected = _groups.Peek() == JsonToken.StartObject ? AllowedToken.Property : AllowedToken.Value;
                SkipWhitespace();
                next = Peek();
            }

            switch (next)
            {
            case '{':
                AssertExpected(AllowedToken.Object);
                _expected = AllowedToken.Property | AllowedToken.EndObject;
                TokenType = JsonToken.StartObject;
                Value     = null;
                ReadChar();
                _groups.Push(TokenType);
                return(true);

            case '[':
                AssertExpected(AllowedToken.Array);
                _expected = AllowedToken.Value | AllowedToken.EndArray;
                TokenType = JsonToken.StartArray;
                Value     = null;
                ReadChar();
                _groups.Push(TokenType);
                return(true);

            case '}':
                if (_groups.Count < 1)
                {
                    ParseException($"Too many closing `{next}`");
                }
                var open = _groups.Pop();
                if (open != JsonToken.StartObject)
                {
                    ParseException($"Closing character `{next}` does not match the last opening character `{Definition(open)}`");
                }

                AssertExpected(AllowedToken.EndObject);
                _expected = AllowedToken.EndValue;
                TokenType = JsonToken.EndObject;
                Value     = null;
                ReadChar();
                return(true);

            case ']':
                if (_groups.Count < 1)
                {
                    ParseException($"Too many closing `{next}`");
                }
                var open2 = _groups.Pop();
                if (open2 != JsonToken.StartArray)
                {
                    ParseException($"Closing character `{next}` does not match the last opening character `{Definition(open2)}`");
                }

                AssertExpected(AllowedToken.EndArray);
                _expected = AllowedToken.EndValue;
                TokenType = JsonToken.EndArray;
                Value     = null;
                ReadChar();
                return(true);

            case '"':
                AssertExpected(AllowedToken.Property | AllowedToken.String);
                Value = ReadString();
                if ((_expected & AllowedToken.Property) != 0)
                {
                    TokenType = JsonToken.PropertyName;
                    _expected = AllowedToken.Colon;
                }
                else
                {
                    TokenType = JsonToken.String;
                    _expected = AllowedToken.EndValue;
                }
                return(true);

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case '-':
                AssertExpected(AllowedToken.Number);
                _expected = AllowedToken.EndValue;
                TokenType = JsonToken.Number;
                Value     = ReadNumber();
                return(true);

            case 't':
            case 'f':
                AssertExpected(AllowedToken.Boolean);
                _expected = AllowedToken.EndValue;
                TokenType = JsonToken.Boolean;
                Value     = ReadBoolean();
                return(true);

            case 'n':
                AssertExpected(AllowedToken.Null);
                _expected = AllowedToken.EndValue;
                TokenType = JsonToken.Null;
                Value     = ReadNull();
                return(true);

            case '\0':
                if (_groups.Count > 0)
                {
                    ParseException($"The last group `{Definition(_groups.Peek())}` is not closed");
                }
                TokenType = JsonToken.None;
                Value     = null;
                return(false);

            default:
                ParseException();
                return(false);
            }
        }