diff options
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 152 |
1 files changed, 84 insertions, 68 deletions
@@ -758,7 +758,8 @@ static void token_info_pop(struct parser_params*, const char *token, const rb_co static void token_info_warn(struct parser_params *p, const char *token, token_info *ptinfo_beg, int same, const rb_code_location_t *loc); %} -%pure-parser +%expect 0 +%define api.pure %lex-param {struct parser_params *p} %parse-param {struct parser_params *p} %initial-action @@ -1211,7 +1212,6 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem command_asgn : lhs '=' command_rhs { /*%%%*/ - value_expr($3); $$ = node_assign(p, $1, $3, &@$); /*% %*/ /*% ripper: assign!($1, $3) %*/ @@ -1219,7 +1219,6 @@ command_asgn : lhs '=' command_rhs | var_lhs tOP_ASGN command_rhs { /*%%%*/ - value_expr($3); $$ = new_op_assign(p, $1, $2, $3, &@$); /*% %*/ /*% ripper: opassign!($1, $2, $3) %*/ @@ -1227,7 +1226,6 @@ command_asgn : lhs '=' command_rhs | primary_value '[' opt_call_args rbracket tOP_ASGN command_rhs { /*%%%*/ - value_expr($6); $$ = new_ary_op_assign(p, $1, $3, $5, $6, &@3, &@$); /*% %*/ /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $6) %*/ @@ -1236,7 +1234,6 @@ command_asgn : lhs '=' command_rhs | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs { /*%%%*/ - value_expr($5); $$ = new_attr_op_assign(p, $1, $2, $3, $4, $5, &@$); /*% %*/ /*% ripper: opassign!(field!($1, $2, $3), $4, $5) %*/ @@ -1244,7 +1241,6 @@ command_asgn : lhs '=' command_rhs | primary_value call_op tCONSTANT tOP_ASGN command_rhs { /*%%%*/ - value_expr($5); $$ = new_attr_op_assign(p, $1, $2, $3, $4, $5, &@$); /*% %*/ /*% ripper: opassign!(field!($1, $2, $3), $4, $5) %*/ @@ -1260,7 +1256,6 @@ command_asgn : lhs '=' command_rhs | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs { /*%%%*/ - value_expr($5); $$ = new_attr_op_assign(p, $1, ID2VAL(idCOLON2), $3, $4, $5, &@$); /*% %*/ /*% ripper: opassign!(field!($1, ID2VAL(idCOLON2), $3), $4, $5) %*/ @@ -4446,7 +4441,7 @@ none : /* none */ # define yylval (*p->lval) static int regx_options(struct parser_params*); -static int tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**); +static int tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**,rb_encoding**); static void tokaddmbc(struct parser_params *p, int c, rb_encoding *enc); static enum yytokentype parse_string(struct parser_params*,rb_strterm_literal_t*); static enum yytokentype here_document(struct parser_params*,rb_strterm_heredoc_t*); @@ -4941,7 +4936,7 @@ yycompile(VALUE vparser, struct parser_params *p, VALUE fname, int line) p->ruby_sourcefile = "(none)"; } else { - p->ruby_sourcefile_string = rb_str_new_frozen(fname); + p->ruby_sourcefile_string = rb_fstring(fname); p->ruby_sourcefile = StringValueCStr(fname); } p->ruby_sourceline = line - 1; @@ -5659,32 +5654,38 @@ parser_update_heredoc_indent(struct parser_params *p, int c) return FALSE; } +static void +parser_mixed_error(struct parser_params *p, rb_encoding *enc1, rb_encoding *enc2) +{ + static const char mixed_msg[] = "%s mixed within %s source"; + const char *n1 = rb_enc_name(enc1), *n2 = rb_enc_name(enc2); + const size_t len = sizeof(mixed_msg) - 4 + strlen(n1) + strlen(n2); + char *errbuf = ALLOCA_N(char, len); + snprintf(errbuf, len, mixed_msg, n1, n2); + yyerror0(errbuf); +} + +static void +parser_mixed_escape(struct parser_params *p, const char *beg, rb_encoding *enc1, rb_encoding *enc2) +{ + const char *pos = p->lex.pcur; + p->lex.pcur = beg; + parser_mixed_error(p, enc1, enc2); + p->lex.pcur = pos; +} + static int tokadd_string(struct parser_params *p, int func, int term, int paren, long *nest, - rb_encoding **encp) + rb_encoding **encp, rb_encoding **enc) { int c; - rb_encoding *enc = 0; - char *errbuf = 0; - static const char mixed_msg[] = "%s mixed within %s source"; + bool erred = false; -#define mixed_error(enc1, enc2) if (!errbuf) { \ - size_t len = sizeof(mixed_msg) - 4; \ - len += strlen(rb_enc_name(enc1)); \ - len += strlen(rb_enc_name(enc2)); \ - errbuf = ALLOCA_N(char, len); \ - snprintf(errbuf, len, mixed_msg, \ - rb_enc_name(enc1), \ - rb_enc_name(enc2)); \ - yyerror0(errbuf); \ - } -#define mixed_escape(beg, enc1, enc2) do { \ - const char *pos = p->lex.pcur; \ - p->lex.pcur = (beg); \ - mixed_error((enc1), (enc2)); \ - p->lex.pcur = pos; \ - } while (0) +#define mixed_error(enc1, enc2) \ + (void)(erred || (parser_mixed_error(p, enc1, enc2), erred = true)) +#define mixed_escape(beg, enc1, enc2) \ + (void)(erred || (parser_mixed_escape(p, beg, enc1, enc2), erred = true)) while ((c = nextc(p)) != -1) { if (p->heredoc_indent > 0) { @@ -5734,7 +5735,7 @@ tokadd_string(struct parser_params *p, tokadd(p, '\\'); break; } - if (!parser_tokadd_utf8(p, &enc, term, + if (!parser_tokadd_utf8(p, enc, term, func & STR_FUNC_SYMBOL, func & STR_FUNC_REGEXP)) { return -1; @@ -5753,17 +5754,17 @@ tokadd_string(struct parser_params *p, continue; } pushback(p, c); - if ((c = tokadd_escape(p, &enc)) < 0) + if ((c = tokadd_escape(p, enc)) < 0) return -1; - if (enc && enc != *encp) { - mixed_escape(p->lex.ptok+2, enc, *encp); + if (*enc && *enc != *encp) { + mixed_escape(p->lex.ptok+2, *enc, *encp); } continue; } else if (func & STR_FUNC_EXPAND) { pushback(p, c); if (func & STR_FUNC_ESCAPE) tokadd(p, '\\'); - c = read_escape(p, 0, &enc); + c = read_escape(p, 0, enc); } else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) { /* ignore backslashed spaces in %w */ @@ -5777,11 +5778,11 @@ tokadd_string(struct parser_params *p, } else if (!parser_isascii(p)) { non_ascii: - if (!enc) { - enc = *encp; + if (!*enc) { + *enc = *encp; } - else if (enc != *encp) { - mixed_error(enc, *encp); + else if (*enc != *encp) { + mixed_error(*enc, *encp); continue; } if (tokadd_mbchar(p, c) == -1) return -1; @@ -5792,18 +5793,18 @@ tokadd_string(struct parser_params *p, break; } if (c & 0x80) { - if (!enc) { - enc = *encp; + if (!*enc) { + *enc = *encp; } - else if (enc != *encp) { - mixed_error(enc, *encp); + else if (*enc != *encp) { + mixed_error(*enc, *encp); continue; } } tokadd(p, c); } terminate: - if (enc) *encp = enc; + if (*enc) *encp = *enc; return c; } @@ -5936,6 +5937,7 @@ parse_string(struct parser_params *p, rb_strterm_literal_t *quote) int paren = (int)quote->u2.paren; int c, space = 0; rb_encoding *enc = p->enc; + rb_encoding *base_enc = 0; VALUE lit; if (func & STR_FUNC_TERM) { @@ -5976,7 +5978,7 @@ parse_string(struct parser_params *p, rb_strterm_literal_t *quote) } pushback(p, c); if (tokadd_string(p, func, term, paren, "e->u0.nest, - &enc) == -1) { + &enc, &base_enc) == -1) { if (p->eofp) { #ifndef RIPPER # define unterminated_literal(mesg) yyerror0(mesg) @@ -6341,6 +6343,7 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here) long len; VALUE str = 0; rb_encoding *enc = p->enc; + rb_encoding *base_enc = 0; int bol; eos = RSTRING_PTR(here->term); @@ -6452,7 +6455,8 @@ here_document(struct parser_params *p, rb_strterm_heredoc_t *here) } do { pushback(p, c); - if ((c = tokadd_string(p, func, '\n', 0, NULL, &enc)) == -1) { + enc = p->enc; + if ((c = tokadd_string(p, func, '\n', 0, NULL, &enc, &base_enc)) == -1) { if (p->eofp) goto error; goto restore; } @@ -8310,16 +8314,17 @@ yylex(YYSTYPE *lval, YYLTYPE *yylloc, struct parser_params *p) p->lval = lval; lval->val = Qundef; t = parser_yylex(p); - if (has_delayed_token(p)) - dispatch_delayed_token(p, t); - else if (t != 0) - dispatch_scan_event(p, t); if (p->lex.strterm && (p->lex.strterm->flags & STRTERM_HEREDOC)) RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC(*yylloc); else RUBY_SET_YYLLOC(*yylloc); + if (has_delayed_token(p)) + dispatch_delayed_token(p, t); + else if (t != 0) + dispatch_scan_event(p, t); + return t; } @@ -9134,7 +9139,7 @@ parser_token_value_print(struct parser_params *p, enum yytokentype type, const Y #ifndef RIPPER v = rb_id2str(valp->id); #else - v = valp->val; + v = valp->node->nd_rval; #endif rb_parser_printf(p, "%"PRIsVALUE, v); break; @@ -9475,10 +9480,10 @@ node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, const YYLTYPE *loc) return lhs; } -static int -value_expr_gen(struct parser_params *p, NODE *node) +static NODE * +value_expr_check(struct parser_params *p, NODE *node) { - int cond = 0; + NODE *void_node = 0, *vn; if (!node) { rb_warning0("empty expression"); @@ -9490,9 +9495,7 @@ value_expr_gen(struct parser_params *p, NODE *node) case NODE_NEXT: case NODE_REDO: case NODE_RETRY: - if (!cond) yyerror1(&node->nd_loc, "void value expression"); - /* or "control never reach"? */ - return FALSE; + return void_node ? void_node : node; case NODE_BLOCK: while (node->nd_next) { @@ -9515,14 +9518,15 @@ value_expr_gen(struct parser_params *p, NODE *node) node = node->nd_body; break; } - if (!value_expr(node->nd_body)) return FALSE; + vn = value_expr_check(p, node->nd_body); + if (!vn) return NULL; + if (!void_node) void_node = vn; node = node->nd_else; break; case NODE_AND: case NODE_OR: - cond = 1; - node = node->nd_2nd; + node = node->nd_1st; break; case NODE_LASGN: @@ -9530,13 +9534,25 @@ value_expr_gen(struct parser_params *p, NODE *node) case NODE_DASGN_CURR: case NODE_MASGN: mark_lvar_used(p, node); - return TRUE; + return NULL; default: - return TRUE; + return NULL; } } + return NULL; +} + +static int +value_expr_gen(struct parser_params *p, NODE *node) +{ + NODE *void_node = value_expr_check(p, node); + if (void_node) { + yyerror1(&void_node->nd_loc, "void value expression"); + /* or "control never reach"? */ + return FALSE; + } return TRUE; } @@ -9852,10 +9868,8 @@ cond0(struct parser_params *p, NODE *node, int method_op, const YYLTYPE *loc) case NODE_DOT3: node->nd_beg = range_op(p, node->nd_beg, loc); node->nd_end = range_op(p, node->nd_end, loc); - if (nd_type(node) == NODE_DOT2 || nd_type(node) == NODE_DOT3) { - nd_set_type(node, nd_type(node) == NODE_DOT2 ? NODE_FLIP2 : NODE_FLIP3); - parser_warn(p, node, "flip-flop is deprecated"); - } + if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2); + else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3); if (!method_op && !e_option_supplied(p)) { int b = literal_node(node->nd_beg); int e = literal_node(node->nd_end); @@ -10670,12 +10684,13 @@ reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end, NODE *node, *succ; if (!len) return ST_CONTINUE; - if (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) - return ST_CONTINUE; if (rb_enc_symname_type(s, len, enc, (1U<<ID_LOCAL)) != ID_LOCAL) return ST_CONTINUE; var = intern_cstr(s, len, enc); + if (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) { + if (!lvar_defined(p, var)) return ST_CONTINUE; + } node = node_assign(p, assignable(p, var, 0, arg->loc), NEW_LIT(ID2SYM(var), arg->loc), arg->loc); succ = arg->succ_block; if (!succ) succ = NEW_BEGIN(0, arg->loc); @@ -10810,8 +10825,9 @@ rb_init_parse(void) static ID internal_id(struct parser_params *p) { + const ID max_id = RB_ID_SERIAL_MAX & ~0xffff; ID id = (ID)vtable_size(p->lvtbl->args) + (ID)vtable_size(p->lvtbl->vars); - id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1; + id = max_id - id; return ID_STATIC_SYM | ID_INTERNAL | (id << ID_SCOPE_SHIFT); } |