⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 config.y

📁 TCP-IP红宝书源代码
💻 Y
📖 第 1 页 / 共 2 页
字号:
%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 + -