Exemplo n.º 1
0
        private static IBooleanExpression BuildTree(List <BooleanExpressionToken> tokens)
        {
            BooleanExpressionGroup defaultGroup = new BooleanExpressionGroup();

            bool not = false;

            for (int i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];

                if (token.Type == BooleanExpressionTokenType.GroupClose ||
                    (defaultGroup.Operands.Count == 0 && (token.Type == BooleanExpressionTokenType.And || token.Type == BooleanExpressionTokenType.Or)) ||
                    (i == tokens.Count - 1 && (token.Type == BooleanExpressionTokenType.And || token.Type == BooleanExpressionTokenType.Or)))
                {
                    throw new ArgumentException("Unexpected token '" + token.Value + "'");
                }

                if (token.Type == BooleanExpressionTokenType.GroupOpen)
                {
                    int numOpen = 1;
                    List <BooleanExpressionToken> groupedExpression = new List <BooleanExpressionToken>();
                    for (int j = i + 1; j < tokens.Count; j++)
                    {
                        var innerToken = tokens[j];
                        if (innerToken.Type == BooleanExpressionTokenType.GroupClose && numOpen == 1)
                        {
                            numOpen = 0;
                            i       = j;
                            break;
                        }
                        else if (innerToken.Type == BooleanExpressionTokenType.GroupClose)
                        {
                            numOpen--;
                        }
                        else if (innerToken.Type == BooleanExpressionTokenType.GroupOpen)
                        {
                            numOpen++;
                        }

                        groupedExpression.Add(innerToken);
                    }

                    if (numOpen > 0)
                    {
                        throw new ArgumentException("You are missing at least 1 closing parenthesis");
                    }

                    if (groupedExpression.Count == 0)
                    {
                        throw new ArgumentException("You have an empty set of parenthesis");
                    }

                    var group = BuildTree(groupedExpression);
                    group.Not = not;
                    defaultGroup.Operands.Add(group);
                    not = false;
                }
                else if (token.Type == BooleanExpressionTokenType.Variable)
                {
                    if (defaultGroup.Operands.Count != defaultGroup.Operators.Count)
                    {
                        throw new ArgumentException("Expected an operator, got variable: " + token.Value);
                    }

                    defaultGroup.Operands.Add(new BooleanVariable()
                    {
                        VariableName = token.Value, Not = not
                    });
                    not = false;
                }
                else if (token.Type == BooleanExpressionTokenType.And || token.Type == BooleanExpressionTokenType.Or)
                {
                    if (not)
                    {
                        throw new ArgumentException("You cannot have an operator '&' or '|' after a '!'");
                    }

                    if (defaultGroup.Operators.Count >= defaultGroup.Operands.Count)
                    {
                        throw new ArgumentException("You cannot have two consecutive operators '&&' or '||', use '&' or '|'");
                    }
                    defaultGroup.Operators.Add((BooleanOperator)token.Type);
                }
                else if (token.Type == BooleanExpressionTokenType.Not)
                {
                    if (not)
                    {
                        throw new ArgumentException("You cannot have two consecutive '!' operators");
                    }
                    else
                    {
                        not = true;
                    }
                }
                else
                {
                    throw new ArgumentException("Unexpected token '" + token.Value + "'");
                }
            }

            if (not == true)
            {
                throw new ArgumentException("Unexpected token '!' at end of expression");
            }

            if (defaultGroup.Operands.Count == 1)
            {
                return(defaultGroup.Operands[0]);
            }
            else
            {
                return(defaultGroup);
            }
        }
        private static IBooleanExpression BuildTree(List<BooleanExpressionToken> tokens)
        {
            BooleanExpressionGroup defaultGroup = new BooleanExpressionGroup();

            bool not = false;

            for (int i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];

                if (token.Type == BooleanExpressionTokenType.GroupClose ||
                    (defaultGroup.Operands.Count == 0 && (token.Type == BooleanExpressionTokenType.And || token.Type == BooleanExpressionTokenType.Or)) ||
                    (i == tokens.Count - 1 && (token.Type == BooleanExpressionTokenType.And || token.Type == BooleanExpressionTokenType.Or)))
                {
                    throw new ArgumentException("Unexpected token '" + token.Value + "'");
                }

                if (token.Type == BooleanExpressionTokenType.GroupOpen)
                {
                    int numOpen = 1;
                    List<BooleanExpressionToken> groupedExpression = new List<BooleanExpressionToken>();
                    for (int j = i + 1; j < tokens.Count; j++)
                    {
                        var innerToken = tokens[j];
                        if (innerToken.Type == BooleanExpressionTokenType.GroupClose && numOpen == 1)
                        {
                            numOpen = 0;
                            i = j;
                            break;
                        }
                        else if (innerToken.Type == BooleanExpressionTokenType.GroupClose)
                        {
                            numOpen--;
                        }
                        else if (innerToken.Type == BooleanExpressionTokenType.GroupOpen)
                        {
                            numOpen++;
                        }

                        groupedExpression.Add(innerToken);
                    }

                    if (numOpen > 0)
                    {
                        throw new ArgumentException("You are missing at least 1 closing parenthesis");
                    }

                    if (groupedExpression.Count == 0)
                    {
                        throw new ArgumentException("You have an empty set of parenthesis");
                    }

                    var group = BuildTree(groupedExpression);
                    group.Not = not;
                    defaultGroup.Operands.Add(group);
                    not = false;
                }
                else if (token.Type == BooleanExpressionTokenType.Variable)
                {
                    if(defaultGroup.Operands.Count != defaultGroup.Operators.Count)
                    {
                        throw new ArgumentException("Expected an operator, got variable: "+token.Value);
                    }

                    defaultGroup.Operands.Add(new BooleanVariable() { VariableName = token.Value, Not = not });
                    not = false;
                }
                else if (token.Type == BooleanExpressionTokenType.And || token.Type == BooleanExpressionTokenType.Or)
                {
                    if(not)
                    {
                        throw new ArgumentException("You cannot have an operator '&' or '|' after a '!'");
                    }

                    if (defaultGroup.Operators.Count >= defaultGroup.Operands.Count)
                    {
                        throw new ArgumentException("You cannot have two consecutive operators '&&' or '||', use '&' or '|'");
                    }
                    defaultGroup.Operators.Add((BooleanOperator)token.Type);
                }
                else if(token.Type == BooleanExpressionTokenType.Not)
                {
                    if (not)
                    {
                        throw new ArgumentException("You cannot have two consecutive '!' operators");
                    }
                    else
                    {
                        not = true;
                    }
                }
                else
                {
                    throw new ArgumentException("Unexpected token '" + token.Value + "'");
                }
            }

            if(not == true)
            {
                throw new ArgumentException("Unexpected token '!' at end of expression");
            }

            if (defaultGroup.Operands.Count == 1)
            {
                return defaultGroup.Operands[0];
            }
            else
            {
                return defaultGroup;
            }
        }