예제 #1
0
        public MultiLineStringNode GetChildAddresedByStringLineNumber(int number)
        {
            EnsureProperType(NodeChildrenType.multiLineString);

            // ensure proper number of child string nodes exist
            var indentation = GetProperChildIndentation();
            for(int i = ChildNodes.Count; i <= number; i++)
            {
                var newnode = new MultiLineStringNode(indentation, File);
                AddChild(newnode);
            }

            return ChildNodes[number] as MultiLineStringNode;
        }
예제 #2
0
        /// <summary>
        /// Parses lines of SUCC into a data structure
        /// </summary>
        internal static (List <Line>, Dictionary <string, KeyNode>) DataStructureFromSUCC(string[] lines, DataFileBase fileRef) // I am so, so sorry. If you need to understand this function for whatever reason... may god give you guidance.
        {
            // if the file is empty
            // do this because otherwise new files are created with a newline at the top
            if (lines.Length == 1 && lines[0] == "")
            {
                return(new List <Line>(), new Dictionary <string, KeyNode>());
            }


            var TopLevelLines = new List <Line>();
            var TopLevelNodes = new Dictionary <string, KeyNode>();

            var  NestingNodeStack     = new Stack <Node>(); // the top of the stack is the node that new nodes should be children of
            bool DoingMultiLineString = false;

            var file = fileRef as DataFile; // this will be null if fileRef is a ReadOnlyDataFile

            // parse the input line by line
            for (int i = 0; i < lines.Length; i++)
            {
                var line = lines[i];
                if (line.Contains('\t'))
                {
                    throw new FormatException("a SUCC file cannot contain tabs. Please use spaces instead.");
                }

                if (DoingMultiLineString)
                {
                    if (NestingNodeStack.Peek().ChildNodeType != NodeChildrenType.multiLineString)
                    {
                        throw new Exception("oh f**k, we were supposed to be doing a multi-line string but the top of the node stack isn't a multi-line string node!");
                    }

                    var newboi = new MultiLineStringNode(rawText: line, file);

                    NestingNodeStack.Peek().AddChild(newboi);

                    if (newboi.IsTerminator)
                    {
                        DoingMultiLineString = false;
                        NestingNodeStack.Pop();
                    }

                    continue;
                }

                if (LineHasData(line))
                {
                    Node node = GetNodeFromLine(line, file);

boobies:

                    if (NestingNodeStack.Count == 0) // if this is a top-level node
                    {
                        if (!(node is KeyNode))
                        {
                            throw new FormatException($"top level lines must be key nodes. Line {i} does not conform to this: '{line}'");
                        }
                        TopLevelLines.Add(node);
                        KeyNode heck = node as KeyNode;
                        TopLevelNodes.Add(heck.Key, heck);
                    }
                    else // if this is NOT a top-level node
                    {
                        int StackTopIndentation = NestingNodeStack.Peek().IndentationLevel;
                        int LineIndentation     = line.GetIndentationLevel();

                        if (LineIndentation > StackTopIndentation) // if this should be a child of the stack top
                        {
                            Node newParent = NestingNodeStack.Peek();
                            if (newParent.ChildNodes.Count == 0) // if this is the first child of the parent, assign the parent's child type
                            {
                                if (node is KeyNode)
                                {
                                    newParent.ChildNodeType = NodeChildrenType.key;
                                }
                                else if (node is ListNode)
                                {
                                    newParent.ChildNodeType = NodeChildrenType.list;
                                }
                                else
                                {
                                    throw new Exception("what the f**k?");
                                }
                            }
                            else // if the parent already has children, check for errors with this line
                            {
                                CheckNewSiblingForErrors(child: node, newParent: newParent);
                            }

                            newParent.AddChild(node);
                        }
                        else // if this should NOT be a child of the stack top
                        {
                            NestingNodeStack.Pop();
                            goto boobies;
                        }
                    }

                    if (node.Value == "") // if this is a node with children
                    {
                        NestingNodeStack.Push(node);
                    }

                    if (node.Value == MultiLineStringNode.Terminator) // if this is the start of a multi line string
                    {
                        NestingNodeStack.Push(node);
                        node.ChildNodeType   = NodeChildrenType.multiLineString;
                        DoingMultiLineString = true;
                    }
                }
                else // line has no data
                {
                    Line NoDataLine = new Line(rawText: line);

                    if (NestingNodeStack.Count == 0)
                    {
                        TopLevelLines.Add(NoDataLine);
                    }
                    else
                    {
                        NestingNodeStack.Peek().AddChild(NoDataLine);
                    }
                }
            }

            return(TopLevelLines, TopLevelNodes);
        }