%{
#include "expr_parser.h"
#include "ogsql_hint_parser.h"
#include "gramparse.h"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wunused-variable"
extern void yyerror(yyscan_t yyscanner, const char *msg);
extern void hint_scanner_yyerror(const char *msg, yyscan_t yyscanner);
extern void *yyalloc(size_t bytes, yyscan_t yyscanner);
extern void yyfree(void *ptr, yyscan_t yyscanner);
#define YYMALLOC(size) yyalloc(size, yyscanner)
#define YYFREE(ptr) yyfree(ptr, yyscanner)
#define hint_parser_yyerror(msg) \
do { \
hint_scanner_yyerror(msg, yyscanner); \
YYABORT; \
} while (0)
%}
%define api.pure
%expect 0
%parse-param {yyscan_t yyscanner}
%lex-param {yyscan_t yyscanner}
%union
{
int ival;
char *str;
galist_t *list;
expr_tree_t *expr;
hint_item_t *hint_item;
}
%type <list> join_hint_list hint_lst
%type <hint_item> join_hint_item
%type <expr> arg_list arg_item
%token <str> IDENT FCONST SCONST
%token <ival> ICONST HINT_KEY_WORD
%token LEX_ERROR_TOKEN
%%
//yacc syntax start here
hint_lst:
join_hint_list
{
og_hint_yyget_extra(yyscanner)->hint_lst = $1;
}
;
join_hint_list:
join_hint_item
{
galist_t *hint_lst = NULL;
if (sql_create_list(og_hint_yyget_extra(yyscanner)->stmt, &hint_lst) != OG_SUCCESS) {
hint_parser_yyerror("create hint list failed.");
}
if (cm_galist_insert(hint_lst, $1)) {
hint_parser_yyerror("insert hint list failed.");
}
$$ = hint_lst;
}
| join_hint_list join_hint_item
{
galist_t *hint_lst = $1;
if (cm_galist_insert(hint_lst, $1)) {
hint_parser_yyerror("insert hint list failed.");
}
$$ = hint_lst;
}
;
join_hint_item:
HINT_KEY_WORD '(' arg_list ')'
{
hint_item_t *hint = NULL;
if (sql_alloc_mem(og_hint_yyget_extra(yyscanner)->stmt->context, sizeof(hint_item_t), (void **)&hint) != OG_SUCCESS) {
hint_parser_yyerror("alloc hint item failed");
}
hint->id = $1;
hint->args = $3;
$$ = hint;
}
;
arg_list:
arg_item
{
$$ = $1;
}
| arg_list ',' arg_item
{
expr_tree_t *arg_tree = $1;
expr_tree_t **temp = &arg_tree->next;
while (*temp != NULL) {
temp = &(*temp)->next;
}
*temp = $3;
$$ = arg_tree;
}
| arg_list arg_item
{
expr_tree_t *arg_tree = $1;
expr_tree_t **temp = &arg_tree->next;
while (*temp != NULL) {
temp = &(*temp)->next;
}
*temp = $2;
$$ = arg_tree;
}
;
arg_item:
ICONST
{
expr_tree_t *expr = NULL;
source_location_t loc = {.line = 0, .column = 0};
if (sql_create_int_const_expr(og_hint_yyget_extra(yyscanner)->stmt, &expr, $1, loc) != OG_SUCCESS) {
hint_parser_yyerror("init const expr failed");
}
$$ = expr;
}
| FCONST
{
expr_tree_t *expr = NULL;
source_location_t loc = {.line = 0, .column = 0};
if (sql_create_float_const_expr(og_hint_yyget_extra(yyscanner)->stmt, &expr, $1, loc) != OG_SUCCESS) {
hint_parser_yyerror("init const expr failed");
}
$$ = expr;
}
| SCONST
{
expr_tree_t *expr = NULL;
source_location_t loc = {.line = 0, .column = 0};
if (sql_create_string_const_expr(og_hint_yyget_extra(yyscanner)->stmt, &expr, $1, loc) != OG_SUCCESS) {
hint_parser_yyerror("init const expr failed");
}
$$ = expr;
}
| IDENT
{
expr_tree_t *expr = NULL;
source_location_t loc = {.line = 0, .column = 0};
if (sql_create_string_const_expr(og_hint_yyget_extra(yyscanner)->stmt, &expr, $1, loc) != OG_SUCCESS) {
hint_parser_yyerror("init const expr failed");
}
$$ = expr;
}
| '='
{
expr_tree_t *expr = NULL;
source_location_t loc = {.line = 0, .column = 0};
if (sql_create_string_const_expr(og_hint_yyget_extra(yyscanner)->stmt, &expr, "=", loc) != OG_SUCCESS) {
hint_parser_yyerror("init const expr failed");
}
$$ = expr;
}
;
%%
void
yyerror(yyscan_t yyscanner, const char *msg)
{
hint_scanner_yyerror(msg, yyscanner);
return;
}
#include "hint_scan.inc"