diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-11-09 00:04:44 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-11-09 00:04:44 +0200 |
commit | 4d75955e833201c4f1d0219d48676521aeee1afa (patch) | |
tree | 56f03526c28bb6ee56d73a57915dc25592c7e47b | |
parent | b097ff86951b52a4e34bd0d7e40921e5469c4f5f (diff) | |
download | cflow-4d75955e833201c4f1d0219d48676521aeee1afa.tar.gz cflow-4d75955e833201c4f1d0219d48676521aeee1afa.tar.bz2 |
Fix parsing of typedefs after `struct'.
* src/c.l: Include cflow.h (and, consequently, config.h) at the top
of the generated source.
(prev_token): New static.
(get_token): Set prev_token.
(ident): Treat any valid identifier after struct/union/enum
as identifier (do not attempt any symbol lookup).
-rw-r--r-- | src/c.l | 38 |
1 files changed, 28 insertions, 10 deletions
@@ -13,20 +13,23 @@ You should have received a copy of the GNU General Public License along with GNU cflow; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +%top { +#include <cflow.h> +#include <ctype.h> +#include <parser.h> +} + %x comment %x string %x stringwait %x longline %{ -#include <cflow.h> -#include <ctype.h> -#include <parser.h> struct obstack string_stk; int line_num; char *filename; char *canonical_filename; @@ -34,12 +37,17 @@ YYSTYPE yylval; unsigned input_file_count; /* Number of input files, processed by source() */ int ident(); void update_loc(); #define lex_error(msg) error_at_line(0, 0, filename, line_num, "%s", msg) +/* Keep the token returned at the previous call to yylex. This is used + as a lexical tie-in to ensure that the next token after STRUCT is + IDENTIFIER. See get_token and ident below. */ +static int prev_token; + %} FILENAME [^\n*?]* ONUMBER (0[0-7]*) HNUMBER (0[xX][0-9a-fA-F]*) DNUMBER ([1-9][0-9]*) DIGITS [0-9][0-9]* @@ -218,18 +226,26 @@ init_lex(int debug_level) sp->ref_line = NULL; } int ident() { - Symbol *sp; + /* Do not attempt any symbol table lookup if the previous token was + STRUCT. This helps properly parse constructs like: - sp = lookup(yytext); - if (sp && sp->type == SymToken) { - yylval.str = sp->name; - return sp->token_type; + typedef struct foo foo; + struct foo { + int dummy; + }; + */ + if (prev_token != STRUCT) { + Symbol *sp = lookup(yytext); + if (sp && sp->type == SymToken) { + yylval.str = sp->name; + return sp->token_type; + } } obstack_grow(&string_stk, yytext, yyleng); obstack_1grow(&string_stk, 0); yylval.str = obstack_finish(&string_stk); return IDENTIFIER; } @@ -317,22 +333,24 @@ yywrap() if (preprocess_option) pp_close(yyin); else fclose(yyin); yyin = NULL; #ifdef FLEX_SCANNER - yy_delete_buffer(yy_current_buffer); + yy_delete_buffer(YY_CURRENT_BUFFER); #endif delete_statics(); return 1; } int get_token() { - return yyin ? yylex() : 0; + int tok = yylex(); + prev_token = tok; + return tok; } int source(char *name) { FILE *fp; |