using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using miew.Enumerable;
using miew.String;
namespace agree
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class GrammarNodeLabeler
{
NodeLabelTemplate[] label_templates;
NodeMetaTemplate[] meta_templates;
NodeLabelTemplate[] local_label_templates;
Config.NodeLabels nlc;
Grammar g;
TypeMgr tm;
public GrammarNodeLabeler(Grammar g, Config.NodeLabels nlc, IEnumerable<NodeLabelTemplate> labels, IEnumerable<NodeMetaTemplate> metas)
{
this.g = g;
this.tm = g.tm;
this.nlc = nlc;
label_templates = labels.ToArray();
meta_templates = metas.ToArray();
local_label_templates = labels.Where(nlt => nlt.effective_local != null).ToArray();
}
public String FindLabel(Tfs pe)
{
foreach (NodeLabelTemplate nlt in label_templates)
{
Tfs tfs;
if (nlc.LabelFsPath != null && nlc.LabelFsPath.Count > 0)
{
TfsSection ts = pe.GetSection(nlc.LabelFsPath);
if (ts == null)
continue;
tfs = ts;
}
else
tfs = pe;
if (g.tm.da.UnifyCheck(tfs, nlt.effective))
{
String s_label = nlt.Label;
TfsSection te_meta;
if (meta_templates.Length > 0 && (te_meta = pe.GetSection(nlc.RecursivePath)) != null)
{
foreach (NodeMetaTemplate nmt in meta_templates)
{
if (g.tm.da.UnifyCheck(nmt.effective, te_meta))
{
Tfs tfs_local;
if (nlc.LocalPath != null && nlc.LocalPath.Count > 0)
{
TfsSection ts = tfs.GetSection(nlc.LocalPath);
tfs_local = ts;
}
else
tfs_local = tfs;
foreach (NodeLabelTemplate nlt_sub in label_templates)
{
/// jikes.
if (g.tm.da.UnifyCheck(tfs_local, nlt_sub.effective_local))
return s_label + nmt.Prefix + nlt_sub.Label + nmt.Suffix;
}
}
}
}
return s_label;
}
}
return null;
}
public ParseTree GetParseTree(ParseChart pc, IDerivation pe)
{
return new ParseTree(this, pc, pe.Source);
}
public class ParseTree
{
static readonly ParseTree[] rg_pt_empty = new ParseTree[0];
public ParseTree(GrammarNodeLabeler gnl, ParseChart pc, IParseObj pce)
{
this.pc = pc;
this.pce = pce;
this.label = gnl.FindLabel(pce.Tfs) ?? pce.Tfs.Name;
PassiveEdge.Derived dpe = pce as PassiveEdge.Derived;
if (dpe != null)
children = dpe.ChartDaughters.Select(d => new ParseTree(gnl, pc, d)).ToArray();
else
children = rg_pt_empty;
}
readonly ParseChart pc;
readonly IParseObj pce;
readonly ParseTree[] children;
readonly String label;
public ParseTree[] Children { get { return children; } }
public String Label { get { return label; } }
//public IParseObj ChartEdge { get { return pce; } }
public String SourceText
{
get
{
var tok = pce as IParseObj;
if (tok != null)
return tok.Text;
return String.Empty;
//return pc.InputTokens.Source.MinimalSpanText(pce.ChartSpan);
}
}
public override String ToString()
{
return children.Length == 0 ?
label :
String.Format("{0} ({1})", label, children.StringJoin(" "));
}
public String MonospaceFormat()
{
var ca = children.Select(c => c.MonospaceFormat().Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)).ToArray();
String s = String.Format("{0}", label);
if (ca.Length > 0)
{
int width = ca.Max(c => c.Max(s_lab => s_lab.Length)) + 2;
int j_max = ca.Max(c => c.Length);
StringBuilder sb = new StringBuilder();
sb.AppendLine(s.PadCenter(width * ca.Length, ' '));
for (int j = 0; j < j_max; j++)
{
for (int q = 0; q < ca.Length; q++)
{
String s0;
if (j < ca[q].Length)
s0 = ca[q][j];
else
s0 = "";
sb.Append(s0.PadCenter(width, ' '));
}
sb.AppendLine();
}
s = sb.ToString();
}
else
s += Environment.NewLine;
return s;
}
};
};
}