⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan.l

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 L
📖 第 1 页 / 共 2 页
字号:
				}<xq>{xqinside}  {					addlit(yytext, yyleng);				}<xq>{xqescape}  {					if (yytext[1] == '\'')					{						if (backslash_quote == BACKSLASH_QUOTE_OFF ||							(backslash_quote == BACKSLASH_QUOTE_SAFE_ENCODING &&							 PG_ENCODING_IS_CLIENT_ONLY(pg_get_client_encoding())))							ereport(ERROR,									(errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),									 errmsg("unsafe use of \\' in a string literal"),									 errhint("Use '' to write quotes in strings. \\' is insecure in client-only encodings."),									 errposition(pg_err_position())));						if (warn_on_first_escape && escape_string_warning)							ereport(WARNING,									(errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),									 errmsg("nonstandard use of \\' in a string literal"),									 errhint("Use '' to write quotes in strings, or use the escape string syntax (E'...')."),									 errposition(pg_err_position())));						warn_on_first_escape = false;	/* warn only once per string */					}					else if (yytext[1] == '\\')					{						if (warn_on_first_escape && escape_string_warning)							ereport(WARNING,									(errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),									 errmsg("nonstandard use of \\\\ in a string literal"),									 errhint("Use the escape string syntax for backslashes, e.g., E'\\\\'."),									 errposition(pg_err_position())));						warn_on_first_escape = false;	/* warn only once per string */					}					else						check_escape_warning();					addlitchar(unescape_single_char(yytext[1]));				}<xq>{xqoctesc}  {					unsigned char c = strtoul(yytext+1, NULL, 8);					check_escape_warning();					addlitchar(c);				}<xq>{xqhexesc}  {					unsigned char c = strtoul(yytext+2, NULL, 16);					check_escape_warning();					addlitchar(c);				}<xq>{quotecontinue} {					/* ignore */				}<xq>.			{					/* This is only needed for \ just before EOF */					addlitchar(yytext[0]);				}<xq><<EOF>>		{ yyerror("unterminated quoted string"); }{dolqdelim}		{					token_start = yytext;					dolqstart = pstrdup(yytext);					BEGIN(xdolq);					startlit();				}{dolqfailed}	{					/* throw back all but the initial "$" */					yyless(1);					/* and treat it as {other} */					return yytext[0];				}<xdolq>{dolqdelim} {					if (strcmp(yytext, dolqstart) == 0)					{						pfree(dolqstart);						BEGIN(INITIAL);						yylval.str = litbufdup();						return SCONST;					}					else					{						/*						 * When we fail to match $...$ to dolqstart, transfer						 * the $... part to the output, but put back the final						 * $ for rescanning.  Consider $delim$...$junk$delim$						 */						addlit(yytext, yyleng-1);						yyless(yyleng-1);					}				}<xdolq>{dolqinside} {					addlit(yytext, yyleng);				}<xdolq>{dolqfailed} {					addlit(yytext, yyleng);				}<xdolq>.		{					/* This is only needed for $ inside the quoted text */					addlitchar(yytext[0]);				}<xdolq><<EOF>>	{ yyerror("unterminated dollar-quoted string"); }{xdstart}		{					token_start = yytext;					BEGIN(xd);					startlit();				}<xd>{xdstop}	{					char		   *ident;					BEGIN(INITIAL);					if (literallen == 0)						yyerror("zero-length delimited identifier");					ident = litbufdup();					if (literallen >= NAMEDATALEN)						truncate_identifier(ident, literallen, true);					yylval.str = ident;					return IDENT;				}<xd>{xddouble}	{					addlitchar('"');				}<xd>{xdinside}	{					addlit(yytext, yyleng);				}<xd><<EOF>>		{ yyerror("unterminated quoted identifier"); }{typecast}		{					return TYPECAST;				}{self}			{					return yytext[0];				}{operator}		{					/*					 * Check for embedded slash-star or dash-dash; those					 * are comment starts, so operator must stop there.					 * Note that slash-star or dash-dash at the first					 * character will match a prior rule, not this one.					 */					int		nchars = yyleng;					char   *slashstar = strstr(yytext, "/*");					char   *dashdash = strstr(yytext, "--");					if (slashstar && dashdash)					{						/* if both appear, take the first one */						if (slashstar > dashdash)							slashstar = dashdash;					}					else if (!slashstar)						slashstar = dashdash;					if (slashstar)						nchars = slashstar - yytext;					/*					 * For SQL compatibility, '+' and '-' cannot be the					 * last char of a multi-char operator unless the operator					 * contains chars that are not in SQL operators.					 * The idea is to lex '=-' as two operators, but not					 * to forbid operator names like '?-' that could not be					 * sequences of SQL operators.					 */					while (nchars > 1 &&						   (yytext[nchars-1] == '+' ||							yytext[nchars-1] == '-'))					{						int		ic;						for (ic = nchars-2; ic >= 0; ic--)						{							if (strchr("~!@#^&|`?%", yytext[ic]))								break;						}						if (ic >= 0)							break; /* found a char that makes it OK */						nchars--; /* else remove the +/-, and check again */					}					if (nchars < yyleng)					{						/* Strip the unwanted chars from the token */						yyless(nchars);						/*						 * If what we have left is only one char, and it's						 * one of the characters matching "self", then						 * return it as a character token the same way						 * that the "self" rule would have.						 */						if (nchars == 1 &&							strchr(",()[].;:+-*/%^<>=", yytext[0]))							return yytext[0];					}					/*					 * Complain if operator is too long.  Unlike the case					 * for identifiers, we make this an error not a notice-					 * and-truncate, because the odds are we are looking at					 * a syntactic mistake anyway.					 */					if (nchars >= NAMEDATALEN)						yyerror("operator too long");					/* Convert "!=" operator to "<>" for compatibility */					if (strcmp(yytext, "!=") == 0)						yylval.str = pstrdup("<>");					else						yylval.str = pstrdup(yytext);					return Op;				}{param}			{					yylval.ival = atol(yytext + 1);					return PARAM;				}{integer}		{					long val;					char* endptr;					errno = 0;					val = strtol(yytext, &endptr, 10);					if (*endptr != '\0' || errno == ERANGE#ifdef HAVE_LONG_INT_64						/* if long > 32 bits, check for overflow of int4 */						|| val != (long) ((int32) val)#endif						)					{						/* integer too large, treat it as a float */						yylval.str = pstrdup(yytext);						return FCONST;					}					yylval.ival = val;					return ICONST;				}{decimal}		{					yylval.str = pstrdup(yytext);					return FCONST;				}{real}			{					yylval.str = pstrdup(yytext);					return FCONST;				}{realfail1}		{					/*					 * throw back the [Ee], and treat as {decimal}.  Note					 * that it is possible the input is actually {integer},					 * but since this case will almost certainly lead to a					 * syntax error anyway, we don't bother to distinguish.					 */					yyless(yyleng-1);					yylval.str = pstrdup(yytext);					return FCONST;				}{realfail2}		{					/* throw back the [Ee][+-], and proceed as above */					yyless(yyleng-2);					yylval.str = pstrdup(yytext);					return FCONST;				}{identifier}	{					const ScanKeyword *keyword;					char		   *ident;					/* Is it a keyword? */					keyword = ScanKeywordLookup(yytext);					if (keyword != NULL)					{						yylval.keyword = keyword->name;						return keyword->value;					}					/*					 * No.  Convert the identifier to lower case, and truncate					 * if necessary.					 */					ident = downcase_truncate_identifier(yytext, yyleng, true);					yylval.str = ident;					return IDENT;				}{other}			{					return yytext[0];				}%%static intpg_err_position(void){	const char *loc = token_start ? token_start : yytext;	/* in multibyte encodings, return index in characters not bytes */	return pg_mbstrlen_with_len(scanbuf, loc - scanbuf) + 1;}voidyyerror(const char *message){	const char *loc = token_start ? token_start : yytext;	int			cursorpos = pg_err_position();	if (*loc == YY_END_OF_BUFFER_CHAR)	{		ereport(ERROR,				(errcode(ERRCODE_SYNTAX_ERROR),				 /* translator: %s is typically "syntax error" */				 errmsg("%s at end of input", _(message)),				 errposition(cursorpos)));	}	else	{		ereport(ERROR,				(errcode(ERRCODE_SYNTAX_ERROR),				 /* translator: first %s is typically "syntax error" */				 errmsg("%s at or near \"%s\"", _(message), loc),				 errposition(cursorpos)));	}}/* * Called before any actual parsing is done */voidscanner_init(const char *str){	Size	slen = strlen(str);	/*	 * Might be left over after ereport()	 */	if (YY_CURRENT_BUFFER)		yy_delete_buffer(YY_CURRENT_BUFFER);	/*	 * Make a scan buffer with special termination needed by flex.	 */	scanbuf = palloc(slen + 2);	memcpy(scanbuf, str, slen);	scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;	scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);	/* initialize literal buffer to a reasonable but expansible size */	literalalloc = 128;	literalbuf = (char *) palloc(literalalloc);	startlit();	BEGIN(INITIAL);}/* * Called after parsing is done to clean up after scanner_init() */voidscanner_finish(void){	yy_delete_buffer(scanbufhandle);	pfree(scanbuf);}static voidaddlit(char *ytext, int yleng){	/* enlarge buffer if needed */	if ((literallen+yleng) >= literalalloc)	{		do {			literalalloc *= 2;		} while ((literallen+yleng) >= literalalloc);		literalbuf = (char *) repalloc(literalbuf, literalalloc);	}	/* append new data, add trailing null */	memcpy(literalbuf+literallen, ytext, yleng);	literallen += yleng;	literalbuf[literallen] = '\0';}static voidaddlitchar(unsigned char ychar){	/* enlarge buffer if needed */	if ((literallen+1) >= literalalloc)	{		literalalloc *= 2;		literalbuf = (char *) repalloc(literalbuf, literalalloc);	}	/* append new data, add trailing null */	literalbuf[literallen] = ychar;	literallen += 1;	literalbuf[literallen] = '\0';}/* * One might be tempted to write pstrdup(literalbuf) instead of this, * but for long literals this is much faster because the length is * already known. */static char *litbufdup(void){	char *new;	new = palloc(literallen + 1);	memcpy(new, literalbuf, literallen+1);	return new;}unsigned charunescape_single_char(unsigned char c){	switch (c)	{		case 'b':			return '\b';		case 'f':			return '\f';		case 'n':			return '\n';		case 'r':			return '\r';		case 't':			return '\t';		default:			return c;	}}static voidcheck_escape_warning(void){	if (warn_on_first_escape && escape_string_warning)		ereport(WARNING,				(errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),				 errmsg("nonstandard use of escape in a string literal"),				 errhint("Use the escape string syntax for escapes, e.g., E'\\r\\n'."),				 errposition(pg_err_position())));	warn_on_first_escape = false;	/* warn only once per string */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -