1 /* 2 ** 2014 May 31 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ****************************************************************************** 12 ** 13 */ 14 15 16 // All token codes are small integers with #defines that begin with "TK_" 17 %token_prefix FTS5_ 18 19 // The type of the data attached to each token is Token. This is also the 20 // default type for non-terminals. 21 // 22 %token_type {Fts5Token} 23 %default_type {Fts5Token} 24 25 // The generated parser function takes a 4th argument as follows: 26 %extra_argument {Fts5Parse *pParse} 27 28 // This code runs whenever there is a syntax error 29 // 30 %syntax_error { 31 UNUSED_PARAM(yymajor); /* Silence a compiler warning */ 32 sqlite3Fts5ParseError( 33 pParse, "fts5: syntax error near \"%.*s\"",TOKEN.n,TOKEN.p 34 ); 35 } 36 %stack_overflow { 37 sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow"); 38 } 39 40 // The name of the generated procedure that implements the parser 41 // is as follows: 42 %name sqlite3Fts5Parser 43 44 // The following text is included near the beginning of the C source 45 // code file that implements the parser. 46 // 47 %include { 48 #include "fts5Int.h" 49 #include "fts5parse.h" 50 51 /* 52 ** Disable all error recovery processing in the parser push-down 53 ** automaton. 54 */ 55 #define YYNOERRORRECOVERY 1 56 57 /* 58 ** Make yytestcase() the same as testcase() 59 */ 60 #define yytestcase(X) testcase(X) 61 62 /* 63 ** Indicate that sqlite3ParserFree() will never be called with a null 64 ** pointer. 65 */ 66 #define YYPARSEFREENOTNULL 1 67 68 /* 69 ** Alternative datatype for the argument to the malloc() routine passed 70 ** into sqlite3ParserAlloc(). The default is size_t. 71 */ 72 #define YYMALLOCARGTYPE u64 73 74 } // end %include 75 76 %left OR. 77 %left AND. 78 %left NOT. 79 %left TERM. 80 %left COLON. 81 82 input ::= expr(X). { sqlite3Fts5ParseFinished(pParse, X); } 83 %destructor input { (void)pParse; } 84 85 %type cnearset {Fts5ExprNode*} 86 %type expr {Fts5ExprNode*} 87 %type exprlist {Fts5ExprNode*} 88 %destructor cnearset { sqlite3Fts5ParseNodeFree($$); } 89 %destructor expr { sqlite3Fts5ParseNodeFree($$); } 90 %destructor exprlist { sqlite3Fts5ParseNodeFree($$); } 91 92 %type colset {Fts5Colset*} 93 %destructor colset { sqlite3_free($$); } 94 %type colsetlist {Fts5Colset*} 95 %destructor colsetlist { sqlite3_free($$); } 96 97 colset(A) ::= MINUS LCP colsetlist(X) RCP. { 98 A = sqlite3Fts5ParseColsetInvert(pParse, X); 99 } 100 colset(A) ::= LCP colsetlist(X) RCP. { A = X; } 101 colset(A) ::= STRING(X). { 102 A = sqlite3Fts5ParseColset(pParse, 0, &X); 103 } 104 colset(A) ::= MINUS STRING(X). { 105 A = sqlite3Fts5ParseColset(pParse, 0, &X); 106 A = sqlite3Fts5ParseColsetInvert(pParse, A); 107 } 108 109 colsetlist(A) ::= colsetlist(Y) STRING(X). { 110 A = sqlite3Fts5ParseColset(pParse, Y, &X); } 111 colsetlist(A) ::= STRING(X). { 112 A = sqlite3Fts5ParseColset(pParse, 0, &X); 113 } 114 115 expr(A) ::= expr(X) AND expr(Y). { 116 A = sqlite3Fts5ParseNode(pParse, FTS5_AND, X, Y, 0); 117 } 118 expr(A) ::= expr(X) OR expr(Y). { 119 A = sqlite3Fts5ParseNode(pParse, FTS5_OR, X, Y, 0); 120 } 121 expr(A) ::= expr(X) NOT expr(Y). { 122 A = sqlite3Fts5ParseNode(pParse, FTS5_NOT, X, Y, 0); 123 } 124 125 expr(A) ::= colset(X) COLON LP expr(Y) RP. { 126 sqlite3Fts5ParseSetColset(pParse, Y, X); 127 A = Y; 128 } 129 expr(A) ::= LP expr(X) RP. {A = X;} 130 expr(A) ::= exprlist(X). {A = X;} 131 132 exprlist(A) ::= cnearset(X). {A = X;} 133 exprlist(A) ::= exprlist(X) cnearset(Y). { 134 A = sqlite3Fts5ParseImplicitAnd(pParse, X, Y); 135 } 136 137 cnearset(A) ::= nearset(X). { 138 A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, X); 139 } 140 cnearset(A) ::= colset(X) COLON nearset(Y). { 141 A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, Y); 142 sqlite3Fts5ParseSetColset(pParse, A, X); 143 } 144 145 146 %type nearset {Fts5ExprNearset*} 147 %type nearphrases {Fts5ExprNearset*} 148 %destructor nearset { sqlite3Fts5ParseNearsetFree($$); } 149 %destructor nearphrases { sqlite3Fts5ParseNearsetFree($$); } 150 151 nearset(A) ::= phrase(Y). { A = sqlite3Fts5ParseNearset(pParse, 0, Y); } 152 nearset(A) ::= CARET phrase(Y). { 153 sqlite3Fts5ParseSetCaret(Y); 154 A = sqlite3Fts5ParseNearset(pParse, 0, Y); 155 } 156 nearset(A) ::= STRING(X) LP nearphrases(Y) neardist_opt(Z) RP. { 157 sqlite3Fts5ParseNear(pParse, &X); 158 sqlite3Fts5ParseSetDistance(pParse, Y, &Z); 159 A = Y; 160 } 161 162 nearphrases(A) ::= phrase(X). { 163 A = sqlite3Fts5ParseNearset(pParse, 0, X); 164 } 165 nearphrases(A) ::= nearphrases(X) phrase(Y). { 166 A = sqlite3Fts5ParseNearset(pParse, X, Y); 167 } 168 169 /* 170 ** The optional ", <integer>" at the end of the NEAR() arguments. 171 */ 172 neardist_opt(A) ::= . { A.p = 0; A.n = 0; } 173 neardist_opt(A) ::= COMMA STRING(X). { A = X; } 174 175 /* 176 ** A phrase. A set of primitives connected by "+" operators. Examples: 177 ** 178 ** "the" + "quick brown" + fo * 179 ** "the quick brown fo" * 180 ** the+quick+brown+fo* 181 */ 182 %type phrase {Fts5ExprPhrase*} 183 %destructor phrase { sqlite3Fts5ParsePhraseFree($$); } 184 185 phrase(A) ::= phrase(X) PLUS STRING(Y) star_opt(Z). { 186 A = sqlite3Fts5ParseTerm(pParse, X, &Y, Z); 187 } 188 phrase(A) ::= STRING(Y) star_opt(Z). { 189 A = sqlite3Fts5ParseTerm(pParse, 0, &Y, Z); 190 } 191 192 /* 193 ** Optional "*" character. 194 */ 195 %type star_opt {int} 196 star_opt(A) ::= STAR. { A = 1; } 197 star_opt(A) ::= . { A = 0; } 198