public IEnumerable <Word> ParseWord(string word, out object trace) { // convert the word to its phonetic shape Shape shape = _lang.SurfaceStratum.CharacterDefinitionTable.Segment(word); var input = new Word(_lang.SurfaceStratum, shape); input.Freeze(); if (_traceManager.IsTracing) { _traceManager.AnalyzeWord(_lang, input); } trace = input.CurrentTrace; // Unapply rules IEnumerable <Word> analyses = _analysisRule.Apply(input); #if OUTPUT_ANALYSES var lines = new List <string>(); foreach (Word w in analyses) { string shapeStr = w.ToString(); string rulesStr = string.Join(", ", w.MorphologicalRules.Select(r => r.Name)); lines.Add(string.Format("{0} : {1}", shapeStr, rulesStr)); } File.WriteAllLines("analyses.txt", lines.OrderBy(l => l)); #endif #if SINGLE_THREADED IEnumerable <Word> validWords = Synthesize(analyses); #else IEnumerable <Word> validWords = ParallelSynthesize(analyses); #endif var matchList = new List <Word>(); foreach (Word w in CheckDisjunction(validWords)) { if (_lang.SurfaceStratum.CharacterDefinitionTable.IsMatch(word, w.Shape)) { if (_traceManager.IsTracing) { _traceManager.Successful(_lang, w); } matchList.Add(w); } else if (_traceManager.IsTracing) { _traceManager.Failed(_lang, w, FailureReason.SurfaceFormMismatch, null, word); } } return(matchList); }
public IEnumerable <Word> ParseWord(string word, out object trace) { // convert the word to its phonetic shape Shape shape = _lang.SurfaceStratum.CharacterDefinitionTable.Segment(word); var input = new Word(_lang.SurfaceStratum, shape); input.Freeze(); if (_traceManager.IsTracing) { _traceManager.AnalyzeWord(_lang, input); } trace = input.CurrentTrace; // Unapply rules IEnumerable <Word> analyses = _analysisRule.Apply(input); #if OUTPUT_ANALYSES var lines = new List <string>(); foreach (Word w in analyses) { string shapeStr = w.ToString(); string rulesStr = string.Join(", ", w.MorphologicalRules.Select(r => r.Name)); lines.Add(string.Format("{0} : {1}", shapeStr, rulesStr)); } File.WriteAllLines("analyses.txt", lines.OrderBy(l => l)); #endif #if SINGLE_THREADED IEnumerable <Word> validWords = Synthesize(analyses); #else IEnumerable <Word> validWords = ParallelSynthesize(analyses); #endif var matchList = new List <Word>(); foreach (IGrouping <IEnumerable <Allomorph>, Word> group in validWords.GroupBy(validWord => validWord.AllomorphsInMorphOrder, MorphsEqualityComparer)) { // enforce the disjunctive property of allomorphs by ensuring that this word synthesis // has the highest order of precedence for its allomorphs Word[] words = group.ToArray(); for (int i = 0; i < words.Length; i++) { bool disjunctive = false; for (int j = 0; j < words.Length; j++) { if (i == j) { continue; } // if the two parses differ by one allomorph and that allomorph does not free fluctuate and has a lower precedence, than the parse fails Tuple <Allomorph, Allomorph>[] differentAllomorphs = words[i].AllomorphsInMorphOrder.Zip(words[j].AllomorphsInMorphOrder).Where(t => t.Item1 != t.Item2).ToArray(); if (differentAllomorphs.Length == 1 && !differentAllomorphs[0].Item1.FreeFluctuatesWith(differentAllomorphs[0].Item2) && differentAllomorphs[0].Item1.Index >= differentAllomorphs[0].Item2.Index) { disjunctive = true; if (_traceManager.IsTracing) { _traceManager.ParseFailed(_lang, words[i], FailureReason.DisjunctiveAllomorph, null, words[j]); } break; } } if (!disjunctive) { if (_lang.SurfaceStratum.CharacterDefinitionTable.IsMatch(word, words[i].Shape)) { if (_traceManager.IsTracing) { _traceManager.ParseSuccessful(_lang, words[i]); } matchList.Add(words[i]); } else if (_traceManager.IsTracing) { _traceManager.ParseFailed(_lang, words[i], FailureReason.SurfaceFormMismatch, null, word); } } } } return(matchList); }