Line data Source code
1 : %top{
2 : /*
3 : * A scanner for EMP-style numeric ranges
4 : */
5 : #include "postgres.h"
6 :
7 : #include "nodes/miscnodes.h"
8 :
9 : #include "segdata.h"
10 : #include "segparse.h" /* must be after segdata.h for SEG */
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 0 : fprintf_to_ereport(const char *fmt, const char *msg)
25 : {
26 0 : ereport(ERROR, (errmsg_internal("%s", msg)));
27 0 : }
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="seg_yy"
43 :
44 :
45 : range (\.\.)(\.)?
46 : plumin (\'\+\-\')|(\(\+\-)\)
47 : integer [+-]?[0-9]+
48 : real [+-]?[0-9]+\.[0-9]+
49 : float ({integer}|{real})([eE]{integer})?
50 :
51 : %%
52 :
53 : {range} yylval->text = yytext; return RANGE;
54 : {plumin} yylval->text = yytext; return PLUMIN;
55 : {float} yylval->text = yytext; return SEGFLOAT;
56 : \< yylval->text = "<"; return EXTENSION;
57 : \> yylval->text = ">"; return EXTENSION;
58 : \~ yylval->text = "~"; return EXTENSION;
59 : [ \t\n\r\f\v]+ /* discard spaces */
60 : . return yytext[0]; /* alert parser of the garbage */
61 :
62 : %%
63 :
64 : /* LCOV_EXCL_STOP */
65 :
66 : void
67 0 : seg_yyerror(SEG *result, struct Node *escontext, yyscan_t yyscanner, const char *message)
68 : {
69 0 : struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; /* needed for yytext
70 : * macro */
71 :
72 : /* if we already reported an error, don't overwrite it */
73 0 : if (SOFT_ERROR_OCCURRED(escontext))
74 0 : return;
75 :
76 0 : if (*yytext == YY_END_OF_BUFFER_CHAR)
77 : {
78 0 : errsave(escontext,
79 : (errcode(ERRCODE_SYNTAX_ERROR),
80 : errmsg("bad seg representation"),
81 : /* translator: %s is typically "syntax error" */
82 : errdetail("%s at end of input", message)));
83 0 : }
84 : else
85 : {
86 0 : errsave(escontext,
87 : (errcode(ERRCODE_SYNTAX_ERROR),
88 : errmsg("bad seg representation"),
89 : /* translator: first %s is typically "syntax error" */
90 : errdetail("%s at or near \"%s\"", message, yytext)));
91 : }
92 0 : }
93 :
94 :
95 : /*
96 : * Called before any actual parsing is done
97 : */
98 : void
99 0 : seg_scanner_init(const char *str, yyscan_t *yyscannerp)
100 : {
101 0 : yyscan_t yyscanner;
102 :
103 0 : if (yylex_init(yyscannerp) != 0)
104 0 : elog(ERROR, "yylex_init() failed: %m");
105 :
106 0 : yyscanner = *yyscannerp;
107 :
108 0 : yy_scan_string(str, yyscanner);
109 0 : }
110 :
111 :
112 : /*
113 : * Called after parsing is done to clean up after seg_scanner_init()
114 : */
115 : void
116 0 : seg_scanner_finish(yyscan_t yyscanner)
117 : {
118 0 : yylex_destroy(yyscanner);
119 0 : }
120 :
121 : /*
122 : * Interface functions to make flex use palloc() instead of malloc().
123 : * It'd be better to make these static, but flex insists otherwise.
124 : */
125 :
126 : void *
127 0 : yyalloc(yy_size_t size, yyscan_t yyscanner)
128 : {
129 0 : return palloc(size);
130 : }
131 :
132 : void *
133 0 : yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
134 : {
135 0 : if (ptr)
136 0 : return repalloc(ptr, size);
137 : else
138 0 : return palloc(size);
139 0 : }
140 :
141 : void
142 0 : yyfree(void *ptr, yyscan_t yyscanner)
143 : {
144 0 : if (ptr)
145 0 : pfree(ptr);
146 0 : }
|