GENWiki

Premier IT Outsourcing and Support Services within the UK

User Tools

Site Tools


archive:programming:yaccex

_GENERATING PARSERS WITH PCYACC_ by Alex Lane

[LISTING ONE]

yacc specification

/* TEST.Y

This specification is based largely on the yacc specification for a simple desk calculator from "Compilers: Principles, Techniques and Tools," by Aho, et al. (p. 259, Addison-Wesley, 1986).

2/2/89 a.lane */

%{ #include <stdio.h> #include <ctype.h> %}

%token DIGIT %left '+' %left '*'

line : /* nothing */ | expr '\n' { printf("%d\n", $1); } ; expr : expr '+' term { $$ = $1 + $3; } | term ; term : term '*' factor { $$ = $1 * $3; } | factor ; factor: '(' expr ')' { $$ = $2; } | DIGIT ; main() { yyparse(); }

yylex() {

   int c;
   if ( isdigit( ( c = getchar() ) ) )  {
        yylval = c - '0';
        return DIGIT;
   }
   return c;

}

yyerror(s) char *s; {

   fprintf(stderr, "PYERR: %s\n", s);

}

[LISTING TWO]

# line 11 "test.y" #include <stdio.h> #include <ctype.h> #define DIGIT 257 #ifndef YYSTYPE #define YYSTYPE int #endif YYSTYPE yylval, yyval; #define YYERRCODE 256

# line 33 "test.y"

main() { yyparse(); }

yylex() {

   int c;
   if ( isdigit( ( c = getchar() ) ) )  {
        yylval = c - '0';
        return DIGIT;
   }
   return c;

}

yyerror(s) char *s; {

   fprintf(stderr, "PYERR: %s\n", s);

}

FILE *yytfilep; char *yytfilen; int yytflag = 0; int svdprd[2]; char svdnams[2][2];

int yyexca[] = {

  1. 1, 1,

0, -1,

  1. 2, 0,

0, };

#define YYNPROD 9 #define YYLAST 218

int yyact[] = {

     5,       7,      13,       4,       8,       9,       3,       1,
     2,       0,       0,       0,       0,      12,      10,      11,
     4,       0,       3,       2,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       8,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       0,       0,       0,       0,       0,       0,       0,
     0,       6,

};

int yypact[] = {

  1. 40, -1000, -9, -37, -1000, -40, -1000, -1000,
  2. 40, -40, -39, -37, -1000, -1000,

};

int yypgo[] = {

     0,       7,       8,       6,       3,

};

int yyr1[] = {

     0,       1,       1,       2,       2,       3,       3,       4,
     4,

};

int yyr2[] = {

     2,       0,       2,       3,       1,       3,       1,       3,
     1,

};

int yychk[] = {

  1. 1000, -1, -2, -3, -4, 40, 257, 10,

43, 42, -2, -3, -4, 41, };

int yydef[] = {

     1,      -2,       0,       4,       6,       0,       8,       2,
     0,       0,       0,       3,       5,       7,

};

int *yyxi;

/*/ /* PCYACC LALR parser driver routine – a table driven procedure */ /* for recognizing sentences of a language defined by the */ /* grammar that PCYACC analyzes. An LALR parsing table is then */ /* constructed for the grammar and the skeletal parser uses the */ /* table when performing syntactical analysis on input source */ /* programs. The actions associated with grammar rules are */ /* inserted into a switch statement for execution. */ /*/

#ifndef YYMAXDEPTH #define YYMAXDEPTH 200 #endif #ifndef YYREDMAX #define YYREDMAX 1000 #endif #define PCYYFLAG -1000 #define WAS0ERR 0 #define WAS1ERR 1 #define WAS2ERR 2 #define WAS3ERR 3 #define yyclearin pcyytoken = -1 #define yyerrok pcyyerrfl = 0 YYSTYPE yyv[YYMAXDEPTH]; /* value stack */ int pcyyerrct = 0; /* error count */ int pcyyerrfl = 0; /* error flag */ int redseq[YYREDMAX]; int redcnt = 0; int pcyytoken = -1; /* input token */

yyparse() {

int statestack[YYMAXDEPTH]; /* state stack */
int      j, m;              /* working index */
YYSTYPE *yypvt;
int      tmpstate, tmptoken, *yyps, n;
YYSTYPE *yypv;

tmpstate = 0;

pcyytoken = -1;

#ifdef YYDEBUG

tmptoken = -1;

#endif

pcyyerrct = 0;
pcyyerrfl = 0;
yyps = &statestack[-1];
yypv = &yyv[-1];

enstack: /* push stack */ #ifdef YYDEBUG

  printf("at state %d, next token %d\n", tmpstate, tmptoken);

#endif

  if (++yyps - &statestack[YYMAXDEPTH] > 0) {
    yyerror("pcyacc internal stack overflow");
    return(1);
  }
  *yyps = tmpstate;
  ++yypv;
  *yypv = yyval;

newstate:

  n = yypact[tmpstate];
  if (n <= PCYYFLAG) goto defaultact; /*  a simple state */

if (pcyytoken < 0) if 1) < 0) pcyytoken = 0;

  if ((n += pcyytoken) < 0 || n >= YYLAST) goto defaultact;

if (yychk[n=yyact[n]] == pcyytoken) { /* a shift */ #ifdef YYDEBUG

    tmptoken  = pcyytoken;

#endif

    pcyytoken = -1;
    yyval = yylval;
    tmpstate = n;
    if (pcyyerrfl > 0) --pcyyerrfl;
    goto enstack;
  }

defaultact:

if 2)

1)
pcyytoken=yylex(
2)
n=yydef[tmpstate]) == -2) {
    if (pcyytoken < 0) if ((pcyytoken=yylex())<0) pcyytoken = 0;
    for (yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=tmpstate); yyxi += 2);
    while (*(yyxi+=2) >= 0) if (*yyxi == pcyytoken) break;
    if ((n=yyxi[1]) < 0) { /* an accept action */
      if (yytflag) {
        int ti; int tj;
        yytfilep = fopen(yytfilen, "w");
        if (yytfilep == NULL) {
          fprintf(stderr, "Can't open t file: %s\n", yytfilen);
          return(0);          }
        for (ti=redcnt-1; ti>=0; ti--) {
          tj = svdprd[redseq[ti]];
          while (strcmp(svdnams[tj], "$EOP"))
            fprintf(yytfilep, "%s ", svdnams[tj++]);
          fprintf(yytfilep, "\n");
        }
        fclose(yytfilep);
      }
      return (0);
    }
  }
  if (n == 0) {        /* error situation */
    switch (pcyyerrfl) {
      case WAS0ERR:          /* an error just occurred */
        yyerror("syntax error");
        yyerrlab:
          ++pcyyerrct;
      case WAS1ERR:
      case WAS2ERR:           /* try again */
        pcyyerrfl = 3;
      /* find a state for a legal shift action */
        while (yyps >= statestack) {
        n = yypact[*yyps] + YYERRCODE;
        if (n >= 0 && n < YYLAST && yychk[yyact[n]] == YYERRCODE) {
          tmpstate = yyact[n];  /* simulate a shift of "error" */
          goto enstack;
          }
        n = yypact[*yyps];
        /* the current yyps has no shift on "error", pop stack */
#ifdef YYDEBUG
          printf("error: pop state %d, recover state %d\n", *yyps, yyps[-
1]); #endif
  1. -yyps;
  2. -yypv;
}
      yyabort:
          if (yytflag) {
            int ti; int tj;
            yytfilep = fopen(yytfilen, "w");
            if (yytfilep == NULL) {
              fprintf(stderr, "Can't open t file: %s\n", yytfilen);
              return(1);              }
            for (ti=1; ti<redcnt; ti++) {
              tj = svdprd[redseq[ti]];
              while (strcmp(svdnams[tj], "$EOP"))
                fprintf(yytfilep, "%s ", svdnams[tj++]);
              fprintf(yytfilep, "\n");
            }
            fclose(yytfilep);
          }
        return(1);
    case WAS3ERR:  /* clobber input char */
#ifdef YYDEBUG
        printf("error: discard token %d\n", pcyytoken);
#endif
        if (pcyytoken == 0) goto yyabort; /* quit */
      pcyytoken = -1;
      goto newstate;      } /* switch */
  } /* if */
  /* reduction, given a production n */
#ifdef YYDEBUG
  printf("reduce with rule %d\n", n);
#endif
  if (yytflag && redcnt<YYREDMAX) redseq[redcnt++] = n;
  yyps -= yyr2[n];
  yypvt = yypv;
  yypv -= yyr2[n];
  yyval = yypv[1];
  m = n;
  /* find next state from goto table */
  n = yyr1[n];
  j = yypgo[n] + *yyps + 1;
  if (j>=YYLAST || yychk[ tmpstate = yyact[j] ] != -n) tmpstate =
yyact[yypgo[n]];
  switch (m) { /* actions associated with grammar rules */
    case 2:
# line 22 "test.y"
    { printf("%d\n", yypvt[-1]); } break;
    case 3:
# line 24 "test.y"
    { yyval = yypvt[-2] + yypvt[-0]; } break;
    case 5:
# line 27 "test.y"
    { yyval = yypvt[-2] * yypvt[-0]; } break;
    case 7:
# line 30 "test.y"
    { yyval = yypvt[-1]; } break;    }
  goto enstack;
}
/data/webs/external/dokuwiki/data/pages/archive/programming/yaccex.txt · Last modified: 2001/11/08 10:27 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki