home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cproto.zip / cproto46 / yyerror.c < prev   
C/C++ Source or Header  |  1996-04-13  |  4KB  |  179 lines

  1. /* $Id: yyerror.c,v 4.3 1996/04/13 04:29:18 cthuang Exp $
  2.  *
  3.  * This file is included into grammar.y to provide the 'yyerror()' function. 
  4.  * If the yacc/bison parser is one that we know how to backtrack, we'll augment
  5.  * the "syntax error" message with information that shows what type of token we
  6.  * expected.
  7.  */
  8.  
  9. /* 'yyerror()' has to be a macro, since it must be expanded inline to subvert
  10.  * the internal state of 'yyparse()'.
  11.  */
  12. #if BISON_HAS_YYTNAME    /* bison 1.22 */
  13. #if YYDEBUG
  14. /* this is better than defining YYERROR_VERBOSE */
  15. #define    yyerror(text) {\
  16.     register int n, c1, count = 0;\
  17.     yaccError(text);\
  18.     if (yypact[yystate] != YYFLAG)\
  19.     for (c1 = 0; c1 < YYLAST; c1++) {\
  20.         n = yypact[yystate] + c1;\
  21.         if (n >= 0 && n < YYLAST\
  22.          && yycheck[n] == c1 && yytname[c1] != 0)\
  23.         yaccExpected(yytname[c1], count++);\
  24.     }\
  25.     yaccExpected("", -1);\
  26. }
  27. #endif
  28. #endif    /* BISON_HAS_YYTNAME */
  29.  
  30. #if YACC_HAS_YYTOKS_2
  31. #undef  YACC_HAS_YYTOKS
  32. #define YACC_HAS_YYTOKS 1
  33. #define YaccState yy_state
  34. #endif
  35.  
  36. #if YACC_HAS_YYTOKS        /* Solaris, Gould */
  37. #if YYDEBUG
  38. #ifndef YaccState
  39. #define YaccState yystate    /* sometimes 'yy_state' */
  40. #endif
  41. #define    yyerror(text) {\
  42.     register int    n, x, c1, y, count = 0;\
  43.     yaccError(text);\
  44.     if (((n = yypact[YaccState]) > YYFLAG) && (n < YYLAST)) {\
  45.     for (x = ((n > 0) ? n : 0); x < YYLAST; ++x) {\
  46.         c1 = x - n;\
  47.         if ((yychk[yyact[x]] == c1) && (c1 != YYERRCODE)) {\
  48.         if (isascii(c1)) {\
  49.             static char tmp[] = "'%'";\
  50.             tmp[1] = c1;\
  51.             yaccExpected(tmp, count++);\
  52.         } else {\
  53.             for (y = 0; yytoks[y].t_val >= 0; y++) {\
  54.             if (yytoks[y].t_val == c1) {\
  55.                 yaccExpected(yytoks[y].t_name, count++);\
  56.                 break;\
  57.             }\
  58.             }\
  59.         }\
  60.         }\
  61.     }\
  62.     }\
  63.     yaccExpected("", -1);\
  64. }
  65. #endif
  66. #endif    /* YACC_HAS_YYTOKS */
  67.  
  68. #if YACC_HAS_YYNAME    /* Linux's yacc */
  69. #if YYDEBUG
  70. #define    yyerror(text) {\
  71.     register int n, x, c1, count = 0;\
  72.     yaccError(text);\
  73.     if (((n = yysindex[yystate]) != 0) && (n < YYTABLESIZE)) {\
  74.     for (x = ((n > 0) ? n : 0); x < YYTABLESIZE; ++x) {\
  75.         c1 = x - n;\
  76.         if ((yycheck[x] == c1) && (c1 != YYERRCODE)) {\
  77.         yaccExpected(yyname[c1] ? yyname[c1] : "illegal symbol",\
  78.             count++);\
  79.         }\
  80.     }\
  81.     }\
  82.     yaccExpected("", -1);\
  83. #endif
  84. #endif    /* YACC_HAS_YYNAME */
  85.  
  86.  
  87. /*
  88.  * Any way we define it, 'yyerror()' is a real function (that we provide,
  89.  * rather than use the one from a library).
  90.  */
  91. static void yaccError    ARGS((char *));
  92.  
  93. #ifdef yyerror
  94. static int  compar       ARGS((const void *a, const void *b));
  95. static void yaccExpected ARGS((const char *, int count));
  96.  
  97. static
  98. int compar(p1, p2)
  99. const void *p1;
  100. const void *p2;
  101. {
  102.     return (strcmp(*(char **)p1, *(char **)p2));
  103. }
  104.  
  105. static
  106. void yaccExpected (s, count)
  107. const char *s;
  108. int count;
  109. {
  110.     static struct {
  111.     char *actual, *name;
  112.     } tbl[] = {
  113.     {"...",    "T_ELLIPSIS"},
  114.     {"[]",    "T_BRACKETS"},
  115.     {"{",    "T_LBRACE"},
  116.     {"}",    "T_MATCHRBRACE"},
  117.     };
  118.     register int j, k, x;
  119.     char *t = (char *)s;
  120.     char *tag;
  121.     char tmp[80];
  122.     static int last;
  123.     static char    *vec[10];    /* patch: don't know how big */
  124.  
  125.     if (count < 0) {
  126.     if (last++ >= 0) {
  127.         qsort((char *)vec, (size_t)last, sizeof(vec[0]), compar);
  128.         /* limit length of error message */
  129.         k = 80 - (strlen(vec[last-1]) + 2);
  130.         for (j = 0; j < last; j++) {
  131.         tag = j ? " " : "Expected: ";
  132.         s = vec[j];
  133.         if (j != (last - 1)) {
  134.             x = strlen(s) + strlen(tag);
  135.             if (k <= 0)
  136.             continue;
  137.             else if ((k - x) <= 0)
  138.             s = "...";
  139.             k -= x;
  140.         }
  141.         fprintf(stderr, "%s%s", tag, s);
  142.         }
  143.         fprintf(stderr, "\n");
  144.         while (--last >= 0)
  145.             free(vec[last]);
  146.     }
  147.     } else {
  148.     if (!strncmp(t, "T_", 2)) {
  149.         int    found = FALSE;
  150.         for (j = 0; j < sizeof(tbl)/sizeof(tbl[0]); j++) {
  151.         if (!strcmp(t, tbl[j].name)) {
  152.             t = tbl[j].actual;
  153.             found = TRUE;
  154.             break;
  155.         }
  156.         }
  157.         if (!found) {
  158.         t = strncpy(tmp, t + 2, sizeof(tmp)-1);
  159.         for (k = 0; t[k] != '\0'; k++) {
  160.             if (t[k] == '_')
  161.             t[k] = '-';
  162.             else if (isalpha(t[k]) && isupper(t[k]))
  163.             t[k] = tolower(t[k]);
  164.         }
  165.         }
  166.     }
  167.     if (count > (sizeof(vec)/sizeof(vec[0]))-1) {
  168.         count = (sizeof(vec)/sizeof(vec[0]))-1;
  169.         free(vec[count]);
  170.     }
  171.     vec[count] = xstrdup(t);
  172.     }
  173.     last = count;
  174. }
  175. #else
  176. #define yyerror(s) yaccError(s)
  177. #endif    /* yyerror */
  178.