lupton@uhccux.uhcc.hawaii.edu (Robert Lupton) (01/09/90)
Posting-number: Volume 10, Issue 3 Submitted-by: lupton@uhccux.uhcc.hawaii.edu (Robert Lupton) Archive-name: get_grammar Here's a simple programme to take a yacc (or bison) file and convert it to a readable form by stripping out all of the C. If given the -t flag it'll produce TeX output (and strip comments; I couldn't be bothered to figure out how to make them look nice) Robert : =-=-=-=-=-=-=-=-=-=-= Cut Here =-=-=-=-=-=-=-=-=-=-= PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH export PATH echo Extracting get_grammar.c if [ -w get_grammar.c ]; then echo File already exists - saving as get_grammar.c.old mv get_grammar.c get_grammar.c.old chmod 444 get_grammar.c.old fi sed 's/^X//' <<'//go.sysin dd *' >get_grammar.c X/* * Extract the grammar from a set of yacc rules * Syntax: get_grammar [-t] [infile] [outfile] * * Options: * t write a file suitable for TeX * * If files are omitted, use standard in/output * * You are welcome to make any use you like of this code, providing that * my name remains on it, and that you don't make any money out of it. * * Robert Lupton (lupton@uhifa.ifa.hawaii.edu) */ #include <stdio.h> #include <ctype.h> #define ISSPECIAL(C) ((C) == '{' || (C) == '}' || (C) == '_' || \ (C) == '&' || (C) == '%') #define SIZE 82 static int TeX = 0; /* produce a TeX file? */ main(ac,av) int ac; char **av; { char line[SIZE], *lptr; /* pointer to line */ FILE *infil = stdin, *outfil = stdout; int ctr, /* counter for {} */ print_on = 1, /* Should I print line? */ rule; /* is this line a rule? */ if(ac >= 2 && av[1][0] == '-') { if(av[1][1] == 't') { TeX = 1; } else { fprintf(stderr,"Unknown flag %s\n",av[1]); } ac--; av++; } if(ac >= 2) { if((infil = fopen(av[1],"r")) == NULL) { fprintf(stderr,"Can't open %s\n",av[1]); exit(); } } if(ac >= 3) { if((outfil = fopen(av[2],"w")) == NULL) { fprintf(stderr,"Can't open %s\n",av[2]); fclose(infil); exit(); } } if(TeX) { fprintf(outfil,"%\n% YACC grammar from %s\n%\n",(ac > 1)?av[1]:"?"); fprintf(outfil, "{\\tt\\obeylines\\obeyspaces\\parskip=0pt\\parindent=0pt\n"); fprintf(outfil,"\\settabs\\+\\ \\ \\ \\ \\ \\ &\\cr\n"); } while(fgets(line,SIZE,infil) != NULL) { rule = 0; if(line[0] == '%') { if(line[1] == '{' || line[1] == '%') { print_on = 0; } else if(line[1] == '}') { print_on = 1; } line_out(line,outfil); continue; } if(print_on) { line_out(line,outfil); continue; } lptr = line; if(!isspace(line[0])) { /* probably start of new rule */ while(*lptr != '\0' && !isspace(*lptr)) { /* skip word */ lptr++; } while(isspace(*lptr)) lptr++; /* skip white space */ if(*lptr == ':') { rule = 1; } lptr = line; } while(isspace(*lptr)) lptr++; /* skip white space */ if(rule || *lptr == '|') { /* a rule */ if(TeX) { fprintf(outfil,"\\+"); if(isspace(line[0])) { fprintf(outfil,"&"); } } if(!TeX) { /* we don't want it for TeX */ lptr = line; } while(*lptr != '\0') { while(*lptr != '\0') { if(TeX) { if(ISSPECIAL(*lptr)) { putc('\\',outfil); } else if(*lptr == '/' && *(lptr + 1) == '*') { while(!(*++lptr == '*' && *(lptr + 1) == '/')) ; if(*lptr == '*' && *(lptr + 1) == '/') lptr += 2; } if(*lptr == '\n') { fprintf(outfil,"\\cr"); } } putc(*lptr,outfil); if(*lptr == '{' && *(lptr - 1) != '\'') { ctr = 0; /* we'll see that { again */ break; } else { lptr++; } } while(*lptr != '\0') { if(*lptr == '}') { if(--ctr == 0) { break; } } else if(*lptr == '{') { ctr++; } lptr++; } } } else if(*lptr == ';') { line_out(line,outfil); if(TeX) { fprintf(outfil,"\\+\\cr"); } putc('\n',outfil); } } if(TeX) { fprintf(outfil,"}\n"); } fclose(infil); fclose(outfil); } line_out(line,fil) char *line; FILE *fil; { if(line[0] == '\0' || !TeX) { fputs(line,fil); return; } fprintf(fil,"\\+"); if(isspace(*line)) { fprintf(fil,"&"); while(isspace(*++line)) ; } for(;*line != '\0';line++) { if(ISSPECIAL(*line)) { putc('\\',fil); } else if(*line == '/' && *(line + 1) == '*') { while(!(*++line == '*' && *(line + 1) == '/')) ; if(*line == '*' && *(line + 1) == '/') line += 2; } if(*line == '\n') { break; } putc(*line,fil); } fprintf(fil,"\\cr\n"); } //go.sysin dd * if [ `wc -c < get_grammar.c` != 3985 ]; then made=FALSE echo error transmitting get_grammar.c -- echo length should be 3985, not `wc -c < get_grammar.c` else made=TRUE fi if [ $made = TRUE ]; then chmod 755 get_grammar.c echo -n ; ls -ld get_grammar.c fi