Improvements to constant int parsing.
Accept 'u' and 'l' suffixes to force the constants to be corresponding types. Just carry around a single 64-bit int value in yylval rather than having both 32- and 64-bit variants.
This commit is contained in:
59
lex.ll
59
lex.ll
@@ -148,57 +148,40 @@ L?\"(\\.|[^\\"])*\" { lStringConst(yylval, yylloc); return TOKEN_STRING_LITERAL;
|
|||||||
return TOKEN_IDENTIFIER;
|
return TOKEN_IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
{INT_NUMBER} {
|
{INT_NUMBER}+(u|U|l|L)*? {
|
||||||
char *endPtr = NULL;
|
int ls = 0, us = 0;
|
||||||
int64_t val;
|
|
||||||
|
|
||||||
if (yytext[0] == '0' && yytext[1] == 'b')
|
if (yytext[0] == '0' && yytext[1] == 'b')
|
||||||
val = lParseBinary(yytext+2, *yylloc);
|
yylval->intVal = lParseBinary(yytext+2, *yylloc);
|
||||||
else {
|
else {
|
||||||
|
char *endPtr = NULL;
|
||||||
|
|
||||||
#ifdef ISPC_IS_WINDOWS
|
#ifdef ISPC_IS_WINDOWS
|
||||||
val = _strtoi64(yytext, &endPtr, 0);
|
yylval->intVal = _strtoi64(yytext, &endPtr, 0);
|
||||||
#else
|
#else
|
||||||
// FIXME: should use strtouq and then issue an error if we can't
|
// FIXME: should use strtouq and then issue an error if we can't
|
||||||
// fit into 64 bits...
|
// fit into 64 bits...
|
||||||
val = strtoull(yytext, &endPtr, 0);
|
yylval->intVal = strtoull(yytext, &endPtr, 0);
|
||||||
#endif
|
#endif
|
||||||
|
for (; *endPtr; endPtr++) {
|
||||||
|
if (*endPtr == 'l' || *endPtr == 'L')
|
||||||
|
ls++;
|
||||||
|
else if (*endPtr == 'u' || *endPtr == 'U')
|
||||||
|
us++;
|
||||||
|
}
|
||||||
|
if (ls >= 2)
|
||||||
|
return us ? TOKEN_UINT64_CONSTANT : TOKEN_INT64_CONSTANT;
|
||||||
|
else if (ls == 1)
|
||||||
|
return us ? TOKEN_UINT32_CONSTANT : TOKEN_INT32_CONSTANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we can fit this into a 32-bit integer...
|
// See if we can fit this into a 32-bit integer...
|
||||||
if ((val & 0xffffffff) == val) {
|
if ((yylval->intVal & 0xffffffff) == yylval->intVal)
|
||||||
yylval->int32Val = (int32_t)val;
|
return us ? TOKEN_UINT32_CONSTANT : TOKEN_INT32_CONSTANT;
|
||||||
return TOKEN_INT32_CONSTANT;
|
else
|
||||||
}
|
return us ? TOKEN_UINT64_CONSTANT : TOKEN_INT64_CONSTANT;
|
||||||
else {
|
|
||||||
yylval->int64Val = val;
|
|
||||||
return TOKEN_INT64_CONSTANT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{INT_NUMBER}[uU] {
|
|
||||||
char *endPtr = NULL;
|
|
||||||
uint64_t val;
|
|
||||||
|
|
||||||
if (yytext[0] == '0' && yytext[1] == 'b')
|
|
||||||
val = lParseBinary(yytext+2, *yylloc);
|
|
||||||
else {
|
|
||||||
#ifdef ISPC_IS_WINDOWS
|
|
||||||
val = _strtoui64(yytext, &endPtr, 0);
|
|
||||||
#else
|
|
||||||
val = strtoull(yytext, &endPtr, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((val & 0xffffffff) == val) {
|
|
||||||
// we can represent it in a 32-bit value
|
|
||||||
yylval->int32Val = (int32_t)val;
|
|
||||||
return TOKEN_UINT32_CONSTANT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yylval->int64Val = val;
|
|
||||||
return TOKEN_UINT64_CONSTANT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{FLOAT_NUMBER} {
|
{FLOAT_NUMBER} {
|
||||||
yylval->floatVal = atof(yytext);
|
yylval->floatVal = atof(yytext);
|
||||||
|
|||||||
17
parse.yy
17
parse.yy
@@ -134,9 +134,8 @@ struct ForeachDimension {
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
int32_t int32Val;
|
int64_t intVal;
|
||||||
double floatVal;
|
float floatVal;
|
||||||
int64_t int64Val;
|
|
||||||
std::string *stringVal;
|
std::string *stringVal;
|
||||||
const char *constCharPtr;
|
const char *constCharPtr;
|
||||||
|
|
||||||
@@ -226,7 +225,7 @@ struct ForeachDimension {
|
|||||||
|
|
||||||
%type <stringVal> string_constant
|
%type <stringVal> string_constant
|
||||||
%type <constCharPtr> struct_or_union_name enum_identifier
|
%type <constCharPtr> struct_or_union_name enum_identifier
|
||||||
%type <int32Val> int_constant soa_width_specifier
|
%type <intVal> int_constant soa_width_specifier
|
||||||
|
|
||||||
%type <foreachDimension> foreach_dimension_specifier
|
%type <foreachDimension> foreach_dimension_specifier
|
||||||
%type <foreachDimensionList> foreach_dimension_list
|
%type <foreachDimensionList> foreach_dimension_list
|
||||||
@@ -259,16 +258,16 @@ primary_expression
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
| TOKEN_INT32_CONSTANT {
|
| TOKEN_INT32_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformConstInt32, yylval.int32Val, @1);
|
$$ = new ConstExpr(AtomicType::UniformConstInt32, (int32_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_UINT32_CONSTANT {
|
| TOKEN_UINT32_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformConstUInt32, (uint32_t)yylval.int32Val, @1);
|
$$ = new ConstExpr(AtomicType::UniformConstUInt32, (uint32_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_INT64_CONSTANT {
|
| TOKEN_INT64_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformConstInt64, yylval.int64Val, @1);
|
$$ = new ConstExpr(AtomicType::UniformConstInt64, (int64_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_UINT64_CONSTANT {
|
| TOKEN_UINT64_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformConstUInt64, (uint64_t)yylval.int64Val, @1);
|
$$ = new ConstExpr(AtomicType::UniformConstUInt64, (uint64_t)yylval.intVal, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_FLOAT_CONSTANT {
|
| TOKEN_FLOAT_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformConstFloat, (float)yylval.floatVal, @1);
|
$$ = new ConstExpr(AtomicType::UniformConstFloat, (float)yylval.floatVal, @1);
|
||||||
@@ -930,7 +929,7 @@ declarator
|
|||||||
;
|
;
|
||||||
|
|
||||||
int_constant
|
int_constant
|
||||||
: TOKEN_INT32_CONSTANT { $$ = yylval.int32Val; }
|
: TOKEN_INT32_CONSTANT { $$ = yylval.intVal; }
|
||||||
;
|
;
|
||||||
|
|
||||||
direct_declarator
|
direct_declarator
|
||||||
|
|||||||
Reference in New Issue
Block a user