using System; using System.Collections.Generic; using System.Linq; using System.Text; using agree.Parse; using glue.Extensions.Enumerable; using glue.Extensions.String; namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public class GrammarNodeLabeler { NodeLabelTemplate[] label_templates; NodeMetaTemplate[] meta_templates; NodeLabelTemplate[] local_label_templates; NodeLabelConfiguration nlc; public GrammarNodeLabeler(NodeLabelConfiguration nlc, IEnumerable<NodeLabelTemplate> labels, IEnumerable<NodeMetaTemplate> metas) { this.nlc = nlc; label_templates = labels.ToArray(); meta_templates = metas.ToArray(); local_label_templates = labels.Where(nlt => !nlt.effective_local.Equals(default(TfsEdge))).ToArray(); } public String FindLabel(ParseChart.IParseChartEdge pe) { Tray tr = pe.Contents.Tray; foreach (NodeLabelTemplate nlt in label_templates) { TfsEdge te; if (nlc.LabelFsPath != null && nlc.LabelFsPath.Count > 0) { if (!tr.GetTfsEdgeAtPath(pe.Contents.Edge, nlc.LabelFsPath, out te)) continue; } else te = pe.Contents; if (new Unification.Checker(tr).Check(te, nlt.effective)) { String s_label = nlt.Label; TfsEdge te_meta; if (meta_templates.Length > 0 && tr.GetTfsEdgeAtPath(pe.Contents.Edge, nlc.RecursivePath, out te_meta)) { foreach (NodeMetaTemplate nmt in meta_templates) { if (new Unification.Checker(tr).Check(te_meta, nmt.effective)) { TfsEdge te_local; if (nlc.LocalPath != null && nlc.LocalPath.Count > 0) { tr.GetTfsEdgeAtPath(te.Edge, nlc.LocalPath, out te_local); } else te_local = te; foreach (NodeLabelTemplate nlt_sub in label_templates) { /// jikes. if (new Unification.Checker(tr).Check(te_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, ParseChart.IParseChartEdge pe) { return new ParseTree(this, pc, pe); } public class ParseTree { static readonly ParseTree[] rg_pt_empty = new ParseTree[0]; public ParseTree(GrammarNodeLabeler gnl, ParseChart pc, ParseChart.IParseChartEdge pce) { this.pc = pc; this.pce = pce; this.label = gnl.FindLabel(pce) ?? pce.Contents.Name; ParseChart.DerivedPassiveEdge dpe = pce as ParseChart.DerivedPassiveEdge; if (dpe != null) children = dpe.Daughters.Select(d => new ParseTree(gnl, pc, d)).ToArray(); else children = rg_pt_empty; } readonly ParseChart pc; readonly ParseChart.IParseChartEdge pce; readonly ParseTree[] children; readonly String label; public ParseTree[] Children { get { return children; } } public String Label { get { return label; } } public ParseChart.IParseChartEdge ChartEdge { get { return pce; } } public String SourceText { get { var tok = pce as ParseChart.IParseChartToken; 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; } }; }; }