Fix parser so that spaces aren't needed around "..." in foreach statements.
Issue #207.
This commit is contained in:
121
lex.ll
121
lex.ll
@@ -43,6 +43,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
static uint64_t lParseBinary(const char *ptr, SourcePos pos, char **endPtr);
|
static uint64_t lParseBinary(const char *ptr, SourcePos pos, char **endPtr);
|
||||||
|
static int lParseInteger(bool dotdotdot);
|
||||||
static void lCComment(SourcePos *);
|
static void lCComment(SourcePos *);
|
||||||
static void lCppComment(SourcePos *);
|
static void lCppComment(SourcePos *);
|
||||||
static void lHandleCppHash(SourcePos *);
|
static void lHandleCppHash(SourcePos *);
|
||||||
@@ -322,7 +323,8 @@ inline int ispcRand() {
|
|||||||
%option nounistd
|
%option nounistd
|
||||||
|
|
||||||
WHITESPACE [ \t\r]+
|
WHITESPACE [ \t\r]+
|
||||||
INT_NUMBER (([0-9]+)|(0x[0-9a-fA-F]+)|(0b[01]+))[kMG]?
|
INT_NUMBER (([0-9]+)|(0x[0-9a-fA-F]+)|(0b[01]+))[uUlL]*[kMG]?[uUlL]*
|
||||||
|
INT_NUMBER_DOTDOTDOT (([0-9]+)|(0x[0-9a-fA-F]+)|(0b[01]+))[uUlL]*[kMG]?[uUlL]*\.\.\.
|
||||||
FLOAT_NUMBER (([0-9]+|(([0-9]+\.[0-9]*[fF]?)|(\.[0-9]+)))([eE][-+]?[0-9]+)?[fF]?)
|
FLOAT_NUMBER (([0-9]+|(([0-9]+\.[0-9]*[fF]?)|(\.[0-9]+)))([eE][-+]?[0-9]+)?[fF]?)
|
||||||
HEX_FLOAT_NUMBER (0x[01](\.[0-9a-fA-F]*)?p[-+]?[0-9]+[fF]?)
|
HEX_FLOAT_NUMBER (0x[01](\.[0-9a-fA-F]*)?p[-+]?[0-9]+[fF]?)
|
||||||
|
|
||||||
@@ -406,53 +408,14 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
|
|||||||
return TOKEN_IDENTIFIER;
|
return TOKEN_IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
{INT_NUMBER}+(u|U|l|L)*? {
|
{INT_NUMBER} {
|
||||||
RT;
|
RT;
|
||||||
int ls = 0, us = 0;
|
return lParseInteger(false);
|
||||||
|
}
|
||||||
|
|
||||||
char *endPtr = NULL;
|
{INT_NUMBER_DOTDOTDOT} {
|
||||||
if (yytext[0] == '0' && yytext[1] == 'b')
|
RT;
|
||||||
yylval.intVal = lParseBinary(yytext+2, yylloc, &endPtr);
|
return lParseInteger(true);
|
||||||
else {
|
|
||||||
#if defined(ISPC_IS_WINDOWS) && !defined(__MINGW32__)
|
|
||||||
yylval.intVal = _strtoui64(yytext, &endPtr, 0);
|
|
||||||
#else
|
|
||||||
// FIXME: should use strtouq and then issue an error if we can't
|
|
||||||
// fit into 64 bits...
|
|
||||||
yylval.intVal = strtoull(yytext, &endPtr, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool kilo = false, mega = false, giga = false;
|
|
||||||
for (; *endPtr; endPtr++) {
|
|
||||||
if (*endPtr == 'k')
|
|
||||||
kilo = true;
|
|
||||||
else if (*endPtr == 'M')
|
|
||||||
mega = true;
|
|
||||||
else if (*endPtr == 'G')
|
|
||||||
giga = true;
|
|
||||||
else if (*endPtr == 'l' || *endPtr == 'L')
|
|
||||||
ls++;
|
|
||||||
else if (*endPtr == 'u' || *endPtr == 'U')
|
|
||||||
us++;
|
|
||||||
}
|
|
||||||
if (kilo)
|
|
||||||
yylval.intVal *= 1024;
|
|
||||||
if (mega)
|
|
||||||
yylval.intVal *= 1024*1024;
|
|
||||||
if (giga)
|
|
||||||
yylval.intVal *= 1024*1024*1024;
|
|
||||||
|
|
||||||
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 ((yylval.intVal & 0xffffffff) == yylval.intVal)
|
|
||||||
return us ? TOKEN_UINT32_CONSTANT : TOKEN_INT32_CONSTANT;
|
|
||||||
else
|
|
||||||
return us ? TOKEN_UINT64_CONSTANT : TOKEN_INT64_CONSTANT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -562,6 +525,72 @@ lParseBinary(const char *ptr, SourcePos pos, char **endPtr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
lParseInteger(bool dotdotdot) {
|
||||||
|
int ls = 0, us = 0;
|
||||||
|
|
||||||
|
char *endPtr = NULL;
|
||||||
|
if (yytext[0] == '0' && yytext[1] == 'b')
|
||||||
|
yylval.intVal = lParseBinary(yytext+2, yylloc, &endPtr);
|
||||||
|
else {
|
||||||
|
#if defined(ISPC_IS_WINDOWS) && !defined(__MINGW32__)
|
||||||
|
yylval.intVal = _strtoui64(yytext, &endPtr, 0);
|
||||||
|
#else
|
||||||
|
// FIXME: should use strtouq and then issue an error if we can't
|
||||||
|
// fit into 64 bits...
|
||||||
|
yylval.intVal = strtoull(yytext, &endPtr, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool kilo = false, mega = false, giga = false;
|
||||||
|
for (; *endPtr; endPtr++) {
|
||||||
|
if (*endPtr == 'k')
|
||||||
|
kilo = true;
|
||||||
|
else if (*endPtr == 'M')
|
||||||
|
mega = true;
|
||||||
|
else if (*endPtr == 'G')
|
||||||
|
giga = true;
|
||||||
|
else if (*endPtr == 'l' || *endPtr == 'L')
|
||||||
|
ls++;
|
||||||
|
else if (*endPtr == 'u' || *endPtr == 'U')
|
||||||
|
us++;
|
||||||
|
else
|
||||||
|
Assert(dotdotdot && *endPtr == '.');
|
||||||
|
}
|
||||||
|
if (kilo)
|
||||||
|
yylval.intVal *= 1024;
|
||||||
|
if (mega)
|
||||||
|
yylval.intVal *= 1024*1024;
|
||||||
|
if (giga)
|
||||||
|
yylval.intVal *= 1024*1024*1024;
|
||||||
|
|
||||||
|
if (dotdotdot) {
|
||||||
|
if (ls >= 2)
|
||||||
|
return us ? TOKEN_UINT64DOTDOTDOT_CONSTANT : TOKEN_INT64DOTDOTDOT_CONSTANT;
|
||||||
|
else if (ls == 1)
|
||||||
|
return us ? TOKEN_UINT32DOTDOTDOT_CONSTANT : TOKEN_INT32DOTDOTDOT_CONSTANT;
|
||||||
|
|
||||||
|
// See if we can fit this into a 32-bit integer...
|
||||||
|
if ((yylval.intVal & 0xffffffff) == yylval.intVal)
|
||||||
|
return us ? TOKEN_UINT32DOTDOTDOT_CONSTANT : TOKEN_INT32DOTDOTDOT_CONSTANT;
|
||||||
|
else
|
||||||
|
return us ? TOKEN_UINT64DOTDOTDOT_CONSTANT : TOKEN_INT64DOTDOTDOT_CONSTANT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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 ((yylval.intVal & 0xffffffff) == yylval.intVal)
|
||||||
|
return us ? TOKEN_UINT32_CONSTANT : TOKEN_INT32_CONSTANT;
|
||||||
|
else
|
||||||
|
return us ? TOKEN_UINT64_CONSTANT : TOKEN_INT64_CONSTANT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Handle a C-style comment in the source.
|
/** Handle a C-style comment in the source.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
|||||||
32
parse.yy
32
parse.yy
@@ -173,8 +173,11 @@ struct ForeachDimension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
%token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT TOKEN_INT64_CONSTANT
|
%token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT
|
||||||
%token TOKEN_UINT64_CONSTANT TOKEN_FLOAT_CONSTANT TOKEN_STRING_C_LITERAL
|
%token TOKEN_INT64_CONSTANT TOKEN_UINT64_CONSTANT
|
||||||
|
%token TOKEN_INT32DOTDOTDOT_CONSTANT TOKEN_UINT32DOTDOTDOT_CONSTANT
|
||||||
|
%token TOKEN_INT64DOTDOTDOT_CONSTANT TOKEN_UINT64DOTDOTDOT_CONSTANT
|
||||||
|
%token TOKEN_FLOAT_CONSTANT TOKEN_STRING_C_LITERAL
|
||||||
%token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME TOKEN_NULL
|
%token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME TOKEN_NULL
|
||||||
%token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
|
%token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
|
||||||
%token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
|
%token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
|
||||||
@@ -196,7 +199,7 @@ struct ForeachDimension {
|
|||||||
%token TOKEN_CIF TOKEN_CDO TOKEN_CFOR TOKEN_CWHILE TOKEN_CBREAK
|
%token TOKEN_CIF TOKEN_CDO TOKEN_CFOR TOKEN_CWHILE TOKEN_CBREAK
|
||||||
%token TOKEN_CCONTINUE TOKEN_CRETURN TOKEN_SYNC TOKEN_PRINT TOKEN_ASSERT
|
%token TOKEN_CCONTINUE TOKEN_CRETURN TOKEN_SYNC TOKEN_PRINT TOKEN_ASSERT
|
||||||
|
|
||||||
%type <expr> primary_expression postfix_expression
|
%type <expr> primary_expression postfix_expression integer_dotdotdot
|
||||||
%type <expr> unary_expression cast_expression funcall_expression launch_expression
|
%type <expr> unary_expression cast_expression funcall_expression launch_expression
|
||||||
%type <expr> multiplicative_expression additive_expression shift_expression
|
%type <expr> multiplicative_expression additive_expression shift_expression
|
||||||
%type <expr> relational_expression equality_expression and_expression
|
%type <expr> relational_expression equality_expression and_expression
|
||||||
@@ -1620,11 +1623,34 @@ foreach_active_identifier
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
integer_dotdotdot
|
||||||
|
: TOKEN_INT32DOTDOTDOT_CONSTANT {
|
||||||
|
$$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
|
||||||
|
(int32_t)yylval.intVal, @1);
|
||||||
|
}
|
||||||
|
| TOKEN_UINT32DOTDOTDOT_CONSTANT {
|
||||||
|
$$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
|
||||||
|
(uint32_t)yylval.intVal, @1);
|
||||||
|
}
|
||||||
|
| TOKEN_INT64DOTDOTDOT_CONSTANT {
|
||||||
|
$$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
|
||||||
|
(int64_t)yylval.intVal, @1);
|
||||||
|
}
|
||||||
|
| TOKEN_UINT64DOTDOTDOT_CONSTANT {
|
||||||
|
$$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
|
||||||
|
(uint64_t)yylval.intVal, @1);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
foreach_dimension_specifier
|
foreach_dimension_specifier
|
||||||
: foreach_identifier '=' assignment_expression TOKEN_DOTDOTDOT assignment_expression
|
: foreach_identifier '=' assignment_expression TOKEN_DOTDOTDOT assignment_expression
|
||||||
{
|
{
|
||||||
$$ = new ForeachDimension($1, $3, $5);
|
$$ = new ForeachDimension($1, $3, $5);
|
||||||
}
|
}
|
||||||
|
| foreach_identifier '=' integer_dotdotdot assignment_expression
|
||||||
|
{
|
||||||
|
$$ = new ForeachDimension($1, $3, $4);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
foreach_dimension_list
|
foreach_dimension_list
|
||||||
|
|||||||
Reference in New Issue
Block a user