internal RegexNode ReduceConcatenation()
{
// Eliminate empties and concat adjacent strings/chars
bool wasLastString;
RegexOptions optionsLast;
RegexOptions optionsAt;
int i;
int j;
if (_children == null)
return new RegexNode(Empty, _options);
wasLastString = false;
optionsLast = 0;
for (i = 0, j = 0; i < _children.Count; i++, j++)
{
RegexNode at;
RegexNode prev;
at = _children[i];
if (j < i)
_children[j] = at;
if (at._type == Concatenate &&
((at._options & RegexOptions.RightToLeft) == (_options & RegexOptions.RightToLeft)))
{
for (int k = 0; k < at._children.Count; k++)
at._children[k]._next = this;
_children.InsertRange(i + 1, at._children);
j--;
}
else if (at._type == Multi ||
at._type == One)
{
// Cannot merge strings if L or I options differ
optionsAt = at._options & (RegexOptions.RightToLeft | RegexOptions.IgnoreCase);
if (!wasLastString || optionsLast != optionsAt)
{
wasLastString = true;
optionsLast = optionsAt;
continue;
}
prev = _children[--j];
if (prev._type == One)
{
prev._type = Multi;
prev._str = Convert.ToString(prev._ch, CultureInfo.InvariantCulture);
}
if ((optionsAt & RegexOptions.RightToLeft) == 0)
{
if (at._type == One)
prev._str += at._ch.ToString();
else
prev._str += at._str;
}
else
{
if (at._type == One)
prev._str = at._ch.ToString() + prev._str;
else
prev._str = at._str + prev._str;
}
}
else if (at._type == Empty)
{
j--;
}
else
{
wasLastString = false;
}
}
if (j < i)
_children.RemoveRange(j, i - j);
return StripEnation(Empty);
}