Beispiel #1
0
        private static GrammarNode <T> GetInnerNode(GrammarNode <T> grammarNode, ref RepetitionRange range, Boolean isLazy)
        {
            if (grammarNode is Repetition <T> repetition && repetition.IsLazy == isLazy)
            {
                /* expr{α}{β} ≡ expr{α·β} */
                if (repetition.Range.IsSingleElement && range.IsSingleElement)
                {
                    var reps = repetition.Range.Minimum * range.Minimum;
                    range = new RepetitionRange(reps, reps);
                    return(repetition.InnerNode);
                }

                /* expr{a, b}{c, d} ≡ expr{a·c, b·d} IF b·c ≥ a·(c + 1) - 1
                 * Basically checks if each occurrence of the range [n·a, n·b] where n ∈ [c, d]
                 * overlaps with each other.
                 * If it does, we then just get the range of [a·c, b·d] (the union of all
                 * occurrences of the range on the previous sentence) instead of nesting the repetitions.
                 */
                if (repetition.Range.IsFinite &&
                    range.IsFinite &&
                    repetition.Range.Maximum * range.Minimum >= repetition.Range.Minimum * (range.Minimum + 1) - 1)
                {
                    range = new RepetitionRange(
                        SaturatingMath.Multiply(repetition.Range.Minimum, range.Minimum),
                        SaturatingMath.Multiply(repetition.Range.Maximum !.Value, range.Maximum !.Value));
                    return(repetition.InnerNode);
                }
            }

            return(grammarNode);
        }
Beispiel #2
0
 /// <summary>
 /// Creates a new repetition node
 /// </summary>
 /// <param name="grammarNode"></param>
 /// <param name="range"></param>
 /// <param name="isLazy"></param>
 public Repetition(GrammarNode <T> grammarNode, RepetitionRange range, Boolean isLazy)
     : base(GetInnerNode(grammarNode, ref range, isLazy))
 {
     this.Range  = range;
     this.IsLazy = isLazy;
 }