ClrPlus.Scripting.MsBuild.Packaging.PivotsExpression.ParseExpression C# (CSharp) Method

ParseExpression() private static method

private static ParseExpression ( Pivots.Pivot>.Dictionary pivotVsPivotValues, GetChoiceDelegate get_choice_fn, string expression ) : AstExpression
pivotVsPivotValues Pivots.Pivot>.Dictionary
get_choice_fn GetChoiceDelegate
expression string
return AstExpression
        private static AstExpression ParseExpression(Dictionary<string, Pivots.Pivot> pivotVsPivotValues,
            GetChoiceDelegate get_choice_fn, string expression)
        {
            AstExpression result = null;
            var rxResult = Pivots.ExpressionRx.Match(expression);
            if (rxResult.Success) {
                var state = ExpressionState.None;
                AstExpression current = null;
                bool invert = false;

                foreach (var item in rxResult.Groups[1].Captures.Cast<Capture>().Select(each => each.Value.Trim()).Where(each => !string.IsNullOrEmpty(each))) {
                    switch (item[0]) {
                        case '!':
                            if (result != null && state == ExpressionState.None) {
                                throw new ClrPlusException("Invalid expression. (not expression must be separated from previous expression with an operator)");
                            }
                            if (item.Length % 2 != 0)
                                invert = !invert;
                            continue;

                        case '&':
                        case ',':
                        case '\\':
                        case '/':
                            if (state != ExpressionState.None) {
                                throw new ClrPlusException("Invalid expression. (May not state two operators in a row)");
                            }
                            if (result == null) {
                                throw new ClrPlusException("Invalid expression. (may not start with an operator)");
                            }
                            state = ExpressionState.HasAnd;
                            continue;

                        case '|':
                        case '+':
                            if (state != ExpressionState.None) {
                                throw new ClrPlusException("Invalid expression. (May not state two operators in a row)");
                            }
                            if (result == null) {
                                throw new ClrPlusException("Invalid expression. (may not start with an operator)");
                            }
                            state = ExpressionState.HasOr;
                            continue;

                        case '(':
                            if (result != null && state == ExpressionState.None) {
                                throw new ClrPlusException("Invalid expression. (nested expression must be separated from previous expression with an operator)");
                            }
                            if (item.EndsWith(")")) {
                                // parse nested expression.
                                current = ParseExpression(pivotVsPivotValues, get_choice_fn, item.Substring(1, item.Length - 2));
                                break;
                            }
                            throw new ClrPlusException("Mismatched '(' in expression");

                        default:
                            if (!Pivots.WordRx.IsMatch(item)) {
                                throw new ClrPlusException("Invalid characters in expression");
                            }
                            if (result != null && state == ExpressionState.None) {
                                throw new ClrPlusException("Invalid expression. (expression must be separated from previous expression with an operator)");
                            }
                            // otherwise, it's the word we're looking for.
                            //
                            string choice;
                            string pivot;

                            if (get_choice_fn(item, out choice, out pivot)) {
                                current = new PivotExpression(pivot, choice, false);
                                break;
                            }
                            else if (item.ToLowerInvariant() == "true") {
                                current = TrueExpression.instance;
                                break;
                            }
                            else if (item.ToLowerInvariant() == "false") {
                                current = FalseExpression.instance;
                                break;
                            }

                            throw new ClrPlusException(string.Format("Unmatched configuration choice '{0}", item));
                    }

                    if (invert)
                        current = current.Invert();

                    switch (state) {
                        case ExpressionState.None:
                            result = current;
                            continue;
                        case ExpressionState.HasAnd:
                            result = new AndExpression(result, current);
                            break;
                        case ExpressionState.HasOr:
                            result = new OrExpression(result, current);
                            break;
                    }

                    current = null;
                    state = ExpressionState.None;
                }
            }

            if (result == null)
                result = TrueExpression.instance;

            return result;
        }