build.c
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:19k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * build.c -- functions associated with building syntax diagrams.
  3.  *
  4.  * SOFTWARE RIGHTS
  5.  *
  6.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  7.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  8.  * company may do whatever they wish with source code distributed with
  9.  * PCCTS or the code generated by PCCTS, including the incorporation of
  10.  * PCCTS, or its output, into commerical software.
  11.  *
  12.  * We encourage users to develop software with PCCTS.  However, we do ask
  13.  * that credit is given to us for developing PCCTS.  By "credit",
  14.  * we mean that if you incorporate our source code into one of your
  15.  * programs (commercial product, research project, or otherwise) that you
  16.  * acknowledge this fact somewhere in the documentation, research report,
  17.  * etc...  If you like PCCTS and have developed a nice tool with the
  18.  * output, please mention that you developed it using PCCTS.  In
  19.  * addition, we ask that this header remain intact in our source code.
  20.  * As long as these guidelines are kept, we expect to continue enhancing
  21.  * this system and expect to make other tools available as they are
  22.  * completed.
  23.  *
  24.  * ANTLR 1.33
  25.  * Terence Parr
  26.  * Parr Research Corporation
  27.  * with Purdue University and AHPCRC, University of Minnesota
  28.  * 1989-1998
  29.  */
  30. #include <stdio.h>
  31. #include <ctype.h>
  32. #ifdef __cplusplus
  33. #ifndef __STDC__
  34. #define __STDC__
  35. #endif
  36. #endif
  37. #include "set.h"
  38. #include "syn.h"
  39. #include "hash.h"
  40. #include "generic.h"
  41. #include "dlgdef.h"
  42. #define SetBlk(g, t, approx) {    
  43. ((Junction *)g.left)->jtype = t;
  44. ((Junction *)g.left)->approx = approx;
  45. ((Junction *)g.left)->end = (Junction *) g.right;
  46. ((Junction *)g.right)->jtype = EndBlk;}
  47. /* Add the parameter string 'parm' to the parms field of a block-type junction
  48.  * g.left points to the sentinel node on a block.  i.e. g.left->p1 points to
  49.  * the actual junction with its jtype == some block-type.
  50.  */
  51. void
  52. #ifdef __STDC__
  53. addParm( Node *p, char *parm )
  54. #else
  55. addParm( p, parm )
  56. Node *p;
  57. char *parm;
  58. #endif
  59. {
  60. char *q = (char *) malloc( strlen(parm) + 1 );
  61. require(p!=NULL, "addParm: NULL objectn");
  62. require(q!=NULL, "addParm: unable to alloc parametern");
  63. strcpy(q, parm);
  64. if ( p->ntype == nRuleRef )
  65. {
  66. ((RuleRefNode *)p)->parms = q;
  67. }
  68. else if ( p->ntype == nJunction )
  69. {
  70. ((Junction *)p)->parm = q; /* only one parameter allowed on subrules */
  71. }
  72. else fatal_internal("addParm: invalid node for adding parm");
  73. }
  74. /*
  75.  * Build an action node for the syntax diagram
  76.  *
  77.  * buildAction(ACTION) ::= --o-->ACTION-->o--
  78.  *
  79.  * Where o is a junction node.
  80.  */
  81. Graph
  82. #ifdef __STDC__
  83. buildAction( char *action, int file, int line, int is_predicate )
  84. #else
  85. buildAction( action, file, line, is_predicate )
  86. char *action;
  87. int file;
  88. int line;
  89. int is_predicate;
  90. #endif
  91. {
  92. Junction *j1, *j2;
  93. Graph g;
  94. ActionNode *a;
  95. require(action!=NULL, "buildAction: invalid action");
  96. j1 = newJunction();
  97. j2 = newJunction();
  98. a = newActionNode();
  99. a->action = (char *) malloc( strlen(action)+1 );
  100. require(a->action!=NULL, "buildAction: cannot alloc space for actionn");
  101. strcpy(a->action, action);
  102. j1->p1 = (Node *) a;
  103. a->next = (Node *) j2;
  104. a->is_predicate = is_predicate;
  105.     if (is_predicate) {
  106.         PredEntry   *predEntry;
  107.         char        *t;
  108.         char        *key;
  109.         char        *u;
  110.         int         inverted=0;
  111.         t=key=(char *)calloc(1,strlen(a->action)+1);
  112.         for (u=a->action; *u != '' ; u++) {
  113.           if (*u != ' ') {
  114.             if (t==key && *u=='!') {
  115.               inverted=!inverted;
  116.             } else {
  117.               *t++=*u;
  118.             };
  119.           };
  120.         };
  121.         *t='';
  122.         predEntry=(PredEntry *)hash_get(Pname,key);
  123.         a->predEntry=predEntry;
  124.         if (predEntry != NULL) a->inverted=inverted;
  125.     } else {
  126. /* MR12c */      char  *strStart=a->action;
  127. /* MR12c */      char  *strEnd;
  128. /* MR12c */      strEnd=strStart+strlen(strStart)-1;
  129. /* MR12c */      for ( ; strEnd >= strStart &&  isspace(*strEnd); strEnd--) *strEnd=0;
  130. /* MR12c */      while (*strStart != '' && isspace(*strStart)) strStart++;
  131. /* MR12c */      if (ci_strequ(strStart,"nohoist")) {
  132. /* MR12c */        a->noHoist=1;
  133. /* MR12c */      }
  134.     };
  135. g.left = (Node *) j1; g.right = (Node *) j2;
  136. a->file = file;
  137. a->line = line;
  138. a->rname = CurRule;     /* MR10 */
  139. return g;
  140. }
  141. /*
  142.  * Build a token node for the syntax diagram
  143.  *
  144.  * buildToken(TOKEN) ::= --o-->TOKEN-->o--
  145.  *
  146.  * Where o is a junction node.
  147.  */
  148. Graph
  149. #ifdef __STDC__
  150. buildToken( char *text )
  151. #else
  152. buildToken( text )
  153. char *text;
  154. #endif
  155. {
  156. Junction *j1, *j2;
  157. Graph g;
  158. TokNode *t;
  159. require(text!=NULL, "buildToken: invalid token name");
  160. j1 = newJunction();
  161. j2 = newJunction();
  162. t = newTokNode();
  163. t->altstart = CurAltStart;
  164. if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );}
  165. else {t->label=TRUE; t->token = addTname( text );}
  166. j1->p1 = (Node *) t;
  167. t->next = (Node *) j2;
  168. g.left = (Node *) j1; g.right = (Node *) j2;
  169. return g;
  170. }
  171. /*
  172.  * Build a wild-card node for the syntax diagram
  173.  *
  174.  * buildToken(TOKEN) ::= --o-->'.'-->o--
  175.  *
  176.  * Where o is a junction node.
  177.  */
  178. Graph
  179. #ifdef __STDC__
  180. buildWildCard( char *text )
  181. #else
  182. buildWildCard( text )
  183. char *text;
  184. #endif
  185. {
  186. Junction *j1, *j2;
  187. Graph g;
  188. TokNode *t;
  189. TCnode *w;
  190. TermEntry *p;
  191. require(text!=NULL, "buildWildCard: invalid token name");
  192. j1 = newJunction();
  193. j2 = newJunction();
  194. t = newTokNode();
  195. /* If the ref a wild card, make a token class for it */
  196. if ( Tnum(WildCardString) == 0 )
  197. {
  198. w = newTCnode;
  199.    w->tok = addTname( WildCardString );
  200. set_orel(w->tok, &imag_tokens);
  201. set_orel(w->tok, &tokclasses);
  202. WildCardToken = w->tok;
  203. require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL,
  204. "hash table mechanism is broken");
  205. p->classname = 1; /* entry is class name, not token */
  206. p->tclass = w; /* save ptr to this tclass def */
  207. list_add(&tclasses, (char *)w);
  208. }
  209. else {
  210. p=(TermEntry *)hash_get(Tname, WildCardString);
  211. require( p!= NULL, "hash table mechanism is broken");
  212. w = p->tclass;
  213. }
  214. t->token = w->tok;
  215. t->wild_card = 1;
  216. t->tclass = w;
  217. t->altstart = CurAltStart;
  218. j1->p1 = (Node *) t;
  219. t->next = (Node *) j2;
  220. g.left = (Node *) j1; g.right = (Node *) j2;
  221. return g;
  222. }
  223. void
  224. #ifdef __STDC__
  225. setUpperRange(TokNode *t, char *text)
  226. #else
  227. setUpperRange(t, text)
  228. TokNode *t;
  229. char *text;
  230. #endif
  231. {
  232. require(t!=NULL, "setUpperRange: NULL token node");
  233. require(text!=NULL, "setUpperRange: NULL token string");
  234. if ( *text == '"' ) {t->upper_range = addTexpr( text );}
  235. else {t->upper_range = addTname( text );}
  236. }
  237. /*
  238.  * Build a rule reference node of the syntax diagram
  239.  *
  240.  * buildRuleRef(RULE) ::= --o-->RULE-->o--
  241.  *
  242.  * Where o is a junction node.
  243.  *
  244.  * If rule 'text' has been defined already, don't alloc new space to store string.
  245.  * Set r->text to point to old copy in string table.
  246.  */
  247. Graph
  248. #ifdef __STDC__
  249. buildRuleRef( char *text )
  250. #else
  251. buildRuleRef( text )
  252. char *text;
  253. #endif
  254. {
  255. Junction *j1, *j2;
  256. Graph g;
  257. RuleRefNode *r;
  258. RuleEntry *p;
  259. require(text!=NULL, "buildRuleRef: invalid rule name");
  260. j1 = newJunction();
  261. j2 = newJunction();
  262. r = newRNode();
  263. r->altstart = CurAltStart;
  264. r->assign = NULL;
  265. if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str;
  266. else r->text = mystrdup( text );
  267. j1->p1  = (Node *) r;
  268. r->next = (Node *) j2;
  269. g.left = (Node *) j1; g.right = (Node *) j2;
  270. return g;
  271. }
  272. /*
  273.  * Or two subgraphs into one graph via:
  274.  *
  275.  * Or(G1, G2) ::= --o-G1-o--
  276.  *                  |    ^
  277.  * v    |
  278.  *                  o-G2-o
  279.  *
  280.  * Set the altnum of junction starting G2 to 1 + altnum of junction starting G1.
  281.  * If, however, the G1 altnum is 0, make it 1 and then
  282.  * make G2 altnum = G1 altnum + 1.
  283.  */
  284. Graph
  285. #ifdef __STDC__
  286. Or( Graph g1, Graph g2 )
  287. #else
  288. Or( g1, g2 )
  289. Graph g1;
  290. Graph g2;
  291. #endif
  292. {
  293. Graph g;
  294. require(g1.left != NULL, "Or: invalid graph");
  295. require(g2.left != NULL && g2.right != NULL, "Or: invalid graph");
  296. ((Junction *)g1.left)->p2 = g2.left;
  297. ((Junction *)g2.right)->p1 = g1.right;
  298. /* set altnums */
  299. if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
  300. ((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1;
  301. g.left = g2.left;
  302. g.right = g1.right;
  303. return g;
  304. }
  305. /*
  306.  * Catenate two subgraphs
  307.  *
  308.  * Cat(G1, G2) ::= --o-G1-o-->o-G2-o--
  309.  * Cat(NULL,G2)::= --o-G2-o--
  310.  * Cat(G1,NULL)::= --o-G1-o--
  311.  */
  312. Graph
  313. #ifdef __STDC__
  314. Cat( Graph g1, Graph g2 )
  315. #else
  316. Cat( g1, g2 )
  317. Graph g1;
  318. Graph g2;
  319. #endif
  320. {
  321. Graph g;
  322. if ( g1.left == NULL && g1.right == NULL ) return g2;
  323. if ( g2.left == NULL && g2.right == NULL ) return g1;
  324. ((Junction *)g1.right)->p1 = g2.left;
  325. g.left = g1.left;
  326. g.right = g2.right;
  327. return g;
  328. }
  329. /*
  330.  * Make a subgraph an optional block
  331.  *
  332.  * makeOpt(G) ::= --o-->o-G-o-->o--
  333.  *                      |      ^
  334.  * v       |
  335.  *     o-------o
  336.  *
  337.  * Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found.
  338.  *
  339.  * The node on the far right is added so that every block owns its own
  340.  * EndBlk node.
  341.  */
  342. Graph
  343. #ifdef __STDC__
  344. makeOpt( Graph g1, int approx )
  345. #else
  346. makeOpt( g1, approx )
  347. Graph g1;
  348. int approx;
  349. #endif
  350. {
  351. Junction *j1,*j2,*p;
  352. Graph g;
  353. require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph");
  354. j1 = newJunction();
  355. j2 = newJunction();
  356. ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
  357. g = emptyAlt();
  358. if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
  359. ((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1;
  360. for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2)
  361. {;} /* find last alt */
  362. p->p2 = g.left; /* add optional alternative */
  363. ((Junction *)g.right)->p1 = (Node *)j2; /* opt alt points to EndBlk */
  364. g1.right = (Node *)j2;
  365. SetBlk(g1, aOptBlk, approx);
  366. j1->p1 = g1.left; /* add generic node in front */
  367. g.left = (Node *) j1;
  368. g.right = g1.right;
  369. return g;
  370. }
  371. /*
  372.  * Make a graph into subblock
  373.  *
  374.  * makeBlk(G) ::= --o-->o-G-o-->o--
  375.  *
  376.  * The node on the far right is added so that every block owns its own
  377.  * EndBlk node.
  378.  */
  379. Graph
  380. #ifdef __STDC__
  381. makeBlk( Graph g1, int approx )
  382. #else
  383. makeBlk( g1, approx )
  384. Graph g1;
  385. int approx;
  386. #endif
  387. {
  388. Junction *j,*j2;
  389. Graph g;
  390. require(g1.left != NULL && g1.right != NULL, "makeBlk: invalid graph");
  391. j = newJunction();
  392. j2 = newJunction();
  393. ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
  394. g1.right = (Node *)j2;
  395. SetBlk(g1, aSubBlk, approx);
  396. j->p1 = g1.left; /* add node in front */
  397. g.left = (Node *) j;
  398. g.right = g1.right;
  399. return g;
  400. }
  401. /*
  402.  * Make a subgraph into a loop (closure) block -- (...)*
  403.  *
  404.  * makeLoop(G) ::=       |---|
  405.  *      v   |
  406.  *    --o-->o-->o-G-o-->o--
  407.  *                   |           ^
  408.  *                   v           |
  409.  *  o-----------o
  410.  *
  411.  * After making loop, always place generic node out front.  It becomes
  412.  * the start of enclosing block.  The aLoopBlk is the target of the loop.
  413.  *
  414.  * Loop blks have TWO EndBlk nodes--the far right and the node that loops back
  415.  * to the aLoopBlk node.  Node with which we can branch past loop == aLoopBegin and
  416.  * one which is loop target == aLoopBlk.
  417.  * The branch-past (initial) aLoopBegin node has end
  418.  * pointing to the last EndBlk node.  The loop-target node has end==NULL.
  419.  *
  420.  * Loop blocks have a set of locks (from 1..CLL_k) on the aLoopBlk node.
  421.  */
  422. Graph
  423. #ifdef __STDC__
  424. makeLoop( Graph g1, int approx )
  425. #else
  426. makeLoop( g1, approx )
  427. Graph g1;
  428. int approx;
  429. #endif
  430. {
  431. Junction *back, *front, *begin;
  432. Graph g;
  433. require(g1.left != NULL && g1.right != NULL, "makeLoop: invalid graph");
  434. back = newJunction();
  435. front = newJunction();
  436. begin = newJunction();
  437. g = emptyAlt();
  438. ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */
  439. ((Junction *)g1.right)->p1 = (Node *) back; /* add node to G at end */
  440. ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */
  441. ((Junction *)g1.left)->jtype = aLoopBlk; /* mark 2nd aLoopBlk node */
  442. ((Junction *)g1.left)->end = (Junction *) g1.right;
  443. ((Junction *)g1.left)->lock = makelocks();
  444. ((Junction *)g1.left)->pred_lock = makelocks();
  445. g1.right = (Node *) back;
  446. begin->p1 = (Node *) g1.left;
  447. g1.left = (Node *) begin;
  448. begin->p2 = (Node *) g.left; /* make bypass arc */
  449. ((Junction *)g.right)->p1 = (Node *) back;
  450. SetBlk(g1, aLoopBegin, approx);
  451. front->p1 = g1.left; /* add node to front */
  452. g1.left = (Node *) front;
  453. return g1;
  454. }
  455. /*
  456.  * Make a subgraph into a plus block -- (...)+ -- 1 or more times
  457.  *
  458.  * makePlus(G) ::=  |---|
  459.  *  v   |
  460.  *    --o-->o-G-o-->o--
  461.  *
  462.  * After making loop, always place generic node out front.  It becomes
  463.  * the start of enclosing block.  The aPlusBlk is the target of the loop.
  464.  *
  465.  * Plus blks have TWO EndBlk nodes--the far right and the node that loops back
  466.  * to the aPlusBlk node.
  467.  *
  468.  * Plus blocks have a set of locks (from 1..CLL_k) on the aPlusBlk node.
  469.  */
  470. Graph
  471. #ifdef __STDC__
  472. makePlus( Graph g1, int approx )
  473. #else
  474. makePlus( g1, approx )
  475. Graph g1;
  476. int approx;
  477. #endif
  478. {
  479. int has_empty_alt_already = 0;
  480. Graph g;
  481. Junction *j2, *j3, *first_alt;
  482. Junction *last_alt=NULL, *p;
  483. require(g1.left != NULL && g1.right != NULL, "makePlus: invalid graph");
  484. first_alt = (Junction *)g1.left;
  485. j2 = newJunction();
  486. j3 = newJunction();
  487. if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
  488. ((Junction *)g1.right)->p2 = g1.left; /* add loop branch to G */
  489. ((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
  490. ((Junction *)g1.right)->jtype = EndBlk; /* mark 1st EndBlk node */
  491. g1.right = (Node *) j2;
  492. SetBlk(g1, aPlusBlk, approx);
  493. ((Junction *)g1.left)->lock = makelocks();
  494. ((Junction *)g1.left)->pred_lock = makelocks();
  495. j3->p1 = g1.left; /* add node to front */
  496. g1.left = (Node *) j3;
  497. /* add an optional branch which is the "exit" branch of loop */
  498. /* FIRST, check to ensure that there does not already exist
  499.  * an optional path.
  500.  */
  501. /* find last alt */
  502. for(p=first_alt; p!=NULL; p=(Junction *)p->p2)
  503. {
  504. if ( p->p1->ntype == nJunction &&
  505.  p->p1!=NULL &&
  506.  ((Junction *)p->p1)->jtype==Generic &&
  507.  ((Junction *)p->p1)->p1!=NULL &&
  508.  ((Junction *)((Junction *)p->p1)->p1)->jtype==EndBlk )
  509. {
  510. has_empty_alt_already = 1;
  511. }
  512. last_alt = p;
  513. }
  514. if ( !has_empty_alt_already )
  515. {
  516. require(last_alt!=NULL, "last_alt==NULL; bad (..)+");
  517. g = emptyAlt();
  518. last_alt->p2 = g.left;
  519. ((Junction *)g.right)->p1 = (Node *) j2;
  520. /* make sure lookahead computation ignores this alt for
  521. * FIRST("(..)+"); but it's still used for computing the FIRST
  522. * of each alternative.
  523. */
  524. ((Junction *)g.left)->ignore = 1;
  525. }
  526. return g1;
  527. }
  528. /*
  529.  * Return an optional path:  --o-->o--
  530.  */
  531. Graph
  532. #ifdef __STDC__
  533. emptyAlt( void )
  534. #else
  535. emptyAlt( )
  536. #endif
  537. {
  538. Junction *j1, *j2;
  539. Graph g;
  540. j1 = newJunction();
  541. j2 = newJunction();
  542. j1->p1 = (Node *) j2;
  543. g.left = (Node *) j1;
  544. g.right = (Node *) j2;
  545. return g;
  546. }
  547. /* N o d e  A l l o c a t i o n */
  548. TokNode *
  549. #ifdef __STDC__
  550. newTokNode( void )
  551. #else
  552. newTokNode( )
  553. #endif
  554. {
  555. static TokNode *FreeList = NULL;
  556. TokNode *p, *newblk;
  557. if ( FreeList == NULL )
  558. {
  559. newblk = (TokNode *)calloc(TokenBlockAllocSize, sizeof(TokNode));
  560. if ( newblk == NULL )
  561. fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
  562. for (p=newblk; p<&(newblk[TokenBlockAllocSize]); p++)
  563. {
  564. p->next = (Node *)FreeList; /* add all new token nodes to FreeList */
  565. FreeList = p;
  566. }
  567. }
  568. p = FreeList;
  569. FreeList = (TokNode *)FreeList->next;/* remove a TokNode node */
  570. p->next = NULL; /* NULL the ptr we used */
  571.     memset( (char *) p, 0, sizeof(TokNode));        /* MR10 */
  572. p->ntype = nToken;
  573. p->rname = CurRule;
  574. p->file = CurFile;
  575. p->line = zzline;
  576. p->altstart = NULL;
  577. return p;
  578. }
  579. RuleRefNode *
  580. #ifdef __STDC__
  581. newRNode( void )
  582. #else
  583. newRNode( )
  584. #endif
  585. {
  586. static RuleRefNode *FreeList = NULL;
  587. RuleRefNode *p, *newblk;
  588. if ( FreeList == NULL )
  589. {
  590. newblk = (RuleRefNode *)calloc(RRefBlockAllocSize, sizeof(RuleRefNode));
  591. if ( newblk == NULL )
  592. fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
  593. for (p=newblk; p<&(newblk[RRefBlockAllocSize]); p++)
  594. {
  595. p->next = (Node *)FreeList; /* add all new rref nodes to FreeList */
  596. FreeList = p;
  597. }
  598. }
  599. p = FreeList;
  600. FreeList = (RuleRefNode *)FreeList->next;/* remove a Junction node */
  601. p->next = NULL; /* NULL the ptr we used */
  602.     memset( (char *) p, 0, sizeof(RuleRefNode));        /* MR10 */
  603. p->ntype = nRuleRef;
  604. p->rname = CurRule;
  605. p->file = CurFile;
  606. p->line = zzline;
  607. p->astnode = ASTinclude;
  608. p->altstart = NULL;
  609. return p;
  610. }
  611. static int junctionSeqNumber=0;         /* MR10 */
  612. Junction *
  613. #ifdef __STDC__
  614. newJunction( void )
  615. #else
  616. newJunction( )
  617. #endif
  618. {
  619. static Junction *FreeList = NULL;
  620. Junction *p, *newblk;
  621. if ( FreeList == NULL )
  622. {
  623. newblk = (Junction *)calloc(JunctionBlockAllocSize, sizeof(Junction));
  624. if ( newblk == NULL )
  625. fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
  626. for (p=newblk; p<&(newblk[JunctionBlockAllocSize]); p++)
  627. {
  628. p->p1 = (Node *)FreeList; /* add all new Junction nodes to FreeList */
  629. FreeList = p;
  630. }
  631. }
  632. p = FreeList;
  633. FreeList = (Junction *)FreeList->p1;/* remove a Junction node */
  634. p->p1 = NULL; /* NULL the ptr we used */
  635.     memset( (char *) p, 0, sizeof(Junction));       /* MR10 */
  636. p->ntype = nJunction;
  637. p->visited = 0;
  638. p->jtype = Generic;
  639. p->rname = CurRule;
  640. p->file = CurFile;
  641. p->line = zzline;
  642. p->exception_label = NULL;
  643. p->fset = (set *) calloc(CLL_k+1, sizeof(set));
  644. require(p->fset!=NULL, "cannot allocate fset in newJunction");
  645.     p->seq=++junctionSeqNumber;     /* MR10 */
  646. return p;
  647. }
  648. ActionNode *
  649. #ifdef __STDC__
  650. newActionNode( void )
  651. #else
  652. newActionNode( )
  653. #endif
  654. {
  655. static ActionNode *FreeList = NULL;
  656. ActionNode *p, *newblk;
  657. if ( FreeList == NULL )
  658. {
  659. newblk = (ActionNode *)calloc(ActionBlockAllocSize, sizeof(ActionNode));
  660. if ( newblk == NULL )
  661. fatal_internal(eMsg1("out of memory while building rule '%s'",CurRule));
  662. for (p=newblk; p<&(newblk[ActionBlockAllocSize]); p++)
  663. {
  664. p->next = (Node *)FreeList; /* add all new Action nodes to FreeList */
  665. FreeList = p;
  666. }
  667. }
  668. p = FreeList;
  669. FreeList = (ActionNode *)FreeList->next;/* remove an Action node */
  670.     memset( (char *) p, 0, sizeof(ActionNode));     /* MR10 */
  671. p->ntype = nAction;
  672. p->next = NULL; /* NULL the ptr we used */
  673. p->done = 0;
  674. p->pred_fail = NULL;
  675. p->guardpred = NULL;
  676.     p->ampersandPred = NULL;
  677. return p;
  678. }
  679. /*
  680.  * allocate the array of locks (1..CLL_k) used to inhibit infinite recursion.
  681.  * Infinite recursion can occur in (..)* blocks, FIRST calcs and FOLLOW calcs.
  682.  * Therefore, we need locks on aLoopBlk, RuleBlk, EndRule nodes.
  683.  *
  684.  * if ( lock[k]==TRUE ) then we have been here before looking for k tokens
  685.  * of lookahead.
  686.  */
  687. char *
  688. #ifdef __STDC__
  689. makelocks( void )
  690. #else
  691. makelocks( )
  692. #endif
  693. {
  694. char *p = (char *) calloc(CLL_k+1, sizeof(char));
  695. require(p!=NULL, "cannot allocate lock array");
  696. return p;
  697. }
  698. #if 0
  699. ** #ifdef __STDC__
  700. ** void my_memset(char *p,char value,int count)
  701. ** #else
  702. ** void my_memset(p,value,count)
  703. **   char      *p;
  704. **   char      value;
  705. **   int       count;
  706. ** #endif
  707. ** {
  708. **    int      i;
  709. **
  710. **    for (i=0; i<count; i++) {
  711. **     p[i]=value;
  712. **   };
  713. ** }
  714. #endif