System.err.println("yikes: a constituent in chart has comma as head" +
System.err.println(className + ": yikes: a constituent in chart has comma as head" +
  private final boolean containsCommaConstraintViolation(CKYItem item) {    Treebank treebank = Language.treebank();    int lastWordIdx = sentence.length() - 1;    // first, look at most recent left children    SLNode first = item.leftChildren();    SLNode second = first != null ? first.next() : null;    SLNode third = (second == null ? null :                    (second.next() == null ?                     headNode.setData(item.headChild()) : second.next()));    while (first != null && second != null && third != null) {      Symbol left = ((CKYItem)first.data()).headWord().word();      Symbol middle = ((CKYItem)second.data()).headWord().word();      Symbol right = ((CKYItem)third.data()).headWord().word();      if (!treebank.isComma(left) && !treebank.isComma(right) &&          treebank.isComma(middle)) {        int rightEdgeIdx = ((CKYItem)third.data()).end();        if (!(rightEdgeIdx == lastWordIdx ||              treebank.isComma(getSentenceWord(rightEdgeIdx + 1))))          return true;      }      first = first.next();      second = second.next();      // if we've reached the end (the rightmost node, third, is the head)      if (third.data() == item.headChild()) {        third = null;      }      else {        third = (third.next() == null ?                 headNode.setData(item.headChild()) : third.next());      }    }    // next, look at most recent right children    first = item.rightChildren();    second = first != null ? first.next() : null;    third = (second == null ? null :             (second.next() == null ?              headNode.setData(item.headChild()) : second.next()));    while (first != null && second != null && third != null) {      Symbol left = ((CKYItem)third.data()).headWord().word();      Symbol middle = ((CKYItem)second.data()).headWord().word();      Symbol right = ((CKYItem)first.data()).headWord().word();      if (!treebank.isComma(left) && !treebank.isComma(right) &&          treebank.isComma(middle)) {        int rightEdgeIdx = ((CKYItem)first.data()).end();        if (!(rightEdgeIdx == lastWordIdx ||              treebank.isComma(getSentenceWord(rightEdgeIdx + 1))))          return true;      }      first = first.next();      second = second.next();      // if we've reached the end (the leftmost node, third, is the head)      if (third.data() == item.headChild()) {        third = null;      }      else {        third = (third.next() == null ?                 headNode.setData(item.headChild()) : third.next());      }    }    if (item.leftChildren() != null && item.rightChildren() != null &&        treebank.isComma(item.headWord().word())) {      if (debugCommaConstraint) {        System.err.println("yikes: a constituent in chart has comma as head" +                           item);      }      return false;    }    return false;  }