You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
5.6 KiB

11 years ago
11 years ago
12 years ago
12 years ago
12 years ago
12 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. /*****************************************************************************
  2. Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
  3. This program is free software; you can redistribute it and/or modify it under
  4. the terms of the GNU General Public License as published by the Free Software
  5. Foundation; version 2 of the License.
  6. This program is distributed in the hope that it will be useful, but WITHOUT
  7. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along with
  10. this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
  12. *****************************************************************************/
  13. /**
  14. * @file fts/fts0pars.y
  15. * FTS parser: input file for the GNU Bison parser generator
  16. *
  17. * Created 2007/5/9 Sunny Bains
  18. */
  19. %{
  20. #include "mem0mem.h"
  21. #include "fts0ast.h"
  22. #include "fts0blex.h"
  23. #include "fts0tlex.h"
  24. #include "fts0pars.h"
  25. extern int fts_lexer(YYSTYPE*, fts_lexer_t*);
  26. extern int fts_blexer(YYSTYPE*, yyscan_t);
  27. extern int fts_tlexer(YYSTYPE*, yyscan_t);
  28. extern int ftserror(const char* p);
  29. /* Required for reentrant parser */
  30. #define ftslex fts_lexer
  31. #define YYERROR_VERBOSE
  32. /* For passing an argument to yyparse() */
  33. #define YYPARSE_PARAM state
  34. #define YYLEX_PARAM ((fts_ast_state_t*) state)->lexer
  35. typedef int (*fts_scanner)(YYSTYPE* val, yyscan_t yyscanner);
  36. struct fts_lexer_struct {
  37. fts_scanner scanner;
  38. void* yyscanner;
  39. };
  40. %}
  41. %union {
  42. int oper;
  43. fts_ast_string_t* token;
  44. fts_ast_node_t* node;
  45. };
  46. /* Enable re-entrant parser */
  47. %pure_parser
  48. %token<oper> FTS_OPER
  49. %token<token> FTS_TEXT FTS_TERM FTS_NUMB
  50. %type<node> prefix term text expr sub_expr expr_lst query
  51. %nonassoc '+' '-' '~' '<' '>'
  52. %%
  53. query : expr_lst {
  54. $$ = $1;
  55. ((fts_ast_state_t*) state)->root = $$;
  56. }
  57. ;
  58. expr_lst: /* Empty */ {
  59. $$ = NULL;
  60. }
  61. | expr_lst expr {
  62. $$ = $1;
  63. if (!$$) {
  64. $$ = fts_ast_create_node_list(state, $2);
  65. } else {
  66. fts_ast_add_node($$, $2);
  67. }
  68. }
  69. | expr_lst sub_expr {
  70. $$ = $1;
  71. $$ = fts_ast_create_node_list(state, $1);
  72. if (!$$) {
  73. $$ = $2;
  74. } else {
  75. fts_ast_add_node($$, $2);
  76. }
  77. }
  78. ;
  79. sub_expr: '(' expr_lst ')' {
  80. $$ = $2;
  81. if ($$) {
  82. $$ = fts_ast_create_node_subexp_list(state, $$);
  83. }
  84. }
  85. | prefix '(' expr_lst ')' {
  86. $$ = fts_ast_create_node_list(state, $1);
  87. if ($3) {
  88. fts_ast_add_node($$,
  89. fts_ast_create_node_subexp_list(state, $3));
  90. }
  91. }
  92. ;
  93. expr : term {
  94. $$ = $1;
  95. }
  96. | text {
  97. $$ = $1;
  98. }
  99. | term '*' {
  100. fts_ast_term_set_wildcard($1);
  101. }
  102. | text '@' FTS_NUMB {
  103. fts_ast_term_set_distance($1, fts_ast_string_to_ul($3, 10));
  104. fts_ast_string_free($3);
  105. }
  106. | prefix term '*' {
  107. $$ = fts_ast_create_node_list(state, $1);
  108. fts_ast_add_node($$, $2);
  109. fts_ast_term_set_wildcard($2);
  110. }
  111. | prefix term {
  112. $$ = fts_ast_create_node_list(state, $1);
  113. fts_ast_add_node($$, $2);
  114. }
  115. | prefix text '@' FTS_NUMB {
  116. $$ = fts_ast_create_node_list(state, $1);
  117. fts_ast_add_node($$, $2);
  118. fts_ast_term_set_distance($2, fts_ast_string_to_ul($4, 10));
  119. fts_ast_string_free($4);
  120. }
  121. | prefix text {
  122. $$ = fts_ast_create_node_list(state, $1);
  123. fts_ast_add_node($$, $2);
  124. }
  125. ;
  126. prefix : '-' {
  127. $$ = fts_ast_create_node_oper(state, FTS_IGNORE);
  128. }
  129. | '+' {
  130. $$ = fts_ast_create_node_oper(state, FTS_EXIST);
  131. }
  132. | '~' {
  133. $$ = fts_ast_create_node_oper(state, FTS_NEGATE);
  134. }
  135. | '<' {
  136. $$ = fts_ast_create_node_oper(state, FTS_DECR_RATING);
  137. }
  138. | '>' {
  139. $$ = fts_ast_create_node_oper(state, FTS_INCR_RATING);
  140. }
  141. ;
  142. term : FTS_TERM {
  143. $$ = fts_ast_create_node_term(state, $1);
  144. fts_ast_string_free($1);
  145. }
  146. | FTS_NUMB {
  147. $$ = fts_ast_create_node_term(state, $1);
  148. fts_ast_string_free($1);
  149. }
  150. /* Ignore leading '*' */
  151. | '*' term {
  152. $$ = $2;
  153. }
  154. ;
  155. text : FTS_TEXT {
  156. $$ = fts_ast_create_node_text(state, $1);
  157. fts_ast_string_free($1);
  158. }
  159. ;
  160. %%
  161. /********************************************************************
  162. */
  163. int
  164. ftserror(
  165. /*=====*/
  166. const char* p)
  167. {
  168. fprintf(stderr, "%s\n", p);
  169. return(0);
  170. }
  171. /********************************************************************
  172. Create a fts_lexer_t instance.*/
  173. fts_lexer_t*
  174. fts_lexer_create(
  175. /*=============*/
  176. ibool boolean_mode,
  177. const byte* query,
  178. ulint query_len)
  179. {
  180. fts_lexer_t* fts_lexer = static_cast<fts_lexer_t*>(
  181. ut_malloc(sizeof(fts_lexer_t)));
  182. if (boolean_mode) {
  183. fts0blex_init(&fts_lexer->yyscanner);
  184. fts0b_scan_bytes((char*) query, query_len, fts_lexer->yyscanner);
  185. fts_lexer->scanner = fts_blexer;
  186. /* FIXME: Debugging */
  187. /* fts0bset_debug(1 , fts_lexer->yyscanner); */
  188. } else {
  189. fts0tlex_init(&fts_lexer->yyscanner);
  190. fts0t_scan_bytes((char*) query, query_len, fts_lexer->yyscanner);
  191. fts_lexer->scanner = fts_tlexer;
  192. }
  193. return(fts_lexer);
  194. }
  195. /********************************************************************
  196. Free an fts_lexer_t instance.*/
  197. void
  198. fts_lexer_free(
  199. /*===========*/
  200. fts_lexer_t* fts_lexer)
  201. {
  202. if (fts_lexer->scanner == fts_blexer) {
  203. fts0blex_destroy(fts_lexer->yyscanner);
  204. } else {
  205. fts0tlex_destroy(fts_lexer->yyscanner);
  206. }
  207. ut_free(fts_lexer);
  208. }
  209. /********************************************************************
  210. Call the appropaiate scanner.*/
  211. int
  212. fts_lexer(
  213. /*======*/
  214. YYSTYPE* val,
  215. fts_lexer_t* fts_lexer)
  216. {
  217. fts_scanner func_ptr;
  218. func_ptr = fts_lexer->scanner;
  219. return(func_ptr(val, fts_lexer->yyscanner));
  220. }
  221. /********************************************************************
  222. Parse the query.*/
  223. int
  224. fts_parse(
  225. /*======*/
  226. fts_ast_state_t* state)
  227. {
  228. return(ftsparse(state));
  229. }