예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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)));
        }