home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume19 / wacco / part01 / check.C < prev    next >
C/C++ Source or Header  |  1991-05-19  |  2KB  |  95 lines

  1. // Copyright (c) 1991 by Parag Patel.  All Rights Reserved.
  2. static const char rcs_id[] = "$Header: check.C,v 1.6 91/02/22 16:07:20 hmgr Exp $";
  3.  
  4. #include "defs.h"
  5.  
  6.  
  7. static void dostruct(symbol *sym)
  8. {
  9.     if (sym->rettype == NULL)
  10.         return;
  11.     if (dargstyle)
  12.     {
  13.         sym->mkstruct = strpbrk(sym->rettype, ",;") != NULL;
  14.         return;
  15.     }
  16.     for (char *s = sym->rettype; *s != '\0'; s++)
  17.         if (*s == ',')
  18.         {
  19.             sym->mkstruct = TRUE;
  20.             *s = ';';
  21.         }
  22. }
  23.  
  24.  
  25. void check()
  26. {
  27.     int i;
  28.     symbol *sym;
  29.     symnode *n;
  30.     Bitset curr(numsymbols());
  31.     Bitset set(numsymbols());
  32.     Bitset t(numsymbols());
  33.  
  34.     if (!exportedname && !startsymbol->export)
  35.         startsymbol->export = TRUE;
  36.  
  37.     for (i = 0; i < numnonterms(); i++)
  38.     {
  39.         sym = getnonterm(i);
  40.         if (sym->type != NONTERMINAL)
  41.             continue;
  42.         
  43.         dostruct(sym);
  44.         if (sym->mkstruct && sym->export)
  45.             error("Non-simple type for exported non-terminal \"%s\"",
  46.                 sym->name);
  47.  
  48.         curr.clear();
  49.         for (n = sym->node; n != NULL; n = n->or)
  50.         {
  51.             set.clear();
  52.             boolean isfirst = TRUE;
  53.             for (symnode *s = n; s != NULL; s = s->next)
  54.             {
  55.                 if (s->sym->type == CODE)
  56.                     continue;
  57.                 if (isfirst)
  58.                     if (s->sym == sym)
  59.                         if (sym->realname != NULL && sym->name != sym->realname)
  60.                             error("Head recursion in grouped rules for \"%s\"",
  61.                                     sym->realname);
  62.                         else
  63.                             error("Head recursion in rules for \"%s\"",
  64.                                     sym->name);
  65.                 isfirst = FALSE;
  66.                 set |= *s->sym->first;
  67.                 if (!s->sym->first->isin(EMPTY))
  68.                     break;
  69.             }
  70.             t = curr;
  71.             t &= set;
  72.             if (t.size() == 0 || (t.size() == 1 && t.isin(EMPTY)))
  73.                 curr |= set;
  74.             else if (sym->type == NONTERMINAL && sym->realname != NULL
  75.                     && sym->name != sym->realname)
  76.                 error("Ambiguous [non-LL(1)] grouped rules in \"%s\"",
  77.                         sym->realname);
  78.             else
  79.                 error("Ambiguous [non-LL(1)] rules for \"%s\"", sym->name);
  80.         }
  81.  
  82.         for (symnode *or = sym->node; or != NULL; or = or->or)
  83.             for (n = or; n != NULL; n = n->next)
  84.                 if (n->sym->type == TERMINAL && n->alias != NULL)
  85.                     if (sym->realname != NULL && sym->name != sym->realname)
  86.                         error(
  87. "Alias \"%s\" defined for terminal \"%s\" in grouped rules for \"%s\"",
  88.                             n->alias, n->sym->name, sym->realname);
  89.                     else
  90.                         error(
  91. "Alias \"%s\" defined for terminal \"%s\" in rules for \"%s\"",
  92.                             n->alias, n->sym->name, sym->name);
  93.     }
  94. }
  95.