mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
Use exclusive states for parsing quoted strings.
Implement extended comments ("/* ... */") using exclusive states. Modify definitions of operators to remove some restrictions on characters and character order.
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.14 1997/08/20 01:50:06 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.15 1997/09/01 05:51:52 thomas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -59,7 +59,42 @@ void unput(char);
|
|||||||
#endif /* FLEX_SCANNER */
|
#endif /* FLEX_SCANNER */
|
||||||
|
|
||||||
extern YYSTYPE yylval;
|
extern YYSTYPE yylval;
|
||||||
|
|
||||||
|
int llen;
|
||||||
|
char literal[MAX_PARSE_BUFFER];
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
/* OK, here is a short description of lex/flex rules behavior.
|
||||||
|
* The longest pattern which matches an input string is always chosen.
|
||||||
|
* For equal-length patterns, the first occurring in the rules list is chosen.
|
||||||
|
* INITIAL is the starting condition, to which all non-conditional rules apply.
|
||||||
|
* <xc> is an exclusive condition to allow embedded C-style comments.
|
||||||
|
* When in an exclusive condition, only those rules defined for that condition apply.
|
||||||
|
* So, when in condition <xc>, only strings which would terminate the "extended comment"
|
||||||
|
* trigger any action other than "ignore".
|
||||||
|
* The "extended comment" syntax closely resembles allowable operator syntax.
|
||||||
|
* Therefore, be sure to match _any_ candidate comment, including those with appended
|
||||||
|
* operator-like symbols. - thomas 1997-07-14
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* define an exclusive condition to allow extended C-style comments - tgl 1997-07-12 */
|
||||||
|
%x xc
|
||||||
|
/* define an exclusive condition for quoted strings - tgl 1997-07-30 */
|
||||||
|
%x xq
|
||||||
|
|
||||||
|
/* We used to allow double-quoted strings, but SQL doesn't so we won't either */
|
||||||
|
quote '
|
||||||
|
xqstart {quote}
|
||||||
|
xqstop {quote}
|
||||||
|
xqdouble {quote}{quote}
|
||||||
|
xqinside [^\']*
|
||||||
|
xqliteral [\\].
|
||||||
|
|
||||||
|
xcline [\/][\*].*[\*][\/]{space}*\n*
|
||||||
|
xcstart [\/][\*]{op_and_self}*
|
||||||
|
xcstop {op_and_self}*[\*][\/]({space}*|\n)
|
||||||
|
xcinside [^*]*
|
||||||
|
xcstar [^/]
|
||||||
|
|
||||||
digit [0-9]
|
digit [0-9]
|
||||||
letter [_A-Za-z]
|
letter [_A-Za-z]
|
||||||
@ -69,15 +104,15 @@ sysfunc SYS_{letter}{letter_or_digit}*
|
|||||||
|
|
||||||
identifier {letter}{letter_or_digit}*
|
identifier {letter}{letter_or_digit}*
|
||||||
|
|
||||||
self [,()\[\].;$\:\+\-\*\/\<\>\=\|]
|
typecast "::"
|
||||||
op_and_self [\~\!\@\#\%\^\&\|\`\?\$\:\+\-\*\/\<\>\=]
|
|
||||||
op_and_self2 [\~\!\@\#\%\^\&\|\`\?\$\:\*\/\<\>\=]
|
|
||||||
op_only [\~\!\@\#\%\^\&\`\?]
|
|
||||||
|
|
||||||
operator ({op_and_self}{op_and_self2}+)|{op_only}+
|
self [,()\[\].;$\:\+\-\*\/\<\>\=\|]
|
||||||
/* we used to allow double-quoted strings, but SQL doesn't */
|
selfm {self}[\-][\.0-9]
|
||||||
/* so we won't either*/
|
|
||||||
quote '
|
op_and_self [\~\!\@\#\%\^\&\|\`\?\$\:\+\-\*\/\<\>\=]
|
||||||
|
|
||||||
|
operator {op_and_self}+
|
||||||
|
operatorm {op_and_self}+[\-][\.0-9]
|
||||||
|
|
||||||
integer -?{digit}+
|
integer -?{digit}+
|
||||||
real -?{digit}+\.{digit}+([Ee][-+]?{digit}+)?
|
real -?{digit}+\.{digit}+([Ee][-+]?{digit}+)?
|
||||||
@ -97,10 +132,57 @@ other .
|
|||||||
|
|
||||||
{comment} { /* ignore */ }
|
{comment} { /* ignore */ }
|
||||||
|
|
||||||
"::" { return TYPECAST; }
|
/* allow extended comments using C-style delimiters - tgl 1997-07-12 */
|
||||||
|
{xcline} { /* ignore */ }
|
||||||
|
|
||||||
{self} { return (yytext[0]); }
|
<xc>{xcstar} |
|
||||||
|
{xcstart} { BEGIN(xc); }
|
||||||
|
|
||||||
|
<xc>{xcstop} { BEGIN(INITIAL); }
|
||||||
|
|
||||||
|
<xc>{xcinside} { /* ignore */ }
|
||||||
|
|
||||||
|
{xqstart} {
|
||||||
|
BEGIN(xq);
|
||||||
|
llen = 0;
|
||||||
|
*literal = '\0';
|
||||||
|
}
|
||||||
|
<xq>{xqstop} {
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
yylval.str = pstrdup(scanstr(literal));
|
||||||
|
return (SCONST);
|
||||||
|
}
|
||||||
|
<xq>{xqdouble} |
|
||||||
|
<xq>{xqinside} {
|
||||||
|
if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1)) {
|
||||||
|
elog(WARN,"quoted string parse buffer of %d chars exceeded",MAX_PARSE_BUFFER);
|
||||||
|
/* not reached */
|
||||||
|
}
|
||||||
|
memcpy(literal+llen, yytext, yyleng+1);
|
||||||
|
llen += yyleng;
|
||||||
|
}
|
||||||
|
<xq>{xqliteral} {
|
||||||
|
if ((llen+yyleng-1) > (MAX_PARSE_BUFFER - 1)) {
|
||||||
|
elog(WARN,"quoted string parse buffer of %d chars exceeded",MAX_PARSE_BUFFER);
|
||||||
|
/* not reached */
|
||||||
|
}
|
||||||
|
memcpy(literal+llen, yytext+1, yyleng);
|
||||||
|
llen += yyleng-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{typecast} { return TYPECAST; }
|
||||||
|
|
||||||
|
{selfm} {
|
||||||
|
yyless(yyleng-2);
|
||||||
|
return (yytext[0]);
|
||||||
|
}
|
||||||
|
{self} { return (yytext[0]); }
|
||||||
|
|
||||||
|
{operatorm} {
|
||||||
|
yyless(yyleng-2);
|
||||||
|
yylval.str = pstrdup((char*)yytext);
|
||||||
|
return (Op);
|
||||||
|
}
|
||||||
{operator} {
|
{operator} {
|
||||||
if (strcmp((char*)yytext,"!=") == 0)
|
if (strcmp((char*)yytext,"!=") == 0)
|
||||||
yylval.str = pstrdup("<>"); /* compatability */
|
yylval.str = pstrdup("<>"); /* compatability */
|
||||||
@ -124,49 +206,6 @@ other .
|
|||||||
CheckFloat8Val(yylval.dval);
|
CheckFloat8Val(yylval.dval);
|
||||||
return (FCONST);
|
return (FCONST);
|
||||||
}
|
}
|
||||||
{quote} {
|
|
||||||
char literal[MAX_PARSE_BUFFER];
|
|
||||||
int i = 0;
|
|
||||||
int c = 0;
|
|
||||||
/* quote_seen can be either \ or ' because
|
|
||||||
we handle both cases of \' and '' for
|
|
||||||
quoting quotes*/
|
|
||||||
int quote_seen = 0;
|
|
||||||
|
|
||||||
while (i < MAX_PARSE_BUFFER - 1) {
|
|
||||||
c = input();
|
|
||||||
if (quote_seen != 0) {
|
|
||||||
if (quote_seen == '\'' &&
|
|
||||||
c != '\'') {
|
|
||||||
/* a non-quote follows a single quote */
|
|
||||||
/* so we've hit the end of the literal */
|
|
||||||
if (c != '\0' && c != EOF)
|
|
||||||
unput(c); /* put back the extra char we read*/
|
|
||||||
i = i - 1;
|
|
||||||
break; /* break out of the while loop */
|
|
||||||
}
|
|
||||||
/* if we reach here, we're still in */
|
|
||||||
/* the string literal */
|
|
||||||
literal[i++] = c;
|
|
||||||
quote_seen = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c == '\0' || c == EOF) {
|
|
||||||
elog(WARN,"unterminated quoted string literal");
|
|
||||||
/* not reached */
|
|
||||||
}
|
|
||||||
literal[i++] = c;
|
|
||||||
if (c == '\'' || c == '\\')
|
|
||||||
quote_seen = c;
|
|
||||||
}
|
|
||||||
if ( i == MAX_PARSE_BUFFER - 1) {
|
|
||||||
elog (WARN, "unterminated quote string. parse buffer of %d chars exceeded", MAX_PARSE_BUFFER);
|
|
||||||
/* not reached */
|
|
||||||
}
|
|
||||||
literal[i] = '\0';
|
|
||||||
yylval.str = pstrdup(scanstr(literal));
|
|
||||||
return (SCONST);
|
|
||||||
}
|
|
||||||
{identifier} {
|
{identifier} {
|
||||||
int i;
|
int i;
|
||||||
ScanKeyword *keyword;
|
ScanKeyword *keyword;
|
||||||
@ -177,19 +216,25 @@ other .
|
|||||||
|
|
||||||
keyword = ScanKeywordLookup((char*)yytext);
|
keyword = ScanKeywordLookup((char*)yytext);
|
||||||
if (keyword != NULL) {
|
if (keyword != NULL) {
|
||||||
if ( keyword->value == DEFAULT )
|
if ( keyword->value == DEFAULT ) {
|
||||||
DefaultStartPosition = CurScanPosition () + yyleng + 1;
|
DefaultStartPosition = CurScanPosition () + yyleng + 1;
|
||||||
else if ( keyword->value == CHECK )
|
printf( "default offset is %d\n", DefaultStartPosition);
|
||||||
|
|
||||||
|
} else if ( keyword->value == CHECK ) {
|
||||||
CheckStartPosition = CurScanPosition () + yyleng + 1;
|
CheckStartPosition = CurScanPosition () + yyleng + 1;
|
||||||
|
printf( "check offset is %d\n", CheckStartPosition);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
return (keyword->value);
|
return (keyword->value);
|
||||||
} else {
|
} else {
|
||||||
yylval.str = pstrdup((char*)yytext);
|
yylval.str = pstrdup((char*)yytext);
|
||||||
return (IDENT);
|
return (IDENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{space} { /* ignore */ }
|
{space} { /* ignore */ }
|
||||||
|
|
||||||
{other} { return (yytext[0]); }
|
{other} { return (yytext[0]); }
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@ -282,7 +327,12 @@ myinput(char* buf, int max)
|
|||||||
int
|
int
|
||||||
CurScanPosition(void)
|
CurScanPosition(void)
|
||||||
{
|
{
|
||||||
|
printf( "current position is %d\n", yy_c_buf_p - yy_current_buffer->yy_ch_buf - yyleng);
|
||||||
|
|
||||||
|
return (parseCh - parseString - yyleng - 1);
|
||||||
|
#if FALSE
|
||||||
return (yy_c_buf_p - yy_current_buffer->yy_ch_buf - yyleng);
|
return (yy_c_buf_p - yy_current_buffer->yy_ch_buf - yyleng);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* FLEX_SCANNER */
|
#endif /* FLEX_SCANNER */
|
||||||
|
Reference in New Issue
Block a user