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