Beispiel #1
0
bool FScanner::CheckFloat ()
{
	char *stopper;

	if (GetString())
	{
		if (String[0] == 0)
		{
			UnGet();
			return false;
		}
	
		Float = strtod (String, &stopper);
		if (*stopper != 0)
		{
			UnGet();
			return false;
		}
		return true;
	}
	else
	{
		return false;
	}
}
Beispiel #2
0
bool FScanner::CheckNumber ()
{
	char *stopper;

	if (GetString())
	{
		if (String[0] == 0)
		{
			UnGet();
			return false;
		}
		else if (strcmp (String, "MAXINT") == 0)
		{
			Number = INT_MAX;
		}
		else
		{
			Number = (int)strtoll (String, &stopper, 0);
			if (*stopper != 0)
			{
				UnGet();
				return false;
			}
		}
		Float = Number;
		return true;
	}
	else
	{
		return false;
	}
}
Beispiel #3
0
bool FScanner::CheckToken (int token)
{
	if (GetToken ())
	{
		if (TokenType == token)
		{
			return true;
		}
		UnGet ();
	}
	return false;
}
Beispiel #4
0
bool FScanner::CheckString (const char *name)
{
	if (GetString ())
	{
		if (Compare (name))
		{
			return true;
		}
		UnGet ();
	}
	return false;
}
 int FastCharStream::Peek() {
   int c = GetNext();
   UnGet();
   return c;
 }
const Token* Tokenizer::Peek() {
  Token* T = GetNext();
  UnGet(T);
  return T;
}
Beispiel #7
0
__int64 __scanttoint64(int  (*Get)   (void *srceP),
               void (*UnGet) (int ch, void *srceP),
               void *srceP,
               int  radix,
               int  width,
               int  *countP,
               int  *statusP )
{
    char        sign        = 0;
    int         ct          = 0;
    int         status      = 1;
    int         ndigits     = 0;
    unsigned __int64 result = 0;
    _TINT       ch;

    enum { _space, _sign, _radix, _digits } stage;

    stage = _space;
    for (;;)
    {
        /* Get the next input character.
         */
        ct++;
        ch = Get (srceP);

        /* Skip over any white-space prefix characters, which don't
         * count as part of the width.
         */
        if (stage == _space)
        {
            if (ch >= 0 && ch < 128 && _istspace(ch))
                continue;
            stage = _sign;
        }

        if (--width < 0)
            break;

        /* Check for optional plus or minus sign.
         */
        if (stage == _sign)
        {
            stage = _radix;
            if (ch == _TEXT('+') || ch == _TEXT('-'))
            {
                sign = ch == _TEXT('-');
                continue;
            }
        }

        /* Check the radix.  If zero, the number may be prefixed
         * with 0x or 0X to indicate hex, or 0 to indicate octal.
         */
        if (stage == _radix)
        {
            stage = _digits;
            if (ch == _TEXT('0'))
            {
                ndigits = 1;

                if (radix == 0 || radix == 16)
                {
                    ct++;
                    ch = Get (srceP);
                    if (--width < 0)
                        break;
                    if (ch == _TEXT('x') || ch == _TEXT('X'))
                    {
                        radix = 16;
                        continue;
                    }
                    else if (radix == 0)
                        radix = 8;
                }
            }

            if (radix == 0)
                radix = 10;
            else if (radix < 1 || radix > 36)
                break;
        }

        /* Accumulate the digits.
         */
        if (stage == _digits)
        {
            int digit;
            unsigned __int64 oldresult;

            if (ch >= _TEXT('0') && ch <= _TEXT('9'))
                digit = ch - _TEXT('0');
            else if (ch >= _TEXT('a') && ch <= _TEXT('z'))
                digit = ch - _TEXT('a') + 10;
            else if (ch >= _TEXT('A') && ch <= _TEXT('Z'))
                digit = ch - _TEXT('A') + 10;
            else
                break;
            if (digit >= radix)
                break;

            ndigits++;
            oldresult = result;
            result = result * radix + digit;
            if ((result - digit) / radix != oldresult)
            {
                status = 2;         /* overflow */
                result = sign ? _I64_MIN : _I64_MAX;
                break;
            }
        }
    }

    /* If there wasn't an overflow, push back the last character read
     * and negate the result if '-' was seen.
     */
    if (status != 2)
    {
        UnGet(ch, srceP);
        ct--;
        if (sign)
            result = -(signed)result;
    }

    /* If no digits were seen, set status to 0 or EOF, depending
     * on whether we terminated due to an end of file.
     */
    if (ndigits == 0)
        status = ch == _TEOF ? _TEOF : 0;

    /* Store the status of the scan and the number of characters
     * scanned, then return the result.
     */
    *statusP = status;
    *countP += ct;
    return ((__int64)result);
}
Beispiel #8
0
static void __scanttod (
                        long double *valueP,
                        int  (* Get) (void *srceP),
                        void (* UnGet) (int ch, void *srceP),
                        void  *srceP,
                        int     width,
                        int    *countP,
                        int    *statusP )
{
	int     decimals = 0x8000;
	int     digits = -2;
	int     maxdigits = MAX_IEEE_DIGS;  /* try 19 at first */
	int     exponent;
	char    sign    = 0;
	char    FirstDigit = 1;
	char    saw_sign= 0;
	char    expSign = 0;
	char    ExpOflow= 0;
	int     ct      = 0;
	int     status  = 1;
	int     ch;

	long double frac = 0.0;
	long double exp;
	unsigned short  *fracw = (unsigned short *)&frac;
	unsigned long   *fracl = (unsigned long  *)&frac;
	long            tempq[2];
	_TCHAR          *decimalpoint = (_TCHAR*) _getLocaleNumericInfo(LOCALE_SDECIMAL);
	_TCHAR          decimal_point_tchar = *decimalpoint; //*_localeconvention.decimal_point;

    /* Skip leading spaces on the input numeral.
     */
    for (;;)
    {
        ct++;
        if ((ch = Get (srceP)) == EOF)
        {
            status = -1;
            goto std_noResult;
        }
#ifndef _UNICODE
	if ((ch & 0x80) != 0 || !_istspace(ch))
#else
	if (!_istspace((int)ch))
#endif
	    break;
    }

    if (--width < 0)
        goto std_fractionLimited;

    /* Is the numeral preceded by a sign ?
     */
    if (ch == _TEXT('+'))
        saw_sign = 1;
    else if (ch == _TEXT('-'))
        sign = saw_sign = 1;
    else
        goto std_gotChar;

    for (;;)            /* Pick up the next character of the fraction.  */
    {
        if (--width < 0)
            goto std_fractionLimited;
        ct ++;
        ch = Get (srceP);

        /* Check for the special cases where +INF -INF +NAN -NAN
         * might be specified.
         */
std_gotChar:
        if (FirstDigit == 1 && saw_sign != 0)
        {
            if (ch == _TEXT('I'))       /* Maybe we have +/-INF         */
                goto PossibleINF;
            else if (ch == _TEXT('N'))  /* Maybe we have +/-NAN         */
                goto PossibleNAN;
        }

        FirstDigit = 0;

        /* Watch for decimal points.
         */
        if (ch == decimal_point_tchar )
        {
            if (decimals != 0x8000)     /* Seen a previous decimal point? */
                break;                  /* If so, fraction is terminated */
            decimals = digits > 0 ? digits : 0;
            continue;
        }

        if (ch < _TEXT('0') || ch > _TEXT('9'))
            break;                     /* Non-numeric terminates fraction */
        ch -= _TEXT('0');              /* convert digit to equivalent number.  */

        if (++digits <= 0)             /* Was it the first digit? */
        {
            /* The first digit begins the fraction.  Leading
             * zeros are noted by setting digits -1, so that the
             * fraction syntax is valid if no other digits are
             * seen, but following digits will still be treated
             * as "firsts".  Leading non-zero digits cause digits
             * to be set to 1.
             */
            fracw[0] = ch;
            if (ch != 0)                /* not a leading zero? */
                digits = 1;
            else
            {
                digits = -1;            /* it is a leading zero */
                if (decimals != 0x8000) /* has decimal point been seen ? */
                    decimals--;         /* if yes, move it to the left. */
            }
            continue;
        }

        /* If a digit is seen, then multiply the existing fraction by 10 and
         * add in the new digit.  The special case of the first 9 digits is
         * treated separately for speed, because the value can't exceed
         * 32 bits.
         */
        if (digits <= 9)
        {
            *fracl = *fracl * 10L + (long)ch;
        }
        else if (digits <= maxdigits)
        {
            /* Digits beyond the 9th are more rare in practice
             * (even in 10-digit numbers, 9 will be quick), so no
             * further special cases are justified.  Beyond MAX_IEEE_DIGS
             * digits, or beyond 2^64, ignore the digit values
             * but keep scanning.
             */
            tempq[0] = fracl[0];            /* make temporary copy of frac */
            tempq[1] = fracl[1];
            if (_qmul10(tempq, ch) != 0)    /* overflow? */
                maxdigits = digits -1;      /* say we never saw this digit */
            else
            {
                fracl[0] = tempq[0];        /* no overflow, copy temporary */
                fracl[1] = tempq[1];        /*  result to frac */
            }
        }
        continue;

        /* Arrive here when fraction is width-limited but valid.
         */
std_fractionLimited:
        ch = _TEXT('e');                   /* Behave as if exponent started. */
        break;
    }

    /* The fraction was ended.  If it was valid, it must have had at least
     * one digit.  AL must hold the character which terminated the fraction.
     */
    if (digits == -2)
        goto std_noDigitSeen;

    /* If no decimal point was seen, then the decimal is assumed to be at
     *  the rightmost edge.
     */
    if (decimals == 0x8000)
        decimals = digits;

    /* Now we must gather the exponent.  First, check for 'E' or 'e' to
     * introduce it, then if found gather the short integer.
     */
    exponent = 0;
    if (ch == _TEXT('e') || ch == _TEXT('E'))
    {
        int SignStage = 1;

        for (;;)
        {
            if (--width < 0)
                goto std_exponentLimited;
            ct ++;
            ch = Get (srceP);
            if (SignStage)
            {
                SignStage = 0;
                if (ch == _TEXT('-'))
                {
                    expSign = 1;
                    continue;
                }
                else if (ch == _TEXT('+'))
                    continue;
            }
            if (ch < _TEXT('0') || ch > _TEXT('9'))
                break;
            if ((exponent = exponent * 10 + ch - _TEXT('0')) > 4932)
                ExpOflow = 1;
        }
    }

    /* Arrive here when a valid syntax has been terminated
     * ch must still contain the terminating character, unchanged
     */
    UnGet (ch, srceP);
    ct--;

    /* Arrive here with valid termination but no terminator to be pushed back.
     */
std_exponentLimited:
    if (expSign)                /* was the exponent signed ?    */
    {
        exponent = -exponent;

        /* Normal stays normal, Infinity becomes 0 if exponent was hugely
         * negative.
         */
        ExpOflow = -ExpOflow;
    }

    /* The special case when digits = -1 occurs when the fraction is zero.
     * In that case, the result is always zero, whatever the exponent.
     */
    if (digits < 0)
    {
        frac = 0.0;
        goto std_end;
    }

    /* Convert underflows to zero and overflows to ld HUGE_VAL.
     */
    if (ExpOflow)
    {
        if (ExpOflow == 1)              /* big (+) exp -> ld HUGE_VAL */
        {
            /* Make 'frac' a long double HUGE_VAL.
             */
            fracw[0] = fracw[1] = fracw[2] = fracw[3] = 0xffff;
            fracw[4] = 0x7ffe;
        }
        else
            frac = 0.0;
        status = 2;
        goto std_end;
    }

    /* Add the decimal point contribution to the exponent.
     */
    exponent += decimals - (digits > maxdigits ? maxdigits : digits);
    frac = _fuildq((long *)&frac);  /* Convert fraction to a long double */

    /* Multiply fraction * 10^exponent if exponent is non-zero
     */
    if (exponent != 0)
    {
        exp = _pow10(exponent > 0 ? exponent : -exponent);
        if (exponent < 0)       /* negative exponent --> 1 / 10^|exponent|  */
            frac = frac / exp;
        else
            frac = frac * exp;
    }

std_end:
    if (sign)
        frac = -frac;

std_exit:
    *countP += ct;
    *statusP = status;
    *valueP = frac;
    return;

/* Error clauses placed here out of the main loop.
 * Arrive here if an error occurred.
 */
std_noDigitSeen:
    status = 0;

std_noResult:
    if (width >= 0)
    {
        UnGet (ch, srceP);
        ct --;
    }
    frac = 0.0;
    goto std_end;

/*  end of error clauses.
 */

/*-------------------------------------------------------------------------
                Special case code to scan +INF -INF +NAN -NAN
  -------------------------------------------------------------------------
  One side effect here, if this ultimately isn't +INF -INF +NAN -NAN will be
  that the apps input stream is now messed up because we needed to look
  ahead more than 1 character to recognize INF or NAN. The 'unget' functions
  are only guaranteed to be able to unget a maximum of one char. This means
  on a worst case input like "+INX" there will be 3 characters we won't be
  able to push back on the stream successfully.  There's not much that can
  be done to prevent this.  The same kind of thing can happen when reading
  E format numbers, for example "1.234E+Q".  By the time the 'Q' is seen
  "E+" has gone by.
--------------------------------------------------------------------------*/
PossibleINF:
    ct ++;
    ch = Get (srceP);
    if (--width < 0 || ch != _TEXT('N'))
        goto std_noDigitSeen;
    ct ++;
    ch = Get (srceP);
    if (--width < 0 || ch != _TEXT('F'))
        goto std_noDigitSeen;
    if (sign)
        frac = *(long double *)INFM;
    else
        frac = *(long double *)INF;
    goto std_exit;

PossibleNAN:
    ct ++;
    ch = Get (srceP);
    if (--width < 0 || ch != _TEXT('A'))
        goto std_noDigitSeen;
    ct ++;
    ch = Get (srceP);
    if (--width < 0 || ch != _TEXT('N'))
        goto std_noDigitSeen;
    if (sign)
        frac = *(long double *)NANM;
    else
        frac = *(long double *)NAN;
    goto std_exit;
}