diff options
author | Carl Worth <cworth@cworth.org> | 2010-05-12 13:11:50 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2010-05-12 13:11:50 -0700 |
commit | cd27e6413a683d3ba1763ec68edfb1ff13193fc3 (patch) | |
tree | 0d331b3446bc56f18f4003e90e8657fcc8b73dbe | |
parent | 7bdd1f36d9f238e6af4846d46b9dd30fffc772a5 (diff) |
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).
-rw-r--r-- | glcpp-lex.l | 19 | ||||
-rw-r--r-- | glcpp-parse.y | 26 |
2 files changed, 39 insertions, 6 deletions
diff --git a/glcpp-lex.l b/glcpp-lex.l index ec91538a73..9ec4deb718 100644 --- a/glcpp-lex.l +++ b/glcpp-lex.l @@ -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); diff --git a/glcpp-parse.y b/glcpp-parse.y index 1a7ec4970d..29614fb1a4 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -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); } ; |