using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Runtime.InteropServices;
using miew.Debugging;
namespace agree
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public interface IMotherDaughter
{
TfsSection[] RuleDaughters { get; }
int KeyDaughterIndex { get; }
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Caches rule daughters and arity
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public partial class MotherDaughterTfs : ArrayTfs, IMotherDaughter
{
public MotherDaughterTfs(Allocator ctrl,
TargetTfs tt,
int[] rg_feat_delete)
: base(ctrl, tt, rg_feat_delete)
{
}
unsafe public MotherDaughterTfs(Allocator ctrl,
Edge e_top,
arr_tfs_entry* _p_ate,
int c,
int next_mark,
int next_coref_mark,
int min_coref_in_mark,
bool f_restricted)
: base(ctrl, e_top, _p_ate, c, next_mark, next_coref_mark, min_coref_in_mark, f_restricted)
{
}
unsafe public MotherDaughterTfs(Allocator ctrl,
Edge e_top,
arr_tfs_entry[] rg_ate,
ushort[] hidx,
ushort[] rgn,
int next_mark,
int next_coref_mark,
bool f_restricted)
: base(ctrl, e_top, rg_ate, hidx, rgn, next_mark, next_coref_mark, f_restricted)
{
}
TfsSection[] daughters = null;
int i_key_daughter = 0;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public int KeyDaughterIndex
{
get
{
if (daughters == null)
_lazy_load_rule_daughters();
return i_key_daughter;
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public TfsSection[] RuleDaughters
{
get { return daughters ?? _lazy_load_rule_daughters(); }
}
public TfsSection[] _lazy_load_rule_daughters()
{
#if false
/// locate the daughter entry points in the expanded contents
TfsSection[] _tmp = GetSectionsFromPathToList(tm.config.RuleArgsPath).ToArray();
#else
/// locate the daughter entry points in the expanded contents
var rg_lp_edges = tm.config.parser.RuleArgsPath.GetListPathEdges(this).ToArray();
if (rg_lp_edges.Length == 0)
throw new Exception();
TfsSection[] _tmp = new TfsSection[rg_lp_edges.Length];
for (int i = 0; i < rg_lp_edges.Length; i++)
_tmp[i] = GetSection(rg_lp_edges[i], i);
#endif
/// find the first KEY daughter, i.e. the first daughter where the type at the KEY daughter path (if
/// specified) matches the KEY daughter type (if specified). In the absence of such a match, the
/// parser will default to active rightwards expansion starting at daughter index 0.
/// As noted in a comment elsewhere, the KEY daughter index remains constant for active edges derived
/// from this rule, so we don't need to redo this during parsing; instead we can just copy this value
/// over.
i_key_daughter = 0;
Type t_key = tm.tt_key_daughter;
if (!t_key.IsTop)
{
for (int i = 0; i < _tmp.Length; i++)
if (tm.config.parser.KeyDaughterPath.GetType(_tmp[i]) == t_key)
{
i_key_daughter = i;
/// If multiple daughters have KEY-ARG marked, it is not clear what to do. This
/// implementation currently elects to take the leftmost acceptable KEY:
break;
}
}
return daughters = _tmp;
}
};
}