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

📄 ccpp.c

📁 KCC , a good c compiler, write by Ken Harrenstien
💻 C
📖 第 1 页 / 共 5 页
字号:
int c;
{
    if (backstr)
	{
	backstr--;		/* pushed string input, back up over it */
	if(c != *backstr)
	    int_error("pushch: bad backup char");
	return;
	}

    /* File input, back up over that.
    ** Note that errlin and t/f/line only need to be fixed up for file input.
    */
    if (c != ungetc(c, in))
	int_error("pushch: ungetc failed: %o", c);
    if (isceol(c))
	{
	line--;				/* dont lose track of line count */
	fline--;
	tline--;
	}
    /* Back up over char of saved context */
    if (erptr == errlin)		/* If at start of buffer */
	{
	erptr = errlin + ERRLSIZE;	/* Wrap back to end */
	erpleft = 0;
	}
    *--erptr = '\0';		/* Back up and zap what we previously stored */
    ++erpleft;
}

static
int
pushstr(cp)
char *cp;
{
    bstrpush(cp);
    return nextch();
}

static
void
bstrpush(cp)
char *cp;
{
    if (bkstrlev >= MAXBKSTRS-1)
	{
	int_error("bstrpush: bkstrs overflow");
	bkstrlev = MAXBKSTRS-1;
	}
else
    {
    bkstrs[bkstrlev++] = backstr;
    backstr = cp;
    }
}

static
void
bstrpop (void)
{
    if (--bkstrlev < 0)
	{
	int_error("bstrpop: bkstrs underflow");
	backstr = NULL, bkstrlev = 0;
	}
else
    backstr = bkstrs[bkstrlev];
}

/* NEXTRAWPP()	Phase 3 - produce raw PP tokens
**			(handles comments, flushes WSP)
**
*/

#define retchk(chr,no,yes)	if (nextch () != chr)	\
				    rawpp = no;		\
				else			\
				    {			\
				    nextch ();		\
				    rawpp = yes;	\
				    }			 

#define retchk2(ch1,ch2,no,yes1,yes2)	switch (nextch ())		\
					    {				\
					    case ch1:			\
						nextch ();		\
						rawpp = yes1;		\
						break;			\
					    case ch2:			\
						nextch ();		\
						rawpp = yes2;		\
						break;			\
					    default:			\
						rawpp = no;		\
						break;			\
					    }

static
int
nextrawpp (void)
{
    int	    retflag = 0;


    rawval.i = 0;
    
    switch (ch)
	{
	case EOF:
	    rawpp = T_EOF;
	    retflag = 1;
	    break;


	/* Check for "bad" horiz whitespace (may give error msg) */

	case '\r':			/* Include CR here for now */
	case '\v':			/* Vert tab */
	case '\f':			/* Ditto FF */
	    pushch (ch);	/* Ensure scanhwsp () will see this char */

	/* Drop thru to call scanner */

	/* Check for "good" horiz whitespace */

	case '\t':			/* Horiz tab */
	case ' ':			/* Space */
	    scanhwsp ();
	    retflag = 1;
	    break;


	case '\n':
	    rawpp = T_EOL;
	    break;


	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	    ppnconst (0);
	    retflag = 1;
	    break;


	case '\'':
	    ppsconst (0);		/* Char constant */
	    rawpp = T_CCONST;
	    retflag = 1;
	    break;


	case '"':
	    ppsconst (0);		/* String constant */
	    rawpp = T_SCONST;
	    retflag = 1;
	    break;


	case '.':

	    if (isdigit (nextch ()))	/* If followed by digit, */
		{
		ppnconst ('.');
		retflag = 1;
		break;
		}

	    if (ch != '.')
		{
		rawpp = Q_DOT;
		retflag = 1;
		break;
		}

	    if (nextch() != '.')	/* Ellipsis "..."? */
		{
		pushch(ch);		/* Nope, push it back */
		ch = '.';		/* And restore prev char */
		rawpp = Q_DOT;
		retflag = 1;
		break;
		}

	    rawpp = T_ELPSIS;		/* ... */
	    break;


	case '#':
	    retchk('#', T_SHARP, T_SHARP2) /* # and ## */
	    retflag = 1;
	    break;


	case '=':	/* KAR-11/91, usage before initialization code */

	    if (nextch() != '=')
		{
		ra_expr = 1;
		rawpp = Q_ASGN;
		retflag = 1;
		break;
		}

	    nextch();
	    rawpp = Q_EQUAL;
	    retflag = 1;
	    break;


	case '!':
	    retchk('=', Q_NOT, Q_NEQ)	/* ! and != */
	    retflag = 1;
	    break;


	case '*':
	    retchk('=', Q_MPLY, Q_ASMPLY) /* * and *= */
	    retflag = 1;
	    break;


	case '%':
	    retchk('=', Q_MOD, Q_ASMOD)	/* % and %= */
	    retflag = 1;
	    break;


	case '^':
	    retchk('=', Q_XORT, Q_ASXOR) /* ^ and ^= */
	    retflag = 1;
	    break;


	case '/':	/* Special, to check for comments! */

	    switch (nextch ())
		{
		default:
		    rawpp = Q_DIV;
		    break;


		case '=':
		    nextch();
		    rawpp = Q_ASDIV;
		    break;


		case '*':
		    scancomm ();
		    scanhwsp ();
		    break;

		case '/':		/* KAR-2/93, PPS 4574; C++ comments */

		    if (!clevnocpp)	/* FW 2A(46) August 1993 */
			{
			comment_type = CPP;
			scancomm ();
			pushch (ch);	/* FW 2A(50) September 1993 */
			comment_type = C;
			}

		    scanhwsp ();
		    break;
		    
		}

	    retflag = 1;
	    break;


	case '|':
	    retchk2('=','|', Q_OR, Q_ASOR, Q_LOR) /* |  and |= and || */
	    retflag = 1;
	    break;


	case '&':
	    retchk2('=','&', Q_ANDT, Q_ASAND, Q_LAND) /* &  and &= and && */
	    retflag = 1;
	    break;


	case '+':
	    retchk2('=','+', Q_PLUS, Q_ASPLUS, T_INC)	/* +  and += and ++ */
	    retflag = 1;
	    break;


	case '-':

	    switch (nextch())
		{
		case '-':
		    rawpp = T_DEC;
		    break;	/* -- */


		case '=':
		    rawpp = Q_ASMINUS;
		    break;/* -= */


		case '>':
		    rawpp = Q_MEMBER;
		    break;/* -> */


		default:
		    rawpp = Q_MINUS;
		    retflag = 1;
		    break;
		}

	    break;


	case '>':

	    switch (nextch())
		{
		default:
		    rawpp = Q_GREAT;
		    retflag = 1;
		    break;


		case '=':
		    rawpp = Q_GEQ;
		    break;		/* >= */


		case '>':
		    retchk ('=', Q_RSHFT, Q_ASRSH)	/* >> and >>= */
		    retflag = 1;
		    break;
		}

	    break;


	case '<':

	    switch (nextch())
		{
		default:
		    rawpp = Q_LESS;
		    retflag = 1;
		    break;


		case '=':
		    rawpp = Q_LEQ;		/* <= */
		    break;


		case '<':
		    retchk('=', Q_LSHFT, Q_ASLSH)	/* << and <<= */
		    retflag = 1;
		    break;
		}
	    
	    break;


	case '(':
	    rawpp = T_LPAREN;
	    break;


	case ')':
	    rawpp = T_RPAREN;
	    break;


	case ',':
	    rawpp = T_COMMA;
	    ra_expr = 0;
	    break;


	case ':':
	    rawpp = T_COLON;
	    break;


	case ';':
	    rawpp = T_SCOLON;
	    ra_expr = 0;
	    break;


	case '?':
	    rawpp = Q_QUERY;
	    break;


	case '[':
	    rawpp = T_LBRACK;
	    break;


	case ']':
	    rawpp = T_RBRACK;
	    break;


	case '{':
	    rawpp = T_LBRACE;
	    ra_expr = 0;
	    break;


	case '}':
	    rawpp = T_RBRACE;
	    break;


	case '~':
	    rawpp = Q_COMPL;
	    break;


	case '`':			/* KCC extension: identifier quoter */

	    if (clevkcc)		/* If extensions in effect, */
		{
		ppsconst(0);		/* parse like string literal! */
		rawpp = T_IDENT;
		}
	    else
		ppunknwn();

	    retflag = 1;
	    break;


	default:

	    if (!iscsymf(ch))	/* Can char be start of identifier? */
		{
		ppunknwn();
		retflag = 1;
		break;
		}

	    /* Handle identifier! */

	    rawval.cp = ppcbeg();	/* Assume ident, harmless if not */

	    if (ch == 'L')	/* Possible "wide char" indicator? (BARF!!) */
		{
		int ch2 = nextch();


		if (ch2 =='\'')
		    {
		    ppsconst('L');
		    rawpp = T_CCONST;
		    retflag = 1;
		    break;
		    }
		else if (ch2 =='\"')
		    {
		    ppsconst('L');
		    rawpp = T_SCONST;
		    retflag = 1;
		    break;
		    }

		ppcput('L');	/* Not a wide char, recover from peekahead */

		if (!iscsym(ch))	/* Was it just "L"?  Barf, barf */
		    {
		    rawpplen = ppcend();
		    rawpp = T_IDENT;
		    retflag = 1;
		    break;
		    }
		}

	    do
		{
		ppcput(ch);	/* Gobble up identifier */
		}
	    while (iscsym(nextch()));

	    rawpplen = ppcend();
	    rawpp = T_IDENT;
	    retflag = 1;
	    break;
	}				/* End of switch(ch) */

    if (!retflag)
	nextch();		/* Done, set up next char after this token */

    /*
     * A tokenizing pre-compilation scheme will break the input stream
     * at this point.  Tokens, and their associated string literals
     * if any, will be diverted to a file.
     */
    
    return rawpp;
}

/* SCANHWSP - gobbles all horiz whitespace starting with current char, and
**	returns a T_WSP token.
*/
static
int
scanhwsp (void)
{
    for (;;)
	{
	while (iscppwsp(nextch())) ;	/* Skip all valid PP whitespace */
	switch (ch)
	    {
	    case '\r':
		if (nextch() == '\n')	/* Peek ahead */
		    {
		    note("Stray '\\r' seen, ignoring");
		    break;
		    }
		else
		    {

⌨️ 快捷键说明

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