home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume10 / get_grammar < prev    next >
Text File  |  1990-01-08  |  5KB  |  224 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v10i003: Extract a grammar from a YACC file
  3. From: lupton@uhccux.uhcc.hawaii.edu (Robert Lupton)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 10, Issue 3
  7. Submitted-by: lupton@uhccux.uhcc.hawaii.edu (Robert Lupton)
  8. Archive-name: get_grammar
  9.  
  10. Here's a simple programme to take a yacc (or bison) file and convert it
  11. to a readable form by stripping out all of the C. If given the -t flag
  12. it'll produce TeX output (and strip comments; I couldn't be bothered to
  13. figure out how to make them look nice)
  14.  
  15.             Robert
  16.  
  17. : =-=-=-=-=-=-=-=-=-=-= Cut Here =-=-=-=-=-=-=-=-=-=-=
  18. PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH
  19. export PATH
  20. echo Extracting get_grammar.c
  21. if [ -w get_grammar.c ]; then
  22.     echo File already exists - saving as get_grammar.c.old
  23.     mv get_grammar.c get_grammar.c.old
  24.     chmod 444 get_grammar.c.old
  25. fi
  26. sed 's/^X//' <<'//go.sysin dd *' >get_grammar.c
  27. X/*
  28.  * Extract the grammar from a set of yacc rules
  29.  * Syntax: get_grammar [-t] [infile] [outfile]
  30.  *
  31.  * Options:
  32.  *    t    write a file suitable for TeX
  33.  *
  34.  * If files are omitted, use standard in/output
  35.  *
  36.  * You are welcome to make any use you like of this code, providing that
  37.  * my name remains on it, and that you don't make any money out of it.
  38.  *
  39.  *    Robert Lupton (lupton@uhifa.ifa.hawaii.edu)
  40.  */
  41. #include <stdio.h>
  42. #include <ctype.h>
  43. #define ISSPECIAL(C) ((C) == '{' || (C) == '}' || (C) == '_' ||              \
  44.                               (C) == '&' || (C) == '%')
  45. #define SIZE 82
  46.  
  47. static int TeX = 0;            /* produce a TeX file? */
  48.  
  49. main(ac,av)
  50. int ac;
  51. char **av;
  52. {
  53.    char line[SIZE],
  54.        *lptr;                /* pointer to line */
  55.    FILE *infil = stdin,
  56.        *outfil = stdout;
  57.    int ctr,                /* counter for {} */
  58.        print_on = 1,            /* Should I print line? */
  59.        rule;                /* is this line a rule? */
  60.  
  61.    if(ac >= 2 && av[1][0] == '-') {
  62.       if(av[1][1] == 't') {
  63.      TeX = 1;
  64.       } else {
  65.      fprintf(stderr,"Unknown flag %s\n",av[1]);
  66.       }
  67.       ac--;
  68.       av++;
  69.    }
  70.    
  71.    if(ac >= 2) {
  72.       if((infil = fopen(av[1],"r")) == NULL) {
  73.      fprintf(stderr,"Can't open %s\n",av[1]);
  74.      exit();
  75.       }
  76.    }
  77.    if(ac >= 3) {
  78.       if((outfil = fopen(av[2],"w")) == NULL) {
  79.      fprintf(stderr,"Can't open %s\n",av[2]);
  80.      fclose(infil);
  81.      exit();
  82.       }
  83.    }
  84.  
  85.    if(TeX) {
  86.       fprintf(outfil,"%\n% YACC grammar from %s\n%\n",(ac > 1)?av[1]:"?");
  87.       fprintf(outfil,
  88.           "{\\tt\\obeylines\\obeyspaces\\parskip=0pt\\parindent=0pt\n");
  89.       fprintf(outfil,"\\settabs\\+\\ \\ \\ \\ \\ \\ &\\cr\n");
  90.    }
  91.  
  92.    while(fgets(line,SIZE,infil) != NULL) {
  93.       rule = 0;
  94.       if(line[0] == '%') {
  95.      if(line[1] == '{' || line[1] == '%') {
  96.         print_on = 0;
  97.      } else if(line[1] == '}') {
  98.         print_on = 1;
  99.      }
  100.      line_out(line,outfil);
  101.      continue;
  102.       }
  103.       if(print_on) {
  104.      line_out(line,outfil);
  105.      continue;
  106.       }
  107.  
  108.       lptr = line;
  109.       if(!isspace(line[0])) {        /* probably start of new rule */
  110.      while(*lptr != '\0' && !isspace(*lptr)) {    /* skip word */
  111.         lptr++;
  112.      }
  113.      while(isspace(*lptr)) lptr++;    /* skip white space */
  114.      if(*lptr == ':') {
  115.         rule = 1;
  116.      }
  117.      lptr = line;
  118.       }
  119.  
  120.       while(isspace(*lptr)) lptr++;    /* skip white space */
  121.       if(rule || *lptr == '|') {    /* a rule */
  122.      if(TeX) {
  123.         fprintf(outfil,"\\+");
  124.         if(isspace(line[0])) {
  125.            fprintf(outfil,"&");
  126.         }
  127.      }
  128.      if(!TeX) {            /* we don't want it for TeX */
  129.         lptr = line;
  130.      }
  131.      while(*lptr != '\0') {
  132.         while(*lptr != '\0') {
  133.            if(TeX) {
  134.           if(ISSPECIAL(*lptr)) {
  135.              putc('\\',outfil);
  136.           } else if(*lptr == '/' && *(lptr + 1) == '*') {
  137.              while(!(*++lptr == '*' && *(lptr + 1) == '/')) ;
  138.              if(*lptr == '*' && *(lptr + 1) == '/') lptr += 2;
  139.           }
  140.           if(*lptr == '\n') {
  141.              fprintf(outfil,"\\cr");
  142.           }
  143.            }
  144.            putc(*lptr,outfil);
  145.            if(*lptr == '{' && *(lptr - 1) != '\'') {
  146.              ctr = 0;        /* we'll see that { again */
  147.           break;
  148.            } else {
  149.           lptr++;
  150.            }
  151.         }
  152.         while(*lptr != '\0') {
  153.            if(*lptr == '}') {
  154.           if(--ctr == 0) {
  155.              break;
  156.           }
  157.            } else if(*lptr == '{') {
  158.           ctr++;
  159.            }
  160.            lptr++;
  161.         }
  162.      }
  163.       } else if(*lptr == ';') {
  164.      line_out(line,outfil);
  165.      if(TeX) {
  166.         fprintf(outfil,"\\+\\cr");
  167.      }
  168.      putc('\n',outfil);
  169.       }
  170.    }
  171.  
  172.    if(TeX) {
  173.       fprintf(outfil,"}\n");
  174.    }
  175.  
  176.    fclose(infil); fclose(outfil);
  177. }
  178.         
  179.      
  180. line_out(line,fil)
  181. char *line;
  182. FILE *fil;
  183. {
  184.    if(line[0] == '\0' || !TeX) {
  185.       fputs(line,fil);
  186.       return;
  187.    }
  188.  
  189.    fprintf(fil,"\\+");
  190.    if(isspace(*line)) {
  191.       fprintf(fil,"&");
  192.       while(isspace(*++line)) ;
  193.    }
  194.  
  195.    for(;*line != '\0';line++) {
  196.       if(ISSPECIAL(*line)) {
  197.      putc('\\',fil);
  198.       } else if(*line == '/' && *(line + 1) == '*') {
  199.      while(!(*++line == '*' && *(line + 1) == '/')) ;
  200.      if(*line == '*' && *(line + 1) == '/') line += 2;
  201.       }
  202.       if(*line == '\n') {
  203.      break;
  204.       }
  205.       putc(*line,fil);
  206.    }
  207.    fprintf(fil,"\\cr\n");
  208. }
  209. //go.sysin dd *
  210. if [ `wc -c < get_grammar.c` != 3985 ]; then
  211. made=FALSE
  212. echo error transmitting get_grammar.c --
  213. echo length should be 3985, not `wc -c < get_grammar.c`
  214. else
  215.     made=TRUE
  216. fi
  217. if [ $made = TRUE ]; then
  218.     chmod 755 get_grammar.c
  219.     echo -n  ; ls -ld get_grammar.c
  220. fi
  221.  
  222.  
  223.  
  224.