private static IList <RowRegexExprNode> ExpandRepeat(RowRegexExprNode node, RowRegexExprRepeatDesc repeat, RegexNFATypeEnum type, RowRegexExprNodeCopier copier) { var evaluateParams = new EvaluateParams(null, true, null); // handle single-bounds (no ranges) IList <RowRegexExprNode> repeated = new List <RowRegexExprNode>(); if (repeat.Single != null) { ValidateExpression(repeat.Single); int numRepeated = repeat.Single.ExprEvaluator.Evaluate(evaluateParams).AsInt(); ValidateRange(numRepeated, 1, int.MaxValue); for (var i = 0; i < numRepeated; i++) { var copy = copier.Copy(node, type); repeated.Add(copy); } return(repeated); } // evaluate bounds int?lower = null; int?upper = null; if (repeat.Lower != null) { ValidateExpression(repeat.Lower); lower = (int?)repeat.Lower.ExprEvaluator.Evaluate(evaluateParams); } if (repeat.Upper != null) { ValidateExpression(repeat.Upper); upper = (int?)repeat.Upper.ExprEvaluator.Evaluate(evaluateParams); } // handle range if (lower != null && upper != null) { ValidateRange(lower.Value, 1, int.MaxValue); ValidateRange(upper.Value, 1, int.MaxValue); ValidateRange(lower.Value, 1, upper.Value); for (var i = 0; i < lower; i++) { var copy = copier.Copy(node, type); repeated.Add(copy); } for (int i = lower.Value; i < upper; i++) { // make type optional var newType = type; if (type == RegexNFATypeEnum.SINGLE) { newType = RegexNFATypeEnum.ONE_OPTIONAL; } else if (type == RegexNFATypeEnum.ONE_TO_MANY) { newType = RegexNFATypeEnum.ZERO_TO_MANY; } else if (type == RegexNFATypeEnum.ONE_TO_MANY_RELUCTANT) { newType = RegexNFATypeEnum.ZERO_TO_MANY_RELUCTANT; } var copy = copier.Copy(node, newType); repeated.Add(copy); } return(repeated); } // handle lower-bounds only if (upper == null) { ValidateRange(lower.Value, 1, int.MaxValue); for (var i = 0; i < lower; i++) { var copyInner = copier.Copy(node, type); repeated.Add(copyInner); } // make type optional var newType = type; if (type == RegexNFATypeEnum.SINGLE) { newType = RegexNFATypeEnum.ZERO_TO_MANY; } else if (type == RegexNFATypeEnum.ONE_OPTIONAL) { newType = RegexNFATypeEnum.ZERO_TO_MANY; } else if (type == RegexNFATypeEnum.ONE_OPTIONAL_RELUCTANT) { newType = RegexNFATypeEnum.ZERO_TO_MANY_RELUCTANT; } else if (type == RegexNFATypeEnum.ONE_TO_MANY) { newType = RegexNFATypeEnum.ZERO_TO_MANY; } else if (type == RegexNFATypeEnum.ONE_TO_MANY_RELUCTANT) { newType = RegexNFATypeEnum.ZERO_TO_MANY_RELUCTANT; } var copy = copier.Copy(node, newType); repeated.Add(copy); return(repeated); } // handle upper-bounds only ValidateRange(upper.Value, 1, int.MaxValue); for (var i = 0; i < upper; i++) { // make type optional var newType = type; if (type == RegexNFATypeEnum.SINGLE) { newType = RegexNFATypeEnum.ONE_OPTIONAL; } else if (type == RegexNFATypeEnum.ONE_TO_MANY) { newType = RegexNFATypeEnum.ZERO_TO_MANY; } else if (type == RegexNFATypeEnum.ONE_TO_MANY_RELUCTANT) { newType = RegexNFATypeEnum.ZERO_TO_MANY_RELUCTANT; } var copy = copier.Copy(node, newType); repeated.Add(copy); } return(repeated); }
/// <summary> /// Ctor. /// </summary> /// <param name="type">multiplicity and greedy</param> public RowRegexExprNodeNested(RegexNFATypeEnum type, RowRegexExprRepeatDesc optionalRepeat) { NFAType = type; OptionalRepeat = optionalRepeat; }
/// <summary> /// Ctor. /// </summary> /// <param name="tag">variable name</param> /// <param name="type">multiplicity and greedy indicator</param> /// <param name="optionalRepeat">optional repeating information</param> public RowRegexExprNodeAtom(String tag, RegexNFATypeEnum type, RowRegexExprRepeatDesc optionalRepeat) { Tag = tag; NFAType = type; OptionalRepeat = optionalRepeat; }