From cc335c0e57a92fd78141894350607eca3622465a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 19 Jun 2014 11:57:06 -0700 Subject: [PATCH] glsl/glcpp: Add support for comments between #define and macro identifier The recent adddition of an error for "#define followed by a non-identifier" was a bit to aggressive since it used a regular expression in the lexer to flag any character that's not legal as the first character of an identifier. But we need to allow comments to appear here, (since we aren't removing comments in a preliminary pass). So we refine the error here to only flag characters that could not be an identifier, nor a comment, nor whitespace. We also augment the existing comment support to be active in the state as well. Reviewed-by: Jordan Justen --- src/glsl/glcpp/glcpp-lex.l | 38 ++++++++++++++++++- src/glsl/glcpp/tests/130-define-comment.c | 2 + .../glcpp/tests/130-define-comment.c.expected | 3 ++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/glsl/glcpp/tests/130-define-comment.c create mode 100644 src/glsl/glcpp/tests/130-define-comment.c.expected diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l index 0d4bfc8d443..a9801f4b6a4 100644 --- a/src/glsl/glcpp/glcpp-lex.l +++ b/src/glsl/glcpp/glcpp-lex.l @@ -161,7 +161,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? } /* Multi-line comments */ -"/*" { yy_push_state(COMMENT, yyscanner); } +"/*" { yy_push_state(COMMENT, yyscanner); } [^*\n]* [^*\n]*\n { yylineno++; yycolumn = 0; parser->commented_newlines++; } "*"+[^*/\n]* @@ -241,25 +241,59 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? glcpp_error(yylloc, yyextra, "#error%s", p); } + /* After we see a "#define" we enter the start state + * for the lexer. Within we are looking for the first + * identifier and specifically checking whether the identifier + * is followed by a '(' or not, (to lex either a + * FUNC_IDENTIFIER or an OBJ_IDENITIFIER token). + * + * While in the state we also need to explicitly + * handle a few other things that may appear before the + * identifier: + * + * * Comments, (handled above with the main support for + * comments). + * + * * Whitespace (simply ignored) + * + * * Anything else, (not an identifier, not a comment, + * and not whitespace). This will generate an error. + */ {HASH}define{HSPACE}+ { yyextra->space_tokens = 0; yy_push_state(DEFINE, yyscanner); return HASH_DEFINE; } + /* An identifier immediately followed by '(' */ {IDENTIFIER}/"(" { yy_pop_state(yyscanner); yylval->str = ralloc_strdup (yyextra, yytext); return FUNC_IDENTIFIER; } + /* An identifier not immediately followed by '(' */ {IDENTIFIER} { yy_pop_state(yyscanner); yylval->str = ralloc_strdup (yyextra, yytext); return OBJ_IDENTIFIER; } -[^_a-zA-Z]{NONSPACE}* { + /* Whitespace */ +{HSPACE}+ { + /* Just ignore it. Nothing to do here. */ +} + + /* '/' not followed by '*', so not a comment. This is an error. */ +[/][^*]{NONSPACE}* { + BEGIN INITIAL; + glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext); + return INTEGER_STRING; +} + + /* A character that can't start an identifier, comment, or + * space. This is an error. */ +[^_a-zA-Z/[:space:]]{NONSPACE}* { BEGIN INITIAL; glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext); return INTEGER_STRING; diff --git a/src/glsl/glcpp/tests/130-define-comment.c b/src/glsl/glcpp/tests/130-define-comment.c new file mode 100644 index 00000000000..33312362cc7 --- /dev/null +++ b/src/glsl/glcpp/tests/130-define-comment.c @@ -0,0 +1,2 @@ +#define /*...*/ FUNC( /*...*/ x /*...*/ ) /*...*/ FOO( /*...*/ x /*...*/ ) +FUNC(bar) diff --git a/src/glsl/glcpp/tests/130-define-comment.c.expected b/src/glsl/glcpp/tests/130-define-comment.c.expected new file mode 100644 index 00000000000..ed59055e306 --- /dev/null +++ b/src/glsl/glcpp/tests/130-define-comment.c.expected @@ -0,0 +1,3 @@ + +FOO( bar ) + -- 2.30.2