home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Copyright (C) 1992-1993 Jeffrey Chilton
- *
- * Permission is granted to anyone to make or distribute copies of
- * this program, in any medium, provided that the copyright notice
- * and permission notice are preserved, and that the distributor
- * grants the recipient permission for further redistribution as
- * permitted by this notice.
- *
- * Author's E-mail address: 172-9221@mcimail.com
- *
- */
-
- static char *whatstring = "@(#)verb.c 2.6 JWC";
-
- #include <stdio.h>
- #include <string.h>
-
- #include "class.h"
- #include "form.h"
- #include "verb.h"
- #include "verbset.h"
-
- extern Verb *Avoir;
- extern Verb *Etre;
-
- #define MOD N_OF_PERSON
-
- /* Verb_new - Create an empty verb object */
-
- Verb *
- Verb_new(infinitive)
- char *infinitive;
- {
- int pers;
- int plur;
- int gender;
- Verb *self;
-
- self = (Verb *)malloc(sizeof (Verb));
- if (!self)
- {
- fprintf(stderr, "Verb_new: malloc fails\n");
- goto out;
- }
-
- self->infinitive = ExtendString_newFromString(infinitive);
-
- for (pers = 0; pers < N_OF_PERSON; pers++)
- {
- for (plur = 0; plur < N_OF_PLURAL; plur++)
- {
- self->presIndEndings[pers][plur] = (ExtendString *)0;
- self->presSubjEndings[pers][plur] = (ExtendString *)0;
- self->imperfectEndings[pers][plur] = (ExtendString *)0;
- }
- }
-
- self->imperativeEndings[0] = (ExtendString *)0;
- self->imperativeEndings[1] = (ExtendString *)0;
- self->imperativeEndings[2] = (ExtendString *)0;
-
- self->presIndStem = (ExtendString *)0;
- self->presSubjStem = (ExtendString *)0;
- self->imperativeStem = (ExtendString *)0;
- self->imperfectStem = (ExtendString *)0;
- self->futureStem = (ExtendString *)0;
- self->presentParticipal = (ExtendString *)0;
- self->pastParticipal = (ExtendString *)0;
-
- self->conjugationClass = 0;
- self->auxiliary = -1;
-
- out:
-
- return self;
-
- }
-
- /* Verb_newFromFile - read formatted representation from file stream */
-
- #define FORMAT " %[^:]: %s %s %s %s %s %s %s "
-
- #define ENDS ends[0], ends[1], ends[2], ends[3], ends[4], ends[5]
-
- Verb *
- Verb_newFromFile(infinitive, stream)
- char *infinitive;
- FILE *stream;
- {
- register int i;
- Verb *self;
- char oneLine[80];
- char conjugate[32];
- char ends[6][32];
- char stem[32];
- Form *form;
- ExtendString *t, u;
- int count;
-
- self = Verb_new(infinitive);
- if (!self)
- {
- goto out;
- }
-
- fgets(oneLine, 80, stream);
- while (TRUE)
- {
- if (oneLine[0] == '\n' || oneLine[0] == '{')
- {
- fgets(oneLine, 80, stream);
- continue;
- }
-
- if (0 == strcmp(oneLine, "}\n"))
- {
- break;
- }
-
- count = sscanf(oneLine, FORMAT, conjugate, stem, ENDS);
-
- #if XDEBUG
- printf("Verb_newFromFile: %s: ", conjugate);
- printf("%s ", stem);
- for (i = 0; i < count - 2; i++)
- {
- printf("%s ", ends[i]);
- }
- printf("\n");
- #endif
-
- if (0 == strcmp(conjugate, "PRES-IND"))
- {
- stem[strlen(stem) - 1] = '\0';
- self->presIndStem = ExtendString_newFromString(stem);
- self->thirdPersonOnly = count < 8;
- for (i = 0; i < count - 2; i++)
- {
- t = ExtendString_newFromString(ends[i]);
- if (self->thirdPersonOnly)
- {
- i = PERSON_THIRD;
- }
- self->presIndEndings[i % MOD][i / MOD] = t;
- }
- }
- else if (0 == strcmp(conjugate, "PRES-SUB"))
- {
- stem[strlen(stem) - 1] = '\0';
- self->presSubjStem = ExtendString_newFromString(stem);
- for (i = 0; i < count - 2; i++)
- {
- t = ExtendString_newFromString(ends[i]);
- if (self->thirdPersonOnly)
- {
- i = PERSON_THIRD;
- }
- self->presSubjEndings[i % MOD][i / MOD] = t;
- }
- }
- else if (0 == strcmp(conjugate, "IMPERFECT"))
- {
- stem[strlen(stem) - 1] = '\0';
- self->imperfectStem = ExtendString_newFromString(stem);
- for (i = 0; i < count - 2; i++)
- {
- t = ExtendString_newFromString(ends[i]);
- if (self->thirdPersonOnly)
- {
- i = PERSON_THIRD;
- }
- self->imperfectEndings[i % MOD][i / MOD] = t;
- }
- }
- else if (0 == strcmp(conjugate, "IMPERATIVE"))
- {
- stem[strlen(stem) - 1] = '\0';
- self->imperativeStem = ExtendString_newFromString(stem);
- for (i = 0; i < count - 2; i++)
- {
- t = ExtendString_newFromString(ends[i]);
- self->imperativeEndings[i] = t;
- }
- }
- else if (0 == strcmp(conjugate, "FUTURE"))
- {
- stem[strlen(stem) - 1] = '\0';
- self->futureStem = ExtendString_newFromString(stem);
- }
- else if (0 == strcmp(conjugate, "PRES-PART"))
- {
- self->presentParticipal = ExtendString_newFromString(stem);
- }
- else if (0 == strcmp(conjugate, "PAST-PART"))
- {
- self->pastParticipal = ExtendString_newFromString(stem);
- }
- else if (0 == strcmp(conjugate, "AUXILIARY"))
- {
- if (0 == strcmp(stem, "avoir"))
- {
- self->auxiliary = AUX_AVOIR;
- }
- else if (0 == strcmp(stem, "e^tre"))
- {
- self->auxiliary = AUX_ETRE;
- }
- else
- {
- fprintf(stderr, "Verb_newFromFile: unknown: %s\n", stem);
- self = (Verb *)0;
- goto out;
- }
- }
- else
- {
- fprintf(stderr, "Verb_newFromFile: unknown: %s\n", conjugate);
- self = (Verb *)0;
- goto out;
- }
-
- fgets(oneLine, 80, stream);
- }
-
- out:
-
- return self;
-
- }
-
-
- /* Verb_conjugate - assemble text of any form of a verb */
-
- ExtendString *ImperfectEndings[N_OF_PERSON][N_OF_PLURAL] =
- {
- (ExtendString *)"ais",
- (ExtendString *)"ions",
- (ExtendString *)"ais",
- (ExtendString *)"iez",
- (ExtendString *)"ait",
- (ExtendString *)"aient"
- };
-
- ExtendString *FutureEndings[N_OF_PERSON][N_OF_PLURAL] =
- {
- (ExtendString *)"ai",
- (ExtendString *)"ons",
- (ExtendString *)"as",
- (ExtendString *)"ez",
- (ExtendString *)"a",
- (ExtendString *)"ont"
- };
-
- ExtendString *AgreementEndings[N_OF_PLURAL][N_OF_GENDER] =
- {
- (ExtendString *)"",
- (ExtendString *)"e",
- (ExtendString *)"s",
- (ExtendString *)"es"
- };
-
- ExtendString *
- Verb_conjugate(self, form, tense)
- Verb *self;
- Form *form;
- int tense;
- {
- register int i, j;
- ExtendString cg[80];
- ExtendString *e, *f;
- ExtendString *result;
-
- i = form->person;
- j = form->plurality;
-
- if (self->thirdPersonOnly && (i != PERSON_THIRD || j != PLURAL_SINGULAR))
- {
- result = (ExtendString *)0;
- goto out;
- }
-
- switch (tense)
- {
- case TENSE_INFINITIVE:
-
- ExtendString_copy(cg, self->infinitive);
- break;
-
- case TENSE_PRESENT:
-
- ExtendString_copy(cg, self->presIndStem);
- ExtendString_cat(cg, self->presIndEndings[i][j]);
- break;
-
- case TENSE_IMPERFECT:
-
- ExtendString_copy(cg, self->imperfectStem);
- e = self->imperfectEndings[i][j];
- f = ImperfectEndings[i][j];
- ExtendString_cat(cg, e ? e : f);
- break;
-
- case TENSE_PASTCOMP:
-
- if (self->auxiliary == AUX_ETRE)
- {
- e = Verb_conjugate(Etre, form, TENSE_PRESENT);
- ExtendString_copy(cg, e);
- ExtendString_cat(cg, " ");
- ExtendString_cat(cg, self->pastParticipal);
- ExtendString_cat(cg, AgreementEndings[j][form->gender]);
- }
- else
- {
- e = Verb_conjugate(Avoir, form, TENSE_PRESENT);
- ExtendString_copy(cg, e);
- ExtendString_cat(cg, " ");
- ExtendString_cat(cg, self->pastParticipal);
- }
- ExtendString_destroy(e);
- break;
-
- case TENSE_FUTURE:
-
- ExtendString_copy(cg, self->futureStem);
- ExtendString_cat(cg, FutureEndings[i][j]);
- break;
-
- case TENSE_CONDITION:
-
- ExtendString_copy(cg, self->futureStem);
- ExtendString_cat(cg, ImperfectEndings[i][j]);
- break;
-
- case TENSE_SUBJUNCT:
-
- ExtendString_copy(cg, self->presSubjStem);
- ExtendString_cat(cg, self->presSubjEndings[i][j]);
- break;
-
- case TENSE_IMPERATIVE:
-
- ExtendString_copy(cg, self->imperativeStem);
- ExtendString_cat(cg, self->imperativeEndings[IMPERSUM(i, j)]);
- break;
-
- case TENSE_PLUPERFECT:
-
- if (self->auxiliary == AUX_ETRE)
- {
- e = Verb_conjugate(Etre, form, TENSE_IMPERFECT);
- ExtendString_copy(cg, e);
- ExtendString_cat(cg, " ");
- ExtendString_cat(cg, self->pastParticipal);
- ExtendString_cat(cg, AgreementEndings[j][form->gender]);
- }
- else
- {
- e = Verb_conjugate(Avoir, form, TENSE_IMPERFECT);
- ExtendString_copy(cg, e);
- ExtendString_cat(cg, " ");
- ExtendString_cat(cg, self->pastParticipal);
- }
- ExtendString_destroy(e);
- break;
-
- case TENSE_PASTSIMP:
- case TENSE_IMPSUBJ:
- case TENSE_PASTANT:
- case TENSE_FUTUREANT:
- case TENSE_CONDPERF:
- case TENSE_PLUPSUBJ:
-
- fprintf(stderr, "Verb_conjugate: not implemented: #%d\n", tense);
- break;
-
- default:
-
- fprintf(stderr, "Verb_conjugate: unknown tense: %d\n", tense);
- break;
-
- }
-
- i = ExtendString_len(cg) + 1;
- result = (ExtendString *)malloc(i);
- if (!result)
- {
- fprintf(stderr, "Verb_conjugate: malloc fails\n");
- goto out;
- }
-
- ExtendString_copy(result, cg);
-
- #if XDEBUG
- printf("Verb_conjugate: got %s (%s)\n", result, self->infinitive);
- #endif
-
- out:
-
- return result;
-
- }
-
- void
- Verb_destroy(self)
- Verb *self;
- {
-
- ExtendString_destroy(self->presentParticipal);
- ExtendString_destroy(self->pastParticipal);
- ExtendString_destroy(self->imperativeStem);
- ExtendString_destroy(self->presSubjStem);
- ExtendString_destroy(self->presIndStem);
- ExtendString_destroy(self->imperfectStem);
- ExtendString_destroy(self->infinitive);
-
- free(self);
-
- }
-
- #ifndef PRODUCTION
-
- /* Verb_printOn - write formatted representation to output file stream */
-
- void
- Verb_printOn(self, stream)
- Verb *self;
- FILE *stream;
- {
- register int i, j;
- ExtendString *e;
- int length;
- char *t, *f;
-
- t = ExtendString_externalFormat(self->infinitive);
- fprintf(stream, "VERB: %s (%d)\n", t, self->conjugationClass);
- fprintf(stream, "{\n");
- free(t);
-
- /* Output present indicative line */
-
- t = ExtendString_externalFormat(self->presIndStem);
- fprintf(stream, " PRES-IND: %s- ", t);
- free(t);
- for (j = 0; j < N_OF_PLURAL; j++)
- {
- for (i = 0; i < N_OF_PERSON; i++)
- {
- e = self->presIndEndings[i][j];
- if (e)
- {
- t = ExtendString_externalFormat(e);
- fprintf(stream, "%s ", t);
- free(t);
- }
- }
- }
- fprintf(stream, "\n");
-
- /* Output present subjunctive line */
-
- t = ExtendString_externalFormat(self->presSubjStem);
- fprintf(stream, " PRES-SUB: %s- ", t);
- free(t);
- for (j = 0; j < N_OF_PLURAL; j++)
- {
- for (i = 0; i < N_OF_PERSON; i++)
- {
- e = self->presSubjEndings[i][j];
- if (e)
- {
- t = ExtendString_externalFormat(e);
- fprintf(stream, "%s ", t);
- free(t);
- }
- }
- }
- fprintf(stream, "\n");
-
- /* Output imperatives */
-
- e = self->imperativeStem;
- if (e)
- {
- t = ExtendString_externalFormat(e);
- fprintf(stream, " IMPERATIVE: %s- ", t);
- free(t);
- for (j = 0; j < N_OF_PLURAL + 1; j++)
- {
- e = self->imperativeEndings[j];
- t = ExtendString_externalFormat(e);
- fprintf(stream, "%s ", t);
- free(t);
- }
- fprintf(stream, "\n");
- }
-
- /* Output imperfect */
-
- if (self->imperfectStem)
- {
- t = ExtendString_externalFormat(self->imperfectStem);
- fprintf(stream, " IMPERFECT: %s- ", t);
- free(t);
- for (j = 0; j < N_OF_PLURAL; j++)
- {
- for (i = 0; i < N_OF_PERSON; i++)
- {
- e = self->imperfectEndings[i][j];
- if (e)
- {
- t = ExtendString_externalFormat(e);
- fprintf(stream, "%s ", t);
- free(t);
- }
- }
- }
- fprintf(stream, "\n");
- }
-
- /* Output future stem */
-
- if (self->futureStem)
- {
- t = ExtendString_externalFormat(self->futureStem);
- fprintf(stream, " FUTURE: %s-\n", t);
- free(t);
- }
-
- /* Output participals */
-
- if (self->presentParticipal)
- {
- t = ExtendString_externalFormat(self->presentParticipal);
- fprintf(stream, " PRES-PART: %s\n", t);
- free(t);
- }
-
- if (self->pastParticipal)
- {
- t = ExtendString_externalFormat(self->pastParticipal);
- fprintf(stream, " PAST-PART: %s\n", t);
- free(t);
- }
-
- switch (self->auxiliary)
- {
- case AUX_AVOIR:
- fprintf(stream, " AUXILIARY: avoir\n");
- break;
- case AUX_ETRE:
- fprintf(stream, " AUXILIARY: e^tre\n");
- break;
- }
-
- fprintf(stream, "}\n\n");
-
- }
-
- #endif
-