mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03: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);
 | 
						|
}
 |