Add support for the #undef macro.

This isn't ideal for two reasons:

1. There's a bunch of stateful redundancy in the lexer that should be
   cleaned up.

2. The hash table does not provide a mechanism to delete an entry, so
   we waste memory to add a new NULL entry in front of the existing
   entry with the same key.

But this does at least work, (it passes the recently added undef test
case).
This commit is contained in:
Carl Worth 2010-05-12 13:11:50 -07:00
parent 7bdd1f36d9
commit cd27e6413a
2 changed files with 39 additions and 6 deletions

View file

@ -33,7 +33,7 @@
%option extra-type="glcpp_parser_t *"
%x ST_DEFINE
%x ST_DEFVAL
%x ST_UNDEF
SPACE [[:space:]]
NONSPACE [^[:space:]]
@ -67,6 +67,23 @@ TOKEN {NONSPACE}+
<ST_DEFINE>{SPACE}+
{HASH}undef{HSPACE}* {
BEGIN ST_UNDEF;
return UNDEF;
}
<ST_UNDEF>{IDENTIFIER} {
yylval.str = xtalloc_strdup (yyextra, yytext);
return IDENTIFIER;
}
<ST_UNDEF>\n {
BEGIN INITIAL;
return NEWLINE;
}
<ST_UNDEF>{SPACE}+
/* Anything we don't specifically recognize is a stream of tokens */
{NONSPACE}+ {
yylval.str = xtalloc_strdup (yyextra, yytext);

View file

@ -57,7 +57,7 @@ _list_append (list_t *list, const char *str);
%parse-param {glcpp_parser_t *parser}
%lex-param {void *scanner}
%token DEFINE IDENTIFIER NEWLINE TOKEN
%token DEFINE IDENTIFIER NEWLINE TOKEN UNDEF
%type <str> token IDENTIFIER TOKEN
%type <list> replacement_list
@ -73,19 +73,35 @@ content:
_print_resolved_token (parser, $1);
talloc_free ($1);
}
| directive
| directive_with_newline
| content token {
_print_resolved_token (parser, $2);
talloc_free ($2);
}
| content directive
| content directive_with_newline
;
directive_with_newline:
directive NEWLINE {
printf ("\n");
}
;
directive:
DEFINE IDENTIFIER replacement_list NEWLINE {
DEFINE IDENTIFIER replacement_list {
talloc_steal ($3, $2);
hash_table_insert (parser->defines, $3, $2);
printf ("\n");
}
| UNDEF IDENTIFIER {
list_t *replacement = hash_table_find (parser->defines, $2);
if (replacement) {
/* XXX: Need hash table to support a real way
* to remove an element rather than prefixing
* a new node with data of NULL like this. */
hash_table_insert (parser->defines, NULL, $2);
talloc_free (replacement);
}
talloc_free ($2);
}
;