diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-09-21 15:12:15 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-09-21 15:12:15 +0000 |
commit | 8dcd4f4af1fd1068f35839bd8fe5f1f2849d33c3 (patch) | |
tree | 5d4324ad5bfdf1966b5c204328e2ed09328df007 /src | |
parent | 153040933c1b97eda6707cd0316eed8fa73f1c16 (diff) | |
download | cflow-8dcd4f4af1fd1068f35839bd8fe5f1f2849d33c3.tar.gz cflow-8dcd4f4af1fd1068f35839bd8fe5f1f2849d33c3.tar.bz2 |
(parse_variable_declaration,parse_variable_declaration): Take an
extra argument indicating whether we are handling function
parameters. All uses changed.
(parse_variable_declaration,maybe_parm_list): Add error recovery.
(func_body): Handle static symbols separately.
(declare): Fix condition of declaring a function definition.
(reference): Update caller list as well.
Diffstat (limited to 'src')
-rw-r--r-- | src/parser.c | 88 |
1 files changed, 66 insertions, 22 deletions
diff --git a/src/parser.c b/src/parser.c index d0a7f32..b32b652 100644 --- a/src/parser.c +++ b/src/parser.c @@ -27,8 +27,8 @@ typedef struct { enum storage storage; } Ident; -void parse_declaration(Ident*); -void parse_variable_declaration(Ident*); +void parse_declaration(Ident*, int); +void parse_variable_declaration(Ident*, int); void parse_function_declaration(Ident*); void parse_dcl(Ident*); void parse_knr_dcl(Ident*); @@ -298,13 +298,13 @@ yyparse() break; case EXTERN: identifier.storage = ExplicitExternStorage; - parse_declaration(&identifier); + parse_declaration(&identifier, 0); break; case STATIC: identifier.storage = StaticStorage; /* FALLTHRU */ default: - parse_declaration(&identifier); + parse_declaration(&identifier, 0); break; } cleanup_stack(); @@ -336,12 +336,12 @@ is_function() } void -parse_declaration(Ident *ident) +parse_declaration(Ident *ident, int parm) { if (is_function()) parse_function_declaration(ident); else - parse_variable_declaration(ident); + parse_variable_declaration(ident, parm); } @@ -411,14 +411,22 @@ parse_function_declaration(Ident *ident) { ident->type_end = -1; parse_knr_dcl(ident); - + int error_recovery = 0; + + restart: switch (tok.type) { default: - if (verbose) - file_error(_("expected `;'"), 1); - putback(); - /* FALLTHRU */ + if (error_recovery) + nexttoken(); + else { + if (verbose) + file_error(_("expected `;'"), 1); + error_recovery = 1; + } + goto restart; + case ';': + case ',': break; case LBRACE0: case LBRACE: @@ -467,7 +475,7 @@ fake_struct(Ident *ident) } void -parse_variable_declaration(Ident *ident) +parse_variable_declaration(Ident *ident, int parm) { Stackpos sp; @@ -503,14 +511,20 @@ parse_variable_declaration(Ident *ident) select: switch (tok.type) { + case ')': + if (parm) + break; + /*FALLTHROUGH*/ default: if (verbose) file_error(_("expected `;'"), 1); - /* should putback() here */ + /* FIXME: should putback() here */ /* FALLTHRU */ case ';': break; case ',': + if (parm) + break; tos = ident->type_end; restore(sp); goto again; @@ -810,6 +824,8 @@ void maybe_parm_list(int *parm_cnt_return) { int parmcnt = 0; + Ident ident; + int level; while (nexttoken()) { switch (tok.type) { case ')': @@ -818,14 +834,34 @@ maybe_parm_list(int *parm_cnt_return) return; case ',': break; - default: + case IDENTIFIER: + case STRUCT: + case UNION: + case ENUM: + case TYPE: parmcnt++; + ident.storage = AutoStorage; + parse_declaration(&ident, 1); putback(); - parmdcl(NULL); + break; + default: + if (verbose) + file_error(_("unexpected token in parameter list"), 1); + level = 0; + do { + if (tok.type == '(') + level++; + else if (tok.type == ')') { + if (level-- == 0) + break; + } + } while (nexttoken()); + ; putback(); } } - file_error(_("unexpected eof in parameter list"), 0); + if (verbose) + file_error(_("unexpected eof in parameter list"), 0); } void @@ -842,13 +878,17 @@ func_body() expression(); break; case STATIC: + ident.storage = StaticStorage; + parse_variable_declaration(&ident, 0); + break; case TYPE: + case STRUCT: ident.storage = AutoStorage; - parse_variable_declaration(&ident); + parse_variable_declaration(&ident, 0); break; case EXTERN: ident.storage = ExplicitExternStorage; - parse_declaration(&ident); + parse_declaration(&ident, 0); break; case LBRACE0: case '{': @@ -894,8 +934,8 @@ declare(Ident *ident) return; } - if ((ident->parmcnt >= 0 && tok.type == ';') || - (ident->parmcnt < 0 && ident->storage == ExplicitExternStorage)) { + if ((ident->parmcnt >= 0 && !(tok.type == LBRACE || tok.type == LBRACE0)) + || (ident->parmcnt < 0 && ident->storage == ExplicitExternStorage)) { /* add_external()?? */ return; } @@ -1015,7 +1055,11 @@ reference(char *name, int line) Symbol *sp = add_reference(name, line); if (!sp) return; - if (caller && !symbol_in_list(sp, caller->callee)) - append_to_list(&caller->callee, sp); + if (caller) { + if (!symbol_in_list(caller, sp->caller)) + append_to_list(&sp->caller, caller); + if (!symbol_in_list(sp, caller->callee)) + append_to_list(&caller->callee, sp); + } } |