private void CalculateFC(int NodeType, RegexNode node, int CurIndex)
{
bool ci = false;
bool rtl = false;
if (NodeType <= RegexNode.Ref)
{
if ((node._options & RegexOptions.IgnoreCase) != 0)
ci = true;
if ((node._options & RegexOptions.RightToLeft) != 0)
rtl = true;
}
switch (NodeType)
{
case RegexNode.Concatenate | BeforeChild:
case RegexNode.Alternate | BeforeChild:
case RegexNode.Testref | BeforeChild:
case RegexNode.Loop | BeforeChild:
case RegexNode.Lazyloop | BeforeChild:
break;
case RegexNode.Testgroup | BeforeChild:
if (CurIndex == 0)
SkipChild();
break;
case RegexNode.Empty:
PushFC(new RegexFC(true));
break;
case RegexNode.Concatenate | AfterChild:
if (CurIndex != 0)
{
RegexFC child = PopFC();
RegexFC cumul = TopFC();
_failed = !cumul.AddFC(child, true);
}
if (!TopFC()._nullable)
_skipAllChildren = true;
break;
case RegexNode.Testgroup | AfterChild:
if (CurIndex > 1)
{
RegexFC child = PopFC();
RegexFC cumul = TopFC();
_failed = !cumul.AddFC(child, false);
}
break;
case RegexNode.Alternate | AfterChild:
case RegexNode.Testref | AfterChild:
if (CurIndex != 0)
{
RegexFC child = PopFC();
RegexFC cumul = TopFC();
_failed = !cumul.AddFC(child, false);
}
break;
case RegexNode.Loop | AfterChild:
case RegexNode.Lazyloop | AfterChild:
if (node._m == 0)
TopFC()._nullable = true;
break;
case RegexNode.Group | BeforeChild:
case RegexNode.Group | AfterChild:
case RegexNode.Capture | BeforeChild:
case RegexNode.Capture | AfterChild:
case RegexNode.Greedy | BeforeChild:
case RegexNode.Greedy | AfterChild:
break;
case RegexNode.Require | BeforeChild:
case RegexNode.Prevent | BeforeChild:
SkipChild();
PushFC(new RegexFC(true));
break;
case RegexNode.Require | AfterChild:
case RegexNode.Prevent | AfterChild:
break;
case RegexNode.One:
case RegexNode.Notone:
PushFC(new RegexFC(node._ch, NodeType == RegexNode.Notone, false, ci));
break;
case RegexNode.Oneloop:
case RegexNode.Onelazy:
PushFC(new RegexFC(node._ch, false, node._m == 0, ci));
break;
case RegexNode.Notoneloop:
case RegexNode.Notonelazy:
PushFC(new RegexFC(node._ch, true, node._m == 0, ci));
break;
case RegexNode.Multi:
if (node._str.Length == 0)
PushFC(new RegexFC(true));
else if (!rtl)
PushFC(new RegexFC(node._str[0], false, false, ci));
else
PushFC(new RegexFC(node._str[node._str.Length - 1], false, false, ci));
break;
case RegexNode.Set:
PushFC(new RegexFC(node._str, false, ci));
break;
case RegexNode.Setloop:
case RegexNode.Setlazy:
PushFC(new RegexFC(node._str, node._m == 0, ci));
break;
case RegexNode.Ref:
PushFC(new RegexFC(RegexCharClass.AnyClass, true, false));
break;
case RegexNode.Nothing:
case RegexNode.Bol:
case RegexNode.Eol:
case RegexNode.Boundary:
case RegexNode.Nonboundary:
case RegexNode.ECMABoundary:
case RegexNode.NonECMABoundary:
case RegexNode.Beginning:
case RegexNode.Start:
case RegexNode.EndZ:
case RegexNode.End:
PushFC(new RegexFC(true));
break;
default:
throw new ArgumentException(SR.Format(SR.UnexpectedOpcode, NodeType.ToString(CultureInfo.CurrentCulture)));
}
}