home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 443.lha / grammar_v1.5 / grammar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-02  |  12.9 KB  |  552 lines

  1. /* GRAMMER ERROR FINDER PROGRAM                   */
  2. /* r p sarna                                      */
  3.  
  4. /* !!!!!!!!!!!!!!! COPYLEFTED !!!!!!!!!!!!!!!!!!! */
  5. /* !!!!!!!!!See notice below in code !!!!!!!!!!!! */
  6.  
  7. /* original version: 25 Sep 1990                  */
  8.  
  9. /* FINDS:                                         */
  10. /*                                                */
  11.  
  12. #define VERSION "$Revision: 1.5 $"
  13.  
  14. #define YES 1
  15. #define NO 2
  16. #define TRUE 1
  17. #define FALSE 0
  18.  
  19. #define COMMA ','
  20. #define PERIOD '.'
  21. #define LPAREN '('
  22. #define RPAREN ')'
  23. #define LBRACKET '['
  24. #define RBRACKET ']'
  25. #define LBRACE '{'
  26. #define RBRACE '}'
  27. #define ON 1
  28. #define OFF 0
  29.  
  30. #define UNIXFLAG 0
  31.  
  32. #ifdef __UNIX__
  33. #undef UNIXFLAG
  34. #define UNIXFLAG 1
  35. #endif
  36. #ifdef __unix__
  37. #undef UNIXFLAG
  38. #define UNIXFLAG 1
  39. #endif
  40. #ifdef unix
  41. #undef UNIXFLAG
  42. #define UNIXFLAG 1
  43. #endif
  44. #ifdef UNIX
  45. #undef UNIXFLAG
  46. #define UNIXFLAG 1
  47. #endif
  48.  
  49. #define MSDOSFLAG 0
  50.  
  51. #ifdef __MSDOS__
  52. #undef MSDOSFLAG
  53. #define MSDOSFLAG 1
  54. #endif
  55. #ifdef MSDOS
  56. #undef MSDOSFLAG
  57. #define MSDOSFLAG 1
  58. #endif
  59.  
  60. /* the following, as well as all Amiga references by TCS 10/7/90 */
  61. #define AMIGAFLAG 0
  62.  
  63. #ifdef AMIGA
  64. #undef AMIGAFLAG
  65. #define AMIGAFLAG 1
  66. #endif
  67. #ifdef amiga
  68. #undef AMIGAFLAG
  69. #define AMIGAFLAG 1
  70. #endif
  71. #ifdef __AMIGA__
  72. #undef AMIGAFLAG
  73. #define AMIGAFLAG 1
  74. #endif
  75. #ifdef __amiga__
  76. #undef AMIGAFLAG
  77. #define AMIGAFLAG 1
  78. #endif
  79.  
  80. #include <stdio.h>
  81. #include <string.h>
  82.  
  83. char id[] = "$Header: /u/red/programs/grammar/grammar.c,v 1.5 90/09/25 20:44:38 red Exp Locker: red $";
  84.  
  85. char copyleft1[] = "Copyright (c) 1990 R. P. Sarna.  All Rights Reserved";
  86. char copyleft2[] = "Free distribution allowed if source also given";
  87.  
  88. char prevw[35];
  89. char currw[35];
  90.  
  91. FILE *fopen();
  92. FILE *ibuf;
  93.  
  94. void exit(int);
  95. int makeupper(char);
  96. int getword(void);
  97. int isletter(char);
  98. int givechar(void);
  99. int issmall(char);
  100. int lastchars(char *str, char *pat);
  101.  
  102. char newword[25];
  103. long int nline;
  104. int endsent;
  105. int exclams;
  106. int hyphens;
  107. long int nword;
  108. int verys;
  109. int ands;
  110. int adverbs;
  111. int ings;
  112. int passives;
  113. int nsent;
  114. int lastchar;
  115. int begsent;
  116. int vflag;    /* to throw away ventura stuff */
  117. int tflag;    /* to check for word "that" */
  118.   
  119. float words_sent;
  120. float adverbs_sent;
  121. float ings_sent;
  122. float exclams_sent;
  123. float verys_sent;
  124. float ands_sent;
  125. float passives_sent;
  126. float hyphens_sent;
  127.  
  128. void main(int argc, char **argv)
  129. {
  130.     int namearg;
  131.     
  132.     char tversion[30];
  133.     char version[10];
  134.     char dummy[19];
  135.  
  136.     vflag = FALSE;
  137.     tflag = FALSE;
  138.     newword[0] = '\0';
  139.     nline = 0L;
  140.     endsent = TRUE;
  141.     begsent = TRUE;
  142.     nsent = 1;
  143.     exclams = 0;
  144.     hyphens = 0;
  145.     verys = 0;
  146.     ands = 0;
  147.     ings = 0;
  148.     adverbs = 0;
  149.     passives = 0;
  150.     nword = 0;
  151.     namearg = 1;
  152.  
  153.     prevw[0] = '\0';
  154.                     
  155.     strcpy(tversion, VERSION);
  156.     sscanf(tversion, "%s %s", dummy, version);
  157. #if UNIXFLAG
  158.     strcat(version, " (Unix)");
  159. #endif
  160. #if MSDOSFLAG
  161.     strcat(version, " (MS-DOS)");
  162. #endif
  163. #if AMIGAFLAG
  164.     strcat(version, " (Amiga)");
  165. #endif
  166.  
  167.     if ((argv[1][0] == '-') && (argv[1][1] == 'h')) {
  168.         printf("GRAMMAR\n");
  169.         printf("     r p sarna   Version %s\n", version);
  170.         printf("\nThis program checks for improper grammar.\n");
  171.         printf("\nThe program looks for:");
  172.         printf("\n   Repeated words.");
  173.         printf("\n   Split infinitives.");
  174.         printf("\n   Sentences beginning with AND or BUT.");
  175.         printf("\n   Sentences ending with prepositions.");
  176.         printf("\n   Use of the word VERY.");
  177.         printf("\n   Use of the word THAT (with -t option).");
  178.         printf("\n   Possible use of LIKE instead of AS.");
  179.         printf("\n   Double negatives.");
  180.         printf("\n   Some types of wordiness.");
  181.         printf("\n   Improper pronoun use.\n");
  182.  
  183. #if UNIXFLAG
  184.         printf("\nUsage: %s [-v -t] filename\n", argv[0]);
  185. #else
  186.         printf("\nUsage: grammar [-v -t] filename\n");
  187. #endif
  188.         printf(  "       (-v for Xerox Ventura Publisher files)\n");
  189.         printf(  "       (-t to show lines with word THAT)\n");
  190.         exit(1);
  191.     }
  192.  
  193.  
  194.     if ((argv[1][0] == '-') && (argv[1][1] == 'v')) {
  195.         vflag = TRUE;
  196.         namearg++;
  197.     }
  198.     if ((argv[2][0] == '-') && (argv[2][1] == 'v')) {
  199.         vflag = TRUE;
  200.         namearg++;
  201.     }
  202.     if ((argv[1][0] == '-') && (argv[1][1] == 't')) {
  203.         tflag = TRUE;
  204.         namearg++;
  205.     }
  206.     if ((argv[2][0] == '-') && (argv[2][1] == 't')) {
  207.         tflag = TRUE;
  208.         namearg++;
  209.     }
  210.  
  211.     if (argc < (namearg + 1)) {
  212. #if UNIXFLAG
  213.         printf("\nUsage: %s [-v -t] filename", argv[0]);
  214.         printf("\n    or %s -help\n", argv[0]);
  215. #else
  216.         printf("\nUsage: grammar [-v -t] filename");
  217.         printf("\n    or grammar -help\n");
  218. #endif
  219.         exit(1);
  220.     }
  221.  
  222.     if ((ibuf = fopen(argv[namearg], "r")) == NULL) {
  223. #if UNIXFLAG
  224.         fprintf(stderr, "error: %s: can't find %s\n", argv[0], argv[namearg]);
  225. #else
  226.         fprintf(stderr, "error: grammar: can't find %s\n", argv[namearg]);
  227. #endif
  228.         exit(1);
  229.     }
  230.     
  231.     printf("\n\nGRAMMAR CHECKING PROGRAM  --  r p sarna  -- Ver. %s\n", version);
  232.     printf(    "     Copyright (c) 1990 R. P. Sarna.  All Rights Reserved.\n");
  233.     printf(    "        Free distribution allowed if source also given.\n");
  234.     printf("\n-------------------------\n");
  235.  
  236.     while (getword() == TRUE) {
  237.         strcpy(currw, newword);
  238.  
  239.         if (begsent) {
  240.             if (!(strcmp(currw, "AND"))) 
  241.               printf("A sentence begins with AND in line %ld.\n",
  242.               nline);
  243.             if (!(strcmp(currw, "BUT"))) 
  244.               printf("A sentence begins with BUT in line %ld.\n",
  245.               nline);
  246.             begsent = FALSE;
  247.         }
  248.                 
  249.         if (endsent) begsent = TRUE;
  250.             
  251.         if (!(strcmp(prevw, currw)))
  252.             printf("The word %s is repeated in line %ld.\n",
  253.                     currw, nline);
  254.     
  255.         if (!(strcmp(currw, "VERY"))) {
  256.             printf("Is the use of the word VERY in line %ld necessary?\n", nline);
  257.             verys++;
  258.         }
  259.     
  260.         if (tflag)
  261.             if (!(strcmp(currw, "THAT"))) {
  262.                 printf("Is the word THAT necessary in line %ld?\n", nline);
  263.             };
  264.     
  265.         if ((!(strcmp(prevw, "LIKE"))) && (!(strcmp(currw, "I")))) {
  266.             printf("Possible use of LIKE instead of AS in line %ld.\n",
  267.                 nline);
  268.         }
  269.     
  270.         if ((!(strcmp(prevw, "LIKE"))) && (!(strcmp(currw, "WE")))) {
  271.             printf("Possible use of LIKE instead of AS in line %ld.\n",
  272.                 nline);
  273.         }
  274.     
  275.         if ((!(strcmp(prevw, "LIKE"))) && (!(strcmp(currw, "HE")))) {
  276.             printf("Possibly AS should be used instead of LIKE in line %ld.\n",
  277.                 nline);
  278.         }
  279.     
  280.         if ((!(strcmp(prevw, "LIKE"))) && (!(strcmp(currw, "SHE")))) {
  281.             printf("Possibly AS should be used instead of LIKE in line %ld.\n",
  282.                 nline);
  283.         }
  284.     
  285.         if ((!(strcmp(prevw, "LIKE"))) && (!(strcmp(currw, "THEY")))) {
  286.             printf("Possibly AS should be used instead of LIKE in line %ld.\n",
  287.                 nline);
  288.         }
  289.     
  290.         if ((!(strcmp(prevw, "NOT"))) && (!(strcmp(currw, "HARDLY")))) {
  291.             printf("The double negative NOT HARDLY is used in line %ld.\n",
  292.                 nline);
  293.         }
  294.     
  295.         if ((!(strcmp(prevw, "HARDLY"))) && (!(strcmp(currw, "NOT")))) {
  296.             printf("The double negative HARDLY NOT is used in line %ld.\n",
  297.                 nline);
  298.         }
  299.     
  300.         if ((!(strcmp(prevw, "HARDLY"))) && (!(strcmp(currw, "EVER")))) {
  301.             printf("The double negative HARDLY EVER is used in line %ld.\n",
  302.                 nline);
  303.         }
  304.     
  305.         if ((!(strcmp(prevw, "HARDLY"))) && (!(strcmp(currw, "NEVER")))) {
  306.             printf("The double negative HARDLY NEVER is used in line %ld.\n",
  307.                 nline);
  308.         }
  309.     
  310.         if ((!(strcmp(prevw, "NOTE"))) && (!(strcmp(currw, "THAT")))) {
  311.             printf("The phrase NOTE THAT in line %ld may be excessively wordy.\n",
  312.                 nline);
  313.         }
  314.     
  315.         if ((!(strcmp(prevw, "AS"))) && (!(strcmp(currw, "US")))) {
  316.             printf("Use WE instead of %s in line %ld.\n",
  317.                 currw, nline);
  318.         }
  319.     
  320.         if ((!(strcmp(prevw, "AS"))) && (!(strcmp(currw, "HIM")))) {
  321.             printf("Use HE instead of %s in line %ld.\n",
  322.                 currw, nline);
  323.         }
  324.     
  325.         if ((!(strcmp(prevw, "AS"))) && (!(strcmp(currw, "HER")))) {
  326.             printf("Possible misuse of %s instead of SHE in line %ld.\n",
  327.                 currw, nline);
  328.         }
  329.     
  330.         if ((!(strcmp(prevw, "THAN"))) && (!(strcmp(currw, "US")))) {
  331.             printf("Use WE instead of %s in line %ld.\n",
  332.                 currw, nline);
  333.         }
  334.     
  335.         if ((!(strcmp(prevw, "THAN"))) && (!(strcmp(currw, "HIM")))) {
  336.             printf("Use HE instead of %s in line %ld.\n",
  337.                 currw, nline);
  338.         }
  339.     
  340.         if ((!(strcmp(prevw, "THAN"))) && (!(strcmp(currw, "HER")))) {
  341.             printf("Possibly use SHE instead of %s in line %ld.\n",
  342.                 currw, nline);
  343.         }
  344.     
  345.         if ((endsent) && (!(strcmp(currw, "OF")))) {
  346.             printf("A sentence ends with the preposition %s in line %ld.\n",
  347.                 currw, nline);
  348.         }
  349.     
  350.         if ((endsent) && (!(strcmp(currw, "WITH")))) {
  351.             printf("A sentence ends with the preposition %s in line %ld.\n",
  352.                 currw, nline);
  353.         }
  354.  
  355.         if ((endsent) && (!(strcmp(currw, "TO")))) {
  356.             printf("A sentence ends with the preposition %s in line %ld.\n",
  357.                 currw, nline);
  358.         }
  359.  
  360.         if ((!(strcmp(prevw, "TO"))) && (lastchars(currw, "LY"))) {
  361.             printf("%s %s appears to be a split infinitive in line %ld.\n",
  362.                 prevw, currw, nline);
  363.         }
  364.     
  365.         if (!(strcmp(currw, "IS"))) passives++;
  366.         if (!(strcmp(currw, "WAS"))) passives++;
  367.         if (!(strcmp(currw, "WERE"))) passives++;
  368.         if (!(strcmp(currw, "ARE"))) passives++;
  369.         if (!(strcmp(currw, "AND"))) ands++;
  370.         if (lastchars(currw, "ING")) ings++;
  371.         if (lastchars(currw, "LY")) adverbs++;
  372.         
  373.         strcpy(prevw, currw);
  374.     }
  375.     printf("\n-------------------------\n");
  376.     printf("Number of sentences: %d\n", nsent - 1);
  377.     printf("Number of words: %d\n\n", nword);
  378.  
  379.     if (nsent < 1) nsent = 1;
  380.     words_sent = (float)nword / (float)(nsent - 1);
  381.     adverbs_sent = (float)adverbs / (float)(nsent - 1);
  382.     ings_sent = (float)ings / (float)(nsent - 1);
  383.     exclams_sent = (float)exclams / (float)(nsent - 1);
  384.     verys_sent = (float)verys / (float)(nsent - 1);
  385.     ands_sent = (float)ands / (float)(nsent - 1);
  386.     passives_sent = (float)passives / (float)(nsent - 1);
  387.     hyphens_sent = (float)hyphens / (float)(nsent - 1);
  388.     
  389.     printf("The average number of words per sentence is %0.3f\n", words_sent);
  390.     printf("   For comparison: Steinbeck = 16.397  Hemingway = 15.782  BYTE = 22.000\n");
  391.  
  392.     printf("The average number of adverbs per sentence is %0.3f\n", adverbs_sent);
  393.     printf("   For comparison: Steinbeck = 0.247  Hemingway = 0.253  BYTE = 0.328\n");
  394.  
  395.     printf("The average number of words ending in -ING per sentence is %0.3f\n", ings_sent);
  396.     printf("   For comparison: Steinbeck = 0.342  Hemingway = 0.425  BYTE = 0.484\n");
  397.  
  398.     printf("The average number of exclamation points per sentence is %0.3f\n", exclams_sent);
  399.     printf("   For comparison: Steinbeck = 0.000  Hemingway = 0.000  BYTE = 0.000\n");
  400.  
  401.     printf("The average number of uses of VERY per sentence is %0.3f\n", verys_sent);
  402.     printf("   For comparison: Steinbeck = 0.027  Hemingway = 0.092  BYTE = 0.000\n");
  403.  
  404.     printf("The average number of uses of AND per sentence is %0.3f\n", ands_sent);
  405.     printf("   For comparison: Steinbeck = 1.219  Hemingway = 0.609  BYTE = 0.688\n");
  406.  
  407.     printf("The average number of passive verbs per sentence is %0.3f\n", passives_sent);
  408.     printf("   For comparison: Steinbeck = 0.233  Hemingway = 0.437  BYTE = 0.250\n");
  409.     
  410.     printf("The average number of hyphens per sentence is %0.3f\n", hyphens_sent);
  411.     printf("   For comparison: Steinbeck = 0.000  Hemingway = 0.034  BYTE = 0.703\n");
  412.  
  413.     fclose(ibuf);
  414.     exit(0);
  415.  
  416. }
  417.  
  418. /* ########## end of main() ########## */
  419.  
  420. int getword(void)
  421. {
  422.     static int c;
  423.     char string[25];
  424.     int p;
  425.     
  426.     if (endsent) endsent = FALSE;
  427.     
  428.     p = 0;
  429.     if (c == '\n') nline++;
  430.     while ((!isletter(c = givechar())) && (c != EOF));
  431.     if (c == EOF) {
  432.         newword[p] = '\0';
  433.         return(FALSE);
  434.     }
  435.     if (isletter(c)) {
  436.         newword[p] = makeupper(c);
  437.         p++;
  438.     }
  439.     while (((c = givechar()) != EOF) && (isletter(c))) {
  440.         newword[p] = makeupper(c);
  441.         p++;
  442.     }
  443.     newword[p] = '\0';
  444.     nword++;
  445.     
  446.     if (c == EOF) return(FALSE);
  447.     return(TRUE);
  448. }
  449.  
  450. int isletter(char c)
  451. {
  452.     if ((c >= 'A') && (c <= 'Z')) return(TRUE);
  453.     if ((c >= 'a') && (c <= 'z')) return(TRUE);
  454.     if ((c >= '0') && (c <= '9')) return(TRUE);
  455.  
  456.     if (c =='!') exclams++;
  457.     if (c == '\n') nline++;
  458.     if (c == '-') hyphens++;
  459.     if ((c == '-') && (lastchar == '-')) hyphens = hyphens - 2;
  460.     if (hyphens < 0) hyphens = 0;
  461.     if ((c == '.') && (issmall(lastchar))) {
  462.         nsent++;
  463.         endsent = TRUE;
  464.     }
  465.     if ((c == '!') && (issmall(lastchar))) {
  466.         nsent++;
  467.         endsent = TRUE;
  468.     }
  469.     if ((c == '?') && (issmall(lastchar))) {
  470.         nsent++;
  471.         endsent = TRUE;
  472.     }
  473.  
  474.     return(FALSE);
  475.  
  476. }
  477.  
  478. int makeupper(char c)
  479. {
  480.     if ((c >= 'a') && (c <= 'z')) c = c - ('a' - 'A');
  481.     return(c);
  482. }
  483.  
  484. int givechar(void)
  485. {
  486.     static int charin;
  487.     
  488.     lastchar = charin;
  489.     charin = fgetc(ibuf);
  490.  
  491.     /* Throw away Ventura stuff (duplicate in case stacked
  492.        format commands): */
  493.     if (vflag) {
  494.         if (charin == '<') {
  495.             while ((charin = fgetc(ibuf)) != '>');
  496.             charin = fgetc(ibuf);
  497.         }
  498.         if (charin == '<') {
  499.             while ((charin = fgetc(ibuf)) != '>');
  500.             charin = fgetc(ibuf);
  501.         }
  502.         if (charin == '<') {
  503.             while ((charin = fgetc(ibuf)) != '>');
  504.             charin = fgetc(ibuf);
  505.         }
  506.         if (charin == '@') {
  507.             while ((charin = fgetc(ibuf)) != '=');
  508.             charin = fgetc(ibuf);
  509.         }
  510.         if (charin == '@') {
  511.             while ((charin = fgetc(ibuf)) != '=');
  512.             charin = fgetc(ibuf);
  513.         }
  514.         if (charin == '@') {
  515.             while ((charin = fgetc(ibuf)) != '=');
  516.             charin = fgetc(ibuf);
  517.         }
  518.     }
  519.         /* end Ventura */
  520.  
  521.     return(charin);
  522.  
  523. }
  524.  
  525. int issmall(char x)
  526. {
  527.     if ((x >= 'a') && (x <= 'z')) return(TRUE);
  528.     else return(FALSE);
  529.     
  530. }
  531.  
  532. int lastchars(char *str, char *pat)
  533. {
  534.     char *ps;
  535.     char *pp;
  536.     int flag;
  537.     
  538.     flag = TRUE;
  539.     
  540.     ps = (char *)((int)str + (strlen(str) - 1));
  541.     pp = (char *)((int)pat + (strlen(pat) - 1));
  542.  
  543.     while ((ps >= str) && (pp >= pat)) {
  544.         if (*ps != *pp) flag = FALSE;
  545.         ps--;
  546.         pp--;
  547.     }
  548.     return(flag);
  549.     
  550. }
  551.  
  552.