[C2hs] A problem parsing a C header

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Sun Dec 11 07:37:51 EST 2005


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



More information about the C2hs mailing list