Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Src/LexText/ParserCore/FwXmlTraceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ public void BeginUnapplyTemplate(AffixTemplate template, Word input)
CreateWordElement("Input", input, true)));
}

public void EndUnapplyTemplate(AffixTemplate template, Word output, bool unapplied, FailureReason reason)
public void EndUnapplyTemplate(AffixTemplate template, Word output, bool unapplied, FailureReason reason,
object failureObj)
{
var trace = new XElement(
"TemplateAnalysisTraceOut",
Expand All @@ -82,6 +83,11 @@ public void EndUnapplyTemplate(AffixTemplate template, Word output, bool unappli
new XElement("FailureReason", new XAttribute("type", "nonPartialRuleAfterFinalTemplate"))
);
}
else if (reason == FailureReason.UnreachableRequiredSlot)
{
trace.Add(new XElement("FailureReason", new XAttribute("type", "unreachableRequiredSlot"),
new XElement("Slot", (failureObj as AffixTemplateSlot)?.Name)));
}
((XElement)output.CurrentTrace).Add(trace);
}

Expand Down
15 changes: 15 additions & 0 deletions Src/LexText/ParserCore/ParserCoreTests/FwXmlTraceManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ public void CompoundingFailure_UnknownReasonIsNotGuessedFromOperand()
Assert.That((string)reason.Attribute("type"), Is.EqualTo("unknown"));
}

/// <summary>Records which required slot made a template fail.</summary>
[Test]
public void TemplateFailure_RecordsUnreachableRequiredSlot()
{
var template = new AffixTemplate { Name = "synthetic template" };
var slot = new AffixTemplateSlot(new AffixProcessRule()) { Name = "synthetic slot" };

m_manager.EndUnapplyTemplate(template, m_word, false,
FailureReason.UnreachableRequiredSlot, slot);

var reason = m_trace.Element("TemplateAnalysisTraceOut").Element("FailureReason");
Assert.That((string)reason.Attribute("type"), Is.EqualTo("unreachableRequiredSlot"));
Assert.That(reason.Element("Slot").Value, Is.EqualTo("synthetic slot"));
}

private RootAllomorph CreateRoot(string headword)
{
var entry = Cache.ServiceLocator.GetInstance<ILexEntryFactory>().Create(
Expand Down
19 changes: 19 additions & 0 deletions Src/LexText/ParserCore/ParserCoreTests/HCTraceTransformTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,25 @@ public void CompoundingFailure_UnknownCauseIsExplicit(string type)
Assert.That(Text(Transform(CompoundFailure(type))), Does.Contain("Reason: Unknown reason."));
}

/// <summary>Names the required slot whose affixes the word cannot supply.</summary>
[Test]
public void TemplateFailure_NamesUnreachableRequiredSlot()
{
var node = new XElement("MorphologicalRuleAnalysisTrace",
new XElement("MorphologicalRule", new XAttribute("type", "affix"), "suffix"),
new XElement("Output", "a"),
new XElement("TemplateAnalysisTraceOut",
new XElement("AffixTemplate", new XAttribute("id", 0), "verb template"),
new XElement("Output", "*None*"),
new XElement("FailureReason", new XAttribute("type", "unreachableRequiredSlot"),
new XElement("Slot", "subject slot"))));

var text = Text(Transform(node));

Assert.That(text, Does.Contain("failed."));
Assert.That(text, Does.Contain("(Reason: The required slot 'subject slot' cannot be filled"));
}

private static XElement Allomorph()
{
return new XElement("Allomorph", new XAttribute("id", 42),
Expand Down
10 changes: 10 additions & 0 deletions Src/Transforms/Presentation/FormatHCTrace.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,16 @@ ShowMsaInfo
<xsl:when test="@type = 'maxAppCount'">
<xsl:text>An affix cannot be applied more than once.</xsl:text>
</xsl:when>
<xsl:when test="@type = 'unreachableRequiredSlot'">
<xsl:text>The required slot '</xsl:text>
<span>
<xsl:attribute name="style">
<xsl:call-template name="GetAnalysisFont"/>
</xsl:attribute>
<xsl:value-of select="Slot"/>
</span>
<xsl:text>' cannot be filled: no affix in this slot can be found in what remains of the word, in the order and position the template requires.</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Unknown reason.</xsl:text>
</xsl:otherwise>
Expand Down
10 changes: 10 additions & 0 deletions Src/Transforms/Presentation/HCSynthByGlossFormatHCTrace.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,16 @@ ShowMsaInfo
<xsl:when test="@type = 'maxAppCount'">
<xsl:text>An affix cannot be applied more than once.</xsl:text>
</xsl:when>
<xsl:when test="@type = 'unreachableRequiredSlot'">
<xsl:text>The required slot '</xsl:text>
<span>
<xsl:attribute name="style">
<xsl:call-template name="GetAnalysisFont"/>
</xsl:attribute>
<xsl:value-of select="Slot"/>
</span>
<xsl:text>' cannot be filled: no affix in this slot can be found in what remains of the word, in the order and position the template requires.</xsl:text>
</xsl:when>
</xsl:choose>
<xsl:text>)</xsl:text>
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using SIL.Machine.FeatureModel;
using SIL.Machine.Morphology;
using SIL.Machine.Morphology.HermitCrab;
using SIL.Machine.Morphology.HermitCrab.MorphologicalRules;
using System.Reflection;
using System.IO;
using HCSynthByGloss;
Expand Down Expand Up @@ -145,5 +146,25 @@ public void TraceListsEachFailedEnvironment()
Assert.That(reason.Elements("Environment").Select(e => e.Value).ToList(),
Has.Count.EqualTo(2).And.All.Not.Empty);
}

/// <summary>The trace names the required slot that made a template fail.</summary>
[Test]
public void TraceNamesUnreachableRequiredSlot()
{
var traceManager = new HcXmlTraceManager { IsTracing = true };
var table = new CharacterDefinitionTable();
table.AddSegment("a");
var trace = new XElement("WordAnalysisTrace");
var word = new Word(new Stratum(table), table.Segment("a")) { CurrentTrace = trace };
var template = new AffixTemplate { Name = "synthetic template" };
var slot = new AffixTemplateSlot(new AffixProcessRule()) { Name = "synthetic slot" };

traceManager.EndUnapplyTemplate(template, word, false,
FailureReason.UnreachableRequiredSlot, slot);

XElement reason = trace.Element("TemplateAnalysisTraceOut").Element("FailureReason");
Assert.That((string)reason.Attribute("type"), Is.EqualTo("unreachableRequiredSlot"));
Assert.That(reason.Element("Slot").Value, Is.EqualTo("synthetic slot"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,13 @@ public void BeginUnapplyTemplate(AffixTemplate template, Word input)
);
}

public void EndUnapplyTemplate(AffixTemplate template, Word output, bool unapplied, FailureReason reason)
public void EndUnapplyTemplate(
AffixTemplate template,
Word output,
bool unapplied,
FailureReason reason,
object failureObj
)
{
var trace = new XElement(
"TemplateAnalysisTraceOut",
Expand All @@ -110,6 +116,16 @@ public void EndUnapplyTemplate(AffixTemplate template, Word output, bool unappli
new XElement("FailureReason", new XAttribute("type", "nonPartialRuleAfterFinalTemplate"))
);
}
else if (reason == FailureReason.UnreachableRequiredSlot)
{
trace.Add(
new XElement(
"FailureReason",
new XAttribute("type", "unreachableRequiredSlot"),
new XElement("Slot", (failureObj as AffixTemplateSlot)?.Name)
)
);
}
((XElement)output.CurrentTrace).Add(trace);
}

Expand Down
Loading