home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / pi0 / yypanic.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  3KB  |  160 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #
  3. /*
  4.  * pi - Pascal interpreter code translator
  5.  *
  6.  * Charles Haley, Bill Joy UCB
  7.  * Version 1.2 January 1979
  8.  *
  9.  *
  10.  * pxp - Pascal execution profiler
  11.  *
  12.  * Bill Joy UCB
  13.  * Version 1.2 January 1979
  14.  */
  15.  
  16. #include "0.h"
  17. #include "yy.h"
  18.  
  19. struct yytok oldpos;
  20. /*
  21.  * The routine yyPerror coordinates the panic when
  22.  * the correction routines fail. Three types of panics
  23.  * are possible - those in a declaration part, those
  24.  * in a statement part, and those in an expression.
  25.  *
  26.  * Declaration part panics consider insertion of "begin",
  27.  * expression part panics will stop on more symbols.
  28.  * The panics are otherwise the same.
  29.  *
  30.  * ERROR MESSAGE SUPPRESSION STRATEGY: August 11, 1977
  31.  *
  32.  * If the parser has not made at least 2 moves since the last point of
  33.  * error then we want to suppress the supplied error message.
  34.  * Otherwise we print it.
  35.  * We then skip input up to the next solid symbol.
  36.  */
  37. yyPerror(cp, kind)
  38.     char *cp;
  39.     register int kind;
  40. {
  41.     register int ishifts, brlev;
  42.  
  43.     copy(&oldpos, &Y, sizeof oldpos);
  44.     brlev = 0;
  45.     if (yychar < 0)
  46.         yychar = yylex();
  47.     for (ishifts = yyshifts; ; yychar = yylex(), yyshifts++)
  48.         switch (yychar) {
  49.             case YILLCH:
  50.                 yerror("Illegal character");
  51.                 if (ishifts == yyshifts)
  52.                     yyOshifts = 0;
  53.                 continue;
  54.             case YEOF:
  55.                 goto quiet;
  56.             case ';':
  57.                 if (kind == PPROG)
  58.                     continue;
  59.                 if (kind == PDECL)
  60.                     yychar = yylex();
  61.                 goto resume;
  62.             case YEND:
  63.                 if (kind == PPROG)
  64.                     continue;
  65.             case YPROCEDURE:
  66.             case YFUNCTION:
  67.                 goto resume;
  68.             case YLABEL:
  69.             case YTYPE:
  70.             case YCONST:
  71.             case YVAR:
  72.                 if (kind == PSTAT) {
  73.                     yerror("Declaration found when statement expected");
  74.                     goto quiet;
  75.                 }
  76.             case YBEGIN:
  77.                 goto resume;
  78.             case YFOR:
  79.             case YREPEAT:
  80.             case YWHILE:
  81.             case YGOTO:
  82.             case YIF:
  83.                 if (kind != PDECL)
  84.                     goto resume;
  85.                 yerror("Expected keyword begin after declarations, before statements");
  86.                 unyylex(&Y);
  87.                 yychar = YBEGIN;
  88.                 yylval = nullsem(YBEGIN);
  89.                 goto quiet;
  90.             case YTHEN:
  91.             case YELSE:
  92.             case YDO:
  93.                 if (kind == PSTAT) {
  94.                     yychar = yylex();
  95.                     goto resume;
  96.                 }
  97.                 if (kind == PEXPR)
  98.                     goto resume;
  99.                 continue;
  100.             case ')':
  101.             case ']':
  102.                 if (kind != PEXPR)
  103.                     continue;
  104.                 if (brlev == 0)
  105.                     goto resume;
  106.                 if (brlev > 0)
  107.                     brlev--;
  108.                 continue;
  109.             case '(':
  110.             case '[':
  111.                 brlev++;
  112.                 continue;
  113.             case ',':
  114.                 if (brlev != 0)
  115.                     continue;
  116.             case YOF:
  117.             case YTO:
  118.             case YDOWNTO:
  119.                 if (kind == PEXPR)
  120.                     goto resume;
  121.                 continue;
  122. #ifdef PI
  123.             /*
  124.              * A rough approximation for now
  125.              * Should be much more lenient on suppressing
  126.              * warnings.
  127.              */
  128.             case YID:
  129.                 syneflg++;
  130.                 continue;
  131. #endif
  132.         }
  133. resume:
  134.     if (yyOshifts >= 2) {
  135.         if (yychar != -1)
  136.             unyylex(&Y);
  137.         copy(&Y, &oldpos, sizeof Y);
  138.         yerror(cp);
  139.         yychar = yylex();
  140.     }
  141. quiet:
  142.     if (yyshifts - ishifts > 2 && opt('r')) {
  143.         setpfx('r');
  144.         yerror("Parsing resumes");
  145.     }
  146.     /*
  147.      * If we paniced in the statement part,
  148.      * and didn't stop at a ';', then we insert
  149.      * a ';' to prevent the recovery from immediately
  150.      * inserting one and complaining about it.
  151.      */
  152.     if (kind == PSTAT && yychar != ';') {
  153.         unyylex(&Y);
  154.         yyshifts--;
  155.         yytshifts--;
  156.         yychar = ';';
  157.         yylval = nullsem(';');
  158.     }
  159. }
  160.