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