blob: c25aa1a73fa57d769654b3af5213e216f1a5107d [file] [log] [blame]
%{
/*-------------------------------------------------------------------------
*
* specparse.y
* bison grammar for the isolation test file format
*
* Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*-------------------------------------------------------------------------
*/
#include "postgres_fe.h"
#include "isolationtester.h"
TestSpec parseresult; /* result of parsing is left here */
%}
%expect 0
%name-prefix="spec_yy"
%union
{
char *str;
int integer;
Session *session;
Step *step;
Permutation *permutation;
PermutationStep *permutationstep;
PermutationStepBlocker *blocker;
struct
{
void **elements;
int nelements;
} ptr_list;
}
%type <ptr_list> setup_list
%type <str> opt_setup opt_teardown
%type <str> setup
%type <ptr_list> step_list session_list permutation_list opt_permutation_list
%type <ptr_list> permutation_step_list blocker_list
%type <session> session
%type <step> step
%type <permutation> permutation
%type <permutationstep> permutation_step
%type <blocker> blocker
%token <str> sqlblock identifier
%token <integer> INTEGER
%token NOTICES PERMUTATION SESSION SETUP STEP TEARDOWN TEST
%%
TestSpec:
setup_list
opt_teardown
session_list
opt_permutation_list
{
parseresult.setupsqls = (char **) $1.elements;
parseresult.nsetupsqls = $1.nelements;
parseresult.teardownsql = $2;
parseresult.sessions = (Session **) $3.elements;
parseresult.nsessions = $3.nelements;
parseresult.permutations = (Permutation **) $4.elements;
parseresult.npermutations = $4.nelements;
}
;
setup_list:
/* EMPTY */
{
$$.elements = NULL;
$$.nelements = 0;
}
| setup_list setup
{
$$.elements = pg_realloc($1.elements,
($1.nelements + 1) * sizeof(void *));
$$.elements[$1.nelements] = $2;
$$.nelements = $1.nelements + 1;
}
;
opt_setup:
/* EMPTY */ { $$ = NULL; }
| setup { $$ = $1; }
;
setup:
SETUP sqlblock { $$ = $2; }
;
opt_teardown:
/* EMPTY */ { $$ = NULL; }
| TEARDOWN sqlblock { $$ = $2; }
;
session_list:
session_list session
{
$$.elements = pg_realloc($1.elements,
($1.nelements + 1) * sizeof(void *));
$$.elements[$1.nelements] = $2;
$$.nelements = $1.nelements + 1;
}
| session
{
$$.nelements = 1;
$$.elements = pg_malloc(sizeof(void *));
$$.elements[0] = $1;
}
;
session:
SESSION identifier opt_setup step_list opt_teardown
{
$$ = pg_malloc(sizeof(Session));
$$->name = $2;
$$->setupsql = $3;
$$->steps = (Step **) $4.elements;
$$->nsteps = $4.nelements;
$$->teardownsql = $5;
}
;
step_list:
step_list step
{
$$.elements = pg_realloc($1.elements,
($1.nelements + 1) * sizeof(void *));
$$.elements[$1.nelements] = $2;
$$.nelements = $1.nelements + 1;
}
| step
{
$$.nelements = 1;
$$.elements = pg_malloc(sizeof(void *));
$$.elements[0] = $1;
}
;
step:
STEP identifier sqlblock
{
$$ = pg_malloc(sizeof(Step));
$$->name = $2;
$$->sql = $3;
$$->session = -1; /* until filled */
$$->used = false;
}
;
opt_permutation_list:
permutation_list
{
$$ = $1;
}
| /* EMPTY */
{
$$.elements = NULL;
$$.nelements = 0;
}
permutation_list:
permutation_list permutation
{
$$.elements = pg_realloc($1.elements,
($1.nelements + 1) * sizeof(void *));
$$.elements[$1.nelements] = $2;
$$.nelements = $1.nelements + 1;
}
| permutation
{
$$.nelements = 1;
$$.elements = pg_malloc(sizeof(void *));
$$.elements[0] = $1;
}
;
permutation:
PERMUTATION permutation_step_list
{
$$ = pg_malloc(sizeof(Permutation));
$$->nsteps = $2.nelements;
$$->steps = (PermutationStep **) $2.elements;
}
;
permutation_step_list:
permutation_step_list permutation_step
{
$$.elements = pg_realloc($1.elements,
($1.nelements + 1) * sizeof(void *));
$$.elements[$1.nelements] = $2;
$$.nelements = $1.nelements + 1;
}
| permutation_step
{
$$.nelements = 1;
$$.elements = pg_malloc(sizeof(void *));
$$.elements[0] = $1;
}
;
permutation_step:
identifier
{
$$ = pg_malloc(sizeof(PermutationStep));
$$->name = $1;
$$->blockers = NULL;
$$->nblockers = 0;
$$->step = NULL;
}
| identifier '(' blocker_list ')'
{
$$ = pg_malloc(sizeof(PermutationStep));
$$->name = $1;
$$->blockers = (PermutationStepBlocker **) $3.elements;
$$->nblockers = $3.nelements;
$$->step = NULL;
}
;
blocker_list:
blocker_list ',' blocker
{
$$.elements = pg_realloc($1.elements,
($1.nelements + 1) * sizeof(void *));
$$.elements[$1.nelements] = $3;
$$.nelements = $1.nelements + 1;
}
| blocker
{
$$.nelements = 1;
$$.elements = pg_malloc(sizeof(void *));
$$.elements[0] = $1;
}
;
blocker:
identifier
{
$$ = pg_malloc(sizeof(PermutationStepBlocker));
$$->stepname = $1;
$$->blocktype = PSB_OTHER_STEP;
$$->num_notices = -1;
$$->step = NULL;
$$->target_notices = -1;
}
| identifier NOTICES INTEGER
{
$$ = pg_malloc(sizeof(PermutationStepBlocker));
$$->stepname = $1;
$$->blocktype = PSB_NUM_NOTICES;
$$->num_notices = $3;
$$->step = NULL;
$$->target_notices = -1;
}
| '*'
{
$$ = pg_malloc(sizeof(PermutationStepBlocker));
$$->stepname = NULL;
$$->blocktype = PSB_ONCE;
$$->num_notices = -1;
$$->step = NULL;
$$->target_notices = -1;
}
;
%%
#include "specscanner.c"