forward declaration of a struct typedef

E

eliben

Hello,

I'm working on a parser for ANSI C (http://code.google.com/p/
pycparser/), and it was reported that the parser chokes on the
following code:

typedef struct tagEntry tagEntry;
struct tagEntry
{
char* key;
char* value;
} Entry;

The reason for its choking is that the first line defines tagEntry as
a type, and the parser then can't parse the struct declaration
correctly, because following the C grammar (as defined in K&R2), a
known type can't follow the keyword 'struct', but only an identifier.

Is this correct? GCC seems to parse this just fine, why is that?

Thanks in advance
Eli
 
F

Fred

Hello,

I'm working on a parser for ANSI C (http://code.google.com/p/
pycparser/), and it was reported that the parser chokes on the
following code:

typedef struct tagEntry tagEntry;
struct tagEntry
{
    char* key;
    char* value;

} Entry;

The reason for its choking is that the first line defines tagEntry as
a type, and the parser then can't parse the struct declaration
correctly, because following the C grammar (as defined in K&R2), a
known type can't follow the keyword 'struct', but only an identifier.

Is this correct? GCC seems to parse this just fine, why is that?

Why bother with the "forward declaration"? Why not just:
typedef struct tagEntry
{
char* key;
char* value;
} tagEntry;

Then later create an instance:
tagEntry Entry;
 
C

crisgoogle

Why bother with the "forward declaration"? Why not just:
typedef struct tagEntry
{
char* key;
char* value;
} tagEntry;

Then later create an instance:
tagEntry Entry;


I don't think that was Eli's point. Since he's working on a parser,
I believe he's more concerned about whether his code, as presented,
_should_ work.

And it should. Struct tags and typedefs are in different namespaces
so there should be no conflict in his struct declaration.

Cris
 
S

swengineer001

Hello,

I'm working on a parser for ANSI C (http://code.google.com/p/
pycparser/), and it was reported that the parser chokes on the
following code:

typedef struct tagEntry tagEntry;
struct tagEntry
{
    char* key;
    char* value;

} Entry;

The reason for its choking is that the first line defines tagEntry as
a type, and the parser then can't parse the struct declaration
correctly, because following the C grammar (as defined in K&R2), a
known type can't follow the keyword 'struct', but only an identifier.

Is this correct? GCC seems to parse this just fine, why is that?

Thanks in advance
Eli

I think you have two identifiers with the same name but different
namespaces based on the following from the standard:

Section 6.1.2

"An identifier can denote an object, a function, or one
of the following entities that will be described later: a
tag or a member of a structure, union, or enumeration; a
typedef name; a label name; a macro name; or a macro
parameter."

and Section 6.1.2.3

"If more than one declaration of a particular identifier
is visible at any point in a translation unit, the syntactic
context disambiguates uses that refer to different entities.
Thus, there are separate name spaces for various categories
of identifiers, as follows:

- label names (disambiguated by the syntax of the label
declaration and use);

- the tags of structures, unions, and enumerations
(disambiguated by following any23 of the keywords
struct, union, or enum);

- the members of structures or unions; each structure or
union has a separate name space for its members
(disambiguated by the type of the expression used to
access the member via the . or -> operator);

- all other identifiers, called ordinary identifiers
(declared in ordinary declarators or as enumeration
constants)."

Given this your parser needs to account for the context of

struct tagEntry
{
char* key;
char* value;

} Entry;
and recognize that following the keyword struct it is not looking for
a typedef name.
 
C

CBFalconer

eliben said:
I'm working on a parser for ANSI C (http://code.google.com/p/
pycparser/), and it was reported that the parser chokes on the
following code:

typedef struct tagEntry tagEntry;
struct tagEntry
{
char* key;
char* value;
} Entry;

The reason for its choking is that the first line defines tagEntry as
a type, and the parser then can't parse the struct declaration
correctly, because following the C grammar (as defined in K&R2), a
known type can't follow the keyword 'struct', but only an identifier.

Is this correct? GCC seems to parse this just fine, why is that?

It is wrong. The identifier after struct is not a member of the
main name table, but goes into a separate table. So there is no
confusion in an accurate compiler.
 
E

eliben

Annex A of the C99 standard, while not normative, also specifies an
(optional in some cases) identifier to be used after the 'struct'
keyword. The same Annex, as with 6.4.2.1, reduces identifiers to
their components of digit, nondigit, and so forth. We get identifiers
and keywords described as syntactical tokens, but you have to read
the standard to determine that there's a restriction on using keyword
tokens as identifier tokens in translation phases 7 and 8 (6.4.1{2}),
though they're allowed to be used as such in earlier translation phases
(7.1.2{4}). A type *can* follow the keyword 'struct', but a keyword
type *cannot*.

    struct tagEntry ... OK
    struct int      ... NOT OK


It's correct.

Thanks for (yours and the others') the answers. It's clear now, and
I'll fix my parser.

Eli
 
E

eliben

You're welcome, bro.

I'm guessing by the name that your parser is written in Python. Some of
us here dabble with Python, so feel free to post some Python code if
you encounter any other parsing difficulties. You could probably
cross-post to both comp.lang.python and comp.lang.c so we can get
a bit of a three-way happening.

I do not think c.l.c. would appreciate Python code, but nor is there a
need for it. The parser itself has little to do with Python's
specifics, because it's implemented with PLY - which is a Python port
of Lex and Yacc, so it's your old-n'good LexYaccy parser (just the
code is Python and not C, which is nice).

If you're interested, pycparser is open-source here: http://code.google.com/p/pycparser/

Apart from the random and obscure problem like the one I posted here,
it parses ANSI C89/90 successfully (including the stdio headers of
GCC).

Eli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top