mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-19 10:03:23 +02:00
Since the retirement of some older buildfarm members, the oldest Bison that gets regular testing is 2.3. MacOS ships that version, and will continue doing so for the forseeable future because of Apple's policy regarding GPLv3. While Mac users could use a package manager to install a newer version, there is no compelling reason to force them do so at this time. Reviewed by Andres Freund Discussion: https://www.postgresql.org/message-id/1097762.1662145681@sss.pgh.pa.us
160 lines
3.0 KiB
Plaintext
160 lines
3.0 KiB
Plaintext
%{
|
|
/* contrib/seg/segparse.y */
|
|
|
|
#include "postgres.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include "fmgr.h"
|
|
#include "utils/builtins.h"
|
|
|
|
#include "segdata.h"
|
|
|
|
/*
|
|
* Bison doesn't allocate anything that needs to live across parser calls,
|
|
* so we can easily have it use palloc instead of malloc. This prevents
|
|
* memory leaks if we error out during parsing.
|
|
*/
|
|
#define YYMALLOC palloc
|
|
#define YYFREE pfree
|
|
|
|
static float seg_atof(const char *value);
|
|
|
|
static char strbuf[25] = {
|
|
'0', '0', '0', '0', '0',
|
|
'0', '0', '0', '0', '0',
|
|
'0', '0', '0', '0', '0',
|
|
'0', '0', '0', '0', '0',
|
|
'0', '0', '0', '0', '\0'
|
|
};
|
|
|
|
%}
|
|
|
|
/* BISON Declarations */
|
|
%parse-param {SEG *result}
|
|
%expect 0
|
|
%name-prefix="seg_yy"
|
|
|
|
%union
|
|
{
|
|
struct BND
|
|
{
|
|
float val;
|
|
char ext;
|
|
char sigd;
|
|
} bnd;
|
|
char *text;
|
|
}
|
|
%token <text> SEGFLOAT
|
|
%token <text> RANGE
|
|
%token <text> PLUMIN
|
|
%token <text> EXTENSION
|
|
%type <bnd> boundary
|
|
%type <bnd> deviation
|
|
%start range
|
|
|
|
/* Grammar follows */
|
|
%%
|
|
|
|
|
|
range: boundary PLUMIN deviation
|
|
{
|
|
result->lower = $1.val - $3.val;
|
|
result->upper = $1.val + $3.val;
|
|
sprintf(strbuf, "%g", result->lower);
|
|
result->l_sigd = Max(Min(6, significant_digits(strbuf)), Max($1.sigd, $3.sigd));
|
|
sprintf(strbuf, "%g", result->upper);
|
|
result->u_sigd = Max(Min(6, significant_digits(strbuf)), Max($1.sigd, $3.sigd));
|
|
result->l_ext = '\0';
|
|
result->u_ext = '\0';
|
|
}
|
|
|
|
| boundary RANGE boundary
|
|
{
|
|
result->lower = $1.val;
|
|
result->upper = $3.val;
|
|
if ( result->lower > result->upper ) {
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
errmsg("swapped boundaries: %g is greater than %g",
|
|
result->lower, result->upper)));
|
|
|
|
YYERROR;
|
|
}
|
|
result->l_sigd = $1.sigd;
|
|
result->u_sigd = $3.sigd;
|
|
result->l_ext = ( $1.ext ? $1.ext : '\0' );
|
|
result->u_ext = ( $3.ext ? $3.ext : '\0' );
|
|
}
|
|
|
|
| boundary RANGE
|
|
{
|
|
result->lower = $1.val;
|
|
result->upper = HUGE_VAL;
|
|
result->l_sigd = $1.sigd;
|
|
result->u_sigd = 0;
|
|
result->l_ext = ( $1.ext ? $1.ext : '\0' );
|
|
result->u_ext = '-';
|
|
}
|
|
|
|
| RANGE boundary
|
|
{
|
|
result->lower = -HUGE_VAL;
|
|
result->upper = $2.val;
|
|
result->l_sigd = 0;
|
|
result->u_sigd = $2.sigd;
|
|
result->l_ext = '-';
|
|
result->u_ext = ( $2.ext ? $2.ext : '\0' );
|
|
}
|
|
|
|
| boundary
|
|
{
|
|
result->lower = result->upper = $1.val;
|
|
result->l_sigd = result->u_sigd = $1.sigd;
|
|
result->l_ext = result->u_ext = ( $1.ext ? $1.ext : '\0' );
|
|
}
|
|
;
|
|
|
|
boundary: SEGFLOAT
|
|
{
|
|
/* temp variable avoids a gcc 3.3.x bug on Sparc64 */
|
|
float val = seg_atof($1);
|
|
|
|
$$.ext = '\0';
|
|
$$.sigd = significant_digits($1);
|
|
$$.val = val;
|
|
}
|
|
| EXTENSION SEGFLOAT
|
|
{
|
|
/* temp variable avoids a gcc 3.3.x bug on Sparc64 */
|
|
float val = seg_atof($2);
|
|
|
|
$$.ext = $1[0];
|
|
$$.sigd = significant_digits($2);
|
|
$$.val = val;
|
|
}
|
|
;
|
|
|
|
deviation: SEGFLOAT
|
|
{
|
|
/* temp variable avoids a gcc 3.3.x bug on Sparc64 */
|
|
float val = seg_atof($1);
|
|
|
|
$$.ext = '\0';
|
|
$$.sigd = significant_digits($1);
|
|
$$.val = val;
|
|
}
|
|
;
|
|
|
|
%%
|
|
|
|
|
|
static float
|
|
seg_atof(const char *value)
|
|
{
|
|
Datum datum;
|
|
|
|
datum = DirectFunctionCall1(float4in, CStringGetDatum(value));
|
|
return DatumGetFloat4(datum);
|
|
}
|