diff options
-rw-r--r-- | glcpp-lex.l | 41 | ||||
-rw-r--r-- | glcpp-parse.y | 32 |
2 files changed, 58 insertions, 15 deletions
diff --git a/glcpp-lex.l b/glcpp-lex.l index c6e545aa8e..3c9dda46d4 100644 --- a/glcpp-lex.l +++ b/glcpp-lex.l @@ -32,6 +32,9 @@ %option reentrant noyywrap %option extra-type="glcpp_parser_t *" +%x ST_DEFINE +%x ST_DEFVAL + SPACE [[:space:]] NONSPACE [^[:space:]] NEWLINE [\n] @@ -42,16 +45,42 @@ TOKEN [^[:space:](),]+ %% -{HASH}define{HSPACE}* { +{HASH}undef{HSPACE}* { + return UNDEF; +} + + /* We use the ST_DEFINE and ST_DEFVAL states so that we can + * pass a space token, (yes, a token for whitespace!), since + * the preprocessor specification requires distinguishing + * "#define foo()" from "#define foo ()". + */ +{HASH}define{HSPACE}* { + BEGIN ST_DEFINE; return DEFINE; } -{HASH}undef{HSPACE}* { - return UNDEF; +<ST_DEFINE>{IDENTIFIER} { + BEGIN ST_DEFVAL; + yylval.str = xtalloc_strdup (yyextra, yytext); + return IDENTIFIER; } +<ST_DEFVAL>\n { + BEGIN INITIAL; + return NEWLINE; +} + +<ST_DEFVAL>{HSPACE}+ { + BEGIN INITIAL; + return SPACE; +} -{IDENTIFIER} { +<ST_DEFVAL>"(" { + BEGIN INITIAL; + return '('; +} + +{IDENTIFIER} { yylval.str = xtalloc_strdup (yyextra, yytext); switch (glcpp_parser_macro_type (yyextra, yylval.str)) { @@ -67,7 +96,9 @@ TOKEN [^[:space:](),]+ } } -[(),] { return yytext[0]; } +[(),] { + return yytext[0]; +} {TOKEN} { yylval.str = xtalloc_strdup (yyextra, yytext); diff --git a/glcpp-parse.y b/glcpp-parse.y index 66725db69e..dc352de55b 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -83,8 +83,8 @@ _list_append_list (list_t *list, list_t *tail); %parse-param {glcpp_parser_t *parser} %lex-param {void *scanner} -%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO TOKEN UNDEF -%type <str> FUNC_MACRO IDENTIFIER OBJ_MACRO TOKEN string +%token DEFINE FUNC_MACRO IDENTIFIER NEWLINE OBJ_MACRO SPACE TOKEN UNDEF +%type <str> FUNC_MACRO IDENTIFIER OBJ_MACRO TOKEN word word_or_symbol %type <list> argument argument_list parameter_list replacement_list %% @@ -105,9 +105,10 @@ content: } | macro | directive_with_newline -| NEWLINE { - printf ("\n"); - } +| NEWLINE { printf ("\n"); } +| '(' { printf ("("); } +| ')' { printf (")"); } +| ',' { printf (","); } ; macro: @@ -135,7 +136,7 @@ argument: /* empty */ { $$ = _list_create (parser); } -| argument string { +| argument word { _list_append_item ($1, $2); talloc_free ($2); } @@ -149,8 +150,12 @@ directive_with_newline: ; directive: - DEFINE IDENTIFIER replacement_list { - _define_object_macro (parser, $2, $3); + DEFINE IDENTIFIER { + list_t *list = _list_create (parser); + _define_object_macro (parser, $2, list); + } +| DEFINE IDENTIFIER SPACE replacement_list { + _define_object_macro (parser, $2, $4); } | DEFINE IDENTIFIER '(' parameter_list ')' replacement_list { _define_function_macro (parser, $2, $4, $6); @@ -183,7 +188,7 @@ replacement_list: /* empty */ { $$ = _list_create (parser); } -| replacement_list string { +| replacement_list word_or_symbol { _list_append_item ($1, $2); talloc_free ($2); $$ = $1; @@ -206,7 +211,14 @@ parameter_list: } ; -string: +word_or_symbol: + word { $$ = $1; } +| '(' { $$ = xtalloc_strdup (parser, "("); } +| ')' { $$ = xtalloc_strdup (parser, ")"); } +| ',' { $$ = xtalloc_strdup (parser, ","); } +; + +word: IDENTIFIER { $$ = $1; } | FUNC_MACRO { $$ = $1; } | OBJ_MACRO { $$ = $1; } |