예제 #1
0
 private void CheckAccepting(Annotation <TOffset> ann, NullableValue <TOffset>[,] registers, TData output,
                             VariableBindings varBindings, Arc <TData, TOffset> arc, ICollection <FstResult <TData, TOffset> > curResults, int[] priorities)
 {
     if (arc.Target.IsAccepting && (!_endAnchor || ann == _data.Annotations.GetEnd(_dir)))
     {
         var matchRegisters = (NullableValue <TOffset> [, ])registers.Clone();
         ExecuteCommands(matchRegisters, arc.Target.Finishers, new NullableValue <TOffset>(), new NullableValue <TOffset>());
         if (arc.Target.AcceptInfos.Count > 0)
         {
             foreach (AcceptInfo <TData, TOffset> acceptInfo in arc.Target.AcceptInfos)
             {
                 var candidate = new FstResult <TData, TOffset>(acceptInfo.ID, matchRegisters, output.DeepClone(), varBindings.DeepClone(),
                                                                acceptInfo.Priority, arc.Target.IsLazy, ann, priorities);
                 if (acceptInfo.Acceptable == null || acceptInfo.Acceptable(_data, candidate))
                 {
                     curResults.Add(candidate);
                 }
             }
         }
         else
         {
             curResults.Add(new FstResult <TData, TOffset>(null, matchRegisters, output.DeepClone(), varBindings.DeepClone(), -1, arc.Target.IsLazy, ann,
                                                           priorities));
         }
     }
 }
예제 #2
0
        protected IEnumerable <TInst> Advance <TInst>(Annotation <TOffset> ann, NullableValue <TOffset>[,] registers, TData output, VariableBindings varBindings,
                                                      Arc <TData, TOffset> arc, ICollection <FstResult <TData, TOffset> > curResults, int[] priorities,
                                                      Func <State <TData, TOffset>, Annotation <TOffset>, NullableValue <TOffset> [, ], VariableBindings, bool, TInst> instFactory)
        {
            Annotation <TOffset> nextAnn = ann.GetNextDepthFirst(_dir, (cur, next) => !cur.Span.Overlaps(next.Span) && _filter(next));
            TOffset nextOffset           = nextAnn == _data.Annotations.GetEnd(_dir) ? _data.Annotations.GetLast(_dir, _filter).Span.GetEnd(_dir) : nextAnn.Span.GetStart(_dir);
            TOffset end          = ann.Span.GetEnd(_dir);
            var     newRegisters = (NullableValue <TOffset> [, ])registers.Clone();

            ExecuteCommands(newRegisters, arc.Commands, new NullableValue <TOffset>(nextOffset), new NullableValue <TOffset>(end));

            CheckAccepting(nextAnn, newRegisters, output, varBindings, arc, curResults, priorities);

            if (nextAnn != _data.Annotations.GetEnd(_dir))
            {
                var  anns         = new List <Annotation <TOffset> >();
                bool cloneOutputs = false;
                for (Annotation <TOffset> curAnn = nextAnn; curAnn != _data.Annotations.GetEnd(_dir) && curAnn.Span.GetStart(_dir).Equals(nextOffset); curAnn = curAnn.GetNextDepthFirst(_dir, _filter))
                {
                    if (curAnn.Optional)
                    {
                        foreach (TInst ni in Advance(curAnn, registers, output, varBindings, arc, curResults, priorities, instFactory))
                        {
                            yield return(ni);

                            cloneOutputs = true;
                        }
                    }
                    anns.Add(curAnn);
                }

                bool cloneRegisters = false;
                foreach (Annotation <TOffset> curAnn in anns)
                {
                    yield return(instFactory(arc.Target, curAnn, cloneRegisters ? (NullableValue <TOffset> [, ])newRegisters.Clone() : newRegisters,
                                             cloneOutputs ? varBindings.DeepClone() : varBindings, cloneOutputs));

                    cloneOutputs   = true;
                    cloneRegisters = true;
                }
            }
            else
            {
                yield return(instFactory(arc.Target, nextAnn, newRegisters, varBindings, false));
            }
        }
예제 #3
0
        protected IEnumerable <TInst> Initialize <TInst>(ref Annotation <TOffset> ann, NullableValue <TOffset>[,] registers,
                                                         IList <TagMapCommand> cmds, ISet <Annotation <TOffset> > initAnns, Func <State <TData, TOffset>, Annotation <TOffset>, NullableValue <TOffset> [, ], VariableBindings, TInst> instFactory)
        {
            var     insts  = new List <TInst>();
            TOffset offset = ann.Span.GetStart(_dir);

            var newRegisters = (NullableValue <TOffset> [, ])registers.Clone();

            ExecuteCommands(newRegisters, cmds, new NullableValue <TOffset>(ann.Span.GetStart(_dir)), new NullableValue <TOffset>());

            for (Annotation <TOffset> a = ann; a != _data.Annotations.GetEnd(_dir) && a.Span.GetStart(_dir).Equals(offset); a = a.GetNextDepthFirst(_dir, _filter))
            {
                if (a.Optional)
                {
                    Annotation <TOffset> nextAnn = a.GetNextDepthFirst(_dir, (cur, next) => !cur.Span.Overlaps(next.Span) && _filter(next));
                    if (nextAnn != null)
                    {
                        insts.AddRange(Initialize(ref nextAnn, registers, cmds, initAnns, instFactory));
                    }
                }
            }

            bool cloneRegisters = false;

            for (; ann != _data.Annotations.GetEnd(_dir) && ann.Span.GetStart(_dir).Equals(offset); ann = ann.GetNextDepthFirst(_dir, _filter))
            {
                if (!initAnns.Contains(ann))
                {
                    insts.Add(instFactory(_startState, ann, cloneRegisters ? (NullableValue <TOffset> [, ])newRegisters.Clone() : newRegisters, new VariableBindings()));
                    initAnns.Add(ann);
                    cloneRegisters = true;
                }
            }

            return(insts);
        }