home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- subject: v10i003: Extract a grammar from a YACC file
- From: lupton@uhccux.uhcc.hawaii.edu (Robert Lupton)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- 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
-
-
-
-