program.g 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Id$ */
  6. /* PROGRAM PARSER */
  7. /* The presence of typedef declarations renders it impossible to
  8. make a context-free grammar of C. Consequently we need
  9. context-sensitive parsing techniques, the simplest one being
  10. a subtle cooperation between the parser and the lexical scanner.
  11. The lexical scanner has to know whether to return IDENTIFIER
  12. or TYPE_IDENTIFIER for a given tag, and it obtains this information
  13. from the definition list, as constructed by the parser.
  14. The present grammar is essentially LL(2), and is processed by
  15. a parser generator which accepts LL(1) with tie breaking rules
  16. in C, of the form %if(cond) and %while(cond). To solve the LL(1)
  17. ambiguities, the lexical scanner does a one symbol look-ahead.
  18. This symbol, however, cannot always be correctly assessed, since
  19. the present symbol may cause a change in the definition list
  20. which causes the identification of the look-ahead symbol to be
  21. invalidated.
  22. The lexical scanner relies on the parser (or its routines) to
  23. detect this situation and then update the look-ahead symbol.
  24. An alternative approach would be to reassess the look-ahead symbol
  25. in the lexical scanner when it is promoted to dot symbol. This
  26. would be more beautiful but less correct, since then for a short
  27. while there would be a discrepancy between the look-ahead symbol
  28. and the definition list; I think it would nevertheless work in
  29. correct programs.
  30. A third solution would be to enter the identifier as soon as it
  31. is found; its storage class is then known, although its full type
  32. isn't. We would have to fill that in afterwards.
  33. At block exit the situation is even worse. Upon reading the
  34. closing brace, the names declared inside the function are cleared
  35. from the name list. This action may expose a type identifier that
  36. is the same as the identifier in the look-ahead symbol. This
  37. situation certainly invalidates the third solution, and casts
  38. doubts upon the second.
  39. */
  40. %lexical LLlex;
  41. %start C_program, program;
  42. %start If_expr, control_if_expression;
  43. {
  44. #include "lint.h"
  45. #include "nopp.h"
  46. #include "debug.h"
  47. #include <flt_arith.h>
  48. #include "arith.h"
  49. #include "LLlex.h"
  50. #include "idf.h"
  51. #include "label.h"
  52. #include "type.h"
  53. #include "declar.h"
  54. #include "decspecs.h"
  55. #include "code.h"
  56. #include "expr.h"
  57. #include "def.h"
  58. #include "code_c.h"
  59. #ifdef LINT
  60. #include "l_lint.h"
  61. #endif /* LINT */
  62. #ifndef NOPP
  63. extern arith ifval;
  64. #endif /* NOPP */
  65. extern error();
  66. }
  67. control_if_expression
  68. {
  69. struct expr *exprX;
  70. }
  71. :
  72. constant_expression(&exprX)
  73. {
  74. #ifndef NOPP
  75. register struct expr *expr = exprX;
  76. if (expr->ex_flags & EX_SIZEOF)
  77. expr_error(expr,
  78. "sizeof not allowed in preprocessor");
  79. ifval = expr->VL_VALUE;
  80. free_expression(expr);
  81. #endif /* NOPP */
  82. }
  83. ;
  84. /* 3.7 */
  85. program:
  86. [%persistent external_definition]*
  87. { unstack_world(); }
  88. ;
  89. /* A C identifier definition is remarkable in that it formulates
  90. the declaration in a way different from most other languages:
  91. e.g., rather than defining x as a pointer-to-integer, it defines
  92. *x as an integer and lets the compiler deduce that x is actually
  93. pointer-to-integer. This has profound consequences, both for the
  94. structure of an identifier definition and for the compiler.
  95. A definition starts with a decl_specifiers, which contains things
  96. like
  97. typedef int
  98. which is implicitly repeated for every definition in the list, and
  99. then for each identifier a declarator is given, of the form
  100. *a()
  101. or so. The decl_specifiers is kept in a struct decspecs, to be
  102. used again and again, while the declarator is stored in a struct
  103. declarator, only to be passed to declare_idf together with the
  104. struct decspecs.
  105. With the introduction of prototypes, extra problems for the scope
  106. administration were introduced as well. We can have, for example,
  107. int x(double x);
  108. and
  109. int x(double x) { ... use(x) ... }
  110. In the first case, the parameter name can be forgotten, whereas in
  111. the second case, the parameter should have a block scope. The
  112. problem lies in the fact that the parameter's type is known before
  113. the type of the function, which causes the def structure to be on
  114. the end of the list. Our solution is as follows:
  115. 1- In case of a declaration, throw the parameter identifier away
  116. before the declaration of the outer x.
  117. 2- In case of a definition, the function begin_proc() changes the
  118. def list for the identifier. This means that declare_idf()
  119. contains an extra test in case we already saw a declaration of
  120. such a function, because this function is called before
  121. begin_proc().
  122. */
  123. external_definition
  124. { struct decspecs Ds;
  125. struct declarator Dc;
  126. }
  127. :
  128. { Ds = null_decspecs;
  129. Dc = null_declarator;
  130. }
  131. [ %if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
  132. decl_specifiers(&Ds)
  133. |
  134. {do_decspecs(&Ds);}
  135. ]
  136. [
  137. declarator(&Dc)
  138. {
  139. declare_idf(&Ds, &Dc, level);
  140. #ifdef LINT
  141. lint_ext_def(Dc.dc_idf, Ds.ds_sc);
  142. #endif /* LINT */
  143. }
  144. [
  145. function(&Ds, &Dc)
  146. |
  147. { if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
  148. Ds.ds_notypegiven) {
  149. strict("declaration specifiers missing");
  150. }
  151. }
  152. non_function(&Ds, &Dc)
  153. ]
  154. |
  155. { if (! Ds.ds_sc_given && ! Ds.ds_typequal &&
  156. Ds.ds_notypegiven) {
  157. strict("declaration missing");
  158. }
  159. }
  160. ';'
  161. ]
  162. {remove_declarator(&Dc); flush_strings(); }
  163. ;
  164. non_function(register struct decspecs *ds; register struct declarator *dc;)
  165. :
  166. { reject_params(dc);
  167. }
  168. [
  169. initializer(dc->dc_idf, ds->ds_sc)
  170. |
  171. { code_declaration(dc->dc_idf, (struct expr *) 0, level, ds->ds_sc); }
  172. ]
  173. {
  174. #ifdef LINT
  175. lint_non_function_decl(ds, dc);
  176. #endif /* LINT */
  177. }
  178. [
  179. ','
  180. init_declarator(ds)
  181. ]*
  182. ';'
  183. ;
  184. /* 3.7.1 */
  185. function(struct decspecs *ds; struct declarator *dc;)
  186. {
  187. arith fbytes;
  188. register struct idf *idf = dc->dc_idf;
  189. }
  190. :
  191. {
  192. #ifdef LINT
  193. lint_start_function();
  194. #endif /* LINT */
  195. idf_initialized(idf);
  196. stack_level(); /* L_FORMAL1 declarations */
  197. declare_params(dc);
  198. begin_proc(ds, idf); /* sets global function info */
  199. stack_level(); /* L_FORMAL2 declarations */
  200. declare_protos(dc);
  201. }
  202. declaration*
  203. {
  204. check_formals(idf, dc); /* check style-mixtures */
  205. declare_formals(idf, &fbytes);
  206. #ifdef LINT
  207. lint_formals();
  208. #endif /* LINT */
  209. }
  210. compound_statement
  211. {
  212. end_proc(fbytes);
  213. #ifdef LINT
  214. lint_implicit_return();
  215. #endif /* LINT */
  216. unstack_level(); /* L_FORMAL2 declarations */
  217. #ifdef LINT
  218. lint_end_formals();
  219. #endif /* LINT */
  220. unstack_level(); /* L_FORMAL1 declarations */
  221. #ifdef LINT
  222. lint_end_function();
  223. #endif /* LINT */
  224. }
  225. ;