示例#1
0
        /// <summary>
        /// Creates the token.
        /// </summary>
        /// <param name="tokenType">Type of the token.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        internal TagToken CreateToken(TagTokenType tokenType, string value)
        {
            int lt = _lastToken;

            _lastToken = _pos;
            return(new TagToken(tokenType, lt, _pos - lt, value));
        }
示例#2
0
 internal TagToken(TagTokenType type, int position, int len, string value)
 {
     _type   = type;
     _offset = position;
     _len    = len;
     _value  = value;
 }
示例#3
0
 static int LastToken(List <TagToken> tokens, TagTokenType tokenType)
 {
     for (int i = tokens.Count - 1; i >= 0; i--)
     {
         if (tokens[i].TokenType == tokenType)
         {
             return(i);
         }
     }
     return(-1);
 }
示例#4
0
 internal TagToken(char token, int offset)
 {
     _type   = (TagTokenType)token;
     _offset = offset;
 }
示例#5
0
        internal static void ResolveAndOrConflicts(TagExpression expr, ParserState state)
        {
            if (expr == null)
            {
                throw new ArgumentNullException("expr");
            }

            AndOrExpression andOr = expr as AndOrExpression;

            if (andOr != null && (andOr.LeftHand is AndOrExpression || andOr.RightHand is AndOrExpression))
            {
                List <TagToken>      tokens = new List <TagToken>();
                List <TagExpression> exprs  = new List <TagExpression>();

                AddAndOr(andOr, tokens, exprs);                 // Create a list of tokens and separating expressions

                if (exprs.Count != tokens.Count + 1)
                {
                    throw new InvalidOperationException();                     // Not a valid token chain
                }
                TagTokenType tt = tokens[0].TokenType;

                bool hasConflict = false;
                for (int i = 1; i < tokens.Count; i++)
                {
                    if (tokens[i].TokenType != tt)
                    {
                        if (!state.Args.ApplyAndOrPriority)
                        {
                            throw new PriorityException("And or conflict; please resolve using parens", tokens[i], state);
                        }
                        else
                        {
                            hasConflict = true;
                        }
                    }
                }

                if (hasConflict)
                {
                    // We re-orden the children to prioritize 'and' above 'or'

                    // We assume: we have at least one 'and' at least one 'or'

                    int i;

                    // Re-create all groups of and-s, from the back
                    while (0 <= (i = LastToken(tokens, TagTokenType.And)))
                    {
                        exprs[i] = new AndOrExpression(tokens[i], exprs[i], exprs[i + 1]);
                        tokens.RemoveAt(i);
                        exprs.RemoveAt(i + 1);
                    }

                    // Re-create all groups of or-s, from the back
                    while (1 <= (i = LastToken(tokens, TagTokenType.Or)))
                    {
                        exprs[i] = new AndOrExpression(tokens[i], exprs[i], exprs[i + 1]);
                        tokens.RemoveAt(i);
                        exprs.RemoveAt(i + 1);
                    }

                    if (exprs.Count != 2 && tokens.Count != 1)
                    {
                        throw new InvalidOperationException();
                    }

                    andOr.ForceExpression(tokens[0], exprs[0], exprs[1]);
                }
            }

            foreach (TagExpression ee in expr.SubExpressions)
            {
                ResolveAndOrConflicts(ee, state);
            }
        }
示例#6
0
        static TagToken ParsePropertyOrTag(ParserState state, TagTokenType type)
        {
            ParsePropertyOrTagInternal(state);

            return(state.CreateToken(type, state.CurrentTokenText));
        }