fset2.c revision 30fdf1140b8d1ce93f3821d986fa165552023440
1/*
2 * fset2.c
3 *
4 * Compute FIRST sets for full LL(k)
5 *
6 * SOFTWARE RIGHTS
7 *
8 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
9 * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
10 * company may do whatever they wish with source code distributed with
11 * PCCTS or the code generated by PCCTS, including the incorporation of
12 * PCCTS, or its output, into commerical software.
13 *
14 * We encourage users to develop software with PCCTS.  However, we do ask
15 * that credit is given to us for developing PCCTS.  By "credit",
16 * we mean that if you incorporate our source code into one of your
17 * programs (commercial product, research project, or otherwise) that you
18 * acknowledge this fact somewhere in the documentation, research report,
19 * etc...  If you like PCCTS and have developed a nice tool with the
20 * output, please mention that you developed it using PCCTS.  In
21 * addition, we ask that this header remain intact in our source code.
22 * As long as these guidelines are kept, we expect to continue enhancing
23 * this system and expect to make other tools available as they are
24 * completed.
25 *
26 * ANTLR 1.33
27 * Terence Parr
28 * Parr Research Corporation
29 * with Purdue University and AHPCRC, University of Minnesota
30 * 1989-2001
31 */
32
33#include <stdio.h>
34#include "pcctscfg.h"
35#include <stdlib.h>
36
37#ifdef PCCTS_USE_STDARG
38#include <stdarg.h>
39#else
40#include <varargs.h>
41#endif
42
43#include "set.h"
44#include "syn.h"
45#include "hash.h"
46#include "generic.h"
47#include "dlgdef.h"
48
49/* ick! globals.  Used by permute() to track which elements of a set have been used */
50
51static int *findex;
52set *fset;              /* MR11 make global */
53static unsigned **ftbl;
54static set *constrain; /* pts into fset. constrains tToken() to 'constrain' */
55int ConstrainSearch;
56int maxk;               /* set to initial k upon tree construction request */
57                        /* MR11 make global */
58static Tree *FreeList = NULL;
59
60#ifdef __USE_PROTOS
61static int tmember_of_context(Tree *, Predicate *);
62#else
63static int tmember_of_context();
64#endif
65
66#if TREE_DEBUG
67set     set_of_tnodes_in_use;
68int     stop_on_tnode_seq_number=(-1);     /* (-1) to disable */
69#endif
70
71/* Do root
72 * Then each sibling
73 */
74
75void
76#ifdef __USE_PROTOS
77preorder( Tree *tree )
78#else
79preorder( tree )
80Tree *tree;
81#endif
82{
83	if ( tree == NULL ) return;
84	if ( tree->down != NULL ) fprintf(stderr, " (");
85	if ( tree->token == ALT ) fprintf(stderr, " ALT");
86	else fprintf(stderr, " %s", TerminalString(tree->token));
87	if ( tree->token==EpToken ) fprintf(stderr, "(%d)", tree->v.rk);
88	preorder(tree->down);
89	if ( tree->down != NULL ) fprintf(stderr, " )");
90	preorder(tree->right);
91}
92
93#ifdef __USE_PROTOS
94int MR_tree_matches_constraints(int k,set * constrain,Tree *t)
95#else
96int MR_tree_matches_constraints(k,constrain,t)
97  int       k;
98  set *     constrain;
99  Tree *    t;
100#endif
101{
102  int       i;
103  Tree      *u;
104
105  if (k == 0) return 1;
106
107  /* for testing guard predicates: if the guard tree is shorter
108     than the constraint then it is a match.  The reason is that
109     a guard of (A B) should be equivalent to a guard of (A B . . .)
110     where "." matches every token.  Thus a match which runs out
111     of tree before constraint is a match.
112  */
113
114  if (t == NULL) return 1;
115  require (set_deg(constrain[0]) == 1,
116            "MR_tree_matches_constraints: set_deg != 1");
117  i=set_int(constrain[0]);
118  if (t->token != i) return 0;
119  if (k-1 == 0) return 1;
120  for (u=t->down; u != NULL; u=u->right) {
121    if (MR_tree_matches_constraints(k-1,&constrain[1],u)) {
122       return 1;
123    };
124  };
125  return 0;
126}
127
128/* check the depth of each primary sibling to see that it is exactly
129 * k deep. e.g.;
130 *
131 *	ALT
132 *   |
133 *   A ------- B
134 *   |         |
135 *   C -- D    E
136 *
137 * Remove all branches <= k deep.
138 *
139 * Added by TJP 9-23-92 to make the LL(k) constraint mechanism to work.
140 */
141
142static int pruneCount=0;
143static int prunePeak=200;
144
145Tree *
146#ifdef __USE_PROTOS
147prune( Tree *t, int k )
148#else
149prune( t, k )
150Tree *t;
151int k;
152#endif
153{
154    pruneCount++;
155    if (pruneCount > prunePeak+100) {
156      prunePeak=pruneCount;
157#if 0
158***   fprintf(stderr,"pruneCount=%d\n",pruneCount);
159/***  preorder(t);   ***/
160***   fprintf(stderr,"\n",pruneCount);
161#endif
162    };
163    if ( t == NULL ) {
164        pruneCount--;
165        return NULL;
166    };
167    if ( t->token == ALT ) fatal_internal("prune: ALT node in FIRST tree");
168    if ( t->right!=NULL ) t->right = prune(t->right, k);
169    if ( k>1 )
170	{
171		if ( t->down!=NULL ) t->down = prune(t->down, k-1);
172		if ( t->down == NULL )
173		{
174			Tree *r = t->right;
175			t->right = NULL;
176			Tfree(t);
177            pruneCount--;
178			return r;
179		}
180	}
181    pruneCount--;
182    return t;
183}
184
185/* build a tree (root child1 child2 ... NULL) */
186#ifdef PCCTS_USE_STDARG
187Tree *tmake(Tree *root, ...)
188#else
189Tree *tmake(va_alist)
190va_dcl
191#endif
192{
193	Tree *w;
194	va_list ap;
195	Tree *child, *sibling=NULL, *tail=NULL;
196#ifndef PCCTS_USE_STDARG
197	Tree *root;
198#endif
199
200#ifdef PCCTS_USE_STDARG
201	va_start(ap, root);
202#else
203	va_start(ap);
204	root = va_arg(ap, Tree *);
205#endif
206	child = va_arg(ap, Tree *);
207	while ( child != NULL )
208	{
209#ifdef DUM
210		/* added "find end of child" thing TJP March 1994 */
211		for (w=child; w->right!=NULL; w=w->right) {;} /* find end of child */
212#else
213		w = child;
214#endif
215
216		if ( sibling == NULL ) {sibling = child; tail = w;}
217		else {tail->right = child; tail = w;}
218		child = va_arg(ap, Tree *);
219	}
220
221	/* was "root->down = sibling;" */
222	if ( root==NULL ) root = sibling;
223	else root->down = sibling;
224
225	va_end(ap);
226	return root;
227}
228
229Tree *
230#ifdef __USE_PROTOS
231tnode( int tok )
232#else
233tnode( tok )
234int tok;
235#endif
236{
237	Tree *p, *newblk;
238	static int n=0;
239
240	if ( FreeList == NULL )
241	{
242		/*fprintf(stderr, "tnode: %d more nodes\n", TreeBlockAllocSize);*/
243		if ( TreeResourceLimit > 0 )
244		{
245			if ( (n+TreeBlockAllocSize) >= TreeResourceLimit )
246			{
247				fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);
248				fprintf(stderr, " hit analysis resource limit while analyzing alts %d and %d %s\n",
249								CurAmbigAlt1,
250								CurAmbigAlt2,
251								CurAmbigbtype);
252				exit(PCCTS_EXIT_FAILURE);
253			}
254		}
255		newblk = (Tree *)calloc(TreeBlockAllocSize, sizeof(Tree));
256		if ( newblk == NULL )
257		{
258			fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);
259			fprintf(stderr, " out of memory while analyzing alts %d and %d %s\n",
260							CurAmbigAlt1,
261							CurAmbigAlt2,
262							CurAmbigbtype);
263			exit(PCCTS_EXIT_FAILURE);
264		}
265		n += TreeBlockAllocSize;
266		for (p=newblk; p<&(newblk[TreeBlockAllocSize]); p++)
267		{
268			p->right = FreeList;	/* add all new Tree nodes to Free List */
269			FreeList = p;
270		}
271	}
272	p = FreeList;
273	FreeList = FreeList->right;		/* remove a tree node */
274	p->right = NULL;				/* zero out ptrs */
275	p->down = NULL;
276	p->token = tok;
277
278    TnodesAllocated++;                                      /* MR10 */
279    TnodesInUse++;                                          /* MR10 */
280    if (TnodesInUse > TnodesPeak) TnodesPeak=TnodesInUse;   /* MR10 */
281
282#ifdef TREE_DEBUG
283	require(!p->in_use, "tnode: node in use!");
284	p->in_use = 1;
285    p->seq=TnodesAllocated;
286    set_orel( (unsigned) TnodesAllocated,&set_of_tnodes_in_use);
287    if (stop_on_tnode_seq_number == p->seq) {
288      fprintf(stderr,"\n*** just allocated tnode #%d ***\n",
289            stop_on_tnode_seq_number);
290    };
291#endif
292	return p;
293}
294
295static Tree *
296#ifdef __USE_PROTOS
297eofnode( int k )
298#else
299eofnode( k )
300int k;
301#endif
302{
303	Tree *t=NULL;
304	int i;
305
306	for (i=1; i<=k; i++)
307	{
308		t = tmake(tnode((TokenInd!=NULL?TokenInd[EofToken]:EofToken)), t, NULL);
309	}
310	return t;
311}
312
313
314
315void
316#ifdef __USE_PROTOS
317_Tfree( Tree *t )
318#else
319_Tfree( t )
320Tree *t;
321#endif
322{
323	if ( t!=NULL )
324	{
325#ifdef TREE_DEBUG
326        if (t->seq == stop_on_tnode_seq_number) {
327           fprintf(stderr,"\n*** just freed tnode #%d ***\n",t->seq);
328        };
329		require(t->in_use, "_Tfree: node not in use!");
330		t->in_use = 0;
331        set_rm( (unsigned) t->seq,set_of_tnodes_in_use);
332#endif
333		t->right = FreeList;
334		FreeList = t;
335        TnodesInUse--;                   /* MR10 */
336	}
337}
338
339/* tree duplicate */
340Tree *
341#ifdef __USE_PROTOS
342tdup( Tree *t )
343#else
344tdup( t )
345Tree *t;
346#endif
347{
348	Tree *u;
349
350	if ( t == NULL ) return NULL;
351	u = tnode(t->token);
352	u->v.rk = t->v.rk;
353	u->right = tdup(t->right);
354	u->down = tdup(t->down);
355	return u;
356}
357
358/* tree duplicate (assume tree is a chain downwards) */
359Tree *
360#ifdef __USE_PROTOS
361tdup_chain( Tree *t )
362#else
363tdup_chain( t )
364Tree *t;
365#endif
366{
367	Tree *u;
368
369	if ( t == NULL ) return NULL;
370	u = tnode(t->token);
371	u->v.rk = t->v.rk;
372	u->down = tdup(t->down);
373	return u;
374}
375
376Tree *
377#ifdef __USE_PROTOS
378tappend( Tree *t, Tree *u )
379#else
380tappend( t, u )
381Tree *t;
382Tree *u;
383#endif
384{
385	Tree *w;
386
387/*** fprintf(stderr, "tappend(");
388 *** preorder(t); fprintf(stderr, ",");
389 *** preorder(u); fprintf(stderr, " )\n");
390*/
391	if ( t == NULL ) return u;
392	if ( t->token == ALT && t->right == NULL ) return tappend(t->down, u);
393	for (w=t; w->right!=NULL; w=w->right) {;}
394	w->right = u;
395	return t;
396}
397
398/* dealloc all nodes in a tree */
399void
400#ifdef __USE_PROTOS
401Tfree( Tree *t )
402#else
403Tfree( t )
404Tree *t;
405#endif
406{
407	if ( t == NULL ) return;
408	Tfree( t->down );
409	Tfree( t->right );
410	_Tfree( t );
411}
412
413/* find all children (alts) of t that require remaining_k nodes to be LL_k
414 * tokens long.
415 *
416 * t-->o
417 *     |
418 *     a1--a2--...--an		<-- LL(1) tokens
419 *     |   |        |
420 *     b1  b2  ...  bn		<-- LL(2) tokens
421 *     |   |        |
422 *     .   .        .
423 *     .   .        .
424 *     z1  z2  ...  zn		<-- LL(LL_k) tokens
425 *
426 * We look for all [Ep] needing remaining_k nodes and replace with u.
427 * u is not destroyed or actually used by the tree (a copy is made).
428 */
429Tree *
430#ifdef __USE_PROTOS
431tlink( Tree *t, Tree *u, int remaining_k )
432#else
433tlink( t, u, remaining_k )
434Tree *t;
435Tree *u;
436int remaining_k;
437#endif
438{
439	Tree *p;
440	require(remaining_k!=0, "tlink: bad tree");
441
442	if ( t==NULL ) return NULL;
443	/*fprintf(stderr, "tlink: u is:"); preorder(u); fprintf(stderr, "\n");*/
444	if ( t->token == EpToken && t->v.rk == remaining_k )
445	{
446		require(t->down==NULL, "tlink: invalid tree");
447		if ( u == NULL ) {
448/* MR10 */  Tree  *tt=t->right;
449/* MR10 */  _Tfree(t);
450/* MR10 */  return tt;
451        };
452		p = tdup( u );
453		p->right = t->right;
454		_Tfree( t );
455		return p;
456	}
457	t->down = tlink(t->down, u, remaining_k);
458	t->right = tlink(t->right, u, remaining_k);
459	return t;
460}
461
462/* remove as many ALT nodes as possible while still maintaining semantics */
463Tree *
464#ifdef __USE_PROTOS
465tshrink( Tree *t )
466#else
467tshrink( t )
468Tree *t;
469#endif
470{
471	if ( t == NULL ) return NULL;
472	t->down = tshrink( t->down );
473	t->right = tshrink( t->right );
474	if ( t->down == NULL )
475	{
476		if ( t->token == ALT )
477		{
478			Tree *u = t->right;
479			_Tfree(t);
480			return u;			/* remove useless alts */
481		}
482		return t;
483	}
484
485	/* (? (ALT (? ...)) s) ==> (? (? ...) s) where s = sibling, ? = match any */
486	if ( t->token == ALT && t->down->right == NULL)
487	{
488		Tree *u = t->down;
489		u->right = t->right;
490		_Tfree( t );
491		return u;
492	}
493	/* (? (A (ALT t)) s) ==> (? (A t) s) where A is a token; s,t siblings */
494	if ( t->token != ALT && t->down->token == ALT && t->down->right == NULL )
495	{
496		Tree *u = t->down->down;
497		_Tfree( t->down );
498		t->down = u;
499		return t;
500	}
501	return t;
502}
503
504Tree *
505#ifdef __USE_PROTOS
506tflatten( Tree *t )
507#else
508tflatten( t )
509Tree *t;
510#endif
511{
512	if ( t == NULL ) return NULL;
513	t->down = tflatten( t->down );
514	t->right = tflatten( t->right );
515	if ( t->down == NULL ) return t;
516
517	if ( t->token == ALT )
518	{
519		Tree *u;
520		/* find tail of children */
521		for (u=t->down; u->right!=NULL; u=u->right) {;}
522		u->right = t->right;
523		u = t->down;
524		_Tfree( t );
525		return u;
526	}
527	return t;
528}
529
530Tree *
531#ifdef __USE_PROTOS
532tJunc( Junction *p, int k, set *rk )
533#else
534tJunc( p, k, rk )
535Junction *p;
536int k;
537set *rk;
538#endif
539{
540	Tree *t=NULL, *u=NULL;
541	Junction *alt;
542	Tree *tail=NULL, *r;
543
544#ifdef DBG_TRAV
545	fprintf(stderr, "tJunc(%d): %s in rule %s\n", k,
546			decodeJType[p->jtype], ((Junction *)p)->rname);
547#endif
548
549/* MR14 */    if (AlphaBetaTrace && p->alpha_beta_guess_end) {
550/* MR14 */         warnFL(
551/* MR14 */           "not possible to compute follow set for alpha in an \"(alpha)? beta\" block.  ",
552/* MR14 */                 FileStr[p->file],p->line);
553/* MR14 */         MR_alphaBetaTraceReport();
554/* MR14 */    };
555
556/* MR14 */    if (p->alpha_beta_guess_end) {
557/* MR14 */      return NULL;
558/* MR14 */    }
559
560	if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||
561		 p->jtype==aPlusBlk || p->jtype==aSubBlk || p->jtype==aOptBlk )
562	{
563		if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) {
564			require(p->lock!=NULL, "rJunc: lock array is NULL");
565			if ( p->lock[k] ) return NULL;
566			p->lock[k] = TRUE;
567		}
568
569/* MR10 */    if (MR_MaintainBackTrace) {
570/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
571/* MR10 */    };
572
573		TRAV(p->p1, k, rk, tail);
574
575/* MR10 */    if (MR_MaintainBackTrace) {
576/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
577/* MR10 */    };
578
579		if ( p->jtype==RuleBlk ) {p->lock[k] = FALSE; return tail;}
580		r = tmake(tnode(ALT), tail, NULL);
581		for (alt=(Junction *)p->p2; alt!=NULL; alt = (Junction *)alt->p2)
582		{
583			/* if this is one of the added optional alts for (...)+ then break */
584			if ( alt->ignore ) break;
585
586			if ( tail==NULL ) {TRAV(alt->p1, k, rk, tail); r->down = tail;}
587			else
588			{
589/* MR10 */    if (MR_MaintainBackTrace) {
590/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
591/* MR10 */    };
592
593				TRAV(alt->p1, k, rk, tail->right);
594
595/* MR10 */    if (MR_MaintainBackTrace) {
596/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
597/* MR10 */    };
598				if ( tail->right != NULL ) tail = tail->right;
599			}
600		}
601		if ( p->jtype!=aSubBlk && p->jtype!=aOptBlk ) p->lock[k] = FALSE;
602#ifdef DBG_TREES
603		fprintf(stderr, "blk(%s) returns:",((Junction *)p)->rname); preorder(r); fprintf(stderr, "\n");
604#endif
605		if ( r->down == NULL ) {_Tfree(r); return NULL;}
606		return r;
607	}
608
609	if ( p->jtype==EndRule )
610	{
611		if ( p->halt )						/* don't want FOLLOW here? */
612		{
613/****		if ( ContextGuardTRAV ) return NULL; ****/
614			set_orel( (unsigned) k, rk);	/* indicate this k value needed */ /* MR10 cast */
615			t = tnode(EpToken);
616			t->v.rk = k;
617			return t;
618		}
619		require(p->lock!=NULL, "rJunc: lock array is NULL");
620		if ( p->lock[k] ) return NULL;
621		/* if no FOLLOW assume k EOF's */
622		if ( p->p1 == NULL ) return eofnode(k);
623		p->lock[k] = TRUE;
624	}
625
626/* MR14 */	if (p->p1 != NULL && p->guess &&  p->guess_analysis_point == NULL) {
627/* MR14 */    Node * guess_point;
628/* MR14 */    guess_point=(Node *)analysis_point(p);
629/* MR14 */    if (guess_point == (Node *)p) {
630/* MR14 */      guess_point=p->p1;
631/* MR14 */    }
632/* MR14 */    p->guess_analysis_point=guess_point;
633/* MR14 */  }
634
635	if ( p->p2 == NULL )
636	{
637
638/* MR10 */    if (MR_MaintainBackTrace) {
639/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
640/* MR10 */    };
641
642/* M14 */        if (p->guess_analysis_point != NULL) {
643/* M14 */ 		   TRAV(p->guess_analysis_point, k, rk,t);
644/* M14 */        } else {
645        		   TRAV(p->p1, k, rk,t);
646/* M14 */        }
647
648/* MR10 */    if (MR_MaintainBackTrace) {
649/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
650/* MR10 */    };
651
652		if ( p->jtype==EndRule ) p->lock[k]=FALSE;
653		return t;
654	}
655
656/* MR10 */    if (MR_MaintainBackTrace) {
657/* MR10 */      if (p->jtype != Generic) MR_pointerStackPush(&MR_BackTraceStack,p);
658/* MR10 */    };
659
660/* M14 */        if (p->guess_analysis_point != NULL) {
661/* M14 */ 		   TRAV(p->guess_analysis_point, k, rk,t);
662/* M14 */        } else {
663        		   TRAV(p->p1, k, rk,t);
664/* M14 */        }
665
666/* MR10 */    if (MR_MaintainBackTrace) {
667/* MR10 */      if (p->jtype != Generic) MR_pointerStackPop(&MR_BackTraceStack);
668/* MR10 */    };
669
670	if ( p->jtype!=RuleBlk && /* MR14 */ !p->guess) TRAV(p->p2, k, rk, u);
671
672	if ( p->jtype==EndRule ) p->lock[k] = FALSE;/* unlock node */
673
674	if ( t==NULL ) return tmake(tnode(ALT), u, NULL);
675	return tmake(tnode(ALT), t, u, NULL);
676}
677
678Tree *
679#ifdef __USE_PROTOS
680tRuleRef( RuleRefNode *p, int k, set *rk_out )
681#else
682tRuleRef( p, k, rk_out )
683RuleRefNode *p;
684int k;
685set *rk_out;
686#endif
687{
688	int k2;
689	Tree *t=NULL, *u=NULL;
690	Junction *r;
691	set rk, rk2;
692	int save_halt;
693	RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
694
695#ifdef DBG_TRAV
696	fprintf(stderr, "tRuleRef: %s\n", p->text);
697#endif
698	if ( q == NULL )
699	{
700		TRAV(p->next, k, rk_out, t);/* ignore undefined rules */
701		return t;
702	}
703	rk = rk2 = empty;
704    if (RulePtr == NULL) fatal("RulePtr==NULL");
705	r = RulePtr[q->rulenum];
706	if ( r->lock[k] ) return NULL;
707	save_halt = r->end->halt;
708	r->end->halt = TRUE;		/* don't let reach fall off end of rule here */
709
710/* MR10 */    if (MR_MaintainBackTrace) {
711/* MR10 */      MR_pointerStackPush(&MR_BackTraceStack,p);
712/* MR10 */    };
713
714	TRAV(r, k, &rk, t);
715
716/* MR10 */    if (MR_MaintainBackTrace) {
717/* MR10 */      MR_pointerStackPop(&MR_BackTraceStack);
718/* MR10 */    };
719
720	r->end->halt = save_halt;
721#ifdef DBG_TREES
722	fprintf(stderr, "after ruleref, t is:"); preorder(t); fprintf(stderr, "\n");
723#endif
724	t = tshrink( t );
725	while ( !set_nil(rk) ) {	/* any k left to do? if so, link onto tree */
726		k2 = set_int(rk);
727		set_rm(k2, rk);
728
729/* MR10 */    if (MR_MaintainBackTrace) {
730/* MR10 */      MR_pointerStackPush(&MR_BackTraceStack,p);
731/* MR10 */    };
732
733		TRAV(p->next, k2, &rk2, u);
734
735/* MR10 */    if (MR_MaintainBackTrace) {
736/* MR10 */      MR_pointerStackPop(&MR_BackTraceStack);
737/* MR10 */    };
738
739		t = tlink(t, u, k2);	/* any alts missing k2 toks, add u onto end */
740        Tfree(u);               /* MR10 */
741	}
742	set_free(rk);				/* rk is empty, but free it's memory */
743	set_orin(rk_out, rk2);		/* remember what we couldn't do */
744	set_free(rk2);
745	return t;
746}
747
748Tree *
749#ifdef __USE_PROTOS
750tToken( TokNode *p, int k, set *rk )
751#else
752tToken( p, k, rk )
753TokNode *p;
754int k;
755set *rk;
756#endif
757{
758	Tree *t=NULL, *tset=NULL, *u;
759
760	if (ConstrainSearch) {
761      if (MR_AmbSourceSearch) {
762		require(constrain>=fset&&constrain<=&(fset[CLL_k]),"tToken: constrain is not a valid set");
763      } else {
764		require(constrain>=fset&&constrain<=&(fset[LL_k]),"tToken: constrain is not a valid set");
765      };
766      constrain = &fset[maxk-k+1];
767	}
768
769#ifdef DBG_TRAV
770        	fprintf(stderr, "tToken(%d): %s\n", k, TerminalString(p->token));
771        	if ( ConstrainSearch ) {
772        		fprintf(stderr, "constrain is:"); s_fprT(stderr, *constrain); fprintf(stderr, "\n");
773        	}
774#endif
775
776	/* is it a meta token (set of tokens)? */
777
778	if ( !set_nil(p->tset) )
779	{
780		unsigned e=0;
781		set a;
782		Tree *n, *tail = NULL;
783
784		if ( ConstrainSearch ) {
785          a = set_and(p->tset, *constrain);
786          if (set_nil(a)) {         /* MR10 */
787            set_free(a);            /* MR11 */
788            return NULL;            /* MR10 */
789          };                        /* MR10 */
790		} else {
791          a = set_dup(p->tset);
792        };
793
794		for (; !set_nil(a); set_rm(e, a))
795		{
796			e = set_int(a);
797			n = tnode(e);
798			if ( tset==NULL ) { tset = n; tail = n; }
799			else { tail->right = n; tail = n; }
800		}
801		set_free( a );
802	}
803	else if ( ConstrainSearch && !set_el(p->token, *constrain) )
804    {
805/*      fprintf(stderr, "ignoring token %s(%d)\n", TerminalString(p->token),
806                k);*/
807        return NULL;
808    }
809	else {
810        tset = tnode( p->token );
811    };
812
813/* MR10 */    if (MR_MaintainBackTrace) {
814/* MR10 */      if (k == 1) {
815/* MR10 */        MR_pointerStackPush(&MR_BackTraceStack,p);
816/* MR13 */        if (MR_SuppressSearch) {
817/* MR13 */          MR_suppressSearchReport();
818/* MR13 */        } else {
819/* MR10 */          MR_backTraceReport();
820/* MR13 */        };
821/* MR10 */        MR_pointerStackPop(&MR_BackTraceStack);
822/* MR11 */        Tfree(tset);
823/* MR11 */        return NULL;
824/* MR10 */      };
825/* MR10 */    };
826
827	if ( k == 1 ) return tset;
828
829    if (MR_MaintainBackTrace) {
830      MR_pointerStackPush(&MR_BackTraceStack,p);
831    };
832
833	TRAV(p->next, k-1, rk, t);
834
835    if (MR_MaintainBackTrace) {
836      Tfree(t);
837      Tfree(tset);
838      MR_pointerStackPop(&MR_BackTraceStack);
839      return NULL;
840    };
841
842	/* here, we are positive that, at least, this tree will not contribute
843	 * to the LL(2) tree since it will be too shallow, IF t==NULL.
844	 * If doing a context guard walk, then don't prune.
845	 */
846	if ( t == NULL && !ContextGuardTRAV )	/* tree will be too shallow */
847	{
848		if ( tset!=NULL ) Tfree( tset );
849		return NULL;
850	}
851#ifdef DBG_TREES
852	fprintf(stderr, "tToken(%d)->next:",k); preorder(t); fprintf(stderr, "\n");
853#endif
854
855	/* if single token root, then just make new tree and return */
856    /* MR10 - set_nil(p->tset) isn't a good test because of ConstraintSearch */
857
858	if (tset->right == NULL) return tmake(tset, t, NULL);    /* MR10 */
859
860	/* here we must make a copy of t as a child of each element of the tset;
861	 * e.g., "T1..T3 A" would yield ( nil ( T1 A ) ( T2 A ) ( T3 A ) )
862	 */
863	for (u=tset; u!=NULL; u=u->right)
864	{
865		/* make a copy of t and hook it onto bottom of u */
866		u->down = tdup(t);
867	}
868	Tfree( t );
869#ifdef DBG_TREES
870	fprintf(stderr, "range is:"); preorder(tset); fprintf(stderr, "\n");
871#endif
872	return tset;
873}
874
875Tree *
876#ifdef __USE_PROTOS
877tAction( ActionNode *p, int k, set *rk )
878#else
879tAction( p, k, rk )
880ActionNode *p;
881int k;
882set *rk;
883#endif
884{
885	Tree        *t=NULL;
886    set         *save_fset=NULL;
887    int         i;
888
889	/* fprintf(stderr, "tAction\n"); */
890
891/*  An MR_SuppressSearch is looking for things that can be
892      reached even when the predicate is false.
893
894    There are three kinds of predicates:
895        plain:              r1: <<p>>? r2
896        guarded:            r1: (A)? => <<p>>? r2
897        ampersand style:    r1: (A)? && <<p>>? r2
898
899    Of the three kinds of predicates, only a guard predicate
900      has things which are reachable even when the predicate
901      is false.  To be reachable the constraint must *not*
902      match the guard.
903
904*/
905
906    if (p->is_predicate && MR_SuppressSearch) {
907
908      Predicate     *pred=p->guardpred;
909
910      if (pred == NULL) {
911        t=NULL;
912        goto EXIT;
913      };
914      constrain = &fset[maxk-k+1];
915      if (pred->k == 1) {
916        set     dif;
917        dif=set_dif(*constrain,pred->scontext[1]);
918        if (set_nil(dif)) {
919          set_free(dif);
920          t=NULL;
921          goto EXIT;
922        };
923        set_free(dif);
924      } else {
925        if (MR_tree_matches_constraints(k,constrain,pred->tcontext)) {
926          t=NULL;
927          goto EXIT;
928        };
929      }
930    };
931
932    /* The ampersand predicate differs from the
933         other predicates because its first set
934         is a subset of the first set behind the predicate
935
936            r1: (A)? && <<p>>? r2 ;
937            r2: A | B;
938
939       In this case first[1] of r1 is A, even
940         though first[1] of r2 is {A B}.
941    */
942
943    if (p->is_predicate && p->ampersandPred != NULL) {
944
945      Predicate     *pred=p->ampersandPred;
946      Tree          *tAND;
947      Tree          *tset;
948
949      if (k <= pred->k) {
950        if (MR_MaintainBackTrace) MR_pointerStackPush(&MR_BackTraceStack,p);
951        TRAV(p->guardNodes,k,rk,t);
952        if (MR_MaintainBackTrace) MR_pointerStackPop(&MR_BackTraceStack);
953        return t;
954      } else {
955        require (k>1,"tAction for ampersandpred: k <= 1");
956        if (ConstrainSearch) {
957          if (MR_AmbSourceSearch) {
958    		require(constrain>=fset&&constrain<=&(fset[CLL_k]),
959                                "tToken: constrain is not a valid set");
960          } else {
961    		require(constrain>=fset&&constrain<=&(fset[LL_k]),
962                                "tToken: constrain is not a valid set");
963          };
964          save_fset=(set *) calloc (CLL_k+1,sizeof(set));
965          require (save_fset != NULL,"tAction save_fset alloc");
966          for (i=1; i <= CLL_k ; i++) {
967            save_fset[i]=set_dup(fset[i]);
968          };
969          if (pred->k == 1) {
970            constrain = &fset[maxk-k+1];
971            set_andin(constrain,pred->scontext[1]);
972            if (set_nil(*constrain)) {
973              t=NULL;
974              goto EXIT;
975            };
976          } else {
977            constrain = &fset[maxk-k+1];
978            if (! MR_tree_matches_constraints(pred->k,constrain,pred->tcontext)) {
979               t=NULL;
980               goto EXIT;
981            };  /* end loop on i          */
982          }; /* end loop on pred scontext/tcontext */
983        }; /* end if on k > pred->k     */
984      }; /* end if on constrain search  */
985
986      TRAV(p->next,k,rk,t);
987
988      if (t != NULL) {
989        t=tshrink(t);
990        t=tflatten(t);
991        t=tleft_factor(t);
992        if (pred->tcontext != NULL) {
993          tAND=MR_computeTreeAND(t,pred->tcontext);
994        } else {
995          tset=MR_make_tree_from_set(pred->scontext[1]);
996          tAND=MR_computeTreeAND(t,tset);
997          Tfree(tset);
998        };
999        Tfree(t);
1000        t=tAND;
1001      };
1002      goto EXIT;
1003
1004    }; /* end if on ampersand predicate */
1005
1006    TRAV(p->next,k,rk,t);
1007
1008EXIT:
1009    if (save_fset != NULL) {
1010      for (i=1 ; i <= CLL_k ; i++) {
1011        set_free(fset[i]);
1012        fset[i]=save_fset[i];
1013      };
1014      free ( (char *) save_fset);
1015    };
1016	return t;
1017}
1018
1019/* see if e exists in s as a possible input permutation (e is always a chain) */
1020
1021int
1022#ifdef __USE_PROTOS
1023tmember( Tree *e, Tree *s )
1024#else
1025tmember( e, s )
1026Tree *e;
1027Tree *s;
1028#endif
1029{
1030	if ( e==NULL||s==NULL ) return 0;
1031/** fprintf(stderr, "tmember(");
1032***	preorder(e); fprintf(stderr, ",");
1033***	preorder(s); fprintf(stderr, " )\n");
1034*/
1035	if ( s->token == ALT && s->right == NULL ) return tmember(e, s->down);
1036	if ( e->token!=s->token )
1037	{
1038		if ( s->right==NULL ) return 0;
1039		return tmember(e, s->right);
1040	}
1041	if ( e->down==NULL && s->down == NULL ) return 1;
1042	if ( tmember(e->down, s->down) ) return 1;
1043	if ( s->right==NULL ) return 0;
1044	return tmember(e, s->right);
1045}
1046
1047/* see if e exists in s as a possible input permutation (e is always a chain);
1048 * Only check s to the depth of e.  In other words, 'e' can be a shorter
1049 * sequence than s.
1050 */
1051int
1052#ifdef __USE_PROTOS
1053tmember_constrained( Tree *e, Tree *s)
1054#else
1055tmember_constrained( e, s )
1056Tree *e;
1057Tree *s;
1058#endif
1059{
1060	if ( e==NULL||s==NULL ) return 0;
1061/**	fprintf(stderr, "tmember_constrained(");
1062***	preorder(e); fprintf(stderr, ",");
1063***	preorder(s); fprintf(stderr, " )\n");
1064**/
1065	if ( s->token == ALT && s->right == NULL )
1066		return tmember_constrained(e, s->down);
1067	if ( e->token!=s->token )
1068	{
1069		if ( s->right==NULL ) return 0;
1070		return tmember_constrained(e, s->right);
1071	}
1072	if ( e->down == NULL ) return 1; /* if s is matched to depth of e return */
1073	if ( tmember_constrained(e->down, s->down) ) return 1;
1074	if ( s->right==NULL ) return 0;
1075	return tmember_constrained(e, s->right);
1076}
1077
1078/* combine (? (A t) ... (A u) ...) into (? (A t u)) */
1079Tree *
1080#ifdef __USE_PROTOS
1081tleft_factor( Tree *t )
1082#else
1083tleft_factor( t )
1084Tree *t;
1085#endif
1086{
1087	Tree *u, *v, *trail, *w;
1088
1089	/* left-factor what is at this level */
1090	if ( t == NULL ) return NULL;
1091	for (u=t; u!=NULL; u=u->right)
1092	{
1093		trail = u;
1094		v=u->right;
1095		while ( v!=NULL )
1096		{
1097			if ( u->token == v->token )
1098			{
1099				if ( u->down!=NULL )
1100				{
1101					for (w=u->down; w->right!=NULL; w=w->right) {;}
1102					w->right = v->down;	/* link children together */
1103				}
1104				else u->down = v->down;
1105				trail->right = v->right;		/* unlink factored node */
1106				_Tfree( v );
1107				v = trail->right;
1108			}
1109			else {trail = v; v=v->right;}
1110		}
1111	}
1112	/* left-factor what is below */
1113	for (u=t; u!=NULL; u=u->right) u->down = tleft_factor( u->down );
1114	return t;
1115}
1116
1117/* remove the permutation p from t if present */
1118Tree *
1119#ifdef __USE_PROTOS
1120trm_perm( Tree *t, Tree *p )
1121#else
1122trm_perm( t, p )
1123Tree *t;
1124Tree *p;
1125#endif
1126{
1127	/*
1128	fprintf(stderr, "trm_perm(");
1129	preorder(t); fprintf(stderr, ",");
1130	preorder(p); fprintf(stderr, " )\n");
1131	*/
1132	if ( t == NULL || p == NULL ) return NULL;
1133	if ( t->token == ALT )
1134	{
1135		t->down = trm_perm(t->down, p);
1136		if ( t->down == NULL ) 				/* nothing left below, rm cur node */
1137		{
1138			Tree *u = t->right;
1139			_Tfree( t );
1140			return trm_perm(u, p);
1141		}
1142		t->right = trm_perm(t->right, p);	/* look for more instances of p */
1143		return t;
1144	}
1145	if ( p->token != t->token )				/* not found, try a sibling */
1146	{
1147		t->right = trm_perm(t->right, p);
1148		return t;
1149	}
1150	t->down = trm_perm(t->down, p->down);
1151	if ( t->down == NULL ) 					/* nothing left below, rm cur node */
1152	{
1153		Tree *u = t->right;
1154		_Tfree( t );
1155		return trm_perm(u, p);
1156	}
1157	t->right = trm_perm(t->right, p);		/* look for more instances of p */
1158	return t;
1159}
1160
1161/* add the permutation 'perm' to the LL_k sets in 'fset' */
1162void
1163#ifdef __USE_PROTOS
1164tcvt( set *fset, Tree *perm )
1165#else
1166tcvt( fset, perm )
1167set *fset;
1168Tree *perm;
1169#endif
1170{
1171	if ( perm==NULL ) return;
1172	set_orel(perm->token, fset);
1173	tcvt(fset+1, perm->down);
1174}
1175
1176/* for each element of ftbl[k], make it the root of a tree with permute(ftbl[k+1])
1177 * as a child.
1178 */
1179Tree *
1180#ifdef __USE_PROTOS
1181permute( int k, int max_k )
1182#else
1183permute( k, max_k )
1184int k, max_k;
1185#endif
1186{
1187	Tree *t, *u;
1188
1189	if ( k>max_k ) return NULL;
1190	if ( ftbl[k][findex[k]] == nil ) return NULL;
1191	t = permute(k+1, max_k);
1192	if ( t==NULL&&k<max_k )		/* no permutation left below for k+1 tokens? */
1193	{
1194		findex[k+1] = 0;
1195		(findex[k])++;			/* try next token at this k */
1196		return permute(k, max_k);
1197	}
1198
1199	u = tmake(tnode(ftbl[k][findex[k]]), t, NULL);
1200	if ( k == max_k ) (findex[k])++;
1201	return u;
1202}
1203
1204/* Compute LL(k) trees for alts alt1 and alt2 of p.
1205 * function result is tree of ambiguous input permutations
1206 *
1207 * ALGORITHM may change to look for something other than LL_k size
1208 * trees ==> maxk will have to change.
1209 */
1210Tree *
1211#ifdef __USE_PROTOS
1212VerifyAmbig( Junction *alt1, Junction *alt2, unsigned **ft, set *fs, Tree **t, Tree **u, int *numAmbig )
1213#else
1214VerifyAmbig( alt1, alt2, ft, fs, t, u, numAmbig )
1215Junction *alt1;
1216Junction *alt2;
1217unsigned **ft;
1218set *fs;
1219Tree **t;
1220Tree **u;
1221int *numAmbig;
1222#endif
1223{
1224	set rk;
1225	Tree *perm, *ambig=NULL;
1226	Junction *p;
1227	int k;
1228    int    tnodes_at_start=TnodesAllocated;
1229    int    tnodes_at_end;
1230    int    tnodes_used;
1231    set    *save_fs;
1232    int    j;
1233
1234    save_fs=(set *) calloc(CLL_k+1,sizeof(set));
1235    require(save_fs != NULL,"save_fs calloc");
1236
1237    for (j=0; j <= CLL_k ; j++) save_fs[j]=set_dup(fs[j]);
1238
1239	maxk = LL_k;				/* NOTE: for now, we look for LL_k */
1240	ftbl = ft;
1241	fset = fs;
1242	constrain = &(fset[1]);
1243	findex = (int *) calloc(LL_k+1, sizeof(int));
1244	if ( findex == NULL )
1245	{
1246		fprintf(stderr, ErrHdr, FileStr[CurAmbigfile], CurAmbigline);
1247		fprintf(stderr, " out of memory while analyzing alts %d and %d of %s\n",
1248						CurAmbigAlt1,
1249						CurAmbigAlt2,
1250						CurAmbigbtype);
1251		exit(PCCTS_EXIT_FAILURE);
1252	}
1253	for (k=1; k<=LL_k; k++) findex[k] = 0;
1254
1255	rk = empty;
1256	ConstrainSearch = 1;	/* consider only tokens in ambig sets */
1257
1258	p = analysis_point((Junction *)alt1->p1);
1259	TRAV(p, LL_k, &rk, *t);
1260	*t = tshrink( *t );
1261	*t = tflatten( *t );
1262	*t = tleft_factor( *t );    /* MR10 */
1263	*t = prune(*t, LL_k);
1264	*t = tleft_factor( *t );
1265
1266/***	fprintf(stderr, "after shrink&flatten&prune&left_factor:"); preorder(*t); fprintf(stderr, "\n");*/
1267	if ( *t == NULL )
1268	{
1269/***	fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/
1270		Tfree( *t );	/* kill if impossible to have ambig */
1271		*t = NULL;
1272	}
1273
1274	p = analysis_point((Junction *)alt2->p1);
1275
1276	TRAV(p, LL_k, &rk, *u);
1277	*u = tshrink( *u );
1278	*u = tflatten( *u );
1279	*t = tleft_factor( *t );    /* MR10 */
1280	*u = prune(*u, LL_k);
1281	*u = tleft_factor( *u );
1282/*	fprintf(stderr, "after shrink&flatten&prune&lfactor:"); preorder(*u); fprintf(stderr, "\n");*/
1283	if ( *u == NULL )
1284	{
1285/*		fprintf(stderr, "TreeIncomplete --> no LL(%d) ambiguity\n", LL_k);*/
1286		Tfree( *u );
1287		*u = NULL;
1288	}
1289
1290	for (k=1; k<=LL_k; k++) set_clr( fs[k] );
1291
1292	ambig = tnode(ALT);
1293	k = 0;
1294	if ( *t!=NULL && *u!=NULL )
1295	{
1296		while ( (perm=permute(1,LL_k))!=NULL )
1297		{
1298/*			fprintf(stderr, "chk perm:"); preorder(perm); fprintf(stderr, "\n");*/
1299			if ( tmember(perm, *t) && tmember(perm, *u) )
1300			{
1301/*				fprintf(stderr, "ambig upon"); preorder(perm); fprintf(stderr, "\n");*/
1302
1303				k++;
1304				perm->right = ambig->down;
1305				ambig->down = perm;
1306				tcvt(&(fs[1]), perm);
1307			}
1308			else Tfree( perm );
1309		}
1310	}
1311
1312    for (j=0; j <= CLL_k ; j++) fs[j]=save_fs[j];
1313    free( (char *) save_fs);
1314
1315    tnodes_at_end=TnodesAllocated;
1316    tnodes_used=tnodes_at_end - tnodes_at_start;
1317
1318    if (TnodesReportThreshold > 0 && tnodes_used > TnodesReportThreshold) {
1319      fprintf(stdout,"There were %d tuples whose ambiguity could not be resolved by full lookahead\n",k);
1320      fprintf(stdout,"There were %d tnodes created to resolve ambiguity between:\n\n",tnodes_used);
1321      fprintf(stdout,"  Choice 1: %s  line %d  file %s\n",
1322                                 MR_ruleNamePlusOffset( (Node *) alt1),alt1->line,FileStr[alt1->file]);
1323      fprintf(stdout,"  Choice 2: %s  line %d  file %s\n",
1324                                 MR_ruleNamePlusOffset( (Node *) alt2),alt2->line,FileStr[alt2->file]);
1325      for (j=1; j <= CLL_k ; j++) {
1326        fprintf(stdout,"\n    Intersection of lookahead[%d] sets:\n",j);
1327        MR_dumpTokenSet(stdout,2,fs[j]);
1328      };
1329      fprintf(stdout,"\n");
1330    };
1331
1332	*numAmbig = k;
1333	if ( ambig->down == NULL ) {_Tfree(ambig); ambig = NULL;}
1334	free( (char *)findex );
1335/*	fprintf(stderr, "final ambig:"); preorder(ambig); fprintf(stderr, "\n");*/
1336	return ambig;
1337}
1338
1339static Tree *
1340#ifdef __USE_PROTOS
1341bottom_of_chain( Tree *t )
1342#else
1343bottom_of_chain( t )
1344Tree *t;
1345#endif
1346{
1347    if ( t==NULL ) return NULL;
1348    for (; t->down != NULL; t=t->down) {;}
1349    return t;
1350}
1351
1352/*
1353 * Make a tree from k sets where the degree of the first k-1 sets is 1.
1354 */
1355Tree *
1356#ifdef __USE_PROTOS
1357make_tree_from_sets( set *fset1, set *fset2 )
1358#else
1359make_tree_from_sets( fset1, fset2 )
1360set *fset1;
1361set *fset2;
1362#endif
1363{
1364	set inter;
1365	int i;
1366	Tree *t=NULL, *n, *u;
1367	unsigned *p,*q;
1368	require(LL_k>1, "make_tree_from_sets: LL_k must be > 1");
1369
1370	/* do the degree 1 sets first */
1371	for (i=1; i<=LL_k-1; i++)
1372	{
1373		inter = set_and(fset1[i], fset2[i]);
1374		require(set_deg(inter)==1, "invalid set to tree conversion");
1375		n = tnode(set_int(inter));
1376		if (t==NULL) t=n; else tmake(t, n, NULL);
1377		set_free(inter);
1378	}
1379
1380	/* now add the chain of tokens at depth k */
1381	u = bottom_of_chain(t);
1382	inter = set_and(fset1[LL_k], fset2[LL_k]);
1383	if ( (q=p=set_pdq(inter)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
1384	/* first one is linked to bottom, then others are sibling linked */
1385	n = tnode(*p++);
1386	u->down = n;
1387	u = u->down;
1388	while ( *p != nil )
1389	{
1390		n = tnode(*p);
1391		u->right = n;
1392		u = u->right;
1393		p++;
1394	}
1395	free((char *)q);
1396
1397	return t;
1398}
1399
1400/* create and return the tree of lookahead k-sequences that are in t, but not
1401 * in the context of predicates in predicate list p.
1402 */
1403Tree *
1404#ifdef __USE_PROTOS
1405tdif( Tree *ambig_tuples, Predicate *p, set *fset1, set *fset2 )
1406#else
1407tdif( ambig_tuples, p, fset1, fset2 )
1408Tree *ambig_tuples;
1409Predicate *p;
1410set *fset1;
1411set *fset2;
1412#endif
1413{
1414	unsigned **ft;
1415	Tree *dif=NULL;
1416	Tree *perm;
1417	set b;
1418	int i,k;
1419
1420	if ( p == NULL ) return tdup(ambig_tuples);
1421
1422	ft = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *));
1423	require(ft!=NULL, "cannot allocate ft");
1424	for (i=1; i<=CLL_k; i++)
1425	{
1426		b = set_and(fset1[i], fset2[i]);
1427		ft[i] = set_pdq(b);
1428		set_free(b);
1429	}
1430	findex = (int *) calloc(LL_k+1, sizeof(int));
1431	if ( findex == NULL )
1432	{
1433		fatal_internal("out of memory in tdif while checking predicates");
1434	}
1435	for (k=1; k<=LL_k; k++) findex[k] = 0;
1436
1437#ifdef DBG_TRAV
1438	fprintf(stderr, "tdif_%d[", p->k);
1439	preorder(ambig_tuples);
1440	fprintf(stderr, ",");
1441	preorder(p->tcontext);
1442	fprintf(stderr, "] =");
1443#endif
1444
1445	ftbl = ft;
1446	while ( (perm=permute(1,p->k))!=NULL )
1447	{
1448#ifdef DBG_TRAV
1449		fprintf(stderr, "test perm:"); preorder(perm); fprintf(stderr, "\n");
1450#endif
1451		if ( tmember_constrained(perm, ambig_tuples) &&
1452			 !tmember_of_context(perm, p) )
1453		{
1454#ifdef DBG_TRAV
1455			fprintf(stderr, "satisfied upon"); preorder(perm); fprintf(stderr, "\n");
1456#endif
1457			k++;
1458			if ( dif==NULL ) dif = perm;
1459			else
1460			{
1461				perm->right = dif;
1462				dif = perm;
1463			}
1464		}
1465		else Tfree( perm );
1466	}
1467
1468#ifdef DBG_TRAV
1469	preorder(dif);
1470	fprintf(stderr, "\n");
1471#endif
1472
1473	for (i=1; i<=CLL_k; i++) free( (char *)ft[i] );
1474	free((char *)ft);
1475	free((char *)findex);
1476
1477	return dif;
1478}
1479
1480/* is lookahead sequence t a member of any context tree for any
1481 * predicate in p?
1482 */
1483static int
1484#ifdef __USE_PROTOS
1485tmember_of_context( Tree *t, Predicate *p )
1486#else
1487tmember_of_context( t, p )
1488Tree *t;
1489Predicate *p;
1490#endif
1491{
1492	for (; p!=NULL; p=p->right)
1493	{
1494		if ( p->expr==PRED_AND_LIST || p->expr==PRED_OR_LIST )
1495			return tmember_of_context(t, p->down);
1496		if ( tmember_constrained(t, p->tcontext) ) return 1;
1497		if ( tmember_of_context(t, p->down) ) return 1;
1498	}
1499	return 0;
1500}
1501
1502int
1503#ifdef __USE_PROTOS
1504is_single_tuple( Tree *t )
1505#else
1506is_single_tuple( t )
1507Tree *t;
1508#endif
1509{
1510	if ( t == NULL ) return 0;
1511	if ( t->right != NULL ) return 0;
1512	if ( t->down == NULL ) return 1;
1513	return is_single_tuple(t->down);
1514}
1515
1516
1517/* MR10 Check that a context guard contains only allowed things */
1518/* MR10   (mainly token references).                            */
1519
1520#ifdef __USE_PROTOS
1521int contextGuardOK(Node *p,int h,int *hmax)
1522#else
1523int contextGuardOK(p,h,hmax)
1524  Node  *p;
1525  int   h;
1526  int   *hmax;
1527#endif
1528{
1529    Junction     *j;
1530    TokNode      *tn;
1531
1532    if (p == NULL) return 1;
1533    if (p->ntype == nToken) {
1534      h++;
1535      if (h > *hmax) *hmax=h;
1536      tn=(TokNode *)p;
1537      if (tn->el_label != NULL) {
1538        warnFL(eMsg1("a label (\"%s\") for a context guard element is meaningless",tn->el_label),
1539                             FileStr[p->file],p->line);
1540      };
1541      return contextGuardOK( ( (TokNode *) p)->next,h,hmax);
1542    } else if (p->ntype == nAction) {
1543      goto Fail;
1544    } else if (p->ntype == nRuleRef) {
1545      goto Fail;
1546    } else {
1547      require (p->ntype == nJunction,"Unexpected ntype");
1548      j=(Junction *) p;
1549      if (j->jtype != Generic &&
1550          j->jtype != aSubBlk &&        /* pretty sure this one is allowed */
1551/****     j->jtype != aOptBlk && ****/  /* pretty sure this one is allowed */ /* MR11 not any more ! */
1552          j->jtype != EndBlk) {
1553        errFL("A context guard may not contain an option block: {...} or looping block: (...)* or (...)+",
1554                  FileStr[p->file],p->line);
1555        contextGuardOK(j->p1,h,hmax);
1556        return 0;
1557      };
1558      /* do both p1 and p2 so use | rather than ||  */
1559      return contextGuardOK(j->p2,h,hmax) | contextGuardOK(j->p1,h,hmax);
1560    };
1561Fail:
1562    errFL("A context guard may contain only Token references - guard will be ignored",
1563                             FileStr[p->file],p->line);
1564    contextGuardOK( ( (ActionNode *) p)->next,h,hmax);
1565    return 0;
1566}
1567
1568/*
1569 * Look at a (...)? generalized-predicate context-guard and compute
1570 * either a lookahead set (k==1) or a lookahead tree for k>1.  The
1571 * k level is determined by the guard itself rather than the LL_k
1572 * variable.  For example, ( A B )? is an LL(2) guard and ( ID )?
1573 * is an LL(1) guard.  For the moment, you can only have a single
1574 * tuple in the guard.  Physically, the block must look like this
1575 *   --o-->TOKEN-->o-->o-->TOKEN-->o-- ... -->o-->TOKEN-->o--
1576 * An error is printed for any other type.
1577 */
1578Predicate *
1579#ifdef __USE_PROTOS
1580computePredFromContextGuard(Graph blk,int *msgDone)    /* MR10 */
1581#else
1582computePredFromContextGuard(blk,msgDone)               /* MR10 */
1583  Graph     blk;
1584  int       *msgDone;                                       /* MR10 */
1585#endif
1586{
1587    Junction *junc = (Junction *)blk.left, *p;
1588    Tree        *t=NULL;
1589	Predicate   *pred = NULL;
1590	set         scontext, rk;
1591    int         ok;
1592    int         hmax=0;
1593
1594    require(junc!=NULL && junc->ntype == nJunction, "bad context guard");
1595
1596/* MR10 Check for anything other than Tokens and generic junctions */
1597
1598    *msgDone=0;                                             /* MR10 */
1599    ok=contextGuardOK( (Node *)junc,0,&hmax);               /* MR10 */
1600    if (! ok) {                                             /* MR10 */
1601      *msgDone=1;                                           /* MR10 */
1602      return NULL;                                          /* MR10 */
1603    };                                                      /* MR10 */
1604    if (hmax == 0) {
1605errFL("guard is 0 tokens long",FileStr[junc->file],junc->line);          /* MR11 */
1606      *msgDone=1;
1607      return NULL;
1608    };
1609    if (hmax > CLL_k) {                                     /* MR10 */
1610errFL(eMsgd2("guard is %d tokens long - lookahead is limited to max(k,ck)==%d", /* MR10 */
1611        hmax,CLL_k),                                        /* MR10 */
1612        FileStr[junc->file],junc->line);                    /* MR10 */
1613      *msgDone=1;                                           /* MR10 */
1614      return NULL;                                          /* MR10 */
1615    };                                                      /* MR10 */
1616
1617	rk = empty;
1618	p = junc;
1619	pred = new_pred();
1620	pred->k = hmax;     /* MR10 should be CLL_k, not LLK ? */
1621	if (hmax > 1 )      /* MR10 was LL_k                   */
1622	{
1623		ConstrainSearch = 0;
1624		ContextGuardTRAV = 1;
1625		TRAV(p, hmax, &rk, t);  /* MR10 was LL_k */
1626		ContextGuardTRAV = 0;
1627		set_free(rk);
1628		t = tshrink( t );
1629		t = tflatten( t );
1630		t = tleft_factor( t );
1631/*
1632		fprintf(stderr, "ctx guard:");
1633		preorder(t);
1634		fprintf(stderr, "\n");
1635*/
1636		pred->tcontext = t;
1637	}
1638	else
1639	{
1640		REACH(p, 1, &rk, scontext);
1641		require(set_nil(rk), "rk != nil");
1642		set_free(rk);
1643/*
1644		fprintf(stderr, "LL(1) ctx guard is:");
1645		s_fprT(stderr, scontext);
1646		fprintf(stderr, "\n");
1647*/
1648		pred->scontext[1] = scontext;
1649	}
1650
1651    list_add(&ContextGuardPredicateList,pred);     /* MR13 */
1652
1653	return pred;
1654}
1655
1656/* MR13
1657   When the context guard is originally computed the
1658   meta-tokens are not known.
1659*/
1660
1661#ifdef __USE_PROTOS
1662void recomputeContextGuard(Predicate *pred)
1663#else
1664void recomputeContextGuard(pred)
1665    Predicate   *pred;
1666#endif
1667{
1668    Tree *          t=NULL;
1669	set             scontext;
1670    set             rk;
1671    ActionNode *    actionNode;
1672    Junction *      p;
1673
1674    actionNode=pred->source;
1675    require (actionNode != NULL,"context predicate's source == NULL");
1676
1677    p=actionNode->guardNodes;
1678    require (p != NULL,"context predicate's guardNodes == NULL");
1679
1680	rk = empty;
1681	if (pred->k > 1 )
1682	{
1683		ConstrainSearch = 0;
1684		ContextGuardTRAV = 1;
1685		TRAV(p, pred->k, &rk, t);
1686		ContextGuardTRAV = 0;
1687		set_free(rk);
1688		t = tshrink( t );
1689		t = tflatten( t );
1690		t = tleft_factor( t );
1691        Tfree(pred->tcontext);
1692		pred->tcontext = t;
1693	}
1694	else
1695	{
1696		REACH(p, 1, &rk, scontext);
1697		require(set_nil(rk), "rk != nil");
1698		set_free(rk);
1699        set_free(pred->scontext[1]);
1700		pred->scontext[1] = scontext;
1701	}
1702}
1703
1704/* MR11 - had enough of flags yet ? */
1705
1706int     MR_AmbSourceSearch=0;
1707int     MR_AmbSourceSearchGroup=0;
1708int     MR_AmbSourceSearchChoice=0;
1709int     MR_AmbSourceSearchLimit=0;
1710int     MR_matched_AmbAidRule=0;
1711
1712static    set         *matchSets[2]={NULL,NULL};
1713static    int         *tokensInChain=NULL;
1714static    Junction    *MR_AmbSourceSearchJ[2];
1715
1716void MR_traceAmbSourceKclient()
1717{
1718  int       i;
1719  set       *save_fset;
1720  int       save_ConstrainSearch;
1721  set       incomplete;
1722  Tree      *t;
1723
1724  if (matchSets[0] == NULL) {
1725    matchSets[0]=(set *) calloc (CLL_k+1,sizeof(set));
1726    require (matchSets[0] != NULL,"matchSets[0] alloc");
1727    matchSets[1]=(set *) calloc (CLL_k+1,sizeof(set));
1728    require (matchSets[1] != NULL,"matchSets[1] alloc");
1729  };
1730
1731  for (i=1 ; i <= MR_AmbSourceSearchLimit ; i++) {
1732    set_clr(matchSets[0][i]);
1733    set_orel( (unsigned) tokensInChain[i],
1734                              &matchSets[0][i]);
1735    set_clr(matchSets[1][i]);
1736    set_orel( (unsigned) tokensInChain[i],
1737                              &matchSets[1][i]);
1738  };
1739
1740  save_fset=fset;
1741  save_ConstrainSearch=ConstrainSearch;
1742
1743
1744
1745  for (i=0 ; i < 2 ; i++) {
1746
1747#if 0
1748**    fprintf(stdout,"  Choice:%d  Depth:%d  ",i+1,MR_AmbSourceSearchLimit);
1749**    fprintf(stdout,"(");
1750**    for (j=1 ; j <= MR_AmbSourceSearchLimit ; j++) {
1751**      if (j != 1) fprintf(stdout," ");
1752**      fprintf(stdout,"%s",TerminalString(tokensInChain[j]));
1753**    };
1754**    fprintf(stdout,")\n\n");
1755#endif
1756
1757    fset=matchSets[i];
1758
1759    MR_AmbSourceSearch=1;
1760    MR_MaintainBackTrace=1;
1761    MR_AmbSourceSearchChoice=i;
1762    ConstrainSearch=1;
1763
1764    maxk = MR_AmbSourceSearchLimit;
1765
1766    incomplete=empty;
1767    t=NULL;
1768
1769    constrain = &(fset[1]);
1770    MR_pointerStackReset(&MR_BackTraceStack);
1771
1772    TRAV(MR_AmbSourceSearchJ[i],maxk,&incomplete,t);
1773
1774    Tfree(t);
1775
1776    require (set_nil(incomplete),"MR_traceAmbSourceK TRAV incomplete");
1777    require (MR_BackTraceStack.count == 0,"K: MR_BackTraceStack.count != 0");
1778
1779    set_free(incomplete);
1780  };
1781
1782  ConstrainSearch=save_ConstrainSearch;
1783  fset=save_fset;
1784  MR_AmbSourceSearch=0;
1785  MR_MaintainBackTrace=0;
1786  MR_AmbSourceSearchChoice=0;
1787}
1788
1789#ifdef __USE_PROTOS
1790Tree *tTrunc(Tree *t,int depth)
1791#else
1792Tree *tTrunc(t,depth)
1793  Tree  *t;
1794#endif
1795{
1796    Tree    *u;
1797
1798    require ( ! (t == NULL && depth > 0),"tree too short");
1799
1800    if (depth == 0) return NULL;
1801
1802    if (t->token == ALT) {
1803      u=tTrunc(t->down,depth);
1804    } else {
1805      u=tnode(t->token);
1806      u->down=tTrunc(t->down,depth-1);
1807    };
1808    if (t->right != NULL) u->right=tTrunc(t->right,depth);
1809    return u;
1810}
1811
1812#ifdef __USE_PROTOS
1813void MR_iterateOverTree(Tree *t,int chain[])
1814#else
1815void MR_iterateOverTree(t,chain)
1816  Tree          *t;
1817  int           chain[];
1818#endif
1819{
1820  if (t == NULL) return;
1821  chain[0]=t->token;
1822  if (t->down != NULL) {
1823    MR_iterateOverTree(t->down,&chain[1]);
1824  } else {
1825    MR_traceAmbSourceKclient();
1826  };
1827  MR_iterateOverTree(t->right,&chain[0]);
1828  chain[0]=0;
1829}
1830
1831#ifdef __USE_PROTOS
1832void MR_traceAmbSourceK(Tree *t,Junction *alt1,Junction *alt2)
1833#else
1834void MR_traceAmbSourceK(t,alt1,alt2)
1835  Tree      *t;
1836  Junction  *alt1;
1837  Junction  *alt2;
1838#endif
1839{
1840    int         i;
1841    int         depth;
1842    int         maxDepth;
1843    Tree        *truncatedTree;
1844
1845    if (MR_AmbAidRule == NULL) return;
1846
1847    if ( ! (
1848            strcmp(MR_AmbAidRule,alt1->rname) == 0 ||
1849            strcmp(MR_AmbAidRule,alt2->rname) == 0 ||
1850            MR_AmbAidLine==alt1->line ||
1851            MR_AmbAidLine==alt2->line
1852           )
1853       ) return;
1854
1855    MR_matched_AmbAidRule++;
1856
1857    /* there are no token sets in trees, only in TokNodes */
1858
1859    MR_AmbSourceSearchJ[0]=analysis_point( (Junction *) alt1->p1);
1860    MR_AmbSourceSearchJ[1]=analysis_point( (Junction *) alt2->p1);
1861
1862    if (tokensInChain == NULL) {
1863      tokensInChain=(int *) calloc (CLL_k+1,sizeof(int));
1864      require (tokensInChain != NULL,"tokensInChain alloc");
1865    };
1866
1867    MR_AmbSourceSearchGroup=0;
1868
1869    fprintf(stdout,"\n");
1870    fprintf(stdout,"  Ambiguity Aid                 ");
1871    fprintf(stdout,
1872                (MR_AmbAidDepth <= LL_k ?
1873                    "(-k %d  -aa %s  %s  -aad %d)\n\n" :
1874                        "(-k %d  -aa %s  %s  [-k value limits -aad %d])\n\n"),
1875                LL_k,
1876                MR_AmbAidRule,
1877                (MR_AmbAidMultiple ? "-aam" : ""),
1878                MR_AmbAidDepth);
1879
1880    for (i=0 ; i < 2 ; i++) {
1881      fprintf(stdout,"    Choice %d: %-25s  line %d  file %s\n",
1882                  (i+1),
1883                  MR_ruleNamePlusOffset( (Node *) MR_AmbSourceSearchJ[i]),
1884                  MR_AmbSourceSearchJ[i]->line,
1885                  FileStr[MR_AmbSourceSearchJ[i]->file]);
1886    };
1887
1888    fprintf(stdout,"\n");
1889
1890    if (MR_AmbAidDepth < LL_k) {
1891      maxDepth=MR_AmbAidDepth;
1892    } else {
1893      maxDepth=LL_k;
1894    };
1895
1896    for (depth=1 ; depth <= maxDepth; depth++) {
1897      MR_AmbSourceSearchLimit=depth;
1898      if (depth < LL_k) {
1899        truncatedTree=tTrunc(t,depth);
1900        truncatedTree=tleft_factor(truncatedTree);
1901        MR_iterateOverTree(truncatedTree,&tokensInChain[1]);    /* <===== */
1902        Tfree(truncatedTree);
1903      } else {
1904        MR_iterateOverTree(t,tokensInChain);                /* <===== */
1905      };
1906      fflush(stdout);
1907      fflush(stderr);
1908    };
1909
1910    fprintf(stdout,"\n");
1911    MR_AmbSourceSearch=0;
1912    MR_MaintainBackTrace=0;
1913    MR_AmbSourceSearchGroup=0;
1914    MR_AmbSourceSearchChoice=0;
1915    MR_AmbSourceSearchLimit=0;
1916
1917}
1918
1919
1920/* this if for k=1 grammars only
1921
1922   this is approximate only because of the limitations of linear
1923   approximation lookahead.  Don't want to do a k=3 search when
1924   the user only specified a ck=3 grammar
1925*/
1926
1927#ifdef __USE_PROTOS
1928void MR_traceAmbSource(set *matchSets,Junction *alt1, Junction *alt2)
1929#else
1930void MR_traceAmbSource(matchSets,alt1,alt2)
1931  set       *matchSets;
1932  Junction  *alt1;
1933  Junction  *alt2;
1934#endif
1935{
1936    set         *save_fset;
1937    Junction    *p[2];
1938    int         i;
1939    int         j;
1940    set         *dup_matchSets;
1941    set         intersection;
1942    set         incomplete;
1943    set         tokensUsed;
1944    int         depth;
1945
1946    if (MR_AmbAidRule == NULL) return;
1947    if ( ! (
1948            strcmp(MR_AmbAidRule,alt1->rname) == 0 ||
1949            strcmp(MR_AmbAidRule,alt2->rname) == 0 ||
1950            MR_AmbAidLine==alt1->line ||
1951            MR_AmbAidLine==alt2->line
1952           )
1953       ) return;
1954
1955    MR_matched_AmbAidRule++;
1956
1957    save_fset=fset;
1958
1959    dup_matchSets=(set *) calloc(CLL_k+1,sizeof(set));
1960    require (dup_matchSets != NULL,"Can't allocate dup_matchSets");
1961
1962    p[0]=analysis_point( (Junction *) alt1->p1);
1963    p[1]=analysis_point( (Junction *) alt2->p1);
1964
1965    fprintf(stdout,"\n");
1966
1967    fprintf(stdout,"  Ambiguity Aid                 ");
1968    fprintf(stdout,
1969                (MR_AmbAidDepth <= CLL_k ?
1970                    "(-ck %d  -aa %s  %s  -aad %d)\n\n" :
1971                        "(-ck %d  -aa %s  %s  [-ck value limits -aad %d])\n\n"),
1972                CLL_k,
1973                MR_AmbAidRule,
1974                (MR_AmbAidMultiple ? "-aam" : ""),
1975                MR_AmbAidDepth);
1976
1977    for (i=0 ; i < 2 ; i++) {
1978      fprintf(stdout,"    Choice %d: %-25s  line %d  file %s\n",
1979                            (i+1),
1980                            MR_ruleNamePlusOffset( (Node *) p[i]),
1981                            p[i]->line,FileStr[p[i]->file]);
1982    };
1983
1984    for (j=1; j <= CLL_k ; j++) {
1985      fprintf(stdout,"\n    Intersection of lookahead[%d] sets:\n",j);
1986      intersection=set_and(alt1->fset[j],alt2->fset[j]);
1987      MR_dumpTokenSet(stdout,2,intersection);
1988      set_free(intersection);
1989    };
1990
1991    fprintf(stdout,"\n");
1992
1993    require (1 <= MR_AmbAidDepth && MR_AmbAidDepth <= CLL_k,
1994                "illegal MR_AmbAidDepth");
1995
1996    MR_AmbSourceSearchGroup=0;
1997    for (depth=1; depth <= MR_AmbAidDepth; depth++) {
1998        MR_AmbSourceSearchLimit=depth;
1999        for (i=0 ; i < 2 ; i++) {
2000
2001/***        fprintf(stdout,"  Choice:%d  Depth:%d\n\n",i+1,depth);  ***/
2002
2003            for (j=0 ; j <= CLL_k ; j++) { dup_matchSets[j]=set_dup(matchSets[j]); };
2004            fset=dup_matchSets;
2005
2006            fflush(output);
2007            fflush(stdout);
2008
2009            MR_AmbSourceSearch=1;
2010            MR_MaintainBackTrace=1;
2011            MR_AmbSourceSearchChoice=i;
2012
2013            maxk = depth;
2014            tokensUsed=empty;
2015            incomplete=empty;
2016
2017            constrain = &(fset[1]);
2018            MR_pointerStackReset(&MR_BackTraceStack);
2019
2020            REACH(p[i],depth,&incomplete,tokensUsed);
2021
2022            fflush(output);
2023            fflush(stdout);
2024
2025            require (set_nil(incomplete),"MR_traceAmbSource REACH incomplete");
2026            require (MR_BackTraceStack.count == 0,"1: MR_BackTraceStack.count != 0");
2027
2028            set_free(incomplete);
2029            set_free(tokensUsed);
2030
2031            for (j=0 ; j <= CLL_k ; j++) { set_free(dup_matchSets[j]); };
2032        };
2033    };
2034
2035    fprintf(stdout,"\n");
2036
2037    MR_AmbSourceSearch=0;
2038    MR_MaintainBackTrace=0;
2039    MR_AmbSourceSearchGroup=0;
2040    MR_AmbSourceSearchChoice=0;
2041    MR_AmbSourceSearchLimit=0;
2042
2043    fset=save_fset;
2044    free ( (char *) dup_matchSets);
2045}
2046
2047static int itemCount;
2048
2049void MR_backTraceDumpItemReset() {
2050  itemCount=0;
2051}
2052
2053#ifdef __USE_PROTOS
2054void MR_backTraceDumpItem(FILE *f,int skip,Node *n)
2055#else
2056void MR_backTraceDumpItem(f,skip,n)
2057  FILE      *f;
2058  int       skip;
2059  Node      *n;
2060#endif
2061{
2062  TokNode       *tn;
2063  RuleRefNode   *rrn;
2064  Junction      *j;
2065  ActionNode    *a;
2066
2067  switch (n->ntype) {
2068    case nToken:
2069        itemCount++; if (skip) goto EXIT;
2070        tn=(TokNode *)n;
2071        if (set_nil(tn->tset)) {
2072          fprintf(f,"  %2d #token %-23s",itemCount,TerminalString(tn->token));
2073        } else {
2074          fprintf(f,"  %2d #tokclass %-20s",itemCount,TerminalString(tn->token));
2075        };
2076        break;
2077    case nRuleRef:
2078        itemCount++; if (skip) goto EXIT;
2079        rrn=(RuleRefNode *)n;
2080        fprintf(f,"  %2d to %-27s",itemCount,rrn->text);
2081        break;
2082    case nAction:
2083        a=(ActionNode *)n;
2084        goto EXIT;
2085    case nJunction:
2086
2087      j=(Junction *)n;
2088
2089      switch (j->jtype) {
2090        case aSubBlk:
2091            if (j->guess) {
2092              itemCount++; if (skip) goto EXIT;
2093              fprintf(f,"  %2d %-30s",itemCount,"in (...)? block at");
2094              break;
2095            };
2096/******     fprintf(f,"  %2d %-32s",itemCount,"in (...) block at");  *******/
2097/******     break;                                                          *******/
2098            goto EXIT;
2099        case aOptBlk:
2100            itemCount++; if (skip) goto EXIT;
2101            fprintf(f,"  %2d %-30s",itemCount,"in {...} block");
2102            break;
2103        case aLoopBlk:
2104            itemCount++; if (skip) goto EXIT;
2105            fprintf(f,"  %2d %-30s",itemCount,"in (...)* block");
2106            break;
2107        case EndBlk:
2108            if (j->alpha_beta_guess_end) {
2109              itemCount++; if (skip) goto EXIT;
2110              fprintf(f,"  %2d %-30s",itemCount,"end (...)? block at");
2111              break;
2112            };
2113            goto EXIT;
2114/******     fprintf(f,"  %2d %-32s",itemCount,"end of a block at");     *****/
2115/******     break;                                                             *****/
2116        case RuleBlk:
2117            itemCount++; if (skip) goto EXIT;
2118            fprintf(f,"  %2d %-30s",itemCount,j->rname);
2119            break;
2120        case Generic:
2121            goto EXIT;
2122        case EndRule:
2123            itemCount++; if (skip) goto EXIT;
2124            fprintf (f,"  %2d end %-26s",itemCount,j->rname);
2125            break;
2126        case aPlusBlk:
2127            itemCount++; if (skip) goto EXIT;
2128            fprintf(f,"  %2d %-30s",itemCount,"in (...)+ block");
2129            break;
2130        case aLoopBegin:
2131            goto EXIT;
2132      };
2133      break;
2134  };
2135  fprintf(f," %-23s line %-4d  %s\n",MR_ruleNamePlusOffset(n),n->line,FileStr[n->file]);
2136EXIT:
2137  return;
2138}
2139
2140
2141static PointerStack     previousBackTrace={0,0,NULL};
2142
2143#ifdef __USE_PROTOS
2144void MR_backTraceReport(void)
2145#else
2146void MR_backTraceReport()
2147#endif
2148{
2149  int       i;
2150  int       match = 0;
2151  int       limitMatch;
2152
2153  Node      *p;
2154  TokNode   *tn;
2155  set       remainder;
2156  int       depth;
2157
2158  /* Even when doing a k=2 search this routine can get
2159       called when there is only 1 token on the stack.
2160     This is because something like rRuleRef can change
2161       the search value of k from 2 to 1 temporarily.
2162     It does this because the it wants to know the k=1
2163       first set before it does a k=2 search
2164  */
2165
2166  depth=0;
2167  for (i=0; i < MR_BackTraceStack.count ; i++) {
2168    p=(Node *) MR_BackTraceStack.data[i];
2169    if (p->ntype == nToken) depth++;
2170  };
2171
2172/* MR14 */  if (MR_AmbSourceSearch) {
2173/* MR14 */     require (depth <= MR_AmbSourceSearchLimit,"depth > MR_AmbSourceSearchLimit");
2174/* MR14 */  }
2175
2176  /* MR23 THM - Traceback report was being called at the wrong time for -alpha reports */
2177  /*            Reported by Arpad Beszedes (beszedes@inf.u-szeged.hu)                  */
2178
2179  if (MR_AmbSourceSearchLimit == 0 || depth < MR_AmbSourceSearchLimit) {
2180    return;
2181  };
2182
2183  MR_backTraceDumpItemReset();
2184
2185  limitMatch=MR_BackTraceStack.count;
2186  if (limitMatch > previousBackTrace.count) {
2187    limitMatch=previousBackTrace.count;
2188  };
2189
2190  for (match=0; match < limitMatch; match++) {
2191    if (MR_BackTraceStack.data[match] !=
2192        previousBackTrace.data[match]) {
2193      break;
2194    };
2195  };
2196
2197  /* not sure at the moment why there would be duplicates */
2198
2199  if (match != MR_BackTraceStack.count) {
2200
2201    fprintf(stdout,"     Choice:%d  Depth:%d  Group:%d",
2202        (MR_AmbSourceSearchChoice+1),
2203        MR_AmbSourceSearchLimit,
2204        ++MR_AmbSourceSearchGroup);
2205
2206    depth=0;
2207    fprintf(stdout,"  (");
2208    for (i=0; i < MR_BackTraceStack.count ; i++) {
2209      p=(Node *) MR_BackTraceStack.data[i];
2210      if (p->ntype != nToken) continue;
2211      tn=(TokNode *)p;
2212      if (depth != 0) fprintf(stdout," ");
2213      fprintf(stdout,TerminalString(tn->token));
2214      depth++;
2215      if (! MR_AmbAidMultiple) {
2216        if (set_nil(tn->tset)) {
2217          set_rm( (unsigned) tn->token,fset[depth]);
2218        } else {
2219          remainder=set_dif(fset[depth],tn->tset);
2220          set_free(fset[depth]);
2221          fset[depth]=remainder;
2222        };
2223      };
2224    };
2225    fprintf(stdout,")\n");
2226
2227    for (i=0; i < MR_BackTraceStack.count ; i++) {
2228      MR_backTraceDumpItem(stdout, (i<match) ,(Node *) MR_BackTraceStack.data[i]);
2229    };
2230    fprintf(stdout,"\n");
2231    fflush(stdout);
2232
2233    MR_pointerStackReset(&previousBackTrace);
2234
2235    for (i=0; i < MR_BackTraceStack.count ; i++) {
2236      MR_pointerStackPush(&previousBackTrace,MR_BackTraceStack.data[i]);
2237    };
2238
2239  };
2240}
2241
2242#ifdef __USE_PROTOS
2243void MR_setConstrainPointer(set * newConstrainValue)
2244#else
2245void MR_setConstrainPointer(newConstrainValue)
2246  set * newConstrainValue;
2247#endif
2248{
2249	constrain=newConstrainValue;
2250}
2251