From 1fa6520cb6cc98c69fb507c5f2ff55dbb8efce8c Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Wed, 14 Dec 2011 15:36:01 -0800 Subject: [PATCH] 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. --- lex.ll | 59 ++++++++++++++++++++------------------------------------ parse.yy | 17 ++++++++-------- 2 files changed, 29 insertions(+), 47 deletions(-) diff --git a/lex.ll b/lex.ll index ce3c4af9..88ff0763 100644 --- a/lex.ll +++ b/lex.ll @@ -148,57 +148,40 @@ L?\"(\\.|[^\\"])*\" { lStringConst(yylval, yylloc); return TOKEN_STRING_LITERAL; return TOKEN_IDENTIFIER; } -{INT_NUMBER} { - char *endPtr = NULL; - int64_t val; +{INT_NUMBER}+(u|U|l|L)*? { + int ls = 0, us = 0; if (yytext[0] == '0' && yytext[1] == 'b') - val = lParseBinary(yytext+2, *yylloc); + yylval->intVal = lParseBinary(yytext+2, *yylloc); else { + char *endPtr = NULL; + #ifdef ISPC_IS_WINDOWS - val = _strtoi64(yytext, &endPtr, 0); + yylval->intVal = _strtoi64(yytext, &endPtr, 0); #else // FIXME: should use strtouq and then issue an error if we can't // fit into 64 bits... - val = strtoull(yytext, &endPtr, 0); + yylval->intVal = strtoull(yytext, &endPtr, 0); #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... - if ((val & 0xffffffff) == val) { - yylval->int32Val = (int32_t)val; - return TOKEN_INT32_CONSTANT; - } - else { - yylval->int64Val = val; - return TOKEN_INT64_CONSTANT; - } + if ((yylval->intVal & 0xffffffff) == yylval->intVal) + return us ? TOKEN_UINT32_CONSTANT : TOKEN_INT32_CONSTANT; + else + return us ? TOKEN_UINT64_CONSTANT : 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} { yylval->floatVal = atof(yytext); diff --git a/parse.yy b/parse.yy index f9a826d4..b9c33a91 100644 --- a/parse.yy +++ b/parse.yy @@ -134,9 +134,8 @@ struct ForeachDimension { %} %union { - int32_t int32Val; - double floatVal; - int64_t int64Val; + int64_t intVal; + float floatVal; std::string *stringVal; const char *constCharPtr; @@ -226,7 +225,7 @@ struct ForeachDimension { %type string_constant %type struct_or_union_name enum_identifier -%type int_constant soa_width_specifier +%type int_constant soa_width_specifier %type foreach_dimension_specifier %type foreach_dimension_list @@ -259,16 +258,16 @@ primary_expression } } | TOKEN_INT32_CONSTANT { - $$ = new ConstExpr(AtomicType::UniformConstInt32, yylval.int32Val, @1); + $$ = new ConstExpr(AtomicType::UniformConstInt32, (int32_t)yylval.intVal, @1); } | TOKEN_UINT32_CONSTANT { - $$ = new ConstExpr(AtomicType::UniformConstUInt32, (uint32_t)yylval.int32Val, @1); + $$ = new ConstExpr(AtomicType::UniformConstUInt32, (uint32_t)yylval.intVal, @1); } | TOKEN_INT64_CONSTANT { - $$ = new ConstExpr(AtomicType::UniformConstInt64, yylval.int64Val, @1); + $$ = new ConstExpr(AtomicType::UniformConstInt64, (int64_t)yylval.intVal, @1); } | TOKEN_UINT64_CONSTANT { - $$ = new ConstExpr(AtomicType::UniformConstUInt64, (uint64_t)yylval.int64Val, @1); + $$ = new ConstExpr(AtomicType::UniformConstUInt64, (uint64_t)yylval.intVal, @1); } | TOKEN_FLOAT_CONSTANT { $$ = new ConstExpr(AtomicType::UniformConstFloat, (float)yylval.floatVal, @1); @@ -930,7 +929,7 @@ declarator ; int_constant - : TOKEN_INT32_CONSTANT { $$ = yylval.int32Val; } + : TOKEN_INT32_CONSTANT { $$ = yylval.intVal; } ; direct_declarator