diff --git a/Src/GenerateHCConfig/ConsoleLogger.cs b/Src/GenerateHCConfig/ConsoleLogger.cs
index bfdfd76d6d..bc9ad55b0f 100644
--- a/Src/GenerateHCConfig/ConsoleLogger.cs
+++ b/Src/GenerateHCConfig/ConsoleLogger.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.ComponentModel;
using SIL.LCModel;
using SIL.FieldWorks.WordWorks.Parser;
@@ -103,5 +103,10 @@ public void InvalidReduplicationForm(IMoForm form, string reason, IMoMorphSynAna
{
Console.WriteLine("The reduplication form \"{0}\" is invalid. Reason: {1}", form.Form.VernacularDefaultWritingSystem.Text, reason);
}
+
+ public void InvalidRewriteRule(IPhRegularRule rule, string reason)
+ {
+ Console.WriteLine("The rewrite rule \"{0}\" is invalid. Reason: {1}", rule.Name.BestAnalysisVernacularAlternative.Text, reason);
+ }
}
}
diff --git a/Src/LexText/Morphology/AffixRuleFormulaControl.cs b/Src/LexText/Morphology/AffixRuleFormulaControl.cs
index d2619971dc..d4a714094c 100644
--- a/Src/LexText/Morphology/AffixRuleFormulaControl.cs
+++ b/Src/LexText/Morphology/AffixRuleFormulaControl.cs
@@ -718,7 +718,7 @@ protected bool RemoveFromOutput(bool forward, SelectionHelper sel, out int index
else
{
int idx = GetIndexToRemove(mappings, sel, forward);
- if (idx > -1)
+ if (idx > -1 && idx < mappings.Count())
{
var mapping = (IMoRuleMapping) mappings[idx];
index = idx - 1;
diff --git a/Src/LexText/ParserCore/HCLoader.cs b/Src/LexText/ParserCore/HCLoader.cs
index 08b81ef8c8..4c969daf5c 100644
--- a/Src/LexText/ParserCore/HCLoader.cs
+++ b/Src/LexText/ParserCore/HCLoader.cs
@@ -236,6 +236,8 @@ private void LoadLanguage()
if (regRule.StrucDescOS.Count > 0 || regRule.RightHandSidesOS.Any(rhs => rhs.StrucChangeOS.Count > 0))
{
RewriteRule hcRegRule = LoadRewriteRule(regRule);
+ if (hcRegRule == null)
+ continue;
m_morphophonemic.PhonologicalRules.Add(hcRegRule);
if (!m_notOnClitics)
m_clitic.PhonologicalRules.Add(hcRegRule);
@@ -1698,6 +1700,11 @@ private RewriteRule LoadRewriteRule(IPhRegularRule prule)
}
hcPrule.Properties[HCParser.PRuleID] = prule.Hvo;
+ if (hcPrule.Lhs.Children.Count > 1)
+ {
+ m_logger.InvalidRewriteRule(prule, ParserCoreStrings.ksMaxElementsInRule);
+ return null;
+ }
foreach (IPhSegRuleRHS rhs in prule.RightHandSidesOS)
{
var psubrule = new RewriteSubrule();
@@ -1748,6 +1755,12 @@ private RewriteRule LoadRewriteRule(IPhRegularRule prule)
psubrule.RightEnvironment = rightPattern;
}
+ if (psubrule.Rhs.Children.Count > 1)
+ {
+ m_logger.InvalidRewriteRule(prule, ParserCoreStrings.ksMaxElementsInRule);
+ return null;
+ }
+
hcPrule.Subrules.Add(psubrule);
}
diff --git a/Src/LexText/ParserCore/HCParser.cs b/Src/LexText/ParserCore/HCParser.cs
index a1f08afd7f..cb28607440 100644
--- a/Src/LexText/ParserCore/HCParser.cs
+++ b/Src/LexText/ParserCore/HCParser.cs
@@ -641,6 +641,14 @@ public void InvalidReduplicationForm(IMoForm form, string reason, IMoMorphSynAna
m_xmlWriter.WriteElementString("Reason", reason);
m_xmlWriter.WriteEndElement();
}
+ public void InvalidRewriteRule(IPhRegularRule rule, string reason)
+ {
+ m_xmlWriter.WriteStartElement("LoadError");
+ m_xmlWriter.WriteAttributeString("type", "invalid-rewrite-rule");
+ m_xmlWriter.WriteElementString("Rule", rule.Name.BestAnalysisVernacularAlternative.Text);
+ m_xmlWriter.WriteElementString("Reason", reason);
+ m_xmlWriter.WriteEndElement();
+ }
}
}
}
diff --git a/Src/LexText/ParserCore/IHCLoadErrorLogger.cs b/Src/LexText/ParserCore/IHCLoadErrorLogger.cs
index 17b154e20c..806c9b9e30 100644
--- a/Src/LexText/ParserCore/IHCLoadErrorLogger.cs
+++ b/Src/LexText/ParserCore/IHCLoadErrorLogger.cs
@@ -1,4 +1,4 @@
-using SIL.LCModel;
+using SIL.LCModel;
namespace SIL.FieldWorks.WordWorks.Parser
{
@@ -10,5 +10,6 @@ public interface IHCLoadErrorLogger
void DuplicateGrapheme(IPhPhoneme phoneme);
void InvalidEnvironment(IMoForm form, IPhEnvironment env, string reason, IMoMorphSynAnalysis msa);
void InvalidReduplicationForm(IMoForm form, string reason, IMoMorphSynAnalysis msa);
+ void InvalidRewriteRule(IPhRegularRule prule, string reason);
}
}
diff --git a/Src/LexText/ParserCore/ParserCoreStrings.Designer.cs b/Src/LexText/ParserCore/ParserCoreStrings.Designer.cs
index eace16ee32..075913c202 100644
--- a/Src/LexText/ParserCore/ParserCoreStrings.Designer.cs
+++ b/Src/LexText/ParserCore/ParserCoreStrings.Designer.cs
@@ -132,6 +132,15 @@ internal static string ksIrregularlyInflectedFormNullAffix {
}
}
+ ///
+ /// Looks up a localized string similar to A rule can't have more than one element in its left-hand side or its right-hand side..
+ ///
+ internal static string ksMaxElementsInRule {
+ get {
+ return ResourceManager.GetString("ksMaxElementsInRule", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to ???.
///
diff --git a/Src/LexText/ParserCore/ParserCoreStrings.resx b/Src/LexText/ParserCore/ParserCoreStrings.resx
index 2e7845b520..0d6fff2d0f 100644
--- a/Src/LexText/ParserCore/ParserCoreStrings.resx
+++ b/Src/LexText/ParserCore/ParserCoreStrings.resx
@@ -189,4 +189,7 @@
Tested {0}
+
+ A rule can't have more than one element in its left-hand side or its right-hand side.
+
\ No newline at end of file
diff --git a/Src/LexText/ParserCore/ParserCoreTests/HCLoaderTests.cs b/Src/LexText/ParserCore/ParserCoreTests/HCLoaderTests.cs
index e9c2adbe57..2f9f93b0c7 100644
--- a/Src/LexText/ParserCore/ParserCoreTests/HCLoaderTests.cs
+++ b/Src/LexText/ParserCore/ParserCoreTests/HCLoaderTests.cs
@@ -41,7 +41,8 @@ private enum LoadErrorType
InvalidPhoneme,
DuplicateGrapheme,
InvalidEnvironment,
- InvalidRedupForm
+ InvalidRedupForm,
+ InvalidRewriteRule
}
private class TestHCLoadErrorLogger : IHCLoadErrorLogger
@@ -82,6 +83,11 @@ public void InvalidReduplicationForm(IMoForm form, string reason, IMoMorphSynAna
{
m_loadErrors.Add(Tuple.Create(LoadErrorType.InvalidRedupForm, (ICmObject) msa));
}
+
+ public void InvalidRewriteRule(IPhRegularRule rule, string reason)
+ {
+ m_loadErrors.Add(Tuple.Create(LoadErrorType.InvalidRedupForm, (ICmObject) rule));
+ }
}
private readonly List> m_loadErrors = new List>();
@@ -988,9 +994,6 @@ public void PhonologicalRule()
Cache.LanguageProject.PhonologicalDataOA.PhonRulesOS.Add(prule);
prule.Name.SetAnalysisDefaultWritingSystem("prule");
prule.Direction = 2;
- IPhSimpleContextSeg segCtxt = Cache.ServiceLocator.GetInstance().Create();
- prule.StrucDescOS.Add(segCtxt);
- segCtxt.FeatureStructureRA = GetPhoneme("a");
IPhSimpleContextNC ncCtxt = Cache.ServiceLocator.GetInstance().Create();
prule.StrucDescOS.Add(ncCtxt);
ncCtxt.FeatureStructureRA = m_vowel;
@@ -1021,7 +1024,7 @@ public void PhonologicalRule()
Assert.That(hcPrule.Direction, Is.EqualTo(Machine.DataStructures.Direction.LeftToRight));
Assert.That(hcPrule.ApplicationMode, Is.EqualTo(RewriteApplicationMode.Simultaneous));
- Assert.That(hcPrule.Lhs.ToString(), Is.EqualTo(m_lang.Strata[0].CharacterDefinitionTable["a"].FeatureStruct + VowelFS));
+ Assert.That(hcPrule.Lhs.ToString(), Is.EqualTo(VowelFS));
Assert.That(hcPrule.Subrules.Count, Is.EqualTo(1));
RewriteSubrule subrule = hcPrule.Subrules[0];
diff --git a/Src/Transforms/Presentation/FormatCommon.xsl b/Src/Transforms/Presentation/FormatCommon.xsl
index 4e9a52c3da..9326558a78 100644
--- a/Src/Transforms/Presentation/FormatCommon.xsl
+++ b/Src/Transforms/Presentation/FormatCommon.xsl
@@ -118,6 +118,15 @@
+
+
+ The rewrite rule "
+
+ " is invalid. Reason:
+
+
+
+