/* *Intermediatefilterbetweenparserandbaselexer(base_yylexinscan.l). * *ThisfilterisneededbecauseinsomecasesthestandardSQLgrammar *requiresmorethanonetokenlookahead.Wereducethesecasestoone-token *lookaheadbyreplacingtokenshere,inordertokeepthegrammarLALR(1). * *Usingafilterissimplerthantryingtorecognizemultiwordtokens *directlyinscan.l,becausewe'dhavetoallowforcommentsbetweenthe *words.Furthermoreit'snotclearhowtodothatwithoutre-introducing *scannerbacktrack,whichwouldcostmoreperformancethanthisfilter *layerdoes. * *WealsousethisfiltertoconvertUIDENTandUSCONSTsequencesinto *plainIDENTandSCONSTtokens.Whilethatcouldbehandledbyadditional *productionsinthemaingrammar,it'smoreefficienttodoitlikethis.
*/ int
filtered_base_yylex(void)
{ int cur_token; int next_token;
YYSTYPE cur_yylval;
YYLTYPE cur_yylloc; char *cur_yytext;
/* Get next token --- we might already have it */ if (have_lookahead)
{
cur_token = lookahead_token;
base_yylval = lookahead_yylval;
base_yylloc = lookahead_yylloc;
base_yytext = lookahead_yytext;
have_lookahead = false;
} else
cur_token = base_yylex_location();
/* *Ifthistokenisn'tonethatrequireslookahead,justreturnit.
*/ switch (cur_token)
{ case FORMAT: caseNOT: case NULLS_P: case WITH: case WITHOUT: case UIDENT: case USCONST: break; default: return cur_token;
}
/* Save and restore lexer output variables around the call */
cur_yylval = base_yylval;
cur_yylloc = base_yylloc;
cur_yytext = base_yytext;
/* Get next token, saving outputs into lookahead variables */
next_token = base_yylex_location();
/* Replace cur_token if needed, based on lookahead */ switch (cur_token)
{ case FORMAT: /* Replace FORMAT by FORMAT_LA if it's followed by JSON */ switch (next_token)
{ case JSON:
cur_token = FORMAT_LA; break;
} break;
caseNOT: /* Replace NOT by NOT_LA if it's followed by BETWEEN, IN, etc */ switch (next_token)
{ case BETWEEN: case IN_P: case LIKE: case ILIKE: case SIMILAR:
cur_token = NOT_LA; break;
} break;
case NULLS_P: /* Replace NULLS_P by NULLS_LA if it's followed by FIRST or LAST */ switch (next_token)
{ case FIRST_P: case LAST_P:
cur_token = NULLS_LA; break;
} break;
case WITH: /* Replace WITH by WITH_LA if it's followed by TIME or ORDINALITY */ switch (next_token)
{ case TIME: case ORDINALITY:
cur_token = WITH_LA; break;
} break;
case WITHOUT: /* Replace WITHOUT by WITHOUT_LA if it's followed by TIME */ switch (next_token)
{ case TIME:
cur_token = WITHOUT_LA; break;
} break; case UIDENT: case USCONST: /* Look ahead for UESCAPE */ if (next_token == UESCAPE)
{ /* Yup, so get third token, which had better be SCONST */ constchar *escstr;
switch (token)
{ /* List a token here if pgc.l assigns to base_yylval.str for it */ case Op: case CSTRING: case CPP_LINE: case CVARIABLE: case BCONST: case SCONST: case USCONST: case XCONST: case FCONST: case IDENT: case UIDENT: case IP: /* Duplicate the <str> value */
base_yylloc = loc_strdup(base_yylval.str); break; default: /* Else just use the input, i.e., yytext */
base_yylloc = loc_strdup(base_yytext); /* Apply an ASCII-only downcasing */ for (unsignedchar *ptr = (unsignedchar *) base_yylloc; *ptr; ptr++)
{ if (*ptr >= 'A' && *ptr <= 'Z')
*ptr += 'a' - 'A';
} break;
} return token;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.