Example #1
0
        private XmlScriptDocument ParseDocument(ScriptParser Parser)
        {
            List <XmlScriptProcessingInstruction> ProcessingInstructions = null;
            int  Start = Parser.Start;
            int  Pos;
            char ch;

            while (Parser.PeekNextChar() == '?')
            {
                Parser.NextChar();
                Pos = Parser.Position;

                while ((ch = Parser.NextChar()) != '?' && ch != 0)
                {
                    ;
                }

                if (ch == 0)
                {
                    return(null);
                }

                if (ProcessingInstructions is null)
                {
                    ProcessingInstructions = new List <XmlScriptProcessingInstruction>();
                }

                string Text = Parser.Expression.Script.Substring(Pos, Parser.Position - Pos - 1);

                if (Parser.NextChar() != '>')
                {
                    throw Parser.SyntaxError("> expected.");
                }

                ProcessingInstructions.Add(new XmlScriptProcessingInstruction(Text,
                                                                              Start, Parser.Position - Start, Parser.Expression));

                Parser.SkipWhiteSpace();

                if (Parser.NextChar() != '<')
                {
                    return(null);
                }

                Start = Parser.Position;
            }

            Parser.UndoChar();
            XmlScriptElement Root = this.ParseElement(Parser);

            if (Root is null)
            {
                return(null);
            }

            return(new XmlScriptDocument(Root, ProcessingInstructions?.ToArray() ?? new XmlScriptProcessingInstruction[0],
                                         Start, Parser.Position - Start, Parser.Expression));
        }
Example #2
0
        private XmlScriptElement ParseElement(ScriptParser Parser)
        {
            if (Parser.NextChar() != '<')
            {
                throw Parser.SyntaxError("< expected.");
            }

            List <XmlScriptAttribute> Attributes = null;
            IElement ElementValue;
            int      ElementStart = Parser.Position;
            string   ElementName  = ParseName(Parser);
            string   Value;
            char     ch;

            Parser.SkipWhiteSpace();

            while ((ch = Parser.PeekNextChar()) != 0)
            {
                if (ch == '>')
                {
                    Parser.NextChar();

                    XmlScriptElement Element = new XmlScriptElement(ElementName, Attributes?.ToArray() ?? new XmlScriptAttribute[0],
                                                                    ElementStart, Parser.Position - ElementStart, Parser.Expression);

                    while (true)
                    {
                        int Pos = Parser.Position;
                        int i   = Parser.Expression.Script.IndexOf('<', Pos);
                        int Len;

                        if (i < 0)
                        {
                            throw Parser.SyntaxError("Open element.");
                        }

                        if (i > Pos)
                        {
                            Len = i - Pos;

                            Element.Add(new XmlScriptText(Parser.Expression.Script.Substring(Pos, Len),
                                                          Pos, Len, Parser.Expression));

                            Parser.SkipChars(Len);
                        }

                        switch (Parser.PeekNextChars(2))
                        {
                        case "</":
                            Parser.NextChar();
                            Parser.NextChar();

                            if (ParseName(Parser) != ElementName)
                            {
                                throw Parser.SyntaxError("Expected end of element " + ElementName);
                            }

                            if (Parser.NextChar() != '>')
                            {
                                throw Parser.SyntaxError("> expected.");
                            }

                            return(Element);

                        case "<!":
                            if (Parser.PeekNextChars(4) == "<!--")
                            {
                                Parser.SkipChars(4);

                                Pos = Parser.Position;
                                i   = Parser.Expression.Script.IndexOf("-->", Pos);
                                if (i < 0)
                                {
                                    throw Parser.SyntaxError("Unterminated comment.");
                                }

                                Len = i - Pos;
                                Element.Add(new XmlScriptComment(Parser.Expression.Script.Substring(Pos, Len),
                                                                 Pos, Len, Parser.Expression));

                                Parser.SkipChars(Len + 3);
                            }
                            else if (Parser.PeekNextChars(9) == "<![CDATA[")
                            {
                                Parser.SkipChars(9);

                                Pos = Parser.Position;
                                i   = Parser.Expression.Script.IndexOf("]]>", Pos);
                                if (i < 0)
                                {
                                    throw Parser.SyntaxError("Unterminated CDATA construct.");
                                }

                                Len = i - Pos;
                                Element.Add(new XmlScriptCData(Parser.Expression.Script.Substring(Pos, Len),
                                                               Pos, Len, Parser.Expression));

                                Parser.SkipChars(Len + 3);
                            }
                            else
                            {
                                throw Parser.SyntaxError("Expected <!-- or <![CDATA[");
                            }

                            break;

                        case "<[":
                            Parser.SkipChars(2);

                            ScriptNode Node = Parser.ParseSequence();
                            Parser.SkipWhiteSpace();

                            if (Parser.PeekNextChars(2) != "]>")
                            {
                                throw Parser.SyntaxError("]> expected.");
                            }

                            Parser.SkipChars(2);

                            Element.Add(new XmlScriptValue(Node, Node.Start, Node.Length, Node.Expression));
                            break;

                        case "<(":
                            Parser.SkipChars(2);

                            Node = Parser.ParseSequence();
                            Parser.SkipWhiteSpace();

                            if (Parser.PeekNextChars(2) != ")>")
                            {
                                throw Parser.SyntaxError(")> expected.");
                            }

                            Parser.SkipChars(2);

                            Element.Add(new XmlScriptValue(Node, Node.Start, Node.Length, Node.Expression));
                            break;

                        default:
                            Element.Add(this.ParseElement(Parser));
                            break;
                        }
                    }
                }
                else if (ch == '/')
                {
                    Parser.NextChar();
                    if (Parser.NextChar() != '>')
                    {
                        throw Parser.SyntaxError("> expected.");
                    }

                    return(new XmlScriptElement(ElementName, Attributes?.ToArray() ?? new XmlScriptAttribute[0],
                                                ElementStart, Parser.Position - ElementStart, Parser.Expression));
                }
                else if (char.IsLetter(ch) || ch == '_' || ch == ':')
                {
                    int    AttributeStart = Parser.Position;
                    string AttributeName  = ParseName(Parser);

                    Parser.SkipWhiteSpace();
                    if (Parser.NextChar() != '=')
                    {
                        throw Parser.SyntaxError("= expected.");
                    }

                    bool Bak = Parser.CanSkipWhitespace;
                    Parser.CanSkipWhitespace = false;
                    ScriptNode Node = Parser.ParsePowers();
                    Parser.CanSkipWhitespace = Bak;

                    if (Attributes is null)
                    {
                        Attributes = new List <XmlScriptAttribute>();
                    }

                    if (Node is ConstantElement Constant)
                    {
                        ElementValue = Constant.Constant;

                        if (ElementValue is StringValue S)
                        {
                            Value = S.Value;
                        }
                        else
                        {
                            Value = Expression.ToString(ElementValue.AssociatedObjectValue);
                        }

                        Attributes.Add(new XmlScriptAttributeString(AttributeName, Value,
                                                                    AttributeStart, Parser.Position - AttributeStart, Parser.Expression));
                    }
                    else
                    {
                        Attributes.Add(new XmlScriptAttributeScript(AttributeName, Node,
                                                                    AttributeStart, Parser.Position - AttributeStart, Parser.Expression));
                    }
                }
                else if (char.IsWhiteSpace(ch))
                {
                    Parser.NextChar();
                }
                else
                {
                    throw Parser.SyntaxError("Invalid XML Element.");
                }
            }

            return(null);
        }