/* Get next token, saving outputs into lookahead variables */
next_token = core_yylex(&(yyextra->lookahead_yylval), llocp, yyscanner);
yyextra->lookahead_token = next_token;
yyextra->lookahead_yylloc = *llocp;
*llocp = cur_yylloc;
/* Now revert the un-truncation of the current token */
yyextra->lookahead_hold_char = *(yyextra->lookahead_end);
*(yyextra->lookahead_end) = '\0';
yyextra->have_lookahead = true;
/* 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;
/* Again save and restore *llocp */
cur_yylloc = *llocp;
/* Un-truncate current token so errors point to third token */
*(yyextra->lookahead_end) = yyextra->lookahead_hold_char;
/* Get third token */
next_token = core_yylex(&(yyextra->lookahead_yylval),
llocp, yyscanner);
/* If we throw error here, it will point to third token */ if (next_token != SCONST)
scanner_yyerror("UESCAPE must be followed by a simple string literal",
yyscanner);
/* *Wedon'tneedtoreverttheun-truncationofUESCAPE.What *wedowanttodoisclearhave_lookahead,therebyconsuming *allthreetokens.
*/
yyextra->have_lookahead = false;
} else
{ /* No UESCAPE, so convert using default escape character */
lvalp->core_yystype.str =
str_udeescape(lvalp->core_yystype.str, '\\',
*llocp,
yyscanner);
}
if (cur_token == UIDENT)
{ /* It's an identifier, so truncate as appropriate */
truncate_identifier(lvalp->core_yystype.str,
strlen(lvalp->core_yystype.str), true);
cur_token = IDENT;
} elseif (cur_token == USCONST)
{
cur_token = SCONST;
} break;
}
return cur_token;
}
/* convert hex digit (caller should have verified that) to value */ staticunsignedint
hexval(unsignedchar c)
{ if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 0xA; if (c >= 'A' && c <= 'F') return c - 'A' + 0xA;
elog(ERROR, "invalid hexadecimal digit"); return0; /* not reached */
}
/* is Unicode code point acceptable? */ staticvoid
check_unicode_value(pg_wchar c)
{ if (!is_valid_unicode_codepoint(c))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid Unicode escape value")));
}
/* is 'escape' acceptable as Unicode escape character (UESCAPE syntax) ? */ staticbool
check_uescapechar(unsignedchar escape)
{ if (isxdigit(escape)
|| escape == '+'
|| escape == '\''
|| escape == '"'
|| scanner_isspace(escape)) returnfalse; else returntrue;
}
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.