chekmate@athena.mit.edu (Adam Kao) (11/13/88)
I've been playing around with the (presumably) most recent ANSI C grammar. Right now I'm just building a parse tree, eventually I'll do interesting things with the tree. I've got a couple of questions. First, about declaration specifiers: declaration_specifiers : storage_class_specifier | storage_class_specifier declaration_specifiers | type_specifier | type_specifier declaration_specifiers | type_qualifier | type_qualifier declaration_specifiers ; So you can stack any number of storage_class_spec, type_spec, and type_qual in front of your declaration, in any order? Things like: void static fn(); and void static extern int auto volatile fn(); With my C, the first compiles, while the second won't compile and won't pass lint (rightly so!). But both slide through the grammar fine. Why? Why didn't ANSI do this: declaration_specifiers : storage_class_specifier | storage_class_specifier type_specifier | storage_clase_specifier type_qualifier | storage_class_specifier type_specifier type_qualifier | type_specifier | type_specifier type_qualifier | type_qualifier ; Yes, I know, now you can't put them in any order, but who would write "void static fn();" anyway? And if it's that important, another eight lines will do it. I'm considering using this specification for my parser. Technically I would then be parsing a subset of ANSI, but who cares? Should I? Second, I've never seen the ellipsis ("...") before. (Guess it's time to buy K&R 2nd ed.) As far as I can tell, the only uses for it are: void static fn(int c, ...); or void static a (n, fn) int n; void fn(int c, ...); { : : Are these in fact the intended uses? Are there any other uses? Unfortunately, my C rejects both of these with "parameters only legal in function definition" and "syntax error". (Guess it's time to buy a new C.) Thanks mulchy, Adam "Wherever you grow, there you are." Buckaroo Bonsai
chekmate@athena.mit.edu (Adam Kao) (11/14/88)
I just realized it's common in C to have things like "unsigned short int", which my modification doesn't parse. (A jellybean for whoever guesses how long I've been using C.) Still, I can think of a couple ways to parse these cases without being as lax as the current grammar. Why isn't this grammar more precise? It would only have to be a little more complicated. By the way, I'm using the 9nov87 draft grammar. Adam
bill@twwells.uucp (T. William Wells) (11/16/88)
In article <7938@bloom-beacon.MIT.EDU> chekmate@athena.mit.edu (Adam Kao) writes: : declaration_specifiers : : storage_class_specifier : | storage_class_specifier declaration_specifiers : | type_specifier : | type_specifier declaration_specifiers : | type_qualifier : | type_qualifier declaration_specifiers : ; : : So you can stack any number of storage_class_spec, type_spec, and type_qual : in front of your declaration, in any order? Things like: : : void static fn(); : : and : : void static extern int auto volatile fn(); Right. This is intentional. Believe it or not, there are situations where this flexibility is useful. As is typical in C, there are lots of things that the language permits you to do, that could be restricted with little harm to the language's utility, and aren't. This is consistent with C's bias toward trusting the programmer. This also means that it is more obviously the programmer's responsibility to carefully use the facilities that C provides. (I was originally going to say "This also makes it the programmer's responsibility..." till it occured to me that some might interpret that to mean that other languages don't impose that responsibility. Utter nonsense, of course: some of the worst programs I have seen were written in Modula 2 and followed all the "structured programming" guidelines.) : Yes, I know, now you can't put them in any order, but who would write : "void static fn();" anyway? I might. Though I never have, I can imagine circumstances where doing it that way might be clearer than the other. : And if it's that important, another eight : lines will do it. I'm considering using this specification for my parser. : Technically I would then be parsing a subset of ANSI, but who cares? : Should I? There is also another factor you should consider: adding those lines to your grammar (and, by extension, lots of other lines for similar purposes), can make the resulting grammar tables *huge*. It just isn't worth it. Especially since, if you *must* do this, there is a better way: do it with attributes passed up the parse tree. : Second, I've never seen the ellipsis ("...") before. (Guess it's time to : buy K&R 2nd ed.) As far as I can tell, the only uses for it are: : : void static fn(int c, ...); : : or : : void static a (n, fn) : int n; : void fn(int c, ...); : { : : : : : : Are these in fact the intended uses? Are there any other uses? The ... can also be used in the prototype with the definition of the function: void static fn(int c, ...) { } --- If you're going to write a C compiler, or a reasonable facsimile thereof, make it a *real* C compiler; don't add your stylistic preferences to it. If you do have style preferences that can be detected syntactically, have your lint detect them, but make it optional. You'll thank yourself the first time you have to deal with someone else's code. --- Bill {uunet|novavax}!proxftl!twwells!bill
guy@auspex.UUCP (Guy Harris) (11/18/88)
>: void static extern int auto volatile fn(); > >Right. This is intentional. Believe it or not, there are situations >where this flexibility is useful. And those cases that are truly *illegal*, such as the one cited above, can still be caught by the compiler even though they pass the grammar.
henry@utzoo.uucp (Henry Spencer) (11/18/88)
In article <179@twwells.uucp> bill@twwells.UUCP (T. William Wells) writes: >: So you can stack any number of storage_class_spec, type_spec, and type_qual >: in front of your declaration, in any order? Things like: >: >: void static fn(); > >Right. This is intentional. Believe it or not, there are situations >where this flexibility is useful. However, beware: the "future directions" section of the draft standard explicitly flags putting the storage class in the middle as "obsolescent", and implies that it is likely to be made illegal in future revisions. -- Sendmail is a bug, | Henry Spencer at U of Toronto Zoology not a feature. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
karl@haddock.ima.isc.com (Karl Heuer) (11/18/88)
In article <179@twwells.uucp> bill@twwells.uucp (T. William Wells) writes: >In article <7938@bloom-beacon.MIT.EDU> chekmate@athena.mit.edu (Adam Kao) writes: >>So you can stack any number of storage_class_spec, type_spec, and type_qual >>in front of your declaration, in any order? Things like: >> void static fn(); >> void static extern int auto volatile fn(); > >Right. This is intentional. Believe it or not, there are situations >where this flexibility is useful. As I'm sure we all realize, the second is *not* legal C (it names two conflicting types, and three conflicting storage classes). More precisely, although it satisfies the syntax rules, it violates the constraint rules. Less well known, but perhaps of interest to y'all, is that the first construct, though still legal, is obsolescent. Don't use it in new programs. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint Followups to comp.std.c.
bill@twwells.uucp (T. William Wells) (11/19/88)
In article <467@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes:
: >: void static extern int auto volatile fn();
: >
: >Right. This is intentional. Believe it or not, there are situations
: >where this flexibility is useful.
:
: And those cases that are truly *illegal*, such as the one cited above,
: can still be caught by the compiler even though they pass the grammar.
Whoops! I didn't carefully read the examples, supposing that they were
all of the kind expressing reordering of the type-specifier and
storage-class. This last example has more than one storage class and
more than one type-specifier, so is illegal.
As an aside, catching this kind of error in the grammar can really
make the grammar *huge*. This is why one does it outside the grammar.
---
Bill
{uunet|novavax}!proxftl!twwells!bill
chekmate@athena.mit.edu (Adam Kao) (11/20/88)
Many thanks to all who responded, on the net and through mail. I am newly enlightened as to the ways of committee and will endeavor to bear the standard :-). Yacc is good, C is good, syntax sucks but you can't win them all. Adam