Add support for the #undef macro.
authorCarl Worth <cworth@cworth.org>
Wed, 12 May 2010 20:11:50 +0000 (13:11 -0700)
committerCarl Worth <cworth@cworth.org>
Wed, 12 May 2010 20:11:50 +0000 (13:11 -0700)
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).

glcpp-lex.l
glcpp-parse.y

index ec91538a73cc9a4b9e9ba4dc8168ae9721d5ae33..9ec4deb7185a30a38f4e8aa65d9283593a96ebaa 100644 (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);
index 1a7ec4970d5ae270c3fa76eaac921462972f6cbb..29614fb1a4dbe51314db1673e34a41a80b65ba61 100644 (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);
        }
 ;