diff options
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 81 |
1 files changed, 47 insertions, 34 deletions
@@ -371,6 +371,9 @@ static int parser_yyerror(struct parser_params*, const char*); #define ruby_coverage (parser->coverage) #endif +#define NODE_CALL_Q(q) (((q) == tDOTQ) ? NODE_QCALL : NODE_CALL) +#define NEW_QCALL(q,r,m,a) NEW_NODE(NODE_CALL_Q(q),r,m,a) + static int yylex(YYSTYPE*, struct parser_params*); #ifndef RIPPER @@ -457,8 +460,8 @@ static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*); #define node_assign(node1, node2) node_assign_gen(parser, (node1), (node2)) static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs); -static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs); -#define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (attr), (op), (rhs)) +static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID atype, ID attr, ID op, NODE *rhs); +#define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs)) static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs); #define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs)) @@ -844,7 +847,7 @@ static void token_info_pop(struct parser_params*, const char *token, size_t len) %type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner %type <id> fsym keyword_variable user_variable sym symbol operation operation2 operation3 %type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg -%type <id> f_kwrest f_label f_arg_asgn +%type <id> f_kwrest f_label f_arg_asgn call_op /*%%%*/ /*% %type <val> program reswords then do dot_or_colon @@ -869,6 +872,7 @@ static void token_info_pop(struct parser_params*, const char *token, size_t len) %token tASET RUBY_TOKEN(ASET) "[]=" %token tLSHFT RUBY_TOKEN(LSHFT) "<<" %token tRSHFT RUBY_TOKEN(RSHFT) ">>" +%token tDOTQ RUBY_TOKEN(DOTQ) ".?" %token tCOLON2 "::" %token tCOLON3 ":: at EXPR_BEG" %token <id> tOP_ASGN /* +=, -= etc. */ @@ -1260,15 +1264,15 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem $$ = dispatch3(opassign, $$, $5, $6); %*/ } - | primary_value '.' tIDENTIFIER tOP_ASGN command_call + | primary_value call_op tIDENTIFIER tOP_ASGN command_call { value_expr($5); - $$ = new_attr_op_assign($1, '.', $3, $4, $5); + $$ = new_attr_op_assign($1, $2, $3, $4, $5); } - | primary_value '.' tCONSTANT tOP_ASGN command_call + | primary_value call_op tCONSTANT tOP_ASGN command_call { value_expr($5); - $$ = new_attr_op_assign($1, '.', $3, $4, $5); + $$ = new_attr_op_assign($1, $2, $3, $4, $5); } | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call { @@ -1456,24 +1460,24 @@ command : fcall command_args %prec tLOWEST $$ = method_add_block($$, $3); %*/ } - | primary_value '.' operation2 command_args %prec tLOWEST + | primary_value call_op operation2 command_args %prec tLOWEST { /*%%%*/ - $$ = NEW_CALL($1, $3, $4); + $$ = NEW_QCALL($2, $1, $3, $4); fixpos($$, $1); /*% - $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4); + $$ = dispatch4(command_call, $1, ripper_id2sym($2), $3, $4); %*/ } - | primary_value '.' operation2 command_args cmd_brace_block + | primary_value call_op operation2 command_args cmd_brace_block { /*%%%*/ block_dup_check($4,$5); - $5->nd_iter = NEW_CALL($1, $3, $4); + $5->nd_iter = NEW_QCALL($2, $1, $3, $4); $$ = $5; fixpos($$, $1); /*% - $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4); + $$ = dispatch4(command_call, $1, ripper_id2sym($2), $3, $4); $$ = method_add_block($$, $5); %*/ } @@ -1713,12 +1717,12 @@ mlhs_node : user_variable $$ = dispatch2(aref_field, $1, escape_Qundef($3)); %*/ } - | primary_value '.' tIDENTIFIER + | primary_value call_op tIDENTIFIER { /*%%%*/ $$ = attrset($1, $3); /*% - $$ = dispatch3(field, $1, ripper_id2sym('.'), $3); + $$ = dispatch3(field, $1, ripper_id2sym($2), $3); %*/ } | primary_value tCOLON2 tIDENTIFIER @@ -1729,12 +1733,12 @@ mlhs_node : user_variable $$ = dispatch2(const_path_field, $1, $3); %*/ } - | primary_value '.' tCONSTANT + | primary_value call_op tCONSTANT { /*%%%*/ $$ = attrset($1, $3); /*% - $$ = dispatch3(field, $1, ripper_id2sym('.'), $3); + $$ = dispatch3(field, $1, ripper_id2sym($2), $3); %*/ } | primary_value tCOLON2 tCONSTANT @@ -1804,12 +1808,12 @@ lhs : user_variable $$ = dispatch2(aref_field, $1, escape_Qundef($3)); %*/ } - | primary_value '.' tIDENTIFIER + | primary_value call_op tIDENTIFIER { /*%%%*/ $$ = attrset($1, $3); /*% - $$ = dispatch3(field, $1, ripper_id2sym('.'), $3); + $$ = dispatch3(field, $1, ripper_id2sym($2), $3); %*/ } | primary_value tCOLON2 tIDENTIFIER @@ -1820,12 +1824,12 @@ lhs : user_variable $$ = dispatch3(field, $1, ID2SYM(idCOLON2), $3); %*/ } - | primary_value '.' tCONSTANT + | primary_value call_op tCONSTANT { /*%%%*/ $$ = attrset($1, $3); /*% - $$ = dispatch3(field, $1, ripper_id2sym('.'), $3); + $$ = dispatch3(field, $1, ripper_id2sym($2), $3); %*/ } | primary_value tCOLON2 tCONSTANT @@ -2064,15 +2068,15 @@ arg : lhs '=' arg $$ = dispatch3(opassign, $1, $5, $6); %*/ } - | primary_value '.' tIDENTIFIER tOP_ASGN arg + | primary_value call_op tIDENTIFIER tOP_ASGN arg { value_expr($5); - $$ = new_attr_op_assign($1, '.', $3, $4, $5); + $$ = new_attr_op_assign($1, $2, $3, $4, $5); } - | primary_value '.' tCONSTANT tOP_ASGN arg + | primary_value call_op tCONSTANT tOP_ASGN arg { value_expr($5); - $$ = new_attr_op_assign($1, '.', $3, $4, $5); + $$ = new_attr_op_assign($1, $2, $3, $4, $5); } | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg { @@ -3648,7 +3652,7 @@ method_call : fcall paren_args $$ = method_arg(dispatch1(fcall, $1), $2); %*/ } - | primary_value '.' operation2 + | primary_value call_op operation2 { /*%%%*/ $<num>$ = ruby_sourceline; @@ -3657,10 +3661,10 @@ method_call : fcall paren_args opt_paren_args { /*%%%*/ - $$ = NEW_CALL($1, $3, $5); + $$ = NEW_QCALL($2, $1, $3, $5); nd_set_line($$, $<num>4); /*% - $$ = dispatch3(call, $1, ripper_id2sym('.'), $3); + $$ = dispatch3(call, $1, ripper_id2sym($2), $3); $$ = method_optarg($$, $5); %*/ } @@ -3688,7 +3692,7 @@ method_call : fcall paren_args $$ = dispatch3(call, $1, ID2SYM(idCOLON2), $3); %*/ } - | primary_value '.' + | primary_value call_op { /*%%%*/ $<num>$ = ruby_sourceline; @@ -3697,10 +3701,10 @@ method_call : fcall paren_args paren_args { /*%%%*/ - $$ = NEW_CALL($1, idCall, $4); + $$ = NEW_QCALL($2, $1, idCall, $4); nd_set_line($$, $<num>3); /*% - $$ = dispatch3(call, $1, ripper_id2sym('.'), + $$ = dispatch3(call, $1, ripper_id2sym($2), ID2SYM(idCall)); $$ = method_optarg($$, $4); %*/ @@ -5103,7 +5107,7 @@ operation3 : tIDENTIFIER | op ; -dot_or_colon : '.' +dot_or_colon : call_op /*%c%*/ /*%c { $$ = $<val>1; } @@ -5115,6 +5119,10 @@ dot_or_colon : '.' %*/ ; +call_op : '.' {$$ = '.';} + | tDOTQ {$$ = tDOTQ;} + ; + opt_terms : /* none */ | terms ; @@ -8356,6 +8364,10 @@ parser_yylex(struct parser_params *parser) pushback(c); return tDOT2; } + if (c == '?') { + lex_state = EXPR_DOT; + return tDOTQ; + } pushback(c); if (c != -1 && ISDIGIT(c)) { yyerror("no .<digit> floating literal anymore; put 0 before dot"); @@ -10036,7 +10048,8 @@ new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs) } static NODE * -new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs) +new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, + ID atype, ID attr, ID op, NODE *rhs) { NODE *asgn; @@ -10046,7 +10059,7 @@ new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, else if (op == tANDOP) { op = 1; } - asgn = NEW_OP_ASGN2(lhs, attr, op, rhs); + asgn = NEW_OP_ASGN2(lhs, (atype == tDOTQ), attr, op, rhs); fixpos(asgn, lhs); return asgn; } |