next up previous
Next: Constants Up: Lexical structure Previous: Keywords


Identifiers

There is a well-known ambiguity in C, resulting from the fact that ordinary identifiers can be type specifiers. It is illustrated by the line:

A (*B);

If A has been defined as a type name, then the line is a declaration of a variable B to be of type ``pointer to A''. (The parentheses surrounding ``*B'' are ignored - see Section 6.5.4 of the standard.) If A has not been defined as a type name, then the line is a call of the function A with the single parameter *B. This ambiguity cannot be resolved by the grammar, since the two constructs can appear in the same contexts.

This specification resolves the ambiguity via an interaction between the scanner and the parser, as described in Section 1.3. When an identifier defined as a type name is used, the scanner reports it as the token typedef_name (Standard, Section 6.5.2).

The semantic analysis task can be simplified if identifiers in two other contexts (definition of a type name and definition of a struct or union member) can also be given distinct tokens. Since the scanner/parser interaction mechanism must be in place to resolve the type name ambiguity, this distinction can be added at very little cost.

Lexical elements[2]:

identifier:   C_IDENTIFIER [IdnOrType]
typedef_name: C_IDENTIFIER
typedef_def:  C_IDENTIFIER
member_def:   C_IDENTIFIER
This macro is defined in definitions 2, 4, and 5.
This macro is invoked in definition 1.

Note that all of these tokens have exactly the same lexical structure. The ambiguity resolution rules of Eli guarantee that the token processor IdnOrType will be invoked after each character sequence satisfying this definition has been recognized. IdnOrType will then classify the sequence. Details can be found in Section 1.3


next up previous
Next: Constants Up: Lexical structure Previous: Keywords
2008-08-30