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>(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 <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); }