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 95aff26db3..d4a714094c 100644 --- a/Src/LexText/Morphology/AffixRuleFormulaControl.cs +++ b/Src/LexText/Morphology/AffixRuleFormulaControl.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2015 SIL International +// Copyright (c) 2015 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) @@ -599,6 +599,8 @@ protected override int RemoveItems(SelectionHelper sel, bool forward, out int ce int prevCellId = GetPrevCell(seqCtxt.Hvo); cellIndex = GetCellCount(prevCellId) - 1; Rule.InputOS.Remove(seqCtxt); + // Unschedule the removal of the column. + m_removeCol = null; return prevCellId; } bool reconstruct = RemoveContextsFrom(forward, sel, seqCtxt, false, out cellIndex); @@ -716,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: + + +
  • +