Age Owner TLA 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 : /*
10 : * NB: include segparse.h only AFTER including segdata.h, because segdata.h
11 : * contains the definition for SEG.
12 : */
13 : #include "segdata.h"
14 : #include "segparse.h"
15 : }
16 :
17 : %{
18 : /* LCOV_EXCL_START */
19 :
20 : /* No reason to constrain amount of data slurped */
21 : #define YY_READ_BUF_SIZE 16777216
22 :
23 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
24 : #undef fprintf
25 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
26 :
27 : static void
3738 tgl 28 UIC 0 : fprintf_to_ereport(const char *fmt, const char *msg)
29 : {
30 0 : ereport(ERROR, (errmsg_internal("%s", msg)));
31 : }
32 :
33 : /* Handles to the buffer that the lexer uses internally */
34 : static YY_BUFFER_STATE scanbufhandle;
35 : static char *scanbuf;
36 : %}
37 :
38 : %option 8bit
7558 tgl 39 EUB : %option never-interactive
40 : %option nodefault
5340 41 : %option noinput
42 : %option nounput
43 : %option noyywrap
44 : %option warn
45 : %option prefix="seg_yy"
46 :
47 :
48 : range (\.\.)(\.)?
49 : plumin (\'\+\-\')|(\(\+\-)\)
50 : integer [+-]?[0-9]+
51 : real [+-]?[0-9]+\.[0-9]+
52 : float ({integer}|{real})([eE]{integer})?
53 :
54 : %%
55 :
217 john.naylor 56 GNC 2447 : {range} seg_yylval.text = yytext; return RANGE;
57 7 : {plumin} seg_yylval.text = yytext; return PLUMIN;
58 7 : {float} seg_yylval.text = yytext; return SEGFLOAT;
59 5174 : \< seg_yylval.text = "<"; return EXTENSION;
60 530 : \> seg_yylval.text = ">"; return EXTENSION;
61 672 : \~ seg_yylval.text = "~"; return EXTENSION;
6984 tgl 62 GIC 15 : [ \t\n\r\f]+ /* discard spaces */
8154 63 486 : . return yytext[0]; /* alert parser of the garbage */
64 10 :
8154 tgl 65 UIC 0 : %%
66 :
2068 peter_e 67 ECB : /* LCOV_EXCL_STOP */
68 :
2936 tgl 69 : void
107 andrew 70 GNC 22 : seg_yyerror(SEG *result, struct Node *escontext, const char *message)
7147 tgl 71 ECB : {
72 : /* if we already reported an error, don't overwrite it */
107 andrew 73 GNC 22 : if (SOFT_ERROR_OCCURRED(escontext))
74 8 : return;
75 :
7147 tgl 76 CBC 14 : if (*yytext == YY_END_OF_BUFFER_CHAR)
7147 tgl 77 ECB : {
107 andrew 78 GNC 3 : errsave(escontext,
7147 tgl 79 ECB : (errcode(ERRCODE_SYNTAX_ERROR),
7147 tgl 80 EUB : errmsg("bad seg representation"),
81 : /* translator: %s is typically "syntax error" */
82 : errdetail("%s at end of input", message)));
83 : }
84 : else
7147 tgl 85 ECB : {
107 andrew 86 GNC 11 : errsave(escontext,
87 : (errcode(ERRCODE_SYNTAX_ERROR),
7147 tgl 88 ECB : errmsg("bad seg representation"),
89 : /* translator: first %s is typically "syntax error" */
90 : errdetail("%s at or near \"%s\"", message, yytext)));
91 : }
92 : }
93 :
94 :
95 : /*
96 : * Called before any actual parsing is done
97 : */
98 : void
7147 tgl 99 GIC 2823 : seg_scanner_init(const char *str)
100 : {
7147 tgl 101 CBC 2823 : Size slen = strlen(str);
102 :
103 : /*
104 : * Might be left over after ereport()
105 : */
7147 tgl 106 GIC 2823 : if (YY_CURRENT_BUFFER)
107 9 : yy_delete_buffer(YY_CURRENT_BUFFER);
108 :
109 : /*
110 : * Make a scan buffer with special termination needed by flex.
111 : */
112 2823 : scanbuf = palloc(slen + 2);
7147 tgl 113 CBC 2823 : memcpy(scanbuf, str, slen);
7147 tgl 114 GIC 2823 : scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
7147 tgl 115 CBC 2823 : scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
116 :
7147 tgl 117 GIC 2823 : BEGIN(INITIAL);
118 2823 : }
119 :
8154 tgl 120 ECB :
7147 121 : /*
122 : * Called after parsing is done to clean up after seg_scanner_init()
123 : */
124 : void
7147 tgl 125 GIC 2814 : seg_scanner_finish(void)
7147 tgl 126 ECB : {
7147 tgl 127 CBC 2814 : yy_delete_buffer(scanbufhandle);
128 2814 : pfree(scanbuf);
8154 129 2814 : }
|