aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-11-09 00:04:44 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-11-09 00:04:44 +0200
commit4d75955e833201c4f1d0219d48676521aeee1afa (patch)
tree56f03526c28bb6ee56d73a57915dc25592c7e47b
parentb097ff86951b52a4e34bd0d7e40921e5469c4f5f (diff)
downloadcflow-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.l38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/c.l b/src/c.l
index 05f2d6e..d64c8f1 100644
--- a/src/c.l
+++ b/src/c.l
@@ -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;

Return to:

Send suggestions and report system problems to the System administrator.