
On Sun, 2005-12-11 at 22:54 +1100, Manuel M T Chakravarty wrote:
Duncan Coutts:
On Fri, 2005-12-09 at 11:23 +0000, Duncan Coutts wrote:
However the change to the grammar to make this possible is non-trivial.
The grammar I was working from originally makes the same mistake. http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
The gcc grammar has a very complex way of partitioning the typedef and non-typedef cases to allow a typedefed name to be reused as an identifier in the right context.
I'm still looking into it.
I've spent quite some time trying to fix this using the gcc grammar as a guide however I can't make a grammar that is free of reduce/reduce conflicts.
What did you try to do? Adding a new case to the direct_declarator definition that parses a `typedef' instead of an `ident'?
That leads to 7 extra shift/reduce conflicts. The reason for the extra conflicts is that in allowing tyidents we are actually making the grammar too general. We should only allow tyidents in a direct_declarator if we have not already seen a type specifier earlier in the declaration. The gcc grammar has a note about it's "typed_declspecs" production: /* Declspecs which contain at least one type specifier or typedef name. (Just `const' or `volatile' is not enough.) A typedef'd name following these is taken as a name to be declared. */ It then partitions the grammar so we can have a decl that has a type specifier name at the beginning (typed_declspecs) followed by initdecls that may not contain a typedef name. Or it can have a decl that does not contain a type specifer followed by initdecls which may not contain a typedef name (notype_initdecls): decl: typed_declspecs setspecs initdecls ';' | declmods setspecs notype_initdecls ';' typed_declspecs: typespec reserved_declspecs | declmods typespec reserved_declspecs Then after this each production comes in two forms: initdecls: initdcl | initdecls ',' initdcl notype_initdecls: notype_initdcl | notype_initdecls ',' initdcl initdcl: declarator '=' init | declarator notype_initdcl: notype_declarator '=' init | notype_declarator An ordinary declarator can have either typedef names or non-typedef names, but the notype_initdcl can only have non-typedef names. declarator: after_type_declarator | notype_declarator after_type_declarator: ... | TYPENAME notype_declarator: ... | IDENTIFIER I've tried to use this technique but the details are tricky to follow and all my attempts so far end up with reduce/reduce ambiguities in the grammar. Duncan