using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using miew.ReadOnly;
using miew.Enumerable;
using miew.Debugging;
using miew.BitArray;
namespace agree
{
public abstract partial class PassiveEdge : ArrayTfs, IParseObj
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// </summary>
/// <remarks>
/// initial lexical edges are now directly (polymorphically) introduced into the chart as AnalysisStack objects via
/// their implementation of the IParseObj interface
/// </remarks>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[DebuggerDisplay("{ToString(),nq}")]
public partial class Derived : PassiveEdge
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
ParseObjs rgo;
public Derived(ParseControl ctrl, GrammarRule rule, Tfs tfs, ref ParseObjs rgo)
: base(ctrl, rgo.Span, rule, tfs)
{
this.rgo = rgo;
// this.m_dseq = -1;
ctrl.stats.Parsing.Chart.PassiveEdge();
}
// public int m_dseq;
// public static int qc = 0;
#if false
public void DirectCancel()
{
int _tmp = ctrl.chart.g_dseq;
if (Interlocked.Exchange(ref m_dseq, _tmp) == _tmp)
return;
for (int j = 0; j < rgo.Count; j++)
{
Derived dtr = rgo[j] as Derived;
if (dtr != null)
{
if (dtr.IsHold())
dtr.DirectCancel();
else if (!dtr.IsRemove())
continue;
this.s_state = SequenceControl.REMOVE;
Interlocked.Increment(ref qc);
break;
}
}
}
#endif
public ParseObjs ChartDaughters { get { return rgo; } }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public IEnumerable<IParseObj> Descendants
{
get
{
Derived dpe;
foreach (IParseObj ipce in rgo)
{
yield return ipce;
if ((dpe = ipce as Derived) != null)
foreach (IParseObj ipce_d in dpe.Descendants)
yield return ipce_d;
}
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public IEnumerable<IParseObj> DescendantsAndSelf
{
get
{
yield return this;
foreach (IParseObj ipce in Descendants)
yield return ipce;
}
}
/// <summary>
/// when initiated with 'i_arg==0', enumerates the fixed-arity cross product of the packed trees
/// across each of this edge's chart daughters
/// </summary>
IEnumerable<IEnumerable<IDerivation>> _rightwards(int i_arg)
{
Debug.Assert(!this.IsRemove());
IParseObj unary = rgo[i_arg];
Debug.Assert(unary.IsActive());
foreach (var d in unary.Derivations)
{
if (i_arg == rgo.Count - 1)
yield return new IDerivation[] { d };
else
{
IParseObj po = rgo[i_arg + 1];
if (po.IsActive())
foreach (var tree_xp in _rightwards(i_arg + 1))
yield return tree_xp.Prepend(d);
}
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
IEnumerable<IDerivation> _packed_trees
{
get
{
Debug.Assert(!this.IsRemove());
/// trees postulated by the cross product of this item's daughters...
if (rgo[0].IsActive())
{
if (rgo.Count == 1)
foreach (var e in rgo[0].Derivations)
yield return new ParseTree(this.ctrl, this, new IDerivation[] { e });
else
foreach (var e in _rightwards(0))
yield return new ParseTree(this.ctrl, this, e);
}
/// ...plus subsumed structures packed into this item itself (and their subsumptions...)
if (this.IsActive())
foreach (var e in _peer_packed())
yield return e;
}
}
static public readonly IDerivation[] NoDerivations = new IDerivation[0];
/// <summary>
/// exhaustive unpacking of trees which are packed into this item with thread-safe cache
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
IDerivation[] _parse_trees = null;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public override IList<IDerivation> Derivations
{
get
{
Debug.Assert(!this.IsRemove());
Debug.Assert(ctrl.f_parse_phase_complete);
IDerivation[] _tmp;
return _parse_trees ??
Interlocked.CompareExchange(ref _parse_trees, _tmp = _packed_trees.ToArray(), null) ??
_tmp;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public override string ToString()
{
return String.Format("{0} {1}", TokenSpan, base.ToString());
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// a derived passive chart edge which has been matched against one or more start symbols
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class Completed : Derived
{
static bool[][] singleton_maps;
static bool[] GetSingletonMap(ParseControl ctrl, int i_ss)
{
if (singleton_maps == null)
Interlocked.CompareExchange(ref singleton_maps, new bool[ctrl.g.StartSymbols.Length][], null);
bool[] _tmp = singleton_maps[i_ss];
if (_tmp == null)
{
_tmp = new bool[i_ss + 1];
_tmp[i_ss] = true;
singleton_maps[i_ss] = _tmp;
}
return _tmp;
}
readonly bool[] start_symbol_map;
public Completed(ParseControl ctrl,
GrammarRule rule,
Tfs tfs,
bool[] rgss_map,
ref ParseObjs rgo)
: base(ctrl, rule, tfs, ref rgo)
{
this.start_symbol_map = rgss_map;
ctrl.chart._completed_edges.Add(this);
ctrl.stats.Parsing.Chart.RootEdge();
}
public Completed(ParseControl ctrl,
GrammarRule rule,
Tfs tfs,
int i_ss,
ref ParseObjs rgo)
: this(ctrl, rule, tfs, GetSingletonMap(ctrl, i_ss), ref rgo)
{
}
public bool[] MatchedStartSymbolsMap { get { return start_symbol_map; } }
public IEnumerable<StartSymbol> MatchedStartSymbols
{
get
{
for (int i = 0; i < start_symbol_map.Length; i++)
if (start_symbol_map[i])
yield return ctrl.g.StartSymbols[i];
}
}
public new String SysObjName
{
get { return String.Format("parse{0}", i_seq >> 1); }
}
public new ISysObj SysObjParent
{
get { return ctrl; }
}
public new IReadOnlyDictionary<string, ISysObj> SysObjChildren
{
get { return SysObjHelper<ISysObj>.Empty; }
}
//public string SysObjDescription
//{
// get { return String.Format("{0} ({1})", License != null ? License.SysObjName : "null license", start_symbol.SysObjName); }
//}
}
};
}