/// <summary> /// Получение информации по предыдущему подпредложению для заданного текущего подпредложения /// </summary> /// <param name="current">информация о текущем подпредложении</param> /// <param name="previous">информация о предыдущем подпредложении для последнего добавленного</param> /// <param name="last">информация о последнем добавленном подпредложении</param> /// <returns>информация о предыдущем подпредложении для текущего</returns> private SubSentenceInfo GetPreviousSubSentenceInfo(SubSentenceInfo current, SubSentenceInfo previous, SubSentenceInfo last) { if ((last != null) && (previous != last)) { SubSentenceInfo parent = previous.Parent; if (parent == null) { if ((previous.SubSentence.GetLastUnitStartPosition() < last.SubSentence.GetLastUnitStartPosition()) || (current.SubSentence.GetLastUnitStartPosition() < previous.SubSentence.GetLastUnitStartPosition())) { previous = last; } } else if (previous.SubSentence.GetLastUnitStartPosition() <= last.SubSentence.GetLastUnitStartPosition()) { previous = GetPreviousSubSentenceInfo(current, parent, last); } #region [.defense.] else { throw new InvalidOperationException("Very complicated hierarchy"); } #endregion } return(previous); }
/// <summary> /// Получение подпредложения, расположенного на том же уровне, куда надо вставлять текущее /// дополнительно указывается флаг, следует ли соединить это подпредложение с текущим /// </summary> /// <param name="brother">результирующее подпредложение</param> /// <param name="lastAdded">последнее добавленное подпредложение</param> /// <returns>флаг, следует ли соединить результирующее подпредложение с текущим</returns> private bool GetCurrentBrother(ref SubSentenceInfo brother, SubSentenceInfo lastAdded) { if (brother.Parent != null) { SubSentenceInfo previousSubSentence = GetRightBorderSubSentence(brother.Parent); if (!CurrentSubSentence.IsExistSubject()) { bool isPartOfPrevious = IsCurrentPartOfPrevious(previousSubSentence, lastAdded); if (isPartOfPrevious || CurrentSubSentence.IsExistSubject()) { brother = previousSubSentence; return(isPartOfPrevious); } } if (CurrentSubSentence.IsContainConjunction && (previousSubSentence != null)) { brother = previousSubSentence; return(false); } brother = brother.Parent; if (IsConjunctionSeria(previousSubSentence)) { return(true); } else { return(GetCurrentBrother(ref brother, lastAdded)); } } return(IsCurrentPartOfPrevious(brother, lastAdded)); }
/// <summary> /// Добавление в иерархию текущего подпредложения, являющегося причастным или деепричастным оборотом /// </summary> /// <param name="lastAdded">последнее добавленное подпредложение</param> private void AddCurrentDanglingParticipleOrParticipialToHierarchy(SubSentenceInfo lastAdded) { #region [.defense.] if (lastAdded == null) { throw new ArgumentNullException("lastAdded"); } if ((CurrentSubSentence.SubSentence.Type != SubSentenceType.DanglingParticiple) && (CurrentSubSentence.SubSentence.Type != SubSentenceType.Participial)) { throw new ArgumentException("Current subsentence isn't DanglingParticiple or Participial"); } #endregion SubSentenceInfo parent = null; if (CurrentSubSentence.IsExistSubject()) { parent = lastAdded; } else /// поиск определяемого слово в других подпредложениях в иерархии { parent = FindParentWithDeterminerUpToHierarchy(lastAdded); } if ((CurrentSubSentence.IsExistSubject()) && (CurrentSubSentence.SubSentence.Type == parent.SubSentence.Type) && (CurrentSubSentence.SubSentence.Subject == parent.SubSentence.Subject)) /// определяемое слово совпадает с определяемым словом родительского подпредложения того же типа - /// сделаем их подпредложениями одного уровня { parent = lastAdded.Parent; } parent.AddChild(CurrentSubSentence); }
/// <summary> /// Проверка, что текущее подпредложение должно быть частью предыдущего подпредложения /// </summary> /// <param name="previous">предыдущее подпредложение</param> /// <returns>результат проверки</returns> private bool IsCurrentPartOfPrevious(SubSentenceInfo previous) { #region [.defense.] if (CurrentSubSentence.IsContainConjunction) { throw new InvalidOperationException("Current subsentence have conjunction"); } #endregion bool result = false; switch (previous.SubSentence.Type) { case SubSentenceType.DanglingParticiple: case SubSentenceType.Participial: result = !(CurrentSubSentence.IsExistVerb() || CurrentSubSentence.IsExistSubject()); break; case SubSentenceType.Default: case SubSentenceType.Subordinate: result = !(CurrentSubSentence.IsExistVerb() && previous.IsExistVerb()) && !((CurrentSubSentence.IsHasLingvisticEntity() || CurrentSubSentence.SubSentence.Children.Any()) && (previous.IsHasLingvisticEntity() || previous.SubSentence.Children.Any())); break; } return(result); }
/// <summary> /// Присоединение заданной информации о подпредложении /// </summary> /// <param name="subSentenceInfo">информация о подпредложении</param> public void Append(SubSentenceInfo subSentenceInfo) { Participles.AddRange(subSentenceInfo.Participles); Verbs.AddRange(subSentenceInfo.Verbs); AddChildrenSubSentences(subSentenceInfo.Childs); SubSentence.SetUnits(SubSentence.Units.Union(subSentenceInfo.SubSentence.Units)); SubSentence.AppendSubSentences(subSentenceInfo.SubSentence.Children); }
/// <summary> /// Проверка, что подпредложение образовано на стыке союзов /// </summary> /// <param name="subSentence">подпредложение</param> /// <returns>результат проверки</returns> private bool IsConjunctionSeria(SubSentenceInfo subSentence) { if ((subSentence != null) && subSentence.IsContainConjunction && (subSentence.Parent != null)) { Entity subSentenceFirst = (Entity)subSentence.SubSentence.Units.First(_ => _.IsEntity); Entity parentLast = (Entity)subSentence.Parent.SubSentence.Units.LastOrDefault(_ => _.IsEntity); return((parentLast != null) && IsConjunction(subSentenceFirst) && IsConjunction(parentLast)); } return(false); }
/// <summary> /// Поиск вверх по иерархии родительского подпредложения, в котором содержится определяемое слово для текущего /// </summary> /// <param name="parent">первое возможное родительское подпредложение</param> /// <returns>родительское подпредложение</returns> private SubSentenceInfo FindParentWithDeterminerUpToHierarchy(SubSentenceInfo parent) { SubSentenceInfo result = parent; while (!CurrentSubSentence.IsExistSubject() && (result.Parent != null)) { SetCurrentDeterminer(result.Parent); result = result.Parent; } return(CurrentSubSentence.IsExistSubject() ? result : parent); }
/// <summary> /// Извлечение из списка подпредложений первого подпредложения, /// которое является подпредложением одного из заданных типов /// </summary> /// <param name="types">коллекция типов</param> /// <returns>первое подходящее предложение</returns> private SubSentenceInfo PopFirstSubSentence(params SubSentenceType[] types) { SubSentenceInfo result = null; for (int i = 0; i < _subSentenceInfoList.Count; ++i) { if (IsAnyType(_subSentenceInfoList[i].SubSentence, types)) { result = _subSentenceInfoList[i]; _subSentenceInfoList.RemoveAt(i); break; } } return(result); }
/// <summary> /// Создание нового подпредложения /// </summary> /// <param name="last">последний юнит текущего подпредложения</param> public void CreateNewSubSentence(UnitTextBase last, bool isStrongPosition = false) { var separateUnit = isStrongPosition ? GetNextNearUnitSkipEmpty(last) : last.GetNonEmptyNext(); CurrentSubSentence.SubSentence.SetSubSentenceUnits(CurrentSubSentence.StartUnit, separateUnit); _subSentenceInfoList.Add(CurrentSubSentence); if (separateUnit != null) { CurrentSubSentence = new SubSentenceInfo(separateUnit, separateUnit.PositionInfo.Start); } else { CurrentSubSentence = null; } }
/// <summary> /// Установка определяемого слова для текущего подпредложения, являющегося причастным оборотом /// </summary> /// <param name="parent">родительское подпредложение</param> private void SetCurrentParticipialDeterminer(SubSentenceInfo parent) { Entity participle = CurrentSubSentence.Participles.First(); Entity lastEntity = (Entity)parent.SubSentence.Units.LastOrDefault(_ => _.UnitTextType == UnitTextType.ENTITY); if (lastEntity != null) { CurrentSubSentence.SubSentence.Subject = GetConsistencyEntity(lastEntity, participle); } if (!CurrentSubSentence.IsExistSubject() && (parent.SubSentence.Type == SubSentenceType.Participial)) { if (IsConsistency(parent.Participles.First(), participle)) { CurrentSubSentence.SubSentence.set_SubjectSubSentence(parent.SubSentence); } } }
/// <summary> /// Установка определяемого слова для текущего подпредложения, являющегося причастным или деепричастным оборотом /// </summary> /// <param name="parent">родительское подпредложение</param> private void SetCurrentDeterminer(SubSentenceInfo parent) { if (CurrentSubSentence.SubSentence.Type == SubSentenceType.DanglingParticiple) { SetCurrentDanglingParticipleDeterminer(parent); } else if (CurrentSubSentence.SubSentence.Type == SubSentenceType.Participial) { SetCurrentParticipialDeterminer(parent); } #region [.defense.] else { throw new ArgumentException("Current subsentence isn't DanglingParticiple or Participial"); } #endregion }
/// <summary> /// Установка субъекта для текущего подпредложения /// </summary> /// <param name="parent">родительское подпредложение</param> private void SetSubjectInCurrent(SubSentenceInfo parent) { SubSentenceType currentType = CurrentSubSentence.SubSentence.Type; if (currentType == SubSentenceType.DanglingParticiple) { SetCurrentDanglingParticipleDeterminer(parent); } else if (currentType == SubSentenceType.Participial) { SetCurrentParticipialDeterminer(parent); } else { SetCurrentSubject(); } }
/// <summary> /// Извлечение из списка подпредложений первой вершины /// </summary> /// <returns>первая вершина</returns> private SubSentenceInfo PopFirstTop() { SubSentenceInfo result = PopFirstSubSentence(SubSentenceType.Default); if (result == null) /// исключение: вообще нет дефолтного предложения - сделаем вершиной подчиненное { result = PopFirstSubSentence(SubSentenceType.Subordinate); if (result == null) /// исключение: нет и подчиненного - сделаем вершиной первое { var firstChild = _subSentenceInfoList.First(); result = new SubSentenceInfo(firstChild.SubSentence.StartPosition); result.SubSentence.SetUnits(new UnitTextBase[] { }); } } return(result); }
/// <summary> /// Получение подпредложения, являющегося самым последним элементом заданного родительского подпредложения /// </summary> /// <param name="parent">родительское подпредложение</param> /// <returns>подпредложение, являющееся самым последним элементом родительского подпредложения</returns> private SubSentenceInfo GetRightBorderSubSentence(SubSentenceInfo parent) { SubSentenceInfo result = parent.Childs.LastOrDefault(); if (result != null) { int subSentenceStart = result.SubSentence.StartPosition; foreach (var unit in parent.SubSentence.Units) { if (unit.PositionInfo.Start > subSentenceStart) { result = null; break; } } } return(result); }
/// <summary> /// Добавление в иерархию текущего дефолтного подпредложения /// </summary> /// <param name="topList">список подпредложений верхнего уровня</param> /// <param name="lastAdded">последнее добавленное подпредложение</param> private void AddCurrentDefaultToHierarchy(List <SubSentenceInfo> topList, SubSentenceInfo lastAdded) { SubSentenceInfo brother = lastAdded; if (GetCurrentBrother(ref brother, lastAdded)) { brother.Append(CurrentSubSentence); CurrentSubSentence = brother; } else if (brother.Parent != null) { brother.Parent.AddChild(CurrentSubSentence); } else { topList.Add(CurrentSubSentence); } }
/// <summary> /// Проверка, что текущее подпредложение должно быть частью предыдущего подпредложения /// </summary> /// <param name="previous">предыдущее подпредложение</param> /// <param name="lastAdded">последнее добавленное подпредложение</param> /// <returns>результат проверки</returns> private bool IsCurrentPartOfPrevious(SubSentenceInfo previous, SubSentenceInfo lastAdded) { if ((previous != null) && !CurrentSubSentence.IsExistSubject()) { bool isPossiblePart = true; if (previous == lastAdded) { UnitTextBase firstUnit = CurrentSubSentence.SubSentence.Units.FirstOrDefault(_ => !_.IsEmptyText()); if ((firstUnit != null) && !DictionaryResource.IsHomogeneousConjunction(firstUnit.Text)) /// подпредложения не будут соединены { isPossiblePart = false; UnitTextBase secondUnit = firstUnit.GetNonEmptyNext(); if (IsAnyType(previous.SubSentence, SubSentenceType.Subordinate) && !(CurrentSubSentence.IsContainConjunction || (firstUnit.IsSeparator(",") && (secondUnit != null) && DictionaryResource.IsHomogeneousConjunction(secondUnit.Text)))) /// не пытаемся восстановить подлежащее { return(false); } } } if (IsAnyType(previous.SubSentence, SubSentenceType.Default, SubSentenceType.Subordinate)) { if (IsCurrentSubject(previous.SubSentence.Subject)) { if (CurrentSubSentence.IsContainConjunction || (CurrentSubSentence.IsExistVerb() && previous.IsExistVerb())) { CurrentSubSentence.SubSentence.set_SubjectSubSentence(previous.SubSentence); } else { return(isPossiblePart); } } } else if (!CurrentSubSentence.IsContainConjunction) { return(isPossiblePart && IsCurrentPartOfPrevious(previous)); } } return(false); }
/// <summary> /// Установка определяемого слова для текущего подпредложения, являющегося деепричастным оборотом /// </summary> /// <param name="parent">родительское подпредложение</param> private void SetCurrentDanglingParticipleDeterminer(SubSentenceInfo parent) { if (parent.IsExistSubject()) { CurrentSubSentence.SubSentence.set_SubjectSubSentence(parent.SubSentence); } else /// определяемое слово - одушевленная сущность в дательном падеже { var dativeAnimation = parent.SubSentence.Units .Where(_ => _.UnitTextType == UnitTextType.ENTITY) .Select(_ => (Entity)_) .Where(_ => IsDativeAnimationEntity(_)); if (dativeAnimation.Count() == 1) { CurrentSubSentence.SubSentence.Subject = dativeAnimation.First(); } } }
/// <summary> /// Добавление информации о дочернем подпредложении /// </summary> /// <param name="child">информация о дочернем подпредложении</param> public void AddChild(SubSentenceInfo child) { Childs.Add(child); child.Parent = this; }
public SubSentenceHierarchy(SubSentence source) { _subSentenceInfoList = new List <SubSentenceInfo>(); CurrentSubSentence = new SubSentenceInfo(source.Units.First(), source.StartPosition); _sourceSubSentence = source; }
/// <summary> /// Добавление в иерархию текущего предложения /// </summary> /// <param name="topList">список подпредложений верхнего уровня</param> /// <param name="previous">последнее добавленное подпредложение</param> private void AddCurrentSubSentenceToHierarchy(List <SubSentenceInfo> topList, SubSentenceInfo previous) { switch (CurrentSubSentence.SubSentence.Type) { case SubSentenceType.Default: AddCurrentDefaultToHierarchy(topList, previous); break; case SubSentenceType.DanglingParticiple: case SubSentenceType.Participial: AddCurrentDanglingParticipleOrParticipialToHierarchy(previous); break; case SubSentenceType.Subordinate: case SubSentenceType.AdjunctPhrase: previous.AddChild(CurrentSubSentence); break; } }