コード例 #1
0
        public StatementNode Parse(TextReader reader)
        {
            var swixTokens = new Token <ParserTokenType>[] { new Token <ParserTokenType>(ParserTokenType.Object, "swix", new Range(new Position(-1, -1, -1), 0)) };

            this.RootStatementNode = new StatementNode(-1, null, new Statement <StatementType, ParserTokenType>(StatementType.Object, swixTokens, swixTokens));
            this.Errors            = new List <Error>();

            using (ReaderTextProvider textProvider = new ReaderTextProvider(reader))
            {
                var statements = RtypeStatementParser.ParseStatements(new Position(0, 0, 0), textProvider);

                Stack <StatementNode> parentStack       = new Stack <StatementNode>();
                StatementNode         lastStatementNode = null;
                char requiredLeadingWhitespaceStyle     = '\0';

                parentStack.Push(this.RootStatementNode);

                foreach (var statement in statements)
                {
                    if (statement.HasError)
                    {
                        // Propagate the error...
                        foreach (var token in statement.Tokens)
                        {
                            if (token.Errors != null)
                            {
                                foreach (var error in token.Errors)
                                {
                                    this.AddError(error.Range, error.Message);
                                }
                            }
                        }
                    }

                    if (statement.StatementType == StatementType.Ignorable)
                    {
                        // TODO: Should we continue to pass along the ignorable statements?
                        continue;
                    }

                    // Look at the leading whitespace (if any!) and decide if we're a child, a sibling, or
                    // if we need to pop the stack some...
                    int indent = 0;
                    Token <ParserTokenType> leadingWhitespace = statement.AllTokens
                                                                .Take(1)
                                                                .Where(t => t.TokenType == ParserTokenType.Whitespace)
                                                                .FirstOrDefault();

                    if (leadingWhitespace != null)
                    {
                        string whitespace = leadingWhitespace.Value;

                        // If we haven't decided whether we require leading tabs or spaces, just use the
                        // first character in this leading whitespace!

                        if (requiredLeadingWhitespaceStyle == '\0')
                        {
                            requiredLeadingWhitespaceStyle = whitespace[0];
                        }

                        if (!whitespace.All(c => c == requiredLeadingWhitespaceStyle))
                        {
                            this.AddError(leadingWhitespace, "Leading whitespace must be either all tabs or all spaces.");
                        }

                        indent = leadingWhitespace.Value.Length;
                    }

                    // Look at the indent of this statement, and decide where it goes...
                    if (lastStatementNode != null && indent > lastStatementNode.Indent)
                    {
                        parentStack.Push(lastStatementNode);
                    }
                    else if (lastStatementNode != null && indent < lastStatementNode.Indent)
                    {
                        // Pop the parent stack until we have a parent with less indentation...
                        while (parentStack.Peek().Indent >= indent)
                        {
                            parentStack.Pop();
                        }
                    }

                    // Now we've fixed up the parent stack, so we can add this statement to the
                    // proper parent...
                    lastStatementNode = new StatementNode(indent, parentStack.Peek(), statement);
                    parentStack.Peek().Add(lastStatementNode);
                }
            }

            return(this.RootStatementNode);
        }
コード例 #2
0
 public void Add(StatementNode childStatementNode)
 {
     this.Children.Add(childStatementNode);
 }
コード例 #3
0
        public StatementNode Parse(TextReader reader)
        {
            ////var swixTokens = new Token<ParserTokenType>[] { new Token<ParserTokenType>(ParserTokenType.Object, "swix", new Range(new Position(-1, -1, -1), 0)) };
            ////this.RootStatementNode = new StatementNode(-1, null, new Statement<StatementType, ParserTokenType>(StatementType.Object, swixTokens, swixTokens));
            this.Errors = new List <Error>();

            using (ReaderTextProvider textProvider = new ReaderTextProvider(reader))
            {
                var statements = XmlStatementParser.ParseStatements(new Position(0, 0, 0), textProvider);

                Stack <StatementNode> parentStack = new Stack <StatementNode>();

                ////parentStack.Push(this.RootStatementNode);

                foreach (var statement in statements)
                {
                    if (statement.HasError)
                    {
                        // Propagate the error...
                        foreach (var token in statement.Tokens)
                        {
                            if (token.Errors != null)
                            {
                                foreach (var error in token.Errors)
                                {
                                    this.AddError(error.Range, error.Message);
                                }
                            }
                        }
                    }

                    if (statement.StatementType == StatementType.Ignorable ||
                        statement.StatementType == StatementType.Comment)
                    {
                        // TODO: Should we continue to pass along the ignorable statements?
                        continue;
                    }

                    if (statement.StatementType == StatementType.Object ||
                        statement.StatementType == StatementType.ObjectStart)
                    {
                        StatementNode parent = null;
                        int           indent = 0;

                        if (parentStack.Count > 0)
                        {
                            parent = parentStack.Peek();
                            indent = parent.Indent + 1;
                        }

                        var node = new StatementNode(indent, parent, statement);

                        if (this.RootStatementNode == null)
                        {
                            this.RootStatementNode = node;
                        }

                        if (parent != null)
                        {
                            parent.Add(node);
                        }

                        if (statement.StatementType == StatementType.ObjectStart)
                        {
                            parentStack.Push(node);
                        }
                    }
                    else if (statement.StatementType == StatementType.ObjectEnd)
                    {
                        // Should we push the close statement to the end of
                        // the children?  I think so!
                        var parent = parentStack.Pop();
                        while (parent != null && !ObjectEndMatches(parent.Statement, statement))
                        {
                            parent = parentStack.Pop();
                        }

                        if (parent != null)
                        {
                            // push the close statement...
                            var node = new StatementNode(parent.Indent + 1, parent, statement);
                            parent.Add(node);
                        }

                        // Flag an error?
                        ////// If we over-pop, push the root node back on...
                        ////if (parentStack.Count == 0)
                        ////{
                        ////    parentStack.Push(this.RootStatementNode);
                        ////}
                    }
                }
            }

            return(this.RootStatementNode);
        }