Example #1
0
        IKDLValue ParseValue(KDLParseContext context) // throws IOException
        {
            int c = context.Peek();

            if (c == '"')
            {
                return(new KDLString(ParseEscapedString(context)));
            }
            else if (c == 'r')
            {
                return(new KDLString(ParseRawString(context)));
            }
            else if (IsValidNumericStart(c))
            {
                return(ParseNumber(context));
            }
            else
            {
                var stringBuilder = new StringBuilder();

                while (IsLiteralChar(c))
                {
                    context.Read();
                    stringBuilder.AppendCodePoint(c);
                    c = context.Peek();
                }

                var strVal = stringBuilder.ToString();
                return(strVal switch {
                    "true" => KDLBoolean.True,
                    "false" => KDLBoolean.False,
                    "null" => KDLNull.Instance,
                    _ => throw new KDLParseException(string.Format("Unknown literal in property value: '{0}' Expected 'true', 'false', or 'null'", strVal))
                });
Example #2
0
        KDLDocument ParseChild(KDLParseContext context) // throws IOException
        {
            int c = context.Read();

            if (c != '{')
            {
                throw new KDLInternalException(string.Format("Expected '{' but found '%s'", (char)c));
            }

            var document = ParseDocument(context, false);

            switch (ConsumeWhitespaceAndLinespace(context))
            {
            case WhitespaceResult.EndNode:
                throw new KDLInternalException("Got unexpected END_NODE");

            case WhitespaceResult.SkipNext:
                throw new KDLParseException("Trailing skip markers are not allowed");
                // default:
                //Fall through
            }

            c = context.Read();
            if (c != '}')
            {
                throw new KDLParseException("No closing brace found for child");
            }

            return(document);
        }
Example #3
0
        string ParseIdentifier(KDLParseContext context) // throws IOException
        {
            int c = context.Peek();

            if (c == '"')
            {
                return(ParseEscapedString(context));
            }
            else if (IsValidBareIdStart(c))
            {
                if (c == 'r')
                {
                    context.Read();
                    int next = context.Peek();
                    context.Unread('r');
                    if (next == '"' || next == '#')
                    {
                        return(ParseRawString(context));
                    }
                    else
                    {
                        return(ParseBareIdentifier(context));
                    }
                }
                else
                {
                    return(ParseBareIdentifier(context));
                }
            }
            else
            {
                throw new KDLParseException(string.Format("Expected an identifier, but identifiers can't start with '{0}'", (char)c));
            }
        }
Example #4
0
        private KDLDocument ParseDocument(KDLParseContext context, bool root)
        {
            var c = context.Peek();

            if (c == EOF)
            {
                return(new KDLDocument(new List <KDLNode>(0)));
            }

            var nodes = new List <KDLNode>();

            while (true)
            {
                bool skippingNode = false;
                switch (ConsumeWhitespaceAndLinespace(context))
                {
                case WhitespaceResult.NodeSpace:
                case WhitespaceResult.NoWhitespace:
                    break;

                case WhitespaceResult.EndNode:
                    c = context.Peek();
                    if (c == EOF)
                    {
                        break;
                    }
                    else
                    {
                        continue;
                    }

                case WhitespaceResult.SkipNext:
                    skippingNode = true;
                    break;
                }

                c = context.Peek();
                if (c == EOF)
                {
                    if (root)
                    {
                        return(new KDLDocument(nodes));
                    }
                    else
                    {
                        throw new KDLParseException("Got EOF, expected a node or '}'");
                    }
                }
                else if (c == '}')
                {
                    if (root)
                    {
                        throw new KDLParseException("Unexpected '}' in root document");
                    }
                    else
                    {
                        return(new KDLDocument(nodes));
                    }
                }

                var node = ParseNode(context);
                ConsumeAfterNode(context);
                if (!skippingNode && node != null)
                {
                    nodes.Add(node);
                }
            }
        }
Example #5
0
        public KDLDocument Parse(StreamReader reader)
        {
            var context = new KDLParseContext(reader);

            return(ParseDocument(context, true));
        }
Example #6
0
        IKDLObject ParseArgOrProp(KDLParseContext context) // throws IOException
        {
            IKDLObject obj;
            bool       isBare = false;
            int        c      = context.Peek();

            if (c == '"')
            {
                obj = new KDLString(ParseEscapedString(context));
            }
            else if (IsValidNumericStart(c))
            {
                obj = ParseNumber(context);
            }
            else if (IsValidBareIdStart(c))
            {
                string strVal;
                if (c == 'r')
                {
                    context.Read();
                    int next = context.Peek();
                    context.Unread('r');
                    if (next == '"' || next == '#')
                    {
                        strVal = ParseRawString(context);
                    }
                    else
                    {
                        isBare = true;
                        strVal = ParseBareIdentifier(context);
                    }
                }
                else
                {
                    isBare = true;
                    strVal = ParseBareIdentifier(context);
                }

                if (isBare)
                {
                    if ("true" == strVal)
                    {
                        obj = KDLBoolean.True;
                    }
                    else if ("false" == strVal)
                    {
                        obj = KDLBoolean.False;
                    }
                    else if ("null" == strVal)
                    {
                        obj = KDLNull.Instance;
                    }
                    else
                    {
                        obj = new KDLString(strVal);
                    }
                }
                else
                {
                    obj = new KDLString(strVal);
                }
            }
            else
            {
                throw new KDLParseException(string.Format("Unexpected character: '{0}'", (char)c));
            }

            if (obj is KDLString kdlString)
            {
                c = context.Peek();
                if (c == '=')
                {
                    context.Read();
                    var value = ParseValue(context);
                    return(new KDLProperty(kdlString.Value, value));
                }
                else if (isBare)
                {
                    throw new KDLParseException("Arguments may not be bare");
                }
                else
                {
                    return(obj);
                }
            }
            else
            {
                return(obj);
            }
        }
Example #7
0
        KDLNode?ParseNode(KDLParseContext context)  // throws IOException
        {
            var         args       = new List <IKDLValue>();
            var         properties = new Dictionary <string, IKDLValue>();
            KDLDocument?child      = null;

            int c = context.Peek();

            if (c == '}')
            {
                return(null);
            }

            var identifier = ParseIdentifier(context);

            while (true)
            {
                var whitespaceResult = ConsumeWhitespaceAndBlockComments(context);
                c = context.Peek();
                switch (whitespaceResult)
                {
                case WhitespaceResult.NodeSpace:
                    if (c == '{')
                    {
                        child = ParseChild(context);
                        return(new KDLNode(identifier, properties, args, child));
                    }
                    else if (IsUnicodeLinespace(c))
                    {
                        return(new KDLNode(identifier, properties, args, child));
                    }
                    if (c == EOF)
                    {
                        return(new KDLNode(identifier, properties, args, child));
                    }
                    else
                    {
                        var obj = ParseArgOrProp(context);
                        if (obj is IKDLValue kdlValue)
                        {
                            args.Add(kdlValue);
                        }
                        else if (obj is KDLProperty kdlProp)
                        {
                            properties[kdlProp.Key] = kdlProp.Value;
                        }
                        else
                        {
                            throw new KDLInternalException(
                                      string.Format("Unexpected type found, expected property, arg, or child: '{0}' type: {1}",
                                                    obj.ToKDL(), obj.GetType().ToString()));
                        }
                    }
                    break;

                case WhitespaceResult.NoWhitespace:
                    if (c == '{')
                    {
                        child = ParseChild(context);
                        return(new KDLNode(identifier, properties, args, child));
                    }
                    else if (IsUnicodeLinespace(c) || c == EOF)
                    {
                        return(new KDLNode(identifier, properties, args, child));
                    }
                    else if (c == ';')
                    {
                        context.Read();
                        return(new KDLNode(identifier, properties, args, child));
                    }
                    else
                    {
                        throw new KDLParseException($"Unexpected character: '{(char)c}'");
                    }

                case WhitespaceResult.EndNode:
                    return(new KDLNode(identifier, properties, args, child));

                case WhitespaceResult.SkipNext:
                    if (c == '{')
                    {
                        ParseChild(context);     //Ignored
                        return(new KDLNode(identifier, properties, args, child));
                    }
                    else if (IsUnicodeLinespace(c))
                    {
                        throw new KDLParseException("Unexpected skip marker before newline");
                    }
                    else if (c == EOF)
                    {
                        throw new KDLParseException("Unexpected EOF following skip marker");
                    }
                    else
                    {
                        var obj = ParseArgOrProp(context);
                        if (!(obj is IKDLValue) && !(obj is KDLProperty))
                        {
                            throw new KDLInternalException(
                                      string.Format("Unexpected type found, expected property, arg, or child: '{0}' type: {1}",
                                                    obj.ToKDL(), obj.GetType()));
                        }
                    }
                    break;
                }
            }
        }