<commit_before>%{
/* XXX: should be a pure-parser */
#include "col-internal.h"
#include "nodes/makefuncs.h"
/* XXX: see note about #include order in parser.c */
#include "parser/parser-internal.h"
#include "ol_scan.h"
#include "util/list.h"

int yyerror(ColParser *context, void *scanner, const char *message);
static void split_program_clauses(List *clauses, List **defines, List **facts,
                                  List **rules, apr_pool_t *pool);
static void split_rule_body(List *body, List **joins,
                            List **quals, apr_pool_t *pool);
%}

%union
{
    apr_int64_t     ival;
    char           *str;
    List           *list;
    void           *ptr;
    bool            boolean;
    AstHashVariant  hash_v;
    AstStorageKind  store_kind;
}

%start program
%error-verbose
%parse-param { ColParser *context }
%parse-param { void *scanner }
%lex-param { yyscan_t scanner }

%token KEYS DEFINE MEMORY SQLITE DELETE NOTIN OL_HASH_INSERT OL_HASH_DELETE
       OL_FALSE OL_TRUE
%token <str> VAR_IDENT TBL_IDENT FCONST SCONST CCONST ICONST

%left OL_EQ OL_NEQ
%nonassoc '>' '<' OL_GTE OL_LTE
%left '+' '-'
%left '*' '/' '%'
%left UMINUS

%type <ptr>        clause define rule table_ref column_ref join_clause
%type <list>       program_body opt_int_list int_list schema_list define_schema
%type <list>       opt_keys column_ref_list opt_rule_body rule_body
%type <ptr>        rule_body_elem qualifier qual_expr expr const_expr op_expr
%type <ptr>        var_expr column_ref_expr rule_prefix schema_elt
%type <str>        bool_const
%type <ival>       iconst_ival
%type <boolean>    opt_not opt_delete
%type <hash_v>     opt_hash_variant
%type <store_kind> storage_kind

%%
program: program_body {
    List *defines;
    List *facts;
    List *rules;

    split_program_clauses($1, &defines, &facts, &rules, context->pool);
    context->result = make_program(defines, facts, rules, context->pool);
};

program_body:
  clause ';' program_body       { $$ = list_prepend($3, $1); }
| /* EMPTY */                   { $$ = list_make(context->pool); }
;

clause:
  define        { $$ = $1; }
| rule          { $$ = $1; }
;

/*
 * XXX: We need to write this in a non-obvious way because bison gets
 * confused by adjacent optional productions. Is there a better fix?
 */
define:
  DEFINE '(' TBL_IDENT ',' opt_keys define_schema ')' {
    $$ = make_define($3, AST_STORAGE_MEMORY, $5, $6, context->pool);
}
| DEFINE '(' TBL_IDENT ',' storage_kind ',' opt_keys define_schema ')' {
    $$ = make_define($3, $5, $7, $8, context->pool);
}
;

/*
 * Note that we currently equate an empty key list with an absent key list;
 * this is inconsistent with JOL
 */
opt_keys:
  KEYS '(' opt_int_list ')' ',' { $$ = $3; }
| /* EMPTY */ { $$ = NULL; }
;

storage_kind:
  MEMORY        { return AST_STORAGE_MEMORY; }
| SQLITE        { return AST_STORAGE_SQLITE; }
;

define_schema: '{' schema_list '}' { $$ = $2; };

opt_int_list:
  int_list      { $$ = $1; }
| /* EMPTY */   { $$ = NULL; }
;
<commit_msg>More temporary hacks to work around a bison issue.<commit_after>%{
/* XXX: should be a pure-parser */
#include "col-internal.h"
#include "nodes/makefuncs.h"
/* XXX: see note about #include order in parser.c */
#include "parser/parser-internal.h"
#include "ol_scan.h"
#include "util/list.h"

int yyerror(ColParser *context, void *scanner, const char *message);
static void split_program_clauses(List *clauses, List **defines, List **facts,
                                  List **rules, apr_pool_t *pool);
static void split_rule_body(List *body, List **joins,
                            List **quals, apr_pool_t *pool);
%}

%union
{
    apr_int64_t     ival;
    char           *str;
    List           *list;
    void           *ptr;
    bool            boolean;
    AstHashVariant  hash_v;
}

%start program
%error-verbose
%parse-param { ColParser *context }
%parse-param { void *scanner }
%lex-param { yyscan_t scanner }

%token KEYS DEFINE MEMORY SQLITE DELETE NOTIN OL_HASH_INSERT OL_HASH_DELETE
       OL_FALSE OL_TRUE
%token <str> VAR_IDENT TBL_IDENT FCONST SCONST CCONST ICONST

%left OL_EQ OL_NEQ
%nonassoc '>' '<' OL_GTE OL_LTE
%left '+' '-'
%left '*' '/' '%'
%left UMINUS

%type <ptr>        clause define rule table_ref column_ref join_clause
%type <list>       program_body opt_int_list int_list schema_list define_schema
%type <list>       opt_keys column_ref_list opt_rule_body rule_body
%type <ptr>        rule_body_elem qualifier qual_expr expr const_expr op_expr
%type <ptr>        var_expr column_ref_expr rule_prefix schema_elt
%type <str>        bool_const
%type <ival>       iconst_ival
%type <boolean>    opt_not opt_delete
%type <hash_v>     opt_hash_variant

%%
program: program_body {
    List *defines;
    List *facts;
    List *rules;

    split_program_clauses($1, &defines, &facts, &rules, context->pool);
    context->result = make_program(defines, facts, rules, context->pool);
};

program_body:
  clause ';' program_body       { $$ = list_prepend($3, $1); }
| /* EMPTY */                   { $$ = list_make(context->pool); }
;

clause:
  define        { $$ = $1; }
| rule          { $$ = $1; }
;

/*
 * XXX: We need to write this in a non-obvious way because bison gets
 * confused by adjacent optional productions. Is there a better fix?
 */
define:
  DEFINE '(' TBL_IDENT ',' opt_keys define_schema ')' {
    $$ = make_define($3, AST_STORAGE_MEMORY, $5, $6, context->pool);
}
| DEFINE '(' TBL_IDENT ',' MEMORY ',' opt_keys define_schema ')' {
    $$ = make_define($3, AST_STORAGE_MEMORY, $7, $8, context->pool);
}
| DEFINE '(' TBL_IDENT ',' SQLITE ',' opt_keys define_schema ')' {
    $$ = make_define($3, AST_STORAGE_MEMORY, $7, $8, context->pool);
}
;

/*
 * Note that we currently equate an empty key list with an absent key list;
 * this is inconsistent with JOL
 */
opt_keys:
  KEYS '(' opt_int_list ')' ',' { $$ = $3; }
| /* EMPTY */ { $$ = NULL; }
;

define_schema: '{' schema_list '}' { $$ = $2; };

opt_int_list:
  int_list      { $$ = $1; }
| /* EMPTY */   { $$ = NULL; }
;

{'fraction_non_alphanumeric': 0.1364389920424403, 'fraction_numerical': 0.005968169761273209, 'mean_word_length': 3.07085020242915, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1657044', 'n_tokens_mistral': 2163, 'n_tokens_neox': 2128, 'n_words': 554}