[comp.lang.c] C-type-gen long

djones@megatest.UUCP (Dave Jones) (11/19/88)

From article <207600008@s.cs.uiuc.edu>, by dlee@s.cs.uiuc.edu:
> 
> I usually don't have any trouble with C, but this is a
> glaring exception:  I need the syntax of definition for an array 
> (of arbitrary size) of pointers to functions returning pointers to 
> integer (HOW'S *THAT* FOR A DOOZY!!!).  

As doozies go, it is a very excellent doozy indeed.  You should
be very proud.

>
> My closest (possibly correct) guess follows:
> 
> 	int *(*opfuncs[])() = {
> 		.
> 		.
> 		.
> 	};
> 


You win, Mr. Presky!  Come back next week to try for the Grand
Prize: A week's supply of designer roofing nails and an all expense-
paid vacation for none to Holland, where you can stick your finger
in a dike!

I've got a little program to figure these things out. There is
also a more involved program called "cdecl" which I have seen posted
to the net a couple of times, but I don't know anything about it.

I don't remember if I have posted this to an archive.  Most of
the moderators are not interested in programs this short. 

So I'll just include it here...



#include <stdio.h>
#include <setjmp.h>

/*
** I got tired of straining my fragile synapses writing C type-declarators.
** So I wrote this little program.
** 
** You enter a declaration for the type using prefix notation.
** The implicit base-type is always "int", (why not), and the
** implicit type-name is "foo", (of course).
**
**   '^' means "pointer to"
**
**   '_' means "array of"
**
**   '!' means "function returning"
**
** So for example, if you want a declarator for an array of pointers to
** functions returning int, you say,
**
** _^!
**
** and it says
**
** int (*foo[])();
**
*/


/*
**  In C, () and [] are postfix, left-associative operators, and have
**  a high precedence.
**
**  * is a prefix, right-associative operator, and has a low precedence. 
*/  


#define LEN 256
static char decl[LEN];
jmp_buf restart;

main()
{
  int ch;
  printf("\n_ array of\n^ pointer to\n! function returning\n\n");
  setjmp(restart);
  do
    {
      int i = 0;
      printf("? "); fflush(stdout);
      do
	{
	  if(i >= LEN ){ fprintf(stderr, "Too long. So long.\n"); exit(1); }
	  ch = getchar();
	  if(ch != EOF) decl[i++] = ch;
	}
      while(ch != '\n' && ch != EOF);
      if(ch != EOF) print_type_def();
    }
  while(ch != EOF);
  exit(0);
}

print_type_def()
{
  print_left(0);
  printf("foo");
  print_right(0);
  printf(";\n");
}





print_right(i)
  int i;
{
  switch(decl[i])
    {
    default:
      printf("\Hold it! What's a '%c'?\n", decl[i]);
      longjmp(restart);

    case '\n':
      return;

    case '^':
      if( decl[i+1] == '_' || decl[i+1] == '!')
	putchar(')');
      break;

    case '_':
      printf("[]");
      break;

    case '!':
      printf("()");
      break;

    }

  print_right(i+1);
}




print_left(i)
  int i;
{
  switch(decl[i])
    {

    default:
      printf("\Hold it! What's a '%c'?\n", decl[i]);
      longjmp(restart);

    case '\n':
      printf("int ");
      return;

    case '^':
      print_left(i+1);
      if( decl[i+1] == '_' || decl[i+1] == '!')
	putchar('(');
      putchar('*');
      break;

    case '_':
    case '!':
      print_left(i+1);
      break;
    }
}