Mesa (master): glcpp: Don' t use infinite lookhead for #define differentiation.

Kenneth Graunke kwg at kemper.freedesktop.org
Thu Oct 25 21:54:55 UTC 2012


Module: Mesa
Branch: master
Commit: 9142ade15416415f2d5eb20b093b898c649cd2bb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9142ade15416415f2d5eb20b093b898c649cd2bb

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Mon Oct 22 10:56:46 2012 -0700

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 <kenneth at whitecape.org>
Reviewed-by: Carl Worth <cworth at cworth.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 ||




More information about the mesa-commit mailing list