Revision: 7717
          
http://languagetool.svn.sourceforge.net/languagetool/?rev=7717&view=rev
Author:   gulp21-1
Date:     2012-07-18 11:05:58 +0000 (Wed, 18 Jul 2012)
Log Message:
-----------
[de] replace ICH_BIST and ER_BIST with a more powerful java rule
     remove DU_ERHAELST as the error is detected by the spell checker
[zh] change id of WORD_REPEAT_BEGINNING_RULE so that there is no conflict

Modified Paths:
--------------
    trunk/JLanguageTool/src/java/org/languagetool/language/German.java
    
trunk/JLanguageTool/src/java/org/languagetool/rules/zh/ChineseWordRepeatBeginningRule.java
    trunk/JLanguageTool/src/rules/de/grammar.xml

Added Paths:
-----------
    
trunk/JLanguageTool/src/java/org/languagetool/rules/de/VerbAgreementRule.java
    
trunk/JLanguageTool/src/test/org/languagetool/rules/de/VerbAgreementRuleTest.java

Modified: trunk/JLanguageTool/src/java/org/languagetool/language/German.java
===================================================================
--- trunk/JLanguageTool/src/java/org/languagetool/language/German.java  
2012-07-18 09:49:52 UTC (rev 7716)
+++ trunk/JLanguageTool/src/java/org/languagetool/language/German.java  
2012-07-18 11:05:58 UTC (rev 7717)
@@ -36,6 +36,7 @@
 import org.languagetool.rules.de.GermanWordRepeatBeginningRule;
 import org.languagetool.rules.de.GermanWordRepeatRule;
 import org.languagetool.rules.de.GermanWrongWordInContextRule;
+import org.languagetool.rules.de.VerbAgreementRule;
 import org.languagetool.rules.de.WiederVsWiderRule;
 import org.languagetool.rules.de.WordCoherencyRule;
 import org.languagetool.rules.spelling.hunspell.HunspellNoSuggestionRule;
@@ -126,6 +127,7 @@
             CaseRule.class,
             CompoundRule.class,
             DashRule.class,
+            VerbAgreementRule.class,
             WordCoherencyRule.class,
             WiederVsWiderRule.class
     );

Added: 
trunk/JLanguageTool/src/java/org/languagetool/rules/de/VerbAgreementRule.java
===================================================================
--- 
trunk/JLanguageTool/src/java/org/languagetool/rules/de/VerbAgreementRule.java   
                            (rev 0)
+++ 
trunk/JLanguageTool/src/java/org/languagetool/rules/de/VerbAgreementRule.java   
    2012-07-18 11:05:58 UTC (rev 7717)
@@ -0,0 +1,288 @@
+/* LanguageTool, a natural language style checker 
+ * Copyright (C) 2005 Daniel Naber (http://www.danielnaber.de)
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ */
+package org.languagetool.rules.de;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import org.languagetool.AnalyzedSentence;
+import org.languagetool.AnalyzedToken;
+import org.languagetool.AnalyzedTokenReadings;
+import org.languagetool.JLanguageTool;
+import org.languagetool.Language;
+import org.languagetool.rules.Category;
+import org.languagetool.rules.RuleMatch;
+import org.languagetool.tools.StringTools;
+
+/**
+ * Simple agreement checker for German verbs and subject. Checks agreement in:
+ * 
+ * <ul>
+ *  <li>VER:1:SIN w/o ich: e.g. "Max bin da." (incorrect) [same for VER:2:SIN 
w/o du, VER:1:PLU w/o wir]</li>
+ *  <li>ich + VER:[123]:.* (not VER:1:SIN): e.g. "ich bist" (incorrect) [same 
for du, er, wir]</li> 
+ * </ul>
+ * 
+ * TODO
+ * wenn nur ein mögliches finites Verb -> das nehmen (Max machen das.)
+ * Sie (i>1)
+ * bei ich/du/er/wir sofort prüfen, damit alle vorkommen geprüft werden (Ich 
geht jetzt nach Hause und dort gehe ich sofort unter die Dusche.) [aber: isNear]
+ *
+ * @author Markus Brenneis
+ */
+public class VerbAgreementRule extends GermanRule {
+  
+  private AnalyzedTokenReadings finiteVerb;
+  
+  private static final Set<String> BIN_IGNORE = new 
HashSet<String>(Arrays.asList(
+    "Abdullah",
+    "Isa",
+    "Osama",
+    "Turki"
+  ));
+  
+  private static final Set<String> QUOTATION_MARKS = new 
HashSet<String>(Arrays.asList(
+    "\"", "„"
+  ));
+    
+  public VerbAgreementRule(final ResourceBundle messages) {
+    if (messages != null)
+      super.setCategory(new Category(messages.getString("category_grammar")));
+  }
+  
+  @Override
+  public String getId() {
+    return "DE_VERBAGREEMENT";
+  }
+  
+  @Override
+  public String getDescription() {
+    return "Kongruenz von Subjekt und Prädikat (nur 1. u. 2. Pers. od. m. 
Personalpronomen), z.B. 'Er bist (ist)'";
+  }
+  
+  @Override
+  public RuleMatch[] match(final AnalyzedSentence text) {
+    
+    final List<RuleMatch> ruleMatches = new ArrayList<RuleMatch>();
+    AnalyzedTokenReadings[] tokens = text.getTokensWithoutWhitespace();
+    
+    if (tokens.length < 4) // ignore one-word sentences (3 tokens: SENT_START, 
one word, SENT_END)
+      return toRuleMatchArray(ruleMatches);
+    
+    // position of the pronouns
+    int posIch = -1, posDu = -1, posEr = -1, posWir = -1;
+    // positions of verbs which do match in person and number, and do not 
match any other person nor number
+    int posVer1Sin = -1, posVer2Sin = -1, posVer1Plu = -1, posVer2Plu = -1;
+    // positions of verbs which do match in person and number
+    int posPossibleVer1Sin = -1, posPossibleVer2Sin = -1, posPossibleVer3Sin = 
-1,
+        posPossibleVer1Plu = -1, posPossibleVer2Plu = -1;
+    
+    for (int i = 1; i < tokens.length; ++i) { // ignore SENT_START
+      
+      String strToken = tokens[i].getToken().toLowerCase();
+      strToken = strToken.replace("‚","");
+      
+      if (strToken.equals("ich")) {
+        posIch = i;
+      } else if (strToken.equals("du")) {
+        posDu = i;
+      } else if (strToken.equals("er")) {
+        posEr = i;
+      } else if (strToken.equals("wir")) {
+        posWir = i;
+      }
+      
+      if (tokens[i].hasPartialPosTag("VER")
+          && (Character.isLowerCase(tokens[i].getToken().charAt(0)) || i == 1) 
) {
+        if (hasUnambiguouslyPersonAndNumber(tokens[i], "1", "SIN")
+            && !(strToken.equals("bin") && 
(BIN_IGNORE.contains(tokens[i-1].getToken())
+                  || (tokens.length != i + 1 && 
tokens[i+1].getToken().startsWith("Laden")) ))) {
+          posVer1Sin = i;
+        } 
+        else if (hasUnambiguouslyPersonAndNumber(tokens[i], "2", "SIN")) {
+          posVer2Sin = i;
+        } else if (hasUnambiguouslyPersonAndNumber(tokens[i], "1", "PLU")) {
+          posVer1Plu = i;
+        } else if (hasUnambiguouslyPersonAndNumber(tokens[i], "2", "PLU")) {
+          posVer2Plu = i;
+        }
+        
+        if (tokens[i].hasPartialPosTag(":1:SIN"))
+          posPossibleVer1Sin = i;
+        if (tokens[i].hasPartialPosTag(":2:SIN"))
+          posPossibleVer2Sin = i;
+        if (tokens[i].hasPartialPosTag(":3:SIN"))
+          posPossibleVer3Sin = i;
+        if (tokens[i].hasPartialPosTag(":1:PLU"))
+          posPossibleVer1Plu = i;
+        if (tokens[i].hasPartialPosTag(":2:PLU"))
+          posPossibleVer2Plu = i;
+        
+      }
+           
+    } // for each token
+      
+    // "ich", "du", and "wir" must be subject (no other interpretation 
possible)
+    // "ich", "du", "er", and "wir" must have a matching verb
+    
+    if (posVer1Sin != -1 && posIch == -1 && 
!isQuotationMark(tokens[posVer1Sin-1])) { // 1st pers sg verb but no "ich"
+      ruleMatches.add(ruleMatchWrongVerb(tokens[posVer1Sin]));
+    } else if (posIch > 0 && !isNear(posPossibleVer1Sin, posIch) // check 
whether verb next to "ich" is 1st pers sg
+               && (tokens[posIch].getToken().equals("ich") || 
tokens[posIch].getStartPos() == 0) // ignore "lyrisches Ich" etc.
+               && !isQuotationMark(tokens[posIch-1])) {
+      int plus1 = ((posIch + 1) == tokens.length) ? 0 : +1; // prevent 
posIch+1 segfault
+      if (!verbDoesMatchPersonAndNumber(tokens[posIch-1], 
tokens[posIch+plus1], "1", "SIN")) {
+        ruleMatches.add(ruleMatchWrongVerbSubject(tokens[posIch], finiteVerb));
+      }
+    }
+    
+    if (posVer2Sin != -1 && posDu == -1 && 
!isQuotationMark(tokens[posVer2Sin-1])) {
+      ruleMatches.add(ruleMatchWrongVerb(tokens[posVer2Sin]));
+    } else if (posDu > 0 && !isNear(posPossibleVer2Sin, posDu) && 
!isQuotationMark(tokens[posDu-1])) {
+      int plus1 = ((posDu + 1) == tokens.length) ? 0 : +1;
+      if (!verbDoesMatchPersonAndNumber(tokens[posDu-1], tokens[posDu+plus1], 
"2", "SIN")) {
+        ruleMatches.add(ruleMatchWrongVerbSubject(tokens[posDu], finiteVerb));
+      }
+    }
+    
+    if (posEr > 0 && !isNear(posPossibleVer3Sin, posEr) && 
!isQuotationMark(tokens[posEr-1])) {
+      int plus1 = ((posEr + 1) == tokens.length) ? 0 : +1;
+      if (!verbDoesMatchPersonAndNumber(tokens[posEr-1], tokens[posEr+plus1], 
"3", "SIN")) {
+        ruleMatches.add(ruleMatchWrongVerbSubject(tokens[posEr], finiteVerb));
+      }
+    }
+    
+    if (posVer1Plu != -1 && posWir == -1 && 
!isQuotationMark(tokens[posVer1Plu-1])) {
+      ruleMatches.add(ruleMatchWrongVerb(tokens[posVer1Plu]));
+    } else if (posWir > 0 && !isNear(posPossibleVer1Plu, posWir) && 
!isQuotationMark(tokens[posWir-1])) {
+      int plus1 = ((posWir + 1) == tokens.length) ? 0 : +1;
+      if (!verbDoesMatchPersonAndNumber(tokens[posWir-1], 
tokens[posWir+plus1], "1", "PLU")) {
+        ruleMatches.add(ruleMatchWrongVerbSubject(tokens[posWir], finiteVerb));
+      }
+    }
+    
+    return toRuleMatchArray(ruleMatches);
+    
+  }
+  
+  /**
+   * @return true if |@param a - @param b| &lt; 5, and a != -1 
+   */
+  
+  private boolean isNear(final int a, final int b) {
+    return ((Math.abs(a - b) < 5) && a != -1);
+  }
+  
+  private boolean isQuotationMark(final AnalyzedTokenReadings token) {
+    return QUOTATION_MARKS.contains(token.getToken());
+  }
+  
+  /**
+   * @return true if the verb @param token (if it is a verb) matches @param 
person and @param number, and matches no other person/number
+   */
+  private boolean hasUnambiguouslyPersonAndNumber(final AnalyzedTokenReadings 
token, final String person, final String number) {
+    if (token.getToken().length() == 0
+        || (Character.isUpperCase(token.getToken().charAt(0)) && 
!(token.getStartPos() == 0) )
+        || !token.hasPartialPosTag("VER"))
+      return false;
+    
+    for (int i = 0; i < token.getReadingsLength(); ++i) {
+      String postag = token.getReadings().get(i).getPOSTag();
+      if (postag.contains("_END")) // ignore SENT_END and PARA_END
+        continue;
+      if (!postag.contains(":" + person + ":" + number))
+        return false;
+    } // for each reading
+    
+    return true;
+  }
+  
+  /**
+   * @return true if @param token is a finite verb, and it is no pronoun or 
number
+   */
+  private boolean isFiniteVerb(final AnalyzedTokenReadings token) {
+    if (token.getToken().length() == 0
+        || (Character.isUpperCase(token.getToken().charAt(0)) && 
token.getStartPos() != 0)
+        || !token.hasPartialPosTag("VER")
+        || token.hasPartialPosTag("PRO:")
+        || token.hasPartialPosTag("ZAL"))
+      return false;
+    
+    return (token.hasPartialPosTag(":1:") || token.hasPartialPosTag(":2:") || 
token.hasPartialPosTag(":3:"));
+  }
+  
+  /**
+   * @return false if neither the verb @param token1 (if any) nor @param 
token2 match @param person and @param number, and none of them is "und" or ","
+   * if a finite verb is found, it is saved in finiteVerb
+   */
+  private boolean verbDoesMatchPersonAndNumber(final AnalyzedTokenReadings 
token1, final AnalyzedTokenReadings token2,
+                                               final String person, final 
String number) {
+   if (token1.getToken().equals(",") || token1.getToken().equals("und") ||
+       token2.getToken().equals(",") || token2.getToken().equals("und"))
+    return true;
+   
+    boolean foundFiniteVerb = false;
+    
+    if (isFiniteVerb(token1)) {
+      foundFiniteVerb = true;
+      finiteVerb = token1;
+      if (token1.hasPartialPosTag(":" + person + ":" + number)) {
+        return true;
+      }
+    }
+    
+    if (isFiniteVerb(token2)) {
+      foundFiniteVerb = true;
+      finiteVerb = token2;
+      if (token2.hasPartialPosTag(":" + person + ":" + number)) {
+        return true;
+      }
+    }
+    
+    return !foundFiniteVerb;
+  }
+  
+  private RuleMatch ruleMatchWrongVerb(final AnalyzedTokenReadings token) {
+    final String msg = "Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt und Prädikat (" +
+      token.getToken() + ") bezüglich Person oder Numerus (Einzahl, Mehrzahl - 
Beispiel: " +
+      "'Max bist' statt 'Max ist').";
+    return new RuleMatch(this, token.getStartPos(), token.getStartPos() + 
token.getToken().length(), msg);
+  }
+  
+  private RuleMatch ruleMatchWrongVerbSubject(final AnalyzedTokenReadings 
subject, final AnalyzedTokenReadings verb) {
+    final String msg = "Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (" + subject.getToken() +
+      ") und Prädikat (" + verb.getToken() + ") bezüglich Person oder Numerus 
(Einzahl, Mehrzahl - Beispiel: " +
+      "'ich sind' statt 'ich bist').";
+    if (subject.getStartPos() < verb.getStartPos()) {
+      return new RuleMatch(this, subject.getStartPos(), verb.getStartPos() + 
verb.getToken().length(), msg);
+    } else {
+      return new RuleMatch(this, verb.getStartPos(), subject.getStartPos() + 
subject.getToken().length(), msg);
+    }
+  }
+  
+  @Override
+  public void reset() {
+    finiteVerb = null;
+  }
+
+}

Modified: 
trunk/JLanguageTool/src/java/org/languagetool/rules/zh/ChineseWordRepeatBeginningRule.java
===================================================================
--- 
trunk/JLanguageTool/src/java/org/languagetool/rules/zh/ChineseWordRepeatBeginningRule.java
  2012-07-18 09:49:52 UTC (rev 7716)
+++ 
trunk/JLanguageTool/src/java/org/languagetool/rules/zh/ChineseWordRepeatBeginningRule.java
  2012-07-18 11:05:58 UTC (rev 7717)
@@ -24,7 +24,7 @@
 
          @Override
          public String getId() {
-           return "WORD_REPEAT_BEGINNING_RULE";
+           return "CHINESE_WORD_REPEAT_BEGINNING_RULE";
          }
 
          @Override

Modified: trunk/JLanguageTool/src/rules/de/grammar.xml
===================================================================
--- trunk/JLanguageTool/src/rules/de/grammar.xml        2012-07-18 09:49:52 UTC 
(rev 7716)
+++ trunk/JLanguageTool/src/rules/de/grammar.xml        2012-07-18 11:05:58 UTC 
(rev 7717)
@@ -2237,7 +2237,7 @@
             </rule>
         </rulegroup>
         <rulegroup id="DU_WUENSCHT" name="Möglicher Tippfehler: 'du wünscht 
(wünschst)'">
-            <!-- TODO this should becovered by ICH_BIST but isn't fully. -->
+            <!-- TODO this should be covered by VerbAgreementRule but isn't 
fully. -->
             <rule>
                 <pattern>
                     <token>du</token>
@@ -2261,30 +2261,6 @@
                 <example type="incorrect"><marker>Wünscht</marker> du dir mehr 
Zeit?</example>
             </rule>
         </rulegroup>
-        <rulegroup id="DU_ERHAELST" name="Möglicher Tippfehler: 'du erhälst 
(erhältst)'">
-            <rule>
-                <pattern>
-                    <token>du</token>
-                    <marker>
-                        <token>erhälst</token>
-                    </marker>
-                </pattern>
-                <message>Meinten Sie 
<suggestion>erhältst</suggestion>?</message>
-                <example type="correct">Du <marker>erhältst</marker> als 
Anlage mein Testament.</example>
-                <example type="incorrect">Du <marker>erhälst</marker> als 
Anlage mein Testament.</example>
-            </rule>
-            <rule>
-                <pattern>
-                    <marker>
-                        <token>erhälst</token>
-                    </marker>
-                    <token>du</token>
-                </pattern>
-                <message>Meinten Sie 
<suggestion>erhältst</suggestion>?</message>
-                <example type="correct">Als Anlage <marker>erhältst</marker> 
Du mein Testament.</example>
-                <example type="incorrect">Als Anlage <marker>erhälst</marker> 
Du mein Testament.</example>
-            </rule>
-        </rulegroup>
         <rule id="HIN_UNS_WIEDER" name="Möglicher Tippfehler: 'hin uns (und) 
wieder/her'">
             <pattern>
                 <token>hin</token>
@@ -17364,170 +17340,6 @@
             <example type="correct"><marker>Das Konzept eines intelligenten 
Autos ist nicht neu.</marker></example>
             <example type="correct"><marker>Das Auto.</marker></example>
         </rule>
-        <rulegroup id="ER_BIST" name="Grammatik: Kongruenz von Subjekt und 
Prädikat (nur 1. u. 2. Person), z.B. 'Er bist (ist)'">
-            <!-- TODO the same for 1:SIN, 2:PLU, and 3:PLU, maybe a Java-rule 
would be easier -->
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START" skip="5"><exception 
scope="next" regexp="yes">[Dd]u</exception></token>
-                    <marker>
-                        <token postag="VER.*:2:SIN.*" postag_regexp="yes" 
regexp="yes" skip="-1">[a-zäüö].*<exception scope="current" 
postag="VER.*:2:SIN.*" postag_regexp="yes" negate_pos="yes"/><exception 
scope="next" regexp="yes">[Dd]u</exception></token>
-                    </marker>
-                    <token postag="SENT_END"></token>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt und Prädikat (\2) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'er bist' statt 'er ist').</message>
-                <example type="correct">Die Unterlagen 
<marker>solltet</marker> ihr gründlich durcharbeiten.</example>
-                <example type="incorrect">Die Unterlagen 
<marker>solltest</marker> ihr gründlich durcharbeiten.</example>
-<!--                 <example type="incorrect"><marker>Solltest</marker> ihr 
das machen?</example> TODO -->
-                <example type="correct">Er reagierte <marker>äußerst</marker> 
negativ.</example>
-            </rule>
-        </rulegroup>
-        <rulegroup id="ICH_BIST" name="Grammatik: Kongruenz von Subjekt (nur 
Personalpronomen!) und Prädikat, z.B. 'Ich bist (bin)'">
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START"></token>
-                    <marker>
-                        <token>Ich</token>
-                        <token postag="VER.*:[123]:.*" postag_regexp="yes" 
regexp="yes">[a-zäüö].*<exception postag="VER.*:1:SIN.*" 
postag_regexp="yes"/></token>
-                    </marker>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (\2) und Prädikat (\3) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'ich sind' statt 'ich bin').</message>
-                <example type="correct"><marker>Ich bin</marker> 
nett.</example>
-                <example type="incorrect"><marker>Ich bist</marker> 
nett.</example>
-                <example type="correct"><marker>Ich kann</marker> heute leider 
nicht kommen.</example>
-                <example type="incorrect"><marker>Ich kannst</marker> heute 
leider nicht kommen.</example>
-                <example type="correct"><marker>Ich lebe</marker>.</example>
-                <example type="incorrect"><marker>Ich leben</marker>.</example>
-                <example type="correct">Er und <marker>ich 
leben</marker>.</example>
-            </rule>
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START"></token>
-                    <token skip="1"></token>
-                    <marker>
-                        <token postag="VER.*:[123]:.*" postag_regexp="yes" 
regexp="yes">[a-zäüö].*<exception postag="VER.*:1:SIN.*" 
postag_regexp="yes"/></token>
-                        <token skip="-1">ich<exception 
scope="next">und</exception></token>
-                    </marker>
-                    <token postag="SENT_END"></token>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (\4) und Prädikat (\3) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'ich sind' statt 'ich bin').</message>
-                <example type="correct">Nett <marker>bin 
ich</marker>.</example>
-                <example type="incorrect">Nett <marker>bist ich</marker> 
nicht.</example>
-                <example type="correct">Auch morgen <marker>lebe 
ich</marker>.</example>
-                <example type="incorrect">Auch morgen <marker>leben 
ich</marker>.</example>
-                <example type="correct">Morgen <marker>kommen ich</marker> und 
sie.</example>
-            </rule>
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START"></token>
-                    <marker>
-                        <token>Du</token>
-                        <token postag="VER.*:[123]:.*" postag_regexp="yes" 
regexp="yes">[a-zäüö].*<exception postag="VER.*:2:SIN.*" 
postag_regexp="yes"/></token>
-                    </marker>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (\2) und Prädikat (\3) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'du seid' statt 'du bist').</message>
-                <example type="correct"><marker>Du bist</marker> 
nett.</example>
-                <example type="incorrect"><marker>Du bin</marker> 
nett.</example>
-                <example type="correct"><marker>Du kannst</marker> heute 
leider nicht kommen.</example>
-                <example type="incorrect"><marker>Du können</marker> heute 
leider nicht kommen.</example>
-                <example type="correct"><marker>Du lebst</marker>.</example>
-                <example type="incorrect"><marker>Du leben</marker>.</example>
-                <example type="correct">Er und <marker>du 
leben</marker>.</example>
-                <example type="correct"><marker>Du wünschst</marker> dir so 
viel.</example>
-                <example type="incorrect"><marker>Du wünscht</marker> dir so 
viel.</example>
-            </rule>
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START" skip="2"></token>
-                    <token skip="1"></token>
-                    <marker>
-                        <token postag="VER.*:[123]:.*" postag_regexp="yes" 
regexp="yes">[a-zäüö].*<exception postag="VER.*:2:SIN.*" 
postag_regexp="yes"/></token>
-                        <token skip="-1">du<exception 
scope="next">und</exception></token>
-                    </marker>
-                    <token postag="SENT_END"></token>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (\4) und Prädikat (\3) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'du seid' statt 'du bist').</message>
-                <example type="correct">Nett <marker>bist 
du</marker>.</example>
-                <example type="incorrect">Nett <marker>sind 
du</marker>.</example>
-                <example type="correct">Auch morgen <marker>lebst 
du</marker>.</example>
-                <example type="incorrect">Auch morgen <marker>leben 
du</marker>.</example>
-                <example type="correct">Morgen <marker>kommen du</marker> und 
ich.</example>
-                <example type="correct"><marker>Wünschst du</marker> dir mehr 
Zeit?</example>
-                <!-- <example type="incorrect"><marker>Wünscht du</marker> dir 
mehr Zeit?</example> -->
-            </rule>
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START"></token>
-                    <marker>
-                        <token>Er</token>
-                        <token postag="VER.*:[123]:.*" postag_regexp="yes" 
regexp="yes">[a-zäüö].*<exception postag="VER.*:3:SIN.*" 
postag_regexp="yes"/></token>
-                    </marker>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (\2) und Prädikat (\3) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'er sind' statt 'er ist').</message>
-                <example type="correct"><marker>Er ist</marker> nett.</example>
-                <example type="incorrect"><marker>Er bin</marker> 
nett.</example>
-                <example type="correct"><marker>Er kann</marker> heute leider 
nicht kommen.</example>
-                <example type="incorrect"><marker>Er können</marker> heute 
leider nicht kommen.</example>
-                <example type="correct"><marker>Er lebt</marker>.</example>
-                <example type="incorrect"><marker>Er lebst</marker>.</example>
-                <example type="correct"><marker>Er geht</marker> zu 
ihr.</example>
-                <example type="incorrect"><marker>Er gelangst</marker> zu 
ihr.</example>
-                <example type="correct">Sie und <marker>er 
leben</marker>.</example>
-            </rule>
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START" skip="2"></token>
-                    <token skip="1"></token>
-                    <marker>
-                        <token postag="VER.*:[123]:.*" postag_regexp="yes" 
regexp="yes">[a-zäüö].*<exception postag="VER.*:3:SIN.*" 
postag_regexp="yes"/></token>
-                        <token skip="-1">er<exception 
scope="next">und</exception></token>
-                    </marker>
-                    <token postag="SENT_END"></token>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (\4) und Prädikat (\3) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'er sind' statt 'er ist').</message>
-                <example type="correct">Nett <marker>ist er</marker>.</example>
-                <example type="incorrect">Nett <marker>sind 
er</marker>.</example>
-                <example type="correct">Auch morgen <marker>lebt 
er</marker>.</example>
-                <example type="incorrect">Auch morgen <marker>leben 
er</marker>.</example>
-                <example type="correct">Morgen <marker>kommen er</marker> und 
ich.</example>
-                <example type="correct">Morgen <marker>kommen er</marker>, den 
ich sehr mag, und ich.</example>
-                <example type="correct">Welche <marker>Aufgaben er</marker> 
dabei tatsächlich übernehmen könnte</example>
-            </rule>
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START"></token>
-                    <marker>
-                        <token>Wir</token>
-                        <token postag="VER.*:[123]:.*" postag_regexp="yes" 
regexp="yes">[a-zäüö].*<exception postag="VER.*:1:PLU.*" 
postag_regexp="yes"/></token>
-                    </marker>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (\2) und Prädikat (\3) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'wir ist' statt 'wir sind').</message>
-                <example type="correct"><marker>Wir sind</marker> 
nett.</example>
-                <example type="incorrect"><marker>Wir bin</marker> 
nett.</example>
-                <example type="correct"><marker>Wir können</marker> heute 
leider nicht kommen.</example>
-                <example type="incorrect"><marker>Wir könnt</marker> heute 
leider nicht kommen.</example>
-                <example type="correct"><marker>Wir leben</marker> 
noch.</example>
-                <example type="incorrect"><marker>Wir lebst</marker> 
noch.</example>
-                <example type="correct"><marker>Wir gelangen</marker> zu 
dir.</example>
-                <example type="incorrect"><marker>Wir gelangst</marker> zu 
ihr.</example>
-                <example type="correct">Sie lebt und <marker>wir 
leben</marker>.</example>
-            </rule>
-            <rule>
-                <pattern case_sensitive="yes">
-                    <token postag="SENT_START" skip="2"></token>
-                    <token skip="1"></token>
-                    <marker>
-                        <token postag="VER.*:[123]:.*" postag_regexp="yes" 
regexp="yes">[a-zäüö].*<exception postag="VER.*:1:PLU.*" 
postag_regexp="yes"/></token>
-                        <token skip="-1">wir</token>
-                    </marker>
-                </pattern>
-                <message>Möglicherweise fehlende grammatische Übereinstimmung 
zwischen Subjekt (\4) und Prädikat (\3) bezüglich Person oder Numerus (Einzahl, 
Mehrzahl - Beispiel: 'wir ist' statt 'wir sind').</message>
-                <example type="correct">Nett <marker>sind 
wir</marker>.</example>
-                <example type="incorrect">Nett <marker>warst 
wir</marker>.</example>
-                <example type="correct">Auch morgen <marker>leben wir</marker> 
noch.</example>
-                <example type="incorrect">Auch morgen <marker>lebte 
wir</marker> noch.</example>
-                <example type="correct">Morgen <marker>kommen wir</marker> und 
sie.</example>
-            </rule>
-        </rulegroup>
         <rulegroup id="NACHDEM_PRAETERITUM" name="Grammatik: 'nachdem' mit 
Präteritum">
             <rule>
                 <pattern case_sensitive="yes">

Added: 
trunk/JLanguageTool/src/test/org/languagetool/rules/de/VerbAgreementRuleTest.java
===================================================================
--- 
trunk/JLanguageTool/src/test/org/languagetool/rules/de/VerbAgreementRuleTest.java
                           (rev 0)
+++ 
trunk/JLanguageTool/src/test/org/languagetool/rules/de/VerbAgreementRuleTest.java
   2012-07-18 11:05:58 UTC (rev 7717)
@@ -0,0 +1,176 @@
+/* LanguageTool, a natural language style checker 
+ * Copyright (C) 2005 Daniel Naber (http://www.danielnaber.de)
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ */
+package org.languagetool.rules.de;
+
+import java.io.IOException;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.languagetool.JLanguageTool;
+import org.languagetool.Language;
+import org.languagetool.rules.RuleMatch;
+
+/**
+ * @author Markus Brenneis
+ */
+public class VerbAgreementRuleTest extends TestCase {
+
+  private VerbAgreementRule rule;
+  private JLanguageTool langTool;
+  
+  @Override
+  public void setUp() throws IOException {
+    rule = new VerbAgreementRule(null);
+    langTool = new JLanguageTool(Language.GERMAN);
+  }
+  
+  public void testWrongVerb() throws IOException {
+    // correct sentences:
+    assertGood("Das Wort „schreibst“ ist schön.");
+    assertGood("Die Jagd nach bin Laden.");
+    assertGood("Die Unterlagen solltet ihr gründlich durcharbeiten.");
+    assertGood("Er reagierte äußerst negativ.");
+    assertGood("Max und ich sollten das machen.");
+    assertGood("Osama bin Laden stammt aus Saudi-Arabien.");
+    assertGood("Solltet ihr das machen?");
+    // incorrect sentences:
+    assertBad("Als Borcarbid weißt es eine hohe Härte auf.");
+    assertBad("Das greift auf Vorläuferinstitutionen bist auf die Zeit von 
1234 zurück.");
+    assertBad("Die Eisenbahn dienst überwiegend dem Güterverkehr.");
+    assertBad("Die Unterlagen solltest ihr gründlich durcharbeiten.");
+    assertBad("Peter bin nett.");
+    assertBad("Solltest ihr das machen?", "Subjekt und Prädikat (Solltest)");
+    assertBad("Weiter befindest sich im Osten die Gemeinde Dorf.");
+  }
+  
+  public void testWrongVerbSubject() throws IOException {
+    // correct sentences:
+    assertGood("Auch morgen lebe ich.");
+    assertGood("Auch morgen leben wir noch.");
+    assertGood("Auch morgen lebst du.");
+    assertGood("Auch morgen lebt er.");
+    assertGood("Auch wenn du leben möchtest.");
+    assertGood("auf der er sieben Jahre blieb.");
+    assertGood("Das absolute Ich ist nicht mit dem individuellen Geist zu 
verwechseln.");
+    assertGood("Das Ich ist keine Einbildung");
+    assertGood("Das lyrische Ich ist verzweifelt.");
+    assertGood("Den Park, von dem er äußerst genaue Karten zeichnete.");
+    assertGood("Der Vorfall, bei dem er einen Teil seines Vermögens verloren 
hat, ist lange vorbei.");
+    assertGood("Diese Lösung wurde in der 64'er beschrieben, kam jedoch nie.");
+    assertGood("Die Theorie, mit der ich arbeiten konnte.");
+//     assertGood("Die Zeitschrift film-dienst."); TODO
+    assertGood("Du bist nett.");
+    assertGood("Du kannst heute leider nicht kommen.");
+    assertGood("Du lebst.");
+    assertGood("Du wünschst dir so viel.");
+    assertGood("Er geht zu ihr.");
+    assertGood("Er ist nett.");
+    assertGood("Er kann heute leider nicht kommen.");
+    assertGood("Er lebt.");
+    assertGood("Er wisse nicht, ob er lachen oder weinen solle.");
+    assertGood("Er und du leben.");
+    assertGood("Er und ich leben.");
+    assertGood("Falls er bestehen sollte, gehen sie weg.");
+//     assertGood("Fest wie unsere Eichen halten allezeit wir stand, wenn 
Stürme brausen übers Land."); // TODO (remembers "brausen", forgets about 
"halten")
+    assertGood("Heere, des Gottes der Schlachtreihen Israels, den du verhöhnt 
hast.");
+    assertGood("Ich bin");
+    assertGood("Ich bin Frankreich!");
+    assertGood("Ich bin froh, dass ich arbeiten kann.");
+    assertGood("Ich bin nett.");
+    assertGood("‚ich bin tot‘"); // TODO 1st token is "‚ich" ?
+    assertGood("Ich kann heute leider nicht kommen.");
+    assertGood("Ich lebe.");
+    assertGood("Lebst du?");
+    assertGood("Morgen kommen du und ich.");
+    assertGood("Morgen kommen er, den ich sehr mag, und ich.");
+    assertGood("Morgen kommen er und ich.");
+    assertGood("Morgen kommen ich und sie.");
+    assertGood("Morgen kommen wir und sie.");
+    assertGood("nachdem er erfahren hatte");
+    assertGood("Nett bin ich.");
+    assertGood("Nett bist du.");
+    assertGood("Nett ist er.");
+    assertGood("Nett sind wir.");
+    assertGood("Sie lebt und wir leben.");
+    assertGood("Sie und er leben.");
+    assertGood("Sind ich und Peter nicht nette Kinder?");
+    assertGood("Sodass ich sagen möchte, dass unsere schönen Erinnerungen gut 
sind.");
+    assertGood("Wann ich meinen letzten Film drehen werde, ist unbekannt.");
+    assertGood("Was ich tun muss.");
+    assertGood("Welche Aufgaben er dabei tatsächlich übernehmen könnte");
+    assertGood("wie er beschaffen war");
+    assertGood("Wir gelangen zu dir.");
+    assertGood("Wir können heute leider nicht kommen.");
+    assertGood("Wir leben noch.");
+    assertGood("Wir sind nett.");
+    assertGood("Wobei wir benutzt haben, dass der Satz gilt.");
+    assertGood("Wünschst du dir mehr Zeit?");
+    assertGood("Wyrjtjbst du?"); // make sure that "UNKNOWN" is handled 
correctly
+    // incorrect sentences:
+    assertBad("Auch morgen leben du.");
+    assertBad("Auch morgen leben du"); // do not segfault because "du" is the 
last token
+    assertBad("Auch morgen leben er.");
+    assertBad("Auch morgen leben ich.");
+    assertBad("Auch morgen lebte wir noch.");
+    assertBad2("Du bin nett."); // TODO 2 errors
+    assertBad("Du können heute leider nicht kommen.");
+    assertBad("Du leben.");
+    assertBad("Du wünscht dir so viel.");
+    assertBad2("Er bin nett.");
+    assertBad2("Er gelangst zu ihr.");
+    assertBad("Er können heute leider nicht kommen.", "Subjekt (Er) und 
Prädikat (können)");
+    assertBad2("Er lebst.");
+    assertBad2("Ich bist nett.");
+//     assertBad("Ich geht jetzt nach Hause und dort gehe ich sofort unter die 
Dusche."); TODO
+    assertBad2("Ich kannst heute leider nicht kommen.");
+    assertBad("Ich leben.");
+    assertBad("Lebe du?");
+//     assertBad("Leben du?"); // TODO "Leben" not tagged as verb
+    assertBad2("Nett bist ich nicht.");
+    assertBad("Nett sind du.");
+    assertBad("Nett sind er.");
+    assertBad2("Nett warst wir.");
+    assertBad2("Wir bin nett.");
+    assertBad2("Wir gelangst zu ihr.");
+    assertBad("Wir könnt heute leider nicht kommen.");
+    assertBad2("Wir lebst noch.");
+    assertBad("Wünscht du dir mehr Zeit?", "Subjekt (du) und Prädikat 
(Wünscht)");
+  }
+
+  private void assertGood(String s) throws IOException {
+    assertEquals(0, rule.match(langTool.getAnalyzedSentence(s)).length);
+  }
+
+  private void assertBad(String s) throws IOException {
+    assertEquals(1, rule.match(langTool.getAnalyzedSentence(s)).length);
+  }
+  
+  private void assertBad2(String s) throws IOException {
+    assertEquals(2, rule.match(langTool.getAnalyzedSentence(s)).length);
+  }
+
+  private void assertBad(String s, String expectedErrorSubstring) throws 
IOException {
+    assertEquals(1, rule.match(langTool.getAnalyzedSentence(s)).length);
+    final String errorMessage = 
rule.match(langTool.getAnalyzedSentence(s))[0].getMessage();
+    assertTrue("Got error '" + errorMessage + "', expected substring '" + 
expectedErrorSubstring + "'",
+            errorMessage.contains(expectedErrorSubstring));
+  }
+  
+}

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Languagetool-cvs mailing list
Languagetool-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/languagetool-cvs

Reply via email to