summaryrefslogtreecommitdiffstats
path: root/src/glsl/glcpp/glcpp-lex.l
diff options
context:
space:
mode:
authorCarl Worth <[email protected]>2014-06-19 11:57:06 -0700
committerCarl Worth <[email protected]>2014-07-29 15:11:48 -0700
commitcc335c0e57a92fd78141894350607eca3622465a (patch)
treed205bcd9ea62081d67a3bd74e6054d917eff42bf /src/glsl/glcpp/glcpp-lex.l
parentea2e9300ece89dffdc4a228dc86bea28a7cd58e2 (diff)
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 <DEFINE> state as well. Reviewed-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src/glsl/glcpp/glcpp-lex.l')
-rw-r--r--src/glsl/glcpp/glcpp-lex.l38
1 files changed, 36 insertions, 2 deletions
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); }
+<DEFINE,INITIAL>"/*" { yy_push_state(COMMENT, yyscanner); }
<COMMENT>[^*\n]*
<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; parser->commented_newlines++; }
<COMMENT>"*"+[^*/\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 <DEFINE> start state
+ * for the lexer. Within <DEFINE> 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 <DEFINE> 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 '(' */
<DEFINE>{IDENTIFIER}/"(" {
yy_pop_state(yyscanner);
yylval->str = ralloc_strdup (yyextra, yytext);
return FUNC_IDENTIFIER;
}
+ /* An identifier not immediately followed by '(' */
<DEFINE>{IDENTIFIER} {
yy_pop_state(yyscanner);
yylval->str = ralloc_strdup (yyextra, yytext);
return OBJ_IDENTIFIER;
}
-<DEFINE>[^_a-zA-Z]{NONSPACE}* {
+ /* Whitespace */
+<DEFINE>{HSPACE}+ {
+ /* Just ignore it. Nothing to do here. */
+}
+
+ /* '/' not followed by '*', so not a comment. This is an error. */
+<DEFINE>[/][^*]{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. */
+<DEFINE>[^_a-zA-Z/[:space:]]{NONSPACE}* {
BEGIN INITIAL;
glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext);
return INTEGER_STRING;