public bool PhraseNodesAreEqual(PhraseNode pn1, PhraseNode pn2) { if(pn1 == pn2) { return true; } if(pn1 == null ^ pn2 == null) { return false; } if(pn1.Size() != pn2.Size()) { return false; } for(int i = 0; i < pn1.Size(); i++) { if(!WordNodesAreEqual(pn1[i], pn2[i])) { return false; } } return true; }
/// <summary> /// Assigns part-of-speech tags to the word nodes in the given phrase, assuming it is a noun phrase. /// Only the words between startIndex and stopIndex, inclusive, are tagged. /// </summary> /// <param name="phrase">The noun phrase to tag.</param> /// <param name="startIndex">The index of the first word to tag.</param> /// <param name="stopIndex">The index of the last word to tag.</param> /// <exception cref="System.ArgumentOutOfRangeException">startIndex or stopIndex are not valid indices, or stopIndex is less than startIndex</exception> public override void TagNounPhrase(PhraseNode phrase, int startIndex, int stopIndex) { if (phrase == null || phrase.Size() <= 0) { return; } if (startIndex < 0 || startIndex >= phrase.Size()) { throw new ArgumentOutOfRangeException("startIndex", startIndex, string.Format("The given value is not a valid index of the PhraseNode. It must be between 0 and {0}.", phrase.Size() - 1)); } if (stopIndex < startIndex || stopIndex >= phrase.Size()) { throw new ArgumentOutOfRangeException("stopIndex", stopIndex, string.Format("The given value must be a valid index of the PhraseNode, and must be larger than the given startIndex value of {0}", startIndex)); } //start from the end of the phrase int currentWord = stopIndex; //skip any digits at the end while (phrase[currentWord].Tag == PartOfSpeechTag.Digit) { currentWord--; } //tag the last word if (currentWord >= startIndex) { if (pos.IsDeterminer(phrase[currentWord].Text)) { phrase[currentWord].Tag = PartOfSpeechTag.Determiner; } else if (pos.IsPronoun(phrase[currentWord].Text)) { phrase[currentWord].Tag = PartOfSpeechTag.Pronoun; } else if (pos.IsIgnorableHeadWord(phrase[currentWord].Text)) { phrase[currentWord].Tag = PartOfSpeechTag.NounIgnorable; } else { phrase[currentWord].Tag = PartOfSpeechTag.Noun; } currentWord--; } //tag the rest of the words while (currentWord >= startIndex) { if (pos.IsDeterminer(phrase[currentWord].Text)) { phrase[currentWord].Tag = PartOfSpeechTag.Determiner; } else if (pos.IsPronoun(phrase[currentWord].Text)) { phrase[currentWord].Tag = PartOfSpeechTag.Pronoun; } else if (phrase[currentWord].Tag != PartOfSpeechTag.Digit) { phrase[currentWord].Tag = PartOfSpeechTag.NounModifier; } currentWord--; } }
/// <summary> /// Assigns part-of-speech tags to the word nodes in the given phrase, assuming it is a noun phrase. /// </summary> /// <param name="phrase">The noun phrase to tag.</param> public override void TagNounPhrase(PhraseNode phrase) { TagNounPhrase(phrase, 0, phrase.Size() - 1); }
/// <summary> /// Determines whether the given phrase indicates an event handler method. /// </summary> /// <param name="parsedName">The PhraseNode to test.</param> /// <returns>True if the phrase indicates an event handler method, False otherwise.</returns> protected bool IsEventHandler(PhraseNode parsedName) { if (parsedName == null || parsedName.Size() == 0) { return false; } else { return IsNonBaseVerb(parsedName.LastWord().Text) && parsedName[0].Text.ToLower() != "get" && parsedName[0].Text.ToLower() != "set"; } }
/// <summary> /// Determines whether the given PhraseNode overlaps with the given word. /// The two overlap if the last word of the phrase is the same as the given word, /// or if the second-to-last word of the phrase is the same as the given word and the last word of the phrase is ignorable. /// </summary> /// <param name="name">The phrase to check for overlap.</param> /// <param name="word">The word to check for overlap with.</param> /// <returns>True if the phrase and word overlap, False otherwise.</returns> private bool HasOverlap(PhraseNode name, string word) { if (name == null || name.Size() == 0 || string.IsNullOrEmpty(word)) { return false; } bool hasOverlap = false; if (string.Equals(name.LastWord().Text, word, StringComparison.InvariantCultureIgnoreCase)) { //last word of name is same as given word hasOverlap = true; } else if (name.Size() > 1) { if (string.Equals(name[name.Size() - 2].Text, word, StringComparison.InvariantCultureIgnoreCase) && PosData.IsIgnorableHeadWord(name.LastWord().Text)) { //second-to-last word of name is same as given word, and the last word of name is ignorable hasOverlap = true; } } return hasOverlap; }
/// <summary> /// Returns a PhraseNode containing the noun phrase words from the given name, starting from startIndex. /// All noun phrase words prior to the first encountered preposition are included. /// </summary> /// <param name="parsedName">The PhraseNode to get the noun phrase from.</param> /// <param name="startIndex">The index of the word to start from.</param> private PhraseNode GetNounPhrase(PhraseNode parsedName, int startIndex) { PhraseNode phrase = parsedName.GetNewEmpty(); for (int i = startIndex; i < parsedName.Size(); i++) { PartOfSpeechTag tag = parsedName[i].Tag; if (tag == PartOfSpeechTag.Noun || tag == PartOfSpeechTag.NounModifier || tag == PartOfSpeechTag.Determiner || tag == PartOfSpeechTag.Pronoun || tag == PartOfSpeechTag.NounIgnorable || tag == PartOfSpeechTag.Digit || tag == PartOfSpeechTag.Preamble) { phrase.Add(parsedName[i]); } else if (tag == PartOfSpeechTag.Preposition) { break; } } return phrase; }
/// <summary> /// Finds the index of the first preposition within the given PhraseNode, starting from the word indicated by startIndex. /// </summary> /// <param name="parsedName">The PhraseNode to search.</param> /// <param name="startIndex">The index of the word to start searching for prepositions from.</param> /// <returns>The index of the first preposition in the PhraseNode after startIndex, inclusively.</returns> private int FindFirstPreposition(PhraseNode parsedName, int startIndex) { for (int i = startIndex; i < parsedName.Size(); i++) { if (parsedName[i].Tag == PartOfSpeechTag.Preposition) { return i; } } return -1; }
/// <summary> /// Determines whether the specified word in the given phrase is an ignorable verb. If so, it tags it appropriately. /// </summary> /// <param name="parsedName">The PhraseNode containing the word to check.</param> /// <param name="wordIndex">The index of the desired word within the PhraseNode.</param> /// <returns>wordIndex+1 if the word was an ignorable verb; wordIndex if it was not.</returns> private int CheckForIgnorableVerb(PhraseNode parsedName, int wordIndex) { if (wordIndex < parsedName.Size() - 1 //make sure last word in name is verb && (PosData.IsIgnorableVerb(parsedName[wordIndex].Text) && (PositionalFrequencies.GetVerbProbability(parsedName[wordIndex + 1].Text) > PositionalFrequencies.GetNounProbability(parsedName[wordIndex + 1].Text)) || PosData.IsModalVerb(parsedName[wordIndex].Text)) ) { parsedName[wordIndex].Tag = PartOfSpeechTag.VerbIgnorable; wordIndex++; } return wordIndex; }