mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 17:30:20 +01:00
Fix parsing of object-like macro with a definition that begins with '('.
Previously our parser was incorrectly treating this case as a function-like macro. We fix this by conditionally passing a SPACE token from the lexer, (but only immediately after the identifier immediately after #define).
This commit is contained in:
parent
67c27afc16
commit
0a93cbbe4f
2 changed files with 60 additions and 17 deletions
45
glcpp-lex.l
45
glcpp-lex.l
|
|
@ -32,6 +32,9 @@
|
|||
%option reentrant noyywrap
|
||||
%option extra-type="glcpp_parser_t *"
|
||||
|
||||
%x ST_DEFINE
|
||||
%x ST_DEFVAL
|
||||
|
||||
SPACE [[:space:]]
|
||||
NONSPACE [^[:space:]]
|
||||
NEWLINE [\n]
|
||||
|
|
@ -42,16 +45,42 @@ TOKEN [^[:space:](),]+
|
|||
|
||||
%%
|
||||
|
||||
{HASH}define{HSPACE}* {
|
||||
return DEFINE;
|
||||
}
|
||||
|
||||
{HASH}undef{HSPACE}* {
|
||||
{HASH}undef{HSPACE}* {
|
||||
return UNDEF;
|
||||
}
|
||||
|
||||
/* We use the ST_DEFINE and ST_DEFVAL states so that we can
|
||||
* pass a space token, (yes, a token for whitespace!), since
|
||||
* the preprocessor specification requires distinguishing
|
||||
* "#define foo()" from "#define foo ()".
|
||||
*/
|
||||
{HASH}define{HSPACE}* {
|
||||
BEGIN ST_DEFINE;
|
||||
return DEFINE;
|
||||
}
|
||||
|
||||
{IDENTIFIER} {
|
||||
<ST_DEFINE>{IDENTIFIER} {
|
||||
BEGIN ST_DEFVAL;
|
||||
yylval.str = xtalloc_strdup (yyextra, yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
||||
<ST_DEFVAL>\n {
|
||||
BEGIN INITIAL;
|
||||
return NEWLINE;
|
||||
}
|
||||
|
||||
<ST_DEFVAL>{HSPACE}+ {
|
||||
BEGIN INITIAL;
|
||||
return SPACE;
|
||||
}
|
||||
|
||||
<ST_DEFVAL>"(" {
|
||||
BEGIN INITIAL;
|
||||
return '(';
|
||||
}
|
||||
|
||||
{IDENTIFIER} {
|
||||
yylval.str = xtalloc_strdup (yyextra, yytext);
|
||||
switch (glcpp_parser_macro_type (yyextra, yylval.str))
|
||||
{
|
||||
|
|
@ -67,7 +96,9 @@ TOKEN [^[:space:](),]+
|
|||
}
|
||||
}
|
||||
|
||||
[(),] { return yytext[0]; }
|
||||
[(),] {
|
||||
return yytext[0];
|
||||
}
|
||||
|
||||
{TOKEN} {
|
||||
yylval.str = xtalloc_strdup (yyextra, yytext);
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ _list_append_list (list_t *list, list_t *tail);
|
|||
%parse-param {glcpp_parser_t *parser}
|
||||
%lex-param {void *scanner}
|
||||
|
||||
%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO TOKEN UNDEF
|
||||
%type <str> FUNC_MACRO IDENTIFIER OBJ_MACRO TOKEN string
|
||||
%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO SPACE TOKEN UNDEF
|
||||
%type <str> FUNC_MACRO IDENTIFIER OBJ_MACRO TOKEN word word_or_symbol
|
||||
%type <list> argument argument_list parameter_list replacement_list
|
||||
|
||||
%%
|
||||
|
|
@ -105,9 +105,10 @@ content:
|
|||
}
|
||||
| macro
|
||||
| directive_with_newline
|
||||
| NEWLINE {
|
||||
printf ("\n");
|
||||
}
|
||||
| NEWLINE { printf ("\n"); }
|
||||
| '(' { printf ("("); }
|
||||
| ')' { printf (")"); }
|
||||
| ',' { printf (","); }
|
||||
;
|
||||
|
||||
macro:
|
||||
|
|
@ -135,7 +136,7 @@ argument:
|
|||
/* empty */ {
|
||||
$$ = _list_create (parser);
|
||||
}
|
||||
| argument string {
|
||||
| argument word {
|
||||
_list_append_item ($1, $2);
|
||||
talloc_free ($2);
|
||||
}
|
||||
|
|
@ -149,8 +150,12 @@ directive_with_newline:
|
|||
;
|
||||
|
||||
directive:
|
||||
DEFINE IDENTIFIER replacement_list {
|
||||
_define_object_macro (parser, $2, $3);
|
||||
DEFINE IDENTIFIER {
|
||||
list_t *list = _list_create (parser);
|
||||
_define_object_macro (parser, $2, list);
|
||||
}
|
||||
| DEFINE IDENTIFIER SPACE replacement_list {
|
||||
_define_object_macro (parser, $2, $4);
|
||||
}
|
||||
| DEFINE IDENTIFIER '(' parameter_list ')' replacement_list {
|
||||
_define_function_macro (parser, $2, $4, $6);
|
||||
|
|
@ -183,7 +188,7 @@ replacement_list:
|
|||
/* empty */ {
|
||||
$$ = _list_create (parser);
|
||||
}
|
||||
| replacement_list string {
|
||||
| replacement_list word_or_symbol {
|
||||
_list_append_item ($1, $2);
|
||||
talloc_free ($2);
|
||||
$$ = $1;
|
||||
|
|
@ -206,7 +211,14 @@ parameter_list:
|
|||
}
|
||||
;
|
||||
|
||||
string:
|
||||
word_or_symbol:
|
||||
word { $$ = $1; }
|
||||
| '(' { $$ = xtalloc_strdup (parser, "("); }
|
||||
| ')' { $$ = xtalloc_strdup (parser, ")"); }
|
||||
| ',' { $$ = xtalloc_strdup (parser, ","); }
|
||||
;
|
||||
|
||||
word:
|
||||
IDENTIFIER { $$ = $1; }
|
||||
| FUNC_MACRO { $$ = $1; }
|
||||
| OBJ_MACRO { $$ = $1; }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue