diff options
author | Kenneth Graunke <[email protected]> | 2012-10-22 10:56:46 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2012-10-25 14:52:53 -0700 |
commit | 9142ade15416415f2d5eb20b093b898c649cd2bb (patch) | |
tree | 48292bfda5326e7696bc830fe31320cf860c50df /src | |
parent | eeb2fb72eb4f573410eae45896bc744d6c47b4d6 (diff) |
glcpp: Don't use infinite lookhead for #define differentiation.
Previously, we used lookahead patterns to differentiate:
#define FOO(x) function macro
#define FOO (x) object macro
Unfortunately, our rule for function macros:
{HASH}define{HSPACE}+/{IDENTIFIER}"("
relies on infinite lookahead, and apparently triggers a Flex bug where
the generated code overflows a state buffer (see YY_STATE_BUF_SIZE).
There's no need to use infinite lookahead. We can simply change state,
match the identifier, and use a single character lookahead for the '('.
This apparently makes Flex not generate the giant state array, which
avoids the buffer overflow, and should be more efficient anyway.
Fixes piglit test 17000-consecutive-chars-identifier.frag.
NOTE: This is a candidate for every release branch ever.
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Carl Worth <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/glcpp/glcpp-lex.l | 20 | ||||
-rw-r--r-- | src/glsl/glcpp/glcpp-parse.y | 12 |
2 files changed, 20 insertions, 12 deletions
diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l index 7ab58cb288d..783c545495e 100644 --- a/src/glsl/glcpp/glcpp-lex.l +++ b/src/glsl/glcpp/glcpp-lex.l @@ -67,7 +67,7 @@ void glcpp_set_column (int column_no , yyscan_t yyscanner); %option stack %option never-interactive -%x DONE COMMENT UNREACHABLE SKIP +%x DONE COMMENT UNREACHABLE SKIP DEFINE SPACE [[:space:]] NONSPACE [^[:space:]] @@ -184,14 +184,22 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? glcpp_error(yylloc, yyextra, "#error%s", p); } -{HASH}define{HSPACE}+/{IDENTIFIER}"(" { +{HASH}define{HSPACE}+ { yyextra->space_tokens = 0; - return HASH_DEFINE_FUNC; + yy_push_state(DEFINE, yyscanner); + return HASH_DEFINE; } -{HASH}define { - yyextra->space_tokens = 0; - return HASH_DEFINE_OBJ; +<DEFINE>{IDENTIFIER}/"(" { + yy_pop_state(yyscanner); + yylval->str = ralloc_strdup (yyextra, yytext); + return FUNC_IDENTIFIER; +} + +<DEFINE>{IDENTIFIER} { + yy_pop_state(yyscanner); + yylval->str = ralloc_strdup (yyextra, yytext); + return OBJ_IDENTIFIER; } {HASH}undef { diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y index fb9bc588ef8..ffb48e330b0 100644 --- a/src/glsl/glcpp/glcpp-parse.y +++ b/src/glsl/glcpp/glcpp-parse.y @@ -160,10 +160,10 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value); %lex-param {glcpp_parser_t *parser} %expect 0 -%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH HASH_DEFINE_FUNC HASH_DEFINE_OBJ HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF HASH_LINE HASH_UNDEF HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE +%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH HASH_DEFINE FUNC_IDENTIFIER OBJ_IDENTIFIER HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF HASH_LINE HASH_UNDEF HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE %token PASTE %type <ival> expression INTEGER operator SPACE integer_constant -%type <str> IDENTIFIER INTEGER_STRING OTHER +%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER %type <string_list> identifier_list %type <token> preprocessing_token conditional_token %type <token_list> pp_tokens replacement_list text_line conditional_tokens @@ -227,13 +227,13 @@ expanded_line: ; control_line: - HASH_DEFINE_OBJ IDENTIFIER replacement_list NEWLINE { + HASH_DEFINE OBJ_IDENTIFIER replacement_list NEWLINE { _define_object_macro (parser, & @2, $2, $3); } -| HASH_DEFINE_FUNC IDENTIFIER '(' ')' replacement_list NEWLINE { +| HASH_DEFINE FUNC_IDENTIFIER '(' ')' replacement_list NEWLINE { _define_function_macro (parser, & @2, $2, NULL, $5); } -| HASH_DEFINE_FUNC IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE { +| HASH_DEFINE FUNC_IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE { _define_function_macro (parser, & @2, $2, $4, $6); } | HASH_UNDEF IDENTIFIER NEWLINE { @@ -1843,7 +1843,7 @@ glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) if (ret == NEWLINE) parser->in_control_line = 0; } - else if (ret == HASH_DEFINE_OBJ || ret == HASH_DEFINE_FUNC || + else if (ret == HASH_DEFINE || ret == HASH_UNDEF || ret == HASH_IF || ret == HASH_IFDEF || ret == HASH_IFNDEF || ret == HASH_ELIF || ret == HASH_ELSE || |