69,371
社区成员
发帖
与我相关
我的任务
分享
class Number : public WXCC
{
virtual void calcHash(void);
public:
NS_LEX_CONSTANTS::TYPE type; /* T_INT_CON T_FLOAT_CON T_CHAR_CON */
NS_LEX_CONSTANTS::NUMBER_TYPE numberType; /* enum NUMBER_TYPE */
union
{
double d_value;
int i_value;
} val;
Number(const Number& num)
:type(num.type), numberType(num.numberType)
{
val.d_value = num.val.d_value;
calcHash();
}
};
Number* Lex::tryParseFloatNumber(char* numberBuffer, Number **dest)
{
/* try to parse a floating number. first check the vaildity, then call the
* C library call strod()
*
* FLOATING-CONSTANT:
* FRACTIONAL-CONSTANT [ EXPONENT-PART ] [ FLOATING-SUFFIX ]
*
* FRACTIONAL-CONSTANT:
* [ DIGIT-SEQUENCE ]. DIGIT-SEQUENCE
*
* EXPONENT-PART:
* E [ SIGN ] DIGIT-SEQUENCE
* e [ SIGN ] DIGIT-SEQUENCE
*
* DIGIT-SEQUENCE:
* DIGIT { DIGIT }
*
* FLOATING-SUFFIX:
* one of F f L l
*/
int reachE = 0, reachP = 0, reachL = 0, reachF = 0;
double result;
char* tp = numberBuffer;
(*dest)->type = T_FLOAT_CON;
(*dest)->numberType = NT_DB;
for (;*tp; tp++)
{
switch (*tp)
{
case '.':
if (reachE != 0)
{
lexerError(LEX_ERROR_ILL_FLO_SUFFIX,tp);
goto parseFloatError;
}
if (reachP != 0)
{
lexerError(LEX_ERROR_ILL_FLO_SUFFIX,tp);
goto parseFloatError;
}
reachP++;
break;
case 'E':case'e':
if (reachE != 0)
{
lexerError(LEX_ERROR_ILL_FLO_SUFFIX,tp);
goto parseFloatError;
}
reachE++;
break;
case 'f':case 'F':
reachF++;
*tp = '\0';
break;
case 'l':case 'L':
reachL++;
*tp = '\0';
break;
case '1': case'2':case'3':case'4':case'5':case '6':case '7':case '8':
case '9':case '0':case '+':case '-':
break;
default:
lexerError(LEX_ERROR_ILL_FLO_SUFFIX, tp);
(*dest)->numberType = NT_DB;
goto parseFloatError;
}
}
if (reachP > 1 || reachF > 1 || reachL > 1)
{
lexerError(LEX_ERROR_ILL_FLO_SUFFIX, tp);
(*dest)->numberType = NT_DB;
goto parseFloatError;
}
else
{
errno = 0;
result = strtod((char *)tmpBuffer, NULL);
if (errno == ERANGE)
{
lexerError(LEX_ERROR_FLOATING_OVERFLOW, tmpBuffer);
goto parseFloatError;
}
else
{
if (reachF == 1)
/* this is single precision value, check the range. */
{
if ((float)result> FLT_MAX + FLT_EPSILON ||
(float)result < (FLT_MAX * -1 ) - FLT_EPSILON)
{
lexerError(LEX_ERROR_FLOATING_OVERFLOW, tmpBuffer);
goto parseFloatError;
}
(*dest)->numberType = NT_FL;
}
if (reachL == 1)
(*dest)->numberType = NT_LD;
}
}
(*dest)->val.d_value = result;
return *dest;
parseFloatError:
(*dest)->val.d_value = 1.0;
return *dest;
}
Number* Lex::tryParseDecNumber(char* numberBuffer)
{
char* tp = numberBuffer;
int reachU = 0, reachL = 0;
int result = 0;
Number * ret;
int times = 0;
ret = (Number *)allocateMemory(sizeof(Number));
ret->numberType = NT_SI;
ret->type = T_INT_CON;
while (*(tp))
{
switch (*tp)
{
case '1': case'2':case'3':case'4':case'5':case '6':case '7':case '8':
case '9':case '0':
result = (result * 10) + (*tp - '0');
break;
case 'u':case 'U':
if (reachU == 0) /* 0x123u */
{
ret->numberType |= NT_UNSIGNED_MASK;
reachU = 1;
}
else
{
lexerError(LEX_ERROR_ILL_SUFFIX, tp);
}
break;
case 'l':case 'L':
if (reachL == 0) /* 0x123l */
{
ret->numberType |= NT_LONG_MASK;
reachU = 1;
}
else
{
lexerError(LEX_ERROR_ILL_SUFFIX, tp);
}
break;
default:
lexerError(LEX_ERROR_ILL_SUFFIX, tp);
break;
case '.':case 'e':case 'E':
return tryParseFloatNumber(numberBuffer, &ret);
}
tp++;
times++;
if (times >= 8)
/* an integer or long integer is 32bit, 8 hex numbers
* UINT_MAX = 0xffffffff
*/
{
lexerError(LEX_ERROR_ICON_TOO_BIG, tmpBuffer);
goto parHexNumFinish;
}
}
parHexNumFinish:
ret->val.i_value = result;
return ret;
}
Number* Lex::tryParseHexNumber(char* numberBuffer)
{
char* tp = numberBuffer;
int reachU = 0, reachL = 0;
int result = 0;
Number * ret;
int times = 0;
ret = (Number *)allocateMemory(sizeof(Number));
ret->numberType = NT_SI;
ret->type = T_INT_CON;
tp += 2 ; /* ignore the '0x' or '0X' character */
while (*(tp))
{
switch (*tp)
{
case '1': case'2':case'3':case'4':case'5':case '6':case '7':case '8':
case '9':case '0':
result = (result << 4) + (*tp - '0');
break;
case 'a':case 'A':
result = (result << 4) + 10;
break;
case 'b':case 'B':
result = (result << 4) + 11;
break;
case 'c':case 'C':
result = (result << 4) + 12;
break;
case 'd':case 'D':
result = (result << 4) + 13;
break;
case 'e':case 'E':
result = (result << 4) + 14;
break;
case 'f':case 'F':
result = (result << 4) + 15;
break;
case 'u':case 'U':
if (reachU == 0) /* 0x123u */
{
ret->numberType |= NT_UNSIGNED_MASK;
reachU = 1;
}
else
{
lexerError(LEX_ERROR_ILL_SUFFIX, tp);
}
break;
case 'l':case 'L':
if (reachL == 0) /* 0x123l */
{
ret->numberType |= NT_LONG_MASK;
reachL = 1;
}
else
{
lexerError(LEX_ERROR_ILL_SUFFIX, tp);
}
break;
case '\0':
break;
default:
lexerError(LEX_ERROR_ILL_CHAR_IN_HEX, tp);
goto parHexNumFinish;
}
tp++;
if (times >= 8)
/* an integer or long integer is 32bit, 8 hex numbers
* UINT_MAX = 0xffffffff
*/
{
lexerError(LEX_ERROR_ICON_TOO_BIG, tmpBuffer);
goto parHexNumFinish;
}
times++;
}
parHexNumFinish:
ret->val.i_value = result;
return ret;
}
Number* Lex::tryParseOctNumber(char* numberBuffer)
{
char* tp = numberBuffer;
int reachU = 0, reachL = 0;
int result = 0;
Number * ret;
int times = 0;
ret = (Number *)allocateMemory(sizeof(Number));
ret->numberType = NT_SI;
ret->type = T_INT_CON;
while (*(tp))
{
switch (*tp)
{
case '1': case'2':case'3':case'4':case'5':case '6':case '7':case '8':
case '0':
result = (result << 3) + (*tp - '0');
break;
case 'u':case 'U':
if (reachU == 0) /* 0123u */
{
ret->numberType |= NT_UNSIGNED_MASK;
reachU = 1;
}
else
{
lexerError(LEX_ERROR_ILL_SUFFIX, tp);
}
break;
case 'l':case 'L':
if (reachL == 0) /* 0123l */
{
ret->numberType |= NT_LONG_MASK;
reachU = 1;
}
else
{
lexerError(LEX_ERROR_ILL_SUFFIX, tp);
}
break;
default:
lexerError(LEX_ERROR_ILL_CHAR_IN_OCT, tp);
goto parOctNumFinish;
break;
}
tp++;
times++;
if (times >= 11)
/* an integer or long integer is 32bit, 11 oct numbers
* UINT_MAX = 037777777777
*/
{
lexerError(LEX_ERROR_ICON_TOO_BIG, tmpBuffer);
goto parOctNumFinish;
}
}
parOctNumFinish:
ret->val.i_value = result;
return ret;
}
int Lex::newNumber(char *numBuffer, int radix)
{
Number *ret = NULL;
switch (radix)
{
case 10:
ret = tryParseDecNumber(numBuffer);
break;
case 16:
ret = tryParseHexNumber(numBuffer);
break;
case 8:
ret = tryParseOctNumber(numBuffer);
break;
default:
assert(0);
}
//newTok = new Token(ret);
currentToken->token_type = ret->type;
currentToken->token_value.numVal = ret;
switch (ret->type)
{
case T_FLOAT_CON:
currentToken->token_value.numVal->val.d_value = ret->val.d_value;
break;
case T_INT_CON:
currentToken->token_value.numVal->val.i_value = ret->val.i_value;
break;
default: assert(0);
}
return currentToken->token_type;
}
int Lex::number(char peek)
{
getNextChar(BACK);
getBufferUntilSp();//把下一个数字放入tmpBuffer数组
switch (peek)
{
case '0':
if (isdigit(tmpBuffer[1])) /* oct numbers */
{
return newNumber(tmpBuffer, 8);
}
else if (tmpBuffer[1] == 'x' || tmpBuffer[1] == 'X') /*hex numbers*/
return newNumber(tmpBuffer, 16);
else if (tmpBuffer[1] == '\0') /* there is a 0 */
return newNumber(tmpBuffer, 10);
default: /* dec numbers */
return newNumber(tmpBuffer, 10);
}
}
template<class Out_Type, class In_Type>
Out_Type type_convert(const In_Type& T)
{
stringstream ss;
ss<<T;
Out_Type result;
ss>>result;
return result;
}
char s1[]="123";
char s2[]="123.555";
double d1,d2;
sscanf(s1,"%lf",&d1);
sscanf(s2,"%lf",&d2);
printf("%lg\n%lg\n",d1,d2);