2000-12-12 04:39:15 +08:00
|
|
|
%{
|
|
|
|
/*
|
|
|
|
** A scanner for EMP-style numeric ranges
|
|
|
|
*/
|
|
|
|
|
2002-09-05 08:43:07 +08:00
|
|
|
#include "postgres.h"
|
|
|
|
|
2003-09-14 09:52:25 +08:00
|
|
|
/* No reason to constrain amount of data slurped */
|
|
|
|
#define YY_READ_BUF_SIZE 16777216
|
2000-12-12 04:39:15 +08:00
|
|
|
|
2003-05-30 06:30:02 +08:00
|
|
|
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
|
|
|
|
#define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))
|
|
|
|
|
2003-09-14 09:52:25 +08:00
|
|
|
/* Handles to the buffer that the lexer uses internally */
|
|
|
|
static YY_BUFFER_STATE scanbufhandle;
|
|
|
|
/* this is now declared in cubeparse.y: */
|
|
|
|
/* static char *scanbuf; */
|
|
|
|
/* static int scanbuflen; */
|
2000-12-12 04:39:15 +08:00
|
|
|
|
2003-09-14 09:52:25 +08:00
|
|
|
/* flex 2.5.4 doesn't bother with a decl for this */
|
|
|
|
int cube_yylex(void);
|
2002-11-07 14:06:17 +08:00
|
|
|
|
2003-09-14 09:52:25 +08:00
|
|
|
void cube_scanner_init(const char *str);
|
|
|
|
void cube_scanner_finish(void);
|
2000-12-12 04:39:15 +08:00
|
|
|
%}
|
|
|
|
|
2002-07-31 00:33:08 +08:00
|
|
|
%option 8bit
|
|
|
|
%option never-interactive
|
|
|
|
%option nounput
|
|
|
|
%option noyywrap
|
2003-09-14 09:52:25 +08:00
|
|
|
%option prefix="cube_yy"
|
2002-07-31 00:33:08 +08:00
|
|
|
|
|
|
|
|
2000-12-12 04:39:15 +08:00
|
|
|
n [0-9]+
|
|
|
|
integer [+-]?{n}
|
2002-08-30 07:03:58 +08:00
|
|
|
real [+-]?({n}\.{n}?|\.{n})
|
2000-12-12 04:39:15 +08:00
|
|
|
float ({integer}|{real})([eE]{integer})?
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
{float} yylval = yytext; return FLOAT;
|
|
|
|
\[ yylval = "("; return O_BRACKET;
|
|
|
|
\] yylval = ")"; return C_BRACKET;
|
|
|
|
\( yylval = "("; return O_PAREN;
|
|
|
|
\) yylval = ")"; return C_PAREN;
|
|
|
|
\, yylval = ")"; return COMMA;
|
|
|
|
[ ]+ /* discard spaces */
|
|
|
|
. return yytext[0]; /* alert parser of the garbage */
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
2003-09-14 09:52:25 +08:00
|
|
|
void
|
|
|
|
yyerror(const char *message)
|
|
|
|
{
|
|
|
|
if (*yytext == YY_END_OF_BUFFER_CHAR)
|
|
|
|
{
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
|
|
errmsg("bad cube representation"),
|
|
|
|
/* translator: %s is typically "syntax error" */
|
|
|
|
errdetail("%s at end of input", message)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
|
|
errmsg("bad cube representation"),
|
|
|
|
/* translator: first %s is typically "syntax error" */
|
|
|
|
errdetail("%s at or near \"%s\"", message, yytext)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Called before any actual parsing is done
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
cube_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.
|
|
|
|
*/
|
|
|
|
scanbuflen = slen;
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2000-12-12 04:39:15 +08:00
|
|
|
|
2003-09-14 09:52:25 +08:00
|
|
|
/*
|
|
|
|
* Called after parsing is done to clean up after cube_scanner_init()
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
cube_scanner_finish(void)
|
|
|
|
{
|
|
|
|
yy_delete_buffer(scanbufhandle);
|
|
|
|
pfree(scanbuf);
|
2000-12-12 04:39:15 +08:00
|
|
|
}
|