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

📄 cc2.c

📁 A simple C compiler source code.
💻 C
字号:
/*** Small-C Compiler -- Part 2 -- Front End and Miscellaneous.** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix** Copyright 1998 H T Walheim** All rights reserved.*/#include <stdio.h>#include "cc.h"extern char*symtab, *macn, *macq, *pline, *mline, optimize,    alarm, *glbptr, *line, *lptr, *cptr, *cptr2, *cptr3,    *locptr, msname[NAMESIZE], pause, quote[2];extern int*wq, ccode, ch, csp, eof, errflag, iflevel,    input, input2, listfp, macptr, nch,    nxtlab, op[16], opindex, opsize, output, pptr, skiplevel, *wqptr;/********************** input functions **********************/preprocess(){    int k;    char c;    if (ccode) {	line = mline;	ifline();	if (eof)	    return;    } else {	zinline();	return;    }    pptr = -1;    while (ch != NEWLINE && ch) {	if (white()) {	    keepch(' ');	    while (white())		gch();	} else if (ch == '"') {	    keepch(ch);	    gch();	    while (ch != '"' || (*(lptr - 1) == 92 && *(lptr - 2) != 92)) {		if (ch == NULL) {		    error("no quote");		    break;		}		keepch(gch());	    }	    gch();	    keepch('"');	} else if (ch == 39) {	    keepch(39);	    gch();	    while (ch != 39 || (*(lptr - 1) == 92 && *(lptr - 2) != 92)) {		if (ch == NULL) {		    error("no apostrophe");		    break;		}		keepch(gch());	    }	    gch();	    keepch(39);	} else if (ch == '/' && nch == '*') {	    bump(2);	    while ((ch == '*' && nch == '/') == 0) {		if (ch)		    bump(1);		else {		    ifline();		    if (eof)			break;		}	    }	    bump(2);	} else if (ch == '/' && nch == '/') {	    bump(2);	    while (ch != NEWLINE) {		if (ch)		    bump(1);		else {		    if (eof)			break;		}	    }	    bump(1);	} else if (an(ch)) {	    k = 0;	    while (an(ch) && k < NAMEMAX) {		msname[k++] = ch;		gch();	    }	    msname[k] = NULL;	    if (search(msname, macn, NAMESIZE + 2, MACNEND, MACNBR, 0)) {		k = getint(cptr + NAMESIZE, 2 /*INTSIZE*/);		while (c = macq[k++])		    keepch(c);		while (an(ch))		    gch();	    } else {		k = 0;		while (c = msname[k++])		    keepch(c);	    }	} else	    keepch(gch());    }    if (pptr >= LINEMAX)	error("line too long");    keepch(NULL);    line = pline;    bump(0);}keepch(c)char c;{    if (pptr < LINEMAX)	pline[++pptr] = c;}ifline(){    while (1) {	zinline();	if (eof)	    return;	if (match("#ifdef")) {	    ++iflevel;	    if (skiplevel)		continue;	    symname(msname);	    if (search(msname, macn, NAMESIZE + 2, MACNEND, MACNBR, 0) ==		0)		skiplevel = iflevel;	    continue;	}	if (match("#ifndef")) {	    ++iflevel;	    if (skiplevel)		continue;	    symname(msname);	    if (search(msname, macn, NAMESIZE + 2, MACNEND, MACNBR, 0))		skiplevel = iflevel;	    continue;	}	if (match("#else")) {	    if (iflevel) {		if (skiplevel == iflevel)		    skiplevel = 0;		else if (skiplevel == 0)		    skiplevel = iflevel;	    } else		noiferr();	    continue;	}	if (match("#endif")) {	    if (iflevel) {		if (skiplevel == iflevel)		    skiplevel = 0;		--iflevel;	    } else		noiferr();	    continue;	}	if (skiplevel)	    continue;	if (ch == 0)	    continue;	break;    }}zinline(){				/* numerous revisions */    int k, unit;    if (input == EOF)	openfile();    if (eof)	return;    if ((unit = input2) == EOF)	unit = input;    if (fgets(line, LINEMAX, unit) == NULL) {	fclose(unit);	if (input2 != EOF)	    input2 = EOF;	else	    input = EOF;	*line = NULL;    } else if (listfp) {	if (listfp == output)	    fputc(';', output);	fputs(line, listfp);    }#ifdef __GNUC__    else {	fputc(';', output);	fputs(line, output);    }#endif    bump(0);}inbyte(){    while (ch == 0) {	if (eof)	    return 0;	preprocess();    }    return gch();}/********************* scanning functions ********************//*** test if next input string is legal symbol name*/symname(sname)char *sname;{    int k;    char c;    blanks();    if (alpha(ch) == 0)	return (*sname = 0);    k = 0;    while (an(ch)) {	sname[k] = gch();	if (k < NAMEMAX)	    ++k;    }    sname[k] = 0;    return 1;}need(str)char *str;{    if (match(str) == 0)	error("missing token");}ns(){    if (match(";") == 0)	error("no semicolon");    else	errflag = 0;}match(lit)char *lit;{    int k;    blanks();    if (k = streq(lptr, lit)) {	bump(k);	return 1;    }    return 0;}streq(str1, str2)char str1[], str2[];{    int k;    k = 0;    while (str2[k]) {	if (str1[k] != str2[k])	    return 0;	++k;    }    return k;}amatch(lit, len)char *lit;int len;{    int k;    blanks();    if (k = astreq(lptr, lit, len)) {	bump(k);	return 1;    }    return 0;}astreq(str1, str2, len)char str1[], str2[];int len;{    int k;    k = 0;    while (k < len) {	if (str1[k] != str2[k])	    break;	/*	   ** must detect end of symbol table names terminated by	   ** symbol length in binary	 */	if (str2[k] < ' ')	    break;	if (str1[k] < ' ')	    break;	++k;    }    if (an(str1[k]) || an(str2[k]))	return 0;    return k;}nextop(list)char *list;{    char op[4];    opindex = 0;    blanks();    while (1) {	opsize = 0;	while (*list > ' ')	    op[opsize++] = *list++;	op[opsize] = 0;	if (opsize = streq(lptr, op))	    if (*(lptr + opsize) != '=' &&		*(lptr + opsize) != *(lptr + opsize - 1))		return 1;	if (*list) {	    ++list;	    ++opindex;	} else	    return 0;    }}blanks(){    while (1) {	while (ch) {	    if (white())		gch();	    else		return;	}	if (line == mline)	    return;	preprocess();	if (eof)	    break;    }}white(){    return (*lptr <= ' ' && *lptr);}gch(){    int c;    if (c = ch)	bump(1);    return c;}bump(n)int n;{    if (n)	lptr += n;    else	lptr = line;    if (ch = nch = *lptr)	nch = *(lptr + 1);}kill(){    *line = 0;    bump(0);}skip(){    if (an(inbyte()))	while (an(ch))	    gch();    else	while (an(ch) == 0) {	    if (ch == 0)		break;	    gch();	}    blanks();}endst(){    blanks();    return (streq(lptr, ";") || ch == 0);}/*********** symbol table management functions ***********/addsym(sname, id, type, size, value, lgpp, class)char *sname, id, type;int size, value, *lgpp, class;{    if (lgpp == &glbptr) {	if (cptr2 = findglb(sname))	    return cptr2;	if (cptr == 0) {	    error("global symbol table overflow");	    return 0;	}    } else {	if (locptr > (ENDLOC - SYMMAX)) {	    error("local symbol table overflow");	    exit(ERRCODE);	}	cptr = *lgpp;    }    cptr[IDENT] = id;    cptr[TYPE] = type;    cptr[CLASS] = class;    putint(size, cptr + SIZE, INTSIZE);    putint(value, cptr + OFFSET, INTSIZE);    cptr3 = cptr2 = cptr + NAME;    while (an(*sname))	*cptr2++ = *sname++;    if (lgpp == &locptr) {	*cptr2 = cptr2 - cptr3;	/* set length */	*lgpp = ++cptr2;    }    return cptr;}/*** search for symbol match** on return cptr points to slot found or empty slot*/search(sname, buf, len, end, max, off)char *sname, *buf, *end;int len, max, off;{    cptr = cptr2 = buf + ((hash(sname) % (max - 1)) * len);    while (*cptr != NULL) {	if (astreq(sname, cptr + off, NAMEMAX))	    return 1;	if ((cptr = cptr + len) >= end)	    cptr = buf;	if (cptr == cptr2)	    return (cptr = 0);    }    return 0;}hash(sname)char *sname;{    int i, c;    i = 0;    while (c = *sname++)	i = (i << 1) + c;    return i;}findglb(sname)char *sname;{    if (search(sname, STARTGLB, SYMMAX, ENDGLB, NUMGLBS, NAME))	return cptr;    return 0;}findloc(sname)char *sname;{    cptr = locptr - 1;		/* search backward for block locals */    while (cptr > STARTLOC) {	cptr = cptr - *cptr;	if (astreq(sname, cptr, NAMEMAX))	    return (cptr - NAME);	cptr = cptr - NAME - 1;    }    return 0;}nextsym(entry)char *entry;{    entry = entry + NAME;    while (*entry++ >= ' ');	/* find length byte */    return entry;}/******** while queue management functions *********/addwhile(ptr)int ptr[];{    int k;    ptr[WQSP] = csp;		/* and stk ptr */    ptr[WQLOOP] = getlabel();	/* and looping label */    ptr[WQEXIT] = getlabel();	/* and exit label */    if (wqptr == WQMAX) {	error("control statement nesting limit");	exit(ERRCODE);    }    k = 0;    while (k < WQSIZ)	*wqptr++ = ptr[k++];}readwhile(ptr)int *ptr;{    if (ptr <= wq) {	error("out of context");	return 0;    } else	return (ptr - WQSIZ);}delwhile(){    if (wqptr > wq)	wqptr -= WQSIZ;}/****************** utility functions ********************//*** test if c is alphabetic*/alpha(c)char c;{    return (isalpha(c) || c == '_');}/*** test if given character is alphanumeric*/an(c)char c;{    return (alpha(c) || isdigit(c));}/*** return next avail internal label number*/getlabel(){    return (nxtlab++);}/*** get integer of length len from address addr** (byte sequence set by "putint")*/getint(addr, len)char *addr;int len;{    int i;    i = *(addr + --len);	/* high order byte sign extended */    while (len--)	i = (i << 8) | *(addr + len) & 255;    return i;}/*** put integer i of length len into address addr** (low byte first)*/putint(i, addr, len)char *addr;int i, len;{    while (len--) {	*addr++ = i;	i = i >> 8;    }}lout(line, fd)char *line;int fd;{    fputs(line, fd);    fputc(NEWLINE, fd);}/******************* error functions *********************/illname(){    error("illegal symbol");    skip();}multidef(sname)char *sname;{    error("already defined");}needlval(){    error("must be lvalue");}noiferr(){    error("no matching #if...");    errflag = 0;}error(msg)char msg[];{    if (errflag)	return;    else	errflag = 1;    lout(line, stderr);    errout(msg, stderr);    if (alarm)	fputc(7, stderr);    if (pause)	while (fgetc(stderr) != NEWLINE);    if (listfp > 0)	errout(msg, listfp);}errout(msg, fp)char msg[];int fp;{    int k;    k = line + 2;    while (k++ <= lptr)	fputc(' ', fp);    lout("/\\", fp);    fputs("**** ", fp);    lout(msg, fp);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -