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

📄 cpp5.c

📁 类PASCAL语言的编译器,LINUX环境的,我没试过是否正确.
💻 C
📖 第 1 页 / 共 2 页
字号:
#if OK_SIZEOFelse if (streq(global->tokenbuf, "sizeof")) { /* New sizeof hackery   */  ret=dosizeof(global, op);             /* Gets own routine     */  return(ret);}#endif      global->evalue = 0;      *op=DIG;      return(FPP_OK);    }    else if (t == DIG) {                  /* Numbers are harder   */      global->evalue = evalnum(global, c);    }    else if (strchr("!=<>&|\\", c) != NULL) {      /*       * Process a possible multi-byte lexeme.       */      c1 = cget(global);                        /* Peek at next char    */      switch (c) {      case '!':	if (c1 == '=') {	  *op=OP_NE;	  return(FPP_OK);	}	break;	      case '=':	if (c1 != '=') {                  /* Can't say a=b in #if */	  unget(global);	  cerror(global, ERROR_ILLEGAL_ASSIGN);	  return (FPP_IF_ERROR);	}	*op=OP_EQ;	return(FPP_OK);	      case '>':      case '<':	if (c1 == c) {	  *op= ((c == '<') ? OP_ASL : OP_ASR);	  return(FPP_OK);	} else if (c1 == '=') {	  *op= ((c == '<') ? OP_LE  : OP_GE);	  return(FPP_OK);	}	break;	      case '|':      case '&':	if (c1 == c) {	  *op= ((c == '|') ? OP_ORO : OP_ANA);	  return(FPP_OK);	}	break;            case '\\':	if (c1 == '\n') {                  /* Multi-line if        */	  loop=TRUE;	  break;	}	cerror(global, ERROR_ILLEGAL_BACKSLASH);	return(FPP_IF_ERROR);      }      if(!loop)	unget(global);    }  } while(loop);  *op=t;  return(FPP_OK);}#if OK_SIZEOFINLINE FILE_LOCALReturnCode dosizeof(struct Global *global, int *result){  /*   * Process the sizeof (basic type) operation in an #if string.   * Sets evalue to the size and returns   *	DIG		success   *	OP_FAIL 	bad parse or something.   */  int c;  TYPES *tp;  SIZES *sizp;  short *testp;  short typecode;  ReturnCode ret;    if ((c = skipws(global)) != '(') {    unget(global);    cerror(global, ERROR_SIZEOF_SYNTAX);    return(FPP_SIZEOF_ERROR);  }  /*   * Scan off the tokens.   */  typecode = 0;  while ((c = skipws(global))) {    if(ret=macroid(global, &c))      return(ret);    /* (I) return on fail! */    if (c  == EOF_CHAR || c == '\n') {      /* End of line is a bug */      unget(global);      cerror(global, ERROR_SIZEOF_SYNTAX);      return(FPP_SIZEOF_ERROR);    } else if (c == '(') {                /* thing (*)() func ptr */      if (skipws(global) == '*'	  && skipws(global) == ')') {         /* We found (*)         */	if (skipws(global) != '(')            /* Let () be optional   */	  unget(global);	else if (skipws(global) != ')') {	  unget(global);	  cerror(global, ERROR_SIZEOF_SYNTAX);	  return(FPP_SIZEOF_ERROR);	}	typecode |= T_FPTR; 		/* Function pointer	*/      } else {				/* Junk is a bug	*/	unget(global);	cerror(global, ERROR_SIZEOF_SYNTAX);	return(FPP_SIZEOF_ERROR);      }    }    else if (type[c] != LET)            /* Exit if not a type   */      break;    else if (!catenate(global, &ret) && !ret) { /* Maybe combine tokens */      /*       * Look for this unexpandable token in basic_types.       * The code accepts "int long" as well as "long int"       * which is a minor bug as bugs go (and one shared with       * a lot of C compilers).       */      for (tp = basic_types; tp->name != NULLST; tp++) {	if (streq(global->tokenbuf, tp->name))	  break;      }      if (tp->name == NULLST) {	cerror(global, ERROR_SIZEOF_UNKNOWN, global->tokenbuf);	return(FPP_SIZEOF_ERROR);      }      typecode |= tp->type;		/* Or in the type bit	*/    } else if(ret)      return(ret);  }  /*   * We are at the end of the type scan.	Chew off '*' if necessary.   */  if (c == '*') {    typecode |= T_PTR;    c = skipws(global);  }  if (c == ')') {                         /* Last syntax check    */    for (testp = test_table; *testp != 0; testp++) {      if (!bittest(typecode & *testp)) {	cerror(global, ERROR_SIZEOF_ILLEGAL_TYPE);	return(FPP_SIZEOF_ERROR);      }    }    /*     * We assume that all function pointers are the same size:     *		sizeof (int (*)()) == sizeof (float (*)())     * We assume that signed and unsigned don't change the size:     *		sizeof (signed int) == (sizeof unsigned int)     */    if ((typecode & T_FPTR) != 0)       /* Function pointer     */      typecode = T_FPTR | T_PTR;    else {				/* Var or var * datum	*/      typecode &= ~(T_SIGNED | T_UNSIGNED);      if ((typecode & (T_SHORT | T_LONG)) != 0)	typecode &= ~T_INT;    }    if ((typecode & ~T_PTR) == 0) {      cerror(global, ERROR_SIZEOF_NO_TYPE);      return(FPP_SIZEOF_ERROR);    }    /*     * Exactly one bit (and possibly T_PTR) may be set.     */    for (sizp = size_table; sizp->bits != 0; sizp++) {      if ((typecode & ~T_PTR) == sizp->bits) {	global->evalue = ((typecode & T_PTR) != 0)	  ? sizp->psize : sizp->size;	*result=DIG;	return(FPP_OK);      }    }					/* We shouldn't fail    */    cerror(global, ERROR_SIZEOF_BUG, typecode);    return(FPP_SIZEOF_ERROR);  }  unget(global);  cerror(global, ERROR_SIZEOF_SYNTAX);  return(FPP_SIZEOF_ERROR);}INLINE FILE_LOCALint bittest(int value){  /*   * TRUE if value is zero or exactly one bit is set in value.   */#if (4096 & ~(-4096)) == 0  return ((value & ~(-value)) == 0);#else  /*   * Do it the hard way (for non 2's complement machines)   */  return (value == 0 || value ^ (value - 1) == (value * 2 - 1));#endif}#endif /* OK_SIZEOF */INLINE FILE_LOCALint evalnum(struct Global *global, int c){  /*   * Expand number for #if lexical analysis.  Note: evalnum recognizes   * the unsigned suffix, but only returns a signed int value.   */  int value;  int base;  int c1;    if (c != '0')    base = 10;  else if ((c = cget(global)) == 'x' || c == 'X') {    base = 16;    c = cget(global);  }  else base = 8;  value = 0;  for (;;) {    c1 = c;    if (isascii(c) && isupper(c1))      c1 = tolower(c1);    if (c1 >= 'a')      c1 -= ('a' - 10);    else c1 -= '0';    if (c1 < 0 || c1 >= base)      break;    value *= base;    value += c1;    c = cget(global);  }  if (c == 'u' || c == 'U')       /* Unsigned nonsense            */    c = cget(global);  unget(global);  return (value);}INLINE FILE_LOCALint evalchar(struct Global *global,	     int skip)		/* TRUE if short-circuit evaluation	*/     /*      * Get a character constant      */{  int c;  int value;  int count;    global->instring = TRUE;  if ((c = cget(global)) == '\\') {    switch ((c = cget(global))) {    case 'a':                           /* New in Standard      */#if ('a' == '\a' || '\a' == ALERT)      value = ALERT;			/* Use predefined value */#else      value = '\a';                   /* Use compiler's value */#endif      break;          case 'b':      value = '\b';      break;          case 'f':      value = '\f';      break;          case 'n':      value = '\n';      break;          case 'r':      value = '\r';      break;          case 't':      value = '\t';      break;          case 'v':                           /* New in Standard      */#if ('v' == '\v' || '\v' == VT)      value = VT;			/* Use predefined value */#else      value = '\v';                   /* Use compiler's value */#endif      break;          case 'x':                           /* '\xFF'               */      count = 3;      value = 0;      while ((((c = get(global)) >= '0' && c <= '9')	      || (c >= 'a' && c <= 'f')	      || (c >= 'A' && c <= 'F'))	     && (--count >= 0)) {	value *= 16;	value += (c <= '9') ? (c - '0') : ((c & 0xF) + 9);      }      unget(global);      break;          default:      if (c >= '0' && c <= '7') {	count = 3;	value = 0;	while (c >= '0' && c <= '7' && --count >= 0) {	  value *= 8;	  value += (c - '0');	  c = get(global);	}	unget(global);      } else	value = c;      break;    }  } else if (c == '\'')    value = 0;  else value = c;  /*   * We warn on multi-byte constants and try to hack   * (big|little)endian machines.   */#if BIG_ENDIAN  count = 0;#endif  while ((c = get(global)) != '\'' && c != EOF_CHAR && c != '\n') {    if (!skip)      cwarn(global, WARN_MULTIBYTE_NOT_PORTABLE, c);#if BIG_ENDIAN    count += BITS_CHAR;    value += (c << count);#else    value <<= BITS_CHAR;    value += c;#endif  }  global->instring = FALSE;  return (value);}INLINE FILE_LOCALint *evaleval(struct Global *global,	      int *valp,	      int op,	      int skip)		/* TRUE if short-circuit evaluation	*/{  /*   * Apply the argument operator to the data on the value stack.   * One or two values are popped from the value stack and the result   * is pushed onto the value stack.   *   * OP_COL is a special case.   *   * evaleval() returns the new pointer to the top of the value stack.   */  int v1, v2;    if (isbinary(op))    v2 = *--valp;  v1 = *--valp;  switch (op) {  case OP_EOE:    break;  case OP_ADD:    v1 += v2;    break;  case OP_SUB:    v1 -= v2;    break;  case OP_MUL:    v1 *= v2;    break;  case OP_DIV:  case OP_MOD:    if (v2 == 0) {      if (!skip) {	cwarn(global, WARN_DIVISION_BY_ZERO,	      (op == OP_DIV) ? "divide" : "mod");      }      v1 = 0;    }    else if (op == OP_DIV)      v1 /= v2;    else      v1 %= v2;    break;  case OP_ASL:    v1 <<= v2;    break;  case OP_ASR:    v1 >>= v2;    break;  case OP_AND:    v1 &= v2;    break;  case OP_OR:    v1 |= v2;    break;  case OP_XOR:    v1 ^= v2;    break;  case OP_EQ:    v1 = (v1 == v2);    break;  case OP_NE:    v1 = (v1 != v2);    break;  case OP_LT:    v1 = (v1 < v2);    break;  case OP_LE:    v1 = (v1 <= v2);    break;  case OP_GE:    v1 = (v1 >= v2);    break;  case OP_GT:    v1 = (v1 > v2);    break;  case OP_ANA:    v1 = (v1 && v2);    break;  case OP_ORO:    v1 = (v1 || v2);    break;  case OP_COL:    /*     * v1 has the "true" value, v2 the "false" value.     * The top of the value stack has the test.     */    v1 = (*--valp) ? v1 : v2;    break;  case OP_NEG:    v1 = (-v1);    break;  case OP_PLU:    break;  case OP_COM:    v1 = ~v1;    break;  case OP_NOT:    v1 = !v1;    break;  default:    cerror(global, ERROR_IF_OPERAND, op);    v1 = 0;  }  *valp++ = v1;  return (valp);}

⌨️ 快捷键说明

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