/* The banner used here should be replaced with an #ident directive */ /* if the target C compiler supports #ident directives. */ /* */ /* If the skeleton is changed, the banner should be changed so that */ /* the altered version can easily be distinguished from the original. */ %% banner // // @(#)btyaccpar, based on byacc 1.8 (Berkeley) // #define YYBTYACC 1 #include #include #include typedef int Yshort; %% tables #define _C_ "C" extern _C_ Yshort yylhs[]; extern _C_ Yshort yylen[]; extern _C_ Yshort yydefred[]; extern _C_ Yshort yydgoto[]; extern _C_ Yshort yysindex[]; extern _C_ Yshort yyrindex[]; extern _C_ Yshort yycindex[]; extern _C_ Yshort yygindex[]; extern _C_ Yshort yytable[]; extern _C_ Yshort yycheck[]; extern _C_ Yshort yyctable[]; #if YYDEBUG extern _C_ char *yyname[]; extern _C_ char *yyrule[]; #endif %% header // // YYPOSN is user-defined text position type. // #ifndef YYPOSN #define YYPOSN int #endif #ifdef YYREDUCEPOSNFUNC #define YYCALLREDUCEPOSN(e) \ if(reduce_posn) { \ YYREDUCEPOSNFUNC(yyps->pos, &(yyps->psp)[1-yym], &(yyps->vsp)[1-yym], \ yym, yyps->psp - yyps->ps, yychar, yyposn, e); \ reduce_posn = 0; \ } #ifndef YYCALLREDUCEPOSNARG #define YYCALLREDUCEPOSNARG yyps->val #endif #define YYPOSNARG(n) ((yyps->psp)[1-yym+(n)-1]) #define YYPOSNOUT (yyps->pos) #endif // If delete function is not defined by the user, do not deletions. #ifndef YYDELETEVAL #define YYDELETEVAL(v) #endif // If delete function is not defined by the user, do not deletions. #ifndef YYDELETEPOSN #define YYDELETEPOSN(v) #endif #define yyclearin (yychar=(-1)) #define yyerrok (yyps->errflag=0) #ifndef YYSTACKGROWTH #define YYSTACKGROWTH 16 #endif #ifndef YYDEFSTACKSIZE #define YYDEFSTACKSIZE 12 #endif #ifdef YYDEBUG int yydebug; #endif int yynerrs; /* These value/posn are taken from the lexer */ YYSTYPE yylval; YYPOSN yyposn; /* These value/posn of the root non-terminal are returned to the caller */ YYSTYPE yyretlval; YYPOSN yyretposn; #define YYABORT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab #define YYVALID do { if (yyps->save) goto yyvalid; } while(0) #define YYVALID_NESTED do { if (yyps->save && \ yyps->save->save==0) goto yyvalid; } while(0) struct yyparsestate { yyparsestate *save; // Previously saved parser state int state; int errflag; Yshort *ssp; // state stack pointer YYSTYPE *vsp; // value stack pointer YYPOSN *psp; // position stack pointer YYSTYPE val; // value as returned by actions YYPOSN pos; // position as returned by universal action Yshort *ss; // state stack base YYSTYPE *vs; // values stack base YYPOSN *ps; // position stack base int lexeme; // index of the conflict lexeme in the lexical queue unsigned int stacksize; // current maximum stack size Yshort ctry; // index in yyctable[] for this conflict }; // Current parser state static yyparsestate *yyps=0; // yypath!=NULL: do the full parse, starting at *yypath parser state. static yyparsestate *yypath=0; // Base of the lexical value queue static YYSTYPE *yylvals=0; // Current posistion at lexical value queue static YYSTYPE *yylvp=0; // End position of lexical value queue static YYSTYPE *yylve=0; // The last allocated position at the lexical value queue static YYSTYPE *yylvlim=0; // Base of the lexical position queue static YYPOSN *yylpsns=0; // Current posistion at lexical position queue static YYPOSN *yylpp=0; // End position of lexical position queue static YYPOSN *yylpe=0; // The last allocated position at the lexical position queue static YYPOSN *yylplim=0; // Current position at lexical token queue static Yshort *yylexp=0; static Yshort *yylexemes=0; // // For use in generated program // #define yytrial (yyps->save) #define yyvsp (yyps->vsp) #define yyval (yyps->val) #define yydepth (yyps->ssp - yyps->ss) // // Local prototypes. // int yyparse(void); int YYLex1(); int yyexpand(); void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size); void YYPCopy(YYPOSN *to, YYPOSN *from, int size); void YYMoreStack(yyparsestate *yyps); yyparsestate *YYNewState(int size); void YYFreeState(yyparsestate *p); %% body // // Parser function // int yyparse() { int yym, yyn, yystate, yychar, yynewerrflag; yyparsestate *yyerrctx = NULL; int reduce_posn; #if YYDEBUG char *yys; if ((yys = getenv("YYDEBUG"))) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif yyps = YYNewState(YYDEFSTACKSIZE); yyps->save = 0; yynerrs = 0; yyps->errflag = 0; yychar = (-1); yyps->ssp = yyps->ss; yyps->vsp = yyps->vs; yyps->psp = yyps->ps; *(yyps->ssp) = yystate = 0; // // Main parsing loop // yyloop: if ((yyn = yydefred[yystate])) { goto yyreduce; } // // Read one token // if (yychar < 0) { if ((yychar = YYLex1()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug[%d,%d]: state %d, reading %d (%s)", yydepth, (int)yytrial, yystate, yychar, yys); #ifdef YYDBPR printf("<"); YYDBPR(yylval); printf(">"); #endif printf("\n"); } #endif } // // Do we have a conflict? // if ((yyn = yycindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { int ctry; if (yypath) { #if YYDEBUG if (yydebug) { printf("yydebug[%d,%d]: CONFLICT in state %d: following successful trial parse\n", yydepth, (int)yytrial, yystate); } #endif // Switch to the next conflict context yyparsestate *save = yypath; yypath = save->save; ctry = save->ctry; if (save->state != yystate) goto yyabort; YYFreeState(save); } else { #if YYDEBUG if (yydebug) { printf("yydebug[%d,%d]: CONFLICT in state %d. ", yydepth, (int)yytrial, yystate); if(yyps->save) { printf("ALREADY in conflict. Continue trial parse."); } else { printf("Start trial parse."); } printf("\n"); } #endif yyparsestate *save = YYNewState(yyps->ssp - yyps->ss); save->save = yyps->save; save->state = yystate; save->errflag = yyps->errflag; save->ssp = save->ss + (yyps->ssp - yyps->ss); save->vsp = save->vs + (yyps->vsp - yyps->vs); save->psp = save->ps + (yyps->psp - yyps->ps); memcpy (save->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort)); YYSCopy(save->vs, yyps->vs, (yyps->ssp - yyps->ss + 1)); YYPCopy(save->ps, yyps->ps, (yyps->ssp - yyps->ss + 1)); ctry = yytable[yyn]; if (yyctable[ctry] == -1) { #if YYDEBUG if (yydebug && yychar >= 0) printf("yydebug[%d]: backtracking 1 token\n", (int)yytrial); #endif ctry++; } save->ctry = ctry; if (!yyps->save) { // If this is a first conflict in the stack, start saving lexemes if (!yylexemes) { yylexemes = new Yshort[YYSTACKGROWTH]; yylvals = new YYSTYPE[YYSTACKGROWTH]; yylvlim = yylvals + YYSTACKGROWTH; yylpsns = new YYPOSN[YYSTACKGROWTH]; yylplim = yylpsns + YYSTACKGROWTH; } if (yylvp == yylve) { yylvp = yylve = yylvals; yylpp = yylpe = yylpsns; yylexp = yylexemes; if (yychar >= 0) { *yylve++ = yylval; *yylpe++ = yyposn; *yylexp = yychar; yychar = -1; } } } if (yychar >= 0) { yylvp--, yylpp--, yylexp--; yychar = -1; } save->lexeme = yylvp - yylvals; yyps->save = save; } if (yytable[yyn] == ctry) { #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: state %d, shifting to state %d\n", yydepth, (int)yytrial, yystate, yyctable[ctry]); #endif if (yychar < 0) yylvp++, yylpp++, yylexp++; yychar = -1; if (yyps->errflag > 0) --yyps->errflag; yystate = yyctable[ctry]; goto yyshift; } else { yyn = yyctable[ctry]; goto yyreduce; } } // // Is action a shift? // if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: state %d, shifting to state %d\n", yydepth, (int)yytrial, yystate, yytable[yyn]); #endif yychar = (-1); if (yyps->errflag > 0) --yyps->errflag; yystate = yytable[yyn]; yyshift: if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) { YYMoreStack(yyps); } *++(yyps->ssp) = yystate; *++(yyps->vsp) = yylval; *++(yyps->psp) = yyposn; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } // // Action: error // if (yyps->errflag) goto yyinrecovery; yynewerrflag = 1; goto yyerrhandler; yyerrlab: yynewerrflag = 0; yyerrhandler: while (yyps->save) { int ctry; yyparsestate *save = yyps->save; #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: ERROR in state %d, CONFLICT BACKTRACKING to state %d, %d tokens\n", yydepth, (int)yytrial, yystate, yyps->save->state, yylvp - yylvals - yyps->save->lexeme); #endif // Memorize most forward-looking error state in case // it's really an error. if(yyerrctx==NULL || yyerrctx->lexemessp - yyps->ss); yyerrctx->save = yyps->save; yyerrctx->state = yystate; yyerrctx->errflag = yyps->errflag; yyerrctx->ssp = yyerrctx->ss + (yyps->ssp - yyps->ss); yyerrctx->vsp = yyerrctx->vs + (yyps->vsp - yyps->vs); yyerrctx->psp = yyerrctx->ps + (yyps->psp - yyps->ps); memcpy (yyerrctx->ss, yyps->ss, (yyps->ssp - yyps->ss + 1)*sizeof(Yshort)); YYSCopy(yyerrctx->vs, yyps->vs, (yyps->ssp - yyps->ss + 1)); YYPCopy(yyerrctx->ps, yyps->ps, (yyps->ssp - yyps->ss + 1)); yyerrctx->lexeme = yylvp - yylvals; } yylvp = yylvals + save->lexeme; yylpp = yylpsns + save->lexeme; yylexp = yylexemes + save->lexeme; yychar = -1; yyps->ssp = yyps->ss + (save->ssp - save->ss); yyps->vsp = yyps->vs + (save->vsp - save->vs); yyps->psp = yyps->ps + (save->psp - save->ps); memcpy (yyps->ss, save->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort)); YYSCopy(yyps->vs, save->vs, yyps->vsp - yyps->vs + 1); YYPCopy(yyps->ps, save->ps, yyps->psp - yyps->ps + 1); ctry = ++save->ctry; yystate = save->state; // We tried shift, try reduce now if ((yyn = yyctable[ctry]) >= 0) { goto yyreduce; } yyps->save = save->save; YYFreeState(save); // // Nothing left on the stack -- error // if (!yyps->save) { #if YYDEBUG if (yydebug) { printf("yydebug[%d]: trial parse FAILED, entering ERROR mode\n", (int)yytrial); } #endif // Restore state as it was in the most forward-advanced error yylvp = yylvals + yyerrctx->lexeme; yylpp = yylpsns + yyerrctx->lexeme; yylexp = yylexemes + yyerrctx->lexeme; yychar = yylexp[-1]; yylval = yylvp[-1]; yyposn = yylpp[-1]; yyps->ssp = yyps->ss + (yyerrctx->ssp - yyerrctx->ss); yyps->vsp = yyps->vs + (yyerrctx->vsp - yyerrctx->vs); yyps->psp = yyps->ps + (yyerrctx->psp - yyerrctx->ps); memcpy (yyps->ss, yyerrctx->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort)); YYSCopy(yyps->vs, yyerrctx->vs, yyps->vsp - yyps->vs + 1); YYPCopy(yyps->ps, yyerrctx->ps, yyps->psp - yyps->ps + 1); yystate = yyerrctx->state; YYFreeState(yyerrctx); yyerrctx = NULL; } yynewerrflag = 1; } if (yynewerrflag) { #ifdef YYERROR_DETAILED yyerror_detailed("syntax error", yychar, yylval, yyposn); #else yyerror("syntax error"); #endif } ++yynerrs; yyinrecovery: if (yyps->errflag < 3) { yyps->errflag = 3; for (;;) { if ((yyn = yysindex[*(yyps->ssp)]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: state %d, ERROR recovery shifts to state %d\n", yydepth, (int)yytrial, *(yyps->ssp), yytable[yyn]); #endif /* Use label yyerrlab, so that compiler does not warn */ if(yyps->errflag != yyps->errflag) goto yyerrlab; yystate = yytable[yyn]; goto yyshift; } else { #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: ERROR recovery discards state %d\n", yydepth, (int)yytrial, *(yyps->ssp)); #endif if (yyps->ssp <= yyps->ss) { goto yyabort; } if(!yytrial) { YYDELETEVAL(yyps->vsp[0],1); YYDELETEPOSN(yyps->psp[0],1); } --(yyps->ssp); --(yyps->vsp); --(yyps->psp); } } } else { if (yychar == 0) goto yyabort; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug[%d,%d]: state %d, ERROR recovery discards token %d (%s)\n", yydepth, (int)yytrial, yystate, yychar, yys); } #endif if(!yytrial) { YYDELETEVAL(yylval,0); YYDELETEPOSN(yyposn,0); } yychar = (-1); goto yyloop; } // // Reduce the rule // yyreduce: yym = yylen[yyn]; #if YYDEBUG if (yydebug) { printf("yydebug[%d,%d]: state %d, reducing by rule %d (%s)", yydepth, (int)yytrial, yystate, yyn, yyrule[yyn]); #ifdef YYDBPR if (yym) { int i; printf("<"); for (i=yym; i>0; i--) { if (i!=yym) printf(", "); YYDBPR((yyps->vsp)[1-i]); } printf(">"); } #endif printf("\n"); } #endif if (yyps->ssp + 1 - yym >= yyps->ss + yyps->stacksize) { YYMoreStack(yyps); } /* "$$ = NULL" default action */ memset(&yyps->val, 0, sizeof(yyps->val)); /* default reduced position is NULL -- no position at all. no position will be assigned at trial time and if no position handling is present */ memset(&yyps->pos, 0, sizeof(yyps->pos)); reduce_posn = TRUE; switch (yyn) { %% trailer default: break; } #if YYDEBUG && defined(YYDBPR) if (yydebug) { printf("yydebug[%d]: after reduction, result is ", yytrial); YYDBPR(yyps->val); printf("\n"); } #endif // Perform user-defined position reduction #ifdef YYREDUCEPOSNFUNC if(!yytrial) { YYCALLREDUCEPOSN(YYREDUCEPOSNFUNCARG); } #endif yyps->ssp -= yym; yystate = *(yyps->ssp); yyps->vsp -= yym; yyps->psp -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) { printf("yydebug[%d,%d]: after reduction, shifting from state 0 to state %d\n", yydepth, (int)yytrial, YYFINAL); } #endif yystate = YYFINAL; *++(yyps->ssp) = YYFINAL; *++(yyps->vsp) = yyps->val; yyretlval = yyps->val; // return value of root non-terminal to yylval *++(yyps->psp) = yyps->pos; yyretposn = yyps->pos; // return value of root position to yyposn if (yychar < 0) { if ((yychar = YYLex1()) < 0) { yychar = 0; } #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("yydebug[%d,%d]: state %d, reading %d (%s)\n", yydepth, (int)yytrial, YYFINAL, yychar, yys); } #endif } if (yychar == 0) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yystate) { yystate = yytable[yyn]; } else { yystate = yydgoto[yym]; } #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: after reduction, shifting from state %d to state %d\n", yydepth, (int)yytrial, *(yyps->ssp), yystate); #endif if (yyps->ssp >= yyps->ss + yyps->stacksize - 1) { YYMoreStack(yyps); } *++(yyps->ssp) = yystate; *++(yyps->vsp) = yyps->val; *++(yyps->psp) = yyps->pos; goto yyloop; // // Reduction declares that this path is valid. // Set yypath and do a full parse // yyvalid: if (yypath) { goto yyabort; } while (yyps->save) { yyparsestate *save = yyps->save; yyps->save = save->save; save->save = yypath; yypath = save; } #if YYDEBUG if (yydebug) printf("yydebug[%d,%d]: CONFLICT trial successful, backtracking to state %d, %d tokens\n", yydepth, (int)yytrial, yypath->state, yylvp - yylvals - yypath->lexeme); #endif if(yyerrctx) { YYFreeState(yyerrctx); yyerrctx = NULL; } yychar = -1; yyps->ssp = yyps->ss + (yypath->ssp - yypath->ss); yyps->vsp = yyps->vs + (yypath->vsp - yypath->vs); yyps->psp = yyps->ps + (yypath->psp - yypath->ps); memcpy (yyps->ss, yypath->ss, (yyps->ssp - yyps->ss + 1) * sizeof(Yshort)); YYSCopy(yyps->vs, yypath->vs, yyps->vsp - yyps->vs + 1); YYPCopy(yyps->ps, yypath->ps, yyps->psp - yyps->ps + 1); yylvp = yylvals + yypath->lexeme; yylpp = yylpsns + yypath->lexeme; yylexp = yylexemes + yypath->lexeme; yystate = yypath->state; goto yyloop; yyabort: if(yyerrctx) { YYFreeState(yyerrctx); yyerrctx = NULL; } YYSTYPE *pv; for(pv=yyps->vs; pvvsp; pv++) { YYDELETEVAL(*pv,2); } YYPOSN *pp; for(pp=yyps->ps; pppsp; pp++) { YYDELETEPOSN(*pp,2); } while (yyps) { yyparsestate *save = yyps; yyps = save->save; YYFreeState(save); } while (yypath) { yyparsestate *save = yypath; yypath = save->save; YYFreeState(save); } return (1); yyaccept: if (yyps->save) goto yyvalid; if(yyerrctx) { YYFreeState(yyerrctx); yyerrctx = NULL; } while (yyps) { yyparsestate *save = yyps; yyps = save->save; YYFreeState(save); } while (yypath) { yyparsestate *save = yypath; yypath = save->save; YYFreeState(save); } return (0); } int YYLex1() { if(yylvpsave) { if(yylvp==yylvlim) { yyexpand(); } *yylexp = yylex(); *yylvp++ = yylval; yylve++; *yylpp++ = yyposn; yylpe++; return *yylexp++; } else { return yylex(); } } } int yyexpand() { int p = yylvp-yylvals; int s = yylvlim-yylvals; s += YYSTACKGROWTH; { Yshort *tl = yylexemes; YYSTYPE *tv = yylvals; YYPOSN *tp = yylpsns; yylvals = new YYSTYPE[s]; yylpsns = new YYPOSN[s]; yylexemes = new Yshort[s]; memcpy(yylexemes, tl, (s-YYSTACKGROWTH)*sizeof(Yshort)); YYSCopy(yylvals, tv, s-YYSTACKGROWTH); YYPCopy(yylpsns, tp, s-YYSTACKGROWTH); delete[] tl; delete[] tv; delete[] tp; } yylvp = yylve = yylvals + p; yylvlim = yylvals + s; yylpp = yylpe = yylpsns + p; yylplim = yylpsns + s; yylexp = yylexemes + p; return 0; } void YYSCopy(YYSTYPE *to, YYSTYPE *from, int size) { int i; for (i = size-1; i >= 0; i--) { to[i] = from[i]; } } void YYPCopy(YYPOSN *to, YYPOSN *from, int size) { int i; for (i = size-1; i >= 0; i--) { to[i] = from[i]; } } void YYMoreStack(yyparsestate *yyps) { int p = yyps->ssp - yyps->ss; Yshort *tss = yyps->ss; YYSTYPE *tvs = yyps->vs; YYPOSN *tps = yyps->ps; yyps->ss = new Yshort [yyps->stacksize + YYSTACKGROWTH]; yyps->vs = new YYSTYPE[yyps->stacksize + YYSTACKGROWTH]; yyps->ps = new YYPOSN [yyps->stacksize + YYSTACKGROWTH]; memcpy(yyps->ss, tss, yyps->stacksize * sizeof(Yshort)); YYSCopy(yyps->vs, tvs, yyps->stacksize); YYPCopy(yyps->ps, tps, yyps->stacksize); yyps->stacksize += YYSTACKGROWTH; delete[] tss; delete[] tvs; delete[] tps; yyps->ssp = yyps->ss + p; yyps->vsp = yyps->vs + p; yyps->psp = yyps->ps + p; } yyparsestate *YYNewState(int size) { yyparsestate *p = new yyparsestate; p->stacksize = size+4; p->ss = new Yshort [size + 4]; p->vs = new YYSTYPE[size + 4]; p->ps = new YYPOSN [size + 4]; memset(&p->vs[0], 0, (size+4)*sizeof(YYSTYPE)); memset(&p->ps[0], 0, (size+4)*sizeof(YYPOSN)); return p; } void YYFreeState(yyparsestate *p) { delete[] p->ss; delete[] p->vs; delete[] p->ps; delete p; }