All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.languagetool.rules.uk.TokenAgreementPrepNounExceptionHelper Maven / Gradle / Ivy

The newest version!
package org.languagetool.rules.uk;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import org.languagetool.AnalyzedTokenReadings;
import org.languagetool.rules.uk.RuleException.Type;
import org.languagetool.rules.uk.SearchHelper.Condition;
import org.languagetool.rules.uk.SearchHelper.Match;
import org.languagetool.tagging.uk.PosTagHelper;
import org.languagetool.rules.uk.TokenAgreementPrepNounRule.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TokenAgreementPrepNounExceptionHelper {
  private static final Logger logger = LoggerFactory.getLogger(TokenAgreementPrepNounExceptionHelper.class);

  private static final Set NAMES = new HashSet<>(Arrays.asList(
      "ім'я", "прізвище"
      ));
  
  public static RuleException getExceptionInfl(AnalyzedTokenReadings[] tokens, int i, State state) {
    AnalyzedTokenReadings tokenReadings = tokens[i];
    String token = tokenReadings.getCleanToken();
    String tokenLower = token.toLowerCase();
    String prep = state.prepTokenReadings.getCleanToken().toLowerCase();

    
    // на дивом уцілілій техніці
    if( tokenReadings.getToken().equals("дивом") )
      return new RuleException(0);

    // в тисяча шістсот якомусь році
    if( i < tokens.length - 1 
        && tokenReadings.getToken().equals("тисяча")
        && PosTagHelper.hasPosTagPart(tokens[i+1], "numr")) {
      return new RuleException(0);
    }
    // в дев'яносто восьмому
    if( i < tokens.length - 1 
        //tokenReadings.getToken().equals("тисяча")
        && PosTagHelper.hasPosTagPart(tokenReadings, "numr") && PosTagHelper.hasPosTagPart(tokenReadings, "v_naz")
        && PosTagHelper.hasPosTagPart(tokens[i+1], "numr") && PosTagHelper.hasPosTag(tokenReadings, Pattern.compile(".*v_(rod|dav|zna|oru|mis).*")) ) {
      return new RuleException(1);
    }

    if (prep.equals("на")) {
      // 1) на (свято) Купала, на (вулиці) Мазепи, на (вулиці) Тюльпанів
      if (LemmaHelper.isCapitalized(token) && PosTagHelper.hasPosTag(tokenReadings, Pattern.compile("noun.*?:.:v_rod.*"))) {
        return new RuleException(Type.exception);
      } 
      if (PosTagHelper.hasPosTag(tokenReadings, Pattern.compile("noun:anim:.:v_naz:prop:[fl]name.*"))
          && ((i > 1 && NAMES.contains(tokens[i-2].getAnalyzedToken(0).getToken()))
              || (i > 2 && NAMES.contains(tokens[i-3].getAnalyzedToken(0).getLemma())))) {
        return new RuleException(Type.exception);
      }

      // handled by xml rule
      if( token.equals("манер") ) {
        return new RuleException(Type.exception);
      }
      // на біс (TODO: можливо краще tag=intj?)
      if( tokenLower.equals("біс") ) {
        return new RuleException(Type.exception);
      }
    }

    // TODO: temporary until we have better logic - skip
    // при їх виборі
    if( prep.equals("при") ) {
      if( token.equals("їх") ) {
        return new RuleException(Type.skip);
      }
    }
    else
      if( prep.equals("з") ) {
        if( token.equals("рана") ) {
          return new RuleException(Type.exception);
        }
      }
      else
        if( prep.equals("від") ) {
          if( token.equalsIgnoreCase("а") || token.equals("рана") || token.equals("корки") || token.equals("мала") ) {  // корки/мала ловиться іншим правилом
            return new RuleException(Type.exception);
          }
        }
        else if( prep.equals("до") ) {
          if( token.equalsIgnoreCase("я") || token.equals("корки") || token.equals("велика") ) {  // корки/велика ловиться іншим правилом
            return new RuleException(Type.exception);
          }
        }

    
    // exceptions
    if( tokens.length > i+1 ) {
      //      if( tokens.length > i+1 && Character.isUpperCase(tokenReadings.getAnalyzedToken(0).getToken().charAt(0))
      //        && hasRequiredPosTag(Arrays.asList("v_naz"), tokenReadings)
      //        && Character.isUpperCase(tokens[i+1].getAnalyzedToken(0).getToken().charAt(0)) )
      //          continue; // "у Конан Дойла", "у Робін Гуда"

      // по Пенсильванія авеню
//      if( LemmaHelper.isCapitalized( token ) 
//          && LemmaHelper.CITY_AVENU.contains( tokens[i+1].getAnalyzedToken(0).getToken().toLowerCase() ) ) {
//        return new RuleException(Type.exception);
//      }

      // від мінус 1 до плюс 1
      if( (PosTagHelper.hasPosTagStart(tokens[i+1], "num")
            || tokens[i+1].getToken().equals("$"))
          && LemmaHelper.PLUS_MINUS.contains(tokenLower) ) {
        return new RuleException(Type.exception);
      }

      // на мохом стеленому дні - пропускаємо «мохом»
      if( PosTagHelper.hasPosTag(tokenReadings, "noun.*?:v_oru.*")
          && tokens[i+1].hasPartialPosTag("adjp:pasv") ) {
        return new RuleException(1);
      }

      if( token.equals("святая")
          && tokens[i+1].getToken().equals("святих") ) {
        return new RuleException(Type.exception);
      }

      if( (prep.equals("через") || prep.equals("на"))  // років 10, відсотки 3-4
          && (//PosTagHelper.hasPosTagStart(tokenReadings, "noun:inanim:p:v_naz") 
//              || PosTagHelper.hasPosTagStart(tokenReadings, "noun:inanim:p:v_rod")) // token.equals("років")
              LemmaHelper.hasLemma(tokenReadings, LemmaHelper.TIME_PLUS_LEMMAS, Pattern.compile("noun:inanim:p:v_(rod|zna).*")))
          && (tokens[i+1].hasPartialPosTag("num") // IPOSTag.isNum(tokens[i+1].getAnalyzedToken(0).getPOSTag())
              // відсотки зо 3
              || (i i+2 ) {
        // спиралося на місячної давнини рішення
        if (/*prep.equals("на") &&*/ PosTagHelper.hasPosTag(tokenReadings, "adj:[mfn]:v_rod.*")) {
          String genders = PosTagHelper.getGenders(tokenReadings, "adj:[mfn]:v_rod.*");

          if ( PosTagHelper.hasPosTag(tokens[i+1], "noun.*?:["+genders+"]:v_rod.*")) {
            i += 1;
            return new RuleException(1);
          }
        }

        if( // (token.equals("нікому") || token.equals("ніким") || token.equals("нічим") || token.equals("нічому"))
          PosTagHelper.hasPosTag(tokenReadings, Pattern.compile("noun.*v_(dav|oru):&pron:neg.*"))
            && tokens[i+1].getCleanToken().equals("не")) {
          //          reqTokenReadings = null;
          return new RuleException(Type.skip);
        }
      }
    }

    return new RuleException(Type.none);
  }

  public static RuleException getExceptionStrong(AnalyzedTokenReadings[] tokens, int i, AnalyzedTokenReadings prepTokenReadings) {
    AnalyzedTokenReadings tokenReadings = tokens[i];
    String token = tokenReadings.getCleanToken();
    String tokenLower = token.toLowerCase();
    String prep = prepTokenReadings.getCleanToken().toLowerCase();

    

    // TODO: make it more generic
//    if( tokenLower.equals("брати") ) {
//      prepTokenReadings = null;
//      continue;
//    }

    // TODO: про вчора, щодо завтра

    if( prep.equals("до") || prep.equals("по") ) {
      if( tokenLower.matches("сьогодні|[ву]чора|позавчора|(після)?завтра|тепер|зараз|нині|опівдня|опівночі|досі|навпаки") ) {
        return new RuleException(Type.exception);
      }
    }

    if( prep.equals("на") || prep.equals("від") || prep.equals("про") ) {
      if( tokenLower.matches("сьогодні|[ву]чора|позавчора|(після)?завтра|тепер|зараз|нині|тоді|потім|щодень|повсякдень") ) {
        return new RuleException(Type.exception);
      }
    }

    if( prep.matches("за|зі?|із") ) {
      if( tokenLower.matches("сьогодні|[ву]чора|позавчора|(після)?завтра") ) {
        return new RuleException(Type.exception);
      }
    }

    if( prep.equals("в") || prep.equals("у") ) {
      if( Arrays.asList("нікуди").contains(tokenLower) ) {
        return new RuleException(Type.exception);
      }
    }

    // помилка: до не властиву йому функцію
    if( i < tokens.length - 1
        && token.equals("не")
        && PosTagHelper.hasPosTagStart(tokens[i+1], "ad") )
      return new RuleException(0);

//    "чимало|стільки|обмаль"
    
    // про чимало обмежень
    if( i < tokens.length - 1 
        && LemmaHelper.ADV_QUANT_PATTERN.matcher(tokenLower).matches() ) {
      return new RuleException(Type.exception);
    }

    // за цілком собі реалістичною соціальною
    if( PosTagHelper.hasPosTagAll(tokenReadings.getReadings(), Pattern.compile("adv(?!p).*"))) {
      if( i < tokens.length - 1 
          && tokens[i+1].getCleanToken().equals("собі") ) { 
        return new RuleException(1);
      }
      return new RuleException(0);
    }

    // замість вже самому засвоїти
    if( prep.equals("замість") ) {
      if( new Match()
          .target(Condition.postag(Pattern.compile("verb.*:inf.*")))
          .limit(4)
          .skip(Condition.token("можна").negate())
          .mAfter(tokens, i+1) > 0 ) {
        return new RuleException(Type.exception);
      }
    }

    // Усупереч не те що лихим
    if( new Match().tokenLine("не те").mBefore(tokens, i) > 0 ) {
      return new RuleException(Type.exception);
    }

    return new RuleException(Type.none);
  }

  public static RuleException getExceptionNonInfl(AnalyzedTokenReadings[] tokens, int i, State state) {
    AnalyzedTokenReadings tokenReadings = tokens[i];
    String token = tokenReadings.getCleanToken();
//    String prep = prepTokenReadings.getCleanToken().toLowerCase();

//    if( PosTagHelper.hasPosTagPart(tokenReadings, "insert") )
//      return new RuleException(0);

    if( PosTagHelper.hasPosTagStart(tokenReadings, "part") ) {
      if( LemmaHelper.PART_INSERT_PATTERN.matcher(token.toLowerCase()).matches() ) {
        return new RuleException(0);
      }
    }

   // if( i < tokens.length - 1 && token.equals("їх") && PosTagHelper.hasPosTag(tokens[i+1], Pattern.compile("(adj|noun).*")) ) {
     // return new RuleException(Type.skip);
   // }

    if( token.matches("лиш(е(нь)?)?") ) {
      return new RuleException(0);
    }

    if( tokenReadings.getToken().equals("наприклад") )
      return new RuleException(0);

    if( PosTagHelper.hasPosTag(tokenReadings, Pattern.compile("adv(?!p).*")) ) {
      // по швидко напруженим рукам
      if( i < tokens.length -1 
          && PosTagHelper.hasPosTagStart(tokens[i+1], "adj")
          && PosTagHelper.hasPosTagPartAll(tokenReadings, "adv") )
        return new RuleException(0);
     
      return new RuleException(Type.exception);
    }

    if( tokens.length > i+1 ) {
      // на лише їм відомому ...
      // на вже всім відомому ...
      if ( PosTagHelper.hasPosTag(tokens[i], Pattern.compile("noun:(un)?anim:.:v_dav:&pron.*")) ) {
          if( PosTagHelper.hasPosTagStart(tokens[i+1], "adj")
              && CaseGovernmentHelper.hasCaseGovernment(tokens[i+1], "v_dav") )
          return new RuleException(1);

          if( tokens.length > i+2
              && PosTagHelper.hasPosTagStart(tokens[i+1], "adv")
              && PosTagHelper.hasPosTagStart(tokens[i+2], "adj")
              && CaseGovernmentHelper.hasCaseGovernment(tokens[i+2], "v_dav") )
          return new RuleException(2);
        }
    }    
    if( tokens.length > i+2 ) {
      // на нічого не вартий папірець
      if ( token.equals("нічого")
          && tokens[i+1].getToken().equals("не")
          && PosTagHelper.hasPosTagStart(tokens[i+2], "adj")
          ) {
        return new RuleException(1);
      }
    }
    return new RuleException(Type.none);
  }


  static void logException() {
    if( logger.isDebugEnabled() ) {
      StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3];
      logger.debug("exception: " /*+ stackTraceElement.getFileName()*/ + stackTraceElement.getLineNumber());
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy