in languagetool-language-modules/de/src/main/java/org/languagetool/rules/de/CaseRule.java [1188:1242]
private boolean isAdjectiveAsNoun(int i, AnalyzedTokenReadings[] tokens, AnalyzedTokenReadings lowercaseReadings) {
AnalyzedTokenReadings prevToken = i > 0 ? tokens[i-1] : null;
AnalyzedTokenReadings nextReadings = i < tokens.length-1 ? tokens[i+1] : null;
AnalyzedTokenReadings prevLowercaseReadings = null;
if (i > 1 && StringUtils.equalsAny(tokens[i-2].getToken(), SENTENCE_START_EXCEPTIONS)) {
prevLowercaseReadings = lookup(prevToken.getToken().toLowerCase());
}
// ignore "Der Versuch, Neues zu lernen / Gutes zu tun / Spannendes auszuprobieren"
boolean isPossiblyFollowedByInfinitive = nextReadings != null && nextReadings.getToken().equals("zu");
boolean isFollowedByInfinitive = nextReadings != null && !isPossiblyFollowedByInfinitive && nextReadings.hasPartialPosTag("EIZ");
boolean isFollowedByPossessiveIndicator = nextReadings != null && StringUtils.equalsAny(nextReadings.getToken(),POSSESSIVE_INDICATORS);
boolean isUndefQuantifier = prevToken != null && StringUtils.equalsAny(prevToken.getToken().toLowerCase(), UNDEFINED_QUANTIFIERS);
boolean isPrevDeterminer = prevToken != null
&& (hasPartialTag(prevToken, "ART", "PRP", "ZAL") || hasPartialTag(prevLowercaseReadings, "ART", "PRP", "ZAL"))
&& !prevToken.hasPartialPosTag(":STD");
boolean isPrecededByVerb = prevToken != null && prevToken.matchesPosTagRegex("VER:(MOD:|AUX:)?[1-3]:.*") && !prevToken.hasLemma("sein");
if (!isPrevDeterminer && !isUndefQuantifier && !(isPossiblyFollowedByInfinitive || isFollowedByInfinitive)
&& !(isPrecededByVerb && lowercaseReadings != null && hasPartialTag(lowercaseReadings, "ADJ:", "PA") && nextReadings != null &&
!StringUtils.equalsAny(nextReadings.getToken(), "und", "oder", ","))
&& !(isFollowedByPossessiveIndicator && hasPartialTag(lowercaseReadings, "ADJ", "VER")) // "Wacht auf, Verdammte dieser Welt!"
&& !(prevToken != null && prevToken.hasPosTag("KON:UNT") && !hasNounReading(nextReadings) && nextReadings != null && !nextReadings.hasPosTag("KON:NEB"))) {
AnalyzedTokenReadings prevPrevToken = i > 1 && prevToken != null && prevToken.hasPartialPosTag("ADJ") ? tokens[i-2] : null;
// Another check to avoid false alarms for "eine Gruppe Aufständischer starb"
if (!isPrecededByVerb && lowercaseReadings != null && prevToken != null) {
if (prevToken.hasPartialPosTag("SUB:") && lowercaseReadings.matchesPosTagRegex("(ADJ|PA2):GEN:PLU:MAS:GRU:SOL.*")) {
return nextReadings != null && !nextReadings.hasPartialPosTag("SUB:");
} else if (nextReadings != null && nextReadings.getReadingsLength() == 1 && prevToken.hasPosTagStartingWith("PRO:PER:NOM:") && nextReadings.hasPosTag("ADJ:PRD:GRU")) {
// avoid false alarm "Weil er Unmündige sexuell missbraucht haben soll,..."
return true;
}
}
// Another check to avoid false alarms for "ein politischer Revolutionär"
if (!hasPartialTag(prevPrevToken, "ART", "PRP", "ZAL")) {
return false;
}
}
// ignore "die Ausgewählten" but not "die Ausgewählten Leute":
for (AnalyzedToken reading : tokens[i].getReadings()) {
String posTag = reading.getPOSTag();
if ((posTag == null || posTag.contains("ADJ")) && !hasNounReading(nextReadings) && !StringUtils.isNumeric(nextReadings != null ? nextReadings.getToken() : "")) {
if(posTag == null && hasPartialTag(lowercaseReadings, "PRP:LOK", "PA2:PRD:GRU:VER", "PA1:PRD:GRU:VER", "ADJ:PRD:KOM", "ADV:TMP")) {
// skip to avoid a false true for, e.g. "Die Zahl ging auf Über 1.000 zurück."/ "Dies gilt schon lange als Überholt." / "Bis Bald!"
// but not for "Er versuchte, Neues zu wagen."
} else {
return true;
}
}
}
return false;
}