/// <summary> /// Initializes a new instance of the <see cref="WordSynthesis"/> class. /// </summary> /// <param name="rootAllomorph">The root allomorph.</param> /// <param name="nonHead">The non-head synthesis.</param> /// <param name="rzFeatures">The realizational features.</param> /// <param name="mrules">The morphological rules to apply.</param> /// <param name="curTrace">The current trace record.</param> internal WordSynthesis(LexEntry.RootAllomorph rootAllomorph, WordSynthesis nonHead, FeatureValues rzFeatures, IEnumerable <MorphologicalRule> mrules, Trace curTrace) { m_root = (LexEntry)rootAllomorph.Morpheme; m_mprFeatures = m_root.MPRFeatures != null?m_root.MPRFeatures.Clone() : new MPRFeatureSet(); m_headFeatures = m_root.HeadFeatures != null?m_root.HeadFeatures.Clone() : new FeatureValues(); m_footFeatures = m_root.FootFeatures != null?m_root.FootFeatures.Clone() : new FeatureValues(); m_pos = m_root.POS; m_stratum = m_root.Stratum; m_nonHead = nonHead; m_morphs = new Morphs(); Morph morph = new Morph(rootAllomorph); morph.Shape.AddMany(rootAllomorph.Shape.Segments); m_morphs.Add(morph); m_shape = new PhoneticShape(); m_shape.Add(new Margin(Direction.LEFT)); m_shape.AddPartition(rootAllomorph.Shape.Segments, morph.Partition); m_shape.Add(new Margin(Direction.RIGHT)); m_obligHeadFeatures = new HCObjectSet <Feature>(); m_mrules = new List <MorphologicalRule>(mrules); m_rzFeatures = rzFeatures; m_curTrace = curTrace; m_mrulesApplied = new Dictionary <MorphologicalRule, int>(); }
PhoneticShape UnapplyRHS(Match match) { PhoneticShape output = new PhoneticShape(); output.Add(new Margin(Direction.LEFT)); // iterate thru LHS partitions, copying the matching partition from the // input to the output for (int i = 0; i < m_transform.PartitionCount; i++) { m_transform.Unapply(match, i, output); } output.Add(new Margin(Direction.RIGHT)); return(output); }
void UnapplyRHS(Match match, out PhoneticShape headShape, out PhoneticShape nonHeadShape) { headShape = new PhoneticShape(); headShape.Add(new Margin(Direction.LEFT)); nonHeadShape = new PhoneticShape(); nonHeadShape.Add(new Margin(Direction.LEFT)); // iterate thru LHS partitions, copying the matching partition from the // input to the output for (int i = 0; i < m_transform.PartitionCount; i++) { PhoneticShape curShape = i < m_firstNonHeadPartition ? headShape : nonHeadShape; m_transform.Unapply(match, i, curShape); } headShape.Add(new Margin(Direction.RIGHT)); nonHeadShape.Add(new Margin(Direction.RIGHT)); }
void Untruncate(PhoneticPattern lhs, PhoneticShape output, bool optional, VariableValues instantiatedVars) { // create segments from the LHS partition pattern and append them to the output foreach (PhoneticPatternNode node in lhs) { switch (node.Type) { case PhoneticPatternNode.NodeType.SIMP_CTXT: SimpleContext ctxt = node as SimpleContext; Segment newSeg = ctxt.UnapplyDeletion(instantiatedVars); newSeg.IsOptional = optional; output.Add(newSeg); break; case PhoneticPatternNode.NodeType.PATTERN: NestedPhoneticPattern nestedPattern = node as NestedPhoneticPattern; // untruncate nested partitions the maximum number of times it can occur, // marking any segments that occur after the minimum number of occurrences // as optional for (int j = 0; j < nestedPattern.MaxOccur; j++) { Untruncate(nestedPattern.Pattern, output, j >= nestedPattern.MinOccur, instantiatedVars); } break; case PhoneticPatternNode.NodeType.BDRY_CTXT: // skip boundaries break; } } }
/// <summary> /// Unapplies this transform to the specified partition in the specified match. /// </summary> /// <param name="match">The match.</param> /// <param name="partition">The partition.</param> /// <param name="output">The output.</param> public void Unapply(Match match, int partition, PhoneticShape output) { IList <PhoneticShapeNode> nodes = match.GetPartition(partition); if (nodes != null && nodes.Count > 0) { SimpleContext ctxt; if (!m_modifyFromCtxts.TryGetValue(partition, out ctxt)) { ctxt = null; } foreach (PhoneticShapeNode node in nodes) { switch (node.Type) { case PhoneticShapeNode.NodeType.SEGMENT: Segment newSeg = new Segment(node as Segment); // if there is a modify-from context on this partition, unapply it if (ctxt != null) { ctxt.Unapply(newSeg, match.VariableValues); } output.Add(newSeg); break; case PhoneticShapeNode.NodeType.BOUNDARY: output.Add(node.Clone()); break; } } } else { // untruncate a partition Untruncate(m_lhs[partition], output, false, match.VariableValues); } }
/// <summary> /// Converts the specified string to a phonetic shape. It matches the longest possible segment /// first. /// </summary> /// <param name="str">The string.</param> /// <param name="mode">The mode.</param> /// <returns>The phonetic shape, <c>null</c> if the string contains invalid segments.</returns> public PhoneticShape ToPhoneticShape(string str, ModeType mode) { PhoneticShape ps = new PhoneticShape(); int i = 0; ps.Add(new Margin(Direction.LEFT)); while (i < str.Length) { bool match = false; for (int j = str.Length - i; j > 0; j--) { string s = str.Substring(i, j); PhoneticShapeNode node = GetPhoneticShapeNode(s, mode); if (node != null) { try { ps.Add(node); } catch (InvalidOperationException) { return(null); } i += j; match = true; break; } } if (!match) { return(null); } } ps.Add(new Margin(Direction.RIGHT)); return(ps); }