Line data Source code
1 : %top{
2 : /*
3 : * A scanner for EMP-style numeric ranges
4 : * contrib/cube/cubescan.l
5 : */
6 :
7 : #include "postgres.h"
8 :
9 : #include "cubedata.h"
10 : #include "cubeparse.h" /* must be after cubedata.h for YYSTYPE and NDBOX */
11 : }
12 :
13 : %{
14 : /* LCOV_EXCL_START */
15 :
16 : /* No reason to constrain amount of data slurped */
17 : #define YY_READ_BUF_SIZE 16777216
18 :
19 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
20 : #undef fprintf
21 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
22 :
23 : static void
24 : fprintf_to_ereport(const char *fmt, const char *msg)
25 : {
26 : ereport(ERROR, (errmsg_internal("%s", msg)));
27 : }
28 : %}
29 :
30 : %option reentrant
31 : %option bison-bridge
32 : %option 8bit
33 : %option never-interactive
34 : %option nodefault
35 : %option noinput
36 : %option nounput
37 : %option noyywrap
38 : %option noyyalloc
39 : %option noyyrealloc
40 : %option noyyfree
41 : %option warn
42 : %option prefix="cube_yy"
43 :
44 :
45 : n [0-9]+
46 : integer [+-]?{n}
47 : real [+-]?({n}\.{n}?|\.{n})
48 : float ({integer}|{real})([eE]{integer})?
49 : infinity [+-]?[iI][nN][fF]([iI][nN][iI][tT][yY])?
50 : NaN [nN][aA][nN]
51 :
52 : %%
53 :
54 : {float} *yylval = yytext; return CUBEFLOAT;
55 : {infinity} *yylval = yytext; return CUBEFLOAT;
56 : {NaN} *yylval = yytext; return CUBEFLOAT;
57 : \[ *yylval = "("; return O_BRACKET;
58 : \] *yylval = ")"; return C_BRACKET;
59 : \( *yylval = "("; return O_PAREN;
60 : \) *yylval = ")"; return C_PAREN;
61 : \, *yylval = ","; return COMMA;
62 : [ \t\n\r\f\v]+ /* discard spaces */
63 : . return yytext[0]; /* alert parser of the garbage */
64 :
65 : %%
66 :
67 : /* LCOV_EXCL_STOP */
68 :
69 : /* result and scanbuflen are not used, but Bison expects this signature */
70 : void
71 48 : cube_yyerror(NDBOX **result, Size scanbuflen,
72 : struct Node *escontext,
73 : yyscan_t yyscanner,
74 : const char *message)
75 : {
76 48 : struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; /* needed for yytext
77 : * macro */
78 :
79 48 : if (*yytext == YY_END_OF_BUFFER_CHAR)
80 : {
81 6 : errsave(escontext,
82 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
83 : errmsg("invalid input syntax for cube"),
84 : /* translator: %s is typically "syntax error" */
85 : errdetail("%s at end of input", message)));
86 : }
87 : else
88 : {
89 42 : errsave(escontext,
90 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
91 : errmsg("invalid input syntax for cube"),
92 : /* translator: first %s is typically "syntax error" */
93 : errdetail("%s at or near \"%s\"", message, yytext)));
94 : }
95 2 : }
96 :
97 :
98 : /*
99 : * Called before any actual parsing is done
100 : */
101 : void
102 6870 : cube_scanner_init(const char *str, Size *scanbuflen, yyscan_t *yyscannerp)
103 : {
104 6870 : Size slen = strlen(str);
105 : yyscan_t yyscanner;
106 :
107 6870 : if (yylex_init(yyscannerp) != 0)
108 0 : elog(ERROR, "yylex_init() failed: %m");
109 :
110 6870 : yyscanner = *yyscannerp;
111 :
112 6870 : yy_scan_bytes(str, slen, yyscanner);
113 6870 : *scanbuflen = slen;
114 6870 : }
115 :
116 :
117 : /*
118 : * Called after parsing is done to clean up after cube_scanner_init()
119 : */
120 : void
121 6810 : cube_scanner_finish(yyscan_t yyscanner)
122 : {
123 6810 : yylex_destroy(yyscanner);
124 6810 : }
125 :
126 : /*
127 : * Interface functions to make flex use palloc() instead of malloc().
128 : * It'd be better to make these static, but flex insists otherwise.
129 : */
130 :
131 : void *
132 27480 : yyalloc(yy_size_t size, yyscan_t yyscanner)
133 : {
134 27480 : return palloc(size);
135 : }
136 :
137 : void *
138 0 : yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
139 : {
140 0 : if (ptr)
141 0 : return repalloc(ptr, size);
142 : else
143 0 : return palloc(size);
144 : }
145 :
146 : void
147 34050 : yyfree(void *ptr, yyscan_t yyscanner)
148 : {
149 34050 : if (ptr)
150 27240 : pfree(ptr);
151 34050 : }
|