Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ PatternNode<Word, ShapeNode> node in pattern.Children.TakeWhile(n => !(n is Grou
_pattern.Children.Add(node.Clone());
}

AddGroup(groups, leftGroupName);
AddGroup(groups, rightGroupName);
// This pattern matches the surface, where the switch groups appear in reverse pattern order.
int leftIndex = Array.FindIndex(groupOrder, g => g.Name == leftGroupName);
int rightIndex = Array.FindIndex(groupOrder, g => g.Name == rightGroupName);
string firstName = leftIndex < rightIndex ? rightGroupName : leftGroupName;
string secondName = leftIndex < rightIndex ? leftGroupName : rightGroupName;
AddGroup(groups, firstName);
AddGroup(groups, secondName);

foreach (
PatternNode<Word, ShapeNode> node in pattern
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ public void ApplyRhs(Match<Word, ShapeNode> targetMatch, Range<ShapeNode> range,
GroupCapture<ShapeNode> leftGroup = targetMatch.GroupCaptures[_leftGroupName];
GroupCapture<ShapeNode> rightGroup = targetMatch.GroupCaptures[_rightGroupName];

// The splice below needs the later shape-order group first, or its second move re-anchors past its own end.
if (leftGroup.Success && rightGroup.Success && leftGroup.Range.Start.CompareTo(rightGroup.Range.Start) < 0)
{
GroupCapture<ShapeNode> earlier = leftGroup;
leftGroup = rightGroup;
rightGroup = earlier;
}

ShapeNode beforeRightGroup = rightGroup.Range.Start.Prev;
MoveNodesAfter(targetMatch.Input.Shape, leftGroup.Range.End, rightGroup.Range);
MoveNodesAfter(targetMatch.Input.Shape, beforeRightGroup, leftGroup.Range);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using NUnit.Framework;
using SIL.Machine.Annotations;
using SIL.Machine.DataStructures;
using SIL.Machine.FeatureModel;
using SIL.Machine.Matching;
using SIL.Machine.Morphology.HermitCrab.MorphologicalRules;
Expand Down Expand Up @@ -28,6 +29,49 @@ public void SimpleRule()
AssertMorphsEqual(morpher.ParseWord("mui"), "51");
}

// Differs from SimpleRule only in the switch-name order, and must give the same result.
[Test]
public void SimpleRule_LeftSwitchNamesEarlierGroup()
{
var rule1 = new MetathesisRule
{
Name = "rule1",
Pattern = Pattern<Word, ShapeNode>
.New()
.Group("1", group => group.Annotation(Character(Table3, "i")))
.Group("2", group => group.Annotation(Character(Table3, "u")))
.Value,
LeftSwitchName = "1",
RightSwitchName = "2",
};
Morphophonemic.PhonologicalRules.Add(rule1);

var morpher = new Morpher(TraceManager, Language);
AssertMorphsEqual(morpher.ParseWord("mui"), "51");
}

// Differs from SimpleRule only in the switch-name order, plus a right-to-left direction.
[Test]
public void SimpleRule_LeftSwitchNamesEarlierGroup_RightToLeft()
{
var rule1 = new MetathesisRule
{
Name = "rule1",
Direction = Direction.RightToLeft,
Pattern = Pattern<Word, ShapeNode>
.New()
.Group("1", group => group.Annotation(Character(Table3, "i")))
.Group("2", group => group.Annotation(Character(Table3, "u")))
.Value,
LeftSwitchName = "1",
RightSwitchName = "2",
};
Morphophonemic.PhonologicalRules.Add(rule1);

var morpher = new Morpher(TraceManager, Language);
AssertMorphsEqual(morpher.ParseWord("mui"), "51");
}

[Test]
public void ComplexRule()
{
Expand Down Expand Up @@ -62,6 +106,41 @@ public void ComplexRule()
AssertMorphsEqual(morpher.ParseWord("mui"), "53 3SG");
}

// ComplexRule with the switch names reversed: a group sits between the two switches.
[Test]
public void ComplexRule_LeftSwitchNamesEarlierGroup()
{
var any = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value;

var rule1 = new MetathesisRule
{
Name = "rule1",
Pattern = Pattern<Word, ShapeNode>
.New()
.Group("1", group => group.Annotation(Character(Table3, "i")))
.Group("middle", group => group.Annotation(Character(Table3, "+")))
.Group("2", group => group.Annotation(Character(Table3, "u")))
.Group("rightEnv", group => group.Annotation(HCFeatureSystem.RightSideAnchor))
.Value,
LeftSwitchName = "1",
RightSwitchName = "2",
};
Morphophonemic.PhonologicalRules.Add(rule1);

var uSuffix = new AffixProcessRule { Name = "u_suffix", Gloss = "3SG" };
Morphophonemic.MorphologicalRules.Add(uSuffix);
uSuffix.Allomorphs.Add(
new AffixProcessAllomorph
{
Lhs = { Pattern<Word, ShapeNode>.New("1").Annotation(any).OneOrMore.Value },
Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+u") },
}
);

var morpher = new Morpher(TraceManager, Language);
AssertMorphsEqual(morpher.ParseWord("mui"), "53 3SG");
}

[Test]
public void SimpleRuleNotUnapplied()
{
Expand Down
Loading