1/* -*- mode: c; c-basic-offset: 2 -*- */ 2%name grn_expr_parser 3%token_prefix GRN_EXPR_TOKEN_ 4%include { 5#ifdef assert 6# undef assert 7#endif 8#define assert GRN_ASSERT 9} 10 11%token_type { int } 12 13%type suppress_unused_variable_warning { void * } 14%destructor suppress_unused_variable_warning { 15 (void)efsi; 16} 17 18%extra_argument { efs_info *efsi } 19 20%syntax_error { 21 { 22 grn_ctx *ctx = efsi->ctx; 23 grn_obj message; 24 GRN_TEXT_INIT(&message, 0); 25 GRN_TEXT_PUT(ctx, &message, efsi->str, efsi->cur - efsi->str); 26 GRN_TEXT_PUTC(ctx, &message, '|'); 27 if (efsi->cur < efsi->str_end) { 28 GRN_TEXT_PUTC(ctx, &message, efsi->cur[0]); 29 GRN_TEXT_PUTC(ctx, &message, '|'); 30 GRN_TEXT_PUT(ctx, &message, 31 efsi->cur + 1, efsi->str_end - (efsi->cur + 1)); 32 } else { 33 GRN_TEXT_PUTC(ctx, &message, '|'); 34 } 35 if (ctx->rc == GRN_SUCCESS) { 36 ERR(GRN_SYNTAX_ERROR, "Syntax error: <%.*s>", 37 (int)GRN_TEXT_LEN(&message), GRN_TEXT_VALUE(&message)); 38 } else { 39 ERR(ctx->rc, "Syntax error: <%.*s>: %s", 40 (int)GRN_TEXT_LEN(&message), GRN_TEXT_VALUE(&message), 41 ctx->errbuf); 42 } 43 GRN_OBJ_FIN(ctx, &message); 44 } 45} 46 47input ::= query. 48input ::= expression. 49input ::= START_OUTPUT_COLUMNS output_columns. 50input ::= START_ADJUSTER adjuster. 51 52query ::= query_element. 53query ::= query query_element. { 54 grn_expr_append_op(efsi->ctx, efsi->e, grn_int32_value_at(&efsi->op_stack, -1), 2); 55} 56query ::= query LOGICAL_AND query_element. { 57 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND, 2); 58} 59query ::= query LOGICAL_AND_NOT query_element.{ 60 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_NOT, 2); 61} 62query ::= query LOGICAL_OR query_element.{ 63 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR, 2); 64} 65query ::= query NEGATIVE query_element.{ 66 int weight; 67 GRN_INT32_POP(&efsi->weight_stack, weight); 68 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 2); 69} 70 71query_element ::= QSTRING. 72query_element ::= PARENL query PARENR. 73 74query_element ::= ADJUST query_element.{ 75 int weight; 76 GRN_INT32_POP(&efsi->weight_stack, weight); 77} 78query_element ::= RELATIVE_OP query_element.{ 79 int mode; 80 GRN_INT32_POP(&efsi->mode_stack, mode); 81} 82query_element ::= IDENTIFIER RELATIVE_OP query_element. { 83 int mode; 84 grn_obj *c; 85 GRN_PTR_POP(&efsi->column_stack, c); 86 GRN_INT32_POP(&efsi->mode_stack, mode); 87 switch (mode) { 88 case GRN_OP_NEAR : 89 case GRN_OP_NEAR2 : 90 { 91 int max_interval; 92 GRN_INT32_POP(&efsi->max_interval_stack, max_interval); 93 } 94 break; 95 case GRN_OP_SIMILAR : 96 { 97 int similarity_threshold; 98 GRN_INT32_POP(&efsi->similarity_threshold_stack, similarity_threshold); 99 } 100 break; 101 default : 102 break; 103 } 104} 105query_element ::= BRACEL expression BRACER. { 106 efsi->flags = efsi->default_flags; 107} 108query_element ::= EVAL primary_expression. { 109 efsi->flags = efsi->default_flags; 110} 111 112expression ::= assignment_expression. 113expression ::= expression COMMA assignment_expression. { 114 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2); 115} 116 117assignment_expression ::= conditional_expression. 118assignment_expression ::= lefthand_side_expression ASSIGN assignment_expression. { 119 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ASSIGN, 2); 120} 121assignment_expression ::= lefthand_side_expression STAR_ASSIGN assignment_expression. { 122 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR_ASSIGN, 2); 123} 124assignment_expression ::= lefthand_side_expression SLASH_ASSIGN assignment_expression. { 125 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH_ASSIGN, 2); 126} 127assignment_expression ::= lefthand_side_expression MOD_ASSIGN assignment_expression. { 128 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD_ASSIGN, 2); 129} 130assignment_expression ::= lefthand_side_expression PLUS_ASSIGN assignment_expression. { 131 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS_ASSIGN, 2); 132} 133assignment_expression ::= lefthand_side_expression MINUS_ASSIGN assignment_expression. { 134 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS_ASSIGN, 2); 135} 136assignment_expression ::= lefthand_side_expression SHIFTL_ASSIGN assignment_expression. { 137 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL_ASSIGN, 2); 138} 139assignment_expression ::= lefthand_side_expression SHIFTR_ASSIGN assignment_expression. { 140 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR_ASSIGN, 2); 141} 142assignment_expression ::= lefthand_side_expression SHIFTRR_ASSIGN assignment_expression. { 143 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR_ASSIGN, 2); 144} 145assignment_expression ::= lefthand_side_expression AND_ASSIGN assignment_expression. { 146 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_ASSIGN, 2); 147} 148assignment_expression ::= lefthand_side_expression XOR_ASSIGN assignment_expression. { 149 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_XOR_ASSIGN, 2); 150} 151assignment_expression ::= lefthand_side_expression OR_ASSIGN assignment_expression. { 152 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR_ASSIGN, 2); 153} 154 155conditional_expression ::= logical_or_expression. 156conditional_expression ::= logical_or_expression QUESTION(A) assignment_expression COLON(B) assignment_expression. { 157 grn_expr *e = (grn_expr *)efsi->e; 158 e->codes[A].nargs = B - A; 159 e->codes[B].nargs = e->codes_curr - B - 1; 160} 161 162logical_or_expression ::= logical_and_expression. 163logical_or_expression ::= logical_or_expression LOGICAL_OR logical_and_expression. { 164 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_OR, 2); 165} 166 167logical_and_expression ::= bitwise_or_expression. 168logical_and_expression ::= logical_and_expression LOGICAL_AND bitwise_or_expression. { 169 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND, 2); 170} 171logical_and_expression ::= logical_and_expression LOGICAL_AND_NOT bitwise_or_expression. { 172 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_AND_NOT, 2); 173} 174 175bitwise_or_expression ::= bitwise_xor_expression. 176bitwise_or_expression ::= bitwise_or_expression BITWISE_OR bitwise_xor_expression. { 177 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_OR, 2); 178} 179 180bitwise_xor_expression ::= bitwise_and_expression. 181bitwise_xor_expression ::= bitwise_xor_expression BITWISE_XOR bitwise_and_expression. { 182 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_XOR, 2); 183} 184 185bitwise_and_expression ::= equality_expression. 186bitwise_and_expression ::= bitwise_and_expression BITWISE_AND equality_expression. { 187 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_AND, 2); 188} 189 190equality_expression ::= relational_expression. 191equality_expression ::= equality_expression EQUAL relational_expression. { 192 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EQUAL, 2); 193} 194equality_expression ::= equality_expression NOT_EQUAL relational_expression. { 195 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT_EQUAL, 2); 196} 197 198relational_expression ::= shift_expression. 199relational_expression ::= relational_expression LESS shift_expression. { 200 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS, 2); 201} 202relational_expression ::= relational_expression GREATER shift_expression. { 203 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER, 2); 204} 205relational_expression ::= relational_expression LESS_EQUAL shift_expression. { 206 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LESS_EQUAL, 2); 207} 208relational_expression ::= relational_expression GREATER_EQUAL shift_expression. { 209 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GREATER_EQUAL, 2); 210} 211relational_expression ::= relational_expression IN shift_expression. { 212 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_IN, 2); 213} 214relational_expression ::= relational_expression MATCH shift_expression. { 215 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MATCH, 2); 216} 217relational_expression ::= relational_expression NEAR shift_expression. { 218 { 219 int max_interval; 220 GRN_INT32_POP(&efsi->max_interval_stack, max_interval); 221 grn_expr_append_const_int(efsi->ctx, efsi->e, max_interval, 222 GRN_OP_PUSH, 1); 223 } 224 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR, 3); 225} 226relational_expression ::= relational_expression NEAR2 shift_expression. { 227 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NEAR2, 2); 228} 229relational_expression ::= relational_expression SIMILAR shift_expression. { 230 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SIMILAR, 2); 231} 232relational_expression ::= relational_expression TERM_EXTRACT shift_expression. { 233 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_TERM_EXTRACT, 2); 234} 235relational_expression ::= relational_expression LCP shift_expression. { 236 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_LCP, 2); 237} 238relational_expression ::= relational_expression PREFIX shift_expression. { 239 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PREFIX, 2); 240} 241relational_expression ::= relational_expression SUFFIX shift_expression. { 242 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SUFFIX, 2); 243} 244relational_expression ::= relational_expression REGEXP shift_expression. { 245 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_REGEXP, 2); 246} 247 248shift_expression ::= additive_expression. 249shift_expression ::= shift_expression SHIFTL additive_expression. { 250 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTL, 2); 251} 252shift_expression ::= shift_expression SHIFTR additive_expression. { 253 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTR, 2); 254} 255shift_expression ::= shift_expression SHIFTRR additive_expression. { 256 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SHIFTRR, 2); 257} 258 259additive_expression ::= multiplicative_expression. 260additive_expression ::= additive_expression PLUS multiplicative_expression. { 261 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 2); 262} 263additive_expression ::= additive_expression MINUS multiplicative_expression. { 264 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 2); 265} 266 267multiplicative_expression ::= unary_expression. 268multiplicative_expression ::= multiplicative_expression STAR unary_expression. { 269 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR, 2); 270} 271multiplicative_expression ::= multiplicative_expression SLASH unary_expression. { 272 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_SLASH, 2); 273} 274multiplicative_expression ::= multiplicative_expression MOD unary_expression. { 275 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MOD, 2); 276} 277 278unary_expression ::= postfix_expression. 279unary_expression ::= DELETE unary_expression. { 280 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DELETE, 1); 281} 282unary_expression ::= INCR unary_expression. { 283 grn_ctx *ctx = efsi->ctx; 284 grn_expr *e = (grn_expr *)(efsi->e); 285 grn_expr_dfi *dfi_; 286 unsigned int const_p; 287 288 dfi_ = grn_expr_dfi_pop(e); 289 const_p = CONSTP(dfi_->code->value); 290 grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code); 291 if (const_p) { 292 ERR(GRN_SYNTAX_ERROR, 293 "constant can't be incremented: <%.*s>", 294 (int)(efsi->str_end - efsi->str), efsi->str); 295 } else { 296 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR, 1); 297 } 298} 299unary_expression ::= DECR unary_expression. { 300 grn_ctx *ctx = efsi->ctx; 301 grn_expr *e = (grn_expr *)(efsi->e); 302 grn_expr_dfi *dfi_; 303 unsigned int const_p; 304 305 dfi_ = grn_expr_dfi_pop(e); 306 const_p = CONSTP(dfi_->code->value); 307 grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code); 308 if (const_p) { 309 ERR(GRN_SYNTAX_ERROR, 310 "constant can't be decremented: <%.*s>", 311 (int)(efsi->str_end - efsi->str), efsi->str); 312 } else { 313 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR, 1); 314 } 315} 316unary_expression ::= PLUS unary_expression. { 317 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 1); 318} 319unary_expression ::= MINUS unary_expression. { 320 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MINUS, 1); 321} 322unary_expression ::= NOT unary_expression. { 323 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_NOT, 1); 324} 325unary_expression ::= BITWISE_NOT unary_expression. { 326 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_BITWISE_NOT, 1); 327} 328unary_expression ::= ADJUST unary_expression. { 329 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_ADJUST, 1); 330} 331unary_expression ::= EXACT unary_expression. { 332 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_EXACT, 1); 333} 334unary_expression ::= PARTIAL unary_expression. { 335 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PARTIAL, 1); 336} 337unary_expression ::= UNSPLIT unary_expression. { 338 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_UNSPLIT, 1); 339} 340 341postfix_expression ::= lefthand_side_expression. 342postfix_expression ::= lefthand_side_expression INCR. { 343 grn_ctx *ctx = efsi->ctx; 344 grn_expr *e = (grn_expr *)(efsi->e); 345 grn_expr_dfi *dfi_; 346 unsigned int const_p; 347 348 dfi_ = grn_expr_dfi_pop(e); 349 const_p = CONSTP(dfi_->code->value); 350 grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code); 351 if (const_p) { 352 ERR(GRN_SYNTAX_ERROR, 353 "constant can't be incremented: <%.*s>", 354 (int)(efsi->str_end - efsi->str), efsi->str); 355 } else { 356 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_INCR_POST, 1); 357 } 358} 359postfix_expression ::= lefthand_side_expression DECR. { 360 grn_ctx *ctx = efsi->ctx; 361 grn_expr *e = (grn_expr *)(efsi->e); 362 grn_expr_dfi *dfi_; 363 unsigned int const_p; 364 365 dfi_ = grn_expr_dfi_pop(e); 366 const_p = CONSTP(dfi_->code->value); 367 grn_expr_dfi_put(ctx, e, dfi_->type, dfi_->domain, dfi_->code); 368 if (const_p) { 369 ERR(GRN_SYNTAX_ERROR, 370 "constant can't be decremented: <%.*s>", 371 (int)(efsi->str_end - efsi->str), efsi->str); 372 } else { 373 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_DECR_POST, 1); 374 } 375} 376 377lefthand_side_expression ::= call_expression. 378lefthand_side_expression ::= member_expression. 379 380call_expression ::= member_expression arguments(A). { 381 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_CALL, A); 382} 383 384member_expression ::= primary_expression. 385member_expression ::= member_expression member_expression_part. 386 387primary_expression ::= object_literal. 388primary_expression ::= PARENL expression PARENR. 389primary_expression ::= IDENTIFIER. 390primary_expression ::= array_literal. 391primary_expression ::= DECIMAL. 392primary_expression ::= HEX_INTEGER. 393primary_expression ::= STRING. 394primary_expression ::= BOOLEAN. 395primary_expression ::= NULL. 396 397array_literal ::= BRACKETL elision BRACKETR. 398array_literal ::= BRACKETL element_list elision BRACKETR. 399array_literal ::= BRACKETL element_list BRACKETR. 400 401elision ::= COMMA. 402elision ::= elision COMMA. 403 404element_list ::= assignment_expression. 405element_list ::= elision assignment_expression. 406element_list ::= element_list elision assignment_expression. 407 408object_literal ::= BRACEL property_name_and_value_list BRACER. { 409 grn_ctx *ctx = efsi->ctx; 410 grn_expr_take_obj(ctx, efsi->e, (grn_obj *)(efsi->object_literal)); 411 grn_expr_append_obj(ctx, efsi->e, (grn_obj *)(efsi->object_literal), 412 GRN_OP_PUSH, 1); 413 efsi->object_literal = NULL; 414} 415 416property_name_and_value_list ::= . { 417 grn_ctx *ctx = efsi->ctx; 418 419 efsi->object_literal = 420 grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, sizeof(grn_obj), 421 GRN_OBJ_KEY_VAR_SIZE|GRN_OBJ_TEMPORARY|GRN_HASH_TINY); 422 if (!efsi->object_literal) { 423 ERR(GRN_NO_MEMORY_AVAILABLE, 424 "couldn't create hash table for parsing object literal: <%.*s>", 425 (int)(efsi->str_end - efsi->str), efsi->str); 426 } 427} 428property_name_and_value_list ::= property_name_and_value. 429property_name_and_value_list ::= property_name_and_value_list COMMA property_name_and_value. 430 431property_name_and_value ::= property_name COLON assignment_expression. { 432 grn_ctx *ctx = efsi->ctx; 433 grn_expr *e = (grn_expr *)(efsi->e); 434 grn_obj *property = e->codes[e->codes_curr - 3].value; 435 grn_obj *value = e->codes[e->codes_curr - 1].value; 436 437 if (!efsi->object_literal) { 438 efsi->object_literal = 439 grn_hash_create(ctx, NULL, GRN_TABLE_MAX_KEY_SIZE, sizeof(grn_obj), 440 GRN_OBJ_KEY_VAR_SIZE|GRN_OBJ_TEMPORARY|GRN_HASH_TINY); 441 } 442 443 if (!efsi->object_literal) { 444 ERR(GRN_NO_MEMORY_AVAILABLE, 445 "couldn't create hash table for parsing object literal: <%.*s>", 446 (int)(efsi->str_end - efsi->str), efsi->str); 447 } else { 448 grn_obj *buf; 449 int added; 450 if (grn_hash_add(ctx, (grn_hash *)efsi->object_literal, 451 GRN_TEXT_VALUE(property), GRN_TEXT_LEN(property), 452 (void **)&buf, &added)) { 453 if (added) { 454 GRN_OBJ_INIT(buf, value->header.type, 0, value->header.domain); 455 GRN_TEXT_PUT(ctx, buf, GRN_TEXT_VALUE(value), GRN_TEXT_LEN(value)); 456 grn_expr_dfi_pop(e); 457 e->codes_curr -= 3; 458 } else { 459 ERR(GRN_INVALID_ARGUMENT, 460 "duplicated property name: <%.*s>", 461 (int)GRN_TEXT_LEN(property), 462 GRN_TEXT_VALUE(property)); 463 } 464 } else { 465 ERR(GRN_NO_MEMORY_AVAILABLE, 466 "failed to add a property to object literal: <%.*s>", 467 (int)GRN_TEXT_LEN(property), 468 GRN_TEXT_VALUE(property)); 469 } 470 } 471} 472 473property_name ::= STRING. 474 475member_expression_part ::= BRACKETL expression BRACKETR. { 476 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_GET_MEMBER, 2); 477} 478member_expression_part ::= DOT IDENTIFIER. 479 480arguments(A) ::= PARENL argument_list(B) PARENR. { A = B; } 481argument_list(A) ::= . { A = 0; } 482argument_list(A) ::= assignment_expression. { A = 1; } 483argument_list(A) ::= argument_list(B) COMMA assignment_expression. { A = B + 1; } 484 485output_columns(N_STACKED_COLUMNS) ::= . { 486 N_STACKED_COLUMNS = 0; 487} 488output_columns(N_STACKED_COLUMNS) ::= output_column(SUB_N_STACKED_COLUMNS). { 489 N_STACKED_COLUMNS = SUB_N_STACKED_COLUMNS; 490} 491/* Accept "column1,,,,,,column2" */ 492output_columns(N_STACKED_COLUMNS) ::= 493 output_columns(SUB_N_STACKED_COLUMNS) COMMA. { 494 N_STACKED_COLUMNS = SUB_N_STACKED_COLUMNS; 495} 496output_columns(N_STACKED_COLUMNS) ::= 497 output_columns(SUB_N_STACKED_COLUMNS) COMMA 498 output_column(NEW_N_STACKED_COLUMNS). { 499 if (SUB_N_STACKED_COLUMNS == 0) { 500 N_STACKED_COLUMNS = NEW_N_STACKED_COLUMNS; 501 } else if (NEW_N_STACKED_COLUMNS == 0) { 502 N_STACKED_COLUMNS = SUB_N_STACKED_COLUMNS; 503 } else { 504 if (NEW_N_STACKED_COLUMNS == 1) { 505 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_COMMA, 2); 506 } 507 N_STACKED_COLUMNS = 1; 508 } 509} 510 511output_column(N_STACKED_COLUMNS) ::= STAR. { 512 grn_ctx *ctx = efsi->ctx; 513 grn_obj *expr = efsi->e; 514 grn_obj *variable = grn_expr_get_var_by_offset(ctx, expr, 0); 515 if (variable) { 516 grn_id table_id = GRN_OBJ_GET_DOMAIN(variable); 517 grn_obj *table = grn_ctx_at(ctx, table_id); 518 grn_obj columns_buffer; 519 int n_columns; 520 grn_obj **columns; 521 522 GRN_PTR_INIT(&columns_buffer, GRN_OBJ_VECTOR, GRN_ID_NIL); 523 grn_obj_columns(ctx, table, "*", strlen("*"), &columns_buffer); 524 n_columns = GRN_BULK_VSIZE(&columns_buffer) / sizeof(grn_obj *); 525 columns = (grn_obj **)GRN_BULK_HEAD(&columns_buffer); 526 527 if (n_columns == 0) { 528 /* do nothing */ 529 } else if (n_columns == 1) { 530 grn_obj *column = columns[0]; 531 grn_expr_append_const(ctx, expr, column, GRN_OP_GET_VALUE, 1); 532 if (column->header.type == GRN_ACCESSOR) { 533 grn_expr_take_obj(ctx, expr, column); 534 } 535 } else { 536 grn_expr *e = (grn_expr *)expr; 537 grn_bool have_column; 538 int i; 539 540 have_column = (e->codes_curr > 0); 541 for (i = 0; i < n_columns; i++) { 542 grn_obj *column = columns[i]; 543 grn_expr_append_const(ctx, expr, column, GRN_OP_GET_VALUE, 1); 544 if (have_column || i > 0) { 545 grn_expr_append_op(ctx, expr, GRN_OP_COMMA, 2); 546 } 547 if (column->header.type == GRN_ACCESSOR) { 548 grn_expr_take_obj(ctx, expr, column); 549 } 550 } 551 } 552 553 GRN_OBJ_FIN(ctx, &columns_buffer); 554 555 N_STACKED_COLUMNS = n_columns; 556 } else { 557 /* TODO: report error */ 558 N_STACKED_COLUMNS = 0; 559 } 560} 561output_column(N_STACKED_COLUMNS) ::= NONEXISTENT_COLUMN. { 562 N_STACKED_COLUMNS = 0; 563} 564output_column(N_STACKED_COLUMNS) ::= assignment_expression. { 565 N_STACKED_COLUMNS = 1; 566} 567 568adjuster ::= . 569adjuster ::= adjust_expression. 570adjuster ::= adjuster PLUS adjust_expression. { 571 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_PLUS, 2); 572} 573 574adjust_expression ::= adjust_match_expression. 575adjust_expression ::= adjust_match_expression STAR DECIMAL. { 576 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_STAR, 2); 577} 578 579adjust_match_expression ::= IDENTIFIER MATCH STRING. { 580 grn_expr_append_op(efsi->ctx, efsi->e, GRN_OP_MATCH, 2); 581} 582