public INfaVM Visit(RepeatNode node, INfaVM code) { for (int i = node.MinCount; i != 0; --i) { node.Inner.Accept(this, code); } if (node.MaxCount == int.MaxValue) { var start = code.Labels.Generate(); var end = code.Labels.Generate(); code.Label(start); code.Fork(end.GetRef()); node.Inner.Accept(this, code); code.Jmp(start.GetRef()); code.Label(end); } else { int optionalCount = node.MaxCount - node.MinCount; while (optionalCount-- != 0) { var end = code.Labels.Generate(); code.Fork(end.GetRef()); node.Inner.Accept(this, code); code.Label(end); } } return(code); }
public TextWriter Visit(RepeatNode node) { NewLine(); writer.Write("repeat from={0} to={1}:", node.MinCount, node.MaxCount); IncreaseIndent(); try { node.Inner.Accept(this); } finally { DecreaseIndent(); } return(writer); }
public NfaFragment Visit(RepeatNode node) { // TODO: Replace Range with repeat IEnumerable <NfaFragment> required = Enumerable .Range(0, node.MinCount) .Select(_ => Build(node.Inner)); IEnumerable <NfaFragment> optional; if (node.MaxCount != int.MaxValue) { optional = Enumerable .Range(0, node.MaxCount - node.MinCount) .Select(_ => NfaFragment.ZeroOrOne(Build(node.Inner))); } else { optional = new [] { NfaFragment.ZeroOrMore(Build(node.Inner)) }; } return(NfaFragment.Cat(required.Concat(optional))); }