8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 21:23:04 +01:00
firebird-mirror/src/dsql/btyacc_fb.ske
2023-09-18 20:38:33 -03:00

768 lines
19 KiB
Plaintext

/* 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 "firebird.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <optional>
#include "../dsql/Nodes.h"
#include "../dsql/AggNodes.h"
#include "../dsql/DdlNodes.h"
#include "../dsql/BoolNodes.h"
#include "../dsql/ExprNodes.h"
#include "../dsql/PackageNodes.h"
#include "../dsql/StmtNodes.h"
#include "../dsql/WinNodes.h"
#include "../jrd/RecordSourceNodes.h"
#include "../common/classes/TriState.h"
#include "gen/parse.h"
#include "../dsql/Parser.h"
%% 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 128
#endif
#ifndef YYDEFSTACKSIZE
#define YYDEFSTACKSIZE 12
#endif
#ifdef YYDEBUG
int yydebug;
#endif
#define YYABORT goto yyabort
#define YYACCEPT goto yyaccept
#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 = FB_NEW_POOL(getPool()) Yshort [yyps->stacksize + YYSTACKGROWTH];
yyps->vs = FB_NEW_POOL(getPool()) YYSTYPE[yyps->stacksize + YYSTACKGROWTH];
yyps->ps = FB_NEW_POOL(getPool()) 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 = FB_NEW_POOL(getPool()) yyparsestate;
p->stacksize = size + 4;
p->ss = FB_NEW_POOL(getPool()) Yshort [size + 4];
p->vs = FB_NEW_POOL(getPool()) YYSTYPE[size + 4];
p->ps = FB_NEW_POOL(getPool()) 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;
}
void Parser::setNodeLineColumn(Node* node)
{
// Check if we are not accessing the position stack below its base.
if (&YYPOSNARG(1) >= yyps->ps)
{
node->line = YYPOSNARG(1).firstLine;
node->column = YYPOSNARG(1).firstColumn;
}
}
int Parser::parseAux()
{
// ASF: yym moved to Parser.h
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 = FB_NEW_POOL(getPool()) Yshort[YYSTACKGROWTH];
yylvals = FB_NEW_POOL(getPool()) YYSTYPE[YYSTACKGROWTH];
yylvlim = yylvals + YYSTACKGROWTH;
yylpsns = FB_NEW_POOL(getPool()) 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;
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;
}
}
yyerror_detailed("syntax error", yychar, yylval, yyposn);
++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
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 = FB_NEW_POOL(getPool()) YYSTYPE[s];
yylpsns = FB_NEW_POOL(getPool()) YYPOSN[s];
yylexemes = FB_NEW_POOL(getPool()) 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;
}