From 47351f83ec45f8b56207be07aad146a56c006ee9 Mon Sep 17 00:00:00 2001 From: John T Maxwell III Date: Thu, 19 Sep 2024 09:41:10 -0700 Subject: [PATCH] Fix LT-21585: Hermit Crab Parsing Error yellow box crash (#161) * Fix LT-21585: Hermit Crab Parsing Error yellow box crash * Fix test to only have one element in the left-hand side --- Src/GenerateHCConfig/ConsoleLogger.cs | 7 ++++++- Src/LexText/ParserCore/HCLoader.cs | 13 +++++++++++++ Src/LexText/ParserCore/HCParser.cs | 8 ++++++++ Src/LexText/ParserCore/IHCLoadErrorLogger.cs | 3 ++- .../ParserCore/ParserCoreStrings.Designer.cs | 9 +++++++++ Src/LexText/ParserCore/ParserCoreStrings.resx | 3 +++ .../ParserCore/ParserCoreTests/HCLoaderTests.cs | 13 ++++++++----- Src/Transforms/Presentation/FormatCommon.xsl | 9 +++++++++ 8 files changed, 58 insertions(+), 7 deletions(-) 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/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: + + +
  • +