9
9
*
10
10
*
11
11
* IDENTIFICATION
12
- * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.65 2000/02/21 18:47:02 tgl Exp $
12
+ * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.66 2000/03/11 05:14:06 tgl Exp $
13
13
*
14
14
*-------------------------------------------------------------------------
15
15
*/
@@ -133,22 +133,24 @@ xdstop{dquote}
133
133
xdinside [^ " ]+
134
134
135
135
/* C-style comments
136
- * Ignored by the scanner and parser.
137
136
*
138
137
* The "extended comment" syntax closely resembles allowable operator syntax.
139
138
* The tricky part here is to get lex to recognize a string starting with
140
139
* slash-star as a comment, when interpreting it as an operator would produce
141
- * a longer match --- remember lex will prefer a longer match! So, we have
142
- * to provide a special rule for xcline (a complete comment that could
143
- * otherwise look like an operator), as well as append {op_and_self}* to
144
- * xcstart so that it matches at least as much as {operator} would.
145
- * Then the tie-breaker (first matching rule of same length) wins.
146
- * There is still a problem if someone writes, eg, slash-star-star-slash-plus.
147
- * It'll be taken as an xcstart, rather than xcline and an operator as one
148
- * could wish. I don't see any way around that given lex's behavior;
149
- * that someone will just have to write a space after the comment.
140
+ * a longer match --- remember lex will prefer a longer match! Also, if we
141
+ * have something like plus-slash-star, lex will think this is a 3-character
142
+ * operator whereas we want to see it as a + operator and a comment start.
143
+ * The solution is two-fold:
144
+ * 1. append {op_and_self}* to xcstart so that it matches as much text as
145
+ * {operator} would. Then the tie-breaker (first matching rule of same
146
+ * length) ensures xcstart wins. We put back the extra stuff with yyless()
147
+ * in case it contains a star-slash that should terminate the comment.
148
+ * 2. In the operator rule, check for slash-star within the operator, and
149
+ * if found throw it back with yyless(). This handles the plus-slash-star
150
+ * problem.
151
+ * SQL92-style comments, which start with dash-dash, have similar interactions
152
+ * with the operator rule.
150
153
*/
151
- xcline \/\* {op_and_self }* \*\/
152
154
xcstart \/\* {op_and_self }*
153
155
xcstop \* + \/
154
156
xcinside ([^ * ]+ )| (\* + [^ / ])
@@ -161,6 +163,7 @@ identifier{letter}{letter_or_digit}*
161
163
162
164
typecast " ::"
163
165
166
+ /* NB: if you change "self", fix the copy in the operator rule too! */
164
167
self [,() \[\] .;$ \:\+\-\*\/\%\^\<\>\=\| ]
165
168
op_and_self [\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\= ]
166
169
operator {op_and_self }+
@@ -218,27 +221,30 @@ other.
218
221
*
219
222
* Quoted strings must allow some special characters such as single-quote
220
223
* and newline.
221
- * Embedded single-quotes are implemented both in theSQL/92 -standard
224
+ * Embedded single-quotes are implemented both in theSQL92 -standard
222
225
* style of two adjacent single quotes "''" and in the Postgres/Java style
223
226
* of escaped-quote "\'".
224
227
* Other embedded escaped characters are matched explicitly and the leading
225
228
* backslash is dropped from the string. - thomas 1997-09-24
226
- * Note that xcline must appear before xcstart, which must appear before
227
- * operator, as explained above! Also whitespace (comment) must appear
228
- * before operator.
229
+ * Note that xcstart must appear before operator, as explained above!
230
+ * Also whitespace (comment) must appear before operator.
229
231
*/
230
232
231
233
%%
232
234
{whitespace }{/* ignore */ }
233
235
234
- {xcline }{/* ignore */ }
235
-
236
- {xcstart }{BEGIN (xc); }
236
+ {xcstart }{
237
+ BEGIN (xc);
238
+ /* Put back any characters past slash-star; see above */
239
+ yyless (2 );
240
+ }
237
241
238
242
<xc >{xcstop }{BEGIN (INITIAL); }
239
243
240
244
<xc >{xcinside }{/* ignore */ }
241
245
246
+ <xc ><<EOF>> {elog (ERROR," Unterminated /* comment" ); }
247
+
242
248
{xbstart }{
243
249
BEGIN (xb);
244
250
startlit ();
@@ -262,6 +268,7 @@ other.
262
268
<xb >{xbcat }{
263
269
/* ignore */
264
270
}
271
+ <xb ><<EOF>> {elog (ERROR," Unterminated binary integer" ); }
265
272
266
273
{xhstart }{
267
274
BEGIN (xh);
@@ -278,6 +285,7 @@ other.
278
285
literalbuf);
279
286
return ICONST;
280
287
}
288
+ <xh ><<EOF>> {elog (ERROR," Unterminated hexadecimal integer" ); }
281
289
282
290
{xqstart }{
283
291
BEGIN (xq);
@@ -296,6 +304,7 @@ other.
296
304
<xq >{xqcat }{
297
305
/* ignore */
298
306
}
307
+ <xq ><<EOF>> {elog (ERROR," Unterminated quoted string" ); }
299
308
300
309
301
310
{xdstart }{
@@ -310,12 +319,39 @@ other.
310
319
<xd >{xdinside }{
311
320
addlit (yytext, yyleng);
312
321
}
322
+ <xd ><<EOF>> {elog (ERROR," Unterminated quoted identifier" ); }
313
323
314
324
{typecast }{return TYPECAST; }
315
325
316
326
{self }{return yytext[0 ]; }
317
327
318
328
{operator }{
329
+ /* Check for embedded slash-star or dash-dash */
330
+ char *slashstar =strstr ((char *)yytext," /*" );
331
+ char *dashdash =strstr ((char *)yytext," --" );
332
+
333
+ if (slashstar && dashdash)
334
+ {
335
+ if (slashstar > dashdash)
336
+ slashstar = dashdash;
337
+ }
338
+ else if (!slashstar)
339
+ slashstar = dashdash;
340
+
341
+ if (slashstar)
342
+ {
343
+ int nchars = slashstar - ((char *)yytext);
344
+ yyless (nchars);
345
+ /* If what we have left is only one char, and it's
346
+ * one of the characters matching "self", then
347
+ * return it as a character token the same way
348
+ * that the "self" rule would have.
349
+ */
350
+ if (nchars ==1 &&
351
+ strchr (" ,()[].;$:+-*/%^<>=|" , yytext[0 ]))
352
+ return yytext[0 ];
353
+ }
354
+
319
355
if (strcmp ((char *)yytext," !=" ) ==0 )
320
356
yylval.str =pstrdup (" <>" );/* compatibility */
321
357
else