fork download
  1. /* A very simple cdecl clone by FredOverflow.
  2.   Functions are not supported yet, only pointers and arrays.
  3.   Error detection should be pretty good. */
  4.  
  5. #include <ctype.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. void assume(int condition, const char * error_message)
  11. {
  12. if (!condition)
  13. {
  14. fprintf(stderr, "%s\n", error_message);
  15. exit(1);
  16. }
  17. }
  18.  
  19. void remove_spaces(char * dst)
  20. {
  21. while (!isspace(*dst)) ++dst;
  22. char * src = dst;
  23. while (*src)
  24. {
  25. if (!isspace(*src))
  26. {
  27. *dst++ = *src;
  28. }
  29. ++src;
  30. }
  31. *dst = 0;
  32. }
  33.  
  34. /* Yes I know, global variables are evil, kittens die etc...
  35.   In an object-oriented language, this would be a private field, okay? */
  36. static char * p;
  37.  
  38. void skip(int predicate(int))
  39. {
  40. while (predicate(*p))
  41. {
  42. ++p;
  43. }
  44. }
  45.  
  46. int is_star(int x)
  47. {
  48. return '*' == x;
  49. }
  50.  
  51. int parse_int()
  52. {
  53. int x = 0;
  54. while (isalnum(*p))
  55. {
  56. x = x * 10 + (*p++ - '0');
  57. }
  58. return x;
  59. }
  60.  
  61. void parse_declarator();
  62. void parse_atom();
  63. void parse_array();
  64.  
  65. void declaration()
  66. {
  67. skip(isspace);
  68. assume(isalpha(*p), "must start with a letter");
  69.  
  70. char * begin_of_type = p;
  71. skip(isalnum);
  72. char * end_of_type = p;
  73.  
  74. remove_spaces(p);
  75. parse_declarator();
  76.  
  77. *end_of_type = 0;
  78. printf("%s\n", begin_of_type);
  79. }
  80.  
  81. int count_stars()
  82. {
  83. char * first_star = p;
  84. skip(is_star);
  85. return p - first_star;
  86. }
  87.  
  88. void print_stars(int number_of_stars)
  89. {
  90. int i;
  91. for (i = 0; i < number_of_stars; ++i)
  92. {
  93. printf("pointer to ");
  94. }
  95. }
  96.  
  97. void parse_declarator()
  98. {
  99. int number_of_stars = count_stars();
  100. parse_atom();
  101. parse_array();
  102. print_stars(number_of_stars);
  103. }
  104.  
  105. void parse_atom()
  106. {
  107. if ('(' == *p)
  108. {
  109. ++p;
  110. parse_declarator();
  111. assume(')' == *p, "missing )");
  112. ++p;
  113. }
  114. else skip(isalnum);
  115. }
  116.  
  117. void parse_array()
  118. {
  119. while ('[' == *p)
  120. {
  121. ++p;
  122. int n = parse_int();
  123. assume(']' == *p, "missing ]");
  124. ++p;
  125. printf("array of %d ", n);
  126. }
  127. }
  128.  
  129. int main()
  130. {
  131. char test[] = " int ** (* a[ 2 ]) [3 ][5 ] [7] ";
  132. printf("%s\n", test);
  133.  
  134. p = test;
  135. declaration();
  136.  
  137. return 0;
  138. }
  139.  
Success #stdin #stdout 0s 2292KB
stdin
Standard input is empty
stdout
 int ** (* a[ 2 ]) [3 ][5 ]  [7]   
array of 2 pointer to array of 3 array of 5 array of 7 pointer to pointer to int