Go to the first, previous, next, last section, table of contents.


Parser

Some comments on the parser:

The after_type_declarator / notype_declarator hack is necessary in order to allow redeclarations of TYPENAMEs, for instance

typedef int foo;
class A {
  char *foo;
};

In the above, the first foo is parsed as a notype_declarator, and the second as a after_type_declarator.

Ambiguities:

There are currently four reduce/reduce ambiguities in the parser. They are:

1) Between template_parm and named_class_head_sans_basetype, for the tokens aggr identifier. This situation occurs in code looking like

template <class T> class A { };

It is ambiguous whether class T should be parsed as the declaration of a template type parameter named T or an unnamed constant parameter of type class T. Section 14.6, paragraph 3 of the January '94 working paper states that the first interpretation is the correct one. This ambiguity results in two reduce/reduce conflicts.

2) Between primary and type_id for code like `int()' in places where both can be accepted, such as the argument to sizeof. Section 8.1 of the pre-San Diego working paper specifies that these ambiguous constructs will be interpreted as typenames. This ambiguity results in six reduce/reduce conflicts between `absdcl' and `functional_cast'.

3) Between functional_cast and complex_direct_notype_declarator, for various token strings. This situation occurs in code looking like

int (*a);

This code is ambiguous; it could be a declaration of the variable `a' as a pointer to `int', or it could be a functional cast of `*a' to `int'. Section 6.8 specifies that the former interpretation is correct. This ambiguity results in 7 reduce/reduce conflicts. Another aspect of this ambiguity is code like 'int (x[2]);', which is resolved at the '[' and accounts for 6 reduce/reduce conflicts between `direct_notype_declarator' and `primary'/`overqualified_id'. Finally, there are 4 r/r conflicts between `expr_or_declarator' and `primary' over code like 'int (a);', which could probably be resolved but would also probably be more trouble than it's worth. In all, this situation accounts for 17 conflicts. Ack!

The second case above is responsible for the failure to parse 'LinppFile ppfile (String (argv[1]), &outs, argc, argv);' (from Rogue Wave Math.h++) as an object declaration, and must be fixed so that it does not resolve until later.

4) Indirectly between after_type_declarator and parm, for type names. This occurs in (as one example) code like

typedef int foo, bar;
class A {
  foo (bar);
};

What is bar inside the class definition? We currently interpret it as a parm, as does Cfront, but IBM xlC interprets it as an after_type_declarator. I believe that xlC is correct, in light of 7.1p2, which says "The longest sequence of decl-specifiers that could possibly be a type name is taken as the decl-specifier-seq of a declaration." However, it seems clear that this rule must be violated in the case of constructors. This ambiguity accounts for 8 conflicts.

Unlike the others, this ambiguity is not recognized by the Working Paper.


Go to the first, previous, next, last section, table of contents.