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

📄 preexpr.c

📁 guide and some example with visualC++
💻 C
字号:
/* preexpr.c * *	(C) Copyright Feb  2 1996, Edmond J. Breen. *		   ALL RIGHTS RESERVED. * This code may be copied for personal, non-profit use only. * */#ifndef _STANDALONE#include <stdio.h>#include <ctype.h>#include <string.h>#include <limits.h>#include "xalloc.h"#include "preproc.h"#endif/*ppint expr(int k);*//* typedef unsigned long ppint;   the preprocessor integer */typedef struct {    union {	long s;           /* signed value */	unsigned long u;  /* unsigned value */    }v;    int type;}ppint;/* methods */#define sval(x)  ((x).v.s)#define uval(x)  ((x).v.u)#define tval(x)  ((x).type)#define USIGN  1#define SIGN   2static ppint do_binary(int tk, ppint left, ppint right);static int getTok(int k);static ppint EiC_expr_unary(void);static ppint get_number(void);static ppint EiC_ifexpr(int k);enum { LOR = 1, LAND, BOR,  XOR,   AND,    EQ,  NEQ,  LT, LEQ,        GT, GEQ, LSHFT, RSHFT,PLUS, MINUS, TIMES, DIV, MOD};static char *S;static int TK =0;#define _StrSz_ 100static void replaceDefines(char *S){    char str[50];    int cmode = 0;    char *p;    p = S;    while(*S != '\0') {        if(!cmode && (isalpha(*S) || *S == '_')) {            if(S[0] == 'd' && S[1] == 'e' &&               S[2] == 'f' && S[3] == 'i' &&               S[4] == 'n' && S[5] == 'e' &&               S[6] == 'd' && !isalpha(S[7]) &&               S[7] != '_') {                int br = 0;                int i;                S+=7;                skipfws(S);                if(*S=='(') {                    S++;                    br = 1;                    skipfws(S);                }                i = 0;                while(i < 50 && (isalpha(*S) || *S == '_' || isdigit(*S)))                    str[i++] = *S++;                str[i] = '\0';                if(br) {                    skipfws(S);                    if(*S != ')')                         EiC_pre_error("Missing ')'");                    else                        S++;                }                if(str[0] != '\0') {                    if(EiC_ismacroid(str) > -1)                        *p = '1';                    else                        *p = '0';                    ++p;                } else                    EiC_pre_error("Missing identifier");                continue;            }             do                 *p++ = *S++;            while(isalpha(*S) || *S == '_' );	    continue;        } if(*S == '\'')            cmode = !cmode;        *p++ = *S++;    }    *p = '\0';}static void replaceIdentifiers(char *S){    int i;    char str[50];    char *p;    int cmode = 0;    p = S;            while(1) {	while(isspace(*S))	    *p++ = *S++;	if(!*S)	    return;	if(!isalpha(*S) && *S != '_') {	    if(isdigit(*S) || *S == '\'') { /* skip throu numbers or literals*/		while(*S && !isspace(*S))		    *p++ = *S++;	    } else 		while(*S && !isspace(*S) && *S != '_' && ispunct(*S))		    *p++ =  *S++;	    continue;	}	if(!cmode) {	    i = 0;	    while(i < 50 && (isalpha(*S) || *S == '_' || isdigit(*S)) )		str[i++] = *S++;	    str[i] = '\0';	    if(strcmp(str,"sizeof") == 0)		EiC_pre_error("Illegal sizeof operator");	    else		*p++ = '0';	} else	    *p++ = *S++;    }}int EiC_cpp_parse(char *s){    ppint res;    S = s;    replaceDefines(S);#ifdef DEBUG    printf("return [%s]\n",S);#endif    S = s  = EiC_process2(S,0,0);    replaceIdentifiers(S);#ifdef DEBUG    printf("return [%s]\n",S);#endif    res = EiC_ifexpr(0);    if(s)        xfree(s);    if(tval(res) == SIGN)	return sval(res);    else	return uval(res);}static ppint EiC_ifexpr(int k){    ppint res;    int k1, tk;    res = EiC_expr_unary();    for(k1 = 10; k1 >= k; k1--)	while((tk = getTok(k1))) 	    res = do_binary(tk, res,EiC_ifexpr(k1>8?k1:k1+1));    return res;}#define eval(a,l,r,op)\{\     if(tval(l) == SIGN)\	 sval(a) = sval(l) op sval(r);\     else\	 uval(a) = uval(l) op uval(r);\}		 static ppint do_binary(int tk, ppint left, ppint right){    ppint r;    if(tval(left) == USIGN || tval(right) == USIGN)	tval(r) = tval(left) = tval(right) = USIGN;    else	tval(r) = tval(left) = tval(right) = SIGN;    	    switch(tk) {      case BOR: eval(r,left,right, | ); break;      case XOR: eval(r,left,right, ^ ); break;      case AND: eval(r,left,right, & ); break;      case LT:  eval(r,left,right, < ); break;      case LEQ: eval(r,left,right, <= ); break;      case EQ:  eval(r,left,right,  == ); break;      case NEQ: eval(r,left,right,  != ); break;      case GT:  eval(r,left,right, > ); break;      case GEQ: eval(r,left,right, >= ); break;      case LOR: eval(r,left,right, || ); break;      case LAND: eval(r,left,right, && ); break;      case LSHFT: eval(r,left,right, << ); break;      case RSHFT: eval(r,left,right, >> ); break; 	      case PLUS: eval(r,left,right, + ); break;      case MINUS: eval(r,left,right, - ); break;      case TIMES: eval(r,left,right, * ); break;      case DIV: eval(r,left,right, / ); break;      case MOD: eval(r,left,right, % ); break;    }    return r;}static int getTok(int k){    TK = 0;        while(isspace(*S))	S++;	    switch(k) {      case 1: /* LOR */	if(*S == '|' && *(S+1) == '|') {S+=2; TK = LOR;}	break;      case 2: /* LAND */	if(*S == '&' && *(S+1) == '&') {S+=2; TK = LAND;}      case 3: /* BOR */	if(*S == '|' && *(S+1) != '|') {S++; TK = BOR;}	break;      case 4: /* XOR */	if(*S == '^') {S++; TK = GEQ;}	break;      case 5: /* AND */	if(*S == '&' && *(S+1) != '&') {S++; TK = GEQ;}	break;      case 6: /* EQ, NEQ */	if(*S == '=' && *(S+1) == '=') {S+=2; TK = EQ;}	else if(*S == '!' && *(S+1) == '=') {S+=2; TK = NEQ;}	break;      case 7: /* LT, LEQ, GT, GEQ */	if(*S == '<') {	    S++;	    if(*S == '='){S++;TK = LEQ;}	    else TK = LT;	} else if(*S == '>') {	    S++;	    if(*S == '='){S++; TK = GEQ;}	    else TK = GT;	}	break;      case 8:  /* LSHFT, RSHFT */	if(*S == '<' && *(S+1) == '<') {S+=2; TK = LSHFT;}	else if(*S == '>' && *(S+1) == '>') {S+=2; TK = RSHFT;}	break;      case 9: /* PLUS, MINUS */	if(*S == '-') {S++;TK = MINUS;}	else if(*S == '+') {S++; TK = PLUS;}	break;      case 10: /* TIMES, DIV, MOD */	if(*S == '*') {S++;TK = TIMES;}	else if(*S == '/') {S++; TK = DIV;}	else if(*S == '%') {S++; TK = MOD;}	break;    }    return TK;}static int get_oct(int x){    return x>='0'&&x<='7'? x-'0':-1;}static int get_hex(int x){        if (x >= '0' && x <= '9')	x -= '0';    else if (x >= 'a' && x <= 'f')	 x = x - 'a' + 10;    else if (x >= 'A' && x <= 'F')	x = x - 'A' + 10;    else	x = -1;    return x;}static int get_dec(int x){    return x >= '0' && x <= '9' ? x-'0':-1;}static ppint get_number()   /* collect hex, octal and decimal integers */{    int (*f)(int x);    int radix,val;    ppint res = {{0},SIGN};    if(*S == '0') {	S++;	if(*S == 'x' || *S == 'X') { /* get hex number */	    S++;	    radix = 16;	    f = get_hex;	} else { /* get octal number */	    radix = 8;	    f = get_oct;	}    } else { /* get decimal number */	radix = 10;	f = get_dec;    }    while((val = (*f)(*S++)) >= 0)	uval(res) = uval(res) * radix + val;    S--;    if(uval(res) > LONG_MAX)	tval(res) = USIGN;        /* check for prefix */        if(*S=='u' || *S=='U') {	S++;	tval(res) = USIGN;    } if(*S=='l' || *S=='L')	S++;    return res;}	static int get_charConst(){        int c;    switch (*S) {      case 'n': c = '\n'; break; /* newline */      case 't': c = '\t'; break; /* tabspace */      case 'v': c = '\v'; break; /* vertical tab */      case 'b': c = '\b'; break; /* backspace */      case 'r': c = '\r'; break; /* carriage return */      case 'f': c = '\f'; break; /* formfeed */      case 'a': c = '\a'; break; /* bell */      case '\\': c = '\\'; break; /* backslash */      case '\'': c = '\''; break; /* single quote */      case '"': c = '\"'; break; /* double quote */      case 'x':			/* string of hex characters */      case 'X':{	  int i, val = 0;	  S++;	  while ((i = get_hex(*S)) > -1) {	      S++;	      val = val * 16 + i;	  }	  if (val > 255)	      EiC_pre_error("Illegal character hex value");	  c = val;      }	break;      default:	if (isdigit(*S)) {	/* treat as octal characters */	    int i, val = 0;	    while ((i = get_oct(*S)) > -1) {		val = val * 8 + i;		S++;	    }	    if (val > 255)		EiC_pre_error("Illegal character octal value");	    c = val;	} else {	    EiC_pre_error("Illegal character escape sequence `\\%c'", *S);	    c = *S++;	}	break;    }    return c;}static ppint EiC_expr_unary(){    ppint res;        while(isspace(*S))	S++;    if(isdigit(*S)) {	res = get_number();    } else if( *S == '(') {	S++;	res = EiC_ifexpr(0);	if(*S != ')')	    EiC_pre_error("Unbalanced parenthesis");	S++;    } else if(*S == '!') {	S++;	res = EiC_expr_unary();	uval(res) = !uval(res);    } else if(*S == '-') {	S++;	if(*S == '-')	    EiC_pre_error("-- not allowed in operand of #if");	res = EiC_expr_unary();		tval(res) = SIGN;	sval(res) = -uval(res);    } else if(*S == '+') {	S++;	if(*S == '+')	    EiC_pre_error("++ not allowed in operand of #if");	res = EiC_expr_unary();    } else if(*S == '~') {	S++;	res = EiC_expr_unary();	uval(res) = ~uval(res);    } else if(*S == '\'') { /* char constants */	S++;	if(*S == '\\') {	    S++;	    uval(res) = get_charConst();	} else	    uval(res) = *S++;	if(*S != '\'')	    EiC_pre_error("Missing closing single quote '");	else	    S++;	tval(res) = SIGN;    } else	EiC_pre_error("Illegal constant expression");    return res;}

⌨️ 快捷键说明

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