1212 *
1313 *
1414 * IDENTIFICATION
15- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.53 2000/03/08 22:03:12 tgl Exp $
15+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.54 2000/03/15 19:09:10 meskes Exp $
1616 *
1717 *-------------------------------------------------------------------------
1818 */
@@ -147,21 +147,22 @@ xdcother [^"]
147147xdcinside ({xdcqq }| {xdcqdq }| {xdcother })
148148
149149/* C-Style Comments
150- * Ignored by the scanner and parser.
151150 * The "extended comment" syntax closely resembles allowable operator syntax.
152151 * The tricky part here is to get lex to recognize a string starting with
153152 * slash-star as a comment, when interpreting it as an operator would produce
154- * a longer match --- remember lex will prefer a longer match! So, we have
155- * to provide a special rule for xcline (a complete comment that could
156- * otherwise look like an operator), as well as append {op_and_self}* to
157- * xcstart so that it matches at least as much as {operator} would.
158- * Then the tie-breaker (first matching rule of same length) wins.
159- * There is still a problem if someone writes, eg, slash-star-star-slash-plus.
160- * It'll be taken as an xcstart, rather than xcline and an operator as one
161- * could wish. I don't see any way around that given lex's behavior;
162- * that someone will just have to write a space after the comment.
153+ * a longer match --- remember lex will prefer a longer match! Also, if we
154+ * have tor whereas we want to see it as a + operator and a comment start.
155+ * The solution is two-fold:
156+ * 1. append {op_and_self}* to xcstart so that it matches as much text as
157+ * {operator} would. Then the tie-breaker (first matching rule of same
158+ * length) ensures xcstart wins. We put back the extra stuff with yyless()
159+ * in case it contains a star-slash that should terminate the comment.
160+ * 2. In the operator rule, check for slash-star within the operator, and
161+ * if found throw it back with yyless(). This handles the plus-slash-star
162+ * problem.
163+ * SQL92-style comments, which start with dash-dash, have similar interactions
164+ * with the operator rule.
163165 */
164- xcline \/\* {op_and_self }* \*\/
165166xcstart \/\* {op_and_self }*
166167xcstop \* + \/
167168xcinside ([^ * ]+ )| (\* + [^ / ])
@@ -174,6 +175,7 @@ identifier {letter}{letter_or_digit}*
174175
175176typecast " ::"
176177
178+ /* NB: if you change "self", fix the copy in the operator rule too! */
177179self [,() \[\] .;$ \:\+\-\*\/\%\^\<\>\=\| ]
178180op_and_self [\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\= ]
179181operator {op_and_self }+
@@ -252,31 +254,32 @@ cppline {space}*#(.*\\{line_end})*.*
252254 *
253255 * Quoted strings must allow some special characters such as single-quote
254256 * and newline.
255- * Embedded single-quotes are implemented both in the SQL/92 -standard
257+ * Embedded single-quotes are implemented both in the SQL92 -standard
256258 * style of two adjacent single quotes "''" and in the Postgres/Java style
257259 * of escaped-quote "\'".
258260 * Other embedded escaped characters are matched explicitly and the leading
259261 * backslash is dropped from the string. - thomas 1997-09-24
260- * Note that xcline must appear before xcstart, which must appear before
261- * operator, as explained above! Also whitespace (comment) must appear
262- * before operator.
262+ * Note that xcstart must appear before operator, as explained above!
263+ * Also whitespace (comment) must appear before operator.
263264 */
264265
265266%%
266267<SQL >{whitespace } { /* ignore */ }
267268
268- {xcline } { ECHO; }
269-
270269{xcstart } {
271270 state_before = YYSTATE;
272271 ECHO;
273272 BEGIN (xc);
273+ /* Put back any characters past slash-star; see above */
274+ yyless (2 );
274275 }
275276
276277<xc >{xcstop } { ECHO; BEGIN (state_before); }
277278
278279<xc >{xcinside } { ECHO; }
279280
281+ <xc ><<EOF>> { mmerror (ET_ERROR, " Unterminated /* comment" ); }
282+
280283<SQL >{xbstart } {
281284 BEGIN (xb);
282285 startlit ();
@@ -291,6 +294,8 @@ cppline {space}*#(.*\\{line_end})*.*
291294 mmerror (ET_ERROR, " Bad binary integer input!" );
292295 return ICONST;
293296 }
297+ <xb ><<EOF>> { mmerror (ET_ERROR, " Unterminated binary integer" ); }
298+
294299<xh >{xhinside } |
295300<xb >{xbinside } {
296301 addlit (yytext, yyleng);
@@ -314,6 +319,8 @@ cppline {space}*#(.*\\{line_end})*.*
314319 return ICONST;
315320 }
316321
322+ <xb ><<EOF>> { mmerror (ET_ERROR, " Unterminated hexadecimal integer" ); }
323+
317324{xqstart } {
318325 state_before = YYSTATE;
319326 BEGIN (xq);
@@ -333,6 +340,8 @@ cppline {space}*#(.*\\{line_end})*.*
333340 /* ignore */
334341 }
335342
343+ <xq ><<EOF>> { mmerror (ET_ERROR, " Unterminated quoted string" ); }
344+
336345{xdstart } {
337346 state_before = YYSTATE;
338347 BEGIN (xd);
@@ -346,6 +355,7 @@ cppline {space}*#(.*\\{line_end})*.*
346355<xd >{xdinside } {
347356 addlit (yytext, yyleng);
348357 }
358+ <xq ><<EOF>> { mmerror (ET_ERROR, " Unterminated quoted identifier" ); }
349359<SQL >{typecast } { return TYPECAST; }
350360<SQL >{self } { /*
351361 * We may find a ';' inside a structure
@@ -357,7 +367,33 @@ cppline {space}*#(.*\\{line_end})*.*
357367 return yytext[0 ];
358368 }
359369<SQL >{operator } {
360- if (strcmp ((char *)yytext," !=" ) == 0 )
370+ /* Check for embedded slash-star or dash-dash */
371+ char *slashstar = strstr ((char *)yytext, " /*" );
372+ char *dashdash = strstr ((char *)yytext, " --" );
373+
374+ if (slashstar && dashdash)
375+ {
376+ if (slashstar > dashdash)
377+ slashstar = dashdash;
378+ }
379+ else if (!slashstar)
380+ slashstar = dashdash;
381+
382+ if (slashstar)
383+ {
384+ int nchars = slashstar - ((char *)yytext);
385+ yyless (nchars);
386+ /* If what we have left is only one char, and it's
387+ * one of the characters matching "self", then
388+ * return it as a character token the same way
389+ * that the "self" rule would have.
390+ */
391+ if (nchars == 1 &&
392+ strchr (" ,()[].;$:+-*/%^<>=|" , yytext[0 ]))
393+ return yytext[0 ];
394+ }
395+
396+ if (strcmp ((char *)yytext, " !=" ) == 0 )
361397 yylval.str = mm_strdup (" <>" ); /* compatability */
362398 else
363399 yylval.str = mm_strdup ((char *)yytext);
0 commit comments