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

📄 token.c

📁 source code: Covert TXT to PDF
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $XConsortium: token.c,v 1.2 91/10/10 11:19:55 rws Exp $ *//* Copyright International Business Machines,Corp. 1991 * All Rights Reserved * * License to use, copy, modify, and distribute this software * and its documentation for any purpose and without fee is * hereby granted, provided that the above copyright notice * appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, * and that the name of IBM not be used in advertising or * publicity pertaining to distribution of the software without * specific, written prior permission. * * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF * THIRD PARTY RIGHTS.  THE ENTIRE RISK AS TO THE QUALITY AND * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT * OR MAINTAIN, BELONGS TO THE LICENSEE.  SHOULD ANY PORTION OF * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION.  IN * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. *//* Authors: Sig Nin & Carol Thompson IBM Almaden Research Laboratory */#include "types.h"#include "t1stdio.h"#include "util.h"#include "digit.h"#include "token.h"#include "tokst.h"#include "hdigit.h" /* * ------------------------------------------------------------------- * Globals * ------------------------------------------------------------------- */ extern int  T1Getc(F_FILE * ), T1Ungetc( int,F_FILE *);/* These variables are set by the caller */char           *tokenStartP;   /* Pointer to token buffer in VM */char           *tokenMaxP;     /* Pointer to last byte in buffer + 1 */ /* These variables are set by TOKEN */int             tokenLength;   /* Characters in token */boolean         tokenTooLong;  /* Token too long for buffer */int             tokenType;     /* Type of token identified */psvalue         tokenValue;    /* Token value */ /* * ------------------------------------------------------------------- * Private variables * ------------------------------------------------------------------- */ static FILE    *inputFileP;    /* Current input file */  /* Token */static char    *tokenCharP;    /* Pointer to next character in token */ /* * ------------------------------------------------------------------- * Private routines for manipulating numbers * ------------------------------------------------------------------- */ #define Exp10(e) \((e) == 0\ ? (DOUBLE)(1.0)\ : (-64 <= (e) && (e) <= 63\    ? Exp10T[(e)+64]\    : P10(e)\   )\) static DOUBLE Exp10T[128] = {  1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57,  1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49,  1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41,  1e-40, 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33,  1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25,  1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18, 1e-17,  1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9,  1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,  1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,  1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,  1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23,  1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31,  1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,  1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47,  1e48, 1e49, 1e50, 1e51, 1e52, 1e53, 1e54, 1e55,  1e56, 1e57, 1e58, 1e59, 1e60, 1e61, 1e62, 1e63}; static DOUBLE P10(exponent)  LONG exponent;{  DOUBLE value, power;   if (exponent < 0) {    power = 0.1;    value = (exponent & 1 ? power : 1.0);    exponent = -((exponent+1) >> 1); /* portable C for -(exponent/2) */  }  else {    power = 10.0;    value = (exponent & 1 ? power : 1.0);    exponent = exponent >> 1;  }   while(exponent > 0) {    power *= power;    if (exponent & 1)      value *= power;    exponent >>= 1;  }   return(value);} /* * ------------------------------------------------------------------- * Private routines and macros for manipulating the input * ------------------------------------------------------------------- */ /* Get next character from the input -- * */#define next_ch()    (getc(inputFileP)) /* Push a character back into the input -- * * Ungetc of EOF will fail, but that's ok: the next getc will * return EOF. * * NOTE:  These macros are presently written to return the character * pushed, or EOF if none was pushed.  However, they are not * required to return anything in particular, and callers should * not rely on the returned value. */#define back_ch(ch)   (ungetc(ch, inputFileP)) /* Push a character back into the input if it was not white space. * If it is a carriage return (\r) then check next char for * linefeed and consume them both, otherwise put next char back. * */#define back_ch_not_white(ch) \(\isWHITE_SPACE(ch)\ ? ((ch == '\r')\   ? (((ch = next_ch()) == '\n')\     ? EOF\     : back_ch(ch)\     )\   : EOF\   )\ : back_ch(ch)\) /* * ------------------------------------------------------------------- * Private routines and macros for manipulating the token buffer * ------------------------------------------------------------------- */ /* Add a character to the token * ---- use ONLY when you KNOW that this character will *      be stored within the token buffer. */#define save_unsafe_ch(ch) (*tokenCharP++ = ch) /* Add a character to the token, if not too long to fit */#define save_ch(ch) \((tokenCharP < tokenMaxP)\ ? save_unsafe_ch(ch)\ : (tokenTooLong = TRUE)\) /* * ------------------------------------------------------------------- * Action Routines * *  These routines all *    -- take int ch as a parameter *    -- return int ch if no token was recognized, DONE otherwise *    -- leave the next character in the input, if returning DONE * ------------------------------------------------------------------- */ #define DONE  (256) /* Get the next input character */static int next_char(ch)  int ch;{  return(next_ch());} /* Add character to token */static int add_char(ch)  int ch;{  save_ch(ch);  return(next_ch());}  /* ------------------------------------------------------------------- * Skip white space and comments */ /* Skip white space */static int skip_space(ch)  int ch;{  do {    ch = next_ch();  } while(isWHITE_SPACE(ch));  return(ch);} /* Skip comments */static int skip_comment(ch)  int ch;{  do {    ch = next_ch();  } while(isCOMMENT(ch));  return(ch);} /* ------------------------------------------------------------------- * Collect value elements for a number */ /* decimal integer or real number mantissa */static int m_sign;static LONG m_value;static LONG m_scale; /* real number exponent */static int e_sign;static LONG e_value;static LONG e_scale; /* radix number */static LONG r_base;static LONG r_value;static LONG r_scale; static int add_sign(ch)  int ch;{  m_sign = ch;  save_unsafe_ch(ch);  return(next_ch());} static int add_1st_digits(ch)  int ch;{  m_sign = '+';  return(add_digits(ch));} static int add_digits(ch)  int ch;{  LONG value, p_value, scale;  int digit;   /* On entry, expect m_sign to be set to '+' or '-';   *  ch is a decimal digit.   * Expect at most one character saved at this point,   *  a sign.  This routine will save up to 10 more   *  characters without checking the buffer boundary.   */   value = ch - '0';  save_unsafe_ch(ch);  ch = next_ch();   while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {    value = (value << 3) + (value << 1) + (ch - '0');    save_unsafe_ch(ch);    ch = next_ch();  }   /* Quick exit for small integers --   *    |x| <= 10*((MAX_INTEGER/10)-1)+9   *    |x| <= 2,147,483,639 for 32 bit integers   */  if (isNUMBER_ENDER(ch)) {    back_ch_not_white(ch);    tokenValue.integer = (m_sign == '-' ? -value : value);    tokenType = TOKEN_INTEGER;    return(DONE);  }   /* Handle additional digits.  Beyond the boundary case,   *   10*(MAX_INTEGER/10) <= |number| <= MAX_INTEGER   * just count the digits: the number is too large to   * represent as an integer and will be returned as a real.   * The mantissa of a real holds fewer bits than an integer.   */  p_value = value;  value = (m_sign == '-' ? -value : value);  scale = 0;   if (isDECIMAL_DIGIT(ch)) {     /* Handle the boundary case */    if (p_value == (MAX_INTEGER/10)) {      digit = ch - '0';       /* Must handle positive and negative values separately  */      /* for 2's complement arithmetic */      if (value > 0) {        if (digit <= MAX_INTEGER%10)          value = (value << 3) + (value << 1) + digit;        else          ++scale;  /* Too big, just count it */      }      else {        /* Use positive % operands for portability */        if (digit <= -(MIN_INTEGER+10)%10)          value = (value << 3) + (value << 1) - digit;        else          ++scale;  /* Too big, just count it */      }    }    else      ++scale;  /* Not boundary case, just count digit */     save_unsafe_ch(ch);    ch = next_ch();     /* Continue scanning digits, but can't store them */    while(isDECIMAL_DIGIT(ch)) {      ++scale;      save_ch(ch);      ch = next_ch();    }  }   /* Continue from here scanning radix integer or real */  m_value = value;  m_scale = scale;   /* Initialize for possible real */  e_sign = '+';  e_value = 0;  e_scale = 0;   return(ch);} static int add_1st_decpt(ch)  int ch;{  m_sign = '+';  return(add_decpt(ch));} static int add_decpt(ch)  int ch;{  /* On entry, expect m_sign to be set to '+' or '-' */  m_value = 0;  m_scale = 0;  save_unsafe_ch(ch);  return(next_ch());} static int add_fraction(ch)  int ch;{  LONG value, scale;  int digit;   /* On entry, expect m_value and m_scale to be initialized,   * and m_sign to be set to '+' or '-'.  Expect m_value and m_sign   * to be consistent (this is not checked).   */  value = m_value;  scale = m_scale;   /* Scan leading zeroes */  if (value == 0) {    while(ch == '0') {      --scale;      save_ch(ch);      ch = next_ch();    }     /* Scan first significant digit */    if (isDECIMAL_DIGIT(ch)) {      --scale;      value = ch - '0';      value = (m_sign == '-' ? -value : value);      save_ch(ch);      ch = next_ch();    }    else      /* no significant digits -- number is zero */      scale = 0;  }  /* value != 0 || value == 0 && !isDECIMAL_DIGIT(ch) */   /* Scan additional significant digits */  if (isDECIMAL_DIGIT(ch)) {    if (value > 0) {      while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {        --scale;        value = (value << 3) + (value << 1) + (ch - '0');        save_ch(ch);        ch = next_ch();      }      /* Check boundary case */      if (isDECIMAL_DIGIT(ch) && value == (MAX_INTEGER/10)) {        digit = ch - '0';        if (digit <= MAX_INTEGER%10) {          --scale;          value = (value << 3) + (value << 1) + digit;          save_ch(ch);          ch = next_ch();        }      }    }    else {      /* value < 0 */      while(isDECIMAL_DIGIT(ch) && value > -(-(MIN_INTEGER+10)/10+1)) {        /* Use positive / operands for portability */        --scale;        value = (value << 3) + (value << 1) - (ch - '0');        save_ch(ch);        ch = next_ch();      }      /* Check boundary case */      if (isDECIMAL_DIGIT(ch)          && value == -(-(MIN_INTEGER+10)/10+1)) {        digit = ch - '0';        if (digit <= -(MIN_INTEGER+10)%10) {        /* Use positive % operands for portability */          --scale;          value = (value << 3) + (value << 1) - digit;          save_ch(ch);          ch = next_ch();        }      }    }     /* Additional digits can be discarded */    while(isDECIMAL_DIGIT(ch)) {      save_ch(ch);      ch = next_ch();    }  }   /* Store results */  m_value = value;  m_scale = scale;   /* Initialize for possible real */  e_sign = '+';  e_value = 0;  e_scale = 0;   return(ch);} static int add_e_sign(ch)  int ch;{  e_sign = ch;  save_ch(ch);  return(next_ch());} static int add_exponent(ch)  int ch;{  LONG value, p_value;  LONG scale = 0;  int digit;   /* On entry, expect e_sign to be set to '+' or '-' */   value = ch - '0';  save_ch(ch);  ch = next_ch();   while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {    value = (value << 3) + (value << 1) + (ch - '0');    save_ch(ch);    ch = next_ch();  }   p_value = value;  value = (e_sign == '-' ? -value : value);   /* Handle additional digits.  Beyond the boundary case,   *   10*(MAX_INTEGER/10) <= |number| <= MAX_INTEGER   * just count the digits: the number is too large to   * represent as an integer.   */  if (isDECIMAL_DIGIT(ch)) {     /* Examine boundary case */    if (p_value == (MAX_INTEGER/10)) {      digit = ch - '0';       /* Must handle positive and negative values separately */      /*  for 2's complement arithmetic */      if (value > 0) {        if (digit <= MAX_INTEGER%10)          value = (value << 3) + (value << 1) + digit;        else          ++scale; /* Too big, just count it */      }      else {        /* Use positive % operands for portability */        if (digit <= -(MIN_INTEGER+10)%10)          value = (value << 3) + (value << 1) - digit;        else          ++scale; /* Too big, just count it */      }    }    else      ++scale;  /* Not boundary case, just count digit */     save_ch(ch);    ch = next_ch();     /* Continue scanning digits, but can't store any more */    while(isDECIMAL_DIGIT(ch)) {      ++scale;      save_ch(ch);      ch = next_ch();    }  }   /* Store results */  e_value = value;  e_scale = scale;   return(ch);} static int add_radix(ch)  int ch;{  if (2 <= m_value && m_value <= 36 && m_scale == 0) {    r_base = m_value;    save_ch(ch);    return(next_ch());  }  else {    /* Radix invalid, complete a name token */    return(AAH_NAME(ch));  }} static int add_r_digits(ch)  int ch;{  ULONG value;  LONG radix, scale;  int digit;   /* NOTE:  The syntax of a radix number allows only for   * values of zero or more.  The value will be stored as   * a 32 bit integer, which PostScript then interprets   * as signed.  This means, for example, that the numbers:   *   *     8#37777777777   *    10#4294967295   *    16#FFFFFFFF   *    36#1Z141Z3   *   * are all interpreted as -1.  This routine implements this   * idea explicitly:  it accumulates the number's value   * as unsigned, then casts it to signed when done.   */   /* Expect r_base to be initialized */  radix = r_base;  value = 0;  scale = 0;   /* Scan leading zeroes */  while(ch == '0') {    save_ch(ch);    ch = next_ch();  }

⌨️ 快捷键说明

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