コード例 #1
0
ファイル: ITagParser.cs プロジェクト: ks3dev/jntemplate
        public Tag Parse(TemplateParser parser, TokenCollection tc)
        {
            if (tc.Count > 2 && HasOperator(tc))
            {
                Int32 start, end, pos;
                start = end = pos = 0;

                #region 去括号
                //(8+2) ==》 8+2
                //(8+2) * (10-5) ==》(8+2) * (10-5)
                if (tc.First.TokenKind == TokenKind.LeftParentheses && tc.Last.TokenKind == TokenKind.RightParentheses)
                {
                    for (Int32 i = 1; i < tc.Count - 1; i++)
                    {
                        switch (tc[i].TokenKind)
                        {
                            case TokenKind.LeftParentheses:
                                pos++;
                                break;
                            case TokenKind.RightParentheses:
                                if (pos > 0)
                                {
                                    pos--;
                                }
                                break;
                        }
                    }
                    if (pos == 0)
                    {
                        tc = new TokenCollection(tc, 1, tc.Count - 2);
                    }
                    else
                    {
                        pos = 0;
                    }
                }
                #endregion

                ExpressionTag tag = new ExpressionTag();

                #region 执行表达式折分

                for (Int32 i = 0; i < tc.Count; i++)
                {
                    end = i;
                    switch (tc[i].TokenKind)
                    {
                        case TokenKind.Operator:
                            if (pos == 0)
                            {
                                if (start != end)
                                {
                                    TokenCollection coll = new TokenCollection();
                                    coll.Add(tc, start, end - 1);
                                    tag.AddChild(parser.Read(coll));
                                }
                                tag.AddChild(new TextTag());
                                tag.Children[tag.Children.Count - 1].FirstToken = tc[i];
                                start = i + 1;
                            }
                            break;
                        default:
                            if (tc[i].TokenKind == TokenKind.LeftParentheses)
                            {
                                pos++;
                            }
                            else if (tc[i].TokenKind == TokenKind.RightParentheses)
                            {
                                pos--;
                            }
                            if (i == tc.Count - 1)
                            {
                                TokenCollection coll = new TokenCollection();
                                if (tc[start].TokenKind == TokenKind.RightParentheses)
                                {

                                    coll.Add(tc, start + 1, end - 1);
                                }
                                else
                                {
                                    coll.Add(tc, start, end);
                                }
                                start = i + 1;
                                if (coll.Count > 0)
                                {
                                    tag.AddChild(parser.Read(coll));
                                }
                            }
                            break;
                    }
                }

                #endregion

                if (tag.Children.Count > 0)
                {
                    if (tag.Children.Count == 1)
                    {
                        return tag.Children[0];
                    }
                    return tag;
                }
            }
            return null;
        }
コード例 #2
0
ファイル: ComplexParser.cs プロジェクト: ks3dev/jntemplate
        /// <summary>
        /// 分析标签
        /// </summary>
        /// <param name="parser">TemplateParser</param>
        /// <param name="tc">Token集合</param>
        /// <returns></returns>
        public Tag Parse(JinianNet.JNTemplate.Parser.TemplateParser parser, TokenCollection tc)
        {
            if (tc != null
                && parser != null
                && tc.Count > 2)
            {
                Int32 start, end, pos;
                start = end = pos = 0;

                Boolean isFunc = false;

                List<Token> data = new List<Token>();

                Queue<TokenCollection> queue = new Queue<TokenCollection>();

                for (Int32 i = 0; i < tc.Count; i++)
                {
                    end = i;
                    if (tc[i].TokenKind == TokenKind.LeftParentheses)
                    {
                        if (pos == 0)
                        {
                            if (i > 0 && tc[i - 1].TokenKind == TokenKind.TextData)
                            {
                                isFunc = true;
                            }
                        }
                        pos++;
                    }
                    else if (tc[i].TokenKind == TokenKind.RightParentheses)
                    {
                        if (pos > 0)
                        {
                            pos--;
                        }
                        else
                        {
                            throw new Exception.ParseException(String.Concat("syntax error near ):", tc), data[i].BeginLine, data[i].BeginColumn);
                        }

                        if (pos == 0)
                        {
                            TokenCollection coll = new TokenCollection();
                            if (!isFunc)
                            {
                                coll.Add(tc, start + 1, end - 1);
                            }
                            else
                            {
                                coll.Add(tc, start, end);
                            }
                            queue.Enqueue(coll);
                            data.Add(null);
                            start = i + 1;
                            //tag.AddChild(parser.Read(coll));
                        }
                    }
                    else if (pos == 0 && (tc[i].TokenKind == TokenKind.Dot || tc[i].TokenKind == TokenKind.Operator))
                    {
                        if (end > start)
                        {
                            TokenCollection coll = new TokenCollection();
                            coll.Add(tc, start, end - 1);
                            queue.Enqueue(coll);
                            data.Add(null);
                        }
                        start = i + 1;
                        data.Add(tc[i]);
                    }

                    if (i == tc.Count - 1 && end >= start)
                    {
                        if (start == 0 && end == i)
                        {
                            throw new Exception.ParseException(String.Concat("Unexpected  tag:", tc), tc[0].BeginLine, tc[0].BeginColumn);
                        }
                        TokenCollection coll = new TokenCollection();
                        coll.Add(tc, start, end);
                        queue.Enqueue(coll);
                        data.Add(null);
                        start = i + 1;
                    }
                }

                List<Tag> tags = new List<Tag>();

                for (Int32 i = 0; i < data.Count; i++)
                {
                    if (data[i] == null)
                    {
                        tags.Add(parser.Read(queue.Dequeue()));
                    }
                    else if (data[i].TokenKind == TokenKind.Dot)
                    {
                        if (tags.Count == 0 || i == data.Count - 1 || data[i + 1] != null)
                        {
                            throw new Exception.ParseException(String.Concat("syntax error near .:", tc), data[i].BeginLine, data[i].BeginColumn);
                        }
                        if (tags[tags.Count - 1] is ReferenceTag)
                        {
                            tags[tags.Count - 1].AddChild(parser.Read(queue.Dequeue()));
                        }
                        else
                        {
                            ReferenceTag t = new ReferenceTag();
                            t.AddChild(tags[tags.Count - 1]);
                            t.AddChild(parser.Read(queue.Dequeue()));
                            tags[tags.Count - 1] = t;
                        }
                        i++;
                    }
                    else if (data[i].TokenKind == TokenKind.Operator)
                    {
                        tags.Add(new TextTag());
                        tags[tags.Count - 1].FirstToken = data[i];

                    }
                }

                if (tags.Count == 1)
                {
                    return tags[0];
                }
                if (tags.Count > 1)
                {
                    ExpressionTag t = new ExpressionTag();

                    for (Int32 i = 0; i < tags.Count; i++)
                    {
                        t.AddChild(tags[i]);
                    }

                    tags.Clear();
                    return t;
                }
            }
            return null;
        }
コード例 #3
0
ファイル: SetParser.cs プロジェクト: ks3dev/jntemplate
        /// <summary>
        /// 分析标签
        /// </summary>
        /// <param name="parser">TemplateParser</param>
        /// <param name="tc">Token集合</param>
        /// <returns></returns>
        public Tag Parse(TemplateParser parser, TokenCollection tc)
        {
            if (tc == null
                || parser == null)
            {
                return null;
            }

            //支持写法:简写格式:
            //常规格式:
            if (tc.Count > 5
                && Common.ParserHelpers.IsEqual(tc.First.Text, Field.KEY_SET)
                && tc[1].TokenKind == TokenKind.LeftParentheses
                && tc[3].Text == "="
                && tc.Last.TokenKind == TokenKind.RightParentheses)
            {
                SetTag tag = new SetTag();
                tag.Name = tc[2].Text;

                TokenCollection coll = new TokenCollection();
                coll.Add(tc, 4, tc.Count - 2);

                tag.Value = parser.Read(coll);
                return tag;

            }

            if (tc.Count == 2
                && tc.First.TokenKind == TokenKind.TextData
                && tc.Last.TokenKind == TokenKind.Operator
                && (tc.Last.Text == "++" || tc.Last.Text == "--"))
            {
                SetTag tag = new SetTag();
                tag.Name = tc.First.Text;

                ExpressionTag c = new ExpressionTag();
                c.AddChild(new VariableTag()
                {
                    FirstToken = tc.First,
                    Name = tc.First.Text
                });
                c.AddChild(new TextTag()
                {
                    FirstToken = new Token(TokenKind.Operator, tc.Last.Text[0].ToString())
                });
                c.AddChild(new NumberTag()
                {
                    Value = 1,
                    FirstToken = new Token(TokenKind.Number, "1")
                });

                tag.Value = c;
                return tag;
            }

            if (tc.Count > 2
                && tc.First.TokenKind == TokenKind.TextData
                && tc[1].Text == "=")
            {
                SetTag tag = new SetTag();
                tag.Name = tc.First.Text;

                TokenCollection coll = new TokenCollection();
                coll.Add(tc, 2, tc.Count - 1);

                tag.Value = parser.Read(coll);
                return tag;
            }

            return null;
        }