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

📄 scan.l

📁 PostgreSQL7.4.6 for Linux
💻 L
📖 第 1 页 / 共 2 页
字号:
					/* National character.					 * We will pass this along as a normal character string,					 * but preceded with an internally-generated "NCHAR".					 */					const ScanKeyword *keyword;					/* This had better be a keyword! */					keyword = ScanKeywordLookup("nchar");					Assert(keyword != NULL);					yylval.keyword = keyword->name;					token_start = yytext;					BEGIN(xq);					startlit();					return keyword->value;				}{xqstart}		{					token_start = yytext;					BEGIN(xq);					startlit();				}<xq>{xqstop}	{					BEGIN(INITIAL);					yylval.str = litbufdup();					return SCONST;				}<xq>{xqdouble}  {					addlitchar('\'');				}<xq>{xqinside}  {					addlit(yytext, yyleng);				}<xq>{xqescape}  {					addlitchar(unescape_single_char(yytext[1]));				}<xq>{xqoctesc}  {					unsigned char c = strtoul(yytext+1, NULL, 8);					addlitchar(c);				}<xq>{xqcat}		{					/* ignore */				}<xq><<EOF>>		{ yyerror("unterminated 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];					}					/* 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;				}{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]; }%%voidyyerror(const char *message){	const char *loc = token_start ? token_start : yytext;	int			cursorpos;	/* in multibyte encodings, return index in characters not bytes */	cursorpos = pg_mbstrlen_with_len(scanbuf, loc - scanbuf) + 1;	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;	}}

⌨️ 快捷键说明

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