<ST_DEFINE_PARAMETER>{HSPACE}+
<ST_DEFINE_VALUE>{TOKEN} {
- yylval.str = xtalloc_strdup (yyextra, yytext);
+ yylval.token.type = TOKEN;
+ yylval.token.value = xtalloc_strdup (yyextra, yytext);
return TOKEN;
}
<ST_DEFINE_VALUE>[(),] {
- yylval.str = xtalloc_strdup (yyextra, yytext);
+ yylval.token.type = TOKEN;
+ yylval.token.value = xtalloc_strdup (yyextra, yytext);
return TOKEN;
}
case TOKEN_CLASS_IDENTIFIER:
return IDENTIFIER;
break;
+ case TOKEN_CLASS_IDENTIFIER_FINALIZED:
+ return IDENTIFIER_FINALIZED;
+ break;
case TOKEN_CLASS_FUNC_MACRO:
return FUNC_MACRO;
break;
}
{TOKEN} {
- yylval.str = xtalloc_strdup (yyextra, yytext);
+ yylval.token.type = TOKEN;
+ yylval.token.value = xtalloc_strdup (yyextra, yytext);
return TOKEN;
}
char *str;
argument_list_t *argument_list;
string_list_t *string_list;
+ token_t token;
token_list_t *token_list;
}
%parse-param {glcpp_parser_t *parser}
%lex-param {glcpp_parser_t *parser}
-%token DEFINE FUNC_MACRO IDENTIFIER OBJ_MACRO NEWLINE SPACE TOKEN UNDEF
-%type <str> argument_word FUNC_MACRO IDENTIFIER OBJ_MACRO TOKEN
+%token DEFINE FUNC_MACRO IDENTIFIER IDENTIFIER_FINALIZED OBJ_MACRO NEWLINE SPACE TOKEN UNDEF
+%type <str> FUNC_MACRO IDENTIFIER IDENTIFIER_FINALIZED OBJ_MACRO
%type <argument_list> argument_list
%type <string_list> macro parameter_list
+%type <token> TOKEN argument_word
%type <token_list> argument replacement_list pp_tokens
/* Hard to remove shift/reduce conflicts documented as follows:
printf ("%s", $1);
talloc_free ($1);
}
-| TOKEN {
+| IDENTIFIER_FINALIZED {
printf ("%s", $1);
talloc_free ($1);
}
+| TOKEN {
+ printf ("%s", $1.value);
+ talloc_free ($1.value);
+ }
| FUNC_MACRO {
printf ("%s", $1);
talloc_free ($1);
argument:
argument_word {
$$ = _token_list_create (parser);
- _token_list_append ($$, IDENTIFIER, $1);
+ _token_list_append ($$, $1.type, $1.value);
}
| argument argument_word {
- _token_list_append ($1, IDENTIFIER, $2);
- talloc_free ($2);
+ _token_list_append ($1, $2.type, $2.value);
+ talloc_free ($2.value);
$$ = $1;
}
| argument '(' argument ')' {
;
argument_word:
- IDENTIFIER { $$ = $1; }
+ IDENTIFIER { $$.type = IDENTIFIER; $$.value = $1; }
+| IDENTIFIER_FINALIZED { $$.type = IDENTIFIER_FINALIZED; $$.value = $1; }
| TOKEN { $$ = $1; }
-| FUNC_MACRO { $$ = $1; }
-| macro { $$ = xtalloc_strdup (parser, ""); }
+| FUNC_MACRO { $$.type = FUNC_MACRO; $$.value = $1; }
+| macro { $$.type = TOKEN; $$.value = xtalloc_strdup (parser, ""); }
;
pp_tokens:
TOKEN {
$$ = _token_list_create (parser);
- _token_list_append ($$, TOKEN, $1);
+ _token_list_append ($$, $1.type, $1.value);
}
| pp_tokens TOKEN {
- _token_list_append ($1, TOKEN, $2);
+ _token_list_append ($1, $2.type, $2.value);
$$ = $1;
}
;
/* Don't consider this a macro if we are already actively
* expanding this macro. */
if (glcpp_parser_is_expanding (parser, identifier))
- return TOKEN_CLASS_IDENTIFIER;
+ return TOKEN_CLASS_IDENTIFIER_FINALIZED;
/* Definitely a macro. Just need to check if it's function-like. */
if (macro->is_function)
yylval.str = xtalloc_strdup (parser, replacements->value);
+ /* Carefully refuse to expand any finalized identifier. */
+ if (replacements->type == IDENTIFIER_FINALIZED)
+ return IDENTIFIER_FINALIZED;
+
switch (glcpp_parser_classify_token (parser, yylval.str,
¶meter_index))
{
case TOKEN_CLASS_IDENTIFIER:
return IDENTIFIER;
break;
+ case TOKEN_CLASS_IDENTIFIER_FINALIZED:
+ return IDENTIFIER_FINALIZED;
+ break;
case TOKEN_CLASS_FUNC_MACRO:
return FUNC_MACRO;
break;