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

📄 scan.l

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 L
📖 第 1 页 / 共 2 页
字号:
			}<IN_STRING>[^'\\]+	{ }<IN_STRING><<EOF>>	{				plpgsql_error_lineno = start_lineno;				ereport(ERROR,						(errcode(ERRCODE_DATATYPE_MISMATCH),						 errmsg("unterminated string")));			}{dolqdelim}		{			  start_lineno = plpgsql_scanner_lineno();			  start_charpos = yytext;			  dolqstart = pstrdup(yytext);			  BEGIN(IN_DOLLARQUOTE);			}<IN_DOLLARQUOTE>{dolqdelim} {			  if (strcmp(yytext, dolqstart) == 0)			  {					pfree(dolqstart);					/* tell plpgsql_get_string_value it is a dollar quote */					dolqlen = yyleng;					/* adjust yytext/yyleng to describe whole string token */					yyleng += (yytext - start_charpos);					yytext = start_charpos;					BEGIN(INITIAL);					return T_STRING;			  }			  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$					 */					yyless(yyleng-1);			  }			}<IN_DOLLARQUOTE>{dolqinside} { }<IN_DOLLARQUOTE>.	{ /* needed for $ inside the quoted text */ }<IN_DOLLARQUOTE><<EOF>>	{ 				plpgsql_error_lineno = start_lineno;				ereport(ERROR,						(errcode(ERRCODE_DATATYPE_MISMATCH),						 errmsg("unterminated dollar-quoted string")));			}    /* ----------     * Any unmatched character is returned as is     * ----------     */.			{ return yytext[0];			}%%/* * This is the yylex routine called from outside. It exists to provide * a pushback facility, as well as to allow us to parse syntax that * requires more than one token of lookahead. */intplpgsql_yylex(void){	int cur_token;	if (have_pushback_token)	{		have_pushback_token = false;		cur_token = pushback_token;	}	else if (have_lookahead_token)	{		have_lookahead_token = false;		cur_token = lookahead_token;	}	else		cur_token = yylex();	/* Do we need to look ahead for a possible multiword token? */	switch (cur_token)	{		/* RETURN NEXT must be reduced to a single token */		case K_RETURN:			if (!have_lookahead_token)			{				lookahead_token = yylex();				have_lookahead_token = true;			}			if (lookahead_token == K_NEXT)			{				have_lookahead_token = false;				cur_token = K_RETURN_NEXT;			}			break;		default:			break;	}	return cur_token;}/* * Push back a single token to be re-read by next plpgsql_yylex() call. */voidplpgsql_push_back_token(int token){	if (have_pushback_token)		elog(ERROR, "cannot push back multiple tokens");	pushback_token = token;	have_pushback_token = true;}/* * Report a syntax error. */voidplpgsql_yyerror(const char *message){	const char *loc = yytext;	int			cursorpos;	plpgsql_error_lineno = plpgsql_scanner_lineno();	/* 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),				 internalerrposition(cursorpos),				 internalerrquery(scanstr)));	}	else	{		ereport(ERROR,				(errcode(ERRCODE_SYNTAX_ERROR),				 /* translator: first %s is typically "syntax error" */				 errmsg("%s at or near \"%s\"", message, loc),				 internalerrposition(cursorpos),				 internalerrquery(scanstr)));	}}/* * Get the line number at which the current token ends.  This substitutes * for flex's very poorly implemented yylineno facility. * * We assume that flex has written a '\0' over the character following the * current token in scanbuf.  So, we just have to count the '\n' characters * before that.  We optimize this a little by keeping track of the last * '\n' seen so far. */intplpgsql_scanner_lineno(void){	const char *c;	while ((c = strchr(cur_line_start, '\n')) != NULL)	{		cur_line_start = c + 1;		cur_line_num++;	}	return cur_line_num;}/* * Called before any actual parsing is done * * Note: the passed "str" must remain valid until plpgsql_scanner_finish(). * Although it is not fed directly to flex, we need the original string * to cite in error messages. */voidplpgsql_scanner_init(const char *str, int functype){	Size	slen;	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);	/* Other setup */	scanstr = str;    scanner_functype = functype;    scanner_typereported = false;	have_pushback_token = false;	have_lookahead_token = false;	cur_line_start = scanbuf;	cur_line_num = 1;	/*----------	 * Hack: skip any initial newline, so that in the common coding layout	 *		CREATE FUNCTION ... AS '	 *			code body	 *		' LANGUAGE 'plpgsql';	 * we will think "line 1" is what the programmer thinks of as line 1.	 *----------	 */    if (*cur_line_start == '\r')        cur_line_start++;    if (*cur_line_start == '\n')        cur_line_start++;	BEGIN(INITIAL);}/* * Called after parsing is done to clean up after plpgsql_scanner_init() */voidplpgsql_scanner_finish(void){	yy_delete_buffer(scanbufhandle);	pfree(scanbuf);}/* * Called after a T_STRING token is read to get the string literal's value * as a palloc'd string.  (We make this a separate call because in many * scenarios there's no need to get the decoded value.) * * Note: we expect the literal to be the most recently lexed token.  This * would not work well if we supported multiple-token pushback or if  * plpgsql_yylex() wanted to read ahead beyond a T_STRING token. */char *plpgsql_get_string_value(void){	char	   *result;	const char *cp;	int			len;	if (dolqlen > 0)	{		/* Token is a $foo$...$foo$ string */		len = yyleng - 2 * dolqlen;		Assert(len >= 0);		result = (char *) palloc(len + 1);		memcpy(result, yytext + dolqlen, len);		result[len] = '\0';	}	else if (*yytext == 'E' || *yytext == 'e')	{		/* Token is an E'...' string */		result = (char *) palloc(yyleng + 1);	/* more than enough room */		len = 0;		for (cp = yytext + 2; *cp; cp++)		{			if (*cp == '\'')			{				if (cp[1] == '\'')					result[len++] = *cp++;				/* else it must be string end quote */			}			else if (*cp == '\\')			{				if (cp[1] != '\0')	/* just a paranoid check */					result[len++] = *(++cp);			}			else				result[len++] = *cp;		}		result[len] = '\0';	}	else	{		/* Token is a '...' string */		result = (char *) palloc(yyleng + 1);	/* more than enough room */		len = 0;		for (cp = yytext + 1; *cp; cp++)		{			if (*cp == '\'')			{				if (cp[1] == '\'')					result[len++] = *cp++;				/* else it must be string end quote */			}			else if (*cp == '\\')			{				if (cp[1] != '\0')	/* just a paranoid check */					result[len++] = *(++cp);			}			else				result[len++] = *cp;		}		result[len] = '\0';	}	return result;}

⌨️ 快捷键说明

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