home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 3.ddi / PARSE.ZIP / ACTIONS.CPP next >
Encoding:
C/C++ Source or Header  |  1989-05-04  |  7.7 KB  |  319 lines

  1. /*****************************************************
  2. File: ACTIONS.CPP    Copyright 1989 by John M. Dlugosz
  3.    the Actions called from the parser
  4. *****************************************************/
  5.  
  6. #include "usual.hpp"
  7. #include <assert.h>
  8. #include <stream.hpp>
  9. #include "atom.hpp"
  10. #include "node.hpp"
  11. #include "define.hpp"
  12.  
  13. // #define SHORT return 0    
  14. /* short out actions for testing parser only.
  15.    if something suddenly goes wrong, I can stub
  16.    out all the actions to make sure I'm not walking
  17.    on data somewhere.  */
  18. #define SHORT
  19.    // the normal case.
  20.  
  21. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  22.  
  23. static char last_token[81];
  24.  
  25. void get_last_token()
  26. {
  27. /* copy last token from scanner into a nul-terminated string */
  28. int len= 80;  //maximum sig. length
  29. extern char *T_beg, *T_end;  //from the scanner
  30. char* source= T_beg;
  31. char* dest= last_token;
  32.  
  33. //cout << (unsigned)T_beg << "  " << T_end;
  34. //for (int x= 0;  x < 5;  x++)   cout.put(T_beg[x]);
  35.  
  36. while (len-- && source < T_end) *dest++ = *source++;
  37. *dest= '\0';
  38. }
  39.  
  40. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  41.  
  42. /* in a declaration, a storage class is the first thing I get.  This starts
  43.    it off.  Then a ConstVol, a StoreType, and a second ConstVol.  The const
  44.    or volatile keyword may appear before or after the type, with equal
  45.    effect.  The two bits are ORed together for the final result.
  46.    After this, I get one or more calls to Declaration.
  47. */
  48.  
  49. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  50.  
  51. // the type I'm building
  52. struct working_type {
  53.    type_node* this_type;    //the tail
  54.    type_node* root_type;    //the head
  55.    int base_type;
  56.    atom tag_name; // if base_type has a name
  57.    atom name;  //The name of the thing being declared
  58.    int storage_class;
  59.    int const_vol;
  60.    bool isfriend;  //this is declaration of a friend function
  61.    working_type* next;
  62.    enum { is_public, is_protected, is_private } protect_mode;
  63.    type_node* forwarded_class;
  64.    def_node_list* classbody;
  65.    } MainType;
  66.  
  67. working_type* Tx= &MainType;
  68. /* this is accessed through a pointer because a declarator can be encounted
  69.    while parsing another declarator.  This lets me stack them.  */
  70.  
  71. static int aggr_form;  //union, struct, class
  72.  
  73. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  74.  
  75. static int const_vol_stack[50];
  76. static int const_vol_stacktop= 0;
  77.  
  78. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  79.  
  80. int IsFriend (int x ...)
  81. {
  82. Tx->isfriend= x;
  83. return 0;
  84. }
  85.  
  86. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  87.  
  88. int ProtectionSpecifier (int x ...)
  89. {
  90. Tx->protect_mode= x;
  91. return 0;
  92. }
  93.  
  94. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  95.  
  96. int Declaration (int x,...)
  97. {
  98. /* values for x:  1- global or local def.
  99.                   2- parameters
  100.                   3- struct/union list
  101. */
  102. SHORT;
  103. /* This finishes it off.  A complete declaration has been found. */
  104. if (Tx->forwarded_class) Tx->this_type= Tx->forwarded_class;
  105. else Tx->this_type->stuff_primary (Tx->base_type, Tx->tag_name);
  106. Tx->this_type->flags |= Tx->const_vol;
  107. // build the 'thing' from the type_node and the name.
  108. store_thing (Tx->root_type, Tx->name, Tx->storage_class, x, Tx->isfriend, Tx->protect_mode);
  109. // Tx->root_type->print();
  110. // cout.put('\n');
  111. return 0;
  112. }
  113.  
  114. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  115.  
  116. int StoreBaseConstVol (int x,...)
  117. {
  118. SHORT;
  119. // the first two calls to ConstVol apply here.
  120. Tx->const_vol =  const_vol_stack[--const_vol_stacktop];
  121. Tx->const_vol |= const_vol_stack[--const_vol_stacktop];
  122. return 0;
  123. }
  124.  
  125. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  126.  
  127. int StoreType (int x,...)
  128. {
  129. SHORT;
  130. if (x == 13) {
  131.   if (aggr_form == 0) Tx->base_type= 14;
  132.   else {
  133.      Tx->base_type= 13;
  134.      Tx->protect_mode= (aggr_form == 1) ? is_public : is_private;
  135.      }
  136.   type_node* n= named_type_list->search(Tx->tag_name);  //present already?
  137.   if (!n) {  //add it
  138.      n= new type_node;
  139.      n->primary= Tx->base_type;
  140.      n->aggr= Tx->classbody;
  141.      if (Tx->tag_name != -1) {
  142.         n->tag= Tx->tag_name;
  143.         named_type_list->add (n);
  144.         }
  145.      }
  146.   else {  //already present
  147.      // >> check for errors
  148.      }
  149.   Tx->forwarded_class= n;
  150.   }
  151. else {
  152.    Tx->forwarded_class= NULL;
  153.    Tx->base_type= x;
  154.    if (x == 0) Tx->const_vol= 0;  // no call to StoreBaseConstVol made.
  155.    }
  156. return 0;
  157. }
  158.  
  159. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  160.  
  161. int StoreTag (int x,...)
  162. {
  163. SHORT;
  164. /* called when a struct, union, or enum is parsed. The tag is the last
  165.    token read.  After this call, the StoreType call is made with 'union'
  166.    or whatever.  */
  167. get_last_token();
  168. Tx->tag_name= atoms[last_token];
  169. return 0;
  170. }
  171.  
  172. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  173.  
  174. int AggrForm (int x, ...)
  175. {
  176. /* is this a class, struct, or union? */
  177. SHORT;
  178. aggr_form= x;
  179. return 0;
  180. }
  181.  
  182. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  183.  
  184. int StoreStorage (int x,...)
  185. {
  186. SHORT;
  187. /* this is the first thing called */
  188. Tx->storage_class= x;
  189. Tx->tag_name= -1;  //initialize
  190. return 0;
  191. }
  192.  
  193. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  194.  
  195. int Dname (int x,...)
  196. {
  197. SHORT;
  198. /* if x==1, the last token is the name of a thing being declared.  If
  199.    x==0, there is no name and this is an abstact declarator.  Either
  200.    way, build a type node and store the name.  This overwrites the type 
  201.    node, as it will be the first thing called.  */
  202.  
  203. if (x) {
  204.    get_last_token();
  205.    Tx->name= atoms[last_token];
  206.    }
  207. Tx->this_type= new type_node;
  208. Tx->root_type= Tx->this_type;
  209. return 0;
  210. }
  211.  
  212. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  213.  
  214. int TypeModifier (int x,...)
  215. {
  216. SHORT;
  217. /*  1 t()     2 t[]     3 *t     4 &t        */
  218.  
  219. switch (x) {
  220.    case 1:
  221.       Tx->this_type->primary= type_function;
  222.       // attach parameter list
  223.       Tx->this_type->aggr= completed_def_list;
  224.       break;
  225.    case 2:
  226.       Tx->this_type->primary= type_array;
  227.       // >> attach size
  228.       break;
  229.    case 3:
  230.       Tx->this_type->primary= type_pointer;
  231.       Tx->this_type->flags |= const_vol_stack[--const_vol_stacktop];
  232.       break;
  233.    case 4:
  234.       Tx->this_type->primary= type_reference;
  235.       Tx->this_type->flags |= const_vol_stack[--const_vol_stacktop];
  236.       break;
  237.    }
  238. Tx->this_type->to_what= new type_node;
  239. Tx->this_type= Tx->this_type->to_what;
  240.  
  241. return 0;
  242. }
  243.  
  244. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  245.  
  246. int StoreAggrBody (int x ...)
  247. {
  248. SHORT;
  249. /* this is called after the body of a class is parsed.  If there was
  250.    no body, the parameter is 0 */
  251. if (x) {
  252.    Tx->classbody= completed_def_list;  //finish off type
  253.    // >> check over completed type.
  254.    }
  255. else Tx->classbody= NULL;
  256. return 0;
  257. }
  258.  
  259. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  260.  
  261. int ConstVol (int x,...)
  262. {
  263. SHORT;
  264. /*  1-const  2-volatile  3-both  */
  265. const_vol_stack[const_vol_stacktop++]= x;
  266. return 0;
  267. }
  268.  
  269. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  270.  
  271. int ReachType (int x,...)
  272. {
  273. SHORT;
  274. /* 0-default  1-near  2-far */
  275. return 0;
  276. }
  277.  
  278. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  279.  
  280. int NestedType (int x, ...)
  281. {
  282. SHORT;
  283. working_type* p;
  284. if (x) {  //start nesting
  285.    p= new working_type;
  286.    p->next= Tx;
  287.    Tx= p;
  288.    }
  289. else {  //restore old type
  290.    p= Tx;
  291.    Tx= Tx->next;
  292.    delete p;
  293.    }
  294. parameter_list (x);  //pass on to DEFINE module
  295. return 0;
  296. }
  297.  
  298. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  299. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  300. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  301.  
  302. int AllDoneNow (int x, ...)
  303. {
  304. SHORT;
  305. cout << "parser complete. \n";
  306. for (int loop= 0;  loop < global_stuff.size();  loop++) {
  307.    assert (global_stuff[loop]);
  308.    global_stuff[loop]->print();
  309.    cout.put ('\n');
  310.    cout << global_stuff[loop]->mangled_name();
  311.    cout.put ('\n');
  312.    }
  313. extern void dump_types();
  314. dump_types();
  315. return 0;
  316. }
  317.  
  318. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  319.