home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / formes / part03 / verb.c next >
Encoding:
C/C++ Source or Header  |  1993-04-01  |  11.7 KB  |  563 lines

  1.  
  2. /*
  3.  *  Copyright (C) 1992-1993 Jeffrey Chilton
  4.  *
  5.  *  Permission is granted to anyone to make or distribute copies of
  6.  *  this program, in any medium, provided that the copyright notice
  7.  *  and permission notice are preserved, and that the distributor
  8.  *  grants the recipient permission for further redistribution as
  9.  *  permitted by this notice.
  10.  *  
  11.  *  Author's E-mail address:  172-9221@mcimail.com
  12.  *  
  13.  */
  14.  
  15. static char *whatstring = "@(#)verb.c    2.6 JWC";
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19.  
  20. #include "class.h"
  21. #include "form.h"
  22. #include "verb.h"
  23. #include "verbset.h"
  24.  
  25. extern Verb *Avoir;
  26. extern Verb *Etre;
  27.  
  28. #define MOD N_OF_PERSON
  29.  
  30. /* Verb_new - Create an empty verb object */
  31.  
  32. Verb *
  33. Verb_new(infinitive)
  34. char *infinitive;
  35. {
  36.     int pers;
  37.     int plur;
  38.     int gender;
  39.     Verb *self;
  40.  
  41.     self = (Verb *)malloc(sizeof (Verb));
  42.     if (!self)
  43.     {
  44.     fprintf(stderr, "Verb_new: malloc fails\n");
  45.     goto out;
  46.     }
  47.  
  48.     self->infinitive = ExtendString_newFromString(infinitive);
  49.  
  50.     for (pers = 0; pers < N_OF_PERSON; pers++)
  51.     {
  52.     for (plur = 0; plur < N_OF_PLURAL; plur++)
  53.     {
  54.         self->presIndEndings[pers][plur] = (ExtendString *)0;
  55.         self->presSubjEndings[pers][plur] = (ExtendString *)0;
  56.         self->imperfectEndings[pers][plur] = (ExtendString *)0;
  57.     }
  58.     }
  59.  
  60.     self->imperativeEndings[0] = (ExtendString *)0;
  61.     self->imperativeEndings[1] = (ExtendString *)0;
  62.     self->imperativeEndings[2] = (ExtendString *)0;
  63.  
  64.     self->presIndStem = (ExtendString *)0;
  65.     self->presSubjStem = (ExtendString *)0;
  66.     self->imperativeStem = (ExtendString *)0;
  67.     self->imperfectStem = (ExtendString *)0;
  68.     self->futureStem = (ExtendString *)0;
  69.     self->presentParticipal = (ExtendString *)0;
  70.     self->pastParticipal = (ExtendString *)0;
  71.  
  72.     self->conjugationClass = 0;
  73.     self->auxiliary = -1;
  74.  
  75. out:
  76.  
  77.     return self;
  78.  
  79. }
  80.  
  81. /* Verb_newFromFile - read formatted representation from file stream */
  82.  
  83. #define FORMAT " %[^:]: %s %s %s %s %s %s %s "
  84.  
  85. #define ENDS ends[0], ends[1], ends[2], ends[3], ends[4], ends[5]
  86.  
  87. Verb *
  88. Verb_newFromFile(infinitive, stream)
  89. char *infinitive;
  90. FILE *stream;
  91. {
  92.     register int i;
  93.     Verb *self;
  94.     char oneLine[80];
  95.     char conjugate[32];
  96.     char ends[6][32];
  97.     char stem[32];
  98.     Form *form;
  99.     ExtendString *t, u;
  100.     int count;
  101.  
  102.     self = Verb_new(infinitive);
  103.     if (!self)
  104.     {
  105.     goto out;
  106.     }
  107.  
  108.     fgets(oneLine, 80, stream);
  109.     while (TRUE)
  110.     {
  111.     if (oneLine[0] == '\n' || oneLine[0] == '{')
  112.     {
  113.         fgets(oneLine, 80, stream);
  114.         continue;
  115.     }
  116.  
  117.     if (0 == strcmp(oneLine, "}\n"))
  118.     {
  119.         break;
  120.     }
  121.  
  122.     count = sscanf(oneLine, FORMAT, conjugate, stem, ENDS);
  123.  
  124. #if XDEBUG
  125. printf("Verb_newFromFile: %s: ", conjugate);
  126. printf("%s ", stem);
  127. for (i = 0; i < count - 2; i++)
  128. {
  129.     printf("%s ", ends[i]);
  130. }
  131. printf("\n");
  132. #endif
  133.  
  134.     if (0 == strcmp(conjugate, "PRES-IND"))
  135.     {
  136.         stem[strlen(stem) - 1] = '\0';
  137.         self->presIndStem = ExtendString_newFromString(stem);
  138.         self->thirdPersonOnly = count < 8;
  139.         for (i = 0; i < count - 2; i++)
  140.         {
  141.         t = ExtendString_newFromString(ends[i]);
  142.         if (self->thirdPersonOnly)
  143.         {
  144.             i = PERSON_THIRD;
  145.         }
  146.             self->presIndEndings[i % MOD][i / MOD] = t;
  147.         }
  148.     }
  149.     else if (0 == strcmp(conjugate, "PRES-SUB"))
  150.     {
  151.         stem[strlen(stem) - 1] = '\0';
  152.         self->presSubjStem = ExtendString_newFromString(stem);
  153.         for (i = 0; i < count - 2; i++)
  154.         {
  155.         t = ExtendString_newFromString(ends[i]);
  156.         if (self->thirdPersonOnly)
  157.         {
  158.             i = PERSON_THIRD;
  159.         }
  160.         self->presSubjEndings[i % MOD][i / MOD] = t;
  161.         }
  162.     }
  163.     else if (0 == strcmp(conjugate, "IMPERFECT"))
  164.     {
  165.         stem[strlen(stem) - 1] = '\0';
  166.         self->imperfectStem = ExtendString_newFromString(stem);
  167.         for (i = 0; i < count - 2; i++)
  168.         {
  169.         t = ExtendString_newFromString(ends[i]);
  170.         if (self->thirdPersonOnly)
  171.         {
  172.             i = PERSON_THIRD;
  173.         }
  174.         self->imperfectEndings[i % MOD][i / MOD] = t;
  175.         }
  176.     }
  177.     else if (0 == strcmp(conjugate, "IMPERATIVE"))
  178.     {
  179.         stem[strlen(stem) - 1] = '\0';
  180.         self->imperativeStem = ExtendString_newFromString(stem);
  181.         for (i = 0; i < count - 2; i++)
  182.         {
  183.         t = ExtendString_newFromString(ends[i]);
  184.         self->imperativeEndings[i] = t;
  185.         }
  186.     }
  187.     else if (0 == strcmp(conjugate, "FUTURE"))
  188.     {
  189.         stem[strlen(stem) - 1] = '\0';
  190.         self->futureStem = ExtendString_newFromString(stem);
  191.     }
  192.     else if (0 == strcmp(conjugate, "PRES-PART"))
  193.     {
  194.         self->presentParticipal = ExtendString_newFromString(stem);
  195.     }
  196.     else if (0 == strcmp(conjugate, "PAST-PART"))
  197.     {
  198.         self->pastParticipal = ExtendString_newFromString(stem);
  199.     }
  200.     else if (0 == strcmp(conjugate, "AUXILIARY"))
  201.     {
  202.         if (0 == strcmp(stem, "avoir"))
  203.         {
  204.         self->auxiliary = AUX_AVOIR;
  205.         }
  206.         else if (0 == strcmp(stem, "e^tre"))
  207.         {
  208.         self->auxiliary = AUX_ETRE;
  209.         }
  210.         else
  211.         {
  212.         fprintf(stderr, "Verb_newFromFile: unknown: %s\n", stem);
  213.         self = (Verb *)0;
  214.         goto out;
  215.         }
  216.     }
  217.     else
  218.     {
  219.         fprintf(stderr, "Verb_newFromFile: unknown: %s\n", conjugate);
  220.         self = (Verb *)0;
  221.         goto out;
  222.     }
  223.  
  224.     fgets(oneLine, 80, stream);
  225.     }
  226.  
  227. out:
  228.  
  229.     return self;
  230.  
  231. }
  232.  
  233.  
  234. /* Verb_conjugate - assemble text of any form of a verb */
  235.  
  236. ExtendString *ImperfectEndings[N_OF_PERSON][N_OF_PLURAL] =
  237. {
  238.     (ExtendString *)"ais",
  239.     (ExtendString *)"ions",
  240.     (ExtendString *)"ais",
  241.     (ExtendString *)"iez",
  242.     (ExtendString *)"ait",
  243.     (ExtendString *)"aient"
  244. };
  245.  
  246. ExtendString *FutureEndings[N_OF_PERSON][N_OF_PLURAL] =
  247. {
  248.     (ExtendString *)"ai",
  249.     (ExtendString *)"ons",
  250.     (ExtendString *)"as",
  251.     (ExtendString *)"ez",
  252.     (ExtendString *)"a",
  253.     (ExtendString *)"ont"
  254. };
  255.  
  256. ExtendString *AgreementEndings[N_OF_PLURAL][N_OF_GENDER] =
  257. {
  258.     (ExtendString *)"",
  259.     (ExtendString *)"e",
  260.     (ExtendString *)"s",
  261.     (ExtendString *)"es"
  262. };
  263.  
  264. ExtendString *
  265. Verb_conjugate(self, form, tense)
  266. Verb *self;
  267. Form *form;
  268. int tense;
  269. {
  270.     register int i, j;
  271.     ExtendString cg[80];
  272.     ExtendString *e, *f;
  273.     ExtendString *result;
  274.  
  275.     i = form->person;
  276.     j = form->plurality;
  277.  
  278.     if (self->thirdPersonOnly && (i != PERSON_THIRD || j != PLURAL_SINGULAR))
  279.     {
  280.     result = (ExtendString *)0;
  281.     goto out;
  282.     }
  283.  
  284.     switch (tense)
  285.     {
  286.     case TENSE_INFINITIVE:
  287.  
  288.         ExtendString_copy(cg, self->infinitive);
  289.         break;
  290.  
  291.     case TENSE_PRESENT:
  292.  
  293.         ExtendString_copy(cg, self->presIndStem);
  294.         ExtendString_cat(cg, self->presIndEndings[i][j]);
  295.         break;
  296.  
  297.     case TENSE_IMPERFECT:
  298.  
  299.         ExtendString_copy(cg, self->imperfectStem);
  300.         e = self->imperfectEndings[i][j];
  301.         f = ImperfectEndings[i][j];
  302.         ExtendString_cat(cg, e ? e : f);
  303.         break;
  304.  
  305.     case TENSE_PASTCOMP:
  306.  
  307.         if (self->auxiliary == AUX_ETRE)
  308.         {
  309.         e = Verb_conjugate(Etre, form, TENSE_PRESENT);
  310.         ExtendString_copy(cg, e);
  311.         ExtendString_cat(cg, " ");
  312.         ExtendString_cat(cg, self->pastParticipal);
  313.         ExtendString_cat(cg, AgreementEndings[j][form->gender]);
  314.         }
  315.         else
  316.         {
  317.         e = Verb_conjugate(Avoir, form, TENSE_PRESENT);
  318.         ExtendString_copy(cg, e);
  319.         ExtendString_cat(cg, " ");
  320.         ExtendString_cat(cg, self->pastParticipal);
  321.         }
  322.         ExtendString_destroy(e);
  323.         break;
  324.  
  325.     case TENSE_FUTURE:
  326.  
  327.         ExtendString_copy(cg, self->futureStem);
  328.         ExtendString_cat(cg, FutureEndings[i][j]);
  329.         break;
  330.  
  331.     case TENSE_CONDITION:
  332.  
  333.         ExtendString_copy(cg, self->futureStem);
  334.         ExtendString_cat(cg, ImperfectEndings[i][j]);
  335.         break;
  336.  
  337.     case TENSE_SUBJUNCT:
  338.  
  339.         ExtendString_copy(cg, self->presSubjStem);
  340.         ExtendString_cat(cg, self->presSubjEndings[i][j]);
  341.         break;
  342.  
  343.     case TENSE_IMPERATIVE:
  344.  
  345.         ExtendString_copy(cg, self->imperativeStem);
  346.         ExtendString_cat(cg, self->imperativeEndings[IMPERSUM(i, j)]);
  347.         break;
  348.  
  349.     case TENSE_PLUPERFECT:
  350.  
  351.         if (self->auxiliary == AUX_ETRE)
  352.         {
  353.         e = Verb_conjugate(Etre, form, TENSE_IMPERFECT);
  354.         ExtendString_copy(cg, e);
  355.         ExtendString_cat(cg, " ");
  356.         ExtendString_cat(cg, self->pastParticipal);
  357.         ExtendString_cat(cg, AgreementEndings[j][form->gender]);
  358.         }
  359.         else
  360.         {
  361.         e = Verb_conjugate(Avoir, form, TENSE_IMPERFECT);
  362.         ExtendString_copy(cg, e);
  363.         ExtendString_cat(cg, " ");
  364.         ExtendString_cat(cg, self->pastParticipal);
  365.         }
  366.         ExtendString_destroy(e);
  367.         break;
  368.  
  369.     case TENSE_PASTSIMP:
  370.     case TENSE_IMPSUBJ:
  371.     case TENSE_PASTANT:
  372.     case TENSE_FUTUREANT:
  373.     case TENSE_CONDPERF:
  374.     case TENSE_PLUPSUBJ:
  375.  
  376.         fprintf(stderr, "Verb_conjugate: not implemented: #%d\n", tense);
  377.         break;
  378.  
  379.     default:
  380.  
  381.         fprintf(stderr, "Verb_conjugate: unknown tense: %d\n", tense);
  382.         break;
  383.  
  384.     }
  385.  
  386.     i = ExtendString_len(cg) + 1;
  387.     result = (ExtendString *)malloc(i);
  388.     if (!result)
  389.     {
  390.     fprintf(stderr, "Verb_conjugate: malloc fails\n");
  391.     goto out;
  392.     }
  393.  
  394.     ExtendString_copy(result, cg);
  395.  
  396. #if XDEBUG
  397.     printf("Verb_conjugate: got %s (%s)\n", result, self->infinitive);
  398. #endif
  399.  
  400. out:
  401.  
  402.     return result;
  403.  
  404. }
  405.  
  406. void
  407. Verb_destroy(self)
  408. Verb *self;
  409. {
  410.  
  411.     ExtendString_destroy(self->presentParticipal);
  412.     ExtendString_destroy(self->pastParticipal);
  413.     ExtendString_destroy(self->imperativeStem);
  414.     ExtendString_destroy(self->presSubjStem);
  415.     ExtendString_destroy(self->presIndStem);
  416.     ExtendString_destroy(self->imperfectStem);
  417.     ExtendString_destroy(self->infinitive);
  418.  
  419.     free(self);
  420.  
  421. }
  422.  
  423. #ifndef PRODUCTION
  424.  
  425. /* Verb_printOn - write formatted representation to output file stream */
  426.  
  427. void
  428. Verb_printOn(self, stream)
  429. Verb *self;
  430. FILE *stream;
  431. {
  432.     register int i, j;
  433.     ExtendString *e;
  434.     int length;
  435.     char *t, *f;
  436.  
  437.     t = ExtendString_externalFormat(self->infinitive);
  438.     fprintf(stream, "VERB: %s (%d)\n", t, self->conjugationClass);
  439.     fprintf(stream, "{\n");
  440.     free(t);
  441.  
  442.     /* Output present indicative line */
  443.  
  444.     t = ExtendString_externalFormat(self->presIndStem);
  445.     fprintf(stream, "    PRES-IND: %s- ", t);
  446.     free(t);
  447.     for (j = 0; j < N_OF_PLURAL; j++)
  448.     {
  449.     for (i = 0; i < N_OF_PERSON; i++)
  450.     {
  451.         e = self->presIndEndings[i][j];
  452.         if (e)
  453.         {
  454.         t = ExtendString_externalFormat(e);
  455.         fprintf(stream, "%s ", t);
  456.         free(t);
  457.         }
  458.     }
  459.     }
  460.     fprintf(stream, "\n");
  461.  
  462.     /* Output present subjunctive line */
  463.  
  464.     t = ExtendString_externalFormat(self->presSubjStem);
  465.     fprintf(stream, "    PRES-SUB: %s- ", t);
  466.     free(t);
  467.     for (j = 0; j < N_OF_PLURAL; j++)
  468.     {
  469.     for (i = 0; i < N_OF_PERSON; i++)
  470.     {
  471.         e = self->presSubjEndings[i][j];
  472.         if (e)
  473.         {
  474.         t = ExtendString_externalFormat(e);
  475.         fprintf(stream, "%s ", t);
  476.         free(t);
  477.         }
  478.     }
  479.     }
  480.     fprintf(stream, "\n");
  481.  
  482.     /* Output imperatives */
  483.  
  484.     e = self->imperativeStem;
  485.     if (e)
  486.     {
  487.     t = ExtendString_externalFormat(e);
  488.     fprintf(stream, "    IMPERATIVE: %s- ", t);
  489.     free(t);
  490.     for (j = 0; j < N_OF_PLURAL + 1; j++)
  491.     {
  492.         e = self->imperativeEndings[j];
  493.         t = ExtendString_externalFormat(e);
  494.         fprintf(stream, "%s ", t);
  495.         free(t);
  496.     }
  497.     fprintf(stream, "\n");
  498.     }
  499.  
  500.     /* Output imperfect */
  501.  
  502.     if (self->imperfectStem)
  503.     {
  504.     t = ExtendString_externalFormat(self->imperfectStem);
  505.         fprintf(stream, "    IMPERFECT: %s- ", t);
  506.     free(t);
  507.     for (j = 0; j < N_OF_PLURAL; j++)
  508.     {
  509.         for (i = 0; i < N_OF_PERSON; i++)
  510.         {
  511.         e = self->imperfectEndings[i][j];
  512.         if (e)
  513.         {
  514.             t = ExtendString_externalFormat(e);
  515.             fprintf(stream, "%s ", t);
  516.             free(t);
  517.         }
  518.         }
  519.     }
  520.     fprintf(stream, "\n");
  521.     }
  522.  
  523.     /* Output future stem */
  524.  
  525.     if (self->futureStem)
  526.     {
  527.     t = ExtendString_externalFormat(self->futureStem);
  528.         fprintf(stream, "    FUTURE: %s-\n", t);
  529.     free(t);
  530.     }
  531.  
  532.     /* Output participals */
  533.  
  534.     if (self->presentParticipal)
  535.     {
  536.     t = ExtendString_externalFormat(self->presentParticipal);
  537.     fprintf(stream, "    PRES-PART: %s\n", t);
  538.     free(t);
  539.     }
  540.  
  541.     if (self->pastParticipal)
  542.     {
  543.     t = ExtendString_externalFormat(self->pastParticipal);
  544.     fprintf(stream, "    PAST-PART: %s\n", t);
  545.     free(t);
  546.     }
  547.  
  548.     switch (self->auxiliary)
  549.     {
  550.     case AUX_AVOIR:
  551.         fprintf(stream, "    AUXILIARY: avoir\n");
  552.         break;
  553.     case AUX_ETRE:
  554.         fprintf(stream, "    AUXILIARY: e^tre\n");
  555.         break;
  556.     }
  557.  
  558.     fprintf(stream, "}\n\n");
  559.  
  560. }
  561.  
  562. #endif
  563.