コード例 #1
0
        static void AddAndOr(TagExpression tagExpression, List <TagToken> tokens, List <TagExpression> exprs)
        {
            AndOrExpression andOr = tagExpression as AndOrExpression;

            if (andOr != null)
            {
                AddAndOr(andOr.LeftHand, tokens, exprs);
                tokens.Add(andOr.Token);
                AddAndOr(andOr.RightHand, tokens, exprs);
            }
            else
            {
                exprs.Add(tagExpression);
            }
        }
コード例 #2
0
        internal static TagExpression CompleteExpression(ParserState state)
        {
            TagExpression expr = Expr(state);

            while (state.PeekTokenType() != TagTokenType.AtEof)
            {
                TagToken tk = state.NextToken();
                switch (tk.TokenType)
                {
                case TagTokenType.Or:
                    expr = new AndOrExpression(tk, expr, BooleanExpression(state));
                    break;

                case TagTokenType.And:
                    expr = new AndOrExpression(tk, expr, BooleanExpression(state));
                    break;

                default:
                    throw new ParserException(string.Format("Unexpected token {0}", tk), tk, state);
                }
            }

            return(expr);
        }
コード例 #3
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);
            }
        }