program.g 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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. * Author: Ceriel J.H. Jacobs
  6. */
  7. /* O V E R A L L S T R U C T U R E */
  8. /* $Id$ */
  9. {
  10. #include "debug.h"
  11. #include <alloc.h>
  12. #include <em_arith.h>
  13. #include <em_label.h>
  14. #include <em_code.h>
  15. #include <stb.h>
  16. #include "dbsymtab.h"
  17. #include "strict3rd.h"
  18. #include "main.h"
  19. #include "idf.h"
  20. #include "LLlex.h"
  21. #include "scope.h"
  22. #include "def.h"
  23. #include "type.h"
  24. #include "node.h"
  25. #include "f_info.h"
  26. #include "warning.h"
  27. #include "misc.h"
  28. extern t_def *GetDefinitionModule();
  29. }
  30. /*
  31. The grammar as given by Wirth is already almost LL(1); the
  32. main problem is that the full form of a qualified designator
  33. may be:
  34. [ module_ident '.' ]* IDENT [ '.' field_ident ]*
  35. which is quite confusing to an LL(1) parser. Rather than
  36. resorting to context-sensitive techniques, I have decided
  37. to render this as:
  38. IDENT [ '.' IDENT ]*
  39. on the grounds that it is quite natural to consider the first
  40. IDENT to be the name of the object and regard the others as
  41. field identifiers.
  42. */
  43. %lexical LLlex;
  44. %start CompUnit, CompilationUnit;
  45. %start DefModule, DefinitionModule;
  46. ModuleDeclaration
  47. {
  48. register t_def *df;
  49. t_node *exportlist;
  50. int qualified;
  51. } :
  52. MODULE IDENT { df = DefineLocalModule(dot.TOK_IDF); }
  53. priority(&(df->mod_priority))
  54. ';'
  55. import(1)*
  56. export(&qualified, &exportlist)
  57. block(&(df->mod_body))
  58. IDENT { EnterExportList(exportlist, qualified);
  59. close_scope(SC_CHKFORW|SC_CHKPROC|SC_REVERSE);
  60. match_id(df->df_idf, dot.TOK_IDF);
  61. }
  62. ;
  63. priority(register t_node **prio;):
  64. [
  65. '[' ConstExpression(prio) ']'
  66. { if (! ((*prio)->nd_type->tp_fund & T_CARDINAL)) {
  67. node_error(*prio, "illegal priority");
  68. }
  69. }
  70. |
  71. ]
  72. ;
  73. export(int *QUALflag; t_node **ExportList;):
  74. { *ExportList = 0; *QUALflag = D_EXPORTED; }
  75. [
  76. EXPORT
  77. [
  78. QUALIFIED
  79. { *QUALflag = D_QEXPORTED; }
  80. |
  81. ]
  82. IdentList(ExportList) ';'
  83. |
  84. ]
  85. ;
  86. import(int local;)
  87. {
  88. t_node *ImportList;
  89. register t_node *FromId = 0;
  90. register t_def *df;
  91. } :
  92. /*
  93. When parsing a global module, this is the place where we must
  94. read already compiled definition modules.
  95. If the FROM clause is present, the identifier in it is a module
  96. name, otherwise the names in the import list are module names.
  97. */
  98. [ FROM
  99. IDENT
  100. %substart DefinitionModule;
  101. { FromId = dot2leaf(Name);
  102. if (local) {
  103. df = lookfor(FromId,enclosing(CurrVis),0,D_USED);
  104. }
  105. else df = GetDefinitionModule(dot.TOK_IDF, 1);
  106. }
  107. ]?
  108. IMPORT IdentList(&ImportList) ';'
  109. %substart DefinitionModule;
  110. { if (FromId) {
  111. EnterFromImportList(ImportList, df, FromId);
  112. }
  113. else {
  114. EnterImportList(ImportList,
  115. local,
  116. enclosing(CurrVis)->sc_scope);
  117. }
  118. FreeNode(ImportList);
  119. }
  120. ;
  121. DefinitionModule
  122. {
  123. register t_def *df;
  124. t_node *exportlist;
  125. int dummy;
  126. extern t_idf *DefId;
  127. extern int ForeignFlag;
  128. extern char *sprint();
  129. register t_scope *currscope = CurrentScope;
  130. char buf[512];
  131. } :
  132. DEFINITION
  133. MODULE IDENT { df = define(dot.TOK_IDF, GlobalScope, D_MODULE);
  134. df->df_flags |= D_BUSY | ForeignFlag;
  135. currscope->sc_definedby = df;
  136. if (DefId &&
  137. df->df_idf != DefId &&
  138. !is_anon_idf(df->df_idf)) {
  139. error("DEFINITION MODULE name is \"%s\", not \"%s\"",
  140. df->df_idf->id_text, DefId->id_text);
  141. }
  142. sprint(buf, "_%s_", df->df_idf->id_text);
  143. currscope->sc_name = Salloc(buf, (unsigned) strlen(buf) + 1);
  144. df->mod_vis = CurrVis;
  145. df->df_type = standard_type(T_RECORD, 1, (arith) 1);
  146. df->df_type->rec_scope = currscope;
  147. DefinitionModule++;
  148. if (!Defined) {
  149. Defined = df;
  150. }
  151. }
  152. ';'
  153. import(0)*
  154. export(&dummy, &exportlist)
  155. /* New Modula-2 does not have export lists in definition
  156. modules. Issue a warning.
  157. */
  158. {
  159. if (exportlist) {
  160. #ifndef STRICT_3RD_ED
  161. if (! options['3'])
  162. node_warning(exportlist, W_OLDFASHIONED, "export list in definition module ignored");
  163. else
  164. #endif
  165. error("export list not allowed in definition module");
  166. FreeNode(exportlist);
  167. }
  168. }
  169. definition* END IDENT
  170. { end_definition_list(&(currscope->sc_def));
  171. DefinitionModule--;
  172. match_id(dot.TOK_IDF, df->df_idf);
  173. df->df_flags &= ~D_BUSY;
  174. }
  175. '.'
  176. ;
  177. definition
  178. {
  179. register t_def *df;
  180. t_def *dummy;
  181. } :
  182. CONST [ %persistent ConstantDeclaration ';' ]*
  183. |
  184. TYPE
  185. [ %persistent
  186. IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
  187. [ '=' type(&(df->df_type))
  188. { SolveForwardTypeRefs(df); }
  189. | /* empty */
  190. /*
  191. Here, the exported type has a hidden implementation.
  192. The export is said to be opaque.
  193. It is restricted to pointer types.
  194. */
  195. { df->df_kind = D_HIDDEN;
  196. df->df_type = construct_type(T_HIDDEN, NULLTYPE);
  197. }
  198. ]
  199. {
  200. #ifdef DBSYMTAB
  201. if (options['g']) stb_string(df, D_TYPE);
  202. #endif
  203. }
  204. ';'
  205. ]*
  206. |
  207. VAR [ %persistent VariableDeclaration ';' ]*
  208. |
  209. ProcedureHeading(&dummy, D_PROCHEAD) ';'
  210. ;
  211. ProgramModule
  212. {
  213. register t_def *df;
  214. } :
  215. MODULE
  216. IDENT
  217. %substart DefinitionModule;
  218. {
  219. if (state == IMPLEMENTATION) {
  220. int len = strlen(dot.TOK_IDF->id_text);
  221. if (len > 10) len = 10;
  222. if (strncmp(FileName, dot.TOK_IDF->id_text, len)) {
  223. warning(W_ORDINARY, "modulename %s does not match filename %s", dot.TOK_IDF->id_text, FileName);
  224. }
  225. df = GetDefinitionModule(dot.TOK_IDF, 0);
  226. CurrVis = df->mod_vis;
  227. }
  228. else {
  229. Defined = df = define(dot.TOK_IDF, GlobalScope, D_MODULE);
  230. open_scope(CLOSEDSCOPE);
  231. df->mod_vis = CurrVis;
  232. CurrentScope->sc_name = "__M2M_";
  233. CurrentScope->sc_definedby = df;
  234. }
  235. }
  236. priority(&(df->mod_priority))
  237. ';' import(0)*
  238. block(&(df->mod_body)) IDENT
  239. {
  240. close_scope(SC_CHKFORW|SC_CHKPROC|SC_REVERSE);
  241. match_id(df->df_idf, dot.TOK_IDF);
  242. }
  243. '.'
  244. ;
  245. CompilationUnit:
  246. { error("Compiling a definition module");
  247. open_scope(CLOSEDSCOPE);
  248. state = DEFINITION;
  249. }
  250. DefinitionModule
  251. { close_scope(SC_CHKFORW); }
  252. | %default
  253. [
  254. IMPLEMENTATION
  255. { state = IMPLEMENTATION; }
  256. |
  257. /* empty */
  258. { state = PROGRAM; }
  259. ]
  260. ProgramModule
  261. ;