2

Looking at https://www.lysator.liu.se/c/ANSI-C-grammar-y.html#direct-abstract-declarator, it seems like int f((int)); can be interpreted either as

  1. 'function f (int)' using the '(' abstract_declarator ')' rule or
  2. 'function f(function(int))' using the '(' parameter_type_list ')' rule.

However, when I compile the file with bison, it doesn't mention any shift-reduce conflicts besides the dangling if/else. cdecl just says 'syntax error'. GCC and Clang seems to parse it as 2:

$ gcc -x c - -o /dev/stdout -S "$@"
int f((int));
<stdin>:1:7: error: expected declaration specifiers or '...' before '(' token
$ clang -x c - -o /dev/stdout -S "$@"
int f((int));
<stdin>:1:8: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]

What's the proper way to parse this? Is this sufficiently arcane that I should just assume no one is using this part of the language?

jyn
  • 463
  • 4
  • 16
  • 2
    Look at grammar for `parameter_list`. It requires each parameter to have both `declaration_specifiers` AND a declarator. `'(' abstract_declarator ')'` and `'(' parameter_type_list ')'` are declarators, but where is `declaration_specifiers`? – HolyBlackCat Jun 01 '19 at 21:58
  • 3
    ahh I was missing that you couldn't have parenthesis around `declaration_specifiers`. So the whole thing is invalid syntax. Thanks! – jyn Jun 01 '19 at 21:59
  • Related: https://stackoverflow.com/q/56258385/6699433 – klutt Jun 01 '19 at 22:23
  • @Broman that deals with expressions and operator precedence, my question was about declarations. – jyn Jun 01 '19 at 23:32
  • @JoshuaNelson Yes, I didn't say it was a dupe. Just that it was related. – klutt Jun 01 '19 at 23:33
  • 2
    @HolyBlackCat: Shouldn't that be an answer? – R.. GitHub STOP HELPING ICE Jun 02 '19 at 01:36
  • @R.. I'd close the question instead as "can't be reproduced" instead. – HolyBlackCat Jun 02 '19 at 10:11
  • @HolyBlackCat: That makes no sense at all. The question is about language syntax, not an observed phenomenon. – R.. GitHub STOP HELPING ICE Jun 02 '19 at 12:14
  • @R.. I'm seem to be interpreting this close reason in a more broad way. OP is asking about grammar for function parameters, yet they for some reason cite grammar for declarators. It looks like OP simply misread the grammar by accident; there is nothing more to it. The question is unlikely to be useful to anyone but the OP, so I see no point in writing an answer. – HolyBlackCat Jun 02 '19 at 13:27
  • I'm asking about grammar for parameters _in declarations_. The grammar I cited would be applicable for a declaration such as `int f(int (int))` as well as `int f(int *)`, I was asking a way to tell the two apart with only two tokens of lookahead. Just because I misunderstood the grammar doesn't mean the question can't be useful. – jyn Jun 02 '19 at 15:32
  • @joshua: "how can I parse declarations with only two tokens of lookahead?" is a very different question than your original, and is also rather difficult to answer unless you at least provide a parsing algorithm. The particular example `int f((int))` is invalid, because `int f((` is not a valid prefix. No more lookahead is necessary for that determination, and nothing has been reduced yet when the second `(` has been encountered. There are many other issues with parsing C declarations, and the grammar file you refer to is not precise enough to reject all errors. – rici Jun 02 '19 at 17:47
  • It seems like you are asking about using a top-down parser. Bison doesn't generate top-down parsers and it is not immediately obvious that it is possible to precisely parse C declarations top-down without back-tracking. – rici Jun 02 '19 at 17:49

0 Answers0