1 /**********************************************************************
6 created at: Fri May 28 18:02:42 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
10 **********************************************************************/
15 #define PARSER_DEBUG 0
18 #define YYERROR_VERBOSE 1
19 #define YYSTACK_USE_ALLOCA 0
21 #include "ruby/ruby.h"
23 #include "ruby/encoding.h"
34 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
36 #define YYMALLOC(size) rb_parser_malloc(parser, (size))
37 #define YYREALLOC(ptr, size) rb_parser_realloc(parser, (ptr), (size))
38 #define YYCALLOC(nelem, size) rb_parser_calloc(parser, (nelem), (size))
39 #define YYFREE(ptr) rb_parser_free(parser, (ptr))
40 #define malloc YYMALLOC
41 #define realloc YYREALLOC
42 #define calloc YYCALLOC
46 static ID register_symid(ID, const char *, long, rb_encoding *);
47 static ID register_symid_str(ID, VALUE);
48 #define REGISTER_SYMID(id, name) register_symid((id), (name), strlen(name), enc)
52 #define is_notop_id(id) ((id)>tLAST_OP_ID)
53 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
54 #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
55 #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
56 #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
57 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
58 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
59 #define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
60 #define id_type(id) (is_notop_id(id) ? (int)((id)&ID_SCOPE_MASK) : -1)
62 #define is_asgn_or_id(id) ((is_notop_id(id)) && \
63 (((id)&ID_SCOPE_MASK) == ID_GLOBAL || \
64 ((id)&ID_SCOPE_MASK) == ID_INSTANCE || \
65 ((id)&ID_SCOPE_MASK) == ID_CLASS))
68 EXPR_BEG_bit, /* ignore newline, +/- is a sign. */
69 EXPR_END_bit, /* newline significant, +/- is an operator. */
70 EXPR_ENDARG_bit, /* ditto, and unbound braces. */
71 EXPR_ENDFN_bit, /* ditto, and unbound braces. */
72 EXPR_ARG_bit, /* newline significant, +/- is an operator. */
73 EXPR_CMDARG_bit, /* newline significant, +/- is an operator. */
74 EXPR_MID_bit, /* newline significant, +/- is an operator. */
75 EXPR_FNAME_bit, /* ignore newline, no reserved words. */
76 EXPR_DOT_bit, /* right after `.' or `::', no reserved words. */
77 EXPR_CLASS_bit, /* immediate after `class', no here document. */
78 EXPR_VALUE_bit, /* alike EXPR_BEG but label is disallowed. */
81 /* examine combinations */
83 #define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
95 EXPR_BEG_ANY = (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS),
96 EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
97 EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
99 #define IS_lex_state_for(x, ls) ((x) & (ls))
100 #define IS_lex_state(ls) IS_lex_state_for(lex_state, (ls))
103 static const char *lex_state_name(enum lex_state_e state);
106 typedef VALUE stack_type;
108 # define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
109 # define BITSTACK_POP(stack) ((stack) = (stack) >> 1)
110 # define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
111 # define BITSTACK_SET_P(stack) ((stack)&1)
113 #define COND_PUSH(n) BITSTACK_PUSH(cond_stack, (n))
114 #define COND_POP() BITSTACK_POP(cond_stack)
115 #define COND_LEXPOP() BITSTACK_LEXPOP(cond_stack)
116 #define COND_P() BITSTACK_SET_P(cond_stack)
118 #define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, (n))
119 #define CMDARG_POP() BITSTACK_POP(cmdarg_stack)
120 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
121 #define CMDARG_P() BITSTACK_SET_P(cmdarg_stack)
134 struct local_vars *prev;
137 #define DVARS_INHERIT ((void*)1)
138 #define DVARS_TOPSCOPE NULL
139 #define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
140 #define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
143 vtable_size(const struct vtable *tbl)
145 if (POINTER_P(tbl)) {
155 static struct vtable *
156 vtable_alloc(struct vtable *prev)
158 struct vtable *tbl = ALLOC(struct vtable);
161 tbl->tbl = ALLOC_N(ID, tbl->capa);
163 if (VTBL_DEBUG) printf("vtable_alloc: %p\n", (void *)tbl);
168 vtable_free(struct vtable *tbl)
170 if (VTBL_DEBUG)printf("vtable_free: %p\n", (void *)tbl);
171 if (POINTER_P(tbl)) {
180 vtable_add(struct vtable *tbl, ID id)
182 if (!POINTER_P(tbl)) {
183 rb_bug("vtable_add: vtable is not allocated (%p)", (void *)tbl);
185 if (VTBL_DEBUG) printf("vtable_add: %p, %s\n", (void *)tbl, rb_id2name(id));
187 if (tbl->pos == tbl->capa) {
188 tbl->capa = tbl->capa * 2;
189 REALLOC_N(tbl->tbl, ID, tbl->capa);
191 tbl->tbl[tbl->pos++] = id;
195 vtable_included(const struct vtable * tbl, ID id)
199 if (POINTER_P(tbl)) {
200 for (i = 0; i < tbl->pos; i++) {
201 if (tbl->tbl[i] == id) {
211 typedef struct token_info {
216 struct token_info *next;
221 Structure of Lexer Buffer:
223 lex_pbeg tokp lex_p lex_pend
225 |-----------+--------------+------------|
229 struct parser_params {
233 YYSTYPE *parser_yylval;
236 NODE *parser_lex_strterm;
237 enum lex_state_e parser_lex_state;
238 stack_type parser_cond_stack;
239 stack_type parser_cmdarg_stack;
240 int parser_class_nest;
241 int parser_paren_nest;
243 int parser_in_single;
245 int parser_brace_nest;
246 int parser_compile_for_eval;
247 VALUE parser_cur_mid;
248 int parser_in_defined;
249 char *parser_tokenbuf;
253 VALUE parser_lex_input;
254 VALUE parser_lex_lastline;
255 VALUE parser_lex_nextline;
256 const char *parser_lex_pbeg;
257 const char *parser_lex_p;
258 const char *parser_lex_pend;
259 int parser_heredoc_end;
260 int parser_command_start;
261 NODE *parser_deferred_nodes;
262 long parser_lex_gets_ptr;
263 VALUE (*parser_lex_gets)(struct parser_params*,VALUE);
264 struct local_vars *parser_lvtbl;
265 int parser_ruby__end__seen;
268 char *parser_ruby_sourcefile; /* current source file */
269 int parser_ruby_sourceline; /* current line no. */
276 NODE *parser_eval_tree_begin;
277 NODE *parser_eval_tree;
282 int parser_token_info_enabled;
283 token_info *parser_token_info;
286 VALUE parser_ruby_sourcefile_string;
294 VALUE parsing_thread;
299 #define STR_NEW(p,n) rb_enc_str_new((p),(n),current_enc)
300 #define STR_NEW0() rb_enc_str_new(0,0,current_enc)
301 #define STR_NEW2(p) rb_enc_str_new((p),strlen(p),current_enc)
302 #define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),current_enc)
303 #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT)
304 #define TOK_INTERN(mb) rb_intern3(tok(), toklen(), current_enc)
306 static int parser_yyerror(struct parser_params*, const char*);
307 #define yyerror(msg) parser_yyerror(parser, (msg))
309 #define lex_strterm (parser->parser_lex_strterm)
310 #define lex_state (parser->parser_lex_state)
311 #define cond_stack (parser->parser_cond_stack)
312 #define cmdarg_stack (parser->parser_cmdarg_stack)
313 #define class_nest (parser->parser_class_nest)
314 #define paren_nest (parser->parser_paren_nest)
315 #define lpar_beg (parser->parser_lpar_beg)
316 #define brace_nest (parser->parser_brace_nest)
317 #define in_single (parser->parser_in_single)
318 #define in_def (parser->parser_in_def)
319 #define compile_for_eval (parser->parser_compile_for_eval)
320 #define cur_mid (parser->parser_cur_mid)
321 #define in_defined (parser->parser_in_defined)
322 #define tokenbuf (parser->parser_tokenbuf)
323 #define tokidx (parser->parser_tokidx)
324 #define toksiz (parser->parser_toksiz)
325 #define tokline (parser->parser_tokline)
326 #define lex_input (parser->parser_lex_input)
327 #define lex_lastline (parser->parser_lex_lastline)
328 #define lex_nextline (parser->parser_lex_nextline)
329 #define lex_pbeg (parser->parser_lex_pbeg)
330 #define lex_p (parser->parser_lex_p)
331 #define lex_pend (parser->parser_lex_pend)
332 #define heredoc_end (parser->parser_heredoc_end)
333 #define command_start (parser->parser_command_start)
334 #define deferred_nodes (parser->parser_deferred_nodes)
335 #define lex_gets_ptr (parser->parser_lex_gets_ptr)
336 #define lex_gets (parser->parser_lex_gets)
337 #define lvtbl (parser->parser_lvtbl)
338 #define ruby__end__seen (parser->parser_ruby__end__seen)
339 #define ruby_sourceline (parser->parser_ruby_sourceline)
340 #define ruby_sourcefile (parser->parser_ruby_sourcefile)
341 #define current_enc (parser->enc)
342 #define yydebug (parser->parser_yydebug)
345 #define ruby_eval_tree (parser->parser_eval_tree)
346 #define ruby_eval_tree_begin (parser->parser_eval_tree_begin)
347 #define ruby_debug_lines (parser->debug_lines)
348 #define ruby_coverage (parser->coverage)
352 static int yylex(void*, void*);
354 static int yylex(void*);
358 #define yyparse ruby_yyparse
360 static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE);
361 #define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, (type), (a1), (a2), (a3))
363 static NODE *cond_gen(struct parser_params*,NODE*);
364 #define cond(node) cond_gen(parser, (node))
365 static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
366 #define logop(type,node1,node2) logop_gen(parser, (type), (node1), (node2))
368 static NODE *newline_node(NODE*);
369 static void fixpos(NODE*,NODE*);
371 static int value_expr_gen(struct parser_params*,NODE*);
372 static void void_expr_gen(struct parser_params*,NODE*);
373 static NODE *remove_begin(NODE*);
374 #define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
375 #define void_expr0(node) void_expr_gen(parser, (node))
376 #define void_expr(node) void_expr0((node) = remove_begin(node))
377 static void void_stmts_gen(struct parser_params*,NODE*);
378 #define void_stmts(node) void_stmts_gen(parser, (node))
379 static void reduce_nodes_gen(struct parser_params*,NODE**);
380 #define reduce_nodes(n) reduce_nodes_gen(parser,(n))
381 static void block_dup_check_gen(struct parser_params*,NODE*,NODE*);
382 #define block_dup_check(n1,n2) block_dup_check_gen(parser,(n1),(n2))
384 static NODE *block_append_gen(struct parser_params*,NODE*,NODE*);
385 #define block_append(h,t) block_append_gen(parser,(h),(t))
386 static NODE *list_append_gen(struct parser_params*,NODE*,NODE*);
387 #define list_append(l,i) list_append_gen(parser,(l),(i))
388 static NODE *list_concat_gen(struct parser_params*,NODE*,NODE*);
389 #define list_concat(h,t) list_concat_gen(parser,(h),(t))
390 static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*);
391 #define arg_append(h,t) arg_append_gen(parser,(h),(t))
392 static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
393 #define arg_concat(h,t) arg_concat_gen(parser,(h),(t))
394 static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
395 #define literal_concat(h,t) literal_concat_gen(parser,(h),(t))
396 static int literal_concat0(struct parser_params *, VALUE, VALUE);
397 static NODE *new_evstr_gen(struct parser_params*,NODE*);
398 #define new_evstr(n) new_evstr_gen(parser,(n))
399 static NODE *evstr2dstr_gen(struct parser_params*,NODE*);
400 #define evstr2dstr(n) evstr2dstr_gen(parser,(n))
401 static NODE *splat_array(NODE*);
403 static NODE *call_bin_op_gen(struct parser_params*,NODE*,ID,NODE*);
404 #define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, (recv),(id),(arg1))
405 static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID);
406 #define call_uni_op(recv,id) call_uni_op_gen(parser, (recv),(id))
408 static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*);
409 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
410 static NODE *new_args_tail_gen(struct parser_params*,NODE*,ID,ID);
411 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
413 static NODE *negate_lit(NODE*);
414 static NODE *ret_args_gen(struct parser_params*,NODE*);
415 #define ret_args(node) ret_args_gen(parser, (node))
416 static NODE *arg_blk_pass(NODE*,NODE*);
417 static NODE *new_yield_gen(struct parser_params*,NODE*);
418 #define new_yield(node) new_yield_gen(parser, (node))
419 static NODE *dsym_node_gen(struct parser_params*,NODE*);
420 #define dsym_node(node) dsym_node_gen(parser, (node))
422 static NODE *gettable_gen(struct parser_params*,ID);
423 #define gettable(id) gettable_gen(parser,(id))
424 static NODE *assignable_gen(struct parser_params*,ID,NODE*);
425 #define assignable(id,node) assignable_gen(parser, (id), (node))
427 static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
428 #define aryset(node1,node2) aryset_gen(parser, (node1), (node2))
429 static NODE *attrset_gen(struct parser_params*,NODE*,ID);
430 #define attrset(node,id) attrset_gen(parser, (node), (id))
432 static void rb_backref_error_gen(struct parser_params*,NODE*);
433 #define rb_backref_error(n) rb_backref_error_gen(parser,(n))
434 static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
435 #define node_assign(node1, node2) node_assign_gen(parser, (node1), (node2))
437 static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
438 static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs);
439 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (attr), (op), (rhs))
440 static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
441 #define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs))
443 static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
444 #define match_op(node1,node2) match_op_gen(parser, (node1), (node2))
446 static ID *local_tbl_gen(struct parser_params*);
447 #define local_tbl() local_tbl_gen(parser)
449 static void fixup_nodes(NODE **);
451 static VALUE reg_compile_gen(struct parser_params*, VALUE, int);
452 #define reg_compile(str,options) reg_compile_gen(parser, (str), (options))
453 static void reg_fragment_setenc_gen(struct parser_params*, VALUE, int);
454 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, (str), (options))
455 static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
456 #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, (str), (options))
457 static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match);
458 #define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
460 #define get_id(id) (id)
461 #define get_value(val) (val)
463 #define value_expr(node) ((void)(node))
464 #define remove_begin(node) (node)
465 #define rb_dvar_defined(id) 0
466 #define rb_local_defined(id) 0
467 static ID ripper_get_id(VALUE);
468 #define get_id(id) ripper_get_id(id)
469 static VALUE ripper_get_value(VALUE);
470 #define get_value(val) ripper_get_value(val)
471 static VALUE assignable_gen(struct parser_params*,VALUE);
472 #define assignable(lhs,node) assignable_gen(parser, (lhs))
473 static int id_is_var_gen(struct parser_params *parser, ID id);
474 #define id_is_var(id) id_is_var_gen(parser, (id))
476 #define node_assign(node1, node2) dispatch2(assign, (node1), (node2))
478 static VALUE new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs);
479 static VALUE new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs);
480 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs))
484 #define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs))
486 static ID formal_argument_gen(struct parser_params*, ID);
487 #define formal_argument(id) formal_argument_gen(parser, (id))
488 static ID shadowing_lvar_gen(struct parser_params*,ID);
489 #define shadowing_lvar(name) shadowing_lvar_gen(parser, (name))
490 static void new_bv_gen(struct parser_params*,ID);
491 #define new_bv(id) new_bv_gen(parser, (id))
493 static void local_push_gen(struct parser_params*,int);
494 #define local_push(top) local_push_gen(parser,(top))
495 static void local_pop_gen(struct parser_params*);
496 #define local_pop() local_pop_gen(parser)
497 static int local_var_gen(struct parser_params*, ID);
498 #define local_var(id) local_var_gen(parser, (id))
499 static int arg_var_gen(struct parser_params*, ID);
500 #define arg_var(id) arg_var_gen(parser, (id))
501 static int local_id_gen(struct parser_params*, ID);
502 #define local_id(id) local_id_gen(parser, (id))
503 static ID internal_id_gen(struct parser_params*);
504 #define internal_id() internal_id_gen(parser)
506 static const struct vtable *dyna_push_gen(struct parser_params *);
507 #define dyna_push() dyna_push_gen(parser)
508 static void dyna_pop_gen(struct parser_params*, const struct vtable *);
509 #define dyna_pop(node) dyna_pop_gen(parser, (node))
510 static int dyna_in_block_gen(struct parser_params*);
511 #define dyna_in_block() dyna_in_block_gen(parser)
512 #define dyna_var(id) local_var(id)
513 static int dvar_defined_gen(struct parser_params*,ID,int);
514 #define dvar_defined(id) dvar_defined_gen(parser, (id), 0)
515 #define dvar_defined_get(id) dvar_defined_gen(parser, (id), 1)
516 static int dvar_curr_gen(struct parser_params*,ID);
517 #define dvar_curr(id) dvar_curr_gen(parser, (id))
519 static int lvar_defined_gen(struct parser_params*, ID);
520 #define lvar_defined(id) lvar_defined_gen(parser, (id))
522 #define RE_OPTION_ONCE (1<<16)
523 #define RE_OPTION_ENCODING_SHIFT 8
524 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
525 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
526 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
527 #define RE_OPTION_MASK 0xff
528 #define RE_OPTION_ARG_ENCODING_NONE 32
530 #define NODE_STRTERM NODE_ZARRAY /* nothing to gc */
531 #define NODE_HEREDOC NODE_ARRAY /* 1, 3 to gc */
532 #define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
533 #define nd_func u1.id
534 #if SIZEOF_SHORT == 2
535 #define nd_term(node) ((signed short)(node)->u2.id)
537 #define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
539 #define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
540 #define nd_nest u3.cnt
542 /****** Ripper *******/
545 #define RIPPER_VERSION "0.1.0"
547 #include "eventids1.c"
548 #include "eventids2.c"
550 static VALUE ripper_dispatch0(struct parser_params*,ID);
551 static VALUE ripper_dispatch1(struct parser_params*,ID,VALUE);
552 static VALUE ripper_dispatch2(struct parser_params*,ID,VALUE,VALUE);
553 static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
554 static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
555 static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
556 static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
558 #define dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
559 #define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
560 #define dispatch2(n,a,b) ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), (a), (b))
561 #define dispatch3(n,a,b,c) ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
562 #define dispatch4(n,a,b,c,d) ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
563 #define dispatch5(n,a,b,c,d,e) ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
564 #define dispatch7(n,a,b,c,d,e,f,g) ripper_dispatch7(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e), (f), (g))
566 #define yyparse ripper_yyparse
568 #define ripper_intern(s) ID2SYM(rb_intern(s))
569 static VALUE ripper_id2sym(ID);
571 #define ripper_id2sym(id) ((id) < 256 && rb_ispunct(id) ? \
572 ID2SYM(id) : ripper_id2sym(id))
575 #define arg_new() dispatch0(args_new)
576 #define arg_add(l,a) dispatch2(args_add, (l), (a))
577 #define arg_add_star(l,a) dispatch2(args_add_star, (l), (a))
578 #define arg_add_block(l,b) dispatch2(args_add_block, (l), (b))
579 #define arg_add_optblock(l,b) ((b)==Qundef? (l) : dispatch2(args_add_block, (l), (b)))
580 #define bare_assoc(v) dispatch1(bare_assoc_hash, (v))
581 #define arg_add_assocs(l,b) arg_add((l), bare_assoc(b))
583 #define args2mrhs(a) dispatch1(mrhs_new_from_args, (a))
584 #define mrhs_new() dispatch0(mrhs_new)
585 #define mrhs_add(l,a) dispatch2(mrhs_add, (l), (a))
586 #define mrhs_add_star(l,a) dispatch2(mrhs_add_star, (l), (a))
588 #define mlhs_new() dispatch0(mlhs_new)
589 #define mlhs_add(l,a) dispatch2(mlhs_add, (l), (a))
590 #define mlhs_add_star(l,a) dispatch2(mlhs_add_star, (l), (a))
592 #define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
593 dispatch7(params, (pars), (opts), (rest), (pars2), (kws), (kwrest), (blk))
595 #define blockvar_new(p,v) dispatch2(block_var, (p), (v))
596 #define blockvar_add_star(l,a) dispatch2(block_var_add_star, (l), (a))
597 #define blockvar_add_block(l,a) dispatch2(block_var_add_block, (l), (a))
599 #define method_optarg(m,a) ((a)==Qundef ? (m) : dispatch2(method_add_arg,(m),(a)))
600 #define method_arg(m,a) dispatch2(method_add_arg,(m),(a))
601 #define method_add_block(m,b) dispatch2(method_add_block, (m), (b))
603 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
606 new_args_gen(struct parser_params *parser, VALUE f, VALUE o, VALUE r, VALUE p, VALUE tail)
608 NODE *t = (NODE *)tail;
609 VALUE k = t->u1.value, kr = t->u2.value, b = t->u3.value;
610 return params_new(f, o, r, p, k, kr, escape_Qundef(b));
612 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
615 new_args_tail_gen(struct parser_params *parser, VALUE k, VALUE kr, VALUE b)
617 return (VALUE)rb_node_newnode(NODE_MEMO, k, kr, b);
619 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
627 # define ifndef_ripper(x) (x)
630 # define ifndef_ripper(x)
634 # define rb_warn0(fmt) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt))
635 # define rb_warnI(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
636 # define rb_warnS(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
637 # define rb_warn4S(file,line,fmt,a) rb_compile_warn((file), (line), (fmt), (a))
638 # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt))
639 # define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt), (a))
641 # define rb_warn0(fmt) ripper_warn0(parser, (fmt))
642 # define rb_warnI(fmt,a) ripper_warnI(parser, (fmt), (a))
643 # define rb_warnS(fmt,a) ripper_warnS(parser, (fmt), (a))
644 # define rb_warn4S(file,line,fmt,a) ripper_warnS(parser, (fmt), (a))
645 # define rb_warning0(fmt) ripper_warning0(parser, (fmt))
646 # define rb_warningS(fmt,a) ripper_warningS(parser, (fmt), (a))
647 static void ripper_warn0(struct parser_params*, const char*);
648 static void ripper_warnI(struct parser_params*, const char*, int);
649 static void ripper_warnS(struct parser_params*, const char*, const char*);
650 static void ripper_warning0(struct parser_params*, const char*);
651 static void ripper_warningS(struct parser_params*, const char*, const char*);
655 static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
656 # define rb_compile_error ripper_compile_error
657 # define compile_error ripper_compile_error
658 # define PARSER_ARG parser,
660 # define rb_compile_error rb_compile_error_with_enc
661 # define compile_error parser->nerr++,rb_compile_error_with_enc
662 # define PARSER_ARG ruby_sourcefile, ruby_sourceline, current_enc,
665 /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
666 for instance). This is too low for Ruby to parse some files, such as
667 date/format.rb, therefore bump the value up to at least Bison's default. */
670 #define YYMAXDEPTH 10000
675 static void token_info_push(struct parser_params*, const char *token);
676 static void token_info_pop(struct parser_params*, const char *token);
677 #define token_info_push(token) (RTEST(ruby_verbose) ? token_info_push(parser, (token)) : (void)0)
678 #define token_info_pop(token) (RTEST(ruby_verbose) ? token_info_pop(parser, (token)) : (void)0)
680 #define token_info_push(token) /* nothing */
681 #define token_info_pop(token) /* nothing */
686 %lex-param {struct parser_params *parser}
687 %parse-param {struct parser_params *parser}
694 const struct vtable *vars;
752 %token <val> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
753 %token <val> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
754 %token <val> tNTH_REF tBACK_REF
755 %token <val> tREGEXP_END
757 %type <val> singleton strings string string1 xstring regexp
758 %type <val> string_contents xstring_contents regexp_contents string_content
759 %type <val> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
760 %type <val> literal numeric dsym cpath
761 %type <val> top_compstmt top_stmts top_stmt
762 %type <val> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
763 %type <val> expr_value arg_value primary_value fcall
764 %type <val> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
765 %type <val> args call_args opt_call_args
766 %type <val> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
767 %type <val> command_args aref_args opt_block_arg block_arg var_ref var_lhs
768 %type <val> command_asgn mrhs superclass block_call block_command
769 %type <val> f_block_optarg f_block_opt
770 %type <val> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
771 %type <val> assoc_list assocs assoc undef_list backref string_dvar for_var
772 %type <val> block_param opt_block_param block_param_def f_opt
773 %type <val> f_kwarg f_kw f_block_kwarg f_block_kw
774 %type <val> bv_decls opt_bv_decl bvar
775 %type <val> lambda f_larglist lambda_body
776 %type <val> brace_block cmd_brace_block do_block lhs none fitem
777 %type <val> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
778 %type <val> fsym keyword_variable user_variable sym symbol operation operation2 operation3
779 %type <val> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
783 %type <val> program reswords then do dot_or_colon
785 %token END_OF_INPUT 0 "end-of-input"
786 %token tUPLUS 130 "unary+"
787 %token tUMINUS 131 "unary-"
789 %token tCMP 134 "<=>"
791 %token tEQQ 140 "==="
797 %token tMATCH 142 "=~"
798 %token tNMATCH 143 "!~"
799 %token tDOT2 128 ".."
800 %token tDOT3 129 "..."
801 %token tAREF 144 "[]"
802 %token tASET 145 "[]="
803 %token tLSHFT 135 "<<"
804 %token tRSHFT 136 ">>"
806 %token tCOLON3 ":: at EXPR_BEG"
807 %token <val> tOP_ASGN /* +=, -= etc. */
810 %token tLPAREN_ARG "( arg"
814 %token tLBRACE_ARG "{ arg"
816 %token tDSTAR "**arg"
819 %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
820 %token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG
827 %nonassoc tLBRACE_ARG
829 %nonassoc modifier_if modifier_unless modifier_while modifier_until
830 %left keyword_or keyword_and
832 %nonassoc keyword_defined
834 %left modifier_rescue
836 %nonassoc tDOT2 tDOT3
839 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
840 %left '>' tGEQ '<' tLEQ
846 %right tUMINUS_NUM tUMINUS
848 %right '!' '~' tUPLUS
854 lex_state = EXPR_BEG;
856 local_push(compile_for_eval || rb_parse_in_main());
864 if ($2 && !compile_for_eval) {
865 /* last expression should not be void */
866 if (nd_type($2) != NODE_BLOCK) void_expr($2);
869 while (node->nd_next) {
870 node = node->nd_next;
872 void_expr(node->nd_head);
875 ruby_eval_tree = NEW_SCOPE(0, block_append(ruby_eval_tree, $2));
878 parser->result = dispatch1(program, $$);
884 top_compstmt : top_stmts opt_terms
888 fixup_nodes(&deferred_nodes);
900 $$ = dispatch2(stmts_add, dispatch0(stmts_new),
901 dispatch0(void_stmt));
907 $$ = newline_node($1);
909 $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
912 | top_stmts terms top_stmt
915 $$ = block_append($1, newline_node($3));
917 $$ = dispatch2(stmts_add, $1, $3);
922 $$ = remove_begin($2);
937 ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
939 /* NEW_PREEXE($4)); */
943 $$ = dispatch1(BEGIN, $4);
956 $$ = NEW_RESCUE($1, $2, $3);
959 rb_warn0("else without rescue is useless");
960 $$ = block_append($$, $3);
964 $$ = NEW_ENSURE($$, $4);
967 $$ = block_append($4, NEW_NIL());
972 $$ = dispatch4(bodystmt,
981 compstmt : stmts opt_terms
985 fixup_nodes(&deferred_nodes);
997 $$ = dispatch2(stmts_add, dispatch0(stmts_new),
998 dispatch0(void_stmt));
1004 $$ = newline_node($1);
1006 $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
1009 | stmts terms stmt_or_begin
1012 $$ = block_append($1, newline_node($3));
1014 $$ = dispatch2(stmts_add, $1, $3);
1019 $$ = remove_begin($2);
1023 stmt_or_begin : stmt
1029 yyerror("BEGIN is permitted only at toplevel");
1031 /* local_push(0); */
1035 '{' top_compstmt '}'
1038 ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
1040 /* NEW_PREEXE($4)); */
1044 $$ = dispatch1(BEGIN, $4);
1048 stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
1051 $$ = NEW_ALIAS($2, $4);
1053 $$ = dispatch2(alias, $2, $4);
1056 | keyword_alias tGVAR tGVAR
1059 $$ = NEW_VALIAS($2, $3);
1061 $$ = dispatch2(var_alias, $2, $3);
1064 | keyword_alias tGVAR tBACK_REF
1069 buf[1] = (char)$3->nd_nth;
1070 $$ = NEW_VALIAS($2, rb_intern2(buf, 2));
1072 $$ = dispatch2(var_alias, $2, $3);
1075 | keyword_alias tGVAR tNTH_REF
1078 yyerror("can't make alias for the number variables");
1081 $$ = dispatch2(var_alias, $2, $3);
1082 $$ = dispatch1(alias_error, $$);
1085 | keyword_undef undef_list
1090 $$ = dispatch1(undef, $2);
1093 | stmt modifier_if expr_value
1096 $$ = NEW_IF(cond($3), remove_begin($1), 0);
1099 $$ = dispatch2(if_mod, $3, $1);
1102 | stmt modifier_unless expr_value
1105 $$ = NEW_UNLESS(cond($3), remove_begin($1), 0);
1108 $$ = dispatch2(unless_mod, $3, $1);
1111 | stmt modifier_while expr_value
1114 if ($1 && nd_type($1) == NODE_BEGIN) {
1115 $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
1118 $$ = NEW_WHILE(cond($3), $1, 1);
1121 $$ = dispatch2(while_mod, $3, $1);
1124 | stmt modifier_until expr_value
1127 if ($1 && nd_type($1) == NODE_BEGIN) {
1128 $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
1131 $$ = NEW_UNTIL(cond($3), $1, 1);
1134 $$ = dispatch2(until_mod, $3, $1);
1137 | stmt modifier_rescue stmt
1140 NODE *resq = NEW_RESBODY(0, remove_begin($3), 0);
1141 $$ = NEW_RESCUE(remove_begin($1), resq, 0);
1143 $$ = dispatch2(rescue_mod, $1, $3);
1146 | keyword_END '{' compstmt '}'
1148 if (in_def || in_single) {
1149 rb_warn0("END in method; use at_exit");
1152 $$ = NEW_POSTEXE(NEW_NODE(
1153 NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */));
1155 $$ = dispatch1(END, $3);
1159 | mlhs '=' command_call
1166 $$ = dispatch2(massign, $1, $3);
1169 | var_lhs tOP_ASGN command_call
1172 $$ = new_op_assign($1, $2, $3);
1174 | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
1180 if (!$3) $3 = NEW_ZARRAY();
1181 args = arg_concat($3, $6);
1185 else if ($5 == tANDOP) {
1188 $$ = NEW_OP_ASGN1($1, $5, args);
1191 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1192 $$ = dispatch3(opassign, $$, $5, $6);
1195 | primary_value '.' tIDENTIFIER tOP_ASGN command_call
1198 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1200 | primary_value '.' tCONSTANT tOP_ASGN command_call
1203 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1205 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
1208 $$ = NEW_COLON2($1, $3);
1209 $$ = new_const_op_assign($$, $4, $5);
1211 $$ = dispatch2(const_path_field, $1, $3);
1212 $$ = dispatch3(opassign, $$, $4, $5);
1215 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
1218 $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
1220 | backref tOP_ASGN command_call
1223 rb_backref_error($1);
1226 $$ = dispatch2(assign, dispatch1(var_field, $1), $3);
1227 $$ = dispatch1(assign_error, $$);
1234 $$ = node_assign($1, $3);
1236 $$ = dispatch2(assign, $1, $3);
1239 | mlhs '=' arg_value
1245 $$ = dispatch2(massign, $1, $3);
1254 $$ = dispatch2(massign, $1, $3);
1260 command_asgn : lhs '=' command_call
1264 $$ = node_assign($1, $3);
1266 $$ = dispatch2(assign, $1, $3);
1269 | lhs '=' command_asgn
1273 $$ = node_assign($1, $3);
1275 $$ = dispatch2(assign, $1, $3);
1282 | expr keyword_and expr
1285 $$ = logop(NODE_AND, $1, $3);
1287 $$ = dispatch3(binary, $1, ripper_intern("and"), $3);
1290 | expr keyword_or expr
1293 $$ = logop(NODE_OR, $1, $3);
1295 $$ = dispatch3(binary, $1, ripper_intern("or"), $3);
1298 | keyword_not opt_nl expr
1301 $$ = call_uni_op(cond($3), '!');
1303 $$ = dispatch2(unary, ripper_intern("not"), $3);
1309 $$ = call_uni_op(cond($2), '!');
1311 $$ = dispatch2(unary, ripper_id2sym('!'), $2);
1322 if (!$$) $$ = NEW_NIL();
1329 command_call : command
1333 block_command : block_call
1334 | block_call dot_or_colon operation2 command_args
1337 $$ = NEW_CALL($1, $3, $4);
1339 $$ = dispatch3(call, $1, $2, $3);
1340 $$ = method_arg($$, $4);
1345 cmd_brace_block : tLBRACE_ARG
1347 $<vars>1 = dyna_push();
1349 $<num>$ = ruby_sourceline;
1358 $$ = NEW_ITER($3,$4);
1359 nd_set_line($$, $<num>2);
1361 $$ = dispatch2(brace_block, escape_Qundef($3), $4);
1370 $$ = NEW_FCALL($1, 0);
1371 nd_set_line($$, tokline);
1377 command : fcall command_args %prec tLOWEST
1383 $$ = dispatch2(command, $1, $2);
1386 | fcall command_args cmd_brace_block
1389 block_dup_check($2,$3);
1395 $$ = dispatch2(command, $1, $2);
1396 $$ = method_add_block($$, $3);
1399 | primary_value '.' operation2 command_args %prec tLOWEST
1402 $$ = NEW_CALL($1, $3, $4);
1405 $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1408 | primary_value '.' operation2 command_args cmd_brace_block
1411 block_dup_check($4,$5);
1412 $5->nd_iter = NEW_CALL($1, $3, $4);
1416 $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1417 $$ = method_add_block($$, $5);
1420 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1423 $$ = NEW_CALL($1, $3, $4);
1426 $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1429 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1432 block_dup_check($4,$5);
1433 $5->nd_iter = NEW_CALL($1, $3, $4);
1437 $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1438 $$ = method_add_block($$, $5);
1441 | keyword_super command_args
1447 $$ = dispatch1(super, $2);
1450 | keyword_yield command_args
1456 $$ = dispatch1(yield, $2);
1459 | keyword_return call_args
1462 $$ = NEW_RETURN(ret_args($2));
1464 $$ = dispatch1(return, $2);
1467 | keyword_break call_args
1470 $$ = NEW_BREAK(ret_args($2));
1472 $$ = dispatch1(break, $2);
1475 | keyword_next call_args
1478 $$ = NEW_NEXT(ret_args($2));
1480 $$ = dispatch1(next, $2);
1486 | tLPAREN mlhs_inner rparen
1491 $$ = dispatch1(mlhs_paren, $2);
1496 mlhs_inner : mlhs_basic
1497 | tLPAREN mlhs_inner rparen
1500 $$ = NEW_MASGN(NEW_LIST($2), 0);
1502 $$ = dispatch1(mlhs_paren, $2);
1507 mlhs_basic : mlhs_head
1510 $$ = NEW_MASGN($1, 0);
1515 | mlhs_head mlhs_item
1518 $$ = NEW_MASGN(list_append($1,$2), 0);
1520 $$ = mlhs_add($1, $2);
1523 | mlhs_head tSTAR mlhs_node
1526 $$ = NEW_MASGN($1, $3);
1528 $$ = mlhs_add_star($1, $3);
1531 | mlhs_head tSTAR mlhs_node ',' mlhs_post
1534 $$ = NEW_MASGN($1, NEW_POSTARG($3,$5));
1536 $1 = mlhs_add_star($1, $3);
1537 $$ = mlhs_add($1, $5);
1543 $$ = NEW_MASGN($1, -1);
1545 $$ = mlhs_add_star($1, Qnil);
1548 | mlhs_head tSTAR ',' mlhs_post
1551 $$ = NEW_MASGN($1, NEW_POSTARG(-1, $4));
1553 $1 = mlhs_add_star($1, Qnil);
1554 $$ = mlhs_add($1, $4);
1560 $$ = NEW_MASGN(0, $2);
1562 $$ = mlhs_add_star(mlhs_new(), $2);
1565 | tSTAR mlhs_node ',' mlhs_post
1568 $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
1570 $2 = mlhs_add_star(mlhs_new(), $2);
1571 $$ = mlhs_add($2, $4);
1577 $$ = NEW_MASGN(0, -1);
1579 $$ = mlhs_add_star(mlhs_new(), Qnil);
1582 | tSTAR ',' mlhs_post
1585 $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
1587 $$ = mlhs_add_star(mlhs_new(), Qnil);
1588 $$ = mlhs_add($$, $3);
1593 mlhs_item : mlhs_node
1594 | tLPAREN mlhs_inner rparen
1599 $$ = dispatch1(mlhs_paren, $2);
1604 mlhs_head : mlhs_item ','
1609 $$ = mlhs_add(mlhs_new(), $1);
1612 | mlhs_head mlhs_item ','
1615 $$ = list_append($1, $2);
1617 $$ = mlhs_add($1, $2);
1622 mlhs_post : mlhs_item
1627 $$ = mlhs_add(mlhs_new(), $1);
1630 | mlhs_post ',' mlhs_item
1633 $$ = list_append($1, $3);
1635 $$ = mlhs_add($1, $3);
1640 mlhs_node : user_variable
1642 $$ = assignable($1, 0);
1646 $$ = assignable($1, 0);
1648 | primary_value '[' opt_call_args rbracket
1651 $$ = aryset($1, $3);
1653 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1656 | primary_value '.' tIDENTIFIER
1659 $$ = attrset($1, $3);
1661 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1664 | primary_value tCOLON2 tIDENTIFIER
1667 $$ = attrset($1, $3);
1669 $$ = dispatch2(const_path_field, $1, $3);
1672 | primary_value '.' tCONSTANT
1675 $$ = attrset($1, $3);
1677 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1680 | primary_value tCOLON2 tCONSTANT
1683 if (in_def || in_single)
1684 yyerror("dynamic constant assignment");
1685 $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
1687 if (in_def || in_single)
1688 yyerror("dynamic constant assignment");
1689 $$ = dispatch2(const_path_field, $1, $3);
1695 if (in_def || in_single)
1696 yyerror("dynamic constant assignment");
1697 $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
1699 $$ = dispatch1(top_const_field, $2);
1705 rb_backref_error($1);
1708 $$ = dispatch1(var_field, $1);
1709 $$ = dispatch1(assign_error, $$);
1716 $$ = assignable($1, 0);
1718 if (!$$) $$ = NEW_BEGIN(0);
1720 $$ = dispatch1(var_field, $$);
1725 $$ = assignable($1, 0);
1727 if (!$$) $$ = NEW_BEGIN(0);
1729 $$ = dispatch1(var_field, $$);
1732 | primary_value '[' opt_call_args rbracket
1735 $$ = aryset($1, $3);
1737 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1740 | primary_value '.' tIDENTIFIER
1743 $$ = attrset($1, $3);
1745 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1748 | primary_value tCOLON2 tIDENTIFIER
1751 $$ = attrset($1, $3);
1753 $$ = dispatch3(field, $1, ripper_intern("::"), $3);
1756 | primary_value '.' tCONSTANT
1759 $$ = attrset($1, $3);
1761 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1764 | primary_value tCOLON2 tCONSTANT
1767 if (in_def || in_single)
1768 yyerror("dynamic constant assignment");
1769 $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
1771 $$ = dispatch2(const_path_field, $1, $3);
1772 if (in_def || in_single) {
1773 $$ = dispatch1(assign_error, $$);
1780 if (in_def || in_single)
1781 yyerror("dynamic constant assignment");
1782 $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
1784 $$ = dispatch1(top_const_field, $2);
1785 if (in_def || in_single) {
1786 $$ = dispatch1(assign_error, $$);
1793 rb_backref_error($1);
1796 $$ = dispatch1(assign_error, $1);
1804 yyerror("class/module name must be CONSTANT");
1806 $$ = dispatch1(class_name_error, $1);
1812 cpath : tCOLON3 cname
1815 $$ = NEW_COLON3($2);
1817 $$ = dispatch1(top_const_ref, $2);
1823 $$ = NEW_COLON2(0, $$);
1825 $$ = dispatch1(const_ref, $1);
1828 | primary_value tCOLON2 cname
1831 $$ = NEW_COLON2($1, $3);
1833 $$ = dispatch2(const_path_ref, $1, $3);
1843 lex_state = EXPR_ENDFN;
1848 lex_state = EXPR_ENDFN;
1864 $$ = NEW_LIT(ID2SYM($1));
1866 $$ = dispatch1(symbol_literal, $1);
1877 $$ = rb_ary_new3(1, $1);
1880 | undef_list ',' {lex_state = EXPR_FNAME;} fitem
1883 $$ = block_append($1, NEW_UNDEF($4));
1885 rb_ary_push($1, $4);
1890 op : '|' { ifndef_ripper($$ = '|'); }
1891 | '^' { ifndef_ripper($$ = '^'); }
1892 | '&' { ifndef_ripper($$ = '&'); }
1893 | tCMP { ifndef_ripper($$ = tCMP); }
1894 | tEQ { ifndef_ripper($$ = tEQ); }
1895 | tEQQ { ifndef_ripper($$ = tEQQ); }
1896 | tMATCH { ifndef_ripper($$ = tMATCH); }
1897 | tNMATCH { ifndef_ripper($$ = tNMATCH); }
1898 | '>' { ifndef_ripper($$ = '>'); }
1899 | tGEQ { ifndef_ripper($$ = tGEQ); }
1900 | '<' { ifndef_ripper($$ = '<'); }
1901 | tLEQ { ifndef_ripper($$ = tLEQ); }
1902 | tNEQ { ifndef_ripper($$ = tNEQ); }
1903 | tLSHFT { ifndef_ripper($$ = tLSHFT); }
1904 | tRSHFT { ifndef_ripper($$ = tRSHFT); }
1905 | '+' { ifndef_ripper($$ = '+'); }
1906 | '-' { ifndef_ripper($$ = '-'); }
1907 | '*' { ifndef_ripper($$ = '*'); }
1908 | tSTAR { ifndef_ripper($$ = '*'); }
1909 | '/' { ifndef_ripper($$ = '/'); }
1910 | '%' { ifndef_ripper($$ = '%'); }
1911 | tPOW { ifndef_ripper($$ = tPOW); }
1912 | tDSTAR { ifndef_ripper($$ = tDSTAR); }
1913 | '!' { ifndef_ripper($$ = '!'); }
1914 | '~' { ifndef_ripper($$ = '~'); }
1915 | tUPLUS { ifndef_ripper($$ = tUPLUS); }
1916 | tUMINUS { ifndef_ripper($$ = tUMINUS); }
1917 | tAREF { ifndef_ripper($$ = tAREF); }
1918 | tASET { ifndef_ripper($$ = tASET); }
1919 | '`' { ifndef_ripper($$ = '`'); }
1922 reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
1923 | keyword_BEGIN | keyword_END
1924 | keyword_alias | keyword_and | keyword_begin
1925 | keyword_break | keyword_case | keyword_class | keyword_def
1926 | keyword_defined | keyword_do | keyword_else | keyword_elsif
1927 | keyword_end | keyword_ensure | keyword_false
1928 | keyword_for | keyword_in | keyword_module | keyword_next
1929 | keyword_nil | keyword_not | keyword_or | keyword_redo
1930 | keyword_rescue | keyword_retry | keyword_return | keyword_self
1931 | keyword_super | keyword_then | keyword_true | keyword_undef
1932 | keyword_when | keyword_yield | keyword_if | keyword_unless
1933 | keyword_while | keyword_until
1940 $$ = node_assign($1, $3);
1942 $$ = dispatch2(assign, $1, $3);
1945 | lhs '=' arg modifier_rescue arg
1949 $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
1950 $$ = node_assign($1, $3);
1952 $$ = dispatch2(assign, $1, dispatch2(rescue_mod, $3, $5));
1955 | var_lhs tOP_ASGN arg
1958 $$ = new_op_assign($1, $2, $3);
1960 | var_lhs tOP_ASGN arg modifier_rescue arg
1964 $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
1966 $3 = dispatch2(rescue_mod, $3, $5);
1968 $$ = new_op_assign($1, $2, $3);
1970 | primary_value '[' opt_call_args rbracket tOP_ASGN arg
1976 if (!$3) $3 = NEW_ZARRAY();
1977 if (nd_type($3) == NODE_BLOCK_PASS) {
1978 args = NEW_ARGSCAT($3, $6);
1981 args = arg_concat($3, $6);
1986 else if ($5 == tANDOP) {
1989 $$ = NEW_OP_ASGN1($1, $5, args);
1992 $1 = dispatch2(aref_field, $1, escape_Qundef($3));
1993 $$ = dispatch3(opassign, $1, $5, $6);
1996 | primary_value '.' tIDENTIFIER tOP_ASGN arg
1999 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
2001 | primary_value '.' tCONSTANT tOP_ASGN arg
2004 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
2006 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
2009 $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
2011 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
2014 $$ = NEW_COLON2($1, $3);
2015 $$ = new_const_op_assign($$, $4, $5);
2017 $$ = dispatch2(const_path_field, $1, $3);
2018 $$ = dispatch3(opassign, $$, $4, $5);
2021 | tCOLON3 tCONSTANT tOP_ASGN arg
2024 $$ = NEW_COLON3($2);
2025 $$ = new_const_op_assign($$, $3, $4);
2027 $$ = dispatch1(top_const_field, $2);
2028 $$ = dispatch3(opassign, $$, $3, $4);
2031 | backref tOP_ASGN arg
2034 rb_backref_error($1);
2037 $$ = dispatch1(var_field, $1);
2038 $$ = dispatch3(opassign, $$, $2, $3);
2039 $$ = dispatch1(assign_error, $$);
2047 $$ = NEW_DOT2($1, $3);
2048 if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
2049 nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
2050 deferred_nodes = list_append(deferred_nodes, $$);
2053 $$ = dispatch2(dot2, $1, $3);
2061 $$ = NEW_DOT3($1, $3);
2062 if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
2063 nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
2064 deferred_nodes = list_append(deferred_nodes, $$);
2067 $$ = dispatch2(dot3, $1, $3);
2073 $$ = call_bin_op($1, '+', $3);
2075 $$ = dispatch3(binary, $1, ID2SYM('+'), $3);
2081 $$ = call_bin_op($1, '-', $3);
2083 $$ = dispatch3(binary, $1, ID2SYM('-'), $3);
2089 $$ = call_bin_op($1, '*', $3);
2091 $$ = dispatch3(binary, $1, ID2SYM('*'), $3);
2097 $$ = call_bin_op($1, '/', $3);
2099 $$ = dispatch3(binary, $1, ID2SYM('/'), $3);
2105 $$ = call_bin_op($1, '%', $3);
2107 $$ = dispatch3(binary, $1, ID2SYM('%'), $3);
2113 $$ = call_bin_op($1, tPOW, $3);
2115 $$ = dispatch3(binary, $1, ripper_intern("**"), $3);
2118 | tUMINUS_NUM tINTEGER tPOW arg
2121 $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
2123 $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2124 $$ = dispatch2(unary, ripper_intern("-@"), $$);
2127 | tUMINUS_NUM tFLOAT tPOW arg
2130 $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
2132 $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2133 $$ = dispatch2(unary, ripper_intern("-@"), $$);
2139 $$ = call_uni_op($2, tUPLUS);
2141 $$ = dispatch2(unary, ripper_intern("+@"), $2);
2147 $$ = call_uni_op($2, tUMINUS);
2149 $$ = dispatch2(unary, ripper_intern("-@"), $2);
2155 $$ = call_bin_op($1, '|', $3);
2157 $$ = dispatch3(binary, $1, ID2SYM('|'), $3);
2163 $$ = call_bin_op($1, '^', $3);
2165 $$ = dispatch3(binary, $1, ID2SYM('^'), $3);
2171 $$ = call_bin_op($1, '&', $3);
2173 $$ = dispatch3(binary, $1, ID2SYM('&'), $3);
2179 $$ = call_bin_op($1, tCMP, $3);
2181 $$ = dispatch3(binary, $1, ripper_intern("<=>"), $3);
2187 $$ = call_bin_op($1, '>', $3);
2189 $$ = dispatch3(binary, $1, ID2SYM('>'), $3);
2195 $$ = call_bin_op($1, tGEQ, $3);
2197 $$ = dispatch3(binary, $1, ripper_intern(">="), $3);
2203 $$ = call_bin_op($1, '<', $3);
2205 $$ = dispatch3(binary, $1, ID2SYM('<'), $3);
2211 $$ = call_bin_op($1, tLEQ, $3);
2213 $$ = dispatch3(binary, $1, ripper_intern("<="), $3);
2219 $$ = call_bin_op($1, tEQ, $3);
2221 $$ = dispatch3(binary, $1, ripper_intern("=="), $3);
2227 $$ = call_bin_op($1, tEQQ, $3);
2229 $$ = dispatch3(binary, $1, ripper_intern("==="), $3);
2235 $$ = call_bin_op($1, tNEQ, $3);
2237 $$ = dispatch3(binary, $1, ripper_intern("!="), $3);
2243 $$ = match_op($1, $3);
2244 if (nd_type($1) == NODE_LIT && RB_TYPE_P($1->nd_lit, T_REGEXP)) {
2245 $$ = reg_named_capture_assign($1->nd_lit, $$);
2248 $$ = dispatch3(binary, $1, ripper_intern("=~"), $3);
2254 $$ = call_bin_op($1, tNMATCH, $3);
2256 $$ = dispatch3(binary, $1, ripper_intern("!~"), $3);
2262 $$ = call_uni_op(cond($2), '!');
2264 $$ = dispatch2(unary, ID2SYM('!'), $2);
2270 $$ = call_uni_op($2, '~');
2272 $$ = dispatch2(unary, ID2SYM('~'), $2);
2278 $$ = call_bin_op($1, tLSHFT, $3);
2280 $$ = dispatch3(binary, $1, ripper_intern("<<"), $3);
2286 $$ = call_bin_op($1, tRSHFT, $3);
2288 $$ = dispatch3(binary, $1, ripper_intern(">>"), $3);
2294 $$ = logop(NODE_AND, $1, $3);
2296 $$ = dispatch3(binary, $1, ripper_intern("&&"), $3);
2302 $$ = logop(NODE_OR, $1, $3);
2304 $$ = dispatch3(binary, $1, ripper_intern("||"), $3);
2307 | keyword_defined opt_nl {in_defined = 1;} arg
2311 $$ = NEW_DEFINED($4);
2314 $$ = dispatch1(defined, $4);
2317 | arg '?' arg opt_nl ':' arg
2321 $$ = NEW_IF(cond($1), $3, $6);
2324 $$ = dispatch3(ifop, $1, $3, $6);
2338 if (!$$) $$ = NEW_NIL();
2350 | args ',' assocs trailer
2353 $$ = arg_append($1, NEW_HASH($3));
2355 $$ = arg_add_assocs($1, $3);
2361 $$ = NEW_LIST(NEW_HASH($1));
2363 $$ = arg_add_assocs(arg_new(), $1);
2368 paren_args : '(' opt_call_args rparen
2373 $$ = dispatch1(arg_paren, escape_Qundef($2));
2378 opt_paren_args : none
2382 opt_call_args : none
2388 | args ',' assocs ','
2391 $$ = arg_append($1, NEW_HASH($3));
2393 $$ = arg_add_assocs($1, $3);
2399 $$ = NEW_LIST(NEW_HASH($1));
2401 $$ = arg_add_assocs(arg_new(), $1);
2412 $$ = arg_add(arg_new(), $1);
2415 | args opt_block_arg
2418 $$ = arg_blk_pass($1, $2);
2420 $$ = arg_add_optblock($1, $2);
2423 | assocs opt_block_arg
2426 $$ = NEW_LIST(NEW_HASH($1));
2427 $$ = arg_blk_pass($$, $2);
2429 $$ = arg_add_assocs(arg_new(), $1);
2430 $$ = arg_add_optblock($$, $2);
2433 | args ',' assocs opt_block_arg
2436 $$ = arg_append($1, NEW_HASH($3));
2437 $$ = arg_blk_pass($$, $4);
2439 $$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
2446 $$ = arg_add_block(arg_new(), $1);
2452 $<val>$ = cmdarg_stack;
2458 cmdarg_stack = $<val>1;
2463 block_arg : tAMPER arg_value
2466 $$ = NEW_BLOCK_PASS($2);
2473 opt_block_arg : ',' block_arg
2488 $$ = arg_add(arg_new(), $1);
2496 $$ = arg_add_star(arg_new(), $2);
2499 | args ',' arg_value
2503 if ((n1 = splat_array($1)) != 0) {
2504 $$ = list_append(n1, $3);
2507 $$ = arg_append($1, $3);
2510 $$ = arg_add($1, $3);
2513 | args ',' tSTAR arg_value
2517 if ((nd_type($4) == NODE_ARRAY) && (n1 = splat_array($1)) != 0) {
2518 $$ = list_concat(n1, $4);
2521 $$ = arg_concat($1, $4);
2524 $$ = arg_add_star($1, $4);
2529 mrhs : args ',' arg_value
2533 if ((n1 = splat_array($1)) != 0) {
2534 $$ = list_append(n1, $3);
2537 $$ = arg_append($1, $3);
2540 $$ = mrhs_add(args2mrhs($1), $3);
2543 | args ',' tSTAR arg_value
2547 if (nd_type($4) == NODE_ARRAY &&
2548 (n1 = splat_array($1)) != 0) {
2549 $$ = list_concat(n1, $4);
2552 $$ = arg_concat($1, $4);
2555 $$ = mrhs_add_star(args2mrhs($1), $4);
2563 $$ = mrhs_add_star(mrhs_new(), $2);
2581 $$ = NEW_FCALL($1, 0);
2583 $$ = method_arg(dispatch1(fcall, $1), arg_new());
2588 $<val>1 = cmdarg_stack;
2591 $<num>$ = ruby_sourceline;
2598 cmdarg_stack = $<val>1;
2604 if (nd_type($3) == NODE_RESCUE ||
2605 nd_type($3) == NODE_ENSURE)
2606 nd_set_line($3, $<num>2);
2609 nd_set_line($$, $<num>2);
2611 $$ = dispatch1(begin, $3);
2614 | tLPAREN_ARG {lex_state = EXPR_ENDARG;} rparen
2619 $$ = dispatch1(paren, 0);
2622 | tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} rparen
2627 $$ = dispatch1(paren, $2);
2630 | tLPAREN compstmt ')'
2635 $$ = dispatch1(paren, $2);
2638 | primary_value tCOLON2 tCONSTANT
2641 $$ = NEW_COLON2($1, $3);
2643 $$ = dispatch2(const_path_ref, $1, $3);
2649 $$ = NEW_COLON3($2);
2651 $$ = dispatch1(top_const_ref, $2);
2654 | tLBRACK aref_args ']'
2658 $$ = NEW_ZARRAY(); /* zero length array*/
2664 $$ = dispatch1(array, escape_Qundef($2));
2667 | tLBRACE assoc_list '}'
2672 $$ = dispatch1(hash, escape_Qundef($2));
2680 $$ = dispatch0(return0);
2683 | keyword_yield '(' call_args rparen
2688 $$ = dispatch1(yield, dispatch1(paren, $3));
2691 | keyword_yield '(' rparen
2696 $$ = dispatch1(yield, dispatch1(paren, arg_new()));
2704 $$ = dispatch0(yield0);
2707 | keyword_defined opt_nl '(' {in_defined = 1;} expr rparen
2711 $$ = NEW_DEFINED($5);
2714 $$ = dispatch1(defined, $5);
2717 | keyword_not '(' expr rparen
2720 $$ = call_uni_op(cond($3), '!');
2722 $$ = dispatch2(unary, ripper_intern("not"), $3);
2725 | keyword_not '(' rparen
2728 $$ = call_uni_op(cond(NEW_NIL()), '!');
2730 $$ = dispatch2(unary, ripper_intern("not"), Qnil);
2739 $$ = method_arg(dispatch1(fcall, $1), arg_new());
2740 $$ = method_add_block($$, $2);
2744 | method_call brace_block
2747 block_dup_check($1->nd_args, $2);
2751 $$ = method_add_block($1, $2);
2758 | k_if expr_value then
2764 $$ = NEW_IF(cond($2), $4, $5);
2767 $$ = dispatch3(if, $2, $4, escape_Qundef($5));
2770 | k_unless expr_value then
2776 $$ = NEW_UNLESS(cond($2), $4, $5);
2779 $$ = dispatch3(unless, $2, $4, escape_Qundef($5));
2782 | k_while {COND_PUSH(1);} expr_value do {COND_POP();}
2787 $$ = NEW_WHILE(cond($3), $6, 1);
2790 $$ = dispatch2(while, $3, $6);
2793 | k_until {COND_PUSH(1);} expr_value do {COND_POP();}
2798 $$ = NEW_UNTIL(cond($3), $6, 1);
2801 $$ = dispatch2(until, $3, $6);
2804 | k_case expr_value opt_terms
2809 $$ = NEW_CASE($2, $4);
2812 $$ = dispatch2(case, $2, $4);
2815 | k_case opt_terms case_body k_end
2818 $$ = NEW_CASE(0, $3);
2820 $$ = dispatch2(case, Qnil, $3);
2823 | k_for for_var keyword_in
2834 * e.each{|*x| a, b, c = x
2838 * e.each{|x| a, = x}
2840 ID id = internal_id();
2841 ID *tbl = ALLOC_N(ID, 2);
2842 NODE *m = NEW_ARGS_AUX(0, 0);
2845 if (nd_type($2) == NODE_MASGN) {
2846 /* if args.length == 1 && args[0].kind_of?(Array)
2850 NODE *one = NEW_LIST(NEW_LIT(INT2FIX(1)));
2851 NODE *zero = NEW_LIST(NEW_LIT(INT2FIX(0)));
2852 m->nd_next = block_append(
2855 NEW_CALL(NEW_CALL(NEW_DVAR(id), idLength, 0),
2857 NEW_CALL(NEW_CALL(NEW_DVAR(id), idAREF, zero),
2858 rb_intern("kind_of?"), NEW_LIST(NEW_LIT(rb_cArray))),
2861 NEW_CALL(NEW_DVAR(id), idAREF, zero)),
2863 node_assign($2, NEW_DVAR(id)));
2865 args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
2868 if (nd_type($2) == NODE_LASGN ||
2869 nd_type($2) == NODE_DASGN ||
2870 nd_type($2) == NODE_DASGN_CURR) {
2871 $2->nd_value = NEW_DVAR(id);
2874 args = new_args(m, 0, 0, 0, new_args_tail(0, 0, 0));
2877 m->nd_next = node_assign(NEW_MASGN(NEW_LIST($2), 0), NEW_DVAR(id));
2878 args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
2881 scope = NEW_NODE(NODE_SCOPE, tbl, $8, args);
2882 tbl[0] = 1; tbl[1] = id;
2883 $$ = NEW_FOR(0, $5, scope);
2886 $$ = dispatch3(for, $2, $5, $8);
2889 | k_class cpath superclass
2891 if (in_def || in_single)
2892 yyerror("class definition in method body");
2895 $<num>$ = ruby_sourceline;
2903 $$ = NEW_CLASS($2, $5, $3);
2904 nd_set_line($$, $<num>4);
2906 $$ = dispatch3(class, $2, $3, $5);
2910 | k_class tLSHFT expr
2917 $<num>$ = in_single;
2925 $$ = NEW_SCLASS($3, $7);
2928 $$ = dispatch2(sclass, $3, $7);
2932 in_single = $<num>6;
2936 if (in_def || in_single)
2937 yyerror("module definition in method body");
2940 $<num>$ = ruby_sourceline;
2948 $$ = NEW_MODULE($2, $4);
2949 nd_set_line($$, $<num>3);
2951 $$ = dispatch2(module, $2, $4);
2967 NODE *body = remove_begin($5);
2968 reduce_nodes(&body);
2969 $$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE);
2970 nd_set_line($$, $<num>1);
2972 $$ = dispatch3(def, $2, $4, $5);
2978 | k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
2981 lex_state = EXPR_ENDFN; /* force for args */
2989 NODE *body = remove_begin($8);
2990 reduce_nodes(&body);
2991 $$ = NEW_DEFS($2, $5, $7, body);
2992 nd_set_line($$, $<num>1);
2994 $$ = dispatch5(defs, $2, $3, $5, $7, $8);
3004 $$ = dispatch1(break, arg_new());
3012 $$ = dispatch1(next, arg_new());
3020 $$ = dispatch0(redo);
3028 $$ = dispatch0(retry);
3033 primary_value : primary
3038 if (!$$) $$ = NEW_NIL();
3045 k_begin : keyword_begin
3047 token_info_push("begin");
3053 token_info_push("if");
3057 k_unless : keyword_unless
3059 token_info_push("unless");
3063 k_while : keyword_while
3065 token_info_push("while");
3069 k_until : keyword_until
3071 token_info_push("until");
3075 k_case : keyword_case
3077 token_info_push("case");
3083 token_info_push("for");
3087 k_class : keyword_class
3089 token_info_push("class");
3093 k_module : keyword_module
3095 token_info_push("module");
3101 token_info_push("def");
3103 $<num>$ = ruby_sourceline;
3111 token_info_pop("end");
3137 | keyword_elsif expr_value then
3142 $$ = NEW_IF(cond($2), $4, $5);
3145 $$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
3151 | keyword_else compstmt
3156 $$ = dispatch1(else, $2);
3167 $$ = assignable($1, 0);
3170 $$ = dispatch1(mlhs_paren, $$);
3173 | tLPAREN f_margs rparen
3178 $$ = dispatch1(mlhs_paren, $2);
3183 f_marg_list : f_marg
3188 $$ = mlhs_add(mlhs_new(), $1);
3191 | f_marg_list ',' f_marg
3194 $$ = list_append($1, $3);
3196 $$ = mlhs_add($1, $3);
3201 f_margs : f_marg_list
3204 $$ = NEW_MASGN($1, 0);
3209 | f_marg_list ',' tSTAR f_norm_arg
3211 $$ = assignable($4, 0);
3213 $$ = NEW_MASGN($1, $$);
3215 $$ = mlhs_add_star($1, $$);
3218 | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
3220 $$ = assignable($4, 0);
3222 $$ = NEW_MASGN($1, NEW_POSTARG($$, $6));
3224 $$ = mlhs_add_star($1, $$);
3227 | f_marg_list ',' tSTAR
3230 $$ = NEW_MASGN($1, -1);
3232 $$ = mlhs_add_star($1, Qnil);
3235 | f_marg_list ',' tSTAR ',' f_marg_list
3238 $$ = NEW_MASGN($1, NEW_POSTARG(-1, $5));
3240 $$ = mlhs_add_star($1, $5);
3245 $$ = assignable($2, 0);
3247 $$ = NEW_MASGN(0, $$);
3249 $$ = mlhs_add_star(mlhs_new(), $$);
3252 | tSTAR f_norm_arg ',' f_marg_list
3254 $$ = assignable($2, 0);
3256 $$ = NEW_MASGN(0, NEW_POSTARG($$, $4));
3261 $$ = mlhs_add_star($$, $4);
3267 $$ = NEW_MASGN(0, -1);
3269 $$ = mlhs_add_star(mlhs_new(), Qnil);
3272 | tSTAR ',' f_marg_list
3275 $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
3277 $$ = mlhs_add_star(mlhs_new(), Qnil);
3283 block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
3285 $$ = new_args_tail($1, $3, $4);
3287 | f_block_kwarg opt_f_block_arg
3289 $$ = new_args_tail($1, Qnone, $2);
3291 | f_kwrest opt_f_block_arg
3293 $$ = new_args_tail(Qnone, $1, $2);
3297 $$ = new_args_tail(Qnone, Qnone, $1);
3301 opt_block_args_tail : ',' block_args_tail
3307 $$ = new_args_tail(Qnone, Qnone, Qnone);
3311 block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
3313 $$ = new_args($1, $3, $5, Qnone, $6);
3315 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
3317 $$ = new_args($1, $3, $5, $7, $8);
3319 | f_arg ',' f_block_optarg opt_block_args_tail
3321 $$ = new_args($1, $3, Qnone, Qnone, $4);
3323 | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
3325 $$ = new_args($1, $3, Qnone, $5, $6);
3327 | f_arg ',' f_rest_arg opt_block_args_tail
3329 $$ = new_args($1, Qnone, $3, Qnone, $4);
3333 $$ = new_args($1, Qnone, 1, Qnone, new_args_tail(Qnone, Qnone, Qnone));
3336 dispatch1(excessed_comma, $$);
3339 | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
3341 $$ = new_args($1, Qnone, $3, $5, $6);
3343 | f_arg opt_block_args_tail
3345 $$ = new_args($1, Qnone, Qnone, Qnone, $2);
3347 | f_block_optarg ',' f_rest_arg opt_block_args_tail
3349 $$ = new_args(Qnone, $1, $3, Qnone, $4);
3351 | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
3353 $$ = new_args(Qnone, $1, $3, $5, $6);
3355 | f_block_optarg opt_block_args_tail
3357 $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
3359 | f_block_optarg ',' f_arg opt_block_args_tail
3361 $$ = new_args(Qnone, $1, Qnone, $3, $4);
3363 | f_rest_arg opt_block_args_tail
3365 $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
3367 | f_rest_arg ',' f_arg opt_block_args_tail
3369 $$ = new_args(Qnone, Qnone, $1, $3, $4);
3373 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
3377 opt_block_param : none
3380 command_start = TRUE;
3384 block_param_def : '|' opt_bv_decl '|'
3389 $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
3398 $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
3402 | '|' block_param opt_bv_decl '|'
3407 $$ = blockvar_new(escape_Qundef($2), escape_Qundef($3));
3413 opt_bv_decl : opt_nl
3417 | opt_nl ';' bv_decls opt_nl
3431 $$ = rb_ary_new3(1, $1);
3438 rb_ary_push($1, $3);
3458 $<vars>$ = dyna_push();
3462 lpar_beg = ++paren_nest;
3466 $<num>$ = ruby_sourceline;
3472 $$ = NEW_LAMBDA($3, $5);
3473 nd_set_line($$, $<num>4);
3475 $$ = dispatch2(lambda, $3, $5);
3481 f_larglist : '(' f_args opt_bv_decl ')'
3486 $$ = dispatch1(paren, $2);
3499 lambda_body : tLAMBEG compstmt '}'
3503 | keyword_do_LAMBDA compstmt keyword_end
3509 do_block : keyword_do_block
3511 $<vars>1 = dyna_push();
3513 $<num>$ = ruby_sourceline;
3521 $$ = NEW_ITER($3,$4);
3522 nd_set_line($$, $<num>2);
3524 $$ = dispatch2(do_block, escape_Qundef($3), $4);
3530 block_call : command do_block
3533 if (nd_type($1) == NODE_YIELD) {
3534 compile_error(PARSER_ARG "block given to yield");
3537 block_dup_check($1->nd_args, $2);
3543 $$ = method_add_block($1, $2);
3546 | block_call dot_or_colon operation2 opt_paren_args
3549 $$ = NEW_CALL($1, $3, $4);
3551 $$ = dispatch3(call, $1, $2, $3);
3552 $$ = method_optarg($$, $4);
3555 | block_call dot_or_colon operation2 opt_paren_args brace_block
3558 block_dup_check($4, $5);
3559 $5->nd_iter = NEW_CALL($1, $3, $4);
3563 $$ = dispatch4(command_call, $1, $2, $3, $4);
3564 $$ = method_add_block($$, $5);
3567 | block_call dot_or_colon operation2 command_args do_block
3570 block_dup_check($4, $5);
3571 $5->nd_iter = NEW_CALL($1, $3, $4);
3575 $$ = dispatch4(command_call, $1, $2, $3, $4);
3576 $$ = method_add_block($$, $5);
3581 method_call : fcall paren_args
3587 $$ = method_arg(dispatch1(fcall, $1), $2);
3590 | primary_value '.' operation2
3593 $<num>$ = ruby_sourceline;
3599 $$ = NEW_CALL($1, $3, $5);
3600 nd_set_line($$, $<num>4);
3602 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3603 $$ = method_optarg($$, $5);
3606 | primary_value tCOLON2 operation2
3609 $<num>$ = ruby_sourceline;
3615 $$ = NEW_CALL($1, $3, $5);
3616 nd_set_line($$, $<num>4);
3618 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3619 $$ = method_optarg($$, $5);
3622 | primary_value tCOLON2 operation3
3625 $$ = NEW_CALL($1, $3, 0);
3627 $$ = dispatch3(call, $1, ripper_intern("::"), $3);
3633 $<num>$ = ruby_sourceline;
3639 $$ = NEW_CALL($1, rb_intern("call"), $4);
3640 nd_set_line($$, $<num>3);
3642 $$ = dispatch3(call, $1, ripper_id2sym('.'),
3643 ripper_intern("call"));
3644 $$ = method_optarg($$, $4);
3647 | primary_value tCOLON2
3650 $<num>$ = ruby_sourceline;
3656 $$ = NEW_CALL($1, rb_intern("call"), $4);
3657 nd_set_line($$, $<num>3);
3659 $$ = dispatch3(call, $1, ripper_intern("::"),
3660 ripper_intern("call"));
3661 $$ = method_optarg($$, $4);
3664 | keyword_super paren_args
3669 $$ = dispatch1(super, $2);
3677 $$ = dispatch0(zsuper);
3680 | primary_value '[' opt_call_args rbracket
3683 if ($1 && nd_type($1) == NODE_SELF)
3684 $$ = NEW_FCALL(tAREF, $3);
3686 $$ = NEW_CALL($1, tAREF, $3);
3689 $$ = dispatch2(aref, $1, escape_Qundef($3));
3696 $<vars>1 = dyna_push();
3698 $<num>$ = ruby_sourceline;
3706 $$ = NEW_ITER($3,$4);
3707 nd_set_line($$, $<num>2);
3709 $$ = dispatch2(brace_block, escape_Qundef($3), $4);
3715 $<vars>1 = dyna_push();
3717 $<num>$ = ruby_sourceline;
3722 compstmt keyword_end
3725 $$ = NEW_ITER($3,$4);
3726 nd_set_line($$, $<num>2);
3728 $$ = dispatch2(do_block, escape_Qundef($3), $4);
3734 case_body : keyword_when args then
3739 $$ = NEW_WHEN($2, $4, $5);
3741 $$ = dispatch3(when, $2, $4, escape_Qundef($5));
3750 opt_rescue : keyword_rescue exc_list exc_var then
3756 $3 = node_assign($3, NEW_ERRINFO());
3757 $5 = block_append($3, $5);
3759 $$ = NEW_RESBODY($2, $5, $6);
3760 fixpos($$, $2?$2:$5);
3762 $$ = dispatch4(rescue,
3772 exc_list : arg_value
3777 $$ = rb_ary_new3(1, $1);
3783 if (!($$ = splat_array($1))) $$ = $1;
3791 exc_var : tASSOC lhs
3798 opt_ensure : keyword_ensure compstmt
3803 $$ = dispatch1(ensure, $2);
3813 $$ = NEW_LIT(ID2SYM($1));
3815 $$ = dispatch1(symbol_literal, $1);
3826 node = NEW_STR(STR_NEW0());
3829 node = evstr2dstr(node);
3843 $$ = literal_concat($1, $2);
3845 $$ = dispatch2(string_concat, $1, $2);
3850 string1 : tSTRING_BEG string_contents tSTRING_END
3855 $$ = dispatch1(string_literal, $2);
3860 xstring : tXSTRING_BEG xstring_contents tSTRING_END
3865 node = NEW_XSTR(STR_NEW0());
3868 switch (nd_type(node)) {
3870 nd_set_type(node, NODE_XSTR);
3873 nd_set_type(node, NODE_DXSTR);
3876 node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node));
3882 $$ = dispatch1(xstring_literal, $2);
3887 regexp : tREGEXP_BEG regexp_contents tREGEXP_END
3894 node = NEW_LIT(reg_compile(STR_NEW0(), options));
3896 else switch (nd_type(node)) {
3899 VALUE src = node->nd_lit;
3900 nd_set_type(node, NODE_LIT);
3901 node->nd_lit = reg_compile(src, options);
3905 node = NEW_NODE(NODE_DSTR, STR_NEW0(), 1, NEW_LIST(node));
3907 if (options & RE_OPTION_ONCE) {
3908 nd_set_type(node, NODE_DREGX_ONCE);
3911 nd_set_type(node, NODE_DREGX);
3913 node->nd_cflag = options & RE_OPTION_MASK;
3914 if (!NIL_P(node->nd_lit)) reg_fragment_check(node->nd_lit, options);
3915 for (list = (prev = node)->nd_next; list; list = list->nd_next) {
3916 if (nd_type(list->nd_head) == NODE_STR) {
3917 VALUE tail = list->nd_head->nd_lit;
3918 if (reg_fragment_check(tail, options) && prev && !NIL_P(prev->nd_lit)) {
3919 VALUE lit = prev == node ? prev->nd_lit : prev->nd_head->nd_lit;
3920 if (!literal_concat0(parser, lit, tail)) {
3924 rb_str_resize(tail, 0);
3925 prev->nd_next = list->nd_next;
3926 rb_gc_force_recycle((VALUE)list->nd_head);
3927 rb_gc_force_recycle((VALUE)list);
3938 if (!node->nd_next) {
3939 VALUE src = node->nd_lit;
3940 nd_set_type(node, NODE_LIT);
3941 node->nd_lit = reg_compile(src, options);
3947 $$ = dispatch2(regexp_literal, $2, $3);
3952 words : tWORDS_BEG ' ' tSTRING_END
3957 $$ = dispatch0(words_new);
3958 $$ = dispatch1(array, $$);
3961 | tWORDS_BEG word_list tSTRING_END
3966 $$ = dispatch1(array, $2);
3971 word_list : /* none */
3976 $$ = dispatch0(words_new);
3979 | word_list word ' '
3982 $$ = list_append($1, evstr2dstr($2));
3984 $$ = dispatch2(words_add, $1, $2);
3989 word : string_content
3993 $$ = dispatch0(word_new);
3994 $$ = dispatch2(word_add, $$, $1);
3997 | word string_content
4000 $$ = literal_concat($1, $2);
4002 $$ = dispatch2(word_add, $1, $2);
4007 symbols : tSYMBOLS_BEG ' ' tSTRING_END
4012 $$ = dispatch0(symbols_new);
4013 $$ = dispatch1(array, $$);
4016 | tSYMBOLS_BEG symbol_list tSTRING_END
4021 $$ = dispatch1(array, $2);
4026 symbol_list : /* none */
4031 $$ = dispatch0(symbols_new);
4034 | symbol_list word ' '
4037 $2 = evstr2dstr($2);
4038 nd_set_type($2, NODE_DSYM);
4039 $$ = list_append($1, $2);
4041 $$ = dispatch2(symbols_add, $1, $2);
4046 qwords : tQWORDS_BEG ' ' tSTRING_END
4051 $$ = dispatch0(qwords_new);
4052 $$ = dispatch1(array, $$);
4055 | tQWORDS_BEG qword_list tSTRING_END
4060 $$ = dispatch1(array, $2);
4065 qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END
4070 $$ = dispatch0(qsymbols_new);
4071 $$ = dispatch1(array, $$);
4074 | tQSYMBOLS_BEG qsym_list tSTRING_END
4079 $$ = dispatch1(array, $2);
4084 qword_list : /* none */
4089 $$ = dispatch0(qwords_new);
4092 | qword_list tSTRING_CONTENT ' '
4095 $$ = list_append($1, $2);
4097 $$ = dispatch2(qwords_add, $1, $2);
4102 qsym_list : /* none */
4107 $$ = dispatch0(qsymbols_new);
4110 | qsym_list tSTRING_CONTENT ' '
4115 $2->nd_lit = ID2SYM(rb_intern_str(lit));
4116 nd_set_type($2, NODE_LIT);
4117 $$ = list_append($1, $2);
4119 $$ = dispatch2(qsymbols_add, $1, $2);
4124 string_contents : /* none */
4129 $$ = dispatch0(string_content);
4132 | string_contents string_content
4135 $$ = literal_concat($1, $2);
4137 $$ = dispatch2(string_add, $1, $2);
4142 xstring_contents: /* none */
4147 $$ = dispatch0(xstring_new);
4150 | xstring_contents string_content
4153 $$ = literal_concat($1, $2);
4155 $$ = dispatch2(xstring_add, $1, $2);
4160 regexp_contents: /* none */
4165 $$ = dispatch0(regexp_new);
4168 | regexp_contents string_content
4171 NODE *head = $1, *tail = $2;
4179 switch (nd_type(head)) {
4181 nd_set_type(head, NODE_DSTR);
4186 head = list_append(NEW_DSTR(Qnil), head);
4189 $$ = list_append(head, tail);
4192 $$ = dispatch2(regexp_add, $1, $2);
4197 string_content : tSTRING_CONTENT
4200 $<node>$ = lex_strterm;
4202 lex_state = EXPR_BEG;
4207 lex_strterm = $<node>2;
4210 lex_strterm = $<node>2;
4211 $$ = dispatch1(string_dvar, $3);
4216 $<val>1 = cond_stack;
4217 $<val>$ = cmdarg_stack;
4222 $<node>$ = lex_strterm;
4224 lex_state = EXPR_BEG;
4227 $<num>$ = brace_nest;
4230 compstmt tSTRING_DEND
4232 cond_stack = $<val>1;
4233 cmdarg_stack = $<val>2;
4234 lex_strterm = $<node>3;
4235 brace_nest = $<num>4;
4237 if ($5) $5->flags &= ~NODE_FL_NEWLINE;
4240 $$ = dispatch1(string_embexpr, $5);
4250 $$ = dispatch1(var_ref, $1);
4258 $$ = dispatch1(var_ref, $1);
4266 $$ = dispatch1(var_ref, $1);
4272 symbol : tSYMBEG sym
4274 lex_state = EXPR_END;
4278 $$ = dispatch1(symbol, $2);
4289 dsym : tSYMBEG xstring_contents tSTRING_END
4291 lex_state = EXPR_END;
4295 $$ = dispatch1(dyna_symbol, $2);
4302 | tUMINUS_NUM tINTEGER %prec tLOWEST
4305 $$ = negate_lit($2);
4307 $$ = dispatch2(unary, ripper_intern("-@"), $2);
4310 | tUMINUS_NUM tFLOAT %prec tLOWEST
4313 $$ = negate_lit($2);
4315 $$ = dispatch2(unary, ripper_intern("-@"), $2);
4320 user_variable : tIDENTIFIER
4327 keyword_variable: keyword_nil {ifndef_ripper($$ = keyword_nil);}
4328 | keyword_self {ifndef_ripper($$ = keyword_self);}
4329 | keyword_true {ifndef_ripper($$ = keyword_true);}
4330 | keyword_false {ifndef_ripper($$ = keyword_false);}
4331 | keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);}
4332 | keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);}
4333 | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING__);}
4336 var_ref : user_variable
4339 if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
4341 if (id_is_var(get_id($1))) {
4342 $$ = dispatch1(var_ref, $1);
4345 $$ = dispatch1(vcall, $1);
4352 if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
4354 $$ = dispatch1(var_ref, $1);
4359 var_lhs : user_variable
4361 $$ = assignable($1, 0);
4364 $$ = dispatch1(var_field, $$);
4369 $$ = assignable($1, 0);
4372 $$ = dispatch1(var_field, $$);
4391 lex_state = EXPR_BEG;
4392 command_start = TRUE;
4410 f_arglist : '(' f_args rparen
4415 $$ = dispatch1(paren, $2);
4417 lex_state = EXPR_BEG;
4418 command_start = TRUE;
4423 lex_state = EXPR_BEG;
4424 command_start = TRUE;
4428 args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
4430 $$ = new_args_tail($1, $3, $4);
4432 | f_kwarg opt_f_block_arg
4434 $$ = new_args_tail($1, Qnone, $2);
4436 | f_kwrest opt_f_block_arg
4438 $$ = new_args_tail(Qnone, $1, $2);
4442 $$ = new_args_tail(Qnone, Qnone, $1);
4446 opt_args_tail : ',' args_tail
4452 $$ = new_args_tail(Qnone, Qnone, Qnone);
4456 f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
4458 $$ = new_args($1, $3, $5, Qnone, $6);
4460 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
4462 $$ = new_args($1, $3, $5, $7, $8);
4464 | f_arg ',' f_optarg opt_args_tail
4466 $$ = new_args($1, $3, Qnone, Qnone, $4);
4468 | f_arg ',' f_optarg ',' f_arg opt_args_tail
4470 $$ = new_args($1, $3, Qnone, $5, $6);
4472 | f_arg ',' f_rest_arg opt_args_tail
4474 $$ = new_args($1, Qnone, $3, Qnone, $4);
4476 | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
4478 $$ = new_args($1, Qnone, $3, $5, $6);
4480 | f_arg opt_args_tail
4482 $$ = new_args($1, Qnone, Qnone, Qnone, $2);
4484 | f_optarg ',' f_rest_arg opt_args_tail
4486 $$ = new_args(Qnone, $1, $3, Qnone, $4);
4488 | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
4490 $$ = new_args(Qnone, $1, $3, $5, $6);
4492 | f_optarg opt_args_tail
4494 $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
4496 | f_optarg ',' f_arg opt_args_tail
4498 $$ = new_args(Qnone, $1, Qnone, $3, $4);
4500 | f_rest_arg opt_args_tail
4502 $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
4504 | f_rest_arg ',' f_arg opt_args_tail
4506 $$ = new_args(Qnone, Qnone, $1, $3, $4);
4510 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
4514 $$ = new_args_tail(Qnone, Qnone, Qnone);
4515 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $$);
4519 f_bad_arg : tCONSTANT
4522 yyerror("formal argument cannot be a constant");
4525 $$ = dispatch1(param_error, $1);
4531 yyerror("formal argument cannot be an instance variable");
4534 $$ = dispatch1(param_error, $1);
4540 yyerror("formal argument cannot be a global variable");
4543 $$ = dispatch1(param_error, $1);
4549 yyerror("formal argument cannot be a class variable");
4552 $$ = dispatch1(param_error, $1);
4557 f_norm_arg : f_bad_arg
4560 formal_argument(get_id($1));
4565 f_arg_item : f_norm_arg
4567 arg_var(get_id($1));
4569 $$ = NEW_ARGS_AUX($1, 1);
4574 | tLPAREN f_margs rparen
4576 ID tid = internal_id();
4579 if (dyna_in_block()) {
4580 $2->nd_value = NEW_DVAR(tid);
4583 $2->nd_value = NEW_LVAR(tid);
4585 $$ = NEW_ARGS_AUX(tid, 1);
4588 $$ = dispatch1(mlhs_paren, $2);
4597 $$ = rb_ary_new3(1, $1);
4600 | f_arg ',' f_arg_item
4605 $$->nd_next = block_append($$->nd_next, $3->nd_next);
4606 rb_gc_force_recycle((VALUE)$3);
4608 $$ = rb_ary_push($1, $3);
4613 f_kw : tLABEL arg_value
4615 arg_var(formal_argument(get_id($1)));
4616 $$ = assignable($1, $2);
4618 $$ = NEW_KW_ARG(0, $$);
4620 $$ = rb_assoc_new($$, $2);
4625 f_block_kw : tLABEL primary_value
4627 arg_var(formal_argument(get_id($1)));
4628 $$ = assignable($1, $2);
4630 $$ = NEW_KW_ARG(0, $$);
4632 $$ = rb_assoc_new($$, $2);
4637 f_block_kwarg : f_block_kw
4642 $$ = rb_ary_new3(1, $1);
4645 | f_block_kwarg ',' f_block_kw
4650 while (kws->nd_next) {
4656 $$ = rb_ary_push($1, $3);
4667 $$ = rb_ary_new3(1, $1);
4675 while (kws->nd_next) {
4681 $$ = rb_ary_push($1, $3);
4690 f_kwrest : kwrest_mark tIDENTIFIER
4692 shadowing_lvar(get_id($2));
4701 f_opt : tIDENTIFIER '=' arg_value
4703 arg_var(formal_argument(get_id($1)));
4704 $$ = assignable($1, $3);
4706 $$ = NEW_OPT_ARG(0, $$);
4708 $$ = rb_assoc_new($$, $3);
4713 f_block_opt : tIDENTIFIER '=' primary_value
4715 arg_var(formal_argument(get_id($1)));
4716 $$ = assignable($1, $3);
4718 $$ = NEW_OPT_ARG(0, $$);
4720 $$ = rb_assoc_new($$, $3);
4725 f_block_optarg : f_block_opt
4730 $$ = rb_ary_new3(1, $1);
4733 | f_block_optarg ',' f_block_opt
4738 while (opts->nd_next) {
4739 opts = opts->nd_next;
4744 $$ = rb_ary_push($1, $3);
4754 $$ = rb_ary_new3(1, $1);
4757 | f_optarg ',' f_opt
4762 while (opts->nd_next) {
4763 opts = opts->nd_next;
4768 $$ = rb_ary_push($1, $3);
4777 f_rest_arg : restarg_mark tIDENTIFIER
4780 if (!is_local_id($2))
4781 yyerror("rest argument must be local variable");
4783 arg_var(shadowing_lvar(get_id($2)));
4787 $$ = dispatch1(rest_param, $2);
4796 $$ = dispatch1(rest_param, Qnil);
4805 f_block_arg : blkarg_mark tIDENTIFIER
4808 if (!is_local_id($2))
4809 yyerror("block argument must be local variable");
4810 else if (!dyna_in_block() && local_id($2))
4811 yyerror("duplicated block argument name");
4813 arg_var(shadowing_lvar(get_id($2)));
4817 $$ = dispatch1(blockarg, $2);
4822 opt_f_block_arg : ',' f_block_arg
4841 if (!$$) $$ = NEW_NIL();
4846 | '(' {lex_state = EXPR_BEG;} expr rparen
4850 yyerror("can't define singleton method for ().");
4853 switch (nd_type($3)) {
4862 yyerror("can't define singleton method for literals");
4870 $$ = dispatch1(paren, $3);
4881 $$ = dispatch1(assoclist_from_args, $1);
4890 $$ = rb_ary_new3(1, $1);
4896 $$ = list_concat($1, $3);
4898 $$ = rb_ary_push($1, $3);
4903 assoc : arg_value tASSOC arg_value
4906 $$ = list_append(NEW_LIST($1), $3);
4908 $$ = dispatch2(assoc_new, $1, $3);
4914 $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
4916 $$ = dispatch2(assoc_new, $1, $2);
4922 $$ = list_append(NEW_LIST(0), $2);
4924 $$ = dispatch1(assoc_splat, $2);
4931 operation : tIDENTIFIER
4936 operation2 : tIDENTIFIER
4942 operation3 : tIDENTIFIER
4959 opt_terms : /* none */
4970 rbracket : opt_nl ']'
4973 trailer : /* none */
4978 term : ';' {yyerrok;}
4983 | terms ';' {yyerrok;}
4999 # define yylval (*((YYSTYPE*)(parser->parser_yylval)))
5001 static int parser_regx_options(struct parser_params*);
5002 static int parser_tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**);
5003 static void parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc);
5004 static int parser_parse_string(struct parser_params*,NODE*);
5005 static int parser_here_document(struct parser_params*,NODE*);
5008 # define nextc() parser_nextc(parser)
5009 # define pushback(c) parser_pushback(parser, (c))
5010 # define newtok() parser_newtok(parser)
5011 # define tokspace(n) parser_tokspace(parser, (n))
5012 # define tokadd(c) parser_tokadd(parser, (c))
5013 # define tok_hex(numlen) parser_tok_hex(parser, (numlen))
5014 # define read_escape(flags,e) parser_read_escape(parser, (flags), (e))
5015 # define tokadd_escape(e) parser_tokadd_escape(parser, (e))
5016 # define regx_options() parser_regx_options(parser)
5017 # define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser,(f),(t),(p),(n),(e))
5018 # define parse_string(n) parser_parse_string(parser,(n))
5019 # define tokaddmbc(c, enc) parser_tokaddmbc(parser, (c), (enc))
5020 # define here_document(n) parser_here_document(parser,(n))
5021 # define heredoc_identifier() parser_heredoc_identifier(parser)
5022 # define heredoc_restore(n) parser_heredoc_restore(parser,(n))
5023 # define whole_match_p(e,l,i) parser_whole_match_p(parser,(e),(l),(i))
5026 # define set_yylval_str(x) (yylval.node = NEW_STR(x))
5027 # define set_yylval_num(x) (yylval.num = (x))
5028 # define set_yylval_id(x) (yylval.id = (x))
5029 # define set_yylval_name(x) (yylval.id = (x))
5030 # define set_yylval_literal(x) (yylval.node = NEW_LIT(x))
5031 # define set_yylval_node(x) (yylval.node = (x))
5032 # define yylval_id() (yylval.id)
5035 ripper_yylval_id(ID x)
5037 return (VALUE)NEW_LASGN(x, ID2SYM(x));
5039 # define set_yylval_str(x) (void)(x)
5040 # define set_yylval_num(x) (void)(x)
5041 # define set_yylval_id(x) (void)(x)
5042 # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x))
5043 # define set_yylval_literal(x) (void)(x)
5044 # define set_yylval_node(x) (void)(x)
5045 # define yylval_id() yylval.id
5049 #define ripper_flush(p) (void)(p)
5051 #define ripper_flush(p) ((p)->tokp = (p)->parser_lex_p)
5053 #define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
5056 ripper_has_scan_event(struct parser_params *parser)
5059 if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp");
5060 return lex_p > parser->tokp;
5064 ripper_scan_event_val(struct parser_params *parser, int t)
5066 VALUE str = STR_NEW(parser->tokp, lex_p - parser->tokp);
5067 VALUE rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
5068 ripper_flush(parser);
5073 ripper_dispatch_scan_event(struct parser_params *parser, int t)
5075 if (!ripper_has_scan_event(parser)) return;
5076 yylval_rval = ripper_scan_event_val(parser, t);
5080 ripper_dispatch_ignored_scan_event(struct parser_params *parser, int t)
5082 if (!ripper_has_scan_event(parser)) return;
5083 (void)ripper_scan_event_val(parser, t);
5087 ripper_dispatch_delayed_token(struct parser_params *parser, int t)
5089 int saved_line = ruby_sourceline;
5090 const char *saved_tokp = parser->tokp;
5092 ruby_sourceline = parser->delayed_line;
5093 parser->tokp = lex_pbeg + parser->delayed_col;
5094 yylval_rval = ripper_dispatch1(parser, ripper_token2eventid(t), parser->delayed);
5095 parser->delayed = Qnil;
5096 ruby_sourceline = saved_line;
5097 parser->tokp = saved_tokp;
5101 #include "ruby/regex.h"
5102 #include "ruby/util.h"
5104 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
5105 since ours (we hope) works properly with all combinations of
5106 machines, compilers, `char' and `unsigned char' argument types.
5107 (Per Bothner suggested the basic approach.) */
5108 #undef SIGN_EXTEND_CHAR
5110 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
5111 #else /* not __STDC__ */
5112 /* As in Harbison and Steele. */
5113 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
5116 #define parser_encoding_name() (current_enc->name)
5117 #define parser_mbclen() mbclen((lex_p-1),lex_pend,current_enc)
5118 #define parser_precise_mbclen() rb_enc_precise_mbclen((lex_p-1),lex_pend,current_enc)
5119 #define is_identchar(p,e,enc) (rb_enc_isalnum(*(p),(enc)) || (*(p)) == '_' || !ISASCII(*(p)))
5120 #define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,current_enc))
5122 #define parser_isascii() ISASCII(*(lex_p-1))
5126 token_info_get_column(struct parser_params *parser, const char *token)
5129 const char *p, *pend = lex_p - strlen(token);
5130 for (p = lex_pbeg; p < pend; p++) {
5132 column = (((column - 1) / 8) + 1) * 8;
5140 token_info_has_nonspaces(struct parser_params *parser, const char *token)
5142 const char *p, *pend = lex_p - strlen(token);
5143 for (p = lex_pbeg; p < pend; p++) {
5144 if (*p != ' ' && *p != '\t') {
5151 #undef token_info_push
5153 token_info_push(struct parser_params *parser, const char *token)
5157 if (!parser->parser_token_info_enabled) return;
5158 ptinfo = ALLOC(token_info);
5159 ptinfo->token = token;
5160 ptinfo->linenum = ruby_sourceline;
5161 ptinfo->column = token_info_get_column(parser, token);
5162 ptinfo->nonspc = token_info_has_nonspaces(parser, token);
5163 ptinfo->next = parser->parser_token_info;
5165 parser->parser_token_info = ptinfo;
5168 #undef token_info_pop
5170 token_info_pop(struct parser_params *parser, const char *token)
5173 token_info *ptinfo = parser->parser_token_info;
5175 if (!ptinfo) return;
5176 parser->parser_token_info = ptinfo->next;
5177 if (token_info_get_column(parser, token) == ptinfo->column) { /* OK */
5180 linenum = ruby_sourceline;
5181 if (linenum == ptinfo->linenum) { /* SKIP */
5184 if (token_info_has_nonspaces(parser, token) || ptinfo->nonspc) { /* SKIP */
5187 if (parser->parser_token_info_enabled) {
5188 rb_compile_warn(ruby_sourcefile, linenum,
5189 "mismatched indentations at '%s' with '%s' at %d",
5190 token, ptinfo->token, ptinfo->linenum);
5199 parser_yyerror(struct parser_params *parser, const char *msg)
5202 const int max_line_margin = 30;
5208 compile_error(PARSER_ARG "%s", msg);
5210 while (lex_pbeg <= p) {
5211 if (*p == '\n') break;
5217 while (pe < lex_pend) {
5218 if (*pe == '\n') break;
5225 const char *pre = "", *post = "";
5227 if (len > max_line_margin * 2 + 10) {
5228 if (lex_p - p > max_line_margin) {
5229 p = rb_enc_prev_char(p, lex_p - max_line_margin, pe, rb_enc_get(lex_lastline));
5232 if (pe - lex_p > max_line_margin) {
5233 pe = rb_enc_prev_char(lex_p, lex_p + max_line_margin, pe, rb_enc_get(lex_lastline));
5238 buf = ALLOCA_N(char, len+2);
5239 MEMCPY(buf, p, char, len);
5241 rb_compile_error_append("%s%s%s", pre, buf, post);
5243 i = (int)(lex_p - p);
5244 p2 = buf; pe = buf + len;
5247 if (*p2 != '\t') *p2 = ' ';
5252 rb_compile_error_append("%s%s", pre, buf);
5255 dispatch1(parse_error, STR_NEW2(msg));
5256 #endif /* !RIPPER */
5260 static void parser_prepare(struct parser_params *parser);
5264 debug_lines(const char *f)
5267 CONST_ID(script_lines, "SCRIPT_LINES__");
5268 if (rb_const_defined_at(rb_cObject, script_lines)) {
5269 VALUE hash = rb_const_get_at(rb_cObject, script_lines);
5270 if (RB_TYPE_P(hash, T_HASH)) {
5271 VALUE fname = rb_external_str_new_with_enc(f, strlen(f), rb_filesystem_encoding());
5272 VALUE lines = rb_ary_new();
5273 rb_hash_aset(hash, fname, lines);
5281 coverage(const char *f, int n)
5283 VALUE coverages = rb_get_coverages();
5284 if (RTEST(coverages) && RBASIC(coverages)->klass == 0) {
5285 VALUE fname = rb_external_str_new_with_enc(f, strlen(f), rb_filesystem_encoding());
5286 VALUE lines = rb_ary_new2(n);
5288 RBASIC(lines)->klass = 0;
5289 for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
5290 RARRAY(lines)->as.heap.len = n;
5291 rb_hash_aset(coverages, fname, lines);
5298 e_option_supplied(struct parser_params *parser)
5300 return strcmp(ruby_sourcefile, "-e") == 0;
5304 yycompile0(VALUE arg)
5308 struct parser_params *parser = (struct parser_params *)arg;
5310 if (!compile_for_eval && rb_safe_level() == 0) {
5311 ruby_debug_lines = debug_lines(ruby_sourcefile);
5312 if (ruby_debug_lines && ruby_sourceline > 0) {
5313 VALUE str = STR_NEW0();
5314 n = ruby_sourceline;
5316 rb_ary_push(ruby_debug_lines, str);
5320 if (!e_option_supplied(parser)) {
5321 ruby_coverage = coverage(ruby_sourcefile, ruby_sourceline);
5325 parser_prepare(parser);
5328 parser->parser_token_info_enabled = !compile_for_eval && RTEST(ruby_verbose);
5331 if (RUBY_DTRACE_PARSE_BEGIN_ENABLED()) {
5332 RUBY_DTRACE_PARSE_BEGIN(parser->parser_ruby_sourcefile,
5333 parser->parser_ruby_sourceline);
5336 n = yyparse((void*)parser);
5338 if (RUBY_DTRACE_PARSE_END_ENABLED()) {
5339 RUBY_DTRACE_PARSE_END(parser->parser_ruby_sourcefile,
5340 parser->parser_ruby_sourceline);
5343 ruby_debug_lines = 0;
5345 compile_for_eval = 0;
5348 lex_p = lex_pbeg = lex_pend = 0;
5349 lex_lastline = lex_nextline = 0;
5353 tree = ruby_eval_tree;
5357 else if (ruby_eval_tree_begin) {
5358 tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body);
5364 yycompile(struct parser_params *parser, const char *f, int line)
5366 ruby_sourcefile = ruby_strdup(f);
5367 ruby_sourceline = line - 1;
5368 return (NODE *)rb_suppress_tracing(yycompile0, (VALUE)parser);
5370 #endif /* !RIPPER */
5372 static rb_encoding *
5373 must_be_ascii_compatible(VALUE s)
5375 rb_encoding *enc = rb_enc_get(s);
5376 if (!rb_enc_asciicompat(enc)) {
5377 rb_raise(rb_eArgError, "invalid source encoding");
5383 lex_get_str(struct parser_params *parser, VALUE s)
5385 char *beg, *end, *pend;
5386 rb_encoding *enc = must_be_ascii_compatible(s);
5388 beg = RSTRING_PTR(s);
5390 if (RSTRING_LEN(s) == lex_gets_ptr) return Qnil;
5391 beg += lex_gets_ptr;
5393 pend = RSTRING_PTR(s) + RSTRING_LEN(s);
5395 while (end < pend) {
5396 if (*end++ == '\n') break;
5398 lex_gets_ptr = end - RSTRING_PTR(s);
5399 return rb_enc_str_new(beg, end - beg, enc);
5403 lex_getline(struct parser_params *parser)
5405 VALUE line = (*parser->parser_lex_gets)(parser, parser->parser_lex_input);
5406 if (NIL_P(line)) return line;
5407 must_be_ascii_compatible(line);
5409 if (ruby_debug_lines) {
5410 rb_enc_associate(line, current_enc);
5411 rb_ary_push(ruby_debug_lines, line);
5413 if (ruby_coverage) {
5414 rb_ary_push(ruby_coverage, Qnil);
5421 static rb_data_type_t parser_data_type;
5423 static const rb_data_type_t parser_data_type;
5426 parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
5428 struct parser_params *parser;
5431 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
5432 lex_gets = lex_get_str;
5435 lex_pbeg = lex_p = lex_pend = 0;
5436 compile_for_eval = rb_parse_in_eval();
5438 node = yycompile(parser, f, line);
5439 RB_GC_GUARD(vparser); /* prohibit tail call optimization */
5445 rb_compile_string(const char *f, VALUE s, int line)
5447 must_be_ascii_compatible(s);
5448 return parser_compile_string(rb_parser_new(), f, s, line);
5452 rb_parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
5454 must_be_ascii_compatible(s);
5455 return parser_compile_string(vparser, f, s, line);
5459 rb_compile_cstr(const char *f, const char *s, int len, int line)
5461 VALUE str = rb_str_new(s, len);
5462 return parser_compile_string(rb_parser_new(), f, str, line);
5466 rb_parser_compile_cstr(volatile VALUE vparser, const char *f, const char *s, int len, int line)
5468 VALUE str = rb_str_new(s, len);
5469 return parser_compile_string(vparser, f, str, line);
5473 lex_io_gets(struct parser_params *parser, VALUE io)
5475 return rb_io_gets(io);
5479 rb_compile_file(const char *f, VALUE file, int start)
5481 VALUE volatile vparser = rb_parser_new();
5483 return rb_parser_compile_file(vparser, f, file, start);
5487 rb_parser_compile_file(volatile VALUE vparser, const char *f, VALUE file, int start)
5489 struct parser_params *parser;
5492 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
5493 lex_gets = lex_io_gets;
5495 lex_pbeg = lex_p = lex_pend = 0;
5496 compile_for_eval = rb_parse_in_eval();
5498 node = yycompile(parser, f, start);
5499 RB_GC_GUARD(vparser); /* prohibit tail call optimization */
5503 #endif /* !RIPPER */
5505 #define STR_FUNC_ESCAPE 0x01
5506 #define STR_FUNC_EXPAND 0x02
5507 #define STR_FUNC_REGEXP 0x04
5508 #define STR_FUNC_QWORDS 0x08
5509 #define STR_FUNC_SYMBOL 0x10
5510 #define STR_FUNC_INDENT 0x20
5514 str_dquote = (STR_FUNC_EXPAND),
5515 str_xquote = (STR_FUNC_EXPAND),
5516 str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
5517 str_sword = (STR_FUNC_QWORDS),
5518 str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
5519 str_ssym = (STR_FUNC_SYMBOL),
5520 str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND)
5524 parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *enc0)
5528 str = rb_enc_str_new(p, n, enc);
5529 if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
5530 if (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) {
5532 else if (enc0 == rb_usascii_encoding() && enc != rb_utf8_encoding()) {
5533 rb_enc_associate(str, rb_ascii8bit_encoding());
5540 #define lex_goto_eol(parser) ((parser)->parser_lex_p = (parser)->parser_lex_pend)
5541 #define lex_eol_p() (lex_p >= lex_pend)
5542 #define peek(c) peek_n((c), 0)
5543 #define peek_n(c,n) (lex_p+(n) < lex_pend && (c) == (unsigned char)lex_p[n])
5546 parser_nextc(struct parser_params *parser)
5550 if (lex_p == lex_pend) {
5551 VALUE v = lex_nextline;
5557 if (!lex_input || NIL_P(v = lex_getline(parser))) {
5558 parser->eofp = Qtrue;
5559 lex_goto_eol(parser);
5565 if (parser->tokp < lex_pend) {
5566 if (NIL_P(parser->delayed)) {
5567 parser->delayed = rb_str_buf_new(1024);
5568 rb_enc_associate(parser->delayed, current_enc);
5569 rb_str_buf_cat(parser->delayed,
5570 parser->tokp, lex_pend - parser->tokp);
5571 parser->delayed_line = ruby_sourceline;
5572 parser->delayed_col = (int)(parser->tokp - lex_pbeg);
5575 rb_str_buf_cat(parser->delayed,
5576 parser->tokp, lex_pend - parser->tokp);
5580 if (heredoc_end > 0) {
5581 ruby_sourceline = heredoc_end;
5585 parser->line_count++;
5586 lex_pbeg = lex_p = RSTRING_PTR(v);
5587 lex_pend = lex_p + RSTRING_LEN(v);
5588 ripper_flush(parser);
5592 c = (unsigned char)*lex_p++;
5593 if (c == '\r' && peek('\n')) {
5602 parser_pushback(struct parser_params *parser, int c)
5604 if (c == -1) return;
5606 if (lex_p > lex_pbeg && lex_p[0] == '\n' && lex_p[-1] == '\r') {
5611 #define was_bol() (lex_p == lex_pbeg + 1)
5613 #define tokfix() (tokenbuf[tokidx]='\0')
5614 #define tok() tokenbuf
5615 #define toklen() tokidx
5616 #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
5619 parser_newtok(struct parser_params *parser)
5622 tokline = ruby_sourceline;
5625 tokenbuf = ALLOC_N(char, 60);
5627 if (toksiz > 4096) {
5629 REALLOC_N(tokenbuf, char, 60);
5635 parser_tokspace(struct parser_params *parser, int n)
5639 if (tokidx >= toksiz) {
5640 do {toksiz *= 2;} while (toksiz < tokidx);
5641 REALLOC_N(tokenbuf, char, toksiz);
5643 return &tokenbuf[tokidx-n];
5647 parser_tokadd(struct parser_params *parser, int c)
5649 tokenbuf[tokidx++] = (char)c;
5650 if (tokidx >= toksiz) {
5652 REALLOC_N(tokenbuf, char, toksiz);
5657 parser_tok_hex(struct parser_params *parser, size_t *numlen)
5661 c = scan_hex(lex_p, 2, numlen);
5663 yyerror("invalid hex escape");
5670 #define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
5672 /* return value is for ?\u3042 */
5674 parser_tokadd_utf8(struct parser_params *parser, rb_encoding **encp,
5675 int string_literal, int symbol_literal, int regexp_literal)
5678 * If string_literal is true, then we allow multiple codepoints
5679 * in \u{}, and add the codepoints to the current token.
5680 * Otherwise we're parsing a character literal and return a single
5681 * codepoint without adding it
5687 if (regexp_literal) { tokadd('\\'); tokadd('u'); }
5689 if (peek('{')) { /* handle \u{...} form */
5691 if (regexp_literal) { tokadd(*lex_p); }
5693 codepoint = scan_hex(lex_p, 6, &numlen);
5695 yyerror("invalid Unicode escape");
5698 if (codepoint > 0x10ffff) {
5699 yyerror("invalid Unicode codepoint (too large)");
5703 if (regexp_literal) {
5704 tokcopy((int)numlen);
5706 else if (codepoint >= 0x80) {
5707 *encp = rb_utf8_encoding();
5708 if (string_literal) tokaddmbc(codepoint, *encp);
5710 else if (string_literal) {
5713 } while (string_literal && (peek(' ') || peek('\t')));
5716 yyerror("unterminated Unicode escape");
5720 if (regexp_literal) { tokadd('}'); }
5723 else { /* handle \uxxxx form */
5724 codepoint = scan_hex(lex_p, 4, &numlen);
5726 yyerror("invalid Unicode escape");
5730 if (regexp_literal) {
5733 else if (codepoint >= 0x80) {
5734 *encp = rb_utf8_encoding();
5735 if (string_literal) tokaddmbc(codepoint, *encp);
5737 else if (string_literal) {
5745 #define ESCAPE_CONTROL 1
5746 #define ESCAPE_META 2
5749 parser_read_escape(struct parser_params *parser, int flags,
5755 switch (c = nextc()) {
5756 case '\\': /* Backslash */
5759 case 'n': /* newline */
5762 case 't': /* horizontal tab */
5765 case 'r': /* carriage-return */
5768 case 'f': /* form-feed */
5771 case 'v': /* vertical tab */
5774 case 'a': /* alarm(bell) */
5777 case 'e': /* escape */
5780 case '0': case '1': case '2': case '3': /* octal constant */
5781 case '4': case '5': case '6': case '7':
5783 c = scan_oct(lex_p, 3, &numlen);
5787 case 'x': /* hex constant */
5788 c = tok_hex(&numlen);
5789 if (numlen == 0) return 0;
5792 case 'b': /* backspace */
5795 case 's': /* space */
5799 if (flags & ESCAPE_META) goto eof;
5800 if ((c = nextc()) != '-') {
5804 if ((c = nextc()) == '\\') {
5805 if (peek('u')) goto eof;
5806 return read_escape(flags|ESCAPE_META, encp) | 0x80;
5808 else if (c == -1 || !ISASCII(c)) goto eof;
5810 return ((c & 0xff) | 0x80);
5814 if ((c = nextc()) != '-') {
5819 if (flags & ESCAPE_CONTROL) goto eof;
5820 if ((c = nextc())== '\\') {
5821 if (peek('u')) goto eof;
5822 c = read_escape(flags|ESCAPE_CONTROL, encp);
5826 else if (c == -1 || !ISASCII(c)) goto eof;
5831 yyerror("Invalid escape character syntax");
5840 parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc)
5842 int len = rb_enc_codelen(c, enc);
5843 rb_enc_mbcput(c, tokspace(len), enc);
5847 parser_tokadd_escape(struct parser_params *parser, rb_encoding **encp)
5854 switch (c = nextc()) {
5856 return 0; /* just ignore */
5858 case '0': case '1': case '2': case '3': /* octal constant */
5859 case '4': case '5': case '6': case '7':
5861 ruby_scan_oct(--lex_p, 3, &numlen);
5862 if (numlen == 0) goto eof;
5864 tokcopy((int)numlen + 1);
5868 case 'x': /* hex constant */
5871 if (numlen == 0) return -1;
5872 tokcopy((int)numlen + 2);
5877 if (flags & ESCAPE_META) goto eof;
5878 if ((c = nextc()) != '-') {
5883 flags |= ESCAPE_META;
5887 if (flags & ESCAPE_CONTROL) goto eof;
5888 if ((c = nextc()) != '-') {
5896 if (flags & ESCAPE_CONTROL) goto eof;
5898 flags |= ESCAPE_CONTROL;
5900 if ((c = nextc()) == '\\') {
5903 else if (c == -1) goto eof;
5909 yyerror("Invalid escape character syntax");
5920 parser_regx_options(struct parser_params *parser)
5928 while (c = nextc(), ISALPHA(c)) {
5930 options |= RE_OPTION_ONCE;
5932 else if (rb_char_to_option_kcode(c, &opt, &kc)) {
5934 if (kc != rb_ascii8bit_encindex()) kcode = c;
5949 compile_error(PARSER_ARG "unknown regexp option%s - %s",
5950 toklen() > 1 ? "s" : "", tok());
5952 return options | RE_OPTION_ENCODING(kcode);
5956 dispose_string(VALUE str)
5959 rb_gc_force_recycle(str);
5963 parser_tokadd_mbchar(struct parser_params *parser, int c)
5965 int len = parser_precise_mbclen();
5966 if (!MBCLEN_CHARFOUND_P(len)) {
5967 compile_error(PARSER_ARG "invalid multibyte char (%s)", parser_encoding_name());
5972 if (len > 0) tokcopy(len);
5976 #define tokadd_mbchar(c) parser_tokadd_mbchar(parser, (c))
5979 simple_re_meta(int c)
5982 case '$': case '*': case '+': case '.':
5983 case '?': case '^': case '|':
5984 case ')': case ']': case '}': case '>':
5992 parser_tokadd_string(struct parser_params *parser,
5993 int func, int term, int paren, long *nest,
5997 int has_nonascii = 0;
5998 rb_encoding *enc = *encp;
6000 static const char mixed_msg[] = "%s mixed within %s source";
6002 #define mixed_error(enc1, enc2) if (!errbuf) { \
6003 size_t len = sizeof(mixed_msg) - 4; \
6004 len += strlen(rb_enc_name(enc1)); \
6005 len += strlen(rb_enc_name(enc2)); \
6006 errbuf = ALLOCA_N(char, len); \
6007 snprintf(errbuf, len, mixed_msg, \
6008 rb_enc_name(enc1), \
6009 rb_enc_name(enc2)); \
6012 #define mixed_escape(beg, enc1, enc2) do { \
6013 const char *pos = lex_p; \
6015 mixed_error((enc1), (enc2)); \
6019 while ((c = nextc()) != -1) {
6020 if (paren && c == paren) {
6023 else if (c == term) {
6024 if (!nest || !*nest) {
6030 else if ((func & STR_FUNC_EXPAND) && c == '#' && lex_p < lex_pend) {
6032 if (c2 == '$' || c2 == '@' || c2 == '{') {
6037 else if (c == '\\') {
6038 const char *beg = lex_p - 1;
6042 if (func & STR_FUNC_QWORDS) break;
6043 if (func & STR_FUNC_EXPAND) continue;
6048 if (func & STR_FUNC_ESCAPE) tokadd(c);
6052 if ((func & STR_FUNC_EXPAND) == 0) {
6056 parser_tokadd_utf8(parser, &enc, 1,
6057 func & STR_FUNC_SYMBOL,
6058 func & STR_FUNC_REGEXP);
6059 if (has_nonascii && enc != *encp) {
6060 mixed_escape(beg, enc, *encp);
6065 if (c == -1) return -1;
6067 if ((func & STR_FUNC_EXPAND) == 0) tokadd('\\');
6070 if (func & STR_FUNC_REGEXP) {
6071 if (c == term && !simple_re_meta(c)) {
6076 if ((c = tokadd_escape(&enc)) < 0)
6078 if (has_nonascii && enc != *encp) {
6079 mixed_escape(beg, enc, *encp);
6083 else if (func & STR_FUNC_EXPAND) {
6085 if (func & STR_FUNC_ESCAPE) tokadd('\\');
6086 c = read_escape(0, &enc);
6088 else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6089 /* ignore backslashed spaces in %w */
6091 else if (c != term && !(paren && c == paren)) {
6098 else if (!parser_isascii()) {
6102 mixed_error(enc, *encp);
6105 if (tokadd_mbchar(c) == -1) return -1;
6108 else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6115 mixed_error(enc, *encp);
6125 #define NEW_STRTERM(func, term, paren) \
6126 rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
6130 ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc)
6132 if (!NIL_P(parser->delayed)) {
6133 ptrdiff_t len = lex_p - parser->tokp;
6135 rb_enc_str_buf_cat(parser->delayed, parser->tokp, len, enc);
6137 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6138 parser->tokp = lex_p;
6142 #define flush_string_content(enc) ripper_flush_string_content(parser, (enc))
6144 #define flush_string_content(enc) ((void)(enc))
6147 RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
6148 /* this can be shared with ripper, since it's independent from struct
6151 #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
6152 #define SPECIAL_PUNCT(idx) ( \
6153 BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
6154 BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
6155 BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
6156 BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
6157 BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
6159 const unsigned int ruby_global_name_punct_bits[] = {
6165 #undef SPECIAL_PUNCT
6169 is_global_name_punct(const char c)
6171 if (c <= 0x20 || 0x7e < c) return 0;
6172 return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
6176 parser_peek_variable_name(struct parser_params *parser)
6179 const char *p = lex_p;
6181 if (p + 1 >= lex_pend) return 0;
6185 if ((c = *p) == '-') {
6186 if (++p >= lex_pend) return 0;
6189 else if (is_global_name_punct(c) || ISDIGIT(c)) {
6190 return tSTRING_DVAR;
6194 if ((c = *p) == '@') {
6195 if (++p >= lex_pend) return 0;
6201 command_start = TRUE;
6202 return tSTRING_DBEG;
6206 if (!ISASCII(c) || c == '_' || ISALPHA(c))
6207 return tSTRING_DVAR;
6212 parser_parse_string(struct parser_params *parser, NODE *quote)
6214 int func = (int)quote->nd_func;
6215 int term = nd_term(quote);
6216 int paren = nd_paren(quote);
6218 rb_encoding *enc = current_enc;
6220 if (func == -1) return tSTRING_END;
6222 if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6223 do {c = nextc();} while (ISSPACE(c));
6226 if (c == term && !quote->nd_nest) {
6227 if (func & STR_FUNC_QWORDS) {
6228 quote->nd_func = -1;
6231 if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
6232 set_yylval_num(regx_options());
6240 if ((func & STR_FUNC_EXPAND) && c == '#') {
6241 int t = parser_peek_variable_name(parser);
6247 if (tokadd_string(func, term, paren, "e->nd_nest,
6249 ruby_sourceline = nd_line(quote);
6250 if (func & STR_FUNC_REGEXP) {
6252 compile_error(PARSER_ARG "unterminated regexp meets end of file");
6257 compile_error(PARSER_ARG "unterminated string meets end of file");
6263 set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
6264 flush_string_content(enc);
6266 return tSTRING_CONTENT;
6270 parser_heredoc_identifier(struct parser_params *parser)
6272 int c = nextc(), term, func = 0;
6277 func = STR_FUNC_INDENT;
6281 func |= str_squote; goto quoted;
6283 func |= str_dquote; goto quoted;
6290 while ((c = nextc()) != -1 && c != term) {
6291 if (tokadd_mbchar(c) == -1) return 0;
6294 compile_error(PARSER_ARG "unterminated here document identifier");
6300 if (!parser_is_identchar()) {
6302 if (func & STR_FUNC_INDENT) {
6309 tokadd(func |= str_dquote);
6311 if (tokadd_mbchar(c) == -1) return 0;
6312 } while ((c = nextc()) != -1 && parser_is_identchar());
6319 ripper_dispatch_scan_event(parser, tHEREDOC_BEG);
6321 len = lex_p - lex_pbeg;
6322 lex_goto_eol(parser);
6323 lex_strterm = rb_node_newnode(NODE_HEREDOC,
6324 STR_NEW(tok(), toklen()), /* nd_lit */
6326 lex_lastline); /* nd_orig */
6327 nd_set_line(lex_strterm, ruby_sourceline);
6328 ripper_flush(parser);
6329 return term == '`' ? tXSTRING_BEG : tSTRING_BEG;
6333 parser_heredoc_restore(struct parser_params *parser, NODE *here)
6337 line = here->nd_orig;
6338 lex_lastline = line;
6339 lex_pbeg = RSTRING_PTR(line);
6340 lex_pend = lex_pbeg + RSTRING_LEN(line);
6341 lex_p = lex_pbeg + here->nd_nth;
6342 heredoc_end = ruby_sourceline;
6343 ruby_sourceline = nd_line(here);
6344 dispose_string(here->nd_lit);
6345 rb_gc_force_recycle((VALUE)here);
6346 ripper_flush(parser);
6350 parser_whole_match_p(struct parser_params *parser,
6351 const char *eos, long len, int indent)
6353 const char *p = lex_pbeg;
6357 while (*p && ISSPACE(*p)) p++;
6359 n = lex_pend - (p + len);
6360 if (n < 0 || (n > 0 && p[len] != '\n' && p[len] != '\r')) return FALSE;
6361 return strncmp(eos, p, len) == 0;
6366 ripper_dispatch_heredoc_end(struct parser_params *parser)
6368 if (!NIL_P(parser->delayed))
6369 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6370 lex_goto_eol(parser);
6371 ripper_dispatch_ignored_scan_event(parser, tHEREDOC_END);
6374 #define dispatch_heredoc_end() ripper_dispatch_heredoc_end(parser)
6376 #define dispatch_heredoc_end() ((void)0)
6380 parser_here_document(struct parser_params *parser, NODE *here)
6382 int c, func, indent = 0;
6383 const char *eos, *p, *pend;
6386 rb_encoding *enc = current_enc;
6388 eos = RSTRING_PTR(here->nd_lit);
6389 len = RSTRING_LEN(here->nd_lit) - 1;
6390 indent = (func = *eos++) & STR_FUNC_INDENT;
6392 if ((c = nextc()) == -1) {
6394 compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
6396 if (NIL_P(parser->delayed)) {
6397 ripper_dispatch_scan_event(parser, tSTRING_CONTENT);
6401 ((len = lex_p - parser->tokp) > 0 &&
6402 (str = STR_NEW3(parser->tokp, len, enc, func), 1))) {
6403 rb_str_append(parser->delayed, str);
6405 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6407 lex_goto_eol(parser);
6410 heredoc_restore(lex_strterm);
6414 if (was_bol() && whole_match_p(eos, len, indent)) {
6415 dispatch_heredoc_end();
6416 heredoc_restore(lex_strterm);
6420 if (!(func & STR_FUNC_EXPAND)) {
6422 p = RSTRING_PTR(lex_lastline);
6427 if (--pend == p || pend[-1] != '\r') {
6436 rb_str_cat(str, p, pend - p);
6438 str = STR_NEW(p, pend - p);
6439 if (pend < lex_pend) rb_str_cat(str, "\n", 1);
6440 lex_goto_eol(parser);
6441 if (nextc() == -1) {
6442 if (str) dispose_string(str);
6445 } while (!whole_match_p(eos, len, indent));
6448 /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
6451 int t = parser_peek_variable_name(parser);
6458 if ((c = tokadd_string(func, '\n', 0, NULL, &enc)) == -1) {
6459 if (parser->eofp) goto error;
6463 set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
6464 flush_string_content(enc);
6465 return tSTRING_CONTENT;
6468 /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
6469 if ((c = nextc()) == -1) goto error;
6470 } while (!whole_match_p(eos, len, indent));
6471 str = STR_NEW3(tok(), toklen(), enc, func);
6473 dispatch_heredoc_end();
6474 heredoc_restore(lex_strterm);
6475 lex_strterm = NEW_STRTERM(-1, 0, 0);
6476 set_yylval_str(str);
6477 return tSTRING_CONTENT;
6483 arg_ambiguous_gen(struct parser_params *parser)
6486 rb_warning0("ambiguous first argument; put parentheses or even spaces");
6488 dispatch0(arg_ambiguous);
6491 #define arg_ambiguous() (arg_ambiguous_gen(parser), 1)
6494 formal_argument_gen(struct parser_params *parser, ID lhs)
6497 if (!is_local_id(lhs))
6498 yyerror("formal argument must be local variable");
6500 shadowing_lvar(lhs);
6505 lvar_defined_gen(struct parser_params *parser, ID id)
6507 return (dyna_in_block() && dvar_defined_get(id)) || local_id(id);
6510 /* emacsen -*- hack */
6512 parser_encode_length(struct parser_params *parser, const char *name, long len)
6516 if (len > 5 && name[nlen = len - 5] == '-') {
6517 if (rb_memcicmp(name + nlen + 1, "unix", 4) == 0)
6520 if (len > 4 && name[nlen = len - 4] == '-') {
6521 if (rb_memcicmp(name + nlen + 1, "dos", 3) == 0)
6523 if (rb_memcicmp(name + nlen + 1, "mac", 3) == 0 &&
6524 !(len == 8 && rb_memcicmp(name, "utf8-mac", len) == 0))
6525 /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
6532 parser_set_encode(struct parser_params *parser, const char *name)
6534 int idx = rb_enc_find_index(name);
6539 excargs[1] = rb_sprintf("unknown encoding name: %s", name);
6541 excargs[0] = rb_eArgError;
6542 excargs[2] = rb_make_backtrace();
6543 rb_ary_unshift(excargs[2], rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline));
6544 rb_exc_raise(rb_make_exception(3, excargs));
6546 enc = rb_enc_from_index(idx);
6547 if (!rb_enc_asciicompat(enc)) {
6548 excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
6553 if (ruby_debug_lines) {
6554 long i, n = RARRAY_LEN(ruby_debug_lines);
6555 const VALUE *p = RARRAY_PTR(ruby_debug_lines);
6556 for (i = 0; i < n; ++i) {
6557 rb_enc_associate_index(*p, idx);
6564 comment_at_top(struct parser_params *parser)
6566 const char *p = lex_pbeg, *pend = lex_p - 1;
6567 if (parser->line_count != (parser->has_shebang ? 2 : 1)) return 0;
6569 if (!ISSPACE(*p)) return 0;
6576 typedef long (*rb_magic_comment_length_t)(struct parser_params *parser, const char *name, long len);
6577 typedef void (*rb_magic_comment_setter_t)(struct parser_params *parser, const char *name, const char *val);
6580 magic_comment_encoding(struct parser_params *parser, const char *name, const char *val)
6582 if (!comment_at_top(parser)) {
6585 parser_set_encode(parser, val);
6589 parser_set_token_info(struct parser_params *parser, const char *name, const char *val)
6591 int *p = &parser->parser_token_info_enabled;
6595 if (strcasecmp(val, "true") == 0) {
6601 if (strcasecmp(val, "false") == 0) {
6607 rb_compile_warning(ruby_sourcefile, ruby_sourceline, "invalid value for %s: %s", name, val);
6610 struct magic_comment {
6612 rb_magic_comment_setter_t func;
6613 rb_magic_comment_length_t length;
6616 static const struct magic_comment magic_comments[] = {
6617 {"coding", magic_comment_encoding, parser_encode_length},
6618 {"encoding", magic_comment_encoding, parser_encode_length},
6619 {"warn_indent", parser_set_token_info},
6624 magic_comment_marker(const char *str, long len)
6631 if (str[i-1] == '*' && str[i-2] == '-') {
6637 if (i + 1 >= len) return 0;
6638 if (str[i+1] != '-') {
6641 else if (str[i-1] != '-') {
6657 parser_magic_comment(struct parser_params *parser, const char *str, long len)
6659 VALUE name = 0, val = 0;
6660 const char *beg, *end, *vbeg, *vend;
6661 #define str_copy(_s, _p, _n) ((_s) \
6662 ? (void)(rb_str_resize((_s), (_n)), \
6663 MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
6664 : (void)((_s) = STR_NEW((_p), (_n))))
6666 if (len <= 7) return FALSE;
6667 if (!(beg = magic_comment_marker(str, len))) return FALSE;
6668 if (!(end = magic_comment_marker(beg, str + len - beg))) return FALSE;
6670 len = end - beg - 3;
6672 /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
6675 const struct magic_comment *p = magic_comments;
6681 for (; len > 0 && *str; str++, --len) {
6683 case '\'': case '"': case ':': case ';':
6686 if (!ISSPACE(*str)) break;
6688 for (beg = str; len > 0; str++, --len) {
6690 case '\'': case '"': case ':': case ';':
6693 if (ISSPACE(*str)) break;
6698 for (end = str; len > 0 && ISSPACE(*str); str++, --len);
6700 if (*str != ':') continue;
6702 do str++; while (--len > 0 && ISSPACE(*str));
6705 for (vbeg = ++str; --len > 0 && *str != '"'; str++) {
6718 for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
6721 while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
6724 str_copy(name, beg, n);
6725 s = RSTRING_PTR(name);
6726 for (i = 0; i < n; ++i) {
6727 if (s[i] == '-') s[i] = '_';
6731 if (STRNCASECMP(p->name, s, n) == 0) {
6734 n = (*p->length)(parser, vbeg, n);
6736 str_copy(val, vbeg, n);
6737 (*p->func)(parser, s, RSTRING_PTR(val));
6740 } while (++p < magic_comments + numberof(magic_comments));
6742 str_copy(val, vbeg, vend - vbeg);
6743 dispatch2(magic_comment, name, val);
6751 set_file_encoding(struct parser_params *parser, const char *str, const char *send)
6754 const char *beg = str;
6758 if (send - str <= 6) return;
6760 case 'C': case 'c': str += 6; continue;
6761 case 'O': case 'o': str += 5; continue;
6762 case 'D': case 'd': str += 4; continue;
6763 case 'I': case 'i': str += 3; continue;
6764 case 'N': case 'n': str += 2; continue;
6765 case 'G': case 'g': str += 1; continue;
6772 if (ISSPACE(*str)) break;
6775 if (STRNCASECMP(str-6, "coding", 6) == 0) break;
6779 if (++str >= send) return;
6780 } while (ISSPACE(*str));
6782 if (*str != '=' && *str != ':') return;
6787 while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
6788 s = rb_str_new(beg, parser_encode_length(parser, beg, str - beg));
6789 parser_set_encode(parser, RSTRING_PTR(s));
6790 rb_str_resize(s, 0);
6794 parser_prepare(struct parser_params *parser)
6799 if (peek('!')) parser->has_shebang = 1;
6801 case 0xef: /* UTF-8 BOM marker */
6802 if (lex_pend - lex_p >= 2 &&
6803 (unsigned char)lex_p[0] == 0xbb &&
6804 (unsigned char)lex_p[1] == 0xbf) {
6805 parser->enc = rb_utf8_encoding();
6815 parser->enc = rb_enc_get(lex_lastline);
6818 #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
6819 #define IS_END() IS_lex_state(EXPR_END_ANY)
6820 #define IS_BEG() IS_lex_state(EXPR_BEG_ANY)
6821 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
6822 #define IS_LABEL_POSSIBLE() ((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !cmd_state) || IS_ARG())
6823 #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
6824 #define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
6827 #define ambiguous_operator(op, syn) ( \
6828 rb_warning0("`"op"' after local variable is interpreted as binary operator"), \
6829 rb_warning0("even though it seems like "syn""))
6831 #define ambiguous_operator(op, syn) dispatch2(operator_ambiguous, ripper_intern(op), rb_str_new_cstr(syn))
6833 #define warn_balanced(op, syn) ((void) \
6834 (!IS_lex_state_for(last_state, EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN|EXPR_ENDARG) && \
6835 space_seen && !ISSPACE(c) && \
6836 (ambiguous_operator(op, syn), 0)))
6839 parser_yylex(struct parser_params *parser)
6844 enum lex_state_e last_state;
6848 int fallthru = FALSE;
6853 if (nd_type(lex_strterm) == NODE_HEREDOC) {
6854 token = here_document(lex_strterm);
6855 if (token == tSTRING_END) {
6857 lex_state = EXPR_END;
6861 token = parse_string(lex_strterm);
6862 if (token == tSTRING_END || token == tREGEXP_END) {
6863 rb_gc_force_recycle((VALUE)lex_strterm);
6865 lex_state = EXPR_END;
6870 cmd_state = command_start;
6871 command_start = FALSE;
6873 last_state = lex_state;
6874 switch (c = nextc()) {
6875 case '\0': /* NUL */
6876 case '\004': /* ^D */
6877 case '\032': /* ^Z */
6878 case -1: /* end of script. */
6882 case ' ': case '\t': case '\f': case '\r':
6883 case '\13': /* '\v' */
6886 while ((c = nextc())) {
6888 case ' ': case '\t': case '\f': case '\r':
6889 case '\13': /* '\v' */
6897 ripper_dispatch_scan_event(parser, tSP);
6901 case '#': /* it's a comment */
6902 /* no magic_comment in shebang line */
6903 if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
6904 if (comment_at_top(parser)) {
6905 set_file_encoding(parser, lex_p, lex_pend);
6910 ripper_dispatch_scan_event(parser, tCOMMENT);
6915 if (IS_lex_state(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT)) {
6918 ripper_dispatch_scan_event(parser, tIGNORED_NL);
6924 while ((c = nextc())) {
6926 case ' ': case '\t': case '\f': case '\r':
6927 case '\13': /* '\v' */
6931 if ((c = nextc()) != '.') {
6939 lex_nextline = lex_lastline;
6940 case -1: /* EOF no decrement*/
6941 lex_goto_eol(parser);
6944 parser->tokp = lex_p;
6947 goto normal_newline;
6951 command_start = TRUE;
6952 lex_state = EXPR_BEG;
6956 if ((c = nextc()) == '*') {
6957 if ((c = nextc()) == '=') {
6958 set_yylval_id(tPOW);
6959 lex_state = EXPR_BEG;
6964 rb_warning0("`**' interpreted as argument prefix");
6967 else if (IS_BEG()) {
6971 warn_balanced("**", "argument prefix");
6978 lex_state = EXPR_BEG;
6983 rb_warning0("`*' interpreted as argument prefix");
6986 else if (IS_BEG()) {
6990 warn_balanced("*", "argument prefix");
6994 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
6999 if (IS_AFTER_OPERATOR()) {
7000 lex_state = EXPR_ARG;
7006 lex_state = EXPR_BEG;
7019 /* skip embedded rd document */
7020 if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
7024 lex_goto_eol(parser);
7025 ripper_dispatch_scan_event(parser, tEMBDOC_BEG);
7028 lex_goto_eol(parser);
7031 ripper_dispatch_scan_event(parser, tEMBDOC);
7037 compile_error(PARSER_ARG "embedded document meets end of file");
7040 if (c != '=') continue;
7041 if (strncmp(lex_p, "end", 3) == 0 &&
7042 (lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {
7046 lex_goto_eol(parser);
7048 ripper_dispatch_scan_event(parser, tEMBDOC_END);
7054 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7055 if ((c = nextc()) == '=') {
7056 if ((c = nextc()) == '=') {
7065 else if (c == '>') {
7072 last_state = lex_state;
7075 !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
7077 (!IS_ARG() || space_seen)) {
7078 int token = heredoc_identifier();
7079 if (token) return token;
7081 if (IS_AFTER_OPERATOR()) {
7082 lex_state = EXPR_ARG;
7085 if (IS_lex_state(EXPR_CLASS))
7086 command_start = TRUE;
7087 lex_state = EXPR_BEG;
7090 if ((c = nextc()) == '>') {
7097 if ((c = nextc()) == '=') {
7098 set_yylval_id(tLSHFT);
7099 lex_state = EXPR_BEG;
7103 warn_balanced("<<", "here document");
7110 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7111 if ((c = nextc()) == '=') {
7115 if ((c = nextc()) == '=') {
7116 set_yylval_id(tRSHFT);
7117 lex_state = EXPR_BEG;
7127 lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
7131 if (IS_lex_state(EXPR_FNAME)) {
7132 lex_state = EXPR_ENDFN;
7135 if (IS_lex_state(EXPR_DOT)) {
7137 lex_state = EXPR_CMDARG;
7139 lex_state = EXPR_ARG;
7142 lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
7143 return tXSTRING_BEG;
7146 lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
7151 lex_state = EXPR_VALUE;
7156 compile_error(PARSER_ARG "incomplete character syntax");
7159 if (rb_enc_isspace(c, current_enc)) {
7183 rb_warnI("invalid character syntax; use ?\\%c", c2);
7188 lex_state = EXPR_VALUE;
7193 if (!parser_isascii()) {
7194 if (tokadd_mbchar(c) == -1) return 0;
7196 else if ((rb_enc_isalnum(c, current_enc) || c == '_') &&
7197 lex_p < lex_pend && is_identchar(lex_p, lex_pend, current_enc)) {
7200 else if (c == '\\') {
7203 c = parser_tokadd_utf8(parser, &enc, 0, 0, 0);
7211 else if (!lex_eol_p() && !(c = *lex_p, ISASCII(c))) {
7213 if (tokadd_mbchar(c) == -1) return 0;
7216 c = read_escape(0, &enc);
7224 set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0));
7225 lex_state = EXPR_END;
7229 if ((c = nextc()) == '&') {
7230 lex_state = EXPR_BEG;
7231 if ((c = nextc()) == '=') {
7232 set_yylval_id(tANDOP);
7233 lex_state = EXPR_BEG;
7239 else if (c == '=') {
7241 lex_state = EXPR_BEG;
7246 rb_warning0("`&' interpreted as argument prefix");
7249 else if (IS_BEG()) {
7253 warn_balanced("&", "argument prefix");
7256 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7260 if ((c = nextc()) == '|') {
7261 lex_state = EXPR_BEG;
7262 if ((c = nextc()) == '=') {
7263 set_yylval_id(tOROP);
7264 lex_state = EXPR_BEG;
7272 lex_state = EXPR_BEG;
7275 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7281 if (IS_AFTER_OPERATOR()) {
7282 lex_state = EXPR_ARG;
7291 lex_state = EXPR_BEG;
7294 if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7295 lex_state = EXPR_BEG;
7297 if (c != -1 && ISDIGIT(c)) {
7303 lex_state = EXPR_BEG;
7305 warn_balanced("+", "unary operator");
7310 if (IS_AFTER_OPERATOR()) {
7311 lex_state = EXPR_ARG;
7320 lex_state = EXPR_BEG;
7324 lex_state = EXPR_ENDFN;
7327 if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7328 lex_state = EXPR_BEG;
7330 if (c != -1 && ISDIGIT(c)) {
7335 lex_state = EXPR_BEG;
7337 warn_balanced("-", "unary operator");
7341 lex_state = EXPR_BEG;
7342 if ((c = nextc()) == '.') {
7343 if ((c = nextc()) == '.') {
7350 if (c != -1 && ISDIGIT(c)) {
7351 yyerror("no .<digit> floating literal anymore; put 0 before dot");
7353 lex_state = EXPR_DOT;
7357 case '0': case '1': case '2': case '3': case '4':
7358 case '5': case '6': case '7': case '8': case '9':
7360 int is_float, seen_point, seen_e, nondigit;
7362 is_float = seen_point = seen_e = nondigit = 0;
7363 lex_state = EXPR_END;
7365 if (c == '-' || c == '+') {
7370 #define no_digits() do {yyerror("numeric literal without digits"); return 0;} while (0)
7371 int start = toklen();
7373 if (c == 'x' || c == 'X') {
7376 if (c != -1 && ISXDIGIT(c)) {
7379 if (nondigit) break;
7383 if (!ISXDIGIT(c)) break;
7386 } while ((c = nextc()) != -1);
7390 if (toklen() == start) {
7393 else if (nondigit) goto trailing_uc;
7394 set_yylval_literal(rb_cstr_to_inum(tok(), 16, FALSE));
7397 if (c == 'b' || c == 'B') {
7400 if (c == '0' || c == '1') {
7403 if (nondigit) break;
7407 if (c != '0' && c != '1') break;
7410 } while ((c = nextc()) != -1);
7414 if (toklen() == start) {
7417 else if (nondigit) goto trailing_uc;
7418 set_yylval_literal(rb_cstr_to_inum(tok(), 2, FALSE));
7421 if (c == 'd' || c == 'D') {
7424 if (c != -1 && ISDIGIT(c)) {
7427 if (nondigit) break;
7431 if (!ISDIGIT(c)) break;
7434 } while ((c = nextc()) != -1);
7438 if (toklen() == start) {
7441 else if (nondigit) goto trailing_uc;
7442 set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
7449 if (c == 'o' || c == 'O') {
7450 /* prefixed octal */
7452 if (c == -1 || c == '_' || !ISDIGIT(c)) {
7456 if (c >= '0' && c <= '7') {
7461 if (nondigit) break;
7465 if (c < '0' || c > '9') break;
7466 if (c > '7') goto invalid_octal;
7469 } while ((c = nextc()) != -1);
7470 if (toklen() > start) {
7473 if (nondigit) goto trailing_uc;
7474 set_yylval_literal(rb_cstr_to_inum(tok(), 8, FALSE));
7482 if (c > '7' && c <= '9') {
7484 yyerror("Invalid octal digit");
7486 else if (c == '.' || c == 'e' || c == 'E') {
7491 set_yylval_literal(INT2FIX(0));
7498 case '0': case '1': case '2': case '3': case '4':
7499 case '5': case '6': case '7': case '8': case '9':
7505 if (nondigit) goto trailing_uc;
7506 if (seen_point || seen_e) {
7511 if (c0 == -1 || !ISDIGIT(c0)) {
7539 if (c != '-' && c != '+') continue;
7544 case '_': /* `_' in number just ignored */
7545 if (nondigit) goto decode_num;
7560 snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
7565 double d = strtod(tok(), 0);
7566 if (errno == ERANGE) {
7567 rb_warningS("Float %s out of range", tok());
7570 set_yylval_literal(DBL2NUM(d));
7573 set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
7584 lex_state = EXPR_ENDFN;
7586 lex_state = EXPR_ENDARG;
7588 if (!brace_nest--) c = tSTRING_DEND;
7595 if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
7596 lex_state = EXPR_BEG;
7599 lex_state = EXPR_DOT;
7602 if (IS_END() || ISSPACE(c)) {
7604 warn_balanced(":", "symbol literal");
7605 lex_state = EXPR_BEG;
7610 lex_strterm = NEW_STRTERM(str_ssym, c, 0);
7613 lex_strterm = NEW_STRTERM(str_dsym, c, 0);
7619 lex_state = EXPR_FNAME;
7623 if (IS_lex_state(EXPR_BEG_ANY)) {
7624 lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7627 if ((c = nextc()) == '=') {
7629 lex_state = EXPR_BEG;
7634 (void)arg_ambiguous();
7635 lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7638 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7639 warn_balanced("/", "regexp literal");
7643 if ((c = nextc()) == '=') {
7645 lex_state = EXPR_BEG;
7648 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7653 lex_state = EXPR_BEG;
7654 command_start = TRUE;
7658 lex_state = EXPR_BEG;
7662 if (IS_AFTER_OPERATOR()) {
7663 if ((c = nextc()) != '@') {
7666 lex_state = EXPR_ARG;
7669 lex_state = EXPR_BEG;
7677 else if (IS_SPCARG(-1)) {
7683 lex_state = EXPR_BEG;
7688 if (IS_AFTER_OPERATOR()) {
7689 lex_state = EXPR_ARG;
7690 if ((c = nextc()) == ']') {
7691 if ((c = nextc()) == '=') {
7700 else if (IS_BEG()) {
7703 else if (IS_ARG() && space_seen) {
7706 lex_state = EXPR_BEG;
7713 if (lpar_beg && lpar_beg == paren_nest) {
7714 lex_state = EXPR_BEG;
7721 if (IS_ARG() || IS_lex_state(EXPR_END | EXPR_ENDFN))
7722 c = '{'; /* block (primary) */
7723 else if (IS_lex_state(EXPR_ENDARG))
7724 c = tLBRACE_ARG; /* block (expr) */
7726 c = tLBRACE; /* hash */
7729 lex_state = EXPR_BEG;
7730 if (c != tLBRACE) command_start = TRUE;
7738 ripper_dispatch_scan_event(parser, tSP);
7740 goto retry; /* skip \\n */
7746 if (IS_lex_state(EXPR_BEG_ANY)) {
7752 if (c == -1 || !ISALNUM(c)) {
7758 if (rb_enc_isalnum(term, current_enc) || !parser_isascii()) {
7759 yyerror("unknown type of %string");
7763 if (c == -1 || term == -1) {
7764 compile_error(PARSER_ARG "unterminated quoted string meets end of file");
7768 if (term == '(') term = ')';
7769 else if (term == '[') term = ']';
7770 else if (term == '{') term = '}';
7771 else if (term == '<') term = '>';
7776 lex_strterm = NEW_STRTERM(str_dquote, term, paren);
7780 lex_strterm = NEW_STRTERM(str_squote, term, paren);
7784 lex_strterm = NEW_STRTERM(str_dword, term, paren);
7785 do {c = nextc();} while (ISSPACE(c));
7790 lex_strterm = NEW_STRTERM(str_sword, term, paren);
7791 do {c = nextc();} while (ISSPACE(c));
7796 lex_strterm = NEW_STRTERM(str_dword, term, paren);
7797 do {c = nextc();} while (ISSPACE(c));
7799 return tSYMBOLS_BEG;
7802 lex_strterm = NEW_STRTERM(str_sword, term, paren);
7803 do {c = nextc();} while (ISSPACE(c));
7805 return tQSYMBOLS_BEG;
7808 lex_strterm = NEW_STRTERM(str_xquote, term, paren);
7809 return tXSTRING_BEG;
7812 lex_strterm = NEW_STRTERM(str_regexp, term, paren);
7816 lex_strterm = NEW_STRTERM(str_ssym, term, paren);
7817 lex_state = EXPR_FNAME;
7821 yyerror("unknown type of %string");
7825 if ((c = nextc()) == '=') {
7827 lex_state = EXPR_BEG;
7833 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7835 warn_balanced("%%", "string literal");
7839 lex_state = EXPR_END;
7843 case '_': /* $_: last read line string */
7845 if (parser_is_identchar()) {
7853 case '~': /* $~: match-data */
7854 case '*': /* $*: argv */
7855 case '$': /* $$: pid */
7856 case '?': /* $?: last status */
7857 case '!': /* $!: error string */
7858 case '@': /* $@: error position */
7859 case '/': /* $/: input record separator */
7860 case '\\': /* $\: output record separator */
7861 case ';': /* $;: field separator */
7862 case ',': /* $,: output field separator */
7863 case '.': /* $.: last read line number */
7864 case '=': /* $=: ignorecase */
7865 case ':': /* $:: load path */
7866 case '<': /* $<: reading filename */
7867 case '>': /* $>: default output handle */
7868 case '\"': /* $": already loaded files */
7872 set_yylval_name(rb_intern(tok()));
7879 if (parser_is_identchar()) {
7880 if (tokadd_mbchar(c) == -1) return 0;
7887 set_yylval_name(rb_intern(tok()));
7890 case '&': /* $&: last match */
7891 case '`': /* $`: string before last match */
7892 case '\'': /* $': string after last match */
7893 case '+': /* $+: string matches last paren. */
7894 if (IS_lex_state_for(last_state, EXPR_FNAME)) {
7899 set_yylval_node(NEW_BACK_REF(c));
7902 case '1': case '2': case '3':
7903 case '4': case '5': case '6':
7904 case '7': case '8': case '9':
7909 } while (c != -1 && ISDIGIT(c));
7911 if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
7913 set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
7917 if (!parser_is_identchar()) {
7919 compile_error(PARSER_ARG "`$%c' is not allowed as a global variable name", c);
7935 if (c != -1 && (ISDIGIT(c) || !parser_is_identchar())) {
7938 compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
7941 compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
7948 if (was_bol() && whole_match_p("__END__", 7, 0)) {
7949 ruby__end__seen = 1;
7950 parser->eofp = Qtrue;
7954 lex_goto_eol(parser);
7955 ripper_dispatch_scan_event(parser, k__END__);
7963 if (!parser_is_identchar()) {
7964 rb_compile_error(PARSER_ARG "Invalid char `\\x%02X' in expression", c);
7972 mb = ENC_CODERANGE_7BIT;
7974 if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
7975 if (tokadd_mbchar(c) == -1) return 0;
7977 } while (parser_is_identchar());
7983 if ((c == '!' || c == '?') && !peek('=')) {
7995 last_state = lex_state;
7998 lex_state = EXPR_END;
8002 lex_state = EXPR_END;
8003 if (tok()[1] == '@')
8010 if (toklast() == '!' || toklast() == '?') {
8014 if (IS_lex_state(EXPR_FNAME)) {
8015 if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
8016 (!peek('=') || (peek_n('>', 1)))) {
8017 result = tIDENTIFIER;
8025 if (result == 0 && ISUPPER(tok()[0])) {
8029 result = tIDENTIFIER;
8033 if (IS_LABEL_POSSIBLE()) {
8034 if (IS_LABEL_SUFFIX(0)) {
8035 lex_state = EXPR_BEG;
8037 set_yylval_name(TOK_INTERN(!ENC_SINGLE(mb)));
8041 if (mb == ENC_CODERANGE_7BIT && !IS_lex_state(EXPR_DOT)) {
8042 const struct kwtable *kw;
8044 /* See if it is a reserved word. */
8045 kw = rb_reserved_word(tok(), toklen());
8047 enum lex_state_e state = lex_state;
8048 lex_state = kw->state;
8049 if (state == EXPR_FNAME) {
8050 set_yylval_name(rb_intern(kw->name));
8053 if (lex_state == EXPR_BEG) {
8054 command_start = TRUE;
8056 if (kw->id[0] == keyword_do) {
8057 if (lpar_beg && lpar_beg == paren_nest) {
8060 return keyword_do_LAMBDA;
8062 if (COND_P()) return keyword_do_cond;
8063 if (CMDARG_P() && state != EXPR_CMDARG)
8064 return keyword_do_block;
8065 if (state & (EXPR_BEG | EXPR_ENDARG))
8066 return keyword_do_block;
8069 if (state & (EXPR_BEG | EXPR_VALUE))
8072 if (kw->id[0] != kw->id[1])
8073 lex_state = EXPR_BEG;
8079 if (IS_lex_state(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT)) {
8081 lex_state = EXPR_CMDARG;
8084 lex_state = EXPR_ARG;
8087 else if (lex_state == EXPR_FNAME) {
8088 lex_state = EXPR_ENDFN;
8091 lex_state = EXPR_END;
8095 ID ident = TOK_INTERN(!ENC_SINGLE(mb));
8097 set_yylval_name(ident);
8098 if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
8099 is_local_id(ident) && lvar_defined(ident)) {
8100 lex_state = EXPR_END;
8109 yylex(void *lval, void *p)
8114 struct parser_params *parser = (struct parser_params*)p;
8118 parser->parser_yylval = lval;
8119 parser->parser_yylval->val = Qundef;
8121 t = parser_yylex(parser);
8123 if (!NIL_P(parser->delayed)) {
8124 ripper_dispatch_delayed_token(parser, t);
8128 ripper_dispatch_scan_event(parser, t);
8136 node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
8138 NODE *n = (rb_node_newnode)(type, a0, a1, a2);
8139 nd_set_line(n, ruby_sourceline);
8143 static enum node_type
8144 nodetype(NODE *node) /* for debug */
8146 return (enum node_type)nd_type(node);
8150 nodeline(NODE *node)
8152 return nd_line(node);
8156 newline_node(NODE *node)
8159 node = remove_begin(node);
8160 node->flags |= NODE_FL_NEWLINE;
8166 fixpos(NODE *node, NODE *orig)
8170 if (orig == (NODE*)1) return;
8171 nd_set_line(node, nd_line(orig));
8175 parser_warning(struct parser_params *parser, NODE *node, const char *mesg)
8177 rb_compile_warning(ruby_sourcefile, nd_line(node), "%s", mesg);
8179 #define parser_warning(node, mesg) parser_warning(parser, (node), (mesg))
8182 parser_warn(struct parser_params *parser, NODE *node, const char *mesg)
8184 rb_compile_warn(ruby_sourcefile, nd_line(node), "%s", mesg);
8186 #define parser_warn(node, mesg) parser_warn(parser, (node), (mesg))
8189 block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
8191 NODE *end, *h = head, *nd;
8193 if (tail == 0) return head;
8195 if (h == 0) return tail;
8196 switch (nd_type(h)) {
8203 parser_warning(h, "unused literal ignored");
8206 h = end = NEW_BLOCK(head);
8217 switch (nd_type(nd)) {
8223 if (RTEST(ruby_verbose)) {
8224 parser_warning(tail, "statement not reached");
8232 if (nd_type(tail) != NODE_BLOCK) {
8233 tail = NEW_BLOCK(tail);
8234 tail->nd_end = tail;
8236 end->nd_next = tail;
8237 h->nd_end = tail->nd_end;
8241 /* append item to the list */
8243 list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
8247 if (list == 0) return NEW_LIST(item);
8248 if (list->nd_next) {
8249 last = list->nd_next->nd_end;
8256 last->nd_next = NEW_LIST(item);
8257 list->nd_next->nd_end = last->nd_next;
8261 /* concat two lists */
8263 list_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
8267 if (head->nd_next) {
8268 last = head->nd_next->nd_end;
8274 head->nd_alen += tail->nd_alen;
8275 last->nd_next = tail;
8276 if (tail->nd_next) {
8277 head->nd_next->nd_end = tail->nd_next->nd_end;
8280 head->nd_next->nd_end = tail;
8287 literal_concat0(struct parser_params *parser, VALUE head, VALUE tail)
8289 if (NIL_P(tail)) return 1;
8290 if (!rb_enc_compatible(head, tail)) {
8291 compile_error(PARSER_ARG "string literal encodings differ (%s / %s)",
8292 rb_enc_name(rb_enc_get(head)),
8293 rb_enc_name(rb_enc_get(tail)));
8294 rb_str_resize(head, 0);
8295 rb_str_resize(tail, 0);
8298 rb_str_buf_append(head, tail);
8302 /* concat two string literals */
8304 literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
8306 enum node_type htype;
8310 if (!head) return tail;
8311 if (!tail) return head;
8313 htype = nd_type(head);
8314 if (htype == NODE_EVSTR) {
8315 NODE *node = NEW_DSTR(Qnil);
8316 head = list_append(node, head);
8319 switch (nd_type(tail)) {
8321 if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
8322 nd_type(headlast) == NODE_STR) {
8324 lit = headlast->nd_lit;
8329 if (htype == NODE_STR) {
8330 if (!literal_concat0(parser, lit, tail->nd_lit)) {
8332 rb_gc_force_recycle((VALUE)head);
8333 rb_gc_force_recycle((VALUE)tail);
8336 rb_gc_force_recycle((VALUE)tail);
8339 list_append(head, tail);
8344 if (htype == NODE_STR) {
8345 if (!literal_concat0(parser, head->nd_lit, tail->nd_lit))
8347 tail->nd_lit = head->nd_lit;
8348 rb_gc_force_recycle((VALUE)head);
8351 else if (NIL_P(tail->nd_lit)) {
8353 head->nd_alen += tail->nd_alen - 1;
8354 head->nd_next->nd_end->nd_next = tail->nd_next;
8355 head->nd_next->nd_end = tail->nd_next->nd_end;
8356 rb_gc_force_recycle((VALUE)tail);
8358 else if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
8359 nd_type(headlast) == NODE_STR) {
8360 lit = headlast->nd_lit;
8361 if (!literal_concat0(parser, lit, tail->nd_lit))
8363 tail->nd_lit = Qnil;
8367 nd_set_type(tail, NODE_ARRAY);
8368 tail->nd_head = NEW_STR(tail->nd_lit);
8369 list_concat(head, tail);
8374 if (htype == NODE_STR) {
8375 nd_set_type(head, NODE_DSTR);
8378 list_append(head, tail);
8385 evstr2dstr_gen(struct parser_params *parser, NODE *node)
8387 if (nd_type(node) == NODE_EVSTR) {
8388 node = list_append(NEW_DSTR(Qnil), node);
8394 new_evstr_gen(struct parser_params *parser, NODE *node)
8399 switch (nd_type(node)) {
8400 case NODE_STR: case NODE_DSTR: case NODE_EVSTR:
8404 return NEW_EVSTR(head);
8408 call_bin_op_gen(struct parser_params *parser, NODE *recv, ID id, NODE *arg1)
8412 return NEW_CALL(recv, id, NEW_LIST(arg1));
8416 call_uni_op_gen(struct parser_params *parser, NODE *recv, ID id)
8419 return NEW_CALL(recv, id, 0);
8423 match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8428 switch (nd_type(node1)) {
8430 case NODE_DREGX_ONCE:
8431 return NEW_MATCH2(node1, node2);
8434 if (RB_TYPE_P(node1->nd_lit, T_REGEXP)) {
8435 return NEW_MATCH2(node1, node2);
8441 switch (nd_type(node2)) {
8443 case NODE_DREGX_ONCE:
8444 return NEW_MATCH3(node2, node1);
8447 if (RB_TYPE_P(node2->nd_lit, T_REGEXP)) {
8448 return NEW_MATCH3(node2, node1);
8453 return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
8457 gettable_gen(struct parser_params *parser, ID id)
8468 case keyword__FILE__:
8469 return NEW_STR(rb_external_str_new_with_enc(ruby_sourcefile, strlen(ruby_sourcefile),
8470 rb_filesystem_encoding()));
8471 case keyword__LINE__:
8472 return NEW_LIT(INT2FIX(tokline));
8473 case keyword__ENCODING__:
8474 return NEW_LIT(rb_enc_from_encoding(current_enc));
8476 switch (id_type(id)) {
8478 if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id);
8479 if (local_id(id)) return NEW_LVAR(id);
8480 /* method call without arguments */
8481 return NEW_VCALL(id);
8483 return NEW_GVAR(id);
8485 return NEW_IVAR(id);
8487 return NEW_CONST(id);
8489 return NEW_CVAR(id);
8491 compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
8496 id_is_var_gen(struct parser_params *parser, ID id)
8498 if (is_notop_id(id)) {
8499 switch (id & ID_SCOPE_MASK) {
8500 case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
8503 if (dyna_in_block() && dvar_defined(id)) return 1;
8504 if (local_id(id)) return 1;
8505 /* method call without arguments */
8509 compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
8512 #endif /* !RIPPER */
8516 lex_state_name(enum lex_state_e state)
8518 static const char names[][12] = {
8519 "EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
8520 "EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
8524 if ((unsigned)state & ~(~0u << EXPR_MAX_STATE))
8525 return names[ffs(state)];
8532 assignable_gen(struct parser_params *parser, VALUE lhs)
8535 assignable_gen(struct parser_params *parser, ID id, NODE *val)
8539 ID id = get_id(lhs);
8540 # define assignable_result(x) get_value(lhs)
8541 # define parser_yyerror(parser, x) dispatch1(assign_error, lhs)
8543 # define assignable_result(x) (x)
8545 if (!id) return assignable_result(0);
8548 yyerror("Can't change the value of self");
8551 yyerror("Can't assign to nil");
8554 yyerror("Can't assign to true");
8557 yyerror("Can't assign to false");
8559 case keyword__FILE__:
8560 yyerror("Can't assign to __FILE__");
8562 case keyword__LINE__:
8563 yyerror("Can't assign to __LINE__");
8565 case keyword__ENCODING__:
8566 yyerror("Can't assign to __ENCODING__");
8569 switch (id_type(id)) {
8571 if (dyna_in_block()) {
8572 if (dvar_curr(id)) {
8573 return assignable_result(NEW_DASGN_CURR(id, val));
8575 else if (dvar_defined(id)) {
8576 return assignable_result(NEW_DASGN(id, val));
8578 else if (local_id(id)) {
8579 return assignable_result(NEW_LASGN(id, val));
8583 return assignable_result(NEW_DASGN_CURR(id, val));
8587 if (!local_id(id)) {
8590 return assignable_result(NEW_LASGN(id, val));
8594 return assignable_result(NEW_GASGN(id, val));
8596 return assignable_result(NEW_IASGN(id, val));
8598 if (!in_def && !in_single)
8599 return assignable_result(NEW_CDECL(id, val, 0));
8600 yyerror("dynamic constant assignment");
8603 return assignable_result(NEW_CVASGN(id, val));
8605 compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
8608 return assignable_result(0);
8609 #undef assignable_result
8610 #undef parser_yyerror
8614 is_private_local_id(ID name)
8617 if (name == idUScore) return 1;
8618 if (!is_local_id(name)) return 0;
8619 s = rb_id2str(name);
8621 return RSTRING_PTR(s)[0] == '_';
8624 #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
8627 shadowing_lvar_gen(struct parser_params *parser, ID name)
8629 if (is_private_local_id(name)) return name;
8630 if (dyna_in_block()) {
8631 if (dvar_curr(name)) {
8632 yyerror("duplicated argument name");
8634 else if (dvar_defined_get(name) || local_id(name)) {
8635 rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
8636 vtable_add(lvtbl->vars, name);
8638 vtable_add(lvtbl->used, (ID)ruby_sourceline | LVAR_USED);
8643 if (local_id(name)) {
8644 yyerror("duplicated argument name");
8651 new_bv_gen(struct parser_params *parser, ID name)
8654 if (!is_local_id(name)) {
8655 compile_error(PARSER_ARG "invalid local variable - %s",
8659 shadowing_lvar(name);
8665 aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
8667 if (recv && nd_type(recv) == NODE_SELF)
8669 return NEW_ATTRASGN(recv, tASET, idx);
8673 block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8675 if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
8676 compile_error(PARSER_ARG "both block arg and actual block given");
8681 rb_id_attrset(ID id)
8683 id &= ~ID_SCOPE_MASK;
8689 attrset_gen(struct parser_params *parser, NODE *recv, ID id)
8691 if (recv && nd_type(recv) == NODE_SELF)
8693 return NEW_ATTRASGN(recv, rb_id_attrset(id), 0);
8697 rb_backref_error_gen(struct parser_params *parser, NODE *node)
8699 switch (nd_type(node)) {
8701 compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
8704 compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
8710 arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8712 if (!node2) return node1;
8713 switch (nd_type(node1)) {
8714 case NODE_BLOCK_PASS:
8716 node1->nd_head = arg_concat(node1->nd_head, node2);
8718 node1->nd_head = NEW_LIST(node2);
8721 if (nd_type(node2) != NODE_ARRAY) break;
8722 node1->nd_body = list_concat(NEW_LIST(node1->nd_body), node2);
8723 nd_set_type(node1, NODE_ARGSCAT);
8726 if (nd_type(node2) != NODE_ARRAY ||
8727 nd_type(node1->nd_body) != NODE_ARRAY) break;
8728 node1->nd_body = list_concat(node1->nd_body, node2);
8731 return NEW_ARGSCAT(node1, node2);
8735 arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8737 if (!node1) return NEW_LIST(node2);
8738 switch (nd_type(node1)) {
8740 return list_append(node1, node2);
8741 case NODE_BLOCK_PASS:
8742 node1->nd_head = arg_append(node1->nd_head, node2);
8745 node1->nd_body = list_append(NEW_LIST(node1->nd_body), node2);
8746 nd_set_type(node1, NODE_ARGSCAT);
8749 return NEW_ARGSPUSH(node1, node2);
8753 splat_array(NODE* node)
8755 if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
8756 if (nd_type(node) == NODE_ARRAY) return node;
8761 node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
8765 switch (nd_type(lhs)) {
8771 case NODE_DASGN_CURR:
8775 lhs->nd_value = rhs;
8780 lhs->nd_args = arg_append(lhs->nd_args, rhs);
8784 /* should not happen */
8792 value_expr_gen(struct parser_params *parser, NODE *node)
8797 rb_warning0("empty expression");
8800 switch (nd_type(node)) {
8803 parser_warning(node, "void value expression");
8811 if (!cond) yyerror("void value expression");
8812 /* or "control never reach"? */
8816 while (node->nd_next) {
8817 node = node->nd_next;
8819 node = node->nd_head;
8823 node = node->nd_body;
8827 if (!node->nd_body) {
8828 node = node->nd_else;
8831 else if (!node->nd_else) {
8832 node = node->nd_body;
8835 if (!value_expr(node->nd_body)) return FALSE;
8836 node = node->nd_else;
8842 node = node->nd_2nd;
8854 void_expr_gen(struct parser_params *parser, NODE *node)
8856 const char *useless = 0;
8858 if (!RTEST(ruby_verbose)) return;
8861 switch (nd_type(node)) {
8863 switch (node->nd_mid) {
8882 useless = rb_id2name(node->nd_mid);
8894 useless = "a variable";
8897 useless = "a constant";
8903 case NODE_DREGX_ONCE:
8904 useless = "a literal";
8929 useless = "defined?";
8934 int line = ruby_sourceline;
8936 ruby_sourceline = nd_line(node);
8937 rb_warnS("possibly useless use of %s in void context", useless);
8938 ruby_sourceline = line;
8943 void_stmts_gen(struct parser_params *parser, NODE *node)
8945 if (!RTEST(ruby_verbose)) return;
8947 if (nd_type(node) != NODE_BLOCK) return;
8950 if (!node->nd_next) return;
8951 void_expr0(node->nd_head);
8952 node = node->nd_next;
8957 remove_begin(NODE *node)
8959 NODE **n = &node, *n1 = node;
8960 while (n1 && nd_type(n1) == NODE_BEGIN && n1->nd_body) {
8961 *n = n1 = n1->nd_body;
8967 reduce_nodes_gen(struct parser_params *parser, NODE **body)
8975 #define subnodes(n1, n2) \
8976 ((!node->n1) ? (node->n2 ? (body = &node->n2, 1) : 0) : \
8977 (!node->n2) ? (body = &node->n1, 1) : \
8978 (reduce_nodes(&node->n1), body = &node->n2, 1))
8981 int newline = (int)(node->flags & NODE_FL_NEWLINE);
8982 switch (nd_type(node)) {
8988 *body = node = node->nd_stts;
8989 if (newline && node) node->flags |= NODE_FL_NEWLINE;
8992 *body = node = node->nd_body;
8993 if (newline && node) node->flags |= NODE_FL_NEWLINE;
8996 body = &node->nd_end->nd_head;
8999 if (subnodes(nd_body, nd_else)) break;
9002 body = &node->nd_body;
9005 if (!subnodes(nd_body, nd_next)) goto end;
9008 if (!subnodes(nd_head, nd_resq)) goto end;
9011 if (node->nd_else) {
9012 body = &node->nd_resq;
9015 if (!subnodes(nd_head, nd_resq)) goto end;
9021 if (newline && node) node->flags |= NODE_FL_NEWLINE;
9028 is_static_content(NODE *node)
9030 if (!node) return 1;
9031 switch (nd_type(node)) {
9033 if (!(node = node->nd_head)) break;
9036 if (!is_static_content(node->nd_head)) return 0;
9037 } while ((node = node->nd_next) != 0);
9052 assign_in_cond(struct parser_params *parser, NODE *node)
9054 switch (nd_type(node)) {
9056 yyerror("multiple assignment in conditional");
9061 case NODE_DASGN_CURR:
9070 if (!node->nd_value) return 1;
9071 if (is_static_content(node->nd_value)) {
9072 /* reports always */
9073 parser_warn(node->nd_value, "found = in conditional, should be ==");
9079 warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
9081 if (!e_option_supplied(parser)) parser_warn(node, str);
9085 warning_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
9087 if (!e_option_supplied(parser)) parser_warning(node, str);
9091 fixup_nodes(NODE **rootnode)
9093 NODE *node, *next, *head;
9095 for (node = *rootnode; node; node = next) {
9096 enum node_type type;
9099 next = node->nd_next;
9100 head = node->nd_head;
9101 rb_gc_force_recycle((VALUE)node);
9103 switch (type = nd_type(head)) {
9106 val = rb_range_new(head->nd_beg->nd_lit, head->nd_end->nd_lit,
9108 rb_gc_force_recycle((VALUE)head->nd_beg);
9109 rb_gc_force_recycle((VALUE)head->nd_end);
9110 nd_set_type(head, NODE_LIT);
9119 static NODE *cond0(struct parser_params*,NODE*);
9122 range_op(struct parser_params *parser, NODE *node)
9124 enum node_type type;
9126 if (node == 0) return 0;
9128 type = nd_type(node);
9130 if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
9131 warn_unless_e_option(parser, node, "integer literal in conditional range");
9132 return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."))));
9134 return cond0(parser, node);
9138 literal_node(NODE *node)
9140 if (!node) return 1; /* same as NODE_NIL */
9141 switch (nd_type(node)) {
9147 case NODE_DREGX_ONCE:
9159 cond0(struct parser_params *parser, NODE *node)
9161 if (node == 0) return 0;
9162 assign_in_cond(parser, node);
9164 switch (nd_type(node)) {
9168 rb_warn0("string literal in condition");
9172 case NODE_DREGX_ONCE:
9173 warning_unless_e_option(parser, node, "regex literal in condition");
9174 return NEW_MATCH2(node, NEW_GVAR(rb_intern("$_")));
9178 node->nd_1st = cond0(parser, node->nd_1st);
9179 node->nd_2nd = cond0(parser, node->nd_2nd);
9184 node->nd_beg = range_op(parser, node->nd_beg);
9185 node->nd_end = range_op(parser, node->nd_end);
9186 if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
9187 else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
9188 if (!e_option_supplied(parser)) {
9189 int b = literal_node(node->nd_beg);
9190 int e = literal_node(node->nd_end);
9191 if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
9192 parser_warn(node, "range literal in condition");
9198 parser_warning(node, "literal in condition");
9202 if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
9203 warn_unless_e_option(parser, node, "regex literal in condition");
9204 nd_set_type(node, NODE_MATCH);
9207 parser_warning(node, "literal in condition");
9216 cond_gen(struct parser_params *parser, NODE *node)
9218 if (node == 0) return 0;
9219 return cond0(parser, node);
9223 logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *right)
9226 if (left && (enum node_type)nd_type(left) == type) {
9227 NODE *node = left, *second;
9228 while ((second = node->nd_2nd) != 0 && (enum node_type)nd_type(second) == type) {
9231 node->nd_2nd = NEW_NODE(type, second, right, 0);
9234 return NEW_NODE(type, left, right, 0);
9238 no_blockarg(struct parser_params *parser, NODE *node)
9240 if (node && nd_type(node) == NODE_BLOCK_PASS) {
9241 compile_error(PARSER_ARG "block argument should not be given");
9246 ret_args_gen(struct parser_params *parser, NODE *node)
9249 no_blockarg(parser, node);
9250 if (nd_type(node) == NODE_ARRAY) {
9251 if (node->nd_next == 0) {
9252 node = node->nd_head;
9255 nd_set_type(node, NODE_VALUES);
9263 new_yield_gen(struct parser_params *parser, NODE *node)
9265 if (node) no_blockarg(parser, node);
9267 return NEW_YIELD(node);
9271 negate_lit(NODE *node)
9273 switch (TYPE(node->nd_lit)) {
9275 node->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit));
9278 node->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0);
9282 if (FLONUM_P(node->nd_lit)) {
9283 node->nd_lit = DBL2NUM(-RFLOAT_VALUE(node->nd_lit));
9286 RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
9289 RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
9299 arg_blk_pass(NODE *node1, NODE *node2)
9302 node2->nd_head = node1;
9310 new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, NODE *tail)
9312 int saved_line = ruby_sourceline;
9313 struct rb_args_info *args = tail->nd_ainfo;
9315 args->pre_args_num = m ? rb_long2int(m->nd_plen) : 0;
9316 args->pre_init = m ? m->nd_next : 0;
9318 args->post_args_num = p ? rb_long2int(p->nd_plen) : 0;
9319 args->post_init = p ? p->nd_next : 0;
9320 args->first_post_arg = p ? p->nd_pid : 0;
9326 ruby_sourceline = saved_line;
9332 new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
9334 int saved_line = ruby_sourceline;
9335 struct rb_args_info *args;
9336 NODE *kw_rest_arg = 0;
9339 args = ALLOC(struct rb_args_info);
9340 MEMZERO(args, struct rb_args_info, 1);
9341 node = NEW_NODE(NODE_ARGS, 0, 0, args);
9343 args->block_arg = b;
9345 if (k && !kr) kr = internal_id();
9348 kw_rest_arg = NEW_DVAR(kr);
9350 args->kw_rest_arg = kw_rest_arg;
9352 ruby_sourceline = saved_line;
9357 dsym_node_gen(struct parser_params *parser, NODE *node)
9362 return NEW_LIT(ID2SYM(idNULL));
9365 switch (nd_type(node)) {
9367 nd_set_type(node, NODE_DSYM);
9371 node->nd_lit = ID2SYM(rb_intern_str(lit));
9372 nd_set_type(node, NODE_LIT);
9375 node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node));
9380 #endif /* !RIPPER */
9384 new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
9389 ID vid = lhs->nd_vid;
9391 lhs->nd_value = rhs;
9392 asgn = NEW_OP_ASGN_OR(gettable(vid), lhs);
9393 if (is_asgn_or_id(vid)) {
9397 else if (op == tANDOP) {
9398 lhs->nd_value = rhs;
9399 asgn = NEW_OP_ASGN_AND(gettable(vid), lhs);
9403 asgn->nd_value = NEW_CALL(gettable(vid), op, NEW_LIST(rhs));
9407 asgn = NEW_BEGIN(0);
9413 new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs)
9420 else if (op == tANDOP) {
9423 asgn = NEW_OP_ASGN2(lhs, attr, op, rhs);
9429 new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
9436 else if (op == tANDOP) {
9440 asgn = NEW_OP_CDECL(lhs, op, rhs);
9443 asgn = NEW_BEGIN(0);
9450 new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs)
9452 return dispatch3(opassign, lhs, op, rhs);
9456 new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs)
9458 VALUE recv = dispatch3(field, lhs, type, attr);
9459 return dispatch3(opassign, recv, op, rhs);
9464 warn_unused_var(struct parser_params *parser, struct local_vars *local)
9469 if (!local->used) return;
9470 v = local->vars->tbl;
9471 u = local->used->tbl;
9472 cnt = local->used->pos;
9473 if (cnt != local->vars->pos) {
9474 rb_bug("local->used->pos != local->vars->pos");
9476 for (i = 0; i < cnt; ++i) {
9477 if (!v[i] || (u[i] & LVAR_USED)) continue;
9478 if (is_private_local_id(v[i])) continue;
9479 rb_warn4S(ruby_sourcefile, (int)u[i], "assigned but unused variable - %s", rb_id2name(v[i]));
9484 local_push_gen(struct parser_params *parser, int inherit_dvars)
9486 struct local_vars *local;
9488 local = ALLOC(struct local_vars);
9489 local->prev = lvtbl;
9490 local->args = vtable_alloc(0);
9491 local->vars = vtable_alloc(inherit_dvars ? DVARS_INHERIT : DVARS_TOPSCOPE);
9492 local->used = !(inherit_dvars &&
9493 (ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
9494 RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
9499 local_pop_gen(struct parser_params *parser)
9501 struct local_vars *local = lvtbl->prev;
9503 warn_unused_var(parser, lvtbl);
9504 vtable_free(lvtbl->used);
9506 vtable_free(lvtbl->args);
9507 vtable_free(lvtbl->vars);
9514 vtable_tblcpy(ID *buf, const struct vtable *src)
9516 int i, cnt = vtable_size(src);
9520 for (i = 0; i < cnt; i++) {
9521 buf[i] = src->tbl[i];
9529 local_tbl_gen(struct parser_params *parser)
9531 int cnt = vtable_size(lvtbl->args) + vtable_size(lvtbl->vars);
9534 if (cnt <= 0) return 0;
9535 buf = ALLOC_N(ID, cnt + 1);
9536 vtable_tblcpy(buf+1, lvtbl->args);
9537 vtable_tblcpy(buf+vtable_size(lvtbl->args)+1, lvtbl->vars);
9544 arg_var_gen(struct parser_params *parser, ID id)
9546 vtable_add(lvtbl->args, id);
9547 return vtable_size(lvtbl->args) - 1;
9551 local_var_gen(struct parser_params *parser, ID id)
9553 vtable_add(lvtbl->vars, id);
9555 vtable_add(lvtbl->used, (ID)ruby_sourceline);
9557 return vtable_size(lvtbl->vars) - 1;
9561 local_id_gen(struct parser_params *parser, ID id)
9563 struct vtable *vars, *args, *used;
9569 while (vars && POINTER_P(vars->prev)) {
9572 if (used) used = used->prev;
9575 if (vars && vars->prev == DVARS_INHERIT) {
9576 return rb_local_defined(id);
9578 else if (vtable_included(args, id)) {
9582 int i = vtable_included(vars, id);
9583 if (i && used) used->tbl[i-1] |= LVAR_USED;
9588 static const struct vtable *
9589 dyna_push_gen(struct parser_params *parser)
9591 lvtbl->args = vtable_alloc(lvtbl->args);
9592 lvtbl->vars = vtable_alloc(lvtbl->vars);
9594 lvtbl->used = vtable_alloc(lvtbl->used);
9600 dyna_pop_1(struct parser_params *parser)
9604 if ((tmp = lvtbl->used) != 0) {
9605 warn_unused_var(parser, lvtbl);
9606 lvtbl->used = lvtbl->used->prev;
9610 lvtbl->args = lvtbl->args->prev;
9613 lvtbl->vars = lvtbl->vars->prev;
9618 dyna_pop_gen(struct parser_params *parser, const struct vtable *lvargs)
9620 while (lvtbl->args != lvargs) {
9623 struct local_vars *local = lvtbl->prev;
9632 dyna_in_block_gen(struct parser_params *parser)
9634 return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
9638 dvar_defined_gen(struct parser_params *parser, ID id, int get)
9640 struct vtable *vars, *args, *used;
9647 while (POINTER_P(vars)) {
9648 if (vtable_included(args, id)) {
9651 if ((i = vtable_included(vars, id)) != 0) {
9652 if (used) used->tbl[i-1] |= LVAR_USED;
9658 if (used) used = used->prev;
9661 if (vars == DVARS_INHERIT) {
9662 return rb_dvar_defined(id);
9669 dvar_curr_gen(struct parser_params *parser, ID id)
9671 return (vtable_included(lvtbl->args, id) ||
9672 vtable_included(lvtbl->vars, id));
9677 reg_fragment_setenc_gen(struct parser_params* parser, VALUE str, int options)
9679 int c = RE_OPTION_ENCODING_IDX(options);
9683 rb_char_to_option_kcode(c, &opt, &idx);
9684 if (idx != ENCODING_GET(str) &&
9685 rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
9688 ENCODING_SET(str, idx);
9690 else if (RE_OPTION_ENCODING_NONE(options)) {
9691 if (!ENCODING_IS_ASCII8BIT(str) &&
9692 rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
9696 rb_enc_associate(str, rb_ascii8bit_encoding());
9698 else if (current_enc == rb_usascii_encoding()) {
9699 if (rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
9701 rb_enc_associate(str, rb_usascii_encoding());
9704 rb_enc_associate(str, rb_ascii8bit_encoding());
9710 compile_error(PARSER_ARG
9711 "regexp encoding option '%c' differs from source encoding '%s'",
9712 c, rb_enc_name(rb_enc_get(str)));
9716 reg_fragment_check_gen(struct parser_params* parser, VALUE str, int options)
9719 reg_fragment_setenc(str, options);
9720 err = rb_reg_check_preprocess(str);
9722 err = rb_obj_as_string(err);
9723 compile_error(PARSER_ARG "%s", RSTRING_PTR(err));
9731 struct parser_params* parser;
9736 } reg_named_capture_assign_t;
9739 reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
9740 int back_num, int *back_refs, OnigRegex regex, void *arg0)
9742 reg_named_capture_assign_t *arg = (reg_named_capture_assign_t*)arg0;
9743 struct parser_params* parser = arg->parser;
9744 rb_encoding *enc = arg->enc;
9745 long len = name_end - name;
9746 const char *s = (const char *)name;
9751 if (arg->succ_block == 0) {
9752 arg->succ_block = NEW_BEGIN(0);
9753 arg->fail_block = NEW_BEGIN(0);
9756 if (!len || (*name != '_' && ISASCII(*name) && !rb_enc_islower(*name, enc)) ||
9757 (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) ||
9758 !rb_enc_symname2_p(s, len, enc)) {
9761 var = rb_intern3(s, len, enc);
9762 if (dvar_defined(var) || local_id(var)) {
9763 rb_warningS("named capture conflicts a local variable - %s",
9766 arg->succ_block = block_append(arg->succ_block,
9767 newline_node(node_assign(assignable(var,0),
9769 gettable(rb_intern("$~")),
9771 NEW_LIST(NEW_LIT(ID2SYM(var))))
9773 arg->fail_block = block_append(arg->fail_block,
9774 newline_node(node_assign(assignable(var,0), NEW_LIT(Qnil))));
9779 reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match)
9781 reg_named_capture_assign_t arg;
9783 arg.parser = parser;
9784 arg.enc = rb_enc_get(regexp);
9788 onig_foreach_name(RREGEXP(regexp)->ptr, reg_named_capture_assign_iter, (void*)&arg);
9795 newline_node(match),
9796 NEW_IF(gettable(rb_intern("$~")),
9798 newline_node(arg.succ_block),
9801 gettable(rb_intern("$~")),
9803 NEW_LIST(NEW_LIT(INT2FIX(0)))))),
9805 newline_node(arg.fail_block),
9811 reg_compile_gen(struct parser_params* parser, VALUE str, int options)
9816 reg_fragment_setenc(str, options);
9818 re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
9820 ID mesg = rb_intern("mesg");
9821 VALUE m = rb_attr_get(rb_errinfo(), mesg);
9822 rb_set_errinfo(err);
9824 rb_str_append(rb_str_cat(rb_attr_get(err, mesg), "\n", 1), m);
9827 compile_error(PARSER_ARG "%s", RSTRING_PTR(m));
9835 rb_gc_mark_parser(void)
9840 rb_parser_append_print(VALUE vparser, NODE *node)
9844 struct parser_params *parser;
9846 if (!node) return node;
9848 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
9850 node = node->nd_body;
9852 if (nd_type(node) == NODE_PRELUDE) {
9854 node = node->nd_body;
9857 node = block_append(node,
9858 NEW_FCALL(rb_intern("print"),
9859 NEW_ARRAY(NEW_GVAR(rb_intern("$_")))));
9861 prelude->nd_body = node;
9862 scope->nd_body = prelude;
9865 scope->nd_body = node;
9872 rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
9876 struct parser_params *parser;
9878 if (!node) return node;
9880 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
9882 node = node->nd_body;
9884 if (nd_type(node) == NODE_PRELUDE) {
9886 node = node->nd_body;
9889 node = block_append(NEW_GASGN(rb_intern("$F"),
9890 NEW_CALL(NEW_GVAR(rb_intern("$_")),
9891 rb_intern("split"), 0)),
9895 node = block_append(NEW_CALL(NEW_GVAR(rb_intern("$_")),
9896 rb_intern("chop!"), 0), node);
9899 node = NEW_OPT_N(node);
9902 prelude->nd_body = node;
9903 scope->nd_body = prelude;
9906 scope->nd_body = node;
9912 static const struct {
9937 #define op_tbl_count numberof(op_tbl)
9939 #ifndef ENABLE_SELECTOR_NAMESPACE
9940 #define ENABLE_SELECTOR_NAMESPACE 0
9943 static struct symbols {
9947 #if ENABLE_SELECTOR_NAMESPACE
9951 VALUE op_sym[tLAST_OP_ID];
9952 } global_symbols = {tLAST_TOKEN};
9954 static const struct st_hash_type symhash = {
9959 #if ENABLE_SELECTOR_NAMESPACE
9966 ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2)
9968 if (key1->id == key2->id && key1->klass == key2->klass) {
9975 ivar2_hash(struct ivar2_key *key)
9977 return (key->id << 8) ^ (key->klass >> 2);
9980 static const struct st_hash_type ivar2_hash_type = {
9989 global_symbols.sym_id = st_init_table_with_size(&symhash, 1000);
9990 global_symbols.id_str = st_init_numtable_with_size(1000);
9991 #if ENABLE_SELECTOR_NAMESPACE
9992 global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
9993 global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
9999 (void)lex_state_name(-1);
10006 rb_gc_mark_symbols(void)
10008 rb_mark_tbl(global_symbols.id_str);
10009 rb_gc_mark_locations(global_symbols.op_sym,
10010 global_symbols.op_sym + numberof(global_symbols.op_sym));
10012 #endif /* !RIPPER */
10015 internal_id_gen(struct parser_params *parser)
10017 ID id = (ID)vtable_size(lvtbl->args) + (ID)vtable_size(lvtbl->vars);
10018 id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1;
10019 return ID_INTERNAL | (id << ID_SCOPE_SHIFT);
10024 is_special_global_name(const char *m, const char *e, rb_encoding *enc)
10028 if (m >= e) return 0;
10029 if (is_global_name_punct(*m)) {
10032 else if (*m == '-') {
10034 if (m < e && is_identchar(m, e, enc)) {
10035 if (!ISASCII(*m)) mb = 1;
10036 m += rb_enc_mbclen(m, e, enc);
10040 if (!rb_enc_isdigit(*m, enc)) return 0;
10042 if (!ISASCII(*m)) mb = 1;
10044 } while (m < e && rb_enc_isdigit(*m, enc));
10046 return m == e ? mb + 1 : 0;
10050 rb_symname_p(const char *name)
10052 return rb_enc_symname_p(name, rb_ascii8bit_encoding());
10056 rb_enc_symname_p(const char *name, rb_encoding *enc)
10058 return rb_enc_symname2_p(name, strlen(name), enc);
10062 rb_enc_symname_type(const char *name, long len, rb_encoding *enc)
10064 const char *m = name;
10065 const char *e = m + len;
10066 int type = ID_JUNK;
10068 if (!m || len <= 0) return -1;
10075 if (is_special_global_name(++m, e, enc)) return type;
10079 type = ID_INSTANCE;
10088 case '<': ++m; break;
10089 case '=': if (*++m == '>') ++m; break;
10096 case '>': case '=': ++m; break;
10102 case '~': ++m; break;
10103 case '=': if (*++m == '=') ++m; break;
10104 default: return -1;
10109 if (*++m == '*') ++m;
10112 case '+': case '-':
10113 if (*++m == '@') ++m;
10116 case '|': case '^': case '&': case '/': case '%': case '~': case '`':
10121 if (*++m != ']') return -1;
10122 if (*++m == '=') ++m;
10126 if (len == 1) return ID_JUNK;
10128 case '=': case '~': ++m; break;
10129 default: return -1;
10134 type = rb_enc_isupper(*m, enc) ? ID_CONST : ID_LOCAL;
10136 if (m >= e || (*m != '_' && !rb_enc_isalpha(*m, enc) && ISASCII(*m)))
10138 while (m < e && is_identchar(m, e, enc)) m += rb_enc_mbclen(m, e, enc);
10140 case '!': case '?':
10141 if (type == ID_GLOBAL || type == ID_CLASS || type == ID_INSTANCE) return -1;
10146 if (type != ID_CONST && type != ID_LOCAL) return -1;
10153 return m == e ? type : -1;
10157 rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
10159 return rb_enc_symname_type(name, len, enc) != -1;
10163 rb_str_symname_type(VALUE name)
10165 const char *ptr = StringValuePtr(name);
10166 long len = RSTRING_LEN(name);
10167 int type = rb_enc_symname_type(ptr, len, rb_enc_get(name));
10173 register_symid(ID id, const char *name, long len, rb_encoding *enc)
10175 VALUE str = rb_enc_str_new(name, len, enc);
10176 return register_symid_str(id, str);
10180 register_symid_str(ID id, VALUE str)
10183 st_add_direct(global_symbols.sym_id, (st_data_t)str, id);
10184 st_add_direct(global_symbols.id_str, id, (st_data_t)str);
10189 sym_check_asciionly(VALUE str)
10191 if (!rb_enc_asciicompat(rb_enc_get(str))) return FALSE;
10192 switch (rb_enc_str_coderange(str)) {
10193 case ENC_CODERANGE_BROKEN:
10194 rb_raise(rb_eEncodingError, "invalid encoding symbol");
10195 case ENC_CODERANGE_7BIT:
10202 * _str_ itself will be registered at the global symbol table. _str_
10203 * can be modified before the registration, since the encoding will be
10204 * set to ASCII-8BIT if it is a special global name.
10206 static ID intern_str(VALUE str);
10209 rb_intern3(const char *name, long len, rb_encoding *enc)
10213 struct RString fake_str;
10214 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10215 fake_str.basic.klass = rb_cString;
10216 fake_str.as.heap.len = len;
10217 fake_str.as.heap.ptr = (char *)name;
10218 fake_str.as.heap.aux.capa = len;
10219 str = (VALUE)&fake_str;
10220 rb_enc_associate(str, enc);
10223 if (st_lookup(global_symbols.sym_id, str, &data))
10226 str = rb_enc_str_new(name, len, enc); /* make true string */
10227 return intern_str(str);
10231 intern_str(VALUE str)
10233 const char *name, *m, *e;
10235 rb_encoding *enc, *symenc;
10240 RSTRING_GETMEM(str, name, len);
10243 enc = rb_enc_get(str);
10246 if (rb_cString && !rb_enc_asciicompat(enc)) {
10255 if ((mb = is_special_global_name(++m, e, enc)) != 0) {
10256 if (!--mb) symenc = rb_usascii_encoding();
10272 if (c != '_' && rb_enc_isascii(c, enc) && rb_enc_ispunct(c, enc)) {
10280 for (i = 0; i < op_tbl_count; i++) {
10281 if (*op_tbl[i].name == *m &&
10282 strcmp(op_tbl[i].name, m) == 0) {
10283 id = op_tbl[i].token;
10289 if (m[last] == '=') {
10290 /* attribute assignment */
10291 id = rb_intern3(name, last, enc);
10292 if (id > tLAST_OP_ID && !is_attrset_id(id)) {
10293 enc = rb_enc_get(rb_id2str(id));
10294 id = rb_id_attrset(id);
10299 else if (rb_enc_isupper(m[0], enc)) {
10307 if (!rb_enc_isdigit(*m, enc)) {
10308 while (m <= name + last && is_identchar(m, e, enc)) {
10313 m += rb_enc_mbclen(m, e, enc);
10317 if (m - name < len) id = ID_JUNK;
10318 if (sym_check_asciionly(str)) symenc = rb_usascii_encoding();
10320 if (symenc != enc) rb_enc_associate(str, symenc);
10321 if (global_symbols.last_id >= ~(ID)0 >> (ID_SCOPE_SHIFT+RUBY_SPECIAL_SHIFT)) {
10323 rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.20s...)",
10327 rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.*s)",
10331 id |= ++global_symbols.last_id << ID_SCOPE_SHIFT;
10333 return register_symid_str(id, str);
10337 rb_intern2(const char *name, long len)
10339 return rb_intern3(name, len, rb_usascii_encoding());
10344 rb_intern(const char *name)
10346 return rb_intern2(name, strlen(name));
10350 rb_intern_str(VALUE str)
10354 if (st_lookup(global_symbols.sym_id, str, &id))
10356 return intern_str(rb_str_dup(str));
10364 if (id < tLAST_TOKEN) {
10367 if (id < INT_MAX && rb_ispunct((int)id)) {
10368 VALUE str = global_symbols.op_sym[i = (int)id];
10371 name[0] = (char)id;
10373 str = rb_usascii_str_new(name, 1);
10375 global_symbols.op_sym[i] = str;
10379 for (i = 0; i < op_tbl_count; i++) {
10380 if (op_tbl[i].token == id) {
10381 VALUE str = global_symbols.op_sym[i];
10383 str = rb_usascii_str_new2(op_tbl[i].name);
10385 global_symbols.op_sym[i] = str;
10392 if (st_lookup(global_symbols.id_str, id, &data)) {
10393 VALUE str = (VALUE)data;
10394 if (RBASIC(str)->klass == 0)
10395 RBASIC(str)->klass = rb_cString;
10399 if (is_attrset_id(id)) {
10400 ID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL;
10403 while (!(str = rb_id2str(id2))) {
10404 if (!is_local_id(id2)) return 0;
10405 id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;
10407 str = rb_str_dup(str);
10408 rb_str_cat(str, "=", 1);
10409 rb_intern_str(str);
10410 if (st_lookup(global_symbols.id_str, id, &data)) {
10411 VALUE str = (VALUE)data;
10412 if (RBASIC(str)->klass == 0)
10413 RBASIC(str)->klass = rb_cString;
10423 VALUE str = rb_id2str(id);
10425 if (!str) return 0;
10426 return RSTRING_PTR(str);
10430 symbols_i(VALUE sym, ID value, VALUE ary)
10432 rb_ary_push(ary, ID2SYM(value));
10433 return ST_CONTINUE;
10438 * Symbol.all_symbols => array
10440 * Returns an array of all the symbols currently in Ruby's symbol
10443 * Symbol.all_symbols.size #=> 903
10444 * Symbol.all_symbols[1,20] #=> [:floor, :ARGV, :Binding, :symlink,
10445 * :chown, :EOFError, :$;, :String,
10446 * :LOCK_SH, :"setuid?", :$<,
10447 * :default_proc, :compact, :extend,
10448 * :Tms, :getwd, :$=, :ThreadGroup,
10453 rb_sym_all_symbols(void)
10455 VALUE ary = rb_ary_new2(global_symbols.sym_id->num_entries);
10457 st_foreach(global_symbols.sym_id, symbols_i, ary);
10462 rb_is_const_id(ID id)
10464 return is_const_id(id);
10468 rb_is_class_id(ID id)
10470 return is_class_id(id);
10474 rb_is_global_id(ID id)
10476 return is_global_id(id);
10480 rb_is_instance_id(ID id)
10482 return is_instance_id(id);
10486 rb_is_attrset_id(ID id)
10488 return is_attrset_id(id);
10492 rb_is_local_id(ID id)
10494 return is_local_id(id);
10498 rb_is_junk_id(ID id)
10500 return is_junk_id(id);
10504 * Returns ID for the given name if it is interned already, or 0.
10506 * \param namep the pointer to the name object
10507 * \return the ID for *namep
10508 * \pre the object referred by \p namep must be a Symbol or
10509 * a String, or possible to convert with to_str method.
10510 * \post the object referred by \p namep is a Symbol or a
10511 * String if non-zero value is returned, or is a String
10512 * if 0 is returned.
10515 rb_check_id(volatile VALUE *namep)
10519 VALUE name = *namep;
10521 if (SYMBOL_P(name)) {
10522 return SYM2ID(name);
10524 else if (!RB_TYPE_P(name, T_STRING)) {
10525 tmp = rb_check_string_type(name);
10527 tmp = rb_inspect(name);
10528 rb_raise(rb_eTypeError, "%s is not a symbol",
10535 sym_check_asciionly(name);
10537 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10540 if (rb_is_attrset_name(name)) {
10541 struct RString fake_str;
10542 const VALUE localname = (VALUE)&fake_str;
10543 /* make local name by chopping '=' */
10544 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10545 fake_str.basic.klass = rb_cString;
10546 fake_str.as.heap.len = RSTRING_LEN(name) - 1;
10547 fake_str.as.heap.ptr = RSTRING_PTR(name);
10548 fake_str.as.heap.aux.capa = fake_str.as.heap.len;
10549 rb_enc_copy(localname, name);
10550 OBJ_FREEZE(localname);
10552 if (st_lookup(global_symbols.sym_id, (st_data_t)localname, &id)) {
10553 return rb_id_attrset((ID)id);
10562 rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
10565 struct RString fake_str;
10566 const VALUE name = (VALUE)&fake_str;
10567 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10568 fake_str.basic.klass = rb_cString;
10569 fake_str.as.heap.len = len;
10570 fake_str.as.heap.ptr = (char *)ptr;
10571 fake_str.as.heap.aux.capa = len;
10572 rb_enc_associate(name, enc);
10574 sym_check_asciionly(name);
10576 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10579 if (rb_is_attrset_name(name)) {
10580 fake_str.as.heap.len = len - 1;
10581 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id)) {
10582 return rb_id_attrset((ID)id);
10590 rb_is_const_name(VALUE name)
10592 return rb_str_symname_type(name) == ID_CONST;
10596 rb_is_class_name(VALUE name)
10598 return rb_str_symname_type(name) == ID_CLASS;
10602 rb_is_global_name(VALUE name)
10604 return rb_str_symname_type(name) == ID_GLOBAL;
10608 rb_is_instance_name(VALUE name)
10610 return rb_str_symname_type(name) == ID_INSTANCE;
10614 rb_is_attrset_name(VALUE name)
10616 return rb_str_symname_type(name) == ID_ATTRSET;
10620 rb_is_local_name(VALUE name)
10622 return rb_str_symname_type(name) == ID_LOCAL;
10626 rb_is_method_name(VALUE name)
10628 switch (rb_str_symname_type(name)) {
10629 case ID_LOCAL: case ID_ATTRSET: case ID_JUNK:
10636 rb_is_junk_name(VALUE name)
10638 return rb_str_symname_type(name) == -1;
10641 #endif /* !RIPPER */
10644 parser_initialize(struct parser_params *parser)
10646 parser->eofp = Qfalse;
10648 parser->parser_lex_strterm = 0;
10649 parser->parser_cond_stack = 0;
10650 parser->parser_cmdarg_stack = 0;
10651 parser->parser_class_nest = 0;
10652 parser->parser_paren_nest = 0;
10653 parser->parser_lpar_beg = 0;
10654 parser->parser_brace_nest = 0;
10655 parser->parser_in_single = 0;
10656 parser->parser_in_def = 0;
10657 parser->parser_in_defined = 0;
10658 parser->parser_compile_for_eval = 0;
10659 parser->parser_cur_mid = 0;
10660 parser->parser_tokenbuf = NULL;
10661 parser->parser_tokidx = 0;
10662 parser->parser_toksiz = 0;
10663 parser->parser_heredoc_end = 0;
10664 parser->parser_command_start = TRUE;
10665 parser->parser_deferred_nodes = 0;
10666 parser->parser_lex_pbeg = 0;
10667 parser->parser_lex_p = 0;
10668 parser->parser_lex_pend = 0;
10669 parser->parser_lvtbl = 0;
10670 parser->parser_ruby__end__seen = 0;
10671 parser->parser_ruby_sourcefile = 0;
10673 parser->is_ripper = 0;
10674 parser->parser_eval_tree_begin = 0;
10675 parser->parser_eval_tree = 0;
10677 parser->is_ripper = 1;
10678 parser->parser_ruby_sourcefile_string = Qnil;
10679 parser->delayed = Qnil;
10681 parser->result = Qnil;
10682 parser->parsing_thread = Qnil;
10683 parser->toplevel_p = TRUE;
10686 parser->heap = NULL;
10688 parser->enc = rb_utf8_encoding();
10692 #define parser_mark ripper_parser_mark
10693 #define parser_free ripper_parser_free
10697 parser_mark(void *ptr)
10699 struct parser_params *p = (struct parser_params*)ptr;
10701 rb_gc_mark((VALUE)p->parser_lex_strterm);
10702 rb_gc_mark((VALUE)p->parser_deferred_nodes);
10703 rb_gc_mark(p->parser_lex_input);
10704 rb_gc_mark(p->parser_lex_lastline);
10705 rb_gc_mark(p->parser_lex_nextline);
10707 rb_gc_mark((VALUE)p->parser_eval_tree_begin) ;
10708 rb_gc_mark((VALUE)p->parser_eval_tree) ;
10709 rb_gc_mark(p->debug_lines);
10711 rb_gc_mark(p->parser_ruby_sourcefile_string);
10712 rb_gc_mark(p->delayed);
10713 rb_gc_mark(p->value);
10714 rb_gc_mark(p->result);
10715 rb_gc_mark(p->parsing_thread);
10718 rb_gc_mark((VALUE)p->heap);
10723 parser_free(void *ptr)
10725 struct parser_params *p = (struct parser_params*)ptr;
10726 struct local_vars *local, *prev;
10728 if (p->parser_tokenbuf) {
10729 xfree(p->parser_tokenbuf);
10731 for (local = p->parser_lvtbl; local; local = prev) {
10732 if (local->vars) xfree(local->vars);
10733 prev = local->prev;
10737 xfree(p->parser_ruby_sourcefile);
10743 parser_memsize(const void *ptr)
10745 struct parser_params *p = (struct parser_params*)ptr;
10746 struct local_vars *local;
10747 size_t size = sizeof(*p);
10749 if (!ptr) return 0;
10750 size += p->parser_toksiz;
10751 for (local = p->parser_lvtbl; local; local = local->prev) {
10752 size += sizeof(*local);
10753 if (local->vars) size += local->vars->capa * sizeof(ID);
10756 if (p->parser_ruby_sourcefile) {
10757 size += strlen(p->parser_ruby_sourcefile) + 1;
10767 rb_data_type_t parser_data_type = {
10777 #undef rb_reserved_word
10779 const struct kwtable *
10780 rb_reserved_word(const char *str, unsigned int len)
10782 return reserved_word(str, len);
10785 static struct parser_params *
10788 struct parser_params *p;
10790 p = ALLOC_N(struct parser_params, 1);
10791 MEMZERO(p, struct parser_params, 1);
10792 parser_initialize(p);
10797 rb_parser_new(void)
10799 struct parser_params *p = parser_new();
10801 return TypedData_Wrap_Struct(0, &parser_data_type, p);
10806 * ripper#end_seen? -> Boolean
10808 * Return true if parsed source ended by +\_\_END\_\_+.
10811 rb_parser_end_seen_p(VALUE vparser)
10813 struct parser_params *parser;
10815 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10816 return ruby__end__seen ? Qtrue : Qfalse;
10821 * ripper#encoding -> encoding
10823 * Return encoding of the source.
10826 rb_parser_encoding(VALUE vparser)
10828 struct parser_params *parser;
10830 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10831 return rb_enc_from_encoding(current_enc);
10836 * ripper.yydebug -> true or false
10841 rb_parser_get_yydebug(VALUE self)
10843 struct parser_params *parser;
10845 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10846 return yydebug ? Qtrue : Qfalse;
10851 * ripper.yydebug = flag
10856 rb_parser_set_yydebug(VALUE self, VALUE flag)
10858 struct parser_params *parser;
10860 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10861 yydebug = RTEST(flag);
10866 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
10867 #define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
10868 #define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
10869 (n)->u3.cnt = (c), (p))
10872 rb_parser_malloc(struct parser_params *parser, size_t size)
10874 size_t cnt = HEAPCNT(1, size);
10875 NODE *n = NEWHEAP();
10876 void *ptr = xmalloc(size);
10878 return ADD2HEAP(n, cnt, ptr);
10882 rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
10884 size_t cnt = HEAPCNT(nelem, size);
10885 NODE *n = NEWHEAP();
10886 void *ptr = xcalloc(nelem, size);
10888 return ADD2HEAP(n, cnt, ptr);
10892 rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
10895 size_t cnt = HEAPCNT(1, size);
10897 if (ptr && (n = parser->heap) != NULL) {
10899 if (n->u1.node == ptr) {
10900 n->u1.node = ptr = xrealloc(ptr, size);
10901 if (n->u3.cnt) n->u3.cnt = cnt;
10904 } while ((n = n->u2.node) != NULL);
10907 ptr = xrealloc(ptr, size);
10908 return ADD2HEAP(n, cnt, ptr);
10912 rb_parser_free(struct parser_params *parser, void *ptr)
10914 NODE **prev = &parser->heap, *n;
10916 while ((n = *prev) != NULL) {
10917 if (n->u1.node == ptr) {
10918 *prev = n->u2.node;
10919 rb_gc_force_recycle((VALUE)n);
10922 prev = &n->u2.node;
10930 #ifdef RIPPER_DEBUG
10931 extern int rb_is_pointer_to_heap(VALUE);
10935 ripper_validate_object(VALUE self, VALUE x)
10937 if (x == Qfalse) return x;
10938 if (x == Qtrue) return x;
10939 if (x == Qnil) return x;
10941 rb_raise(rb_eArgError, "Qundef given");
10942 if (FIXNUM_P(x)) return x;
10943 if (SYMBOL_P(x)) return x;
10944 if (!rb_is_pointer_to_heap(x))
10945 rb_raise(rb_eArgError, "invalid pointer: %p", x);
10954 if (nd_type(x) != NODE_LASGN) {
10955 rb_raise(rb_eArgError, "NODE given: %p", x);
10957 return ((NODE *)x)->nd_rval;
10959 rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
10960 x, rb_obj_classname(x));
10966 #define validate(x) ((x) = get_value(x))
10969 ripper_dispatch0(struct parser_params *parser, ID mid)
10971 return rb_funcall(parser->value, mid, 0);
10975 ripper_dispatch1(struct parser_params *parser, ID mid, VALUE a)
10978 return rb_funcall(parser->value, mid, 1, a);
10982 ripper_dispatch2(struct parser_params *parser, ID mid, VALUE a, VALUE b)
10986 return rb_funcall(parser->value, mid, 2, a, b);
10990 ripper_dispatch3(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c)
10995 return rb_funcall(parser->value, mid, 3, a, b, c);
10999 ripper_dispatch4(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d)
11005 return rb_funcall(parser->value, mid, 4, a, b, c, d);
11009 ripper_dispatch5(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e)
11016 return rb_funcall(parser->value, mid, 5, a, b, c, d, e);
11020 ripper_dispatch7(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g)
11029 return rb_funcall(parser->value, mid, 7, a, b, c, d, e, f, g);
11032 static const struct kw_assoc {
11035 } keyword_to_name[] = {
11036 {keyword_class, "class"},
11037 {keyword_module, "module"},
11038 {keyword_def, "def"},
11039 {keyword_undef, "undef"},
11040 {keyword_begin, "begin"},
11041 {keyword_rescue, "rescue"},
11042 {keyword_ensure, "ensure"},
11043 {keyword_end, "end"},
11044 {keyword_if, "if"},
11045 {keyword_unless, "unless"},
11046 {keyword_then, "then"},
11047 {keyword_elsif, "elsif"},
11048 {keyword_else, "else"},
11049 {keyword_case, "case"},
11050 {keyword_when, "when"},
11051 {keyword_while, "while"},
11052 {keyword_until, "until"},
11053 {keyword_for, "for"},
11054 {keyword_break, "break"},
11055 {keyword_next, "next"},
11056 {keyword_redo, "redo"},
11057 {keyword_retry, "retry"},
11058 {keyword_in, "in"},
11059 {keyword_do, "do"},
11060 {keyword_do_cond, "do"},
11061 {keyword_do_block, "do"},
11062 {keyword_return, "return"},
11063 {keyword_yield, "yield"},
11064 {keyword_super, "super"},
11065 {keyword_self, "self"},
11066 {keyword_nil, "nil"},
11067 {keyword_true, "true"},
11068 {keyword_false, "false"},
11069 {keyword_and, "and"},
11070 {keyword_or, "or"},
11071 {keyword_not, "not"},
11072 {modifier_if, "if"},
11073 {modifier_unless, "unless"},
11074 {modifier_while, "while"},
11075 {modifier_until, "until"},
11076 {modifier_rescue, "rescue"},
11077 {keyword_alias, "alias"},
11078 {keyword_defined, "defined?"},
11079 {keyword_BEGIN, "BEGIN"},
11080 {keyword_END, "END"},
11081 {keyword__LINE__, "__LINE__"},
11082 {keyword__FILE__, "__FILE__"},
11083 {keyword__ENCODING__, "__ENCODING__"},
11088 keyword_id_to_str(ID id)
11090 const struct kw_assoc *a;
11092 for (a = keyword_to_name; a->id; a++) {
11099 #undef ripper_id2sym
11101 ripper_id2sym(ID id)
11109 return ID2SYM(rb_intern2(buf, 1));
11111 if ((name = keyword_id_to_str(id))) {
11112 return ID2SYM(rb_intern(name));
11122 name = rb_id2name(id);
11124 rb_bug("cannot convert ID to string: %ld", (unsigned long)id);
11128 return ID2SYM(rb_intern(name));
11132 ripper_get_id(VALUE v)
11135 if (!RB_TYPE_P(v, T_NODE)) return 0;
11137 if (nd_type(nd) != NODE_LASGN) return 0;
11142 ripper_get_value(VALUE v)
11145 if (v == Qundef) return Qnil;
11146 if (!RB_TYPE_P(v, T_NODE)) return v;
11148 if (nd_type(nd) != NODE_LASGN) return Qnil;
11149 return nd->nd_rval;
11153 ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
11158 va_start(args, fmt);
11159 str = rb_vsprintf(fmt, args);
11161 rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
11165 ripper_warn0(struct parser_params *parser, const char *fmt)
11167 rb_funcall(parser->value, rb_intern("warn"), 1, STR_NEW2(fmt));
11171 ripper_warnI(struct parser_params *parser, const char *fmt, int a)
11173 rb_funcall(parser->value, rb_intern("warn"), 2,
11174 STR_NEW2(fmt), INT2NUM(a));
11178 ripper_warnS(struct parser_params *parser, const char *fmt, const char *str)
11180 rb_funcall(parser->value, rb_intern("warn"), 2,
11181 STR_NEW2(fmt), STR_NEW2(str));
11185 ripper_warning0(struct parser_params *parser, const char *fmt)
11187 rb_funcall(parser->value, rb_intern("warning"), 1, STR_NEW2(fmt));
11191 ripper_warningS(struct parser_params *parser, const char *fmt, const char *str)
11193 rb_funcall(parser->value, rb_intern("warning"), 2,
11194 STR_NEW2(fmt), STR_NEW2(str));
11198 ripper_lex_get_generic(struct parser_params *parser, VALUE src)
11200 return rb_io_gets(src);
11204 ripper_s_allocate(VALUE klass)
11206 struct parser_params *p;
11209 p = ALLOC_N(struct parser_params, 1);
11210 MEMZERO(p, struct parser_params, 1);
11211 self = TypedData_Wrap_Struct(klass, &parser_data_type, p);
11216 #define ripper_initialized_p(r) ((r)->parser_lex_input != 0)
11220 * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
11222 * Create a new Ripper object.
11223 * _src_ must be a String, an IO, or an Object which has #gets method.
11225 * This method does not starts parsing.
11226 * See also Ripper#parse and Ripper.parse.
11229 ripper_initialize(int argc, VALUE *argv, VALUE self)
11231 struct parser_params *parser;
11232 VALUE src, fname, lineno;
11234 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11235 rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
11236 if (RB_TYPE_P(src, T_FILE)) {
11237 parser->parser_lex_gets = ripper_lex_get_generic;
11241 parser->parser_lex_gets = lex_get_str;
11243 parser->parser_lex_input = src;
11244 parser->eofp = Qfalse;
11245 if (NIL_P(fname)) {
11246 fname = STR_NEW2("(ripper)");
11249 StringValue(fname);
11251 parser_initialize(parser);
11253 parser->parser_ruby_sourcefile_string = fname;
11254 parser->parser_ruby_sourcefile = RSTRING_PTR(fname);
11255 parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
11260 struct ripper_args {
11261 struct parser_params *parser;
11267 ripper_parse0(VALUE parser_v)
11269 struct parser_params *parser;
11271 TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11272 parser_prepare(parser);
11273 ripper_yyparse((void*)parser);
11274 return parser->result;
11278 ripper_ensure(VALUE parser_v)
11280 struct parser_params *parser;
11282 TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11283 parser->parsing_thread = Qnil;
11291 * Start parsing and returns the value of the root action.
11294 ripper_parse(VALUE self)
11296 struct parser_params *parser;
11298 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11299 if (!ripper_initialized_p(parser)) {
11300 rb_raise(rb_eArgError, "method called for uninitialized object");
11302 if (!NIL_P(parser->parsing_thread)) {
11303 if (parser->parsing_thread == rb_thread_current())
11304 rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
11306 rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
11308 parser->parsing_thread = rb_thread_current();
11309 rb_ensure(ripper_parse0, self, ripper_ensure, self);
11311 return parser->result;
11316 * ripper#column -> Integer
11318 * Return column number of current parsing line.
11319 * This number starts from 0.
11322 ripper_column(VALUE self)
11324 struct parser_params *parser;
11327 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11328 if (!ripper_initialized_p(parser)) {
11329 rb_raise(rb_eArgError, "method called for uninitialized object");
11331 if (NIL_P(parser->parsing_thread)) return Qnil;
11332 col = parser->tokp - parser->parser_lex_pbeg;
11333 return LONG2NUM(col);
11338 * ripper#filename -> String
11340 * Return current parsing filename.
11343 ripper_filename(VALUE self)
11345 struct parser_params *parser;
11347 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11348 if (!ripper_initialized_p(parser)) {
11349 rb_raise(rb_eArgError, "method called for uninitialized object");
11351 return parser->parser_ruby_sourcefile_string;
11356 * ripper#lineno -> Integer
11358 * Return line number of current parsing line.
11359 * This number starts from 1.
11362 ripper_lineno(VALUE self)
11364 struct parser_params *parser;
11366 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11367 if (!ripper_initialized_p(parser)) {
11368 rb_raise(rb_eArgError, "method called for uninitialized object");
11370 if (NIL_P(parser->parsing_thread)) return Qnil;
11371 return INT2NUM(parser->parser_ruby_sourceline);
11374 #ifdef RIPPER_DEBUG
11377 ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
11380 if (obj == Qundef) {
11381 rb_raise(rb_eArgError, "%s", RSTRING_PTR(msg));
11388 ripper_value(VALUE self, VALUE obj)
11390 return ULONG2NUM(obj);
11398 parser_data_type.parent = RTYPEDDATA_TYPE(rb_parser_new());
11400 ripper_init_eventids1();
11401 ripper_init_eventids2();
11402 /* ensure existing in symbol table */
11403 (void)rb_intern("||");
11404 (void)rb_intern("&&");
11410 InitVM_ripper(void)
11414 Ripper = rb_define_class("Ripper", rb_cObject);
11415 rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
11416 rb_define_alloc_func(Ripper, ripper_s_allocate);
11417 rb_define_method(Ripper, "initialize", ripper_initialize, -1);
11418 rb_define_method(Ripper, "parse", ripper_parse, 0);
11419 rb_define_method(Ripper, "column", ripper_column, 0);
11420 rb_define_method(Ripper, "filename", ripper_filename, 0);
11421 rb_define_method(Ripper, "lineno", ripper_lineno, 0);
11422 rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
11423 rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
11424 rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
11425 rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
11426 #ifdef RIPPER_DEBUG
11427 rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
11428 rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
11429 rb_define_method(rb_mKernel, "validate_object", ripper_validate_object, 1);
11432 ripper_init_eventids1_table(Ripper);
11433 ripper_init_eventids2_table(Ripper);
11436 /* Hack to let RDoc document SCRIPT_LINES__ */
11439 * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
11440 * after the assignment will be added as an Array of lines with the file
11443 rb_define_global_const("SCRIPT_LINES__", Qnil);
11447 #endif /* RIPPER */