1 %{
2 /*
3  * A scanner for EMP-style numeric ranges
4  * contrib/cube/cubescan.l
5  */
6 
7 /* No reason to constrain amount of data slurped */
8 #define YY_READ_BUF_SIZE 16777216
9 
10 /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
11 #undef fprintf
12 #define fprintf(file, fmt, msg)  fprintf_to_ereport(fmt, msg)
13 
14 static void
fprintf_to_ereport(const char * fmt,const char * msg)15 fprintf_to_ereport(const char *fmt, const char *msg)
16 {
17 	ereport(ERROR, (errmsg_internal("%s", msg)));
18 }
19 
20 /* Handles to the buffer that the lexer uses internally */
21 static YY_BUFFER_STATE scanbufhandle;
22 /* this is now declared in cubeparse.y: */
23 /* static char *scanbuf; */
24 /* static int	scanbuflen; */
25 %}
26 
27 %option 8bit
28 %option never-interactive
29 %option nodefault
30 %option noinput
31 %option nounput
32 %option noyywrap
33 %option warn
34 %option prefix="cube_yy"
35 
36 
37 n            [0-9]+
38 integer      [+-]?{n}
39 real         [+-]?({n}\.{n}?|\.{n})
40 float        ({integer}|{real})([eE]{integer})?
41 infinity     [+-]?[iI][nN][fF]([iI][nN][iI][tT][yY])?
42 NaN          [nN][aA][nN]
43 
44 %%
45 
46 {float}      yylval = yytext; return CUBEFLOAT;
47 {infinity}   yylval = yytext; return CUBEFLOAT;
48 {NaN}        yylval = yytext; return CUBEFLOAT;
49 \[           yylval = "("; return O_BRACKET;
50 \]           yylval = ")"; return C_BRACKET;
51 \(           yylval = "("; return O_PAREN;
52 \)           yylval = ")"; return C_PAREN;
53 \,           yylval = ","; return COMMA;
54 [ \t\n\r\f]+ /* discard spaces */
55 .            return yytext[0]; /* alert parser of the garbage */
56 
57 %%
58 
59 /* result is not used, but Bison expects this signature */
60 void
61 yyerror(NDBOX **result, const char *message)
62 {
63 	if (*yytext == YY_END_OF_BUFFER_CHAR)
64 	{
65 		ereport(ERROR,
66 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
67 				 errmsg("invalid input syntax for cube"),
68 				 /* translator: %s is typically "syntax error" */
69 				 errdetail("%s at end of input", message)));
70 	}
71 	else
72 	{
73 		ereport(ERROR,
74 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
75 				 errmsg("invalid input syntax for cube"),
76 				 /* translator: first %s is typically "syntax error" */
77 				 errdetail("%s at or near \"%s\"", message, yytext)));
78 	}
79 }
80 
81 
82 /*
83  * Called before any actual parsing is done
84  */
85 void
cube_scanner_init(const char * str)86 cube_scanner_init(const char *str)
87 {
88 	Size	slen = strlen(str);
89 
90 	/*
91 	 * Might be left over after ereport()
92 	 */
93 	if (YY_CURRENT_BUFFER)
94 		yy_delete_buffer(YY_CURRENT_BUFFER);
95 
96 	/*
97 	 * Make a scan buffer with special termination needed by flex.
98 	 */
99 	scanbuflen = slen;
100 	scanbuf = palloc(slen + 2);
101 	memcpy(scanbuf, str, slen);
102 	scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
103 	scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
104 
105 	BEGIN(INITIAL);
106 }
107 
108 
109 /*
110  * Called after parsing is done to clean up after cube_scanner_init()
111  */
112 void
cube_scanner_finish(void)113 cube_scanner_finish(void)
114 {
115 	yy_delete_buffer(scanbufhandle);
116 	pfree(scanbuf);
117 }
118