summaryrefslogtreecommitdiffstats
path: root/storage/innobase/fts/fts0pars.y
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fts/fts0pars.y')
-rw-r--r--storage/innobase/fts/fts0pars.y293
1 files changed, 293 insertions, 0 deletions
diff --git a/storage/innobase/fts/fts0pars.y b/storage/innobase/fts/fts0pars.y
new file mode 100644
index 00000000..deebc79e
--- /dev/null
+++ b/storage/innobase/fts/fts0pars.y
@@ -0,0 +1,293 @@
+/*****************************************************************************
+
+Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+
+*****************************************************************************/
+
+/**
+ * @file fts/fts0pars.y
+ * FTS parser: input file for the GNU Bison parser generator
+ *
+ * Created 2007/5/9 Sunny Bains
+ */
+
+%{
+#include "ha_prototypes.h"
+#include "mem0mem.h"
+#include "fts0ast.h"
+#include "fts0blex.h"
+#include "fts0tlex.h"
+#include "fts0pars.h"
+#include <my_sys.h>
+
+extern int fts_lexer(YYSTYPE*, fts_lexer_t*);
+extern int fts_blexer(YYSTYPE*, yyscan_t);
+extern int fts_tlexer(YYSTYPE*, yyscan_t);
+
+
+
+extern int ftserror(const char* p);
+
+/* Required for reentrant parser */
+#define ftslex fts_lexer
+
+#define YYERROR_VERBOSE
+
+/* For passing an argument to yyparse() */
+#define YYPARSE_PARAM state
+#define YYLEX_PARAM ((fts_ast_state_t*) state)->lexer
+
+
+typedef int (*fts_scanner)(YYSTYPE* val, yyscan_t yyscanner);
+
+struct fts_lexer_struct {
+ fts_scanner scanner;
+ void* yyscanner;
+};
+
+%}
+
+%union {
+ int oper;
+ fts_ast_string_t* token;
+ fts_ast_node_t* node;
+};
+
+/* Enable re-entrant parser */
+%pure_parser
+
+%token<oper> FTS_OPER
+%token<token> FTS_TEXT FTS_TERM FTS_NUMB
+
+%type<node> prefix term text expr sub_expr expr_lst query
+
+%nonassoc '+' '-' '~' '<' '>'
+
+%%
+
+query : expr_lst {
+ $$ = $1;
+ ((fts_ast_state_t*) state)->root = $$;
+ }
+ ;
+
+expr_lst: /* Empty */ {
+ $$ = NULL;
+ }
+
+ | expr_lst expr {
+ $$ = $1;
+
+ if (!$$) {
+ $$ = fts_ast_create_node_list(state, $2);
+ } else {
+ fts_ast_add_node($$, $2);
+ }
+ }
+
+ | expr_lst sub_expr {
+ $$ = $1;
+ $$ = fts_ast_create_node_list(state, $1);
+
+ if (!$$) {
+ $$ = $2;
+ } else {
+ fts_ast_add_node($$, $2);
+ }
+ }
+ ;
+
+sub_expr: '(' expr_lst ')' {
+ $$ = $2;
+
+ if ($$) {
+ $$ = fts_ast_create_node_subexp_list(state, $$);
+ }
+ }
+
+ | prefix '(' expr_lst ')' {
+ $$ = fts_ast_create_node_list(state, $1);
+
+ if ($3) {
+ fts_ast_add_node($$,
+ fts_ast_create_node_subexp_list(state, $3));
+ }
+ }
+ ;
+
+expr : term {
+ $$ = $1;
+ }
+
+ | text {
+ $$ = $1;
+ }
+
+ | term '*' {
+ fts_ast_term_set_wildcard($1);
+ }
+
+ | text '@' FTS_NUMB {
+ fts_ast_text_set_distance($1, fts_ast_string_to_ul($3, 10));
+ fts_ast_string_free($3);
+ }
+
+ | prefix term '*' {
+ $$ = fts_ast_create_node_list(state, $1);
+ fts_ast_add_node($$, $2);
+ fts_ast_term_set_wildcard($2);
+ }
+
+ | prefix term {
+ $$ = fts_ast_create_node_list(state, $1);
+ fts_ast_add_node($$, $2);
+ }
+
+ | prefix text '@' FTS_NUMB {
+ $$ = fts_ast_create_node_list(state, $1);
+ fts_ast_add_node($$, $2);
+ fts_ast_text_set_distance($2, fts_ast_string_to_ul($4, 10));
+ fts_ast_string_free($4);
+ }
+
+ | prefix text {
+ $$ = fts_ast_create_node_list(state, $1);
+ fts_ast_add_node($$, $2);
+ }
+ ;
+
+prefix : '-' {
+ $$ = fts_ast_create_node_oper(state, FTS_IGNORE);
+ }
+
+ | '+' {
+ $$ = fts_ast_create_node_oper(state, FTS_EXIST);
+ }
+
+ | '~' {
+ $$ = fts_ast_create_node_oper(state, FTS_NEGATE);
+ }
+
+ | '<' {
+ $$ = fts_ast_create_node_oper(state, FTS_DECR_RATING);
+ }
+
+ | '>' {
+ $$ = fts_ast_create_node_oper(state, FTS_INCR_RATING);
+ }
+ ;
+
+term : FTS_TERM {
+ $$ = fts_ast_create_node_term(state, $1);
+ fts_ast_string_free($1);
+ }
+
+ | FTS_NUMB {
+ $$ = fts_ast_create_node_term(state, $1);
+ fts_ast_string_free($1);
+ }
+
+ /* Ignore leading '*' */
+ | '*' term {
+ $$ = $2;
+ }
+ ;
+
+text : FTS_TEXT {
+ $$ = fts_ast_create_node_text(state, $1);
+ fts_ast_string_free($1);
+ }
+ ;
+%%
+
+/********************************************************************
+*/
+int
+ftserror(
+/*=====*/
+ const char* p)
+{
+ fprintf(stderr, "%s\n", p);
+ return(0);
+}
+
+/********************************************************************
+Create a fts_lexer_t instance.*/
+fts_lexer_t*
+fts_lexer_create(
+/*=============*/
+ ibool boolean_mode,
+ const byte* query,
+ ulint query_len)
+{
+ fts_lexer_t* fts_lexer = static_cast<fts_lexer_t*>(
+ ut_malloc_nokey(sizeof(fts_lexer_t)));
+
+ if (boolean_mode) {
+ fts0blex_init(&fts_lexer->yyscanner);
+ fts0b_scan_bytes((char*) query, (int) query_len, fts_lexer->yyscanner);
+ fts_lexer->scanner = fts_blexer;
+ /* FIXME: Debugging */
+ /* fts0bset_debug(1 , fts_lexer->yyscanner); */
+ } else {
+ fts0tlex_init(&fts_lexer->yyscanner);
+ fts0t_scan_bytes((char*) query, (int) query_len, fts_lexer->yyscanner);
+ fts_lexer->scanner = fts_tlexer;
+ }
+
+ return(fts_lexer);
+}
+
+/********************************************************************
+Free an fts_lexer_t instance.*/
+void
+
+fts_lexer_free(
+/*===========*/
+ fts_lexer_t* fts_lexer)
+{
+ if (fts_lexer->scanner == fts_blexer) {
+ fts0blex_destroy(fts_lexer->yyscanner);
+ } else {
+ fts0tlex_destroy(fts_lexer->yyscanner);
+ }
+
+ ut_free(fts_lexer);
+}
+
+/********************************************************************
+Call the appropaiate scanner.*/
+int
+fts_lexer(
+/*======*/
+ YYSTYPE* val,
+ fts_lexer_t* fts_lexer)
+{
+ fts_scanner func_ptr;
+
+ func_ptr = fts_lexer->scanner;
+
+ return(func_ptr(val, fts_lexer->yyscanner));
+}
+
+/********************************************************************
+Parse the query.*/
+int
+fts_parse(
+/*======*/
+ fts_ast_state_t* state)
+{
+ return(ftsparse(state));
+}