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:
Matt Pharr
2011-12-14 15:36:01 -08:00
parent b6af5c16c6
commit 1fa6520cb6
2 changed files with 29 additions and 47 deletions

59
lex.ll
View File

@@ -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);

View File

@@ -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