[Mesa-dev] [PATCH] glcpp: Don't use infinite lookhead for #define differentiation.
Kenneth Graunke
kenneth at whitecape.org
Mon Oct 22 11:35:49 PDT 2012
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 <kenneth at whitecape.org>
---
src/glsl/glcpp/glcpp-lex.l | 20 ++++++++++++++------
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 7ab58cb..783c545 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 fb9bc58..ffb48e3 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 ||
--
1.7.12.3
More information about the mesa-dev
mailing list