Ejemplo n.º 1
0
        private void _parser_main(YamlFileData file)
        {
            Output                = new ParserArray(file.LineNumber);
            Output.Indent         = -1;
            Output.ChildrenIndent = -1;

            _readNode(file, Output, 0, YamlListType.NotDefined);

            if (Output.ParserType == ParserTypes.Array)
            {
                var parserArray = Output.To <ParserArray>();

                // Copy pate handling
                if (parserArray.Objects.Count > 0 && parserArray.Objects[0].ParserType == ParserTypes.Array)
                {
                    var tmp_list     = new ParserList(0);
                    var tmp_keyValue = new ParserKeyValue("copy_paste", 0);

                    tmp_list.Objects.AddRange(parserArray.Objects);
                    tmp_keyValue.Value = tmp_list;
                    parserArray.Objects.Clear();
                    parserArray.Objects.Add(tmp_keyValue);
                }
            }

            // Calculate lengths
            if (Output != null)
            {
                _calculateLength(Output);
                Output.Length = _getLength(Output);
            }
        }
Ejemplo n.º 2
0
        private void _readNode(YamlFileData file, ParserObject parent, int indent, YamlListType listType)
        {
            string word_s = null;

            while (file.CanRead)
            {
                char c = file.PeekChar();

                switch (c)
                {
                case '#':
                    file.SkipLine();
                    continue;

                case '\r':                              // Ignore character
                    file.Position++;
                    continue;

                case '\n':
                    file.Position++;
                    file.NextLine();
                    continue;

                case '-':
                    file.SetupParent(parent, indent);

                    if (listType == YamlListType.NotDefined)
                    {
                        listType = YamlListType.Array;
                    }

                    // Validate parent indent
                    switch (parent.ParserType)
                    {
                    case ParserTypes.List:
                    case ParserTypes.Array:
                        if (file.CurrentLineIndent < parent.ChildrenIndent)
                        {
                            return;
                        }

                        if (file.CurrentLineIndent > parent.ChildrenIndent)
                        {
                            throw file.GetException("Unexpected indent (parent indent: " + parent.Indent + ", parent child indent: " + parent.ChildrenIndent + ", current indent: " + file.CurrentLineIndent + ").");
                        }

                        break;
                    }

                    if (!(file.Position + 2 < file.Length && file.Data[file.Position + 1] == ' ' && file.IsLetter((char)file.Data[file.Position + 2])))
                    {
                        throw file.GetException("Expected a space after the hyphen for the list declaration.");
                    }

                    // Array declaration
                    ParserArray array = new ParserArray(file.LineNumber);
                    array.Indent            = file.CurrentLineIndent;
                    file.CurrentLineIndent += 2;
                    array.ChildrenIndent    = file.CurrentLineIndent;
                    file.Position          += 2;

                    _readNode(file, array, file.CurrentLineIndent, YamlListType.NotDefined);

                    switch (parent.ParserType)
                    {
                    case ParserTypes.List:
                        ((ParserList)parent).AddElement(array);
                        break;

                    case ParserTypes.Array:                                     // Used for copy pasting only
                        ((ParserArray)parent).AddElement(array);
                        break;

                    default:
                        throw file.GetException("Unexpected parent node type. It can either be a list or an array, found a '" + parent.ParserType + "'.");
                    }

                    continue;

                case ' ':
                    file.CurrentLineIndent++;
                    file.Position++;
                    continue;

                case ':':
                    if (string.IsNullOrEmpty(word_s))
                    {
                        throw file.GetException("Missing declaration key before ':'.");
                    }

                    file.Position++;
                    file.Trim();

                    ParserKeyValue keyValue = new ParserKeyValue(word_s, file.LineNumber);
                    keyValue.Indent = parent.Indent;
                    word_s          = null;

                    // List declaration
                    if (file.EoL())
                    {
                        ParserList list = new ParserList(file.LineNumber);
                        list.Indent         = -1;
                        list.ChildrenIndent = -1;
                        keyValue.Value      = list;

                        _readNode(file, list, file.CurrentLineIndent, YamlListType.NotDefined);
                    }
                    else if (file.Data[file.Position] == '[')                               // Aggregate parsing, does not support multi-line
                    {
                        file.Position++;
                        ParserAggregate aggregate = new ParserAggregate(file.LineNumber);
                        aggregate.Parent = parent;

                        while (file.CanRead)
                        {
                            c = file.PeekChar();

                            if (c == '\r' || c == '\n')
                            {
                                throw file.GetException("Unexpected syntax; multi-line aggregate arrays are not supported.");
                            }

                            if (c == ']')
                            {
                                break;
                            }

                            word_s = c == '\"' ? file.ReadValue() : file.ReadWord();
                            aggregate.AddElement(new ParserString(word_s.Trim(' '), file.LineNumber));
                            c = file.PeekChar();

                            while (c != '\n' && (c == ',' || c == ' ' || c == '\r'))
                            {
                                file.Position++;
                                c = file.PeekChar();
                            }
                        }

                        word_s         = null;
                        keyValue.Value = aggregate;
                    }
                    else                                // KeyValue, get the line number first!
                    {
                        var parserString = new ParserString(null, file.LineNumber);
                        parserString.Value  = file.ReadValue();
                        parserString.Length = file.ValueLength;
                        keyValue.Value      = parserString;
                    }

                    switch (parent.ParserType)
                    {
                    case ParserTypes.List:
                        ((ParserList)parent).AddElement(keyValue);
                        break;

                    case ParserTypes.Array:
                        ((ParserArray)parent).AddElement(keyValue);
                        break;
                    }

                    continue;

                default:
                    file.SetupParent(parent, indent);

                    if (listType == YamlListType.NotDefined)
                    {
                        listType = YamlListType.KeyValue;
                    }

                    // Validate parent indent
                    switch (parent.ParserType)
                    {
                    case ParserTypes.List:
                        if (file.CurrentLineIndent < parent.ChildrenIndent)
                        {
                            return;
                        }

                        if (file.CurrentLineIndent == parent.ChildrenIndent && listType != YamlListType.KeyValue)
                        {
                            return;
                        }

                        if (file.CurrentLineIndent > parent.ChildrenIndent)
                        {
                            throw file.GetException("Unexpected indent while reading key (parent indent: " + parent.Indent + ", parent child indent: " + parent.ChildrenIndent + ", current indent: " + file.CurrentLineIndent + ").");
                        }

                        break;

                    case ParserTypes.Array:
                        if (file.CurrentLineIndent < parent.ChildrenIndent)
                        {
                            return;
                        }

                        if (file.CurrentLineIndent > parent.ChildrenIndent)
                        {
                            throw file.GetException("Unexpected indent while reading key (parent indent: " + parent.Indent + ", parent child indent: " + parent.ChildrenIndent + ", current indent: " + file.CurrentLineIndent + ").");
                        }

                        break;
                    }

                    word_s = file.ReadKey();

                    if (word_s.Length == 0)
                    {
                        throw file.GetException("Null-length word. This is most likely caused by an unexpected character in a string.");
                    }

                    file.Trim();
                    continue;
                }
            }
        }