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