Beispiel #1
0
void TranslateGetFeatures(PNode *pn, int tgtlang, int pos, /* RESUTS */
                          int *tense, int *gender, int *number, int *person,
                          int *degree)
{
  *tense = FeatureGet(pn->lexitem->features, FT_TENSE);
  *gender = FeatureGet(pn->lexitem->features, FT_GENDER);
  *number = FeatureGet(pn->lexitem->features, FT_NUMBER);
  *person = FeatureGet(pn->lexitem->features, FT_PERSON);
  *degree = FeatureGet(pn->lexitem->features, FT_DEGREE);
  FeatureDefault(tgtlang, pos, tense, gender, number, person, degree);
}
Beispiel #2
0
void WordFormBuildLeFeat(char *in, /* RESULTS */ char *out)
{
  int	c;
  if (F_NULL != (c = FeatureGet(in, FT_GENDER))) {
    *out = c;
    out++;
  }
  *out = FeatureGet(in, FT_POS);
  out++;
  *out = FeatureGet(in, FT_LANG);
  out++;
  *out = TERM;
}
Beispiel #3
0
/* Determine whether an adverb can be "shifted" into the VP from the NP,
 * PP, or AdjP. This is to eliminate supposedly redundant parses.
 * [W
 *  [W
 *   [B n]
 *   [W [V était]]]
 *  [X
 *   [E
 *    [B pas]
 *    [E [A une]]]
 *   [X [N belle journée]]]]
 */
Bool Syn_Parse_IsAdvShiftableToVP(PNode *w, PNode *x, int lang)
{
  int		w_pos;
  LexEntry	*w_le;
  PNode		*adv_pn;

  if ((adv_pn = PNodeLeftmost(x)) && adv_pn->feature == F_ADVERB) {
    if (0.0 == Syn_ParseFilterBW_WB_W(adv_pn, w, 0, lang)) {
      return(0);
    }
    if (!(w_le = PNodeRightmostLexEntry(w))) {
      return(0);
    }
    w_pos = FeatureGet(w_le->features, FT_POS);
    if (w_pos == F_VERB || w_pos == F_ADVERB) {
    /* The adverb which is the leftmost terminal of <x> can modify verbs
     * and it is already to the right of a verb or adverb, so this adverb can
     * be "shifted" into the verb phrase to its left. No shifting actually
     * occurs here but this parse is ruled out and it is left to other rules
     * to introduce the adverb inside the verb phrase.
     */
      return(1);
    }
  }
  return(0);
}
Beispiel #4
0
void ThetaRoleTextPrint(Text *text, int html, LexEntry *le,
                        ThetaRole *theta_roles, Obj *con, Discourse *dc)
{
    int	lang;
    char	buf[DWORDLEN];
    lang = FeatureGet(le->features, FT_LANG);
    ThetaRoleTextPrint1(text, html, lang, TRPOS_NA, N("subj"), theta_roles, con,
                        dc);
    ThetaRoleTextPrint1(text, html, lang, TRPOS_NA, N("aobj"), theta_roles, con,
                        dc);
    ThetaRoleTextPrint1(text, html, lang, TRPOS_PRE_VERB, N("expl"), theta_roles,
                        con, dc);
    LexEntryAddSep(le, le->srcphrase, DWORDLEN-1, buf);
    if (html) {
        HTML_TextPrintBoldBeginIfEnglish(text, lang);
        HTML_TextPrint(text, buf);
        TextPutc(SPACE, text);
        HTML_TextPrintBoldEndIfEnglish(text, lang);
    } else {
        TextPutword(buf, TERM, text);
    }
    ThetaRoleTextPrint1(text, html, lang, TRPOS_POST_VERB_PRE_OBJ, N("expl"),
                        theta_roles, con, dc);
    ThetaRoleTextPrint1(text, html, lang, TRPOS_NA, N("obj"),  theta_roles, con,
                        dc);
    ThetaRoleTextPrint1(text, html, lang, TRPOS_POST_VERB_POST_OBJ, N("expl"),
                        theta_roles, con, dc);
    ThetaRoleTextPrint1(text, html, lang, TRPOS_NA, N("iobj"), theta_roles, con,
                        dc);
}
Beispiel #5
0
void WordFormBuildLinkFeat(char *in, /* RESULTS */ char *out)
{
  int	c;
  if (F_NULL != (c = FeatureGet(in, FT_PARUNIV))) {
    *out = c;
    out++;
  }
  *out = TERM;
}
Beispiel #6
0
/* Accepts:
 * [W [V vais]]
 * [W [H me] [W [V va]]]
 * [W [H vraiment] [W [V va]]]
 * Rejects:
 * [W [W [V vais]] [B pas]]
 */
Float Syn_ParseFilter_Verb_Or_InterHB(PNode *w)
{
  int		pos;
  LexEntry	*le;
  if (w->pn1 && w->pn1->feature == F_VERB && w->pn2 == NULL) return(1.0);
  if (NULL == (le = PNodeLeftmostLexEntry(w))) return(0.0);
  pos = FeatureGet(le->features, FT_POS);
  if (pos != F_PRONOUN && pos != F_ADVERB) return(0.0);
  return(1.0);
}
Beispiel #7
0
Lexitem *TransformPronoun(Lexitem *in, Obj *to_pronoun_class, Discourse *dc)
{
  LexEntry	*le;
  Word		*infl;
  int		gender, number, person;
  gender = FeatureGet(in->features, FT_GENDER);
  number = FeatureGet(in->features, FT_NUMBER);
  person = FeatureGet(in->features, FT_PERSON);
  if (!(le = ObjToLexEntryGet(to_pronoun_class, F_PRONOUN, F_NULL, dc))) {
    Dbg(DBGGENER, DBGBAD, "TransformPronoun: 1");
    return(in);
  }
  if (!(infl = LexEntryGetInflection(le, F_NULL, gender, number, person,
                                     F_NULL, F_NULL, 1, dc))) {
    Dbg(DBGGENER, DBGBAD, "TransformPronoun: 2");
    return(in);
  }
  return(LexitemCreate(infl->word, le, le->features));
}
Beispiel #8
0
/* Used during parsing when parent is not available. */
Bool XBarValidY_MAX(PNode *y)
{
  LexEntry	*le;
  le = PNodeLeftmostLexEntry(y);
  if (le && F_PREPOSITION == FeatureGet(le->features, FT_POS)) {
    return(1);
  }
  if (y->pn1 && y->pn1->feature == F_ADVERB &&
      y->pn2 && y->pn2->feature == F_PP) {
    return(XBarValidY_MAX(y->pn2));
  }
  return(0);
}
Beispiel #9
0
LexEntry *ObjToAbbrev(Obj *obj, int force, Discourse *dc)
{
  int	pos;
  ObjToLexEntry	*ole;
  if (!obj) return(NULL);
  for (ole = obj->ole; ole; ole = ole->next) {
    if (F_NULL != FeatureGet(ole->features, FT_PARUNIV)) continue;
    if (DC(dc).lang != FeatureGet(ole->le->features, FT_LANG)) continue;
    pos = FeatureGet(ole->le->features, FT_POS);
    if (pos != F_NOUN && pos != F_ADJECTIVE) continue;
    if (F_LITERARY == FeatureGet(ole->features, FT_STYLE) &&
        !MorphIsWord(ole->le->srcphrase)) {
      return(ole->le);
    }
  }
  if (force) {
    if ((ole = ObjToLexEntryGet1(obj, NULL, "NA", F_NULL, F_NULL, NULL, dc))) {
      return(ole->le);
    }
  }
  return(NULL);
}
Beispiel #10
0
/* Find ObjToLexEntry (lexical entry) with similar arguments and usage
 * to ole_src.
 *
 * Example:
 * obj: N("like-human")
 * ole_src->theta_roles: 1:subj, 2:obj
 * ole_src->features: TÔ
 * tgtlang: F_FRENCH
 * Returns:
 * ole->theta_roles: 1:iobj:à 2:subj
 * ole->le: plaire.Vy
 *
 * Multiple possibilities are generated only in the case of multiple
 * interpretations. todo: Possibly provide more synonyms as an option.
 */
ObjToLexEntry *ObjToLexEntryTransGet(Obj *obj, int pos, int *theta_filled,
                                     int tgtlang, ObjToLexEntry *ole_src,
                                     Discourse *dc)
{
  char			feat[2];
  int			save_lang, save_style;
  GenAdvice		save_ga;
  ObjToLexEntry		*ole;

  /* Set up dc environment. */
  save_lang = DC(dc).lang;
  save_style = DC(dc).style;
  save_ga = dc->ga;
  DC(dc).lang = tgtlang;
  DC(dc).style = FeatureGet(ole_src->features, FT_STYLE);
  if (DC(dc).style == F_SLANG) DC(dc).style = F_INFORMAL;
  dc->ga.consistent = 1;

  /* Prepare features */
  feat[0] = pos;
  feat[1] = TERM;

  ole = ObjToLexEntryTransGet1(obj, NULL, feat,
                               FeatureGet(ole_src->features, FT_PARUNIV),
                               0, theta_filled, dc);

  if (ole == NULL) {
    Dbg(DBGGENER, DBGBAD, "lexical gap <%s> <%c%c>", M(obj), pos, tgtlang);
  }

  /* Restore previous dc environment. */
  DC(dc).lang = save_lang;
  DC(dc).style = save_style;
  dc->ga = save_ga;

  return(ole);
}
Beispiel #11
0
void ObjToLexEntryClearLastused(ObjToLexEntry *ole, Discourse *dc)
{
  int	i;
  for (i = 0; ole; i++, ole = ole->next) {
  /*
   * "if (consider[i])" was a nice idea but it doesn't work well when doing
   * generation to multiple dialects: the dialect-common items get reset
   * whenever a given dialect finishes the list of lexical items and the
   * result is that the frequent items for other dialects aren't generated.
   */
    if (DC(dc).lang == FeatureGet(ole->le->features, FT_LANG)) {
      ole->lastused = UNIXTSNA;
    }
  }
}
Beispiel #12
0
/* Assumes dc is set according to type of speaker. (Generation would normally
 * be set the same way: generate in American English when talking to an
 * American...)
 * todo: Add FT_ADDRESS (useful only for French, to reduce probability of
 * singular "vous" interpretation when "tu" is expected)
 * todo: If a parse is accepted using a noncongruent lexical item, consider
 * updating the speaker model.
 */
Float LexEntryToObjScore(LexEntryToObj *leo, Discourse *dc)
{
  Float	score;
  if (leo == NULL) return(SCORE_MAX);
  switch (FeatureGet(leo->features, FT_FREQ)) {
  /* todoSCORE */
    case F_FREQUENT:
      score = 1.0;
      break;
    case F_INFREQUENT:
      score = 0.2;
      break;
    default:
      score = 0.9;
      break;
  }
  score = ScoreCombine(score,
                       StyleScore(FeatureGet(leo->features, FT_STYLE),
                                  DC(dc).style));
  score = ScoreCombine(score,
                       DialectScore(FeatureGet(leo->features, FT_DIALECT),
                                    DC(dc).dialect));
  return(score);
}
Beispiel #13
0
PNode *TranslateAWord(PNode *pn, PNode *pnp, Obj *max, int pos, int tense,
                      int gender, int number, int person, int degree,
                      int srclang, int tgtlang, Discourse *dc)
{
  int			number1;
  ObjList		*p;
  ObjToLexEntry	*ole_src, *ole_tgt;
  Word			*infl;
  PNode			*r, *r1;
  r = NULL;
  for (p = TranslateGetAllcons(pn, pn->lexitem ? pn->lexitem->le : NULL);
       p; p = p->next) {
    if (ObjIsList(p->obj)) {
      continue;
    }
/* todo: Put FT_FILTER checks here. */
    if (!TranslateGetOles(pos, p->obj, pn->lexitem->le, NULL, tgtlang, dc,
                          &ole_src, &ole_tgt)) {
      continue;
    }
    if (StringIn(F_COMMON_INFL, ole_tgt->features)) {
      number1 = FeatureGet(ole_tgt->features, FT_NUMBER);
    } else {
      number1 = number;
    }
    if (!(infl = LexEntryGetInflection(ole_tgt->le, tense, gender, number1,
                                       person, F_NULL, degree, 1, dc))) {
      continue;
    }
    r1 = PNodeWord(pos, infl->word, infl->features, ole_tgt->le, p->obj);
    if (pn->punc[0]) TranslatePunc(r1->punc, pn->punc, srclang, tgtlang);
    r1->ole = ole_tgt;
    r1->obj = p->obj;
    r1->next_altern = r;
    r = r1;
  }
  if (r == NULL) {
    return(pn);
  }
  return(r);
}
Beispiel #14
0
Float Syn_ParseFilterRX_Y(PNode *r, PNode *x, int lang)
{
  PNode	*v_pn;
  if (x->pn1 && x->pn1->feature == F_S) {
    if (lang == F_FRENCH) {
      if (LexEntryConceptIsAncestor(N("conj-pp-subord"),
                                    PNodeLeftmostLexEntry(x->pn1)) &&
          LexEntryConceptIsAncestor(N("prep-to"), PNodeLeftmostLexEntry(r))) {
      /* "à ce que" + indic */
        return(1.0);
      } else if (LexEntryConceptIsAncestor(N("prep-to"),
                                           PNodeLeftmostLexEntry(r))) {
      /* "à" + inf todo: Enforce infinitive? Already enforced by
       * Syn_ParseFilterZ_X.
       */
        return(1.0);
      } else if (LexEntryConceptIsAncestor(N("prep-of"),
                                           PNodeLeftmostLexEntry(r))) {
      /* "de" + inf */
        return(1.0);
      }
    } else {
      if (Syn_ParsePresPartPrep(PNodeLeftmostLexEntry(r)) &&
          (v_pn = PNodeLeftmost(x)) && v_pn->lexitem && 
          (F_PRESENT_PARTICIPLE ==
             FeatureGet(v_pn->lexitem->features, FT_TENSE))) {
      /* "to" + pres part */
        return(1.0);
      } else {
        return(0.0);
      }
    }
  } else {
    if (!XBarSatisfiesCaseFilter(x, NULL, N("iobj"), lang)) return(0.0);
  }
  return(1.0);
}
Beispiel #15
0
Float Syn_ParseFilterXW_Z(PNode *x, PNode *w, int lang)
{
  int	noun_gender, noun_number, noun_person, verb_tense;
  Obj	*cas;
  PNode	*auxverb, *mainverb;

  if (Syn_Parse_IsOnlyRelativeW(w, lang)) return(0.0);

  verb_tense = F_NULL;
  PNodeFindHeadVerb(w, &auxverb, &mainverb);
  if (auxverb && auxverb->lexitem &&
      (verb_tense = FeatureGet(auxverb->lexitem->features, FT_TENSE)) &&
      (!StringIn(verb_tense, FS_FINITE_TENSE))) {
  /* Subjects of nonfinite verbs are in objective case.
   * See Chomsky (1982/1987, p. 207).
   */
    cas = N("obj");
  } else {
    cas = N("subj");
  }
  if (!XBarSatisfiesCaseFilter(x, NULL, cas, lang)) return(0.0);

  if (x->pn1 && x->pn1->feature == F_S && x->pn2 == NULL &&
      x->pn1->pn1 && x->pn1->pn1->feature == F_VP && x->pn1->pn2 == NULL &&
      x->pn1->pn1->pn1 && x->pn1->pn1->pn1->feature == F_VERB &&
        x->pn1->pn1->pn2 == NULL) {
  /* The case of an infinitive subject. [X [Z [W [V <garder.fVy¸>]]]]
   * "Aimer"
   * This is indeed possible, but it is causing a lot of extra parses.
   * "Aimer quelqu'un" is allowed.
   */
    return(0.1);	/* todoSCORE */
  }

  /* Subject-verb agreement check. */
  if (auxverb == NULL) return(1.0);
  if (auxverb->lexitem == NULL) return(1.0);
  if (F_IMPERATIVE == FeatureGet(auxverb->lexitem->features, FT_MOOD)) {
  /* Imperative with subject. */
    return(0.2);	/* todoSCORE */
  }
  if (!PNodeGetHeadNounFeatures(x, 0, &noun_gender, &noun_number,
                                &noun_person)) {
    return(1.0);
  }
  if (x->pn1 && x->pn2 &&
      x->pn1->feature == F_NP && x->pn2->feature == F_NP &&
      x->pn2->pn1 && x->pn2->pn1->feature == F_CONJUNCTION) {
    return(1.0); /* todo: Real conjunction agreement rules? */
  }
#ifdef notdef
  /* Seems unnecessary in light of FeatureMatch below */
  if (F_NULL == noun_person && F_NULL == noun_number) {
    /* todoSCORE: This is too relaxed? In any case it allows parsing of
     * Où étais (sic) mon pied gauche ?
     * Où étaient mes... ?
     * When would noun_number be F_NULL?
     */
    return(0.6);	/* todoSCORE */
  }
#endif
  if (F_NULL == noun_person) {
  /* This is necessary to rule out "I am" where "I" = "isospin". */
    noun_person = F_THIRD_PERSON;
  }
  if (FeatureMatch(noun_number,
                   FeatureGet(auxverb->lexitem->features, FT_NUMBER)) &&
      FeatureMatch(noun_person,
                   FeatureGet(auxverb->lexitem->features, FT_PERSON))) {
    return(1.0);
  }
  if (Syn_ParseIsNPVerbInversionVP(w, lang)) {
  /* "What color are elephants? */
    return(1.0);
  }
  return(0.0);
}
Beispiel #16
0
/* "Je ne vais pas m'en aller" */
Bool Syn_ParseRightmostIsPronoun(PNode *w)
{
  LexEntry	*le;
  le = PNodeRightmostLexEntry(w);
  return(le && (F_PRONOUN == FeatureGet(le->features, FT_POS)));
}
Beispiel #17
0
ThetaRole *ThetaRoleBuild(char *features, LexEntry **les, int lelen,
                          int *delims, int *subcats, Obj *con,
                          ThetaRole *theta_roles_expl)
{
    int		i, j, pos, subjfound, subcat, is_optional;
    LexEntry	*le;
    ThetaRole	*trs[MAXCPSIZE], *r;
    for (j = 0; j < MAXCPSIZE; j++) {
        trs[j] = NULL;
    }
    pos = FeatureGetRequired("ThetaRoleBuild", features, FT_POS);
    subjfound = 0;
    if (pos == F_ADJECTIVE || pos == F_NOUN || pos == F_VERB) {
#ifdef maxchecking
        ThetaRoleCheckSubcat(features);
#endif
        /* subj */
        if (StringIn(F_SUBJ3, features)) {
            trs[3] = ThetaRoleCreate(0, ThetaRoleSubjCase(pos), NULL, F_NULL, NULL);
            subjfound = 1;
        }
        if (StringIn(F_SUBJ2, features)) {
            if (subjfound) {
                Dbg(DBGLEX, DBGBAD, "ThetaRoleBuild: multiple subjects");
            }
            trs[2] = ThetaRoleCreate(0, ThetaRoleSubjCase(pos), NULL, F_NULL, NULL);
            subjfound = 1;
        }
        if (pos == F_NOUN) {
            if (subjfound) {
                Dbg(DBGLEX, DBGBAD, "ThetaRoleBuild: subj defined for noun");
            }
        } else {
            if (!subjfound) {
                trs[1] = ThetaRoleCreate(0, ThetaRoleSubjCase(pos), NULL, F_NULL, NULL);
                subjfound = 1;
            }
        }
        /* obj */
        if (ThetaRoleGetSubcat(F_OBJ3, features, &is_optional, &subcat)) {
            if (trs[3]) {
                Dbg(DBGLEX, DBGBAD, "ThetaRoleBuild: object index same as subject");
            }
            trs[3] = ThetaRoleCreate(is_optional, N("obj"), NULL, subcat, NULL);
        }
        if (ThetaRoleGetSubcat(F_OBJ2, features, &is_optional, &subcat)) {
            if (trs[2]) {
                Dbg(DBGLEX, DBGBAD, "ThetaRoleBuild: object index same as subject");
            }
            trs[2] = ThetaRoleCreate(is_optional, N("obj"), NULL, subcat, NULL);
        }
        if (ThetaRoleGetSubcat(F_OBJ1, features, &is_optional, &subcat)) {
            if (trs[1]) {
                Dbg(DBGLEX, DBGBAD, "ThetaRoleBuild: object index same as subject");
            }
            trs[1] = ThetaRoleCreate(is_optional, N("obj"), NULL, subcat, NULL);
        }
    } else {
        subcat = FeatureGet(features, FT_SUBCAT);
        if (pos == F_CONJUNCTION || pos == F_PREPOSITION ||
                pos == F_PRONOUN) {
            if (subcat != F_NULL) {
                /* todo: Inelegant. In order to hold the subcategorization restriction
                 * for later use by ObjToLexEntryGet2 in generating conjunctions.
                 */
                trs[1] = ThetaRoleCreate(0, N("kobj1"), NULL, subcat, NULL);
            }
        } else {
#ifdef maxchecking
            if (subcat != F_NULL) {
                Dbg(DBGLEX, DBGBAD, "ThetaRoleBuild: <%s> unexpected FT_SUBCAT",
                    features);
            }
#endif
        }
#ifdef maxchecking
        if (F_NULL != FeatureGet(features, FT_SUBJLOC) ||
                F_NULL != FeatureGet(features, FT_OBJLOC)) {
            Dbg(DBGLEX, DBGBAD, "inapplicable subj/obj location specs <%s>",
                features);
        }
#endif
    }
    if (les) {
        for (i = 0; i < lelen; i++) {
            if (delims[i] == LE_PHRASE_PREP || delims[i] == LE_PHRASE_OPT_PREP) {
                if (!(le = les[i])) {
                    Dbg(DBGLEX, DBGBAD, "ThetaRoleBuild: empty le");
                } else {
                    for (j = ThetaRoleIOBJStart(features); j < MAXCPSIZE; j++) {
                        if (trs[j] == NULL) {
                            trs[j] = ThetaRoleCreate(delims[i] == LE_PHRASE_OPT_PREP,
                                                     N("iobj"), le, subcats[i], NULL);
                            break;
                        }
                    }
                }
            }
        }
    }
    for (j = MAXCPSIZE-1; j >= 1; j--) {
        if (trs[j]) {
            for (j = j-1; j >= 1; j--) {
                if (trs[j] == NULL) {
                    trs[j] = ThetaRoleCreate(1, ObjNA, NULL, F_NULL, NULL);
                }
            }
            r = theta_roles_expl;
            for (j = MAXCPSIZE-1; j >= 1; j--) {
                if (trs[j]) {
                    trs[j]->next = r;
                    r = trs[j];
                }
            }
            return(r);
        }
    }
    return(NULL);
}
Beispiel #18
0
/* todo: Something compatible with the dialect is chosen.
 * Alter this to PREFER dialect-specific choices?
 * <value_prop> can also just be value number.
 */
ObjToLexEntry *ObjToLexEntryGet3(Obj *obj, Obj *value_prop, char *features,
                                 char *not_usagefeat, int subcat, int paruniv,
                                 int *theta_filled, int pass_two,
                                 Discourse *dc)
{
  int		i, pos, address;
  char		features1[FEATLEN];
  ObjToLexEntry *ole, *p;
  ole = obj->ole;
  address = DiscourseAddress(dc);
  if (dc->ga.qwq &&
      (ISA(N("question-word"), obj) || ISA(N("copula"), obj))) {
    StringCpy(features1, features, FEATLEN);
    StringElimChar(features1, F_NOUN);
    features = features1;
  }
  for (i = 0, p = ole; p; i++, p = p->next) {
    if (i >= MAXOLELEN) {
      Dbg(DBGGENER, DBGBAD, "increase MAXOLELEN");
      break;
    }
    pos = FeatureGet(p->le->features, FT_POS);

    /* todo: For super debugging, if we return NULL from this function,
     * print out list of why each lexical entry failed.
     */
    consider[i] = ((DC(dc).lang == FeatureGetRequired("ObjToLexEntryGet",
                                                      p->le->features,
                                                      FT_LANG))
                   && StringAnyIn(features, p->le->features)
                   && paruniv == FeatureGet(p->features, FT_PARUNIV)
                   && (subcat == F_NULL ||
                       subcat == ThetaRoleGetAnySubcat(p->theta_roles))
                   && F_NULL == FeatureGet(p->features, FT_CONNOTE) /* todo */
                   && FeatureDialectMatch(DC(dc).dialect,
                                          FeatureGet(p->features, FT_DIALECT))
                   && DC(dc).style == FeatureGet(p->features, FT_STYLE)
                   && FeatureTaskOK(p->features, dc->task)
                   && FeatureMatch(address, FeatureGet(p->features, FT_ADDRESS))
                   && (not_usagefeat == NULL ||
                       (!StringAnyIn(not_usagefeat, p->features)))
                   && ((pos != F_NOUN) || ISA(N("relation"), obj) ||
                       ThetaRoleMatch(theta_filled, p->theta_roles, pass_two)));
    Nop(); /* Debugging anchor. */
  }
  if (!dc->ga.consistent) {
    for (i = 0, p = ole; p && i < MAXOLELEN; i++, p = p->next) {
      if (consider[i] && F_FREQUENT == ((uc)FeatureGet(p->features, FT_FREQ)) &&
          p->lastused == UNIXTSNA) {
        p->lastused = time(NULL); return(p);
      }
    }
    for (i = 0, p = ole; p && i < MAXOLELEN; i++, p = p->next) {
      if (consider[i] && F_NULL == FeatureGet(p->features, FT_FREQ) &&
          p->lastused == UNIXTSNA) {
        p->lastused = time(NULL); return(p);
      }
    }
    if (DC(dc).infrequent_ok) {
      for (i = 0, p = ole; p && i < MAXOLELEN; i++, p = p->next) {
        if (consider[i] && F_INFREQUENT == FeatureGet(p->features, FT_FREQ) &&
            p->lastused == UNIXTSNA) {
          p->lastused = time(NULL); return(p);
        }
      }
    }
  }
  if (pass_two) {
    /* In this case ObjToLexEntryClearLastused has already been done. */
    return(NULL);
  }
  ObjToLexEntryClearLastused(ole, dc);
  for (i = 0, p = ole; p && i < MAXOLELEN; i++, p = p->next) {
    if (consider[i] && F_FREQUENT == FeatureGet(p->features, FT_FREQ)) {
      p->lastused = time(NULL); return(p);
    }
  }
  for (i = 0, p = ole; p && i < MAXOLELEN; i++, p = p->next) {
    if (consider[i] && F_NULL == FeatureGet(p->features, FT_FREQ)) {
      p->lastused = time(NULL); return(p);
    }
  }
  /* Note in this case we do permit the generation of infrequent. */
  for (i = 0, p = ole; p && i < MAXOLELEN; i++, p = p->next) {
    if (consider[i] && F_INFREQUENT == FeatureGet(p->features, FT_FREQ)) {
      p->lastused = time(NULL); return(p);
    }
  }
  return(NULL);
}
Beispiel #19
0
/* todo: Avoid enumeration of subjunctive, indicative, and imperative cases?
 * But these have distinct meanings.
 */
void TA_LexEntryEnter(Channel *ch, IndexEntry *ie, int prepunc, char *postpunc,
                      char *phrase, char *begin, char *rest, HashTable *ht)
{
  int		i, phrase_len, pos, le_len, elision_infl, elision_in;
  int		contraction_infl, contraction_in, noun_added;
  Float		score;
  Lexitem	*lexitem;
  LexEntry	*le_le[MAXLES];
  char		*le_feat[MAXLES], feat[FEATLEN];
  noun_added = 0;
  le_len = 0;
  phrase_len = strlen(phrase);
  /* Inflection collapsing and elimination of noncompatible
   * contractions/elisions:
   */
  for (; ie; ie = ie->next) {
    if (ie->lexentry == NULL) continue;
    if (LexEntryFilterOut(ie->lexentry)) continue;
    pos = FeatureGet(ie->lexentry->features, FT_POS);
    if (pos == F_NOUN) noun_added = 1;
    if (phrase_len == 1 &&
        (pos == F_NOUN || pos == F_ADJECTIVE)) {
      /* Noun or adjective meanings of single characters are ruled out
       * here because they should be handled by specialized TAs such as
       * TA_MediaObject, TA_Name, TA_Product, a formula TA. todoSCORE
       * todo: Some TA's assume lexical PNodes have been generated here.
       * If so, they could be marked as "to be ignored by Syn_Parse".
       * todoSCORE: An adjective followed by single quote (as in I')
       * is rare?
       * MRBEGIN
       * Note this prevents R (MPAA rating) from being parsed.
       * MREND
       */
      continue;
    }
    contraction_infl = StringIn(F_CONTRACTION, ie->features);
    contraction_in = ((prepunc == SQUOTE) || (prepunc == SQUOTE2));
    elision_infl = StringIn(F_ELISION, ie->features);
    elision_in = ((postpunc[1] == TERM) &&
                ((postpunc[0] == SQUOTE) || (((uc *)postpunc)[0] == SQUOTE2)));
    if ((elision_infl ? elision_in : 1) &&
        (contraction_infl ? contraction_in : 1)) {
    /* If an inflection is marked for elision or contraction, then
     * the input must have a contraction mark. cf "I'm", "isn't" todoSCORE
     */
      TA_LELAdd(ie->lexentry, ie->features, MAXLES, le_le, le_feat, &le_len);
    }
  }
  for (i = 0; i < le_len; i++) {
    lexitem = LexitemCreate(phrase, le_le[i], HashTableIntern(ht, le_feat[i]));
    score = 1.0;
    /* todoSCORE: LexEntryFind phrase should return a score that
     * indicates the degree of relaxation.
     */
    ChannelAddPNode(ch, PNTYPE_LEXITEM, score, lexitem, postpunc, begin, rest);
  }

  if ((!noun_added) &&
      ((prepunc == SQUOTE && StringIn(SQUOTE, postpunc)) ||
       (prepunc == SQUOTE2 && StringIn(SQUOTE2, postpunc)) ||
       (prepunc == LGUILLEMETS && StringIn(RGUILLEMETS, postpunc)) ||
       (prepunc == DQUOTE && StringIn(DQUOTE, postpunc)))) {
    /* Duplicate quoted lexical items (metalinguistic) as nouns.
     * Example: What does (the word) "stupid" mean?
     */
    for (i = 0; i < le_len; i++) {
      FeatSubstPOS(le_feat[i], F_NOUN, feat);
      lexitem = LexitemCreate(phrase, le_le[i], HashTableIntern(ht, feat));
      score = 1.0;
      ChannelAddPNode(ch, PNTYPE_LEXITEM, score, lexitem, postpunc, begin,
                      rest);
    }
  }

  for (i = 0; i < le_len; i++) {
    MemFree(le_feat[i], "char TA_LELAdd");
  }
}