Ejemplo n.º 1
0
        public static Dom AnalyzeDom(string Code)
        {
            int[] pos  = BracketMatching(Code, true);
            Dom   root = new Dom();

            for (int index = 0, nextIndex; index < Code.Length; index = nextIndex + 1)
            {
                char tempChar = Code[index];
                if (char.IsWhiteSpace(tempChar) == true)
                { // ignore space
                    nextIndex = index;
                }
                else if (tempChar == '<')
                {
                    nextIndex = AnalyzeDom(root, Code, index, pos, CodeType.Html, false);
                }
                else if (tempChar == '@')
                {
                    nextIndex = AnalyzeDom(root, Code, index, pos, CodeType.Razor, false);
                }
                else
                {
                    nextIndex = AnalyzeDom(root, Code, index, pos, CodeType.Text, false);
                    // throw new Exception("Syntax Error");
                }
            }
            return(root);
        }
Ejemplo n.º 2
0
        public static int AnalyzeDom(Dom root, string Code, int sta, int[] pos, CodeType nowType, bool flag)
        {
            Dom now = new Dom {
                Type = nowType
            };
            int end;

            if (nowType == CodeType.Html)
            {
                end = pos[sta]; // '<' at sta, '>' at end
                if (Code[sta] != '<' || Code[end] != '>')
                {
                    throw new Exception();
                }
                if (sta + 2 < end && " /".Equals(Code.substring(end - 2, end)) == true || // match <someTag />
                    sta + 5 < end && "!--".Equals(Code.substring(sta + 1, sta + 4)) == true && "--".Equals(Code.substring(end - 2, end)) == true)
                { // match <!--...--> (may ignored)
                    now.Begin = Code.substring(sta, end + 1);
                }
                else
                {
                    // may match <someTag>
                    int tempIndex = Code.IndexOf(' ', sta + 2); // fetch someTag : <someTag> or <someTag ...>
                    var someTag   = (tempIndex != -1 && tempIndex < end) ? Code.substring(sta + 1, tempIndex) : Code.substring(sta + 1, end);
                    if (IsTag(someTag) == false)
                    {
                        throw new Exception("Syntax Error.");
                    }
                    now.Begin = Code.substring(sta, end + 1); // <someTag...>
                                                              // then try to find child and </someTag>
                    for (int index = end + 1, nextIndex = -1; index < Code.Length; index = nextIndex + 1)
                    {                                         // find now.child
                        char tempChar = Code[index];
                        if (tempChar == '<')
                        {                               // match HTML child or </someTag>
                            if (index + 1 < Code.Length && Code[index + 1] == '/')
                            {                           // match </someTag>
                                tempIndex = pos[index]; // fetch someTag and check it
                                if (tempIndex < 0 || someTag.Equals(Code.substring(index + 2, tempIndex)) == false)
                                {
                                    throw new Exception("Syntax Error.");
                                }
                                end     = tempIndex;
                                now.End = Code.substring(index, end + 1); // <someTag ...> ... </someTag>
                                break;
                            }
                            else   // match HTML child
                            {
                                nextIndex = AnalyzeDom(now, Code, index, pos, CodeType.Html, false);
                            }
                        }
                        else if (tempChar == '@')
                        { // match Razor child
                            nextIndex = AnalyzeDom(now, Code, index, pos, CodeType.Razor, false);
                        }
                        else   // match InnerText child
                        {
                            nextIndex = AnalyzeDom(now, Code, index, pos, CodeType.Text, false);
                        }
                    }
                }
                root.AppendChild(now);
            }
            else if (nowType == CodeType.Razor)
            { // may not start at @
                if (!(flag == true || Code[sta] == '@' && sta + 1 < Code.Length))
                {
                    throw new Exception();
                }
                var isIfElse = false;
                if (flag == false && Code[sta + 1] == '*')
                { // rule 7 : @*...*@
                    end = Code.IndexOf("*@", sta + 2);
                    if (end == -1)
                    {
                        throw new Exception("Syntax Error.");
                    }
                    ++end;
                    now.Begin = Code.substring(sta, end + 1);  // @*...*@ (may ignored)
                }
                else if (flag == false && Code[sta + 1] == '@')
                {                                             // rule 3 : @@
                    end       = sta + 1;
                    now.Begin = Code.substring(sta, end + 1); // @@
                }
                else                                          // other rules
                {
                    if (flag == true)
                    {
                        --sta; // for assuming sta+1 is the first index after @
                    }
                    int tempIndex = Code.Length - 1;
                    for (int index = sta + 1; index < Code.Length; ++index)
                    { // find the first non-blank char after @
                        if (char.IsWhiteSpace(Code[index]) == false)
                        {
                            // the first position after space
                            tempIndex = index;
                            break;
                        }
                    }
                    char tempChar = Code[tempIndex];
                    if (char.IsLetter(tempChar) == true || tempChar == '$' || tempChar == '_')
                    { // rule 1 & 5 (contain rule 6)
                        end = Code.Length - 1;
                        // find the first variable name
                        for (int index = sta + 1; index < Code.Length; ++index)
                        {
                            tempChar = Code[index];
                            if (char.IsLetter(tempChar) == false && char.IsDigit(tempChar) == false && tempChar != '_' && tempChar != '$')
                            {
                                end = index - 1;
                                break;
                            }
                        }
                        String variable = Code.substring(sta + 1, end + 1);
                        if ("if".Equals(variable) == true || "else".Equals(variable) == true || "for".Equals(variable) == true || "foreach".Equals(variable) || "while".Equals(variable) == true || "do".Equals(variable) == true)
                        {
                            // rule 5 : for() {...} or if(expression) {...} else {...}
                            int leftIndex = Code.IndexOf('{', end + 1);
                            while (leftIndex != -1 && pos[leftIndex] == -2)
                            {
                                leftIndex = Code.IndexOf('{', leftIndex + 1);
                            }
                            if (leftIndex == -1)
                            {
                                throw new Exception("Syntax Error.");
                            }
                            int rightIndex = pos[leftIndex];
                            now.Begin = Code.substring(tempIndex, leftIndex + 1);
                            for (int index = leftIndex + 1, nextIndex; index < rightIndex; index = nextIndex + 1)
                            {
                                tempChar = Code[index];
                                if (char.IsWhiteSpace(tempChar) == true)
                                { // ignore space
                                    nextIndex = index;
                                }
                                else if (tempChar == '<')
                                { // HTML
                                    nextIndex = AnalyzeDom(now, Code, index, pos, CodeType.Html, false);
                                }
                                else   // no innerText, all is razor
                                {
                                    nextIndex = AnalyzeDom(now, Code, index, pos, CodeType.Razor, true);
                                }
                            }
                            if ("if".Equals(variable) == true)
                            { // check "else" and "else if"
                                isIfElse = true;
                                end      = rightIndex;
                                now.End  = Code.substring(rightIndex, end + 1);
                                root.AppendChild(now);
                                // prestore if-else-if in nowList.children
                                for (int index = rightIndex + 1; index < Code.Length; index = rightIndex + 1)
                                {
                                    // find a whole word "else"
                                    tempIndex = Code.IndexOf("else", index);
                                    while (tempIndex != -1)
                                    {
                                        if (tempIndex + 4 < Code.Length)
                                        {
                                            tempChar = Code[tempIndex + 4];
                                            if (char.IsLetter(tempChar) == false && char.IsDigit(tempChar) == false && tempChar != '_' && tempChar != '$')
                                            {
                                                break;
                                            }
                                        }
                                        tempIndex = Code.IndexOf("else", tempIndex + 4);
                                    }
                                    if (tempIndex != -1)
                                    {
                                        // add "else" or "else if" to nowList
                                        rightIndex = AnalyzeDom(root, Code, tempIndex, pos, CodeType.Razor, true);
                                        // check "else if" format
                                        leftIndex = Code.IndexOf('{', tempIndex + 4);
                                        while (leftIndex != -1 && pos[leftIndex] == -2)
                                        {
                                            leftIndex = Code.IndexOf('{', leftIndex + 1);
                                        }

                                        /* if(leftIndex == -1) {
                                         *  throw new Exception("cheng xu chu bug la!");
                                         * } */
                                        int tempIndex2 = Code.Length - 1;
                                        for (int index2 = tempIndex + 4; index2 < Code.Length; ++index2)
                                        {
                                            if (char.IsWhiteSpace(Code[index2]) == false)
                                            {
                                                tempIndex2 = index2;
                                                break;
                                            }
                                        }
                                        if (tempIndex2 + 1 >= leftIndex || "if".Equals(Code.substring(tempIndex2, tempIndex + 2)) == false)
                                        {
                                            // not "else if", end the condition
                                            end = rightIndex;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                            else if ("do".Equals(variable) == true)
                            { // check "while (...)"
                                tempIndex = Code.IndexOf('(', rightIndex + 1);
                                while (tempIndex != -1 && pos[tempIndex] == -2)
                                {
                                    tempIndex = Code.IndexOf('(', tempIndex + 1);
                                }
                                if (tempIndex == -1)
                                {
                                    throw new Exception("Syntax Error.");
                                }
                                end     = pos[tempIndex];
                                now.End = Code.substring(rightIndex, end + 1);
                            }
                            else
                            {
                                end     = rightIndex;
                                now.End = Code.substring(rightIndex, end + 1);
                            }
                        }
                        else
                        {
                            // rule 1 : @variable[index].method(parameters)
                            if (end + 1 < Code.Length && Code[end + 1] == '[')
                            { // variable[index]
                                end = pos[end + 1];
                            }
                            if (end + 1 < Code.Length && Code[end + 1] == '.')
                            { // object.property or object.method
                                ++end;
                                tempIndex = Code.Length - 1;
                                for (int index = end + 1; index < Code.Length; ++index)
                                {
                                    tempChar = Code[index];
                                    if (char.IsLetter(tempChar) == false && char.IsDigit(tempChar) == false && tempChar != '_' && tempChar != '$')
                                    {
                                        tempIndex = index - 1;
                                        break;
                                    }
                                }
                                end       = tempIndex;
                                tempIndex = Code.Length - 1;
                                for (int index = end + 1; index < Code.Length; ++index)
                                {
                                    if (char.IsWhiteSpace(Code[index]) == false)
                                    {
                                        tempIndex = index;
                                        break;
                                    }
                                }
                                if (Code[tempIndex] == '(')
                                { // object.method()
                                    int leftIndex = tempIndex, rightIndex = pos[leftIndex];
                                    end       = rightIndex;
                                    tempIndex = Code.IndexOf('{', leftIndex + 1);
                                    while (tempIndex != -1 && tempIndex < rightIndex && pos[tempIndex] == -2)
                                    {
                                        tempIndex = Code.IndexOf('{', tempIndex + 1);
                                    }
                                    if (tempIndex != -1 && tempIndex < rightIndex)
                                    { // object.method( {...} ) like loop
                                        leftIndex  = tempIndex;
                                        rightIndex = pos[tempIndex];
                                        now.Begin  = Code.substring(sta + 1, leftIndex + 1);
                                        for (int index = leftIndex + 1, nextIndex = -1; index < rightIndex; index = nextIndex + 1)
                                        {
                                            tempChar = Code[index];
                                            if (char.IsWhiteSpace(tempChar) == true)
                                            { // ignore space
                                                nextIndex = index;
                                            }
                                            else if (tempChar == '<')
                                            { // HTML
                                                nextIndex = AnalyzeDom(now, Code, index, pos, CodeType.Html, false);
                                            }
                                            else   // no innerText, all is razor
                                            {
                                                nextIndex = AnalyzeDom(now, Code, index, pos, CodeType.Razor, true);
                                            }
                                        }
                                        now.End = Code.substring(rightIndex, end + 1);
                                    }
                                    else   // object.method(...)
                                    {
                                        now.Begin = Code.substring(sta + 1, end + 1);
                                    }
                                }
                                else   // object.property
                                {
                                    now.Begin = Code.substring(sta + 1, end + 1);
                                }
                            }
                            else
                            {
                                now.Begin = Code.substring(sta + 1, end + 1);
                            }
                        }
                    }
                    else if (tempChar == '(')
                    { // rule 2 : @(expression) (mind the "({})")
                      // ( {...} ) not need to split
                        end       = pos[tempIndex];
                        now.Begin = Code.substring(tempIndex, end + 1); // (expression)
                    }
                    else if (tempChar == '{')
                    { // rule 4 : @{JS Code}
                      // {...} not need to split
                        end       = pos[tempIndex];
                        now.Begin = Code.substring(tempIndex, end + 1);
                    }
                    else
                    {
                        throw new Exception("Syntax Error.");
                    }
                }
                if (isIfElse == false)
                {
                    root.AppendChild(now);
                }
            }
            else   // nowType == CodeType.Text
            {
                if (!(Code[sta] != '<' && Code[sta] != '@'))
                {
                    throw new Exception();
                }
                int tempIndex1 = Code.IndexOf('<', sta + 1), tempIndex2 = Code.IndexOf('@', sta + 1);
                while (tempIndex1 != -1 && pos[tempIndex1] < 0)
                { // skip comparison '<' and inner '<'
                    tempIndex1 = Code.IndexOf('<', tempIndex1 + 1);
                }
                // find minimum in {IndexOfMatched('<'), IndexOf('@'), Length}
                end = Code.Length - 1;
                if (tempIndex1 != -1)
                {
                    end = Math.Min(end, tempIndex1 - 1);
                }
                if (tempIndex2 != -1)
                {
                    end = Math.Min(end, tempIndex2 - 1);
                }
                now.Begin = Code.substring(sta, end + 1);
                root.AppendChild(now);
            }
            return(end);
        }
Ejemplo n.º 3
0
 public void AppendChild(Dom dom)
 {
     Children.Add(dom);
 }