示例#1
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));
            }
        }
        protected IEnumerable <TInst> Initialize(ref int annIndex, Register <TOffset>[,] registers,
                                                 IList <TagMapCommand> cmds, ISet <int> initAnns)
        {
            var     insts  = new List <TInst>();
            TOffset offset = _annotations[annIndex].Span.GetStart(_fst.Direction);

            if (_startAnchor)
            {
                for (int i = annIndex; i < _annotations.Count && _annotations[i].Span.GetStart(_fst.Direction).Equals(offset); i++)
                {
                    if (_annotations[i].Optional)
                    {
                        int nextIndex = GetNextNonoverlappingAnnotationIndex(i);
                        if (nextIndex != _annotations.Count)
                        {
                            insts.AddRange(Initialize(ref nextIndex, (Register <TOffset> [, ])registers.Clone(), cmds, initAnns));
                        }
                    }
                }
            }

            ExecuteCommands(registers, cmds, new Register <TOffset>(offset, true), new Register <TOffset>());

            for (; annIndex < _annotations.Count && _annotations[annIndex].Span.GetStart(_fst.Direction).Equals(offset); annIndex++)
            {
                if (!initAnns.Contains(annIndex))
                {
                    TInst inst = GetCachedInstance();
                    inst.State           = _fst.StartState;
                    inst.AnnotationIndex = annIndex;
                    Array.Copy(registers, inst.Registers, registers.Length);
                    if (!_fst.IgnoreVariables)
                    {
                        inst.VariableBindings = _varBindings != null?_varBindings.DeepClone() : new VariableBindings();
                    }
                    insts.Add(inst);
                    initAnns.Add(annIndex);
                }
            }

            return(insts);
        }
示例#3
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));
         }
     }
 }
        protected IEnumerable <TInst> Advance(TInst inst, VariableBindings varBindings, Arc <TData, TOffset> arc, ICollection <FstResult <TData, TOffset> > curResults, bool optional = false)
        {
            if (inst.Priorities != null)
            {
                inst.Priorities.Add(arc.Priority);
            }
            int     nextIndex = GetNextNonoverlappingAnnotationIndex(inst.AnnotationIndex);
            TOffset nextOffset;
            bool    nextStart;

            if (nextIndex < _annotations.Count)
            {
                nextOffset = _annotations[nextIndex].Span.GetStart(_fst.Direction);
                nextStart  = true;
            }
            else
            {
                nextOffset = _data.Annotations.GetLast(_fst.Direction, _fst.Filter).Span.GetEnd(_fst.Direction);
                nextStart  = false;
            }
            TOffset end = _annotations[inst.AnnotationIndex].Span.GetEnd(_fst.Direction);

            if (nextIndex < _annotations.Count)
            {
                var  anns         = new List <int>();
                bool cloneOutputs = false;
                for (int i = nextIndex; i < _annotations.Count && _annotations[i].Span.GetStart(_fst.Direction).Equals(nextOffset); i++)
                {
                    if (_annotations[i].Optional)
                    {
                        TInst ti = CopyInstance(inst);
                        ti.AnnotationIndex = i;
                        foreach (TInst ni in Advance(ti, varBindings, arc, curResults, true))
                        {
                            yield return(ni);

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

                ExecuteCommands(inst.Registers, arc.Commands, new Register <TOffset>(nextOffset, nextStart), new Register <TOffset>(end, false));
                if (!optional || _endAnchor)
                {
                    CheckAccepting(nextIndex, inst.Registers, inst.Output, varBindings, arc, curResults, inst.Priorities);
                }

                inst.State = arc.Target;

                bool first = true;
                foreach (int curIndex in anns)
                {
                    TInst ni = first ? inst : CopyInstance(inst);
                    ni.AnnotationIndex = curIndex;
                    if (varBindings != null)
                    {
                        inst.VariableBindings = cloneOutputs ? varBindings.DeepClone() : varBindings;
                    }
                    yield return(ni);

                    cloneOutputs = true;
                    first        = false;
                }
            }
            else
            {
                ExecuteCommands(inst.Registers, arc.Commands, new Register <TOffset>(nextOffset, nextStart), new Register <TOffset>(end, false));
                CheckAccepting(nextIndex, inst.Registers, inst.Output, varBindings, arc, curResults, inst.Priorities);

                inst.State            = arc.Target;
                inst.AnnotationIndex  = nextIndex;
                inst.VariableBindings = varBindings;
                yield return(inst);
            }
        }
        private void CheckAccepting(int annIndex, Register <TOffset>[,] registers, TData output,
                                    VariableBindings varBindings, Arc <TData, TOffset> arc, ICollection <FstResult <TData, TOffset> > curResults, IList <int> priorities)
        {
            if (arc.Target.IsAccepting && (!_endAnchor || annIndex == _annotations.Count))
            {
                Annotation <TOffset> ann = annIndex < _annotations.Count ? _annotations[annIndex] : _data.Annotations.GetEnd(_fst.Direction);
                var matchRegisters       = (Register <TOffset> [, ])registers.Clone();
                ExecuteCommands(matchRegisters, arc.Target.Finishers, new Register <TOffset>(), new Register <TOffset>());
                if (arc.Target.AcceptInfos.Count > 0)
                {
                    foreach (AcceptInfo <TData, TOffset> acceptInfo in arc.Target.AcceptInfos)
                    {
                        TData resOutput = output;
                        var   cloneable = resOutput as IDeepCloneable <TData>;
                        if (cloneable != null)
                        {
                            resOutput = cloneable.DeepClone();
                        }

                        var candidate = new FstResult <TData, TOffset>(_fst.RegistersEqualityComparer, acceptInfo.ID, matchRegisters, resOutput,
                                                                       varBindings == null ? null : varBindings.DeepClone(), acceptInfo.Priority, arc.Target.IsLazy, ann,
                                                                       priorities == null ? null : priorities.ToArray(), curResults.Count);
                        if (acceptInfo.Acceptable == null || acceptInfo.Acceptable(_data, candidate))
                        {
                            curResults.Add(candidate);
                        }
                    }
                }
                else
                {
                    TData resOutput = output;
                    var   cloneable = resOutput as IDeepCloneable <TData>;
                    if (cloneable != null)
                    {
                        resOutput = cloneable.DeepClone();
                    }
                    curResults.Add(new FstResult <TData, TOffset>(_fst.RegistersEqualityComparer, null, matchRegisters, resOutput,
                                                                  varBindings == null ? null : varBindings.DeepClone(), -1, arc.Target.IsLazy, ann,
                                                                  priorities == null ? null : priorities.ToArray(), curResults.Count));
                }
            }
        }