diff --git a/src/parser.c b/src/parser.c index 7aa6598..8b6bb56 100644 --- a/src/parser.c +++ b/src/parser.c @@ -65,6 +65,7 @@ static int _identifier(C99 * c99); static int _identifier_list(C99 * c99); static int _parameter_type_list(C99 * c99); static int _parameter_declaration(C99 * c99); +static int _abstract_or_declarator(C99 * c99); static int _abstract_declarator(C99 * c99); static int _direct_abstract_declarator(C99 * c99); static int _assignment_expr(C99 * c99); @@ -604,8 +605,7 @@ static int _type_qualifier_list(C99 * c99) /* direct-declarator */ static int _direct_declarator(C99 * c99) - /* FIXME still recursive - * identifier + /* identifier * "(" declarator ")" * direct-declarator "[" (assignment-expression | "*") "]" * direct-declarator "(" parameter-type-list ")" @@ -714,15 +714,28 @@ static int _parameter_declaration(C99 * c99) fprintf(stderr, "DEBUG: %s()\n", __func__); #endif ret = _declaration_specifiers(c99); - /* FIXME ambiguity between declarator and abstract declarator */ - if(_parse_in_set(c99, c99set_abstract_declarator)) - ret |= _abstract_declarator(c99); - else if(_parse_in_set(c99, c99set_declarator)) - ret |= _declarator(c99); + if(_parse_in_set(c99, c99set_abstract_or_declarator)) + ret |= _abstract_or_declarator(c99); return ret; } +/* abstract-or-declarator */ +static int _abstract_or_declarator(C99 * c99) + /* pointer + * [ pointer ] (direct-declarator | abstract-direct-declarator) */ +{ + int ret = 0; + + if(_parse_in_set(c99, c99set_pointer)) + ret |= _pointer(c99); + if(_parse_is_code(c99, C99_CODE_IDENTIFIER)) + return ret | _direct_declarator(c99); + /* FIXME there is still an ambiguity with "(" */ + return ret | _direct_abstract_declarator(c99); +} + + /* abstract-declarator */ static int _abstract_declarator(C99 * c99) /* pointer diff --git a/src/sets/abstract_or_declarator.set b/src/sets/abstract_or_declarator.set new file mode 100644 index 0000000..967ab8f --- /dev/null +++ b/src/sets/abstract_or_declarator.set @@ -0,0 +1,2 @@ +#include "abstract_declarator.set" +#include "declarator.set" diff --git a/src/tokenset.c b/src/tokenset.c index 81da194..a5d0fb8 100644 --- a/src/tokenset.c +++ b/src/tokenset.c @@ -32,6 +32,16 @@ static TokenCode _c99set_abstract_declarator[] = TokenSet c99set_abstract_declarator = _c99set_abstract_declarator; +/* abstract_or_declarator */ +static TokenCode _c99set_abstract_or_declarator[] = +{ +#include "sets/abstract_or_declarator.set" + C99_CODE_NULL +}; + +TokenSet c99set_abstract_or_declarator = _c99set_abstract_or_declarator; + + /* assignment-expr */ static TokenCode _c99set_assignment_expr[] = { diff --git a/src/tokenset.h b/src/tokenset.h index e8d216c..75262f0 100644 --- a/src/tokenset.h +++ b/src/tokenset.h @@ -24,6 +24,7 @@ /* protected */ extern TokenSet c99set_abstract_declarator; +extern TokenSet c99set_abstract_or_declarator; extern TokenSet c99set_assignment_expr; extern TokenSet c99set_block_item; extern TokenSet c99set_block_item_list;