📄 config.y
字号:
%token DEFBRK COLON OCTAL INTEGER IDENT CSR IVEC OVEC IRQ IINT OINT
INIT OPEN CLOSE READ WRITE SEEK CNTL IS ON GETC PUTC
%{
#include <stdio.h>
#define NIL (dvptr)0
#define CONFIGC "conf.c" /* name of .c output */
#define CONFIGH "../h/conf.h" /* name of .h output */
#define CONFHREF "<conf.h>" /* how conf.h referenced*/
#define CONFIGIN "Configuration" /* name of input file */
#define IRQBASE 32
FILE *confc;
FILE *confh;
char *dbstr;
int ndevs = 0;
int currname = -1;
int currtname = -1;
int currdname = -1;
int brkcount = 0;
struct syment { /* symbol table */
char *symname;
int symoccurs;
int symtype;
} symtab[250];
int nsym = 0;
int lookup();
int linectr = 1;
char *doing = "device type declaration";
char *s;
struct dvtype {
char *dvname; /* device name (not used in types)*/
char *dvtname; /* type name */
int dvtnum; /* symbol table index of type */
char *dvdevice; /* device name */
void *dvcsr; /* Control Status Register addr */
int dvivec; /* input interrupt vector */
int dvovec; /* Output interrupt vector */
char dviint[20]; /* input interrupt routine */
char dvoint[20]; /* output interrupt routine */
char dvinit[20]; /* init routine name */
char dvopen[20]; /* open routine name */
char dvclose[20]; /* close routine name */
char dvread[20]; /* read routine name */
char dvwrite[20]; /* write routine name */
char dvcntl[20]; /* control routine name */
char dvseek[20]; /* seek routine name */
char dvgetc[20]; /* getc routine name */
char dvputc[20]; /* putc routine name */
int dvminor; /* device number 0,1,... */
struct dvtype *dvnext; /* next node on the list */
};
typedef struct dvtype *dvptr;
dvptr ftypes = NIL; /* linked list of device types */
dvptr devs = NIL; /* linked list of device decls. */
dvptr lastdv = NIL;
dvptr currtype = NIL;
char *ftout[] =
{"struct\tdevsw\t{\t\t\t/* device table entry */\n",
"\tint\tdvnum;\n",
"\tchar\t*dvname;\n",
"\tint\t(*dvinit)(struct devsw *);\n",
"\tint\t(*dvopen)(struct devsw *, void *, void *);\n",
"\tint\t(*dvclose)(struct devsw *);\n",
"\tint\t(*dvread)(struct devsw *, char *, unsigned);\n",
"\tint\t(*dvwrite)(struct devsw *, unsigned char *, unsigned);\n",
"\tint\t(*dvseek)(struct devsw *, long);\n",
"\tint\t(*dvgetc)(struct devsw *);\n",
"\tint\t(*dvputc)(struct devsw *, unsigned char);\n",
"\tint\t(*dvcntl)(struct devsw *, int, void *, void *);\n",
"\tvoid\t*dvcsr;\n",
"\tint\tdvivec;\n",
"\tint\tdvovec;\n",
"\tvoid\t(*dviint)(struct devsw *, unsigned char);\n",
"\tvoid\t(*dvoint)(struct devsw *);\n",
"\tvoid\t*dvioblk;\n",
"\tint\tdvminor;\n",
"\t};\n\n",
"extern\tstruct\tdevsw devtab[];",
"\t\t/* one entry per device */\n\n",
NULL};
int l_atoi(char *, int);
%}
%%
config.input : devicetypes devicedescriptors
;
devicetypes : ftypes DEFBRK
{doing = "device definitions";}
;
ftypes : /**/
| ftypes ftype
;
ftype : tname device.list
;
device.list : devheader attribute.list
| device.list devheader attribute.list
;
devheader : ON id
{mktype($2);}
;
tname : id COLON
{$$ = currtname = cktname($1);}
;
id : IDENT
{$$ = currname =
lookup(yytext,yyleng);
}
;
attribute.list : /**/
| attribute.list attribute
;
attribute : CSR number
{newattr(CSR,$2);}
| IVEC number
{newattr(IVEC,$2);}
| OVEC number
{newattr(OVEC,$2);}
| IRQ number
{newattr(IRQ,$2 +IRQBASE);}
| IINT id
{newattr(IINT,$2);}
| OINT id
{newattr(OINT,$2);}
| OPEN id
{newattr(OPEN,$2);}
| CLOSE id
{newattr(CLOSE,$2);}
| INIT id
{newattr(INIT,$2);}
| GETC id
{newattr(GETC,$2);}
| PUTC id
{newattr(PUTC,$2);}
| READ id
{newattr(READ,$2);}
| WRITE id
{newattr(WRITE,$2);}
| SEEK id
{newattr(SEEK,$2);}
| CNTL id
{newattr(CNTL,$2);}
;
number : INTEGER
{$$ = l_atoi(yytext,yyleng);}
;
devicedescriptors : /**/
| devicedescriptors descriptor
;
descriptor : fspec attribute.list
;
fspec : dname IS id optional.on
{mkdev($1,$3,$4);}
;
dname : id
{$$ = currdname = ckdname($1);}
;
optional.on : /**/
{$$ = 0;}
| ON id
{$$ = $2;}
;
%%
#include "lex.yy.c"
main(argc, argv)
int argc;
char *argv[];
{
int n, i, j, l, fcount;
dvptr s;
int verbose = 0;
char *p;
char c;
if (argc>1 && (strcmp("-v",argv[1])==0)) {
argc--;
argv++;
verbose++;
}
if (argc>2) {
fprintf(stderr,"use: config [-v] [file]\n");
exit(1);
}
if (verbose)
printf("Opening input file...\n");
if (argc == 2) {
if (freopen(argv[1], "r", stdin) == NULL) {
fprintf(stderr,"Can't open %s\n",argv[1]);
exit(1);
}
} else { /* try to open Configuration file */
if (freopen(CONFIGIN, "r", stdin) == NULL) {
fprintf(stderr,"Can't open %s\n", CONFIGIN);
exit(1);
}
}
/* Parse the Configuration file */
if (verbose)
printf("Parsing configuration specs...\n");
if ((n=yyparse()) != 0)
exit(n);
/* write config.h and config.c */
if (verbose)
printf("Opening output files...\n");
if ( (confc=fopen(CONFIGC,"w") ) == NULL) {
fprintf(stderr, "Can't write on %s\n", CONFIGC);
exit(1);
}
if ( (confh=fopen(CONFIGH,"w") ) == NULL) {
fprintf(stderr, "Can't write on %s\n", CONFIGH);
exit(1);
}
fprintf(confh,
"/* conf.h (GENERATED FILE; DO NOT EDIT) */\n");
fprintf(confc,
"/* conf.c (GENERATED FILE; DO NOT EDIT) */\n");
fprintf(confc, "\n#include %s\n", CONFHREF);
fprintf(confh, "\n#define\tNULLPTR\t(char *)0\n");
if (verbose)
printf("Writing output...\n");
fprintf(confh,"\n/* Device table declarations */\n");
for (i=0 ; (p=ftout[i])!=NULL ; i++)
fprintf(confh, "%s", p);
/* write device declarations and definitions; count type refs. */
fprintf(confh, "\n/* Device name definitions */\n\n");
for (i=0,s=devs; s!=NIL ; s=s->dvnext,i++) {
fprintf(confh, "#define\t%-12s%d\t\t\t/* type %-8s */\n",
s->dvname, i, s->dvtname);
s->dvminor = symtab[s->dvtnum].symoccurs++;
}
/* write count of device types */
fprintf(confh,"\n/* Control block sizes */\n\n");
for (i=0 ; i<nsym ; i++)
if (symtab[i].symoccurs > 0) {
fprintf(confh, "#define\tN%s\t%d\n",
symtab[i].symname, symtab[i].symoccurs);
}
if (ndevs > 0)
fprintf(confh, "\n#define\tNDEVS\t%d\n\n", ndevs);
/* empty symbol table, collect, and write names of all I/O routines */
nsym = 0;
for (s=devs; s!=NIL ; s=s->dvnext) {
i=lookup(s->dvinit,strlen(s->dvinit));
symtab[i].symtype = INIT;
i=lookup(s->dvopen,strlen(s->dvopen));
symtab[i].symtype = OPEN;
i=lookup(s->dvclose,strlen(s->dvclose));
symtab[i].symtype = CLOSE;
i=lookup(s->dvread,strlen(s->dvread));
symtab[i].symtype = READ;
i=lookup(s->dvwrite,strlen(s->dvwrite));
symtab[i].symtype = WRITE;
i=lookup(s->dvseek,strlen(s->dvseek));
symtab[i].symtype = SEEK;
i=lookup(s->dvcntl,strlen(s->dvcntl));
symtab[i].symtype = CNTL;
i=lookup(s->dvgetc,strlen(s->dvgetc));
symtab[i].symtype = GETC;
i=lookup(s->dvputc,strlen(s->dvputc));
symtab[i].symtype = PUTC;
i=lookup(s->dviint,strlen(s->dviint));
symtab[i].symtype = IINT;
i=lookup(s->dvoint,strlen(s->dvoint));
symtab[i].symtype = OINT;
}
fprintf(confh,
"/* Declarations of I/O routines referenced */\n\n");
for (i=0 ; i<nsym ; i++)
prdef(confh, symtab[i].symname, symtab[i].symtype);
/* produce devtab (giant I/O switch table) */
fprintf(confc, "\n/* device independent I/O switch */\n\n");
if (ndevs > 0) {
fprintf(confc, "struct\tdevsw\tdevtab[NDEVS] = {\n");
fprintf(confc, "\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
"/* Format of entries is:",
"device-number, device-name,",
"init, open, close,",
"read, write, seek,",
"getc, putc, cntl,",
"device-csr-address, input-vector, output-vector,",
"iint-handler, oint-handler, control-block, minor-device,",
"*/");
}
for (fcount=0,s=devs ; s!=NIL ; s=s->dvnext,fcount++) {
fprintf(confc, "\n/* %s is %s */\n\n",s->dvname,s->dvtname);
fprintf(confc, "%d, \"%s\",\n", fcount, s->dvname);
fprintf(confc, "%s, %s, %s,\n",
s->dvinit, s->dvopen, s->dvclose);
fprintf(confc, "%s, %s, %s,\n",
s->dvread, s->dvwrite, s->dvseek);
fprintf(confc, "%s, %s, %s,\n",
s->dvgetc, s->dvputc, s->dvcntl);
fprintf(confc, "(void *)0%06o, 0%03o, 0%03o,\n",
s->dvcsr, s->dvivec, s->dvovec);
fprintf(confc, "%s, %s, NULLPTR, %d",
s->dviint, s->dvoint, s->dvminor);
if ( s->dvnext != NIL )
fprintf(confc, ",\n");
else
fprintf(confc, "\n\t};");
}
/* Copy definitions to output */
if (brkcount == 2 && verbose)
printf("Copying definitions to %s...\n", CONFIGH);
if (brkcount == 2 )
while ( (c=input()) > 0) /* lex input routine */
putc(c, confh);
/* guarantee conf.c written later than conf.c for make */
fclose(confh);
fprintf(confc, "\n");
fclose(confc);
/* finish up and write report for user if requested */
if (verbose) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -