public ConditionalExpr(string attr, string @operator, List<string> values, BlockExpr trueExpr, BlockExpr falseExpr) { Attr = attr; Operator = @operator; Values = values; TrueExpr = trueExpr; FalseExpr = falseExpr; }
public BlockExpr Build(Node<NodeType> root) { var blockExpr = new BlockExpr(); Build(blockExpr, root); return blockExpr; }
private static void AddExpressions(BlockExpr blockExpr, Expression helperExpression, List<Expression> expressions) { if (blockExpr == null) { return; } foreach (ExprBase expr in blockExpr.Exprs) { TextExpr textExpr = expr as TextExpr; ConditionalExpr conditionalExpr = expr as ConditionalExpr; AttrExpr attrExpr = expr as AttrExpr; if (textExpr != null) { var methodInfo = typeof(Helper).GetMethod("AddText", new[] { typeof(string) }); expressions.Add(Expression.Call(helperExpression, methodInfo, Expression.Constant(textExpr.Text))); } else if (conditionalExpr != null) { List<Expression> trueExpressions = new List<Expression>(); List<Expression> falseExpressions = new List<Expression>(); AddExpressions(conditionalExpr.TrueExpr, helperExpression, trueExpressions); AddExpressions(conditionalExpr.FalseExpr, helperExpression, falseExpressions); Expression conditionExpression = null; if (conditionalExpr.Values.Count == 1 && conditionalExpr.Values[0] == null) { MethodInfo operatorMethod = typeof(Helper).GetMethod(conditionalExpr.Operator == "=" ? "IsNull" : "IsNotNull", new[] { typeof(string) }); Expression[] paramExpressions = { Expression.Constant(conditionalExpr.Attr) }; conditionExpression = Expression.Call(helperExpression, operatorMethod, paramExpressions); } else { MethodInfo operatorMethod = typeof(Helper).GetMethod(conditionalExpr.Operator == "=" ? "IsEqualTo" : "IsNotEqualTo", new[] { typeof(string), typeof(string) }); foreach (string value in conditionalExpr.Values) { Expression[] paramExpressions = { Expression.Constant(conditionalExpr.Attr), Expression.Constant(value) }; if (conditionExpression == null) { conditionExpression = Expression.Call(helperExpression, operatorMethod, paramExpressions); } else { conditionExpression = conditionalExpr.Operator == "=" ? Expression.Or(conditionExpression, Expression.Call(helperExpression, operatorMethod, paramExpressions)) : Expression.And(conditionExpression, Expression.Call(helperExpression, operatorMethod, paramExpressions)); } } } if (conditionalExpr.FalseExpr == null) { expressions.Add(Expression.IfThen(conditionExpression , Expression.Block(trueExpressions))); } else { expressions.Add(Expression.IfThenElse(conditionExpression , Expression.Block(trueExpressions) , Expression.Block(falseExpressions))); } } else if (attrExpr != null) { var addAttrMethod = typeof(Helper).GetMethod("AddAttr", new[] { typeof(string), typeof(string) }); expressions.Add(Expression.Call(helperExpression, addAttrMethod, Expression.Constant(attrExpr.Name), Expression.Constant(attrExpr.Regex, typeof(string)))); } } }
public BlockExpr Build(BlockExpr blockExpr, Node<NodeType> parent, string name = "") { foreach (var child in parent.Nodes) { if (child.NodeType == NodeType.Text) { blockExpr.Exprs.Add(new TextExpr(child.Text)); } else if (child.NodeType == NodeType.Dollar) { blockExpr.Exprs.Add(new AttrExpr(name, "")); } else if (child.NodeType == NodeType.SubExpr) { var attr = child.Nodes.Single(x => x.NodeType == NodeType.Identifier).Text; var regexNode = child.Nodes.SingleOrDefault(x => x.NodeType == NodeType.Regex); string regex = null; if (regexNode != null) { regex = regexNode.Nodes[0].Text; } var @operator = child.Nodes.SingleOrDefault(x => x.NodeType == NodeType.Equals) != null ? "=" : "!="; var valuesNode = child .Nodes .SingleOrDefault(x => x.NodeType == NodeType.Values); var values = valuesNode?.Nodes.Select(x => x.Text).ToList() ?? new List<string> { null }; BlockExpr thenExpr; BlockExpr elseExpr = null; var then = child.Nodes.SingleOrDefault(x => x.NodeType == NodeType.Then); thenExpr = new BlockExpr(); if (then != null) { Build(thenExpr, then, attr); var @else = then.Nodes.SingleOrDefault(x => x.NodeType == NodeType.Else); if (@else != null) { elseExpr = new BlockExpr(); Build(elseExpr, @else, attr); } } else { thenExpr.Exprs.Add(new AttrExpr(attr, regex)); } blockExpr.Exprs.Add(new ConditionalExpr(attr, @operator, values, thenExpr, elseExpr)); } else if (child.NodeType == NodeType.Else) { } else { throw new Exception(); } } return blockExpr; }