1 /*************************************************************************
2 *									 *
3 *	 YAP Prolog 							 *
4 *									 *
5 *	Yap Prolog was developed at NCCUP - Universidade do Porto	 *
6 *									 *
7 * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 *
8 *									 *
9 **************************************************************************
10 *									 *
11 * File:		parser.c						 *
12 * Last rev:								 *
13 * mods:									 *
14 * comments:	Prolog's parser						 *
15 *									 *
16 *************************************************************************/
17 #ifdef SCCS
18 static char SccsId[] = "%W% %G%";
19 #endif
20 /*
21  * Description:
22  *
23  * parser:     produces a prolog term from an array of tokens
24  *
25  * parser usage: the parser takes its input from an array of token descriptions
26  * addressed by the global variable 'tokptr' and produces a Term as result. A
27  * macro 'NextToken' should be defined in 'yap.h' for advancing 'tokptr' from
28  * one token to the next. In the distributed version this macro also updates
29  * a variable named 'toktide' for keeping track of how far the parser went
30  * before failling with a syntax error. The parser should be invoked with
31  * 'tokptr' pointing to the first token. The last token should have type
32  * 'eot_tok'. The parser return either a Term. Syntactic errors are signaled
33  * by a return value 0. The parser builds new terms on the 'global stack' and
34  * also uses an auxiliary stack pointed to by 'AuxSp'. In the distributed
35  * version this auxiliary stack is assumed to grow downwards. This
36  * assumption, however, is only relevant to routine 'ParseArgs', and to the
37  * variable toktide. conclusion: set tokptr pointing to first token set AuxSp
38  * Call Parse
39  *
40  * VSC: Working whithout known bugs in 87/4/6
41  *
42  * LD: -I or +I evaluated by parser 87/4/28
43  *
44  * LD: parser extended 87/4/28
45  *
46  */
47 
48 
49 #include "Yap.h"
50 #include "Yatom.h"
51 #include "YapHeap.h"
52 #include "yapio.h"
53 #include "eval.h"
54 #if HAVE_STRING_H
55 #include <string.h>
56 #endif
57 
58 #ifdef __STDC__XXX
59 #define Volatile volatile
60 #else
61 #define Volatile
62 #endif
63 
64 
65 /* weak backtraking mechanism based on long_jump */
66 
67 typedef struct jmp_buff_struct {
68 	sigjmp_buf JmpBuff;
69 } JMPBUFF;
70 
71 STATIC_PROTO(void GNextToken, (void));
72 STATIC_PROTO(void checkfor, (Term, JMPBUFF *));
73 STATIC_PROTO(Term ParseArgs, (Atom, JMPBUFF *));
74 STATIC_PROTO(Term ParseList, (JMPBUFF *));
75 STATIC_PROTO(Term ParseTerm, (int, JMPBUFF *));
76 
77 
78 #define TRY(S,P)                               \
79   {	Volatile JMPBUFF *saveenv, newenv;     \
80 	Volatile TokEntry *saveT=Yap_tokptr;   \
81         Volatile CELL *saveH=H;                \
82         Volatile int savecurprio=curprio;      \
83         saveenv=FailBuff;                      \
84         if(!sigsetjmp(newenv.JmpBuff, 0)) {      \
85                 FailBuff = &newenv;            \
86 		S;                             \
87 		FailBuff=saveenv;              \
88 		P;                             \
89 	  }                                    \
90 	else { FailBuff=saveenv;               \
91 		H=saveH;                       \
92 		curprio = savecurprio;         \
93                 Yap_tokptr=saveT;              \
94 	}                                      \
95    }
96 
97 #define TRY3(S,P,F)                            \
98   {	Volatile JMPBUFF *saveenv, newenv;     \
99 	Volatile TokEntry *saveT=Yap_tokptr;   \
100         Volatile CELL *saveH=H;                \
101         saveenv=FailBuff;                      \
102         if(!sigsetjmp(newenv.JmpBuff, 0)) {      \
103                 FailBuff = &newenv;            \
104 		S;                             \
105 		FailBuff=saveenv;              \
106 		P;                             \
107 	  }                                    \
108 	else {                                 \
109                 FailBuff=saveenv;              \
110                 H=saveH;                       \
111                 Yap_tokptr=saveT;              \
112                 F }                            \
113    }
114 
115 
116 #define FAIL  siglongjmp(FailBuff->JmpBuff,1)
117 
118 VarEntry *
Yap_LookupVar(char * var)119 Yap_LookupVar(char *var)	/* lookup variable in variables table   */
120 {
121   VarEntry *p;
122 
123 #ifdef DEBUG
124   if (Yap_Option[4])
125     fprintf(Yap_stderr,"[LookupVar %s]", var);
126 #endif
127   if (var[0] != '_' || var[1] != '\0') {
128     VarEntry **op = &Yap_VarTable;
129     unsigned char *vp = (unsigned char *)var;
130     UInt hv;
131 
132     p = Yap_VarTable;
133     hv = HashFunction(vp) % AtomHashTableSize;
134     while (p != NULL) {
135       CELL hpv = p->hv;
136       if (hv == hpv) {
137 	Int scmp;
138 	if ((scmp = strcmp(var, p->VarRep)) == 0) {
139 	  return(p);
140 	} else if (scmp < 0) {
141 	  op = &(p->VarLeft);
142 	  p = p->VarLeft;
143 	} else {
144 	  op = &(p->VarRight);
145 	  p = p->VarRight;
146 	}
147       } else if (hv < hpv) {
148 	op = &(p->VarLeft);
149 	p = p->VarLeft;
150       } else {
151 	op = &(p->VarRight);
152 	p = p->VarRight;
153       }
154     }
155     p = (VarEntry *) Yap_AllocScannerMemory(strlen(var) + sizeof(VarEntry));
156     *op = p;
157     p->VarLeft = p->VarRight = NULL;
158     p->hv = hv;
159     strcpy(p->VarRep, var);
160   } else {
161     /* anon var */
162     p = (VarEntry *) Yap_AllocScannerMemory(sizeof(VarEntry) + 2);
163     p->VarLeft = Yap_AnonVarTable;
164     Yap_AnonVarTable = p;
165     p->VarRight = NULL;
166     p->hv = 0L;
167     p->VarRep[0] = '_';
168     p->VarRep[1] = '\0';
169   }
170   p->VarAdr = TermNil;
171   return (p);
172 }
173 
174 static Term
VarNames(VarEntry * p,Term l)175 VarNames(VarEntry *p,Term l)
176 {
177   if (p != NULL) {
178     if (strcmp(p->VarRep, "_") != 0) {
179       Term o = MkPairTerm(MkPairTerm(Yap_StringToList(p->VarRep), p->VarAdr),
180 			  VarNames(p->VarRight,
181 				   VarNames(p->VarLeft,l)));
182       if (H > ASP-4096) {
183 	save_machine_regs();
184 	siglongjmp(Yap_IOBotch,1);
185       }
186       return(o);
187     } else {
188       return(VarNames(p->VarRight,VarNames(p->VarLeft,l)));
189     }
190   } else {
191     return (l);
192   }
193 }
194 
195 Term
Yap_VarNames(VarEntry * p,Term l)196 Yap_VarNames(VarEntry *p,Term l)
197 {
198   return VarNames(p,l);
199 }
200 
201 static int
IsPrefixOp(Atom op,int * pptr,int * rpptr)202 IsPrefixOp(Atom op,int  *pptr, int *rpptr)
203 {
204   int p;
205 
206   OpEntry *opp = Yap_GetOpProp(op, PREFIX_OP);
207   if (!opp)
208     return FALSE;
209   if (opp->OpModule &&
210       opp->OpModule != CurrentModule)
211     return FALSE;
212   if ((p = opp->Prefix) != 0) {
213     READ_UNLOCK(opp->OpRWLock);
214     *pptr = *rpptr = p & MaskPrio;
215     if (p & DcrrpFlag)
216       --* rpptr;
217     return TRUE;
218   } else {
219     READ_UNLOCK(opp->OpRWLock);
220     return FALSE;
221   }
222 }
223 
224 int
Yap_IsPrefixOp(Atom op,int * pptr,int * rpptr)225 Yap_IsPrefixOp(Atom op,int  *pptr, int *rpptr)
226 {
227   return IsPrefixOp(op,pptr,rpptr);
228 }
229 
230 static int
IsInfixOp(Atom op,int * pptr,int * lpptr,int * rpptr)231 IsInfixOp(Atom op, int *pptr, int *lpptr, int *rpptr)
232 {
233   int p;
234 
235   OpEntry *opp = Yap_GetOpProp(op, INFIX_OP);
236   if (!opp)
237     return FALSE;
238   if (opp->OpModule &&
239       opp->OpModule != CurrentModule)
240     return FALSE;
241   if ((p = opp->Infix) != 0) {
242     READ_UNLOCK(opp->OpRWLock);
243     *pptr = *rpptr = *lpptr = p & MaskPrio;
244     if (p & DcrrpFlag)
245       --* rpptr;
246     if (p & DcrlpFlag)
247       --* lpptr;
248     return TRUE;
249   } else {
250     READ_UNLOCK(opp->OpRWLock);
251     return FALSE;
252   }
253 }
254 
255 int
Yap_IsInfixOp(Atom op,int * pptr,int * lpptr,int * rpptr)256 Yap_IsInfixOp(Atom op, int *pptr, int *lpptr, int *rpptr)
257 {
258   return IsInfixOp(op, pptr, lpptr, rpptr);
259 }
260 
261 static int
IsPosfixOp(Atom op,int * pptr,int * lpptr)262 IsPosfixOp(Atom op, int *pptr, int *lpptr)
263 {
264   int p;
265 
266   OpEntry *opp = Yap_GetOpProp(op, POSFIX_OP);
267   if (!opp)
268     return FALSE;
269   if (opp->OpModule &&
270       opp->OpModule != CurrentModule)
271     return FALSE;
272   if ((p = opp->Posfix) != 0) {
273     READ_UNLOCK(opp->OpRWLock);
274     *pptr = *lpptr = p & MaskPrio;
275     if (p & DcrlpFlag)
276       --* lpptr;
277     return (TRUE);
278   } else {
279     READ_UNLOCK(opp->OpRWLock);
280     return (FALSE);
281   }
282 }
283 
284 int
Yap_IsPosfixOp(Atom op,int * pptr,int * lpptr)285 Yap_IsPosfixOp(Atom op, int *pptr, int *lpptr)
286 {
287   return IsPosfixOp(op, pptr, lpptr);
288 }
289 
290 inline static void
GNextToken(void)291 GNextToken(void)
292 {
293 	if (Yap_tokptr->Tok == Ord(eot_tok))
294 		return;
295 #ifdef EMACS
296 	if ((Yap_tokptr = Yap_tokptr->TokNext)->TokPos > Yap_toktide->TokPos)
297 		Yap_toktide = Yap_tokptr;
298 #else
299 	if (Yap_tokptr == Yap_toktide)
300 	  Yap_toktide = Yap_tokptr = Yap_tokptr->TokNext;
301 	else
302 	  Yap_tokptr = Yap_tokptr->TokNext;
303 #endif
304 }
305 
306 inline static void
checkfor(Term c,JMPBUFF * FailBuff)307 checkfor(Term c, JMPBUFF *FailBuff)
308 {
309   if (Yap_tokptr->Tok != Ord(Ponctuation_tok)
310       || Yap_tokptr->TokInfo != c)
311     FAIL;
312   NextToken;
313 }
314 
315 static Term
ParseArgs(Atom a,JMPBUFF * FailBuff)316 ParseArgs(Atom a, JMPBUFF *FailBuff)
317 {
318   int nargs = 0;
319   Term *p, t;
320   Functor func;
321 #ifdef SFUNC
322   SFEntry *pe = (SFEntry *) Yap_GetAProp(a, SFProperty);
323 #endif
324 
325   NextToken;
326   p = (Term *) ParserAuxSp;
327   while (1) {
328     Term *tp = (Term *)ParserAuxSp;
329     if (ParserAuxSp+1 > Yap_TrailTop) {
330       Yap_ErrorMessage = "Trail Overflow";
331       FAIL;
332     }
333     *tp++ = Unsigned(ParseTerm(999, FailBuff));
334     ParserAuxSp = (char *)tp;
335     ++nargs;
336     if (Yap_tokptr->Tok != Ord(Ponctuation_tok))
337       break;
338     if (((int) Yap_tokptr->TokInfo) != ',')
339       break;
340     NextToken;
341   }
342   ParserAuxSp = (char *)p;
343   /*
344    * Needed because the arguments for the functor are placed in reverse
345    * order
346    */
347   if (H > ASP-(nargs+1)) {
348     Yap_ErrorMessage = "Stack Overflow";
349     FAIL;
350   }
351   func = Yap_MkFunctor(a, nargs);
352   if (func == NULL) {
353     Yap_ErrorMessage = "Heap Overflow";
354     FAIL;
355   }
356 #ifdef SFUNC
357   if (pe)
358     t = MkSFTerm(Yap_MkFunctor(a, SFArity), nargs, p, pe->NilValue);
359   else
360     t = Yap_MkApplTerm(Yap_MkFunctor(a, nargs), nargs, p);
361 #else
362   if (a == AtomDBref && nargs == 2)
363     t = MkDBRefTerm((DBRef)IntegerOfTerm(p[0]));
364   else
365     t = Yap_MkApplTerm(func, nargs, p);
366 #endif
367   if (H > ASP-4096) {
368     Yap_ErrorMessage = "Stack Overflow";
369     return TermNil;
370   }
371   /* check for possible overflow against local stack */
372   checkfor((Term) ')', FailBuff);
373   return t;
374 }
375 
376 
377 static Term
ParseList(JMPBUFF * FailBuff)378 ParseList(JMPBUFF *FailBuff)
379 {
380   Term o;
381   CELL *to_store;
382   o = AbsPair(H);
383  loop:
384   to_store = H;
385   H+=2;
386   to_store[0] = ParseTerm(999, FailBuff);
387   if (Yap_tokptr->Tok == Ord(Ponctuation_tok)) {
388     if (((int) Yap_tokptr->TokInfo) == ',') {
389       NextToken;
390       if (Yap_tokptr->Tok == Ord(Name_tok)
391 	  && strcmp(RepAtom((Atom)(Yap_tokptr->TokInfo))->StrOfAE, "..") == 0) {
392 	NextToken;
393 	to_store[1] = ParseTerm(999, FailBuff);
394       } else {
395 	/* check for possible overflow against local stack */
396 	if (H > ASP-4096) {
397 	  to_store[1] = TermNil;
398 	  Yap_ErrorMessage = "Stack Overflow";
399 	  FAIL;
400 	} else {
401 	  to_store[1] = AbsPair(H);
402 	  goto loop;
403 	}
404       }
405     } else if (((int) Yap_tokptr->TokInfo) == '|') {
406       NextToken;
407       to_store[1] = ParseTerm(999, FailBuff);
408     } else {
409       to_store[1] = MkAtomTerm(AtomNil);
410     }
411   } else
412     FAIL;
413   return (o);
414 }
415 
416 #ifndef INFINITY
417 #define INFINITY (1.0/0.0)
418 #endif
419 
420 #ifndef NAN
421 #define NAN      (0.0/0.0)
422 #endif
423 
424 static Term
ParseTerm(int prio,JMPBUFF * FailBuff)425 ParseTerm(int prio, JMPBUFF *FailBuff)
426 {
427   /* parse term with priority prio */
428   Volatile Term t;
429   Volatile Functor func;
430   Volatile VarEntry *varinfo;
431   Volatile int curprio = 0, opprio, oplprio, oprprio;
432   Volatile Atom opinfo;
433 
434   switch (Yap_tokptr->Tok) {
435   case Name_tok:
436     t = Yap_tokptr->TokInfo;
437     NextToken;
438     if ((Yap_tokptr->Tok != Ord(Ponctuation_tok)
439 	 || Unsigned(Yap_tokptr->TokInfo) != 'l')
440 	&& IsPrefixOp((Atom)t, &opprio, &oprprio)
441 	) {
442       /* special rules apply for +1, -2.3, etc... */
443       if (Yap_tokptr->Tok == Number_tok) {
444 	if ((Atom)t == AtomMinus) {
445 	  t = Yap_tokptr->TokInfo;
446 	  if (IsIntTerm(t))
447 	    t = MkIntTerm(-IntOfTerm(t));
448 	  else if (IsFloatTerm(t))
449 	    t = MkFloatTerm(-FloatOfTerm(t));
450 #ifdef USE_GMP
451 	  else if (IsBigIntTerm(t)) {
452 	    t = Yap_gmp_neg_big(t);
453 	  }
454 #endif
455 	  else
456 	    t = MkLongIntTerm(-LongIntOfTerm(t));
457 	  NextToken;
458 	  break;
459 	}
460       } else if (Yap_tokptr->Tok == Name_tok) {
461 	Atom at = (Atom)Yap_tokptr->TokInfo;
462 #ifndef _MSC_VER
463 	if ((Atom)t == AtomPlus) {
464 	  if (at == AtomInf) {
465 	    t = MkFloatTerm(INFINITY);
466 	    NextToken;
467 	    break;
468 	  } else if (at == AtomNan) {
469 	    t = MkFloatTerm(NAN);
470 	    NextToken;
471 	    break;
472 	  }
473 	} else if ((Atom)t == AtomMinus) {
474 	  if (at == AtomInf) {
475 	    t = MkFloatTerm(-INFINITY);
476 	    NextToken;
477 	    break;
478 	  } else if (at == AtomNan) {
479 	    t = MkFloatTerm(NAN);
480 	    NextToken;
481 	    break;
482 	  }
483 	}
484 #endif
485       }
486       if (opprio <= prio) {
487       /* try to parse as a prefix operator */
488 	TRY(
489 	  /* build appl on the heap */
490 	  func = Yap_MkFunctor((Atom) t, 1);
491 	  if (func == NULL) {
492 	    Yap_ErrorMessage = "Heap Overflow";
493 	    FAIL;
494 	  }
495 	  t = ParseTerm(oprprio, FailBuff);
496 	  t = Yap_MkApplTerm(func, 1, &t);
497 	  /* check for possible overflow against local stack */
498 	  if (H > ASP-4096) {
499 	    Yap_ErrorMessage = "Stack Overflow";
500 	    FAIL;
501 	  }
502 	  curprio = opprio;
503 	  ,
504 	  break;
505 	  )
506 	}
507     }
508     if (Yap_tokptr->Tok == Ord(Ponctuation_tok)
509 	&& Unsigned(Yap_tokptr->TokInfo) == 'l')
510       t = ParseArgs((Atom) t, FailBuff);
511     else
512       t = MkAtomTerm((Atom)t);
513     break;
514 
515   case Number_tok:
516     t = Yap_tokptr->TokInfo;
517     NextToken;
518     break;
519 
520   case String_tok:	/* build list on the heap */
521     {
522       Volatile char *p = (char *) Yap_tokptr->TokInfo;
523       if (*p == 0)
524 	t = MkAtomTerm(AtomNil);
525       else if (yap_flags[YAP_DOUBLE_QUOTES_FLAG] == STRING_AS_CHARS)
526 	t = Yap_StringToListOfAtoms(p);
527       else if (yap_flags[YAP_DOUBLE_QUOTES_FLAG] == STRING_AS_ATOM) {
528 	Atom at = Yap_LookupAtom(p);
529 	if (at == NIL) {
530 	  Yap_ErrorMessage = "Heap Overflow";
531 	  FAIL;
532 	}
533 	t = MkAtomTerm(at);
534       } else
535 	t = Yap_StringToList(p);
536       NextToken;
537     }
538   break;
539 
540   case WString_tok:	/* build list on the heap */
541     {
542       Volatile wchar_t *p = (wchar_t *) Yap_tokptr->TokInfo;
543       if (*p == 0)
544 	t = MkAtomTerm(AtomNil);
545       else if (yap_flags[YAP_DOUBLE_QUOTES_FLAG] == STRING_AS_CHARS)
546 	t = Yap_WideStringToListOfAtoms(p);
547       else if (yap_flags[YAP_DOUBLE_QUOTES_FLAG] == STRING_AS_ATOM)
548 	t = MkAtomTerm(Yap_LookupWideAtom(p));
549       else
550 	t = Yap_WideStringToList(p);
551       NextToken;
552     }
553   break;
554 
555   case Var_tok:
556     varinfo = (VarEntry *) (Yap_tokptr->TokInfo);
557     if ((t = varinfo->VarAdr) == TermNil) {
558       t = varinfo->VarAdr = MkVarTerm();
559     }
560     NextToken;
561     break;
562 
563   case Error_tok:
564     FAIL;
565 
566   case Ponctuation_tok:
567     switch ((int) Yap_tokptr->TokInfo) {
568     case '(':
569     case 'l':	/* non solo ( */
570       NextToken;
571       t = ParseTerm(1200, FailBuff);
572       checkfor((Term) ')', FailBuff);
573       break;
574     case '[':
575       NextToken;
576       t = ParseList(FailBuff);
577       checkfor((Term) ']', FailBuff);
578       break;
579     case '{':
580       NextToken;
581       t = ParseTerm(1200, FailBuff);
582       t = Yap_MkApplTerm(FunctorBraces, 1, &t);
583       /* check for possible overflow against local stack */
584       if (H > ASP-4096) {
585 	Yap_ErrorMessage = "Stack Overflow";
586 	FAIL;
587       }
588       checkfor((Term) '}', FailBuff);
589       break;
590     default:
591       FAIL;
592     }
593     break;
594 
595   default:
596 
597     FAIL;
598   }
599 
600   /* main loop to parse infix and posfix operators starts here */
601   while (TRUE) {
602     if (Yap_tokptr->Tok == Ord(Name_tok)
603 	&& Yap_HasOp((Atom)(Yap_tokptr->TokInfo))) {
604       Atom save_opinfo = opinfo = (Atom)(Yap_tokptr->TokInfo);
605       if (IsInfixOp(save_opinfo, &opprio, &oplprio, &oprprio)
606 	  && opprio <= prio && oplprio >= curprio) {
607 	/* try parsing as infix operator */
608 	Volatile int oldprio = curprio;
609 	TRY3(
610 	     func = Yap_MkFunctor((Atom) Yap_tokptr->TokInfo, 2);
611 	     if (func == NULL) {
612 	       Yap_ErrorMessage = "Heap Overflow";
613 	       FAIL;
614 	     }
615 	     NextToken;
616 	     {
617 	       Term args[2];
618 	       args[0] = t;
619 	       args[1] = ParseTerm(oprprio, FailBuff);
620 	       t = Yap_MkApplTerm(func, 2, args);
621 	       /* check for possible overflow against local stack */
622 	       if (H > ASP-4096) {
623 		 Yap_ErrorMessage = "Stack Overflow";
624 		 FAIL;
625 	       }
626 	     },
627 	       curprio = opprio;
628 	       opinfo = save_opinfo;
629 	       continue;
630 	       ,
631 	       opinfo = save_opinfo;
632 	       curprio = oldprio;
633 	     )
634       }
635       if (IsPosfixOp(opinfo, &opprio, &oplprio)
636 	  && opprio <= prio && oplprio >= curprio) {
637 	/* parse as posfix operator */
638 	Functor func = Yap_MkFunctor((Atom) Yap_tokptr->TokInfo, 1);
639 	if (func == NULL) {
640 	  Yap_ErrorMessage = "Heap Overflow";
641 	  FAIL;
642 	}
643 	t = Yap_MkApplTerm(func, 1, &t);
644 	/* check for possible overflow against local stack */
645 	if (H > ASP-4096) {
646 	  Yap_ErrorMessage = "Stack Overflow";
647 	  FAIL;
648 	}
649 	curprio = opprio;
650 	NextToken;
651 	continue;
652       }
653       break;
654     }
655     if (Yap_tokptr->Tok == Ord(Ponctuation_tok)) {
656       if (Unsigned(Yap_tokptr->TokInfo) == ',' &&
657 	  prio >= 1000 && curprio <= 999) {
658 	Volatile Term args[2];
659 	NextToken;
660 	args[0] = t;
661 	args[1] = ParseTerm(1000, FailBuff);
662 	t = Yap_MkApplTerm(FunctorComma, 2, args);
663 	/* check for possible overflow against local stack */
664 	if (H > ASP-4096) {
665 	  Yap_ErrorMessage = "Stack Overflow";
666 	  FAIL;
667 	}
668 	curprio = 1000;
669 	continue;
670       } else if (Unsigned(Yap_tokptr->TokInfo) == '|' &&
671                 IsInfixOp(AtomVBar, &opprio, &oplprio, &oprprio)
672                 && opprio <= prio && oplprio >= curprio) {
673 	Volatile Term args[2];
674 	NextToken;
675 	args[0] = t;
676 	args[1] = ParseTerm(oprprio, FailBuff);
677 	t = Yap_MkApplTerm(FunctorVBar, 2, args);
678 	/* check for possible overflow against local stack */
679 	if (H > ASP-4096) {
680 	  Yap_ErrorMessage = "Stack Overflow";
681 	  FAIL;
682 	}
683 	curprio = opprio;
684 	continue;
685       }
686     }
687     if (Yap_tokptr->Tok <= Ord(WString_tok))
688       FAIL;
689     break;
690   }
691 #ifdef DEBUG
692   if (Yap_Option['p' - 'a' + 1]) {
693     Yap_DebugPutc(Yap_c_error_stream,'[');
694     Yap_DebugPlWrite(t);
695     Yap_DebugPutc(Yap_c_error_stream,']');
696     Yap_DebugPutc(Yap_c_error_stream,'\n');
697   }
698 #endif
699   return t;
700 }
701 
702 
703 Term
Yap_Parse(void)704 Yap_Parse(void)
705 {
706   Volatile Term t;
707   JMPBUFF FailBuff;
708 
709   if (!sigsetjmp(FailBuff.JmpBuff, 0)) {
710     t = ParseTerm(1200, &FailBuff);
711     if (Yap_tokptr->Tok != Ord(eot_tok))
712       return (0L);
713     return (t);
714   } else
715     return (0);
716 }
717