%option extra-type="glcpp_parser_t *"
%x ST_DEFINE
-%x ST_DEFVAL
+%x ST_UNDEF
SPACE [[:space:]]
NONSPACE [^[:space:]]
<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);
%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
_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);
}
;