/* 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) // Parser skeleton modified for use in the Firebird project by Nickolay Samofatov // #define YYBTYACC 1 #include #include #include #include "dsql.tab.h" #include "Parser.h" #define YYERROR_DETAILED %% 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_ const char *yyname[]; extern _C_ const char *yyrule[]; #endif %% header #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, n) #endif // If delete function is not defined by the user, do not deletions. #ifndef YYDELETEPOSN #define YYDELETEPOSN(v, n) #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 #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) // // For use in generated program // #define yytrial (yyps->save) #define yyvsp (yyps->vsp) #define yyval (yyps->val) #define yydepth (yyps->ssp - yyps->ss) %% body void Parser::yySCopy(YYSTYPE* to, YYSTYPE* from, int size) { int i; for (i = size - 1; i >= 0; i--) { to[i] = from[i]; } } void Parser::yyPCopy(YYPOSN* to, YYPOSN* from, int size) { int i; for (i = size - 1; i >= 0; i--) { to[i] = from[i]; } } void Parser::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; } Parser::yyparsestate* Parser::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 Parser::yyFreeState(Parser::yyparsestate* p) { delete[] p->ss; delete[] p->vs; delete[] p->ps; delete p; } int Parser::parseAux() { int yym, yyn, yystate, yychar, yynewerrflag; yyparsestate *yyerrctx = NULL; int reduce_posn; #if YYDEBUG const 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,%p]: state %d, reading %d (%s)", int(yydepth), 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,%p]: CONFLICT in state %d: following successful trial parse\n", int(yydepth), 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,%p]: CONFLICT in state %d. ", int(yydepth), 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[%p]: backtracking 1 token\n", 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,%p]: state %d, shifting to state %d\n", int(yydepth), 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,%p]: state %d, shifting to state %d\n", int(yydepth), 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,%p]: ERROR in state %d, CONFLICT BACKTRACKING to state %d, %d tokens\n", int(yydepth), yytrial, yystate, yyps->save->state, int(yylvp - yylvals - yyps->save->lexeme)); #endif // Memorize most forward-looking error state in case // it's really an error. if (yyerrctx == NULL || yyerrctx->lexeme < yylvp-yylvals) { // Free old saved error context state if (yyerrctx) yyFreeState(yyerrctx); // Create and fill out new saved error context state yyerrctx = yyNewState(yyps->ssp - 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[%p]: trial parse FAILED, entering ERROR mode\n", 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,%p]: state %d, ERROR recovery shifts to state %d\n", int(yydepth), 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,%p]: ERROR recovery discards state %d\n", int(yydepth), 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,%p]: state %d, ERROR recovery discards token %d (%s)\n", int(yydepth), 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,%p]: state %d, reducing by rule %d (%s)", int(yydepth), 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); } /* default action - assign last argument as in standard yacc */ yyps->val = yyvsp[1 - yym]; /* 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,%p]: after reduction, shifting from state 0 to state %d\n", int(yydepth), 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,%p]: state %d, reading %d (%s)\n", int(yydepth), 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,%p]: after reduction, shifting from state %d to state %d\n", int(yydepth), 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,%p]: CONFLICT trial successful, backtracking to state %d, %d tokens\n", int(yydepth), yytrial, yypath->state, int(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; pv < yyps->vsp; pv++) { YYDELETEVAL(*pv, 2); } YYPOSN *pp; for(pp = yyps->ps; pp < yyps->psp; 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 Parser::yylex1() { if (yylvp < yylve) { yylval = *yylvp++; yyposn = *yylpp++; return *yylexp++; } else { if (yyps->save) { if (yylvp == yylvlim) { yyexpand(); } *yylexp = yylex(); *yylvp++ = yylval; yylve++; *yylpp++ = yyposn; yylpe++; return *yylexp++; } else { return yylex(); } } } int Parser::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; }