Ruby  2.0.0p247(2013-06-27revision41674)
ripper.y
Go to the documentation of this file.
1 /**********************************************************************
2 
3  parse.y -
4 
5  $Author: nagachika $
6  created at: Fri May 28 18:02:42 JST 1993
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 %{
13 
14 #ifndef PARSER_DEBUG
15 #define PARSER_DEBUG 0
16 #endif
17 #define YYDEBUG 1
18 #define YYERROR_VERBOSE 1
19 #define YYSTACK_USE_ALLOCA 0
20 
21 #include "ruby/ruby.h"
22 #include "ruby/st.h"
23 #include "ruby/encoding.h"
24 #include "internal.h"
25 #include "node.h"
26 #include "parse.h"
27 #include "id.h"
28 #include "regenc.h"
29 #include <stdio.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include "probes.h"
33 
34 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
35 
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
43 #define free YYFREE
44 
45 #ifndef RIPPER
46 static ID register_symid(ID, const char *, long, rb_encoding *);
48 #define REGISTER_SYMID(id, name) register_symid((id), (name), strlen(name), enc)
49 #include "id.c"
50 #endif
51 
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)
61 
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))
66 
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. */
80 };
81 /* examine combinations */
83 #define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
86  DEF_EXPR(ENDARG),
87  DEF_EXPR(ENDFN),
88  DEF_EXPR(ARG),
89  DEF_EXPR(CMDARG),
90  DEF_EXPR(MID),
91  DEF_EXPR(FNAME),
92  DEF_EXPR(DOT),
93  DEF_EXPR(CLASS),
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)
98 };
99 #define IS_lex_state_for(x, ls) ((x) & (ls))
100 #define IS_lex_state(ls) IS_lex_state_for(lex_state, (ls))
102 #if PARSER_DEBUG
103 static const char *lex_state_name(enum lex_state_e state);
104 #endif
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)
123 struct vtable {
124  ID *tbl;
125  int pos;
126  int capa;
127  struct vtable *prev;
128 };
130 struct local_vars {
131  struct vtable *args;
132  struct vtable *vars;
133  struct vtable *used;
134  struct local_vars *prev;
135 };
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)
142 static int
143 vtable_size(const struct vtable *tbl)
144 {
145  if (POINTER_P(tbl)) {
146  return tbl->pos;
147  }
148  else {
149  return 0;
150  }
151 }
153 #define VTBL_DEBUG 0
155 static struct vtable *
157 {
158  struct vtable *tbl = ALLOC(struct vtable);
159  tbl->pos = 0;
160  tbl->capa = 8;
161  tbl->tbl = ALLOC_N(ID, tbl->capa);
162  tbl->prev = prev;
163  if (VTBL_DEBUG) printf("vtable_alloc: %p\n", (void *)tbl);
164  return tbl;
165 }
167 static void
168 vtable_free(struct vtable *tbl)
169 {
170  if (VTBL_DEBUG)printf("vtable_free: %p\n", (void *)tbl);
171  if (POINTER_P(tbl)) {
172  if (tbl->tbl) {
173  xfree(tbl->tbl);
174  }
175  xfree(tbl);
176  }
177 }
179 static void
180 vtable_add(struct vtable *tbl, ID id)
181 {
182  if (!POINTER_P(tbl)) {
183  rb_bug("vtable_add: vtable is not allocated (%p)", (void *)tbl);
184  }
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);
190  }
191  tbl->tbl[tbl->pos++] = id;
192 }
193 
194 static int
195 vtable_included(const struct vtable * tbl, ID id)
196 {
197  int i;
199  if (POINTER_P(tbl)) {
200  for (i = 0; i < tbl->pos; i++) {
201  if (tbl->tbl[i] == id) {
202  return i+1;
203  }
204  }
205  }
206  return 0;
207 }
209 
210 #ifndef RIPPER
211 typedef struct token_info {
212  const char *token;
213  int linenum;
214  int column;
215  int nonspc;
216  struct token_info *next;
218 #endif
219 
220 /*
221  Structure of Lexer Buffer:
223  lex_pbeg tokp lex_p lex_pend
224  | | | |
225  |-----------+--------------+------------|
226  |<------------>|
227  token
228 */
238  stack_type parser_cond_stack;
250  int parser_tokidx;
251  int parser_toksiz;
256  const char *parser_lex_pbeg;
257  const char *parser_lex_p;
258  const char *parser_lex_pend;
264  struct local_vars *parser_lvtbl;
266  int line_count;
267  int has_shebang;
268  char *parser_ruby_sourcefile; /* current source file */
269  int parser_ruby_sourceline; /* current line no. */
270  rb_encoding *enc;
271 
272  int parser_yydebug;
273 
274 #ifndef RIPPER
275  /* Ruby core only */
279  VALUE coverage;
280  int nerr;
281 
284 #else
285  /* Ripper only */
286  VALUE parser_ruby_sourcefile_string;
287  const char *tokp;
288  VALUE delayed;
289  int delayed_line;
290  int delayed_col;
291 
292  VALUE value;
293  VALUE result;
294  VALUE parsing_thread;
295  int toplevel_p;
296 #endif
297 };
298 
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))
308 
309 #define YYLEX_PARAM parser
310 
311 #define lex_strterm (parser->parser_lex_strterm)
312 #define lex_state (parser->parser_lex_state)
313 #define cond_stack (parser->parser_cond_stack)
314 #define cmdarg_stack (parser->parser_cmdarg_stack)
315 #define class_nest (parser->parser_class_nest)
316 #define paren_nest (parser->parser_paren_nest)
317 #define lpar_beg (parser->parser_lpar_beg)
318 #define brace_nest (parser->parser_brace_nest)
319 #define in_single (parser->parser_in_single)
320 #define in_def (parser->parser_in_def)
321 #define compile_for_eval (parser->parser_compile_for_eval)
322 #define cur_mid (parser->parser_cur_mid)
323 #define in_defined (parser->parser_in_defined)
324 #define tokenbuf (parser->parser_tokenbuf)
325 #define tokidx (parser->parser_tokidx)
326 #define toksiz (parser->parser_toksiz)
327 #define tokline (parser->parser_tokline)
328 #define lex_input (parser->parser_lex_input)
329 #define lex_lastline (parser->parser_lex_lastline)
330 #define lex_nextline (parser->parser_lex_nextline)
331 #define lex_pbeg (parser->parser_lex_pbeg)
332 #define lex_p (parser->parser_lex_p)
333 #define lex_pend (parser->parser_lex_pend)
334 #define heredoc_end (parser->parser_heredoc_end)
335 #define command_start (parser->parser_command_start)
336 #define deferred_nodes (parser->parser_deferred_nodes)
337 #define lex_gets_ptr (parser->parser_lex_gets_ptr)
338 #define lex_gets (parser->parser_lex_gets)
339 #define lvtbl (parser->parser_lvtbl)
340 #define ruby__end__seen (parser->parser_ruby__end__seen)
341 #define ruby_sourceline (parser->parser_ruby_sourceline)
342 #define ruby_sourcefile (parser->parser_ruby_sourcefile)
343 #define current_enc (parser->enc)
344 #define yydebug (parser->parser_yydebug)
345 #ifdef RIPPER
346 #else
347 #define ruby_eval_tree (parser->parser_eval_tree)
348 #define ruby_eval_tree_begin (parser->parser_eval_tree_begin)
349 #define ruby_debug_lines (parser->debug_lines)
350 #define ruby_coverage (parser->coverage)
351 #endif
353 static int yylex(void*, void*);
354 
355 #ifndef RIPPER
356 #define yyparse ruby_yyparse
357 
358 static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE);
359 #define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, (type), (a1), (a2), (a3))
360 
361 static NODE *cond_gen(struct parser_params*,NODE*);
362 #define cond(node) cond_gen(parser, (node))
363 static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
364 #define logop(type,node1,node2) logop_gen(parser, (type), (node1), (node2))
365 
366 static NODE *newline_node(NODE*);
367 static void fixpos(NODE*,NODE*);
368 
369 static int value_expr_gen(struct parser_params*,NODE*);
370 static void void_expr_gen(struct parser_params*,NODE*);
371 static NODE *remove_begin(NODE*);
372 #define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
373 #define void_expr0(node) void_expr_gen(parser, (node))
374 #define void_expr(node) void_expr0((node) = remove_begin(node))
375 static void void_stmts_gen(struct parser_params*,NODE*);
376 #define void_stmts(node) void_stmts_gen(parser, (node))
377 static void reduce_nodes_gen(struct parser_params*,NODE**);
378 #define reduce_nodes(n) reduce_nodes_gen(parser,(n))
379 static void block_dup_check_gen(struct parser_params*,NODE*,NODE*);
380 #define block_dup_check(n1,n2) block_dup_check_gen(parser,(n1),(n2))
381 
383 #define block_append(h,t) block_append_gen(parser,(h),(t))
385 #define list_append(l,i) list_append_gen(parser,(l),(i))
387 #define list_concat(h,t) list_concat_gen(parser,(h),(t))
388 static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*);
389 #define arg_append(h,t) arg_append_gen(parser,(h),(t))
391 #define arg_concat(h,t) arg_concat_gen(parser,(h),(t))
393 #define literal_concat(h,t) literal_concat_gen(parser,(h),(t))
394 static int literal_concat0(struct parser_params *, VALUE, VALUE);
396 #define new_evstr(n) new_evstr_gen(parser,(n))
398 #define evstr2dstr(n) evstr2dstr_gen(parser,(n))
402 #define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, (recv),(id),(arg1))
403 static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID);
404 #define call_uni_op(recv,id) call_uni_op_gen(parser, (recv),(id))
406 static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*);
407 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
409 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
411 static NODE *negate_lit(NODE*);
413 #define ret_args(node) ret_args_gen(parser, (node))
416 #define new_yield(node) new_yield_gen(parser, (node))
418 #define dsym_node(node) dsym_node_gen(parser, (node))
419 
420 static NODE *gettable_gen(struct parser_params*,ID);
421 #define gettable(id) gettable_gen(parser,(id))
422 static NODE *assignable_gen(struct parser_params*,ID,NODE*);
423 #define assignable(id,node) assignable_gen(parser, (id), (node))
424 
425 static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
426 #define aryset(node1,node2) aryset_gen(parser, (node1), (node2))
427 static NODE *attrset_gen(struct parser_params*,NODE*,ID);
428 #define attrset(node,id) attrset_gen(parser, (node), (id))
429 
430 static void rb_backref_error_gen(struct parser_params*,NODE*);
431 #define rb_backref_error(n) rb_backref_error_gen(parser,(n))
432 static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
433 #define node_assign(node1, node2) node_assign_gen(parser, (node1), (node2))
434 
435 static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
436 static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs);
437 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (attr), (op), (rhs))
438 static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
439 #define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs))
440 
441 static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
442 #define match_op(node1,node2) match_op_gen(parser, (node1), (node2))
443 
444 static ID *local_tbl_gen(struct parser_params*);
445 #define local_tbl() local_tbl_gen(parser)
446 
447 static void fixup_nodes(NODE **);
448 
449 static VALUE reg_compile_gen(struct parser_params*, VALUE, int);
450 #define reg_compile(str,options) reg_compile_gen(parser, (str), (options))
451 static void reg_fragment_setenc_gen(struct parser_params*, VALUE, int);
452 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, (str), (options))
453 static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
454 #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, (str), (options))
456 #define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
458 #define get_id(id) (id)
459 #define get_value(val) (val)
460 #else
461 #define value_expr(node) ((void)(node))
462 #define remove_begin(node) (node)
463 #define rb_dvar_defined(id) 0
464 #define rb_local_defined(id) 0
465 static ID ripper_get_id(VALUE);
466 #define get_id(id) ripper_get_id(id)
467 static VALUE ripper_get_value(VALUE);
468 #define get_value(val) ripper_get_value(val)
470 #define assignable(lhs,node) assignable_gen(parser, (lhs))
471 static int id_is_var_gen(struct parser_params *parser, ID id);
472 #define id_is_var(id) id_is_var_gen(parser, (id))
474 #define node_assign(node1, node2) dispatch2(assign, (node1), (node2))
478 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs))
479 
480 #endif /* !RIPPER */
481 
482 #define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs))
483 
484 static ID formal_argument_gen(struct parser_params*, ID);
485 #define formal_argument(id) formal_argument_gen(parser, (id))
487 #define shadowing_lvar(name) shadowing_lvar_gen(parser, (name))
488 static void new_bv_gen(struct parser_params*,ID);
489 #define new_bv(id) new_bv_gen(parser, (id))
490 
491 static void local_push_gen(struct parser_params*,int);
492 #define local_push(top) local_push_gen(parser,(top))
493 static void local_pop_gen(struct parser_params*);
494 #define local_pop() local_pop_gen(parser)
495 static int local_var_gen(struct parser_params*, ID);
496 #define local_var(id) local_var_gen(parser, (id))
497 static int arg_var_gen(struct parser_params*, ID);
498 #define arg_var(id) arg_var_gen(parser, (id))
499 static int local_id_gen(struct parser_params*, ID);
500 #define local_id(id) local_id_gen(parser, (id))
501 static ID internal_id_gen(struct parser_params*);
502 #define internal_id() internal_id_gen(parser)
503 
504 static const struct vtable *dyna_push_gen(struct parser_params *);
505 #define dyna_push() dyna_push_gen(parser)
506 static void dyna_pop_gen(struct parser_params*, const struct vtable *);
507 #define dyna_pop(node) dyna_pop_gen(parser, (node))
508 static int dyna_in_block_gen(struct parser_params*);
509 #define dyna_in_block() dyna_in_block_gen(parser)
510 #define dyna_var(id) local_var(id)
511 static int dvar_defined_gen(struct parser_params*,ID,int);
512 #define dvar_defined(id) dvar_defined_gen(parser, (id), 0)
513 #define dvar_defined_get(id) dvar_defined_gen(parser, (id), 1)
514 static int dvar_curr_gen(struct parser_params*,ID);
515 #define dvar_curr(id) dvar_curr_gen(parser, (id))
516 
517 static int lvar_defined_gen(struct parser_params*, ID);
518 #define lvar_defined(id) lvar_defined_gen(parser, (id))
519 
520 #define RE_OPTION_ONCE (1<<16)
521 #define RE_OPTION_ENCODING_SHIFT 8
522 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
523 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
524 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
525 #define RE_OPTION_MASK 0xff
526 #define RE_OPTION_ARG_ENCODING_NONE 32
527 
528 #define NODE_STRTERM NODE_ZARRAY /* nothing to gc */
529 #define NODE_HEREDOC NODE_ARRAY /* 1, 3 to gc */
530 #define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
531 #define nd_func u1.id
532 #if SIZEOF_SHORT == 2
533 #define nd_term(node) ((signed short)(node)->u2.id)
534 #else
535 #define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
536 #endif
537 #define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
538 #define nd_nest u3.cnt
539 
540 /****** Ripper *******/
541 
542 #ifdef RIPPER
543 #define RIPPER_VERSION "0.1.0"
544 
545 #include "eventids1.c"
546 #include "eventids2.c"
547 
548 static VALUE ripper_dispatch0(struct parser_params*,ID);
549 static VALUE ripper_dispatch1(struct parser_params*,ID,VALUE);
550 static VALUE ripper_dispatch2(struct parser_params*,ID,VALUE,VALUE);
551 static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
552 static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
553 static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
554 static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
555 
556 #define dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
557 #define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
558 #define dispatch2(n,a,b) ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), (a), (b))
559 #define dispatch3(n,a,b,c) ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
560 #define dispatch4(n,a,b,c,d) ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
561 #define dispatch5(n,a,b,c,d,e) ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
562 #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))
563 
564 #define yyparse ripper_yyparse
565 
566 #define ripper_intern(s) ID2SYM(rb_intern(s))
567 static VALUE ripper_id2sym(ID);
568 #ifdef __GNUC__
569 #define ripper_id2sym(id) ((id) < 256 && rb_ispunct(id) ? \
570  ID2SYM(id) : ripper_id2sym(id))
571 #endif
572 
573 #define arg_new() dispatch0(args_new)
574 #define arg_add(l,a) dispatch2(args_add, (l), (a))
575 #define arg_add_star(l,a) dispatch2(args_add_star, (l), (a))
576 #define arg_add_block(l,b) dispatch2(args_add_block, (l), (b))
577 #define arg_add_optblock(l,b) ((b)==Qundef? (l) : dispatch2(args_add_block, (l), (b)))
578 #define bare_assoc(v) dispatch1(bare_assoc_hash, (v))
579 #define arg_add_assocs(l,b) arg_add((l), bare_assoc(b))
580 
581 #define args2mrhs(a) dispatch1(mrhs_new_from_args, (a))
582 #define mrhs_new() dispatch0(mrhs_new)
583 #define mrhs_add(l,a) dispatch2(mrhs_add, (l), (a))
584 #define mrhs_add_star(l,a) dispatch2(mrhs_add_star, (l), (a))
586 #define mlhs_new() dispatch0(mlhs_new)
587 #define mlhs_add(l,a) dispatch2(mlhs_add, (l), (a))
588 #define mlhs_add_star(l,a) dispatch2(mlhs_add_star, (l), (a))
589 
590 #define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
591  dispatch7(params, (pars), (opts), (rest), (pars2), (kws), (kwrest), (blk))
592 
593 #define blockvar_new(p,v) dispatch2(block_var, (p), (v))
594 #define blockvar_add_star(l,a) dispatch2(block_var_add_star, (l), (a))
595 #define blockvar_add_block(l,a) dispatch2(block_var_add_block, (l), (a))
597 #define method_optarg(m,a) ((a)==Qundef ? (m) : dispatch2(method_add_arg,(m),(a)))
598 #define method_arg(m,a) dispatch2(method_add_arg,(m),(a))
599 #define method_add_block(m,b) dispatch2(method_add_block, (m), (b))
600 
601 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
602 
603 static inline VALUE
605 {
606  NODE *t = (NODE *)tail;
607  VALUE k = t->u1.value, kr = t->u2.value, b = t->u3.value;
608  return params_new(f, o, r, p, k, kr, escape_Qundef(b));
609 }
610 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
611 
612 static inline VALUE
614 {
615  return (VALUE)rb_node_newnode(NODE_MEMO, k, kr, b);
616 }
617 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
618 
619 #define FIXME 0
620 
621 #endif /* RIPPER */
622 
623 #ifndef RIPPER
624 # define Qnone 0
625 # define ifndef_ripper(x) (x)
626 #else
627 # define Qnone Qnil
628 # define ifndef_ripper(x)
629 #endif
630 
631 #ifndef RIPPER
632 # define rb_warn0(fmt) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt))
633 # define rb_warnI(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
634 # define rb_warnS(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
635 # define rb_warn4S(file,line,fmt,a) rb_compile_warn((file), (line), (fmt), (a))
636 # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt))
637 # define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt), (a))
638 #else
639 # define rb_warn0(fmt) ripper_warn0(parser, (fmt))
640 # define rb_warnI(fmt,a) ripper_warnI(parser, (fmt), (a))
641 # define rb_warnS(fmt,a) ripper_warnS(parser, (fmt), (a))
642 # define rb_warn4S(file,line,fmt,a) ripper_warnS(parser, (fmt), (a))
643 # define rb_warning0(fmt) ripper_warning0(parser, (fmt))
644 # define rb_warningS(fmt,a) ripper_warningS(parser, (fmt), (a))
645 static void ripper_warn0(struct parser_params*, const char*);
646 static void ripper_warnI(struct parser_params*, const char*, int);
647 static void ripper_warnS(struct parser_params*, const char*, const char*);
648 static void ripper_warning0(struct parser_params*, const char*);
649 static void ripper_warningS(struct parser_params*, const char*, const char*);
650 #endif
652 #ifdef RIPPER
653 static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
654 # define rb_compile_error ripper_compile_error
655 # define compile_error ripper_compile_error
656 # define PARSER_ARG parser,
657 #else
658 # define rb_compile_error rb_compile_error_with_enc
659 # define compile_error parser->nerr++,rb_compile_error_with_enc
660 # define PARSER_ARG ruby_sourcefile, ruby_sourceline, current_enc,
661 #endif
663 /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
664  for instance). This is too low for Ruby to parse some files, such as
665  date/format.rb, therefore bump the value up to at least Bison's default. */
666 #ifdef OLD_YACC
667 #ifndef YYMAXDEPTH
668 #define YYMAXDEPTH 10000
669 #endif
670 #endif
672 #ifndef RIPPER
673 static void token_info_push(struct parser_params*, const char *token);
674 static void token_info_pop(struct parser_params*, const char *token);
675 #define token_info_push(token) (RTEST(ruby_verbose) ? token_info_push(parser, (token)) : (void)0)
676 #define token_info_pop(token) (RTEST(ruby_verbose) ? token_info_pop(parser, (token)) : (void)0)
677 #else
678 #define token_info_push(token) /* nothing */
679 #define token_info_pop(token) /* nothing */
680 #endif
681 %}
683 %pure_parser
684 %parse-param {struct parser_params *parser}
686 %union {
688  NODE *node;
690  int num;
691  const struct vtable *vars;
692 }
694 /*
695 %token
696 */
697 %token <val>
698 
707  keyword_if
721  keyword_in
722  keyword_do
734  keyword_or
748 
751 %token <val> tNTH_REF tBACK_REF
752 %token <val> tREGEXP_END
754 %type <val> singleton strings string string1 xstring regexp
755 %type <val> string_contents xstring_contents regexp_contents string_content
756 %type <val> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
757 %type <val> literal numeric dsym cpath
758 %type <val> top_compstmt top_stmts top_stmt
759 %type <val> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
760 %type <val> expr_value arg_value primary_value fcall
761 %type <val> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
762 %type <val> args call_args opt_call_args
763 %type <val> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
764 %type <val> command_args aref_args opt_block_arg block_arg var_ref var_lhs
765 %type <val> command_asgn mrhs superclass block_call block_command
766 %type <val> f_block_optarg f_block_opt
767 %type <val> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
768 %type <val> assoc_list assocs assoc undef_list backref string_dvar for_var
769 %type <val> block_param opt_block_param block_param_def f_opt
770 %type <val> f_kwarg f_kw f_block_kwarg f_block_kw
771 %type <val> bv_decls opt_bv_decl bvar
772 %type <val> lambda f_larglist lambda_body
773 %type <val> brace_block cmd_brace_block do_block lhs none fitem
775 %type <val> fsym keyword_variable user_variable sym symbol operation operation2 operation3
776 %type <val> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
777 %type <val> f_kwrest
778 /*
779 */
780 %type <val> program reswords then do dot_or_colon
781 
782 %token END_OF_INPUT 0 "end-of-input"
783 %token tUPLUS 130 "unary+"
784 %token tUMINUS 131 "unary-"
785 %token tPOW 132 "**"
786 %token tCMP 134 "<=>"
787 %token tEQ 139 "=="
788 %token tEQQ 140 "==="
789 %token tNEQ 141 "!="
790 %token tGEQ 138 ">="
791 %token tLEQ 137 "<="
792 %token tANDOP "&&"
793 %token tOROP "||"
794 %token tMATCH 142 "=~"
795 %token tNMATCH 143 "!~"
796 %token tDOT2 128 ".."
797 %token tDOT3 129 "..."
798 %token tAREF 144 "[]"
799 %token tASET 145 "[]="
800 %token tLSHFT 135 "<<"
801 %token tRSHFT 136 ">>"
802 %token tCOLON2 "::"
803 %token tCOLON3 ":: at EXPR_BEG"
804 %token <val> tOP_ASGN /* +=, -= etc. */
805 %token tASSOC "=>"
806 %token tLPAREN "("
807 %token tLPAREN_ARG "( arg"
808 %token tRPAREN ")"
809 %token tLBRACK "["
810 %token tLBRACE "{"
811 %token tLBRACE_ARG "{ arg"
812 %token tSTAR "*"
813 %token tDSTAR "**arg"
814 %token tAMPER "&"
815 %token tLAMBDA "->"
818 
819 /*
820  * precedence table
821  */
822 
823 %nonassoc tLOWEST
824 %nonassoc tLBRACE_ARG
825 
828 %right keyword_not
829 %nonassoc keyword_defined
830 %right '=' tOP_ASGN
831 %left modifier_rescue
832 %right '?' ':'
833 %nonassoc tDOT2 tDOT3
834 %left tOROP
835 %left tANDOP
836 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
837 %left '>' tGEQ '<' tLEQ
838 %left '|' '^'
839 %left '&'
840 %left tLSHFT tRSHFT
841 %left '+' '-'
842 %left '*' '/' '%'
844 %right tPOW
845 %right '!' '~' tUPLUS
848 
849 %%
850 program : {
851  lex_state = EXPR_BEG;
852 #if 0
854 #endif
855  local_push(0);
856 
857  }
858  top_compstmt
859  {
860 #if 0
861  if ($2 && !compile_for_eval) {
862  /* last expression should not be void */
863  if (nd_type($2) != NODE_BLOCK) void_expr($2);
864  else {
865  NODE *node = $2;
866  while (node->nd_next) {
867  node = node->nd_next;
868  }
869  void_expr(node->nd_head);
870  }
871  }
873 #endif
874  $$ = $2;
875  parser->result = dispatch1(program, $$);
876 
877  local_pop();
878  }
879  ;
880 
881 top_compstmt : top_stmts opt_terms
882  {
883 #if 0
884  void_stmts($1);
886 #endif
888  $$ = $1;
889  }
890  ;
891 
892 top_stmts : none
893  {
894 #if 0
895  $$ = NEW_BEGIN(0);
896 #endif
897  $$ = dispatch2(stmts_add, dispatch0(stmts_new),
898  dispatch0(void_stmt));
899 
900  }
901  | top_stmt
902  {
903 #if 0
904  $$ = newline_node($1);
905 #endif
906  $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
907 
908  }
909  | top_stmts terms top_stmt
910  {
911 #if 0
912  $$ = block_append($1, newline_node($3));
913 #endif
914  $$ = dispatch2(stmts_add, $1, $3);
915 
916  }
917  | error top_stmt
918  {
919  $$ = remove_begin($2);
920  }
921  ;
925  {
926 #if 0
927  /* local_push(0); */
928 #endif
929 
930  }
931  '{' top_compstmt '}'
932  {
933 #if 0
935  $4);
936  /* NEW_PREEXE($4)); */
937  /* local_pop(); */
938  $$ = NEW_BEGIN(0);
939 #endif
940  $$ = dispatch1(BEGIN, $4);
942  }
943  ;
944 
946  opt_rescue
947  opt_else
948  opt_ensure
949  {
950 #if 0
951  $$ = $1;
952  if ($2) {
953  $$ = NEW_RESCUE($1, $2, $3);
954  }
955  else if ($3) {
956  rb_warn0("else without rescue is useless");
957  $$ = block_append($$, $3);
958  }
959  if ($4) {
960  if ($$) {
961  $$ = NEW_ENSURE($$, $4);
962  }
963  else {
964  $$ = block_append($4, NEW_NIL());
965  }
966  }
967  fixpos($$, $1);
968 #endif
969  $$ = dispatch4(bodystmt,
971  escape_Qundef($2),
972  escape_Qundef($3),
973  escape_Qundef($4));
974 
975  }
976  ;
977 
978 compstmt : stmts opt_terms
979  {
980 #if 0
983 #endif
984 
985  $$ = $1;
986  }
987  ;
988 
989 stmts : none
990  {
991 #if 0
992  $$ = NEW_BEGIN(0);
993 #endif
994  $$ = dispatch2(stmts_add, dispatch0(stmts_new),
995  dispatch0(void_stmt));
996 
997  }
998  | stmt_or_begin
999  {
1000 #if 0
1001  $$ = newline_node($1);
1002 #endif
1003  $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
1004 
1005  }
1006  | stmts terms stmt_or_begin
1007  {
1008 #if 0
1009  $$ = block_append($1, newline_node($3));
1010 #endif
1011  $$ = dispatch2(stmts_add, $1, $3);
1012 
1013  }
1014  | error stmt
1015  {
1016  $$ = remove_begin($2);
1017  }
1018  ;
1019 
1021  {
1022  $$ = $1;
1023  }
1024  | keyword_BEGIN
1025  {
1026  yyerror("BEGIN is permitted only at toplevel");
1027 #if 0
1028  /* local_push(0); */
1029 #endif
1030 
1031  }
1032  '{' top_compstmt '}'
1033  {
1034 #if 0
1036  $4);
1037  /* NEW_PREEXE($4)); */
1038  /* local_pop(); */
1039  $$ = NEW_BEGIN(0);
1040 #endif
1041  $$ = dispatch1(BEGIN, $4);
1043  }
1044 
1045 stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
1046  {
1047 #if 0
1048  $$ = NEW_ALIAS($2, $4);
1049 #endif
1050  $$ = dispatch2(alias, $2, $4);
1051 
1052  }
1054  {
1055 #if 0
1056  $$ = NEW_VALIAS($2, $3);
1057 #endif
1058  $$ = dispatch2(var_alias, $2, $3);
1060  }
1062  {
1063 #if 0
1064  char buf[2];
1065  buf[0] = '$';
1066  buf[1] = (char)$3->nd_nth;
1067  $$ = NEW_VALIAS($2, rb_intern2(buf, 2));
1068 #endif
1069  $$ = dispatch2(var_alias, $2, $3);
1070 
1071  }
1073  {
1074 #if 0
1075  yyerror("can't make alias for the number variables");
1076  $$ = NEW_BEGIN(0);
1077 #endif
1078  $$ = dispatch2(var_alias, $2, $3);
1079  $$ = dispatch1(alias_error, $$);
1080 
1081  }
1082  | keyword_undef undef_list
1083  {
1084 #if 0
1085  $$ = $2;
1086 #endif
1087  $$ = dispatch1(undef, $2);
1088 
1089  }
1090  | stmt modifier_if expr_value
1091  {
1092 #if 0
1093  $$ = NEW_IF(cond($3), remove_begin($1), 0);
1094  fixpos($$, $3);
1095 #endif
1096  $$ = dispatch2(if_mod, $3, $1);
1097 
1098  }
1099  | stmt modifier_unless expr_value
1100  {
1101 #if 0
1102  $$ = NEW_UNLESS(cond($3), remove_begin($1), 0);
1103  fixpos($$, $3);
1104 #endif
1105  $$ = dispatch2(unless_mod, $3, $1);
1106 
1107  }
1108  | stmt modifier_while expr_value
1109  {
1110 #if 0
1111  if ($1 && nd_type($1) == NODE_BEGIN) {
1112  $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
1113  }
1114  else {
1115  $$ = NEW_WHILE(cond($3), $1, 1);
1116  }
1117 #endif
1118  $$ = dispatch2(while_mod, $3, $1);
1119 
1120  }
1121  | stmt modifier_until expr_value
1122  {
1123 #if 0
1124  if ($1 && nd_type($1) == NODE_BEGIN) {
1125  $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
1126  }
1127  else {
1128  $$ = NEW_UNTIL(cond($3), $1, 1);
1129  }
1130 #endif
1131  $$ = dispatch2(until_mod, $3, $1);
1132 
1133  }
1135  {
1136 #if 0
1137  NODE *resq = NEW_RESBODY(0, remove_begin($3), 0);
1138  $$ = NEW_RESCUE(remove_begin($1), resq, 0);
1139 #endif
1140  $$ = dispatch2(rescue_mod, $1, $3);
1141 
1142  }
1143  | keyword_END '{' compstmt '}'
1144  {
1145  if (in_def || in_single) {
1146  rb_warn0("END in method; use at_exit");
1147  }
1148 #if 0
1149  $$ = NEW_POSTEXE(NEW_NODE(
1150  NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */));
1151 #endif
1152  $$ = dispatch1(END, $3);
1153 
1154  }
1155  | command_asgn
1156  | mlhs '=' command_call
1157  {
1158 #if 0
1159  value_expr($3);
1160  $1->nd_value = $3;
1161  $$ = $1;
1162 #endif
1163  $$ = dispatch2(massign, $1, $3);
1164 
1165  }
1166  | var_lhs tOP_ASGN command_call
1167  {
1168  value_expr($3);
1169  $$ = new_op_assign($1, $2, $3);
1170  }
1171  | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
1172  {
1173 #if 0
1174  NODE *args;
1175 
1176  value_expr($6);
1177  if (!$3) $3 = NEW_ZARRAY();
1178  args = arg_concat($3, $6);
1179  if ($5 == tOROP) {
1180  $5 = 0;
1181  }
1182  else if ($5 == tANDOP) {
1183  $5 = 1;
1184  }
1185  $$ = NEW_OP_ASGN1($1, $5, args);
1186  fixpos($$, $1);
1187 #endif
1188  $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1189  $$ = dispatch3(opassign, $$, $5, $6);
1190 
1191  }
1192  | primary_value '.' tIDENTIFIER tOP_ASGN command_call
1193  {
1194  value_expr($5);
1195  $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1196  }
1197  | primary_value '.' tCONSTANT tOP_ASGN command_call
1198  {
1199  value_expr($5);
1200  $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1201  }
1203  {
1204 #if 0
1205  $$ = NEW_COLON2($1, $3);
1206  $$ = new_const_op_assign($$, $4, $5);
1207 #endif
1208  $$ = dispatch2(const_path_field, $1, $3);
1209  $$ = dispatch3(opassign, $$, $4, $5);
1210 
1211  }
1213  {
1214  value_expr($5);
1215  $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
1216  }
1217  | backref tOP_ASGN command_call
1218  {
1219 #if 0
1220  rb_backref_error($1);
1221  $$ = NEW_BEGIN(0);
1222 #endif
1223  $$ = dispatch2(assign, dispatch1(var_field, $1), $3);
1224  $$ = dispatch1(assign_error, $$);
1225 
1226  }
1227  | lhs '=' mrhs
1228  {
1229 #if 0
1230  value_expr($3);
1231  $$ = node_assign($1, $3);
1232 #endif
1233  $$ = dispatch2(assign, $1, $3);
1234 
1235  }
1236  | mlhs '=' arg_value
1237  {
1238 #if 0
1239  $1->nd_value = $3;
1240  $$ = $1;
1241 #endif
1242  $$ = dispatch2(massign, $1, $3);
1243 
1244  }
1245  | mlhs '=' mrhs
1246  {
1247 #if 0
1248  $1->nd_value = $3;
1249  $$ = $1;
1250 #endif
1251  $$ = dispatch2(massign, $1, $3);
1252 
1253  }
1254  | expr
1255  ;
1256 
1257 command_asgn : lhs '=' command_call
1258  {
1259 #if 0
1260  value_expr($3);
1261  $$ = node_assign($1, $3);
1262 #endif
1263  $$ = dispatch2(assign, $1, $3);
1265  }
1266  | lhs '=' command_asgn
1267  {
1268 #if 0
1269  value_expr($3);
1270  $$ = node_assign($1, $3);
1271 #endif
1272  $$ = dispatch2(assign, $1, $3);
1273 
1274  }
1275  ;
1276 
1277 
1280  {
1281 #if 0
1282  $$ = logop(NODE_AND, $1, $3);
1283 #endif
1284  $$ = dispatch3(binary, $1, ripper_intern("and"), $3);
1285 
1286  }
1287  | expr keyword_or expr
1288  {
1289 #if 0
1290  $$ = logop(NODE_OR, $1, $3);
1291 #endif
1292  $$ = dispatch3(binary, $1, ripper_intern("or"), $3);
1293 
1294  }
1295  | keyword_not opt_nl expr
1296  {
1297 #if 0
1298  $$ = call_uni_op(cond($3), '!');
1299 #endif
1300  $$ = dispatch2(unary, ripper_intern("not"), $3);
1301 
1302  }
1303  | '!' command_call
1304  {
1305 #if 0
1306  $$ = call_uni_op(cond($2), '!');
1307 #endif
1308  $$ = dispatch2(unary, ripper_id2sym('!'), $2);
1309 
1310  }
1311  | arg
1312  ;
1313 
1314 expr_value : expr
1315  {
1316 #if 0
1317  value_expr($1);
1318  $$ = $1;
1319  if (!$$) $$ = NEW_NIL();
1320 #endif
1321  $$ = $1;
1322 
1323  }
1324  ;
1325 
1326 command_call : command
1327  | block_command
1328  ;
1329 
1330 block_command : block_call
1331  | block_call dot_or_colon operation2 command_args
1332  {
1333 #if 0
1334  $$ = NEW_CALL($1, $3, $4);
1335 #endif
1336  $$ = dispatch3(call, $1, $2, $3);
1337  $$ = method_arg($$, $4);
1338 
1339  }
1340  ;
1341 
1343  {
1344  $<vars>1 = dyna_push();
1345 #if 0
1346  $<num>$ = ruby_sourceline;
1347 #endif
1348 
1349  }
1350  opt_block_param
1351  compstmt
1352  '}'
1353  {
1354 #if 0
1355  $$ = NEW_ITER($3,$4);
1356  nd_set_line($$, $<num>2);
1357 #endif
1358  $$ = dispatch2(brace_block, escape_Qundef($3), $4);
1359 
1360  dyna_pop($<vars>1);
1361  }
1362  ;
1363 
1364 fcall : operation
1365  {
1366 #if 0
1367  $$ = NEW_FCALL($1, 0);
1368  nd_set_line($$, tokline);
1369 #endif
1370 
1371  }
1372  ;
1373 
1374 command : fcall command_args %prec tLOWEST
1375  {
1376 #if 0
1377  $$ = $1;
1378  $$->nd_args = $2;
1379 #endif
1380  $$ = dispatch2(command, $1, $2);
1381 
1382  }
1384  {
1385 #if 0
1386  block_dup_check($2,$3);
1387  $1->nd_args = $2;
1388  $3->nd_iter = $1;
1389  $$ = $3;
1390  fixpos($$, $1);
1391 #endif
1392  $$ = dispatch2(command, $1, $2);
1393  $$ = method_add_block($$, $3);
1394 
1395  }
1396  | primary_value '.' operation2 command_args %prec tLOWEST
1397  {
1398 #if 0
1399  $$ = NEW_CALL($1, $3, $4);
1400  fixpos($$, $1);
1401 #endif
1402  $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1403 
1404  }
1405  | primary_value '.' operation2 command_args cmd_brace_block
1406  {
1407 #if 0
1408  block_dup_check($4,$5);
1409  $5->nd_iter = NEW_CALL($1, $3, $4);
1410  $$ = $5;
1411  fixpos($$, $1);
1412 #endif
1413  $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1414  $$ = method_add_block($$, $5);
1416  }
1417  | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1418  {
1419 #if 0
1420  $$ = NEW_CALL($1, $3, $4);
1421  fixpos($$, $1);
1422 #endif
1423  $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1424 
1425  }
1426  | primary_value tCOLON2 operation2 command_args cmd_brace_block
1427  {
1428 #if 0
1430  $5->nd_iter = NEW_CALL($1, $3, $4);
1431  $$ = $5;
1432  fixpos($$, $1);
1433 #endif
1434  $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1435  $$ = method_add_block($$, $5);
1437  }
1439  {
1440 #if 0
1441  $$ = NEW_SUPER($2);
1442  fixpos($$, $2);
1443 #endif
1444  $$ = dispatch1(super, $2);
1446  }
1448  {
1449 #if 0
1450  $$ = new_yield($2);
1451  fixpos($$, $2);
1452 #endif
1453  $$ = dispatch1(yield, $2);
1455  }
1457  {
1458 #if 0
1460 #endif
1461  $$ = dispatch1(return, $2);
1463  }
1465  {
1466 #if 0
1467  $$ = NEW_BREAK(ret_args($2));
1468 #endif
1469  $$ = dispatch1(break, $2);
1471  }
1473  {
1474 #if 0
1475  $$ = NEW_NEXT(ret_args($2));
1476 #endif
1477  $$ = dispatch1(next, $2);
1479  }
1480  ;
1484  {
1485 #if 0
1486  $$ = $2;
1487 #endif
1488  $$ = dispatch1(mlhs_paren, $2);
1490  }
1491  ;
1492 
1495  {
1496 #if 0
1497  $$ = NEW_MASGN(NEW_LIST($2), 0);
1498 #endif
1499  $$ = dispatch1(mlhs_paren, $2);
1501  }
1502  ;
1505  {
1506 #if 0
1507  $$ = NEW_MASGN($1, 0);
1508 #endif
1509  $$ = $1;
1510 
1511  }
1513  {
1514 #if 0
1515  $$ = NEW_MASGN(list_append($1,$2), 0);
1516 #endif
1517  $$ = mlhs_add($1, $2);
1518 
1519  }
1521  {
1522 #if 0
1523  $$ = NEW_MASGN($1, $3);
1524 #endif
1525  $$ = mlhs_add_star($1, $3);
1526 
1527  }
1529  {
1530 #if 0
1531  $$ = NEW_MASGN($1, NEW_POSTARG($3,$5));
1532 #endif
1533  $1 = mlhs_add_star($1, $3);
1534  $$ = mlhs_add($1, $5);
1535 
1536  }
1537  | mlhs_head tSTAR
1538  {
1539 #if 0
1540  $$ = NEW_MASGN($1, -1);
1541 #endif
1542  $$ = mlhs_add_star($1, Qnil);
1543 
1544  }
1545  | mlhs_head tSTAR ',' mlhs_post
1546  {
1547 #if 0
1548  $$ = NEW_MASGN($1, NEW_POSTARG(-1, $4));
1549 #endif
1550  $1 = mlhs_add_star($1, Qnil);
1551  $$ = mlhs_add($1, $4);
1552 
1553  }
1554  | tSTAR mlhs_node
1555  {
1556 #if 0
1557  $$ = NEW_MASGN(0, $2);
1558 #endif
1559  $$ = mlhs_add_star(mlhs_new(), $2);
1561  }
1562  | tSTAR mlhs_node ',' mlhs_post
1563  {
1564 #if 0
1565  $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
1566 #endif
1567  $2 = mlhs_add_star(mlhs_new(), $2);
1568  $$ = mlhs_add($2, $4);
1569 
1570  }
1571  | tSTAR
1572  {
1573 #if 0
1574  $$ = NEW_MASGN(0, -1);
1575 #endif
1576  $$ = mlhs_add_star(mlhs_new(), Qnil);
1577 
1578  }
1579  | tSTAR ',' mlhs_post
1580  {
1581 #if 0
1582  $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
1583 #endif
1584  $$ = mlhs_add_star(mlhs_new(), Qnil);
1585  $$ = mlhs_add($$, $3);
1586 
1587  }
1588  ;
1589 
1591  | tLPAREN mlhs_inner rparen
1592  {
1593 #if 0
1594  $$ = $2;
1595 #endif
1596  $$ = dispatch1(mlhs_paren, $2);
1597 
1598  }
1599  ;
1600 
1601 mlhs_head : mlhs_item ','
1602  {
1603 #if 0
1604  $$ = NEW_LIST($1);
1605 #endif
1606  $$ = mlhs_add(mlhs_new(), $1);
1607 
1608  }
1609  | mlhs_head mlhs_item ','
1610  {
1611 #if 0
1612  $$ = list_append($1, $2);
1613 #endif
1614  $$ = mlhs_add($1, $2);
1615 
1616  }
1617  ;
1618 
1620  {
1621 #if 0
1622  $$ = NEW_LIST($1);
1623 #endif
1624  $$ = mlhs_add(mlhs_new(), $1);
1625 
1626  }
1627  | mlhs_post ',' mlhs_item
1628  {
1629 #if 0
1630  $$ = list_append($1, $3);
1631 #endif
1632  $$ = mlhs_add($1, $3);
1633 
1634  }
1635  ;
1636 
1637 mlhs_node : user_variable
1638  {
1639  $$ = assignable($1, 0);
1640  }
1642  {
1643  $$ = assignable($1, 0);
1644  }
1645  | primary_value '[' opt_call_args rbracket
1646  {
1647 #if 0
1648  $$ = aryset($1, $3);
1649 #endif
1650  $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1651 
1652  }
1653  | primary_value '.' tIDENTIFIER
1654  {
1655 #if 0
1656  $$ = attrset($1, $3);
1657 #endif
1658  $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1659 
1660  }
1661  | primary_value tCOLON2 tIDENTIFIER
1662  {
1663 #if 0
1664  $$ = attrset($1, $3);
1665 #endif
1666  $$ = dispatch2(const_path_field, $1, $3);
1667 
1668  }
1669  | primary_value '.' tCONSTANT
1670  {
1671 #if 0
1672  $$ = attrset($1, $3);
1673 #endif
1674  $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1675 
1676  }
1677  | primary_value tCOLON2 tCONSTANT
1678  {
1679 #if 0
1680  if (in_def || in_single)
1681  yyerror("dynamic constant assignment");
1682  $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
1683 #endif
1684  if (in_def || in_single)
1685  yyerror("dynamic constant assignment");
1686  $$ = dispatch2(const_path_field, $1, $3);
1687 
1688  }
1689  | tCOLON3 tCONSTANT
1690  {
1691 #if 0
1692  if (in_def || in_single)
1693  yyerror("dynamic constant assignment");
1694  $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
1695 #endif
1696  $$ = dispatch1(top_const_field, $2);
1697 
1698  }
1699  | backref
1700  {
1701 #if 0
1702  rb_backref_error($1);
1703  $$ = NEW_BEGIN(0);
1704 #endif
1705  $$ = dispatch1(var_field, $1);
1706  $$ = dispatch1(assign_error, $$);
1707 
1708  }
1709  ;
1710 
1711 lhs : user_variable
1712  {
1713  $$ = assignable($1, 0);
1714 #if 0
1715  if (!$$) $$ = NEW_BEGIN(0);
1716 #endif
1717  $$ = dispatch1(var_field, $$);
1718 
1719  }
1721  {
1722  $$ = assignable($1, 0);
1723 #if 0
1724  if (!$$) $$ = NEW_BEGIN(0);
1725 #endif
1726  $$ = dispatch1(var_field, $$);
1727 
1728  }
1729  | primary_value '[' opt_call_args rbracket
1730  {
1731 #if 0
1732  $$ = aryset($1, $3);
1733 #endif
1734  $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1735 
1736  }
1737  | primary_value '.' tIDENTIFIER
1738  {
1739 #if 0
1740  $$ = attrset($1, $3);
1741 #endif
1742  $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1743 
1744  }
1745  | primary_value tCOLON2 tIDENTIFIER
1746  {
1747 #if 0
1748  $$ = attrset($1, $3);
1749 #endif
1750  $$ = dispatch3(field, $1, ripper_intern("::"), $3);
1751 
1752  }
1753  | primary_value '.' tCONSTANT
1754  {
1755 #if 0
1756  $$ = attrset($1, $3);
1757 #endif
1758  $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1759 
1760  }
1761  | primary_value tCOLON2 tCONSTANT
1762  {
1763 #if 0
1764  if (in_def || in_single)
1765  yyerror("dynamic constant assignment");
1766  $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
1767 #endif
1768  $$ = dispatch2(const_path_field, $1, $3);
1769  if (in_def || in_single) {
1770  $$ = dispatch1(assign_error, $$);
1771  }
1772 
1773  }
1774  | tCOLON3 tCONSTANT
1775  {
1776 #if 0
1777  if (in_def || in_single)
1778  yyerror("dynamic constant assignment");
1779  $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
1780 #endif
1781  $$ = dispatch1(top_const_field, $2);
1782  if (in_def || in_single) {
1783  $$ = dispatch1(assign_error, $$);
1784  }
1785 
1786  }
1787  | backref
1788  {
1789 #if 0
1790  rb_backref_error($1);
1791  $$ = NEW_BEGIN(0);
1792 #endif
1793  $$ = dispatch1(assign_error, $1);
1794 
1795  }
1796  ;
1797 
1798 cname : tIDENTIFIER
1799  {
1800 #if 0
1801  yyerror("class/module name must be CONSTANT");
1802 #endif
1803  $$ = dispatch1(class_name_error, $1);
1804 
1805  }
1806  | tCONSTANT
1807  ;
1808 
1809 cpath : tCOLON3 cname
1810  {
1811 #if 0
1812  $$ = NEW_COLON3($2);
1813 #endif
1814  $$ = dispatch1(top_const_ref, $2);
1815 
1816  }
1817  | cname
1818  {
1819 #if 0
1820  $$ = NEW_COLON2(0, $$);
1821 #endif
1822  $$ = dispatch1(const_ref, $1);
1823 
1824  }
1825  | primary_value tCOLON2 cname
1826  {
1827 #if 0
1828  $$ = NEW_COLON2($1, $3);
1829 #endif
1830  $$ = dispatch2(const_path_ref, $1, $3);
1831 
1832  }
1833  ;
1834 
1835 fname : tIDENTIFIER
1836  | tCONSTANT
1837  | tFID
1838  | op
1839  {
1840  lex_state = EXPR_ENDFN;
1841  $$ = $1;
1842  }
1843  | reswords
1844  {
1845  lex_state = EXPR_ENDFN;
1846 #if 0
1847  $$ = $<id>1;
1848 #endif
1849  $$ = $1;
1850 
1851  }
1852  ;
1853 
1854 fsym : fname
1855  | symbol
1856  ;
1857 
1858 fitem : fsym
1859  {
1860 #if 0
1861  $$ = NEW_LIT(ID2SYM($1));
1862 #endif
1863  $$ = dispatch1(symbol_literal, $1);
1864 
1865  }
1866  | dsym
1867  ;
1868 
1869 undef_list : fitem
1870  {
1871 #if 0
1872  $$ = NEW_UNDEF($1);
1873 #endif
1874  $$ = rb_ary_new3(1, $1);
1875 
1876  }
1877  | undef_list ',' {lex_state = EXPR_FNAME;} fitem
1878  {
1879 #if 0
1880  $$ = block_append($1, NEW_UNDEF($4));
1881 #endif
1882  rb_ary_push($1, $4);
1883 
1884  }
1885  ;
1886 
1887 op : '|' { ifndef_ripper($$ = '|'); }
1888  | '^' { ifndef_ripper($$ = '^'); }
1889  | '&' { ifndef_ripper($$ = '&'); }
1890  | tCMP { ifndef_ripper($$ = tCMP); }
1891  | tEQ { ifndef_ripper($$ = tEQ); }
1892  | tEQQ { ifndef_ripper($$ = tEQQ); }
1893  | tMATCH { ifndef_ripper($$ = tMATCH); }
1894  | tNMATCH { ifndef_ripper($$ = tNMATCH); }
1895  | '>' { ifndef_ripper($$ = '>'); }
1896  | tGEQ { ifndef_ripper($$ = tGEQ); }
1897  | '<' { ifndef_ripper($$ = '<'); }
1898  | tLEQ { ifndef_ripper($$ = tLEQ); }
1899  | tNEQ { ifndef_ripper($$ = tNEQ); }
1900  | tLSHFT { ifndef_ripper($$ = tLSHFT); }
1901  | tRSHFT { ifndef_ripper($$ = tRSHFT); }
1902  | '+' { ifndef_ripper($$ = '+'); }
1903  | '-' { ifndef_ripper($$ = '-'); }
1904  | '*' { ifndef_ripper($$ = '*'); }
1905  | tSTAR { ifndef_ripper($$ = '*'); }
1906  | '/' { ifndef_ripper($$ = '/'); }
1907  | '%' { ifndef_ripper($$ = '%'); }
1908  | tPOW { ifndef_ripper($$ = tPOW); }
1909  | tDSTAR { ifndef_ripper($$ = tDSTAR); }
1910  | '!' { ifndef_ripper($$ = '!'); }
1911  | '~' { ifndef_ripper($$ = '~'); }
1912  | tUPLUS { ifndef_ripper($$ = tUPLUS); }
1913  | tUMINUS { ifndef_ripper($$ = tUMINUS); }
1914  | tAREF { ifndef_ripper($$ = tAREF); }
1915  | tASET { ifndef_ripper($$ = tASET); }
1916  | '`' { ifndef_ripper($$ = '`'); }
1917  ;
1918 
1931  ;
1932 
1933 arg : lhs '=' arg
1934  {
1935 #if 0
1936  value_expr($3);
1937  $$ = node_assign($1, $3);
1938 #endif
1939  $$ = dispatch2(assign, $1, $3);
1940 
1941  }
1942  | lhs '=' arg modifier_rescue arg
1943  {
1944 #if 0
1945  value_expr($3);
1946  $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
1947  $$ = node_assign($1, $3);
1948 #endif
1949  $$ = dispatch2(assign, $1, dispatch2(rescue_mod, $3, $5));
1950 
1951  }
1952  | var_lhs tOP_ASGN arg
1953  {
1954  value_expr($3);
1955  $$ = new_op_assign($1, $2, $3);
1956  }
1957  | var_lhs tOP_ASGN arg modifier_rescue arg
1958  {
1959 #if 0
1960  value_expr($3);
1961  $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
1962 #endif
1963  $3 = dispatch2(rescue_mod, $3, $5);
1964 
1965  $$ = new_op_assign($1, $2, $3);
1966  }
1967  | primary_value '[' opt_call_args rbracket tOP_ASGN arg
1968  {
1969 #if 0
1970  NODE *args;
1971 
1972  value_expr($6);
1973  if (!$3) $3 = NEW_ZARRAY();
1974  if (nd_type($3) == NODE_BLOCK_PASS) {
1975  args = NEW_ARGSCAT($3, $6);
1976  }
1977  else {
1978  args = arg_concat($3, $6);
1979  }
1980  if ($5 == tOROP) {
1981  $5 = 0;
1982  }
1983  else if ($5 == tANDOP) {
1984  $5 = 1;
1985  }
1986  $$ = NEW_OP_ASGN1($1, $5, args);
1987  fixpos($$, $1);
1988 #endif
1989  $1 = dispatch2(aref_field, $1, escape_Qundef($3));
1990  $$ = dispatch3(opassign, $1, $5, $6);
1991 
1992  }
1993  | primary_value '.' tIDENTIFIER tOP_ASGN arg
1994  {
1995  value_expr($5);
1996  $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1997  }
1998  | primary_value '.' tCONSTANT tOP_ASGN arg
1999  {
2000  value_expr($5);
2001  $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
2002  }
2003  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
2004  {
2005  value_expr($5);
2006  $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
2007  }
2008  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
2009  {
2010 #if 0
2011  $$ = NEW_COLON2($1, $3);
2012  $$ = new_const_op_assign($$, $4, $5);
2013 #endif
2014  $$ = dispatch2(const_path_field, $1, $3);
2015  $$ = dispatch3(opassign, $$, $4, $5);
2016 
2017  }
2019  {
2020 #if 0
2021  $$ = NEW_COLON3($2);
2022  $$ = new_const_op_assign($$, $3, $4);
2023 #endif
2024  $$ = dispatch1(top_const_field, $2);
2025  $$ = dispatch3(opassign, $$, $3, $4);
2026 
2027  }
2028  | backref tOP_ASGN arg
2029  {
2030 #if 0
2031  rb_backref_error($1);
2032  $$ = NEW_BEGIN(0);
2033 #endif
2034  $$ = dispatch1(var_field, $1);
2035  $$ = dispatch3(opassign, $$, $2, $3);
2036  $$ = dispatch1(assign_error, $$);
2037 
2038  }
2039  | arg tDOT2 arg
2040  {
2041 #if 0
2042  value_expr($1);
2043  value_expr($3);
2044  $$ = NEW_DOT2($1, $3);
2045  if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
2046  nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
2048  }
2049 #endif
2050  $$ = dispatch2(dot2, $1, $3);
2051 
2052  }
2053  | arg tDOT3 arg
2054  {
2055 #if 0
2056  value_expr($1);
2057  value_expr($3);
2058  $$ = NEW_DOT3($1, $3);
2059  if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
2060  nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
2062  }
2063 #endif
2064  $$ = dispatch2(dot3, $1, $3);
2065 
2066  }
2067  | arg '+' arg
2068  {
2069 #if 0
2070  $$ = call_bin_op($1, '+', $3);
2071 #endif
2072  $$ = dispatch3(binary, $1, ID2SYM('+'), $3);
2073 
2074  }
2075  | arg '-' arg
2076  {
2077 #if 0
2078  $$ = call_bin_op($1, '-', $3);
2079 #endif
2080  $$ = dispatch3(binary, $1, ID2SYM('-'), $3);
2081 
2082  }
2083  | arg '*' arg
2084  {
2085 #if 0
2086  $$ = call_bin_op($1, '*', $3);
2087 #endif
2088  $$ = dispatch3(binary, $1, ID2SYM('*'), $3);
2089 
2090  }
2091  | arg '/' arg
2092  {
2093 #if 0
2094  $$ = call_bin_op($1, '/', $3);
2095 #endif
2096  $$ = dispatch3(binary, $1, ID2SYM('/'), $3);
2097 
2098  }
2099  | arg '%' arg
2100  {
2101 #if 0
2102  $$ = call_bin_op($1, '%', $3);
2103 #endif
2104  $$ = dispatch3(binary, $1, ID2SYM('%'), $3);
2105 
2106  }
2107  | arg tPOW arg
2108  {
2109 #if 0
2110  $$ = call_bin_op($1, tPOW, $3);
2111 #endif
2112  $$ = dispatch3(binary, $1, ripper_intern("**"), $3);
2113 
2114  }
2116  {
2117 #if 0
2118  $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
2119 #endif
2120  $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2121  $$ = dispatch2(unary, ripper_intern("-@"), $$);
2122 
2123  }
2125  {
2126 #if 0
2127  $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
2128 #endif
2129  $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2130  $$ = dispatch2(unary, ripper_intern("-@"), $$);
2131 
2132  }
2133  | tUPLUS arg
2134  {
2135 #if 0
2136  $$ = call_uni_op($2, tUPLUS);
2137 #endif
2138  $$ = dispatch2(unary, ripper_intern("+@"), $2);
2139 
2140  }
2141  | tUMINUS arg
2142  {
2143 #if 0
2144  $$ = call_uni_op($2, tUMINUS);
2145 #endif
2146  $$ = dispatch2(unary, ripper_intern("-@"), $2);
2147 
2148  }
2149  | arg '|' arg
2150  {
2151 #if 0
2152  $$ = call_bin_op($1, '|', $3);
2153 #endif
2154  $$ = dispatch3(binary, $1, ID2SYM('|'), $3);
2155 
2156  }
2157  | arg '^' arg
2158  {
2159 #if 0
2160  $$ = call_bin_op($1, '^', $3);
2161 #endif
2162  $$ = dispatch3(binary, $1, ID2SYM('^'), $3);
2163 
2164  }
2165  | arg '&' arg
2166  {
2167 #if 0
2168  $$ = call_bin_op($1, '&', $3);
2169 #endif
2170  $$ = dispatch3(binary, $1, ID2SYM('&'), $3);
2171 
2172  }
2173  | arg tCMP arg
2174  {
2175 #if 0
2176  $$ = call_bin_op($1, tCMP, $3);
2177 #endif
2178  $$ = dispatch3(binary, $1, ripper_intern("<=>"), $3);
2179 
2180  }
2181  | arg '>' arg
2182  {
2183 #if 0
2184  $$ = call_bin_op($1, '>', $3);
2185 #endif
2186  $$ = dispatch3(binary, $1, ID2SYM('>'), $3);
2187 
2188  }
2189  | arg tGEQ arg
2190  {
2191 #if 0
2192  $$ = call_bin_op($1, tGEQ, $3);
2193 #endif
2194  $$ = dispatch3(binary, $1, ripper_intern(">="), $3);
2195 
2196  }
2197  | arg '<' arg
2198  {
2199 #if 0
2200  $$ = call_bin_op($1, '<', $3);
2201 #endif
2202  $$ = dispatch3(binary, $1, ID2SYM('<'), $3);
2203 
2204  }
2205  | arg tLEQ arg
2206  {
2207 #if 0
2208  $$ = call_bin_op($1, tLEQ, $3);
2209 #endif
2210  $$ = dispatch3(binary, $1, ripper_intern("<="), $3);
2211 
2212  }
2213  | arg tEQ arg
2214  {
2215 #if 0
2216  $$ = call_bin_op($1, tEQ, $3);
2217 #endif
2218  $$ = dispatch3(binary, $1, ripper_intern("=="), $3);
2219 
2220  }
2221  | arg tEQQ arg
2222  {
2223 #if 0
2224  $$ = call_bin_op($1, tEQQ, $3);
2225 #endif
2226  $$ = dispatch3(binary, $1, ripper_intern("==="), $3);
2227 
2228  }
2229  | arg tNEQ arg
2230  {
2231 #if 0
2232  $$ = call_bin_op($1, tNEQ, $3);
2233 #endif
2234  $$ = dispatch3(binary, $1, ripper_intern("!="), $3);
2235 
2236  }
2237  | arg tMATCH arg
2238  {
2239 #if 0
2240  $$ = match_op($1, $3);
2241  if (nd_type($1) == NODE_LIT && RB_TYPE_P($1->nd_lit, T_REGEXP)) {
2242  $$ = reg_named_capture_assign($1->nd_lit, $$);
2243  }
2244 #endif
2245  $$ = dispatch3(binary, $1, ripper_intern("=~"), $3);
2246 
2247  }
2248  | arg tNMATCH arg
2249  {
2250 #if 0
2251  $$ = call_bin_op($1, tNMATCH, $3);
2252 #endif
2253  $$ = dispatch3(binary, $1, ripper_intern("!~"), $3);
2254 
2255  }
2256  | '!' arg
2257  {
2258 #if 0
2259  $$ = call_uni_op(cond($2), '!');
2260 #endif
2261  $$ = dispatch2(unary, ID2SYM('!'), $2);
2262 
2263  }
2264  | '~' arg
2265  {
2266 #if 0
2267  $$ = call_uni_op($2, '~');
2268 #endif
2269  $$ = dispatch2(unary, ID2SYM('~'), $2);
2270 
2271  }
2272  | arg tLSHFT arg
2273  {
2274 #if 0
2275  $$ = call_bin_op($1, tLSHFT, $3);
2276 #endif
2277  $$ = dispatch3(binary, $1, ripper_intern("<<"), $3);
2278 
2279  }
2280  | arg tRSHFT arg
2281  {
2282 #if 0
2283  $$ = call_bin_op($1, tRSHFT, $3);
2284 #endif
2285  $$ = dispatch3(binary, $1, ripper_intern(">>"), $3);
2286 
2287  }
2288  | arg tANDOP arg
2289  {
2290 #if 0
2291  $$ = logop(NODE_AND, $1, $3);
2292 #endif
2293  $$ = dispatch3(binary, $1, ripper_intern("&&"), $3);
2294 
2295  }
2296  | arg tOROP arg
2297  {
2298 #if 0
2299  $$ = logop(NODE_OR, $1, $3);
2300 #endif
2301  $$ = dispatch3(binary, $1, ripper_intern("||"), $3);
2302 
2303  }
2304  | keyword_defined opt_nl {in_defined = 1;} arg
2305  {
2306 #if 0
2307  in_defined = 0;
2308  $$ = NEW_DEFINED($4);
2309 #endif
2310  in_defined = 0;
2311  $$ = dispatch1(defined, $4);
2312 
2313  }
2314  | arg '?' arg opt_nl ':' arg
2315  {
2316 #if 0
2317  value_expr($1);
2318  $$ = NEW_IF(cond($1), $3, $6);
2319  fixpos($$, $1);
2320 #endif
2321  $$ = dispatch3(ifop, $1, $3, $6);
2322 
2323  }
2324  | primary
2325  {
2326  $$ = $1;
2327  }
2328  ;
2329 
2330 arg_value : arg
2331  {
2332 #if 0
2333  value_expr($1);
2334  $$ = $1;
2335  if (!$$) $$ = NEW_NIL();
2336 #endif
2337  $$ = $1;
2338 
2339  }
2340  ;
2341 
2342 aref_args : none
2343  | args trailer
2344  {
2345  $$ = $1;
2346  }
2347  | args ',' assocs trailer
2348  {
2349 #if 0
2350  $$ = arg_append($1, NEW_HASH($3));
2351 #endif
2352  $$ = arg_add_assocs($1, $3);
2353 
2354  }
2355  | assocs trailer
2356  {
2357 #if 0
2358  $$ = NEW_LIST(NEW_HASH($1));
2359 #endif
2360  $$ = arg_add_assocs(arg_new(), $1);
2361 
2362  }
2363  ;
2364 
2365 paren_args : '(' opt_call_args rparen
2366  {
2367 #if 0
2368  $$ = $2;
2369 #endif
2370  $$ = dispatch1(arg_paren, escape_Qundef($2));
2371 
2372  }
2373  ;
2374 
2375 opt_paren_args : none
2376  | paren_args
2377  ;
2378 
2379 opt_call_args : none
2380  | call_args
2381  | args ','
2382  {
2383  $$ = $1;
2384  }
2385  | args ',' assocs ','
2386  {
2387 #if 0
2388  $$ = arg_append($1, NEW_HASH($3));
2389 #endif
2390  $$ = arg_add_assocs($1, $3);
2391 
2392  }
2393  | assocs ','
2394  {
2395 #if 0
2396  $$ = NEW_LIST(NEW_HASH($1));
2397 #endif
2398  $$ = arg_add_assocs(arg_new(), $1);
2399 
2400  }
2401  ;
2402 
2403 call_args : command
2404  {
2405 #if 0
2406  value_expr($1);
2407  $$ = NEW_LIST($1);
2408 #endif
2409  $$ = arg_add(arg_new(), $1);
2410 
2411  }
2412  | args opt_block_arg
2413  {
2414 #if 0
2415  $$ = arg_blk_pass($1, $2);
2416 #endif
2417  $$ = arg_add_optblock($1, $2);
2418 
2419  }
2420  | assocs opt_block_arg
2421  {
2422 #if 0
2423  $$ = NEW_LIST(NEW_HASH($1));
2424  $$ = arg_blk_pass($$, $2);
2425 #endif
2426  $$ = arg_add_assocs(arg_new(), $1);
2427  $$ = arg_add_optblock($$, $2);
2428 
2429  }
2430  | args ',' assocs opt_block_arg
2431  {
2432 #if 0
2433  $$ = arg_append($1, NEW_HASH($3));
2434  $$ = arg_blk_pass($$, $4);
2435 #endif
2436  $$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
2437 
2438  }
2439  | block_arg
2440 /*
2441 */
2442  {
2443  $$ = arg_add_block(arg_new(), $1);
2444  }
2445 
2446  ;
2447 
2448 command_args : {
2449  $<val>$ = cmdarg_stack;
2450  CMDARG_PUSH(1);
2451  }
2452  call_args
2453  {
2454  /* CMDARG_POP() */
2455  cmdarg_stack = $<val>1;
2456  $$ = $2;
2457  }
2458  ;
2459 
2460 block_arg : tAMPER arg_value
2461  {
2462 #if 0
2463  $$ = NEW_BLOCK_PASS($2);
2464 #endif
2465  $$ = $2;
2466 
2467  }
2468  ;
2469 
2470 opt_block_arg : ',' block_arg
2471  {
2472  $$ = $2;
2473  }
2474  | none
2475  {
2476  $$ = 0;
2477  }
2478  ;
2479 
2480 args : arg_value
2481  {
2482 #if 0
2483  $$ = NEW_LIST($1);
2484 #endif
2485  $$ = arg_add(arg_new(), $1);
2486 
2487  }
2488  | tSTAR arg_value
2489  {
2490 #if 0
2491  $$ = NEW_SPLAT($2);
2492 #endif
2493  $$ = arg_add_star(arg_new(), $2);
2494 
2495  }
2496  | args ',' arg_value
2497  {
2498 #if 0
2499  NODE *n1;
2500  if ((n1 = splat_array($1)) != 0) {
2501  $$ = list_append(n1, $3);
2502  }
2503  else {
2504  $$ = arg_append($1, $3);
2505  }
2506 #endif
2507  $$ = arg_add($1, $3);
2508 
2509  }
2510  | args ',' tSTAR arg_value
2511  {
2512 #if 0
2513  NODE *n1;
2514  if ((nd_type($4) == NODE_ARRAY) && (n1 = splat_array($1)) != 0) {
2515  $$ = list_concat(n1, $4);
2516  }
2517  else {
2518  $$ = arg_concat($1, $4);
2519  }
2520 #endif
2521  $$ = arg_add_star($1, $4);
2522 
2523  }
2524  ;
2525 
2526 mrhs : args ',' arg_value
2527  {
2528 #if 0
2529  NODE *n1;
2530  if ((n1 = splat_array($1)) != 0) {
2531  $$ = list_append(n1, $3);
2532  }
2533  else {
2534  $$ = arg_append($1, $3);
2535  }
2536 #endif
2537  $$ = mrhs_add(args2mrhs($1), $3);
2538 
2539  }
2540  | args ',' tSTAR arg_value
2541  {
2542 #if 0
2543  NODE *n1;
2544  if (nd_type($4) == NODE_ARRAY &&
2545  (n1 = splat_array($1)) != 0) {
2546  $$ = list_concat(n1, $4);
2547  }
2548  else {
2549  $$ = arg_concat($1, $4);
2550  }
2551 #endif
2552  $$ = mrhs_add_star(args2mrhs($1), $4);
2553 
2554  }
2555  | tSTAR arg_value
2556  {
2557 #if 0
2558  $$ = NEW_SPLAT($2);
2559 #endif
2560  $$ = mrhs_add_star(mrhs_new(), $2);
2561 
2562  }
2563  ;
2564 
2565 primary : literal
2566  | strings
2567  | xstring
2568  | regexp
2569  | words
2570  | qwords
2571  | symbols
2572  | qsymbols
2573  | var_ref
2574  | backref
2575  | tFID
2576  {
2577 #if 0
2578  $$ = NEW_FCALL($1, 0);
2579 #endif
2580  $$ = method_arg(dispatch1(fcall, $1), arg_new());
2581 
2582  }
2583  | k_begin
2584  {
2585  $<val>1 = cmdarg_stack;
2586  cmdarg_stack = 0;
2587 #if 0
2588  $<num>$ = ruby_sourceline;
2589 #endif
2590 
2591  }
2592  bodystmt
2593  k_end
2594  {
2595  cmdarg_stack = $<val>1;
2596 #if 0
2597  if ($3 == NULL) {
2598  $$ = NEW_NIL();
2599  }
2600  else {
2601  if (nd_type($3) == NODE_RESCUE ||
2602  nd_type($3) == NODE_ENSURE)
2603  nd_set_line($3, $<num>2);
2604  $$ = NEW_BEGIN($3);
2605  }
2606  nd_set_line($$, $<num>2);
2607 #endif
2608  $$ = dispatch1(begin, $3);
2609 
2610  }
2611  | tLPAREN_ARG {lex_state = EXPR_ENDARG;} rparen
2612  {
2613 #if 0
2614  $$ = 0;
2615 #endif
2616  $$ = dispatch1(paren, 0);
2617 
2618  }
2619  | tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} rparen
2620  {
2621 #if 0
2622  $$ = $2;
2623 #endif
2624  $$ = dispatch1(paren, $2);
2625 
2626  }
2627  | tLPAREN compstmt ')'
2628  {
2629 #if 0
2630  $$ = $2;
2631 #endif
2632  $$ = dispatch1(paren, $2);
2633 
2634  }
2635  | primary_value tCOLON2 tCONSTANT
2636  {
2637 #if 0
2638  $$ = NEW_COLON2($1, $3);
2639 #endif
2640  $$ = dispatch2(const_path_ref, $1, $3);
2641 
2642  }
2643  | tCOLON3 tCONSTANT
2644  {
2645 #if 0
2646  $$ = NEW_COLON3($2);
2647 #endif
2648  $$ = dispatch1(top_const_ref, $2);
2649 
2650  }
2651  | tLBRACK aref_args ']'
2652  {
2653 #if 0
2654  if ($2 == 0) {
2655  $$ = NEW_ZARRAY(); /* zero length array*/
2656  }
2657  else {
2658  $$ = $2;
2659  }
2660 #endif
2661  $$ = dispatch1(array, escape_Qundef($2));
2662 
2663  }
2664  | tLBRACE assoc_list '}'
2665  {
2666 #if 0
2667  $$ = NEW_HASH($2);
2668 #endif
2669  $$ = dispatch1(hash, escape_Qundef($2));
2670 
2671  }
2672  | keyword_return
2673  {
2674 #if 0
2675  $$ = NEW_RETURN(0);
2676 #endif
2677  $$ = dispatch0(return0);
2678 
2679  }
2680  | keyword_yield '(' call_args rparen
2681  {
2682 #if 0
2683  $$ = new_yield($3);
2684 #endif
2685  $$ = dispatch1(yield, dispatch1(paren, $3));
2686 
2687  }
2688  | keyword_yield '(' rparen
2689  {
2690 #if 0
2691  $$ = NEW_YIELD(0);
2692 #endif
2693  $$ = dispatch1(yield, dispatch1(paren, arg_new()));
2694 
2695  }
2696  | keyword_yield
2697  {
2698 #if 0
2699  $$ = NEW_YIELD(0);
2700 #endif
2701  $$ = dispatch0(yield0);
2702 
2703  }
2704  | keyword_defined opt_nl '(' {in_defined = 1;} expr rparen
2705  {
2706 #if 0
2707  in_defined = 0;
2708  $$ = NEW_DEFINED($5);
2709 #endif
2710  in_defined = 0;
2711  $$ = dispatch1(defined, $5);
2712 
2713  }
2714  | keyword_not '(' expr rparen
2715  {
2716 #if 0
2717  $$ = call_uni_op(cond($3), '!');
2718 #endif
2719  $$ = dispatch2(unary, ripper_intern("not"), $3);
2720 
2721  }
2722  | keyword_not '(' rparen
2723  {
2724 #if 0
2725  $$ = call_uni_op(cond(NEW_NIL()), '!');
2726 #endif
2727  $$ = dispatch2(unary, ripper_intern("not"), Qnil);
2728 
2729  }
2730  | fcall brace_block
2731  {
2732 #if 0
2733  $2->nd_iter = $1;
2734  $$ = $2;
2735 #endif
2736  $$ = method_arg(dispatch1(fcall, $1), arg_new());
2737  $$ = method_add_block($$, $2);
2738 
2739  }
2740  | method_call
2741  | method_call brace_block
2742  {
2743 #if 0
2744  block_dup_check($1->nd_args, $2);
2745  $2->nd_iter = $1;
2746  $$ = $2;
2747 #endif
2748  $$ = method_add_block($1, $2);
2749 
2750  }
2751  | tLAMBDA lambda
2752  {
2753  $$ = $2;
2754  }
2755  | k_if expr_value then
2756  compstmt
2757  if_tail
2758  k_end
2759  {
2760 #if 0
2761  $$ = NEW_IF(cond($2), $4, $5);
2762  fixpos($$, $2);
2763 #endif
2764  $$ = dispatch3(if, $2, $4, escape_Qundef($5));
2765 
2766  }
2767  | k_unless expr_value then
2768  compstmt
2769  opt_else
2770  k_end
2771  {
2772 #if 0
2773  $$ = NEW_UNLESS(cond($2), $4, $5);
2774  fixpos($$, $2);
2775 #endif
2776  $$ = dispatch3(unless, $2, $4, escape_Qundef($5));
2777 
2778  }
2779  | k_while {COND_PUSH(1);} expr_value do {COND_POP();}
2780  compstmt
2781  k_end
2782  {
2783 #if 0
2784  $$ = NEW_WHILE(cond($3), $6, 1);
2785  fixpos($$, $3);
2786 #endif
2787  $$ = dispatch2(while, $3, $6);
2788 
2789  }
2790  | k_until {COND_PUSH(1);} expr_value do {COND_POP();}
2791  compstmt
2792  k_end
2793  {
2794 #if 0
2795  $$ = NEW_UNTIL(cond($3), $6, 1);
2796  fixpos($$, $3);
2797 #endif
2798  $$ = dispatch2(until, $3, $6);
2799 
2800  }
2801  | k_case expr_value opt_terms
2802  case_body
2803  k_end
2804  {
2805 #if 0
2806  $$ = NEW_CASE($2, $4);
2807  fixpos($$, $2);
2808 #endif
2809  $$ = dispatch2(case, $2, $4);
2810 
2811  }
2812  | k_case opt_terms case_body k_end
2813  {
2814 #if 0
2815  $$ = NEW_CASE(0, $3);
2816 #endif
2817  $$ = dispatch2(case, Qnil, $3);
2818 
2819  }
2820  | k_for for_var keyword_in
2821  {COND_PUSH(1);}
2822  expr_value do
2823  {COND_POP();}
2824  compstmt
2825  k_end
2826  {
2827 #if 0
2828  /*
2829  * for a, b, c in e
2830  * #=>
2831  * e.each{|*x| a, b, c = x
2832  *
2833  * for a in e
2834  * #=>
2835  * e.each{|x| a, = x}
2836  */
2837  ID id = internal_id();
2838  ID *tbl = ALLOC_N(ID, 2);
2839  NODE *m = NEW_ARGS_AUX(0, 0);
2840  NODE *args, *scope;
2841 
2842  if (nd_type($2) == NODE_MASGN) {
2843  /* if args.length == 1 && args[0].kind_of?(Array)
2844  * args = args[0]
2845  * end
2846  */
2847  NODE *one = NEW_LIST(NEW_LIT(INT2FIX(1)));
2848  NODE *zero = NEW_LIST(NEW_LIT(INT2FIX(0)));
2849  m->nd_next = block_append(
2850  NEW_IF(
2852  NEW_CALL(NEW_CALL(NEW_DVAR(id), idLength, 0),
2853  idEq, one),
2854  NEW_CALL(NEW_CALL(NEW_DVAR(id), idAREF, zero),
2855  rb_intern("kind_of?"), NEW_LIST(NEW_LIT(rb_cArray))),
2856  0),
2857  NEW_DASGN_CURR(id,
2858  NEW_CALL(NEW_DVAR(id), idAREF, zero)),
2859  0),
2860  node_assign($2, NEW_DVAR(id)));
2861 
2862  args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
2863  }
2864  else {
2865  if (nd_type($2) == NODE_LASGN ||
2866  nd_type($2) == NODE_DASGN ||
2867  nd_type($2) == NODE_DASGN_CURR) {
2868  $2->nd_value = NEW_DVAR(id);
2869  m->nd_plen = 1;
2870  m->nd_next = $2;
2871  args = new_args(m, 0, 0, 0, new_args_tail(0, 0, 0));
2872  }
2873  else {
2874  m->nd_next = node_assign(NEW_MASGN(NEW_LIST($2), 0), NEW_DVAR(id));
2875  args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
2876  }
2877  }
2878  scope = NEW_NODE(NODE_SCOPE, tbl, $8, args);
2879  tbl[0] = 1; tbl[1] = id;
2880  $$ = NEW_FOR(0, $5, scope);
2881  fixpos($$, $2);
2882 #endif
2883  $$ = dispatch3(for, $2, $5, $8);
2884 
2885  }
2886  | k_class cpath superclass
2887  {
2888  if (in_def || in_single)
2889  yyerror("class definition in method body");
2890  local_push(0);
2891 #if 0
2892  $<num>$ = ruby_sourceline;
2893 #endif
2894 
2895  }
2896  bodystmt
2897  k_end
2898  {
2899 #if 0
2900  $$ = NEW_CLASS($2, $5, $3);
2901  nd_set_line($$, $<num>4);
2902 #endif
2903  $$ = dispatch3(class, $2, $3, $5);
2904 
2905  local_pop();
2906  }
2907  | k_class tLSHFT expr
2908  {
2909  $<num>$ = in_def;
2910  in_def = 0;
2911  }
2912  term
2913  {
2914  $<num>$ = in_single;
2915  in_single = 0;
2916  local_push(0);
2917  }
2918  bodystmt
2919  k_end
2920  {
2921 #if 0
2922  $$ = NEW_SCLASS($3, $7);
2923  fixpos($$, $3);
2924 #endif
2925  $$ = dispatch2(sclass, $3, $7);
2926 
2927  local_pop();
2928  in_def = $<num>4;
2929  in_single = $<num>6;
2930  }
2931  | k_module cpath
2932  {
2933  if (in_def || in_single)
2934  yyerror("module definition in method body");
2935  local_push(0);
2936 #if 0
2937  $<num>$ = ruby_sourceline;
2938 #endif
2939 
2940  }
2941  bodystmt
2942  k_end
2943  {
2944 #if 0
2945  $$ = NEW_MODULE($2, $4);
2946  nd_set_line($$, $<num>3);
2947 #endif
2948  $$ = dispatch2(module, $2, $4);
2949 
2950  local_pop();
2951  }
2952  | k_def fname
2953  {
2954  $<id>$ = cur_mid;
2955  cur_mid = $2;
2956  in_def++;
2957  local_push(0);
2958  }
2959  f_arglist
2960  bodystmt
2961  k_end
2962  {
2963 #if 0
2964  NODE *body = remove_begin($5);
2965  reduce_nodes(&body);
2966  $$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE);
2967  nd_set_line($$, $<num>1);
2968 #endif
2969  $$ = dispatch3(def, $2, $4, $5);
2970 
2971  local_pop();
2972  in_def--;
2973  cur_mid = $<id>3;
2974  }
2975  | k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
2976  {
2977  in_single++;
2978  lex_state = EXPR_ENDFN; /* force for args */
2979  local_push(0);
2980  }
2981  f_arglist
2982  bodystmt
2983  k_end
2984  {
2985 #if 0
2986  NODE *body = remove_begin($8);
2987  reduce_nodes(&body);
2988  $$ = NEW_DEFS($2, $5, $7, body);
2989  nd_set_line($$, $<num>1);
2990 #endif
2991  $$ = dispatch5(defs, $2, $3, $5, $7, $8);
2992 
2993  local_pop();
2994  in_single--;
2995  }
2996  | keyword_break
2997  {
2998 #if 0
2999  $$ = NEW_BREAK(0);
3000 #endif
3001  $$ = dispatch1(break, arg_new());
3002 
3003  }
3004  | keyword_next
3005  {
3006 #if 0
3007  $$ = NEW_NEXT(0);
3008 #endif
3009  $$ = dispatch1(next, arg_new());
3010 
3011  }
3012  | keyword_redo
3013  {
3014 #if 0
3015  $$ = NEW_REDO();
3016 #endif
3017  $$ = dispatch0(redo);
3018 
3019  }
3020  | keyword_retry
3021  {
3022 #if 0
3023  $$ = NEW_RETRY();
3024 #endif
3025  $$ = dispatch0(retry);
3026 
3027  }
3028  ;
3029 
3030 primary_value : primary
3031  {
3032 #if 0
3033  value_expr($1);
3034  $$ = $1;
3035  if (!$$) $$ = NEW_NIL();
3036 #endif
3037  $$ = $1;
3038 
3039  }
3040  ;
3041 
3042 k_begin : keyword_begin
3043  {
3044  token_info_push("begin");
3045  }
3046  ;
3047 
3048 k_if : keyword_if
3049  {
3050  token_info_push("if");
3051  }
3052  ;
3053 
3054 k_unless : keyword_unless
3055  {
3056  token_info_push("unless");
3057  }
3058  ;
3059 
3060 k_while : keyword_while
3061  {
3062  token_info_push("while");
3063  }
3064  ;
3065 
3066 k_until : keyword_until
3067  {
3068  token_info_push("until");
3069  }
3070  ;
3071 
3072 k_case : keyword_case
3073  {
3074  token_info_push("case");
3075  }
3076  ;
3077 
3078 k_for : keyword_for
3079  {
3080  token_info_push("for");
3081  }
3082  ;
3083 
3084 k_class : keyword_class
3085  {
3086  token_info_push("class");
3087  }
3088  ;
3089 
3090 k_module : keyword_module
3091  {
3092  token_info_push("module");
3093  }
3094  ;
3095 
3096 k_def : keyword_def
3097  {
3098  token_info_push("def");
3099 #if 0
3100  $<num>$ = ruby_sourceline;
3101 #endif
3102 
3103  }
3104  ;
3105 
3106 k_end : keyword_end
3107  {
3108  token_info_pop("end");
3109  }
3110  ;
3111 
3112 then : term
3113 /*
3114 */
3115  { $$ = Qnil; }
3116 
3117  | keyword_then
3118  | term keyword_then
3119 /*
3120 */
3121  { $$ = $2; }
3122 
3123  ;
3124 
3125 do : term
3126 /*
3127 */
3128  { $$ = Qnil; }
3129 
3130  | keyword_do_cond
3131  ;
3132 
3133 if_tail : opt_else
3134  | keyword_elsif expr_value then
3135  compstmt
3136  if_tail
3137  {
3138 #if 0
3139  $$ = NEW_IF(cond($2), $4, $5);
3140  fixpos($$, $2);
3141 #endif
3142  $$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
3143 
3144  }
3145  ;
3146 
3147 opt_else : none
3149  {
3150 #if 0
3151  $$ = $2;
3152 #endif
3153  $$ = dispatch1(else, $2);
3154 
3155  }
3156  ;
3157 
3158 for_var : lhs
3159  | mlhs
3160  ;
3161 
3162 f_marg : f_norm_arg
3163  {
3164  $$ = assignable($1, 0);
3165 #if 0
3166 #endif
3167  $$ = dispatch1(mlhs_paren, $$);
3168 
3169  }
3170  | tLPAREN f_margs rparen
3171  {
3172 #if 0
3173  $$ = $2;
3174 #endif
3175  $$ = dispatch1(mlhs_paren, $2);
3176 
3177  }
3178  ;
3179 
3180 f_marg_list : f_marg
3181  {
3182 #if 0
3183  $$ = NEW_LIST($1);
3184 #endif
3185  $$ = mlhs_add(mlhs_new(), $1);
3186 
3187  }
3188  | f_marg_list ',' f_marg
3189  {
3190 #if 0
3191  $$ = list_append($1, $3);
3192 #endif
3193  $$ = mlhs_add($1, $3);
3194 
3195  }
3196  ;
3197 
3198 f_margs : f_marg_list
3199  {
3200 #if 0
3201  $$ = NEW_MASGN($1, 0);
3202 #endif
3203  $$ = $1;
3204 
3205  }
3206  | f_marg_list ',' tSTAR f_norm_arg
3207  {
3208  $$ = assignable($4, 0);
3209 #if 0
3210  $$ = NEW_MASGN($1, $$);
3211 #endif
3212  $$ = mlhs_add_star($1, $$);
3213 
3214  }
3215  | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
3216  {
3217  $$ = assignable($4, 0);
3218 #if 0
3219  $$ = NEW_MASGN($1, NEW_POSTARG($$, $6));
3220 #endif
3221  $$ = mlhs_add_star($1, $$);
3222 
3223  }
3224  | f_marg_list ',' tSTAR
3225  {
3226 #if 0
3227  $$ = NEW_MASGN($1, -1);
3228 #endif
3229  $$ = mlhs_add_star($1, Qnil);
3230 
3231  }
3232  | f_marg_list ',' tSTAR ',' f_marg_list
3233  {
3234 #if 0
3235  $$ = NEW_MASGN($1, NEW_POSTARG(-1, $5));
3236 #endif
3237  $$ = mlhs_add_star($1, $5);
3238 
3239  }
3240  | tSTAR f_norm_arg
3241  {
3242  $$ = assignable($2, 0);
3243 #if 0
3244  $$ = NEW_MASGN(0, $$);
3245 #endif
3246  $$ = mlhs_add_star(mlhs_new(), $$);
3247 
3248  }
3249  | tSTAR f_norm_arg ',' f_marg_list
3250  {
3251  $$ = assignable($2, 0);
3252 #if 0
3253  $$ = NEW_MASGN(0, NEW_POSTARG($$, $4));
3254 #endif
3255  #if 0
3256  TODO: Check me
3257  #endif
3258  $$ = mlhs_add_star($$, $4);
3259 
3260  }
3261  | tSTAR
3262  {
3263 #if 0
3264  $$ = NEW_MASGN(0, -1);
3265 #endif
3266  $$ = mlhs_add_star(mlhs_new(), Qnil);
3267 
3268  }
3269  | tSTAR ',' f_marg_list
3270  {
3271 #if 0
3272  $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
3273 #endif
3274  $$ = mlhs_add_star(mlhs_new(), Qnil);
3275 
3276  }
3277  ;
3278 
3279 
3280 block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
3281  {
3282  $$ = new_args_tail($1, $3, $4);
3283  }
3284  | f_block_kwarg opt_f_block_arg
3285  {
3286  $$ = new_args_tail($1, Qnone, $2);
3287  }
3288  | f_kwrest opt_f_block_arg
3289  {
3290  $$ = new_args_tail(Qnone, $1, $2);
3291  }
3292  | f_block_arg
3293  {
3294  $$ = new_args_tail(Qnone, Qnone, $1);
3295  }
3296  ;
3297 
3298 opt_block_args_tail : ',' block_args_tail
3299  {
3300  $$ = $2;
3301  }
3302  | /* none */
3303  {
3304  $$ = new_args_tail(Qnone, Qnone, Qnone);
3305  }
3306  ;
3307 
3308 block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
3309  {
3310  $$ = new_args($1, $3, $5, Qnone, $6);
3311  }
3312  | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
3313  {
3314  $$ = new_args($1, $3, $5, $7, $8);
3315  }
3316  | f_arg ',' f_block_optarg opt_block_args_tail
3317  {
3318  $$ = new_args($1, $3, Qnone, Qnone, $4);
3319  }
3320  | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
3321  {
3322  $$ = new_args($1, $3, Qnone, $5, $6);
3323  }
3324  | f_arg ',' f_rest_arg opt_block_args_tail
3325  {
3326  $$ = new_args($1, Qnone, $3, Qnone, $4);
3327  }
3328  | f_arg ','
3329  {
3330  $$ = new_args($1, Qnone, 1, Qnone, new_args_tail(Qnone, Qnone, Qnone));
3331 #if 0
3332 #endif
3333  dispatch1(excessed_comma, $$);
3334 
3335  }
3336  | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
3337  {
3338  $$ = new_args($1, Qnone, $3, $5, $6);
3339  }
3340  | f_arg opt_block_args_tail
3341  {
3342  $$ = new_args($1, Qnone, Qnone, Qnone, $2);
3343  }
3344  | f_block_optarg ',' f_rest_arg opt_block_args_tail
3345  {
3346  $$ = new_args(Qnone, $1, $3, Qnone, $4);
3347  }
3348  | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
3349  {
3350  $$ = new_args(Qnone, $1, $3, $5, $6);
3351  }
3352  | f_block_optarg opt_block_args_tail
3353  {
3354  $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
3355  }
3356  | f_block_optarg ',' f_arg opt_block_args_tail
3357  {
3358  $$ = new_args(Qnone, $1, Qnone, $3, $4);
3359  }
3360  | f_rest_arg opt_block_args_tail
3361  {
3362  $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
3363  }
3364  | f_rest_arg ',' f_arg opt_block_args_tail
3365  {
3366  $$ = new_args(Qnone, Qnone, $1, $3, $4);
3367  }
3368  | block_args_tail
3369  {
3370  $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
3371  }
3372  ;
3373 
3374 opt_block_param : none
3375  | block_param_def
3376  {
3377  command_start = TRUE;
3378  }
3379  ;
3380 
3381 block_param_def : '|' opt_bv_decl '|'
3382  {
3383 #if 0
3384  $$ = 0;
3385 #endif
3386  $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
3387  escape_Qundef($2));
3388 
3389  }
3390  | tOROP
3391  {
3392 #if 0
3393  $$ = 0;
3394 #endif
3395  $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
3396  Qnil);
3397 
3398  }
3399  | '|' block_param opt_bv_decl '|'
3400  {
3401 #if 0
3402  $$ = $2;
3403 #endif
3404  $$ = blockvar_new(escape_Qundef($2), escape_Qundef($3));
3405 
3406  }
3407  ;
3408 
3409 
3410 opt_bv_decl : opt_nl
3411  {
3412  $$ = 0;
3413  }
3414  | opt_nl ';' bv_decls opt_nl
3415  {
3416 #if 0
3417  $$ = 0;
3418 #endif
3419  $$ = $3;
3420 
3421  }
3422  ;
3423 
3424 bv_decls : bvar
3425 /*
3426 */
3427  {
3428  $$ = rb_ary_new3(1, $1);
3429  }
3430 
3431  | bv_decls ',' bvar
3432 /*
3433 */
3434  {
3435  rb_ary_push($1, $3);
3436  }
3437 
3438  ;
3439 
3440 bvar : tIDENTIFIER
3441  {
3442  new_bv(get_id($1));
3443 #if 0
3444 #endif
3445  $$ = get_value($1);
3446 
3447  }
3448  | f_bad_arg
3449  {
3450  $$ = 0;
3451  }
3452  ;
3453 
3454 lambda : {
3455  $<vars>$ = dyna_push();
3456  }
3457  {
3458  $<num>$ = lpar_beg;
3459  lpar_beg = ++paren_nest;
3460  }
3461  f_larglist
3462  lambda_body
3463  {
3464  lpar_beg = $<num>2;
3465 #if 0
3466  $$ = NEW_LAMBDA($3, $4);
3467 #endif
3468  $$ = dispatch2(lambda, $3, $4);
3469 
3470  dyna_pop($<vars>1);
3471  }
3472  ;
3473 
3474 f_larglist : '(' f_args opt_bv_decl ')'
3475  {
3476 #if 0
3477  $$ = $2;
3478 #endif
3479  $$ = dispatch1(paren, $2);
3480 
3481  }
3482  | f_args
3483  {
3484 #if 0
3485  $$ = $1;
3486 #endif
3487  $$ = $1;
3488 
3489  }
3490  ;
3491 
3492 lambda_body : tLAMBEG compstmt '}'
3493  {
3494  $$ = $2;
3495  }
3497  {
3498  $$ = $2;
3499  }
3500  ;
3501 
3502 do_block : keyword_do_block
3503  {
3504  $<vars>1 = dyna_push();
3505 #if 0
3506  $<num>$ = ruby_sourceline;
3507 #endif
3508  }
3509  opt_block_param
3510  compstmt
3511  keyword_end
3512  {
3513 #if 0
3514  $$ = NEW_ITER($3,$4);
3515  nd_set_line($$, $<num>2);
3516 #endif
3517  $$ = dispatch2(do_block, escape_Qundef($3), $4);
3518 
3519  dyna_pop($<vars>1);
3520  }
3521  ;
3522 
3523 block_call : command do_block
3524  {
3525 #if 0
3526  if (nd_type($1) == NODE_YIELD) {
3527  compile_error(PARSER_ARG "block given to yield");
3528  }
3529  else {
3530  block_dup_check($1->nd_args, $2);
3531  }
3532  $2->nd_iter = $1;
3533  $$ = $2;
3534  fixpos($$, $1);
3535 #endif
3536  $$ = method_add_block($1, $2);
3537 
3538  }
3539  | block_call dot_or_colon operation2 opt_paren_args
3540  {
3541 #if 0
3542  $$ = NEW_CALL($1, $3, $4);
3543 #endif
3544  $$ = dispatch3(call, $1, $2, $3);
3545  $$ = method_optarg($$, $4);
3546 
3547  }
3548  | block_call dot_or_colon operation2 opt_paren_args brace_block
3549  {
3550 #if 0
3551  block_dup_check($4, $5);
3552  $5->nd_iter = NEW_CALL($1, $3, $4);
3553  $$ = $5;
3554  fixpos($$, $1);
3555 #endif
3556  $$ = dispatch4(command_call, $1, $2, $3, $4);
3557  $$ = method_add_block($$, $5);
3558 
3559  }
3560  | block_call dot_or_colon operation2 command_args do_block
3561  {
3562 #if 0
3563  block_dup_check($4, $5);
3564  $5->nd_iter = NEW_CALL($1, $3, $4);
3565  $$ = $5;
3566  fixpos($$, $1);
3567 #endif
3568  $$ = dispatch4(command_call, $1, $2, $3, $4);
3569  $$ = method_add_block($$, $5);
3570 
3571  }
3572  ;
3573 
3574 method_call : fcall paren_args
3575  {
3576 #if 0
3577  $$ = $1;
3578  $$->nd_args = $2;
3579 #endif
3580  $$ = method_arg(dispatch1(fcall, $1), $2);
3581 
3582  }
3583  | primary_value '.' operation2
3584  {
3585 #if 0
3586  $<num>$ = ruby_sourceline;
3587 #endif
3588  }
3589  opt_paren_args
3590  {
3591 #if 0
3592  $$ = NEW_CALL($1, $3, $5);
3593  nd_set_line($$, $<num>4);
3594 #endif
3595  $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3596  $$ = method_optarg($$, $5);
3597 
3598  }
3599  | primary_value tCOLON2 operation2
3600  {
3601 #if 0
3602  $<num>$ = ruby_sourceline;
3603 #endif
3604  }
3605  paren_args
3606  {
3607 #if 0
3608  $$ = NEW_CALL($1, $3, $5);
3609  nd_set_line($$, $<num>4);
3610 #endif
3611  $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3612  $$ = method_optarg($$, $5);
3613 
3614  }
3615  | primary_value tCOLON2 operation3
3616  {
3617 #if 0
3618  $$ = NEW_CALL($1, $3, 0);
3619 #endif
3620  $$ = dispatch3(call, $1, ripper_intern("::"), $3);
3621 
3622  }
3623  | primary_value '.'
3624  {
3625 #if 0
3626  $<num>$ = ruby_sourceline;
3627 #endif
3628  }
3629  paren_args
3630  {
3631 #if 0
3632  $$ = NEW_CALL($1, rb_intern("call"), $4);
3633  nd_set_line($$, $<num>3);
3634 #endif
3635  $$ = dispatch3(call, $1, ripper_id2sym('.'),
3636  ripper_intern("call"));
3637  $$ = method_optarg($$, $4);
3638 
3639  }
3640  | primary_value tCOLON2
3641  {
3642 #if 0
3643  $<num>$ = ruby_sourceline;
3644 #endif
3645  }
3646  paren_args
3647  {
3648 #if 0
3649  $$ = NEW_CALL($1, rb_intern("call"), $4);
3650  nd_set_line($$, $<num>3);
3651 #endif
3652  $$ = dispatch3(call, $1, ripper_intern("::"),
3653  ripper_intern("call"));
3654  $$ = method_optarg($$, $4);
3655 
3656  }
3657  | keyword_super paren_args
3658  {
3659 #if 0
3660  $$ = NEW_SUPER($2);
3661 #endif
3662  $$ = dispatch1(super, $2);
3663 
3664  }
3665  | keyword_super
3666  {
3667 #if 0
3668  $$ = NEW_ZSUPER();
3669 #endif
3670  $$ = dispatch0(zsuper);
3671 
3672  }
3673  | primary_value '[' opt_call_args rbracket
3674  {
3675 #if 0
3676  if ($1 && nd_type($1) == NODE_SELF)
3677  $$ = NEW_FCALL(tAREF, $3);
3678  else
3679  $$ = NEW_CALL($1, tAREF, $3);
3680  fixpos($$, $1);
3681 #endif
3682  $$ = dispatch2(aref, $1, escape_Qundef($3));
3683 
3684  }
3685  ;
3686 
3687 brace_block : '{'
3688  {
3689  $<vars>1 = dyna_push();
3690 #if 0
3691  $<num>$ = ruby_sourceline;
3692 #endif
3693 
3694  }
3695  opt_block_param
3696  compstmt '}'
3697  {
3698 #if 0
3699  $$ = NEW_ITER($3,$4);
3700  nd_set_line($$, $<num>2);
3701 #endif
3702  $$ = dispatch2(brace_block, escape_Qundef($3), $4);
3703 
3704  dyna_pop($<vars>1);
3705  }
3706  | keyword_do
3707  {
3708  $<vars>1 = dyna_push();
3709 #if 0
3710  $<num>$ = ruby_sourceline;
3711 #endif
3712 
3713  }
3714  opt_block_param
3716  {
3717 #if 0
3718  $$ = NEW_ITER($3,$4);
3719  nd_set_line($$, $<num>2);
3720 #endif
3721  $$ = dispatch2(do_block, escape_Qundef($3), $4);
3722 
3723  dyna_pop($<vars>1);
3724  }
3725  ;
3726 
3727 case_body : keyword_when args then
3728  compstmt
3729  cases
3730  {
3731 #if 0
3732  $$ = NEW_WHEN($2, $4, $5);
3733 #endif
3734  $$ = dispatch3(when, $2, $4, escape_Qundef($5));
3735 
3736  }
3737  ;
3738 
3739 cases : opt_else
3740  | case_body
3741  ;
3742 
3743 opt_rescue : keyword_rescue exc_list exc_var then
3744  compstmt
3745  opt_rescue
3746  {
3747 #if 0
3748  if ($3) {
3749  $3 = node_assign($3, NEW_ERRINFO());
3750  $5 = block_append($3, $5);
3751  }
3752  $$ = NEW_RESBODY($2, $5, $6);
3753  fixpos($$, $2?$2:$5);
3754 #endif
3755  $$ = dispatch4(rescue,
3756  escape_Qundef($2),
3757  escape_Qundef($3),
3758  escape_Qundef($5),
3759  escape_Qundef($6));
3760 
3761  }
3762  | none
3763  ;
3764 
3765 exc_list : arg_value
3766  {
3767 #if 0
3768  $$ = NEW_LIST($1);
3769 #endif
3770  $$ = rb_ary_new3(1, $1);
3771 
3772  }
3773  | mrhs
3774  {
3775 #if 0
3776  if (!($$ = splat_array($1))) $$ = $1;
3777 #endif
3778  $$ = $1;
3779 
3780  }
3781  | none
3782  ;
3783 
3784 exc_var : tASSOC lhs
3785  {
3786  $$ = $2;
3787  }
3788  | none
3789  ;
3790 
3791 opt_ensure : keyword_ensure compstmt
3792  {
3793 #if 0
3794  $$ = $2;
3795 #endif
3796  $$ = dispatch1(ensure, $2);
3797 
3798  }
3799  | none
3800  ;
3801 
3802 literal : numeric
3803  | symbol
3804  {
3805 #if 0
3806  $$ = NEW_LIT(ID2SYM($1));
3807 #endif
3808  $$ = dispatch1(symbol_literal, $1);
3809 
3810  }
3811  | dsym
3812  ;
3813 
3814 strings : string
3815  {
3816 #if 0
3817  NODE *node = $1;
3818  if (!node) {
3819  node = NEW_STR(STR_NEW0());
3820  }
3821  else {
3822  node = evstr2dstr(node);
3823  }
3824  $$ = node;
3825 #endif
3826  $$ = $1;
3827 
3828  }
3829  ;
3830 
3831 string : tCHAR
3832  | string1
3833  | string string1
3834  {
3835 #if 0
3836  $$ = literal_concat($1, $2);
3837 #endif
3838  $$ = dispatch2(string_concat, $1, $2);
3839 
3840  }
3841  ;
3842 
3843 string1 : tSTRING_BEG string_contents tSTRING_END
3844  {
3845 #if 0
3846  $$ = $2;
3847 #endif
3848  $$ = dispatch1(string_literal, $2);
3849 
3850  }
3851  ;
3852 
3853 xstring : tXSTRING_BEG xstring_contents tSTRING_END
3854  {
3855 #if 0
3856  NODE *node = $2;
3857  if (!node) {
3858  node = NEW_XSTR(STR_NEW0());
3859  }
3860  else {
3861  switch (nd_type(node)) {
3862  case NODE_STR:
3863  nd_set_type(node, NODE_XSTR);
3864  break;
3865  case NODE_DSTR:
3866  nd_set_type(node, NODE_DXSTR);
3867  break;
3868  default:
3869  node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node));
3870  break;
3871  }
3872  }
3873  $$ = node;
3874 #endif
3875  $$ = dispatch1(xstring_literal, $2);
3876 
3877  }
3878  ;
3879 
3880 regexp : tREGEXP_BEG regexp_contents tREGEXP_END
3881  {
3882 #if 0
3883  int options = $3;
3884  NODE *node = $2;
3885  NODE *list, *prev;
3886  if (!node) {
3887  node = NEW_LIT(reg_compile(STR_NEW0(), options));
3888  }
3889  else switch (nd_type(node)) {
3890  case NODE_STR:
3891  {
3892  VALUE src = node->nd_lit;
3893  nd_set_type(node, NODE_LIT);
3894  node->nd_lit = reg_compile(src, options);
3895  }
3896  break;
3897  default:
3898  node = NEW_NODE(NODE_DSTR, STR_NEW0(), 1, NEW_LIST(node));
3899  case NODE_DSTR:
3900  if (options & RE_OPTION_ONCE) {
3902  }
3903  else {
3904  nd_set_type(node, NODE_DREGX);
3905  }
3906  node->nd_cflag = options & RE_OPTION_MASK;
3907  if (!NIL_P(node->nd_lit)) reg_fragment_check(node->nd_lit, options);
3908  for (list = (prev = node)->nd_next; list; list = list->nd_next) {
3909  if (nd_type(list->nd_head) == NODE_STR) {
3910  VALUE tail = list->nd_head->nd_lit;
3911  if (reg_fragment_check(tail, options) && prev && !NIL_P(prev->nd_lit)) {
3912  VALUE lit = prev == node ? prev->nd_lit : prev->nd_head->nd_lit;
3913  if (!literal_concat0(parser, lit, tail)) {
3914  node = 0;
3915  break;
3916  }
3917  rb_str_resize(tail, 0);
3918  prev->nd_next = list->nd_next;
3919  rb_gc_force_recycle((VALUE)list->nd_head);
3920  rb_gc_force_recycle((VALUE)list);
3921  list = prev;
3922  }
3923  else {
3924  prev = list;
3925  }
3926  }
3927  else {
3928  prev = 0;
3929  }
3930  }
3931  if (!node->nd_next) {
3932  VALUE src = node->nd_lit;
3933  nd_set_type(node, NODE_LIT);
3934  node->nd_lit = reg_compile(src, options);
3935  }
3936  break;
3937  }
3938  $$ = node;
3939 #endif
3940  $$ = dispatch2(regexp_literal, $2, $3);
3941 
3942  }
3943  ;
3944 
3945 words : tWORDS_BEG ' ' tSTRING_END
3946  {
3947 #if 0
3948  $$ = NEW_ZARRAY();
3949 #endif
3950  $$ = dispatch0(words_new);
3951  $$ = dispatch1(array, $$);
3952 
3953  }
3954  | tWORDS_BEG word_list tSTRING_END
3955  {
3956 #if 0
3957  $$ = $2;
3958 #endif
3959  $$ = dispatch1(array, $2);
3960 
3961  }
3962  ;
3963 
3964 word_list : /* none */
3965  {
3966 #if 0
3967  $$ = 0;
3968 #endif
3969  $$ = dispatch0(words_new);
3970 
3971  }
3972  | word_list word ' '
3973  {
3974 #if 0
3975  $$ = list_append($1, evstr2dstr($2));
3976 #endif
3977  $$ = dispatch2(words_add, $1, $2);
3978 
3979  }
3980  ;
3981 
3982 word : string_content
3983 /*
3984 */
3985  {
3986  $$ = dispatch0(word_new);
3987  $$ = dispatch2(word_add, $$, $1);
3988  }
3989 
3990  | word string_content
3991  {
3992 #if 0
3993  $$ = literal_concat($1, $2);
3994 #endif
3995  $$ = dispatch2(word_add, $1, $2);
3996 
3997  }
3998  ;
3999 
4001  {
4002 #if 0
4003  $$ = NEW_ZARRAY();
4004 #endif
4005  $$ = dispatch0(symbols_new);
4006  $$ = dispatch1(array, $$);
4007 
4008  }
4009  | tSYMBOLS_BEG symbol_list tSTRING_END
4010  {
4011 #if 0
4012  $$ = $2;
4013 #endif
4014  $$ = dispatch1(array, $2);
4015 
4016  }
4017  ;
4018 
4019 symbol_list : /* none */
4020  {
4021 #if 0
4022  $$ = 0;
4023 #endif
4024  $$ = dispatch0(symbols_new);
4025 
4026  }
4027  | symbol_list word ' '
4028  {
4029 #if 0
4030  $2 = evstr2dstr($2);
4031  nd_set_type($2, NODE_DSYM);
4032  $$ = list_append($1, $2);
4033 #endif
4034  $$ = dispatch2(symbols_add, $1, $2);
4035 
4036  }
4037  ;
4038 
4039 qwords : tQWORDS_BEG ' ' tSTRING_END
4040  {
4041 #if 0
4042  $$ = NEW_ZARRAY();
4043 #endif
4044  $$ = dispatch0(qwords_new);
4045  $$ = dispatch1(array, $$);
4046 
4047  }
4048  | tQWORDS_BEG qword_list tSTRING_END
4049  {
4050 #if 0
4051  $$ = $2;
4052 #endif
4053  $$ = dispatch1(array, $2);
4054 
4055  }
4056  ;
4057 
4058 qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END
4059  {
4060 #if 0
4061  $$ = NEW_ZARRAY();
4062 #endif
4063  $$ = dispatch0(qsymbols_new);
4064  $$ = dispatch1(array, $$);
4065 
4066  }
4067  | tQSYMBOLS_BEG qsym_list tSTRING_END
4068  {
4069 #if 0
4070  $$ = $2;
4071 #endif
4072  $$ = dispatch1(array, $2);
4073 
4074  }
4075  ;
4076 
4077 qword_list : /* none */
4078  {
4079 #if 0
4080  $$ = 0;
4081 #endif
4082  $$ = dispatch0(qwords_new);
4083 
4084  }
4085  | qword_list tSTRING_CONTENT ' '
4086  {
4087 #if 0
4088  $$ = list_append($1, $2);
4089 #endif
4090  $$ = dispatch2(qwords_add, $1, $2);
4091 
4092  }
4093  ;
4094 
4095 qsym_list : /* none */
4096  {
4097 #if 0
4098  $$ = 0;
4099 #endif
4100  $$ = dispatch0(qsymbols_new);
4101 
4102  }
4103  | qsym_list tSTRING_CONTENT ' '
4104  {
4105 #if 0
4106  VALUE lit;
4107  lit = $2->nd_lit;
4108  $2->nd_lit = ID2SYM(rb_intern_str(lit));
4109  nd_set_type($2, NODE_LIT);
4110  $$ = list_append($1, $2);
4111 #endif
4112  $$ = dispatch2(qsymbols_add, $1, $2);
4113 
4114  }
4115  ;
4116 
4117 string_contents : /* none */
4118  {
4119 #if 0
4120  $$ = 0;
4121 #endif
4122  $$ = dispatch0(string_content);
4123 
4124  }
4125  | string_contents string_content
4126  {
4127 #if 0
4128  $$ = literal_concat($1, $2);
4129 #endif
4130  $$ = dispatch2(string_add, $1, $2);
4131 
4132  }
4133  ;
4134 
4135 xstring_contents: /* none */
4136  {
4137 #if 0
4138  $$ = 0;
4139 #endif
4140  $$ = dispatch0(xstring_new);
4141 
4142  }
4143  | xstring_contents string_content
4144  {
4145 #if 0
4146  $$ = literal_concat($1, $2);
4147 #endif
4148  $$ = dispatch2(xstring_add, $1, $2);
4149 
4150  }
4151  ;
4152 
4153 regexp_contents: /* none */
4154  {
4155 #if 0
4156  $$ = 0;
4157 #endif
4158  $$ = dispatch0(regexp_new);
4159 
4160  }
4161  | regexp_contents string_content
4162  {
4163 #if 0
4164  NODE *head = $1, *tail = $2;
4165  if (!head) {
4166  $$ = tail;
4167  }
4168  else if (!tail) {
4169  $$ = head;
4170  }
4171  else {
4172  switch (nd_type(head)) {
4173  case NODE_STR:
4174  nd_set_type(head, NODE_DSTR);
4175  break;
4176  case NODE_DSTR:
4177  break;
4178  default:
4179  head = list_append(NEW_DSTR(Qnil), head);
4180  break;
4181  }
4182  $$ = list_append(head, tail);
4183  }
4184 #endif
4185  $$ = dispatch2(regexp_add, $1, $2);
4186 
4187  }
4188  ;
4189 
4190 string_content : tSTRING_CONTENT
4191  | tSTRING_DVAR
4192  {
4193  $<node>$ = lex_strterm;
4194  lex_strterm = 0;
4195  lex_state = EXPR_BEG;
4196  }
4197  string_dvar
4198  {
4199 #if 0
4200  lex_strterm = $<node>2;
4201  $$ = NEW_EVSTR($3);
4202 #endif
4203  lex_strterm = $<node>2;
4204  $$ = dispatch1(string_dvar, $3);
4205 
4206  }
4207  | tSTRING_DBEG
4208  {
4209  $<val>1 = cond_stack;
4210  $<val>$ = cmdarg_stack;
4211  cond_stack = 0;
4212  cmdarg_stack = 0;
4213  }
4214  {
4215  $<node>$ = lex_strterm;
4216  lex_strterm = 0;
4217  lex_state = EXPR_BEG;
4218  }
4219  {
4220  $<num>$ = brace_nest;
4221  brace_nest = 0;
4222  }
4224  {
4225  cond_stack = $<val>1;
4226  cmdarg_stack = $<val>2;
4227  lex_strterm = $<node>3;
4228  brace_nest = $<num>4;
4229 #if 0
4230  if ($5) $5->flags &= ~NODE_FL_NEWLINE;
4231  $$ = new_evstr($5);
4232 #endif
4233  $$ = dispatch1(string_embexpr, $5);
4234 
4235  }
4236  ;
4237 
4238 string_dvar : tGVAR
4239  {
4240 #if 0
4241  $$ = NEW_GVAR($1);
4242 #endif
4243  $$ = dispatch1(var_ref, $1);
4244 
4245  }
4246  | tIVAR
4247  {
4248 #if 0
4249  $$ = NEW_IVAR($1);
4250 #endif
4251  $$ = dispatch1(var_ref, $1);
4252 
4253  }
4254  | tCVAR
4255  {
4256 #if 0
4257  $$ = NEW_CVAR($1);
4258 #endif
4259  $$ = dispatch1(var_ref, $1);
4260 
4261  }
4262  | backref
4263  ;
4264 
4265 symbol : tSYMBEG sym
4266  {
4267  lex_state = EXPR_END;
4268 #if 0
4269  $$ = $2;
4270 #endif
4271  $$ = dispatch1(symbol, $2);
4272 
4273  }
4274  ;
4275 
4276 sym : fname
4277  | tIVAR
4278  | tGVAR
4279  | tCVAR
4280  ;
4281 
4282 dsym : tSYMBEG xstring_contents tSTRING_END
4283  {
4284  lex_state = EXPR_END;
4285 #if 0
4286  $$ = dsym_node($2);
4287 #endif
4288  $$ = dispatch1(dyna_symbol, $2);
4289 
4290  }
4291  ;
4292 
4293 numeric : tINTEGER
4294  | tFLOAT
4295  | tUMINUS_NUM tINTEGER %prec tLOWEST
4296  {
4297 #if 0
4298  $$ = negate_lit($2);
4299 #endif
4300  $$ = dispatch2(unary, ripper_intern("-@"), $2);
4301 
4302  }
4303  | tUMINUS_NUM tFLOAT %prec tLOWEST
4304  {
4305 #if 0
4306  $$ = negate_lit($2);
4307 #endif
4308  $$ = dispatch2(unary, ripper_intern("-@"), $2);
4309 
4310  }
4311  ;
4312 
4313 user_variable : tIDENTIFIER
4314  | tIVAR
4315  | tGVAR
4316  | tCONSTANT
4317  | tCVAR
4318  ;
4319 
4327  ;
4328 
4329 var_ref : user_variable
4330  {
4331 #if 0
4332  if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
4333 #endif
4334  if (id_is_var(get_id($1))) {
4335  $$ = dispatch1(var_ref, $1);
4336  }
4337  else {
4338  $$ = dispatch1(vcall, $1);
4339  }
4340 
4341  }
4343  {
4344 #if 0
4345  if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
4346 #endif
4347  $$ = dispatch1(var_ref, $1);
4348 
4349  }
4350  ;
4351 
4352 var_lhs : user_variable
4353  {
4354  $$ = assignable($1, 0);
4355 #if 0
4356 #endif
4357  $$ = dispatch1(var_field, $$);
4358 
4359  }
4361  {
4362  $$ = assignable($1, 0);
4363 #if 0
4364 #endif
4365  $$ = dispatch1(var_field, $$);
4366 
4367  }
4368  ;
4369 
4370 backref : tNTH_REF
4371  | tBACK_REF
4372  ;
4373 
4374 superclass : term
4375  {
4376 #if 0
4377  $$ = 0;
4378 #endif
4379  $$ = Qnil;
4380 
4381  }
4382  | '<'
4383  {
4384  lex_state = EXPR_BEG;
4385  command_start = TRUE;
4386  }
4387  expr_value term
4388  {
4389  $$ = $3;
4390  }
4391  | error term
4392  {
4393 #if 0
4394  yyerrok;
4395  $$ = 0;
4396 #endif
4397  yyerrok;
4398  $$ = Qnil;
4399 
4400  }
4401  ;
4402 
4403 f_arglist : '(' f_args rparen
4404  {
4405 #if 0
4406  $$ = $2;
4407 #endif
4408  $$ = dispatch1(paren, $2);
4409 
4410  lex_state = EXPR_BEG;
4411  command_start = TRUE;
4412  }
4413  | f_args term
4414  {
4415  $$ = $1;
4416  lex_state = EXPR_BEG;
4417  command_start = TRUE;
4418  }
4419  ;
4420 
4421 args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
4422  {
4423  $$ = new_args_tail($1, $3, $4);
4424  }
4425  | f_kwarg opt_f_block_arg
4426  {
4427  $$ = new_args_tail($1, Qnone, $2);
4428  }
4429  | f_kwrest opt_f_block_arg
4430  {
4431  $$ = new_args_tail(Qnone, $1, $2);
4432  }
4433  | f_block_arg
4434  {
4435  $$ = new_args_tail(Qnone, Qnone, $1);
4436  }
4437  ;
4438 
4439 opt_args_tail : ',' args_tail
4440  {
4441  $$ = $2;
4442  }
4443  | /* none */
4444  {
4445  $$ = new_args_tail(Qnone, Qnone, Qnone);
4446  }
4447  ;
4448 
4449 f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
4450  {
4451  $$ = new_args($1, $3, $5, Qnone, $6);
4452  }
4453  | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
4454  {
4455  $$ = new_args($1, $3, $5, $7, $8);
4456  }
4457  | f_arg ',' f_optarg opt_args_tail
4458  {
4459  $$ = new_args($1, $3, Qnone, Qnone, $4);
4460  }
4461  | f_arg ',' f_optarg ',' f_arg opt_args_tail
4462  {
4463  $$ = new_args($1, $3, Qnone, $5, $6);
4464  }
4465  | f_arg ',' f_rest_arg opt_args_tail
4466  {
4467  $$ = new_args($1, Qnone, $3, Qnone, $4);
4468  }
4469  | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
4470  {
4471  $$ = new_args($1, Qnone, $3, $5, $6);
4472  }
4473  | f_arg opt_args_tail
4474  {
4475  $$ = new_args($1, Qnone, Qnone, Qnone, $2);
4476  }
4477  | f_optarg ',' f_rest_arg opt_args_tail
4478  {
4479  $$ = new_args(Qnone, $1, $3, Qnone, $4);
4480  }
4481  | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
4482  {
4483  $$ = new_args(Qnone, $1, $3, $5, $6);
4484  }
4485  | f_optarg opt_args_tail
4486  {
4487  $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
4488  }
4489  | f_optarg ',' f_arg opt_args_tail
4490  {
4491  $$ = new_args(Qnone, $1, Qnone, $3, $4);
4492  }
4493  | f_rest_arg opt_args_tail
4494  {
4495  $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
4496  }
4497  | f_rest_arg ',' f_arg opt_args_tail
4498  {
4499  $$ = new_args(Qnone, Qnone, $1, $3, $4);
4500  }
4501  | args_tail
4502  {
4503  $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
4504  }
4505  | /* none */
4506  {
4507  $$ = new_args_tail(Qnone, Qnone, Qnone);
4508  $$ = new_args(Qnone, Qnone, Qnone, Qnone, $$);
4509  }
4510  ;
4511 
4512 f_bad_arg : tCONSTANT
4513  {
4514 #if 0
4515  yyerror("formal argument cannot be a constant");
4516  $$ = 0;
4517 #endif
4518  $$ = dispatch1(param_error, $1);
4519 
4520  }
4521  | tIVAR
4522  {
4523 #if 0
4524  yyerror("formal argument cannot be an instance variable");
4525  $$ = 0;
4526 #endif
4527  $$ = dispatch1(param_error, $1);
4528 
4529  }
4530  | tGVAR
4531  {
4532 #if 0
4533  yyerror("formal argument cannot be a global variable");
4534  $$ = 0;
4535 #endif
4536  $$ = dispatch1(param_error, $1);
4537 
4538  }
4539  | tCVAR
4540  {
4541 #if 0
4542  yyerror("formal argument cannot be a class variable");
4543  $$ = 0;
4544 #endif
4545  $$ = dispatch1(param_error, $1);
4546 
4547  }
4548  ;
4549 
4550 f_norm_arg : f_bad_arg
4551  | tIDENTIFIER
4552  {
4553  formal_argument(get_id($1));
4554  $$ = $1;
4555  }
4556  ;
4557 
4558 f_arg_item : f_norm_arg
4559  {
4560  arg_var(get_id($1));
4561 #if 0
4562  $$ = NEW_ARGS_AUX($1, 1);
4563 #endif
4564  $$ = get_value($1);
4565 
4566  }
4567  | tLPAREN f_margs rparen
4568  {
4569  ID tid = internal_id();
4570  arg_var(tid);
4571 #if 0
4572  if (dyna_in_block()) {
4573  $2->nd_value = NEW_DVAR(tid);
4574  }
4575  else {
4576  $2->nd_value = NEW_LVAR(tid);
4577  }
4578  $$ = NEW_ARGS_AUX(tid, 1);
4579  $$->nd_next = $2;
4580 #endif
4581  $$ = dispatch1(mlhs_paren, $2);
4582 
4583  }
4584  ;
4585 
4586 f_arg : f_arg_item
4587 /*
4588 */
4589  {
4590  $$ = rb_ary_new3(1, $1);
4591  }
4592 
4593  | f_arg ',' f_arg_item
4594  {
4595 #if 0
4596  $$ = $1;
4597  $$->nd_plen++;
4598  $$->nd_next = block_append($$->nd_next, $3->nd_next);
4600 #endif
4601  $$ = rb_ary_push($1, $3);
4602 
4603  }
4604  ;
4605 
4606 f_kw : tLABEL arg_value
4607  {
4609  $$ = assignable($1, $2);
4610 #if 0
4611  $$ = NEW_KW_ARG(0, $$);
4612 #endif
4613  $$ = rb_assoc_new($$, $2);
4614 
4615  }
4616  ;
4617 
4618 f_block_kw : tLABEL primary_value
4619  {
4621  $$ = assignable($1, $2);
4622 #if 0
4623  $$ = NEW_KW_ARG(0, $$);
4624 #endif
4625  $$ = rb_assoc_new($$, $2);
4626 
4627  }
4628  ;
4629 
4630 f_block_kwarg : f_block_kw
4631  {
4632 #if 0
4633  $$ = $1;
4634 #endif
4635  $$ = rb_ary_new3(1, $1);
4636 
4637  }
4638  | f_block_kwarg ',' f_block_kw
4639  {
4640 #if 0
4641  NODE *kws = $1;
4642 
4643  while (kws->nd_next) {
4644  kws = kws->nd_next;
4645  }
4646  kws->nd_next = $3;
4647  $$ = $1;
4648 #endif
4649  $$ = rb_ary_push($1, $3);
4650 
4651  }
4652  ;
4653 
4654 
4655 f_kwarg : f_kw
4656  {
4657 #if 0
4658  $$ = $1;
4659 #endif
4660  $$ = rb_ary_new3(1, $1);
4661 
4662  }
4663  | f_kwarg ',' f_kw
4664  {
4665 #if 0
4666  NODE *kws = $1;
4667 
4668  while (kws->nd_next) {
4669  kws = kws->nd_next;
4670  }
4671  kws->nd_next = $3;
4672  $$ = $1;
4673 #endif
4674  $$ = rb_ary_push($1, $3);
4675 
4676  }
4677  ;
4678 
4679 kwrest_mark : tPOW
4680  | tDSTAR
4681  ;
4682 
4683 f_kwrest : kwrest_mark tIDENTIFIER
4684  {
4685  shadowing_lvar(get_id($2));
4686  $$ = $2;
4687  }
4688  | kwrest_mark
4689  {
4690  $$ = internal_id();
4691  }
4692  ;
4693 
4694 f_opt : tIDENTIFIER '=' arg_value
4695  {
4697  $$ = assignable($1, $3);
4698 #if 0
4699  $$ = NEW_OPT_ARG(0, $$);
4700 #endif
4701  $$ = rb_assoc_new($$, $3);
4702 
4703  }
4704  ;
4705 
4706 f_block_opt : tIDENTIFIER '=' primary_value
4707  {
4709  $$ = assignable($1, $3);
4710 #if 0
4711  $$ = NEW_OPT_ARG(0, $$);
4712 #endif
4713  $$ = rb_assoc_new($$, $3);
4714 
4715  }
4716  ;
4717 
4718 f_block_optarg : f_block_opt
4719  {
4720 #if 0
4721  $$ = $1;
4722 #endif
4723  $$ = rb_ary_new3(1, $1);
4724 
4725  }
4726  | f_block_optarg ',' f_block_opt
4727  {
4728 #if 0
4729  NODE *opts = $1;
4730 
4731  while (opts->nd_next) {
4732  opts = opts->nd_next;
4733  }
4734  opts->nd_next = $3;
4735  $$ = $1;
4736 #endif
4737  $$ = rb_ary_push($1, $3);
4738 
4739  }
4740  ;
4741 
4742 f_optarg : f_opt
4743  {
4744 #if 0
4745  $$ = $1;
4746 #endif
4747  $$ = rb_ary_new3(1, $1);
4748 
4749  }
4750  | f_optarg ',' f_opt
4751  {
4752 #if 0
4753  NODE *opts = $1;
4754 
4755  while (opts->nd_next) {
4756  opts = opts->nd_next;
4757  }
4758  opts->nd_next = $3;
4759  $$ = $1;
4760 #endif
4761  $$ = rb_ary_push($1, $3);
4762 
4763  }
4764  ;
4765 
4766 restarg_mark : '*'
4767  | tSTAR
4768  ;
4769 
4770 f_rest_arg : restarg_mark tIDENTIFIER
4771  {
4772 #if 0
4773  if (!is_local_id($2))
4774  yyerror("rest argument must be local variable");
4775 #endif
4777 #if 0
4778  $$ = $2;
4779 #endif
4780  $$ = dispatch1(rest_param, $2);
4781 
4782  }
4783  | restarg_mark
4784  {
4785 #if 0
4786  $$ = internal_id();
4787  arg_var($$);
4788 #endif
4789  $$ = dispatch1(rest_param, Qnil);
4790 
4791  }
4792  ;
4793 
4794 blkarg_mark : '&'
4795  | tAMPER
4796  ;
4797 
4798 f_block_arg : blkarg_mark tIDENTIFIER
4799  {
4800 #if 0
4801  if (!is_local_id($2))
4802  yyerror("block argument must be local variable");
4803  else if (!dyna_in_block() && local_id($2))
4804  yyerror("duplicated block argument name");
4805 #endif
4807 #if 0
4808  $$ = $2;
4809 #endif
4810  $$ = dispatch1(blockarg, $2);
4811 
4812  }
4813  ;
4814 
4815 opt_f_block_arg : ',' f_block_arg
4816  {
4817  $$ = $2;
4818  }
4819  | none
4820  {
4821 #if 0
4822  $$ = 0;
4823 #endif
4824  $$ = Qundef;
4825 
4826  }
4827  ;
4828 
4829 singleton : var_ref
4830  {
4831 #if 0
4832  value_expr($1);
4833  $$ = $1;
4834  if (!$$) $$ = NEW_NIL();
4835 #endif
4836  $$ = $1;
4837 
4838  }
4839  | '(' {lex_state = EXPR_BEG;} expr rparen
4840  {
4841 #if 0
4842  if ($3 == 0) {
4843  yyerror("can't define singleton method for ().");
4844  }
4845  else {
4846  switch (nd_type($3)) {
4847  case NODE_STR:
4848  case NODE_DSTR:
4849  case NODE_XSTR:
4850  case NODE_DXSTR:
4851  case NODE_DREGX:
4852  case NODE_LIT:
4853  case NODE_ARRAY:
4854  case NODE_ZARRAY:
4855  yyerror("can't define singleton method for literals");
4856  default:
4857  value_expr($3);
4858  break;
4859  }
4860  }
4861  $$ = $3;
4862 #endif
4863  $$ = dispatch1(paren, $3);
4864 
4865  }
4866  ;
4867 
4868 assoc_list : none
4869  | assocs trailer
4870  {
4871 #if 0
4872  $$ = $1;
4873 #endif
4874  $$ = dispatch1(assoclist_from_args, $1);
4875 
4876  }
4877  ;
4878 
4879 assocs : assoc
4880 /*
4881 */
4882  {
4883  $$ = rb_ary_new3(1, $1);
4884  }
4885 
4886  | assocs ',' assoc
4887  {
4888 #if 0
4889  $$ = list_concat($1, $3);
4890 #endif
4891  $$ = rb_ary_push($1, $3);
4892 
4893  }
4894  ;
4895 
4896 assoc : arg_value tASSOC arg_value
4897  {
4898 #if 0
4899  $$ = list_append(NEW_LIST($1), $3);
4900 #endif
4901  $$ = dispatch2(assoc_new, $1, $3);
4902 
4903  }
4904  | tLABEL arg_value
4905  {
4906 #if 0
4907  $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
4908 #endif
4909  $$ = dispatch2(assoc_new, $1, $2);
4910 
4911  }
4912  | tDSTAR arg_value
4913  {
4914 #if 0
4915  $$ = list_append(NEW_LIST(0), $2);
4916 #endif
4917  $$ = dispatch1(assoc_splat, $2);
4918 
4919  }
4920  ;
4921 
4922  ;
4923 
4924 operation : tIDENTIFIER
4925  | tCONSTANT
4926  | tFID
4927  ;
4928 
4929 operation2 : tIDENTIFIER
4930  | tCONSTANT
4931  | tFID
4932  | op
4933  ;
4934 
4935 operation3 : tIDENTIFIER
4936  | tFID
4937  | op
4938  ;
4939 
4940 dot_or_colon : '.'
4941 /*
4942 */
4943  { $$ = $<val>1; }
4944 
4945  | tCOLON2
4946 /*
4947 */
4948  { $$ = $<val>1; }
4949 
4950  ;
4951 
4952 opt_terms : /* none */
4953  | terms
4954  ;
4955 
4956 opt_nl : /* none */
4957  | '\n'
4958  ;
4959 
4960 rparen : opt_nl ')'
4961  ;
4962 
4963 rbracket : opt_nl ']'
4964  ;
4965 
4966 trailer : /* none */
4967  | '\n'
4968  | ','
4969  ;
4970 
4971 term : ';' {yyerrok;}
4972  | '\n'
4973  ;
4974 
4975 terms : term
4976  | terms ';' {yyerrok;}
4977  ;
4978 
4979 none : /* none */
4980  {
4981 #if 0
4982  $$ = 0;
4983 #endif
4984  $$ = Qundef;
4985 
4986  }
4987  ;
4988 %%
4989 # undef parser
4990 # undef yylex
4991 # undef yylval
4992 # define yylval (*((YYSTYPE*)(parser->parser_yylval)))
4993 
4994 static int parser_regx_options(struct parser_params*);
4995 static int parser_tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**);
4996 static void parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc);
4997 static int parser_parse_string(struct parser_params*,NODE*);
4998 static int parser_here_document(struct parser_params*,NODE*);
4999 
5000 
5001 # define nextc() parser_nextc(parser)
5002 # define pushback(c) parser_pushback(parser, (c))
5003 # define newtok() parser_newtok(parser)
5004 # define tokspace(n) parser_tokspace(parser, (n))
5005 # define tokadd(c) parser_tokadd(parser, (c))
5006 # define tok_hex(numlen) parser_tok_hex(parser, (numlen))
5007 # define read_escape(flags,e) parser_read_escape(parser, (flags), (e))
5008 # define tokadd_escape(e) parser_tokadd_escape(parser, (e))
5009 # define regx_options() parser_regx_options(parser)
5010 # define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser,(f),(t),(p),(n),(e))
5011 # define parse_string(n) parser_parse_string(parser,(n))
5012 # define tokaddmbc(c, enc) parser_tokaddmbc(parser, (c), (enc))
5013 # define here_document(n) parser_here_document(parser,(n))
5014 # define heredoc_identifier() parser_heredoc_identifier(parser)
5015 # define heredoc_restore(n) parser_heredoc_restore(parser,(n))
5016 # define whole_match_p(e,l,i) parser_whole_match_p(parser,(e),(l),(i))
5017 
5018 #ifndef RIPPER
5019 # define set_yylval_str(x) (yylval.node = NEW_STR(x))
5020 # define set_yylval_num(x) (yylval.num = (x))
5021 # define set_yylval_id(x) (yylval.id = (x))
5022 # define set_yylval_name(x) (yylval.id = (x))
5023 # define set_yylval_literal(x) (yylval.node = NEW_LIT(x))
5024 # define set_yylval_node(x) (yylval.node = (x))
5025 # define yylval_id() (yylval.id)
5026 #else
5027 static inline VALUE
5028 ripper_yylval_id(ID x)
5029 {
5030  return (VALUE)NEW_LASGN(x, ID2SYM(x));
5031 }
5032 # define set_yylval_str(x) (void)(x)
5033 # define set_yylval_num(x) (void)(x)
5034 # define set_yylval_id(x) (void)(x)
5035 # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x))
5036 # define set_yylval_literal(x) (void)(x)
5037 # define set_yylval_node(x) (void)(x)
5038 # define yylval_id() yylval.id
5039 #endif
5040 
5041 #ifndef RIPPER
5042 #define ripper_flush(p) (void)(p)
5043 #else
5044 #define ripper_flush(p) ((p)->tokp = (p)->parser_lex_p)
5045 
5046 #define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
5047 
5048 static int
5049 ripper_has_scan_event(struct parser_params *parser)
5050 {
5051 
5052  if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp");
5053  return lex_p > parser->tokp;
5054 }
5055 
5056 static VALUE
5057 ripper_scan_event_val(struct parser_params *parser, int t)
5058 {
5059  VALUE str = STR_NEW(parser->tokp, lex_p - parser->tokp);
5060  VALUE rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
5061  ripper_flush(parser);
5062  return rval;
5063 }
5064 
5065 static void
5066 ripper_dispatch_scan_event(struct parser_params *parser, int t)
5067 {
5068  if (!ripper_has_scan_event(parser)) return;
5069  yylval_rval = ripper_scan_event_val(parser, t);
5070 }
5071 
5072 static void
5073 ripper_dispatch_ignored_scan_event(struct parser_params *parser, int t)
5074 {
5075  if (!ripper_has_scan_event(parser)) return;
5076  (void)ripper_scan_event_val(parser, t);
5077 }
5078 
5079 static void
5080 ripper_dispatch_delayed_token(struct parser_params *parser, int t)
5081 {
5082  int saved_line = ruby_sourceline;
5083  const char *saved_tokp = parser->tokp;
5084 
5085  ruby_sourceline = parser->delayed_line;
5086  parser->tokp = lex_pbeg + parser->delayed_col;
5087  yylval_rval = ripper_dispatch1(parser, ripper_token2eventid(t), parser->delayed);
5088  parser->delayed = Qnil;
5089  ruby_sourceline = saved_line;
5090  parser->tokp = saved_tokp;
5091 }
5092 #endif /* RIPPER */
5093 
5094 #include "ruby/regex.h"
5095 #include "ruby/util.h"
5096 
5097 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
5098  since ours (we hope) works properly with all combinations of
5099  machines, compilers, `char' and `unsigned char' argument types.
5100  (Per Bothner suggested the basic approach.) */
5101 #undef SIGN_EXTEND_CHAR
5102 #if __STDC__
5103 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
5104 #else /* not __STDC__ */
5105 /* As in Harbison and Steele. */
5106 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
5107 #endif
5108 
5109 #define parser_encoding_name() (current_enc->name)
5110 #define parser_mbclen() mbclen((lex_p-1),lex_pend,current_enc)
5111 #define parser_precise_mbclen() rb_enc_precise_mbclen((lex_p-1),lex_pend,current_enc)
5112 #define is_identchar(p,e,enc) (rb_enc_isalnum(*(p),(enc)) || (*(p)) == '_' || !ISASCII(*(p)))
5113 #define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,current_enc))
5114 
5115 #define parser_isascii() ISASCII(*(lex_p-1))
5116 
5117 #ifndef RIPPER
5118 static int
5119 token_info_get_column(struct parser_params *parser, const char *token)
5120 {
5121  int column = 1;
5122  const char *p, *pend = lex_p - strlen(token);
5123  for (p = lex_pbeg; p < pend; p++) {
5124  if (*p == '\t') {
5125  column = (((column - 1) / 8) + 1) * 8;
5126  }
5127  column++;
5128  }
5129  return column;
5130 }
5131 
5132 static int
5133 token_info_has_nonspaces(struct parser_params *parser, const char *token)
5134 {
5135  const char *p, *pend = lex_p - strlen(token);
5136  for (p = lex_pbeg; p < pend; p++) {
5137  if (*p != ' ' && *p != '\t') {
5138  return 1;
5139  }
5140  }
5141  return 0;
5142 }
5143 
5144 #undef token_info_push
5145 static void
5146 token_info_push(struct parser_params *parser, const char *token)
5147 {
5148  token_info *ptinfo;
5149 
5150  if (!parser->parser_token_info_enabled) return;
5151  ptinfo = ALLOC(token_info);
5152  ptinfo->token = token;
5153  ptinfo->linenum = ruby_sourceline;
5154  ptinfo->column = token_info_get_column(parser, token);
5155  ptinfo->nonspc = token_info_has_nonspaces(parser, token);
5156  ptinfo->next = parser->parser_token_info;
5157 
5158  parser->parser_token_info = ptinfo;
5159 }
5160 
5161 #undef token_info_pop
5162 static void
5163 token_info_pop(struct parser_params *parser, const char *token)
5164 {
5165  int linenum;
5166  token_info *ptinfo = parser->parser_token_info;
5167 
5168  if (!ptinfo) return;
5169  parser->parser_token_info = ptinfo->next;
5170  if (token_info_get_column(parser, token) == ptinfo->column) { /* OK */
5171  goto finish;
5172  }
5173  linenum = ruby_sourceline;
5174  if (linenum == ptinfo->linenum) { /* SKIP */
5175  goto finish;
5176  }
5177  if (token_info_has_nonspaces(parser, token) || ptinfo->nonspc) { /* SKIP */
5178  goto finish;
5179  }
5180  if (parser->parser_token_info_enabled) {
5182  "mismatched indentations at '%s' with '%s' at %d",
5183  token, ptinfo->token, ptinfo->linenum);
5184  }
5185 
5186  finish:
5187  xfree(ptinfo);
5188 }
5189 #endif /* RIPPER */
5190 
5191 static int
5192 parser_yyerror(struct parser_params *parser, const char *msg)
5193 {
5194 #ifndef RIPPER
5195  const int max_line_margin = 30;
5196  const char *p, *pe;
5197  char *buf;
5198  long len;
5199  int i;
5200 
5201  compile_error(PARSER_ARG "%s", msg);
5202  p = lex_p;
5203  while (lex_pbeg <= p) {
5204  if (*p == '\n') break;
5205  p--;
5206  }
5207  p++;
5208 
5209  pe = lex_p;
5210  while (pe < lex_pend) {
5211  if (*pe == '\n') break;
5212  pe++;
5213  }
5214 
5215  len = pe - p;
5216  if (len > 4) {
5217  char *p2;
5218  const char *pre = "", *post = "";
5219 
5220  if (len > max_line_margin * 2 + 10) {
5221  if (lex_p - p > max_line_margin) {
5222  p = rb_enc_prev_char(p, lex_p - max_line_margin, pe, rb_enc_get(lex_lastline));
5223  pre = "...";
5224  }
5225  if (pe - lex_p > max_line_margin) {
5226  pe = rb_enc_prev_char(lex_p, lex_p + max_line_margin, pe, rb_enc_get(lex_lastline));
5227  post = "...";
5228  }
5229  len = pe - p;
5230  }
5231  buf = ALLOCA_N(char, len+2);
5232  MEMCPY(buf, p, char, len);
5233  buf[len] = '\0';
5234  rb_compile_error_append("%s%s%s", pre, buf, post);
5235 
5236  i = (int)(lex_p - p);
5237  p2 = buf; pe = buf + len;
5238 
5239  while (p2 < pe) {
5240  if (*p2 != '\t') *p2 = ' ';
5241  p2++;
5242  }
5243  buf[i] = '^';
5244  buf[i+1] = '\0';
5245  rb_compile_error_append("%s%s", pre, buf);
5246  }
5247 #else
5248  dispatch1(parse_error, STR_NEW2(msg));
5249 #endif /* !RIPPER */
5250  return 0;
5251 }
5252 
5253 static void parser_prepare(struct parser_params *parser);
5254 
5255 #ifndef RIPPER
5256 static VALUE
5257 debug_lines(const char *f)
5258 {
5259  ID script_lines;
5260  CONST_ID(script_lines, "SCRIPT_LINES__");
5261  if (rb_const_defined_at(rb_cObject, script_lines)) {
5262  VALUE hash = rb_const_get_at(rb_cObject, script_lines);
5263  if (RB_TYPE_P(hash, T_HASH)) {
5265  VALUE lines = rb_ary_new();
5266  rb_hash_aset(hash, fname, lines);
5267  return lines;
5268  }
5269  }
5270  return 0;
5271 }
5272 
5273 static VALUE
5274 coverage(const char *f, int n)
5275 {
5276  VALUE coverages = rb_get_coverages();
5277  if (RTEST(coverages) && RBASIC(coverages)->klass == 0) {
5279  VALUE lines = rb_ary_new2(n);
5280  int i;
5281  RBASIC(lines)->klass = 0;
5282  for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
5283  RARRAY(lines)->as.heap.len = n;
5284  rb_hash_aset(coverages, fname, lines);
5285  return lines;
5286  }
5287  return 0;
5288 }
5289 
5290 static int
5291 e_option_supplied(struct parser_params *parser)
5292 {
5293  return strcmp(ruby_sourcefile, "-e") == 0;
5294 }
5295 
5296 static VALUE
5298 {
5299  int n;
5300  NODE *tree;
5301  struct parser_params *parser = (struct parser_params *)arg;
5302 
5303  if (!compile_for_eval && rb_safe_level() == 0) {
5305  if (ruby_debug_lines && ruby_sourceline > 0) {
5306  VALUE str = STR_NEW0();
5307  n = ruby_sourceline;
5308  do {
5310  } while (--n);
5311  }
5312 
5313  if (!e_option_supplied(parser)) {
5315  }
5316  }
5317 
5318  parser_prepare(parser);
5319  deferred_nodes = 0;
5320 #ifndef RIPPER
5322 #endif
5323 #ifndef RIPPER
5326  parser->parser_ruby_sourceline);
5327  }
5328 #endif
5329  n = yyparse((void*)parser);
5330 #ifndef RIPPER
5333  parser->parser_ruby_sourceline);
5334  }
5335 #endif
5336  ruby_debug_lines = 0;
5337  ruby_coverage = 0;
5338  compile_for_eval = 0;
5339 
5340  lex_strterm = 0;
5341  lex_p = lex_pbeg = lex_pend = 0;
5342  lex_lastline = lex_nextline = 0;
5343  if (parser->nerr) {
5344  return 0;
5345  }
5346  tree = ruby_eval_tree;
5347  if (!tree) {
5348  tree = NEW_NIL();
5349  }
5350  else if (ruby_eval_tree_begin) {
5351  tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body);
5352  }
5353  return (VALUE)tree;
5354 }
5355 
5356 static NODE*
5357 yycompile(struct parser_params *parser, const char *f, int line)
5358 {
5360  ruby_sourceline = line - 1;
5361  return (NODE *)rb_suppress_tracing(yycompile0, (VALUE)parser);
5362 }
5363 #endif /* !RIPPER */
5364 
5365 static rb_encoding *
5367 {
5368  rb_encoding *enc = rb_enc_get(s);
5369  if (!rb_enc_asciicompat(enc)) {
5370  rb_raise(rb_eArgError, "invalid source encoding");
5371  }
5372  return enc;
5373 }
5374 
5375 static VALUE
5376 lex_get_str(struct parser_params *parser, VALUE s)
5377 {
5378  char *beg, *end, *pend;
5380 
5381  beg = RSTRING_PTR(s);
5382  if (lex_gets_ptr) {
5383  if (RSTRING_LEN(s) == lex_gets_ptr) return Qnil;
5384  beg += lex_gets_ptr;
5385  }
5386  pend = RSTRING_PTR(s) + RSTRING_LEN(s);
5387  end = beg;
5388  while (end < pend) {
5389  if (*end++ == '\n') break;
5390  }
5391  lex_gets_ptr = end - RSTRING_PTR(s);
5392  return rb_enc_str_new(beg, end - beg, enc);
5393 }
5394 
5395 static VALUE
5396 lex_getline(struct parser_params *parser)
5397 {
5398  VALUE line = (*parser->parser_lex_gets)(parser, parser->parser_lex_input);
5399  if (NIL_P(line)) return line;
5401 #ifndef RIPPER
5402  if (ruby_debug_lines) {
5405  }
5406  if (ruby_coverage) {
5408  }
5409 #endif
5410  return line;
5411 }
5412 
5413 #ifdef RIPPER
5415 #else
5416 static const rb_data_type_t parser_data_type;
5417 
5418 static NODE*
5419 parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
5420 {
5421  struct parser_params *parser;
5422  NODE *node;
5423 
5424  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
5426  lex_gets_ptr = 0;
5427  lex_input = s;
5428  lex_pbeg = lex_p = lex_pend = 0;
5430 
5431  node = yycompile(parser, f, line);
5432  RB_GC_GUARD(vparser); /* prohibit tail call optimization */
5433 
5434  return node;
5435 }
5436 
5437 NODE*
5438 rb_compile_string(const char *f, VALUE s, int line)
5439 {
5441  return parser_compile_string(rb_parser_new(), f, s, line);
5442 }
5443 
5444 NODE*
5445 rb_parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
5446 {
5448  return parser_compile_string(vparser, f, s, line);
5449 }
5450 
5451 NODE*
5452 rb_compile_cstr(const char *f, const char *s, int len, int line)
5453 {
5454  VALUE str = rb_str_new(s, len);
5455  return parser_compile_string(rb_parser_new(), f, str, line);
5456 }
5457 
5458 NODE*
5459 rb_parser_compile_cstr(volatile VALUE vparser, const char *f, const char *s, int len, int line)
5460 {
5461  VALUE str = rb_str_new(s, len);
5462  return parser_compile_string(vparser, f, str, line);
5463 }
5464 
5465 static VALUE
5466 lex_io_gets(struct parser_params *parser, VALUE io)
5467 {
5468  return rb_io_gets(io);
5469 }
5470 
5471 NODE*
5472 rb_compile_file(const char *f, VALUE file, int start)
5473 {
5474  VALUE volatile vparser = rb_parser_new();
5475 
5476  return rb_parser_compile_file(vparser, f, file, start);
5477 }
5478 
5479 NODE*
5480 rb_parser_compile_file(volatile VALUE vparser, const char *f, VALUE file, int start)
5481 {
5482  struct parser_params *parser;
5483  NODE *node;
5484 
5485  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
5487  lex_input = file;
5488  lex_pbeg = lex_p = lex_pend = 0;
5490 
5491  node = yycompile(parser, f, start);
5492  RB_GC_GUARD(vparser); /* prohibit tail call optimization */
5493 
5494  return node;
5495 }
5496 #endif /* !RIPPER */
5497 
5498 #define STR_FUNC_ESCAPE 0x01
5499 #define STR_FUNC_EXPAND 0x02
5500 #define STR_FUNC_REGEXP 0x04
5501 #define STR_FUNC_QWORDS 0x08
5502 #define STR_FUNC_SYMBOL 0x10
5503 #define STR_FUNC_INDENT 0x20
5504 
5505 enum string_type {
5506  str_squote = (0),
5514 };
5515 
5516 static VALUE
5517 parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *enc0)
5518 {
5519  VALUE str;
5520 
5521  str = rb_enc_str_new(p, n, enc);
5522  if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
5524  }
5525  else if (enc0 == rb_usascii_encoding() && enc != rb_utf8_encoding()) {
5527  }
5528  }
5529 
5530  return str;
5531 }
5532 
5533 #define lex_goto_eol(parser) ((parser)->parser_lex_p = (parser)->parser_lex_pend)
5534 #define lex_eol_p() (lex_p >= lex_pend)
5535 #define peek(c) peek_n((c), 0)
5536 #define peek_n(c,n) (lex_p+(n) < lex_pend && (c) == (unsigned char)lex_p[n])
5537 
5538 static inline int
5539 parser_nextc(struct parser_params *parser)
5540 {
5541  int c;
5542 
5543  if (lex_p == lex_pend) {
5544  VALUE v = lex_nextline;
5545  lex_nextline = 0;
5546  if (!v) {
5547  if (parser->eofp)
5548  return -1;
5549 
5550  if (!lex_input || NIL_P(v = lex_getline(parser))) {
5551  parser->eofp = Qtrue;
5552  lex_goto_eol(parser);
5553  return -1;
5554  }
5555  }
5556  {
5557 #ifdef RIPPER
5558  if (parser->tokp < lex_pend) {
5559  if (NIL_P(parser->delayed)) {
5560  parser->delayed = rb_str_buf_new(1024);
5561  rb_enc_associate(parser->delayed, current_enc);
5562  rb_str_buf_cat(parser->delayed,
5563  parser->tokp, lex_pend - parser->tokp);
5564  parser->delayed_line = ruby_sourceline;
5565  parser->delayed_col = (int)(parser->tokp - lex_pbeg);
5566  }
5567  else {
5568  rb_str_buf_cat(parser->delayed,
5569  parser->tokp, lex_pend - parser->tokp);
5570  }
5571  }
5572 #endif
5573  if (heredoc_end > 0) {
5575  heredoc_end = 0;
5576  }
5577  ruby_sourceline++;
5578  parser->line_count++;
5579  lex_pbeg = lex_p = RSTRING_PTR(v);
5580  lex_pend = lex_p + RSTRING_LEN(v);
5581  ripper_flush(parser);
5582  lex_lastline = v;
5583  }
5584  }
5585  c = (unsigned char)*lex_p++;
5586  if (c == '\r' && peek('\n')) {
5587  lex_p++;
5588  c = '\n';
5589  }
5590 
5591  return c;
5592 }
5593 
5594 static void
5595 parser_pushback(struct parser_params *parser, int c)
5596 {
5597  if (c == -1) return;
5598  lex_p--;
5599  if (lex_p > lex_pbeg && lex_p[0] == '\n' && lex_p[-1] == '\r') {
5600  lex_p--;
5601  }
5602 }
5603 
5604 #define was_bol() (lex_p == lex_pbeg + 1)
5605 
5606 #define tokfix() (tokenbuf[tokidx]='\0')
5607 #define tok() tokenbuf
5608 #define toklen() tokidx
5609 #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
5610 
5611 static char*
5612 parser_newtok(struct parser_params *parser)
5613 {
5614  tokidx = 0;
5616  if (!tokenbuf) {
5617  toksiz = 60;
5618  tokenbuf = ALLOC_N(char, 60);
5619  }
5620  if (toksiz > 4096) {
5621  toksiz = 60;
5622  REALLOC_N(tokenbuf, char, 60);
5623  }
5624  return tokenbuf;
5625 }
5626 
5627 static char *
5628 parser_tokspace(struct parser_params *parser, int n)
5629 {
5630  tokidx += n;
5631 
5632  if (tokidx >= toksiz) {
5633  do {toksiz *= 2;} while (toksiz < tokidx);
5634  REALLOC_N(tokenbuf, char, toksiz);
5635  }
5636  return &tokenbuf[tokidx-n];
5637 }
5638 
5639 static void
5640 parser_tokadd(struct parser_params *parser, int c)
5641 {
5642  tokenbuf[tokidx++] = (char)c;
5643  if (tokidx >= toksiz) {
5644  toksiz *= 2;
5645  REALLOC_N(tokenbuf, char, toksiz);
5646  }
5647 }
5648 
5649 static int
5650 parser_tok_hex(struct parser_params *parser, size_t *numlen)
5651 {
5652  int c;
5653 
5654  c = scan_hex(lex_p, 2, numlen);
5655  if (!*numlen) {
5656  yyerror("invalid hex escape");
5657  return 0;
5658  }
5659  lex_p += *numlen;
5660  return c;
5661 }
5662 
5663 #define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
5664 
5665 /* return value is for ?\u3042 */
5666 static int
5668  int string_literal, int symbol_literal, int regexp_literal)
5669 {
5670  /*
5671  * If string_literal is true, then we allow multiple codepoints
5672  * in \u{}, and add the codepoints to the current token.
5673  * Otherwise we're parsing a character literal and return a single
5674  * codepoint without adding it
5675  */
5676 
5677  int codepoint;
5678  size_t numlen;
5679 
5680  if (regexp_literal) { tokadd('\\'); tokadd('u'); }
5681 
5682  if (peek('{')) { /* handle \u{...} form */
5683  do {
5684  if (regexp_literal) { tokadd(*lex_p); }
5685  nextc();
5686  codepoint = scan_hex(lex_p, 6, &numlen);
5687  if (numlen == 0) {
5688  yyerror("invalid Unicode escape");
5689  return 0;
5690  }
5691  if (codepoint > 0x10ffff) {
5692  yyerror("invalid Unicode codepoint (too large)");
5693  return 0;
5694  }
5695  lex_p += numlen;
5696  if (regexp_literal) {
5697  tokcopy((int)numlen);
5698  }
5699  else if (codepoint >= 0x80) {
5700  *encp = rb_utf8_encoding();
5701  if (string_literal) tokaddmbc(codepoint, *encp);
5702  }
5703  else if (string_literal) {
5704  tokadd(codepoint);
5705  }
5706  } while (string_literal && (peek(' ') || peek('\t')));
5707 
5708  if (!peek('}')) {
5709  yyerror("unterminated Unicode escape");
5710  return 0;
5711  }
5712 
5713  if (regexp_literal) { tokadd('}'); }
5714  nextc();
5715  }
5716  else { /* handle \uxxxx form */
5717  codepoint = scan_hex(lex_p, 4, &numlen);
5718  if (numlen < 4) {
5719  yyerror("invalid Unicode escape");
5720  return 0;
5721  }
5722  lex_p += 4;
5723  if (regexp_literal) {
5724  tokcopy(4);
5725  }
5726  else if (codepoint >= 0x80) {
5727  *encp = rb_utf8_encoding();
5728  if (string_literal) tokaddmbc(codepoint, *encp);
5729  }
5730  else if (string_literal) {
5731  tokadd(codepoint);
5732  }
5733  }
5734 
5735  return codepoint;
5736 }
5737 
5738 #define ESCAPE_CONTROL 1
5739 #define ESCAPE_META 2
5740 
5741 static int
5742 parser_read_escape(struct parser_params *parser, int flags,
5743  rb_encoding **encp)
5744 {
5745  int c;
5746  size_t numlen;
5747 
5748  switch (c = nextc()) {
5749  case '\\': /* Backslash */
5750  return c;
5751 
5752  case 'n': /* newline */
5753  return '\n';
5754 
5755  case 't': /* horizontal tab */
5756  return '\t';
5757 
5758  case 'r': /* carriage-return */
5759  return '\r';
5760 
5761  case 'f': /* form-feed */
5762  return '\f';
5763 
5764  case 'v': /* vertical tab */
5765  return '\13';
5766 
5767  case 'a': /* alarm(bell) */
5768  return '\007';
5769 
5770  case 'e': /* escape */
5771  return 033;
5772 
5773  case '0': case '1': case '2': case '3': /* octal constant */
5774  case '4': case '5': case '6': case '7':
5775  pushback(c);
5776  c = scan_oct(lex_p, 3, &numlen);
5777  lex_p += numlen;
5778  return c;
5779 
5780  case 'x': /* hex constant */
5781  c = tok_hex(&numlen);
5782  if (numlen == 0) return 0;
5783  return c;
5784 
5785  case 'b': /* backspace */
5786  return '\010';
5787 
5788  case 's': /* space */
5789  return ' ';
5790 
5791  case 'M':
5792  if (flags & ESCAPE_META) goto eof;
5793  if ((c = nextc()) != '-') {
5794  pushback(c);
5795  goto eof;
5796  }
5797  if ((c = nextc()) == '\\') {
5798  if (peek('u')) goto eof;
5799  return read_escape(flags|ESCAPE_META, encp) | 0x80;
5800  }
5801  else if (c == -1 || !ISASCII(c)) goto eof;
5802  else {
5803  return ((c & 0xff) | 0x80);
5804  }
5805 
5806  case 'C':
5807  if ((c = nextc()) != '-') {
5808  pushback(c);
5809  goto eof;
5810  }
5811  case 'c':
5812  if (flags & ESCAPE_CONTROL) goto eof;
5813  if ((c = nextc())== '\\') {
5814  if (peek('u')) goto eof;
5815  c = read_escape(flags|ESCAPE_CONTROL, encp);
5816  }
5817  else if (c == '?')
5818  return 0177;
5819  else if (c == -1 || !ISASCII(c)) goto eof;
5820  return c & 0x9f;
5821 
5822  eof:
5823  case -1:
5824  yyerror("Invalid escape character syntax");
5825  return '\0';
5826 
5827  default:
5828  return c;
5829  }
5830 }
5831 
5832 static void
5833 parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc)
5834 {
5835  int len = rb_enc_codelen(c, enc);
5836  rb_enc_mbcput(c, tokspace(len), enc);
5837 }
5838 
5839 static int
5840 parser_tokadd_escape(struct parser_params *parser, rb_encoding **encp)
5841 {
5842  int c;
5843  int flags = 0;
5844  size_t numlen;
5845 
5846  first:
5847  switch (c = nextc()) {
5848  case '\n':
5849  return 0; /* just ignore */
5850 
5851  case '0': case '1': case '2': case '3': /* octal constant */
5852  case '4': case '5': case '6': case '7':
5853  {
5854  ruby_scan_oct(--lex_p, 3, &numlen);
5855  if (numlen == 0) goto eof;
5856  lex_p += numlen;
5857  tokcopy((int)numlen + 1);
5858  }
5859  return 0;
5860 
5861  case 'x': /* hex constant */
5862  {
5863  tok_hex(&numlen);
5864  if (numlen == 0) return -1;
5865  tokcopy((int)numlen + 2);
5866  }
5867  return 0;
5868 
5869  case 'M':
5870  if (flags & ESCAPE_META) goto eof;
5871  if ((c = nextc()) != '-') {
5872  pushback(c);
5873  goto eof;
5874  }
5875  tokcopy(3);
5876  flags |= ESCAPE_META;
5877  goto escaped;
5878 
5879  case 'C':
5880  if (flags & ESCAPE_CONTROL) goto eof;
5881  if ((c = nextc()) != '-') {
5882  pushback(c);
5883  goto eof;
5884  }
5885  tokcopy(3);
5886  goto escaped;
5887 
5888  case 'c':
5889  if (flags & ESCAPE_CONTROL) goto eof;
5890  tokcopy(2);
5891  flags |= ESCAPE_CONTROL;
5892  escaped:
5893  if ((c = nextc()) == '\\') {
5894  goto first;
5895  }
5896  else if (c == -1) goto eof;
5897  tokadd(c);
5898  return 0;
5899 
5900  eof:
5901  case -1:
5902  yyerror("Invalid escape character syntax");
5903  return -1;
5904 
5905  default:
5906  tokadd('\\');
5907  tokadd(c);
5908  }
5909  return 0;
5910 }
5911 
5912 static int
5913 parser_regx_options(struct parser_params *parser)
5914 {
5915  int kcode = 0;
5916  int kopt = 0;
5917  int options = 0;
5918  int c, opt, kc;
5919 
5920  newtok();
5921  while (c = nextc(), ISALPHA(c)) {
5922  if (c == 'o') {
5923  options |= RE_OPTION_ONCE;
5924  }
5925  else if (rb_char_to_option_kcode(c, &opt, &kc)) {
5926  if (kc >= 0) {
5927  if (kc != rb_ascii8bit_encindex()) kcode = c;
5928  kopt = opt;
5929  }
5930  else {
5931  options |= opt;
5932  }
5933  }
5934  else {
5935  tokadd(c);
5936  }
5937  }
5938  options |= kopt;
5939  pushback(c);
5940  if (toklen()) {
5941  tokfix();
5942  compile_error(PARSER_ARG "unknown regexp option%s - %s",
5943  toklen() > 1 ? "s" : "", tok());
5944  }
5945  return options | RE_OPTION_ENCODING(kcode);
5946 }
5947 
5948 static void
5949 dispose_string(VALUE str)
5950 {
5951  rb_str_free(str);
5952  rb_gc_force_recycle(str);
5953 }
5954 
5955 static int
5956 parser_tokadd_mbchar(struct parser_params *parser, int c)
5957 {
5958  int len = parser_precise_mbclen();
5959  if (!MBCLEN_CHARFOUND_P(len)) {
5960  compile_error(PARSER_ARG "invalid multibyte char (%s)", parser_encoding_name());
5961  return -1;
5962  }
5963  tokadd(c);
5964  lex_p += --len;
5965  if (len > 0) tokcopy(len);
5966  return c;
5967 }
5968 
5969 #define tokadd_mbchar(c) parser_tokadd_mbchar(parser, (c))
5970 
5971 static inline int
5972 simple_re_meta(int c)
5973 {
5974  switch (c) {
5975  case '$': case '*': case '+': case '.':
5976  case '?': case '^': case '|':
5977  case ')': case ']': case '}': case '>':
5978  return TRUE;
5979  default:
5980  return FALSE;
5981  }
5982 }
5983 
5984 static int
5985 parser_tokadd_string(struct parser_params *parser,
5986  int func, int term, int paren, long *nest,
5987  rb_encoding **encp)
5988 {
5989  int c;
5990  int has_nonascii = 0;
5991  rb_encoding *enc = *encp;
5992  char *errbuf = 0;
5993  static const char mixed_msg[] = "%s mixed within %s source";
5994 
5995 #define mixed_error(enc1, enc2) if (!errbuf) { \
5996  size_t len = sizeof(mixed_msg) - 4; \
5997  len += strlen(rb_enc_name(enc1)); \
5998  len += strlen(rb_enc_name(enc2)); \
5999  errbuf = ALLOCA_N(char, len); \
6000  snprintf(errbuf, len, mixed_msg, \
6001  rb_enc_name(enc1), \
6002  rb_enc_name(enc2)); \
6003  yyerror(errbuf); \
6004  }
6005 #define mixed_escape(beg, enc1, enc2) do { \
6006  const char *pos = lex_p; \
6007  lex_p = (beg); \
6008  mixed_error((enc1), (enc2)); \
6009  lex_p = pos; \
6010  } while (0)
6011 
6012  while ((c = nextc()) != -1) {
6013  if (paren && c == paren) {
6014  ++*nest;
6015  }
6016  else if (c == term) {
6017  if (!nest || !*nest) {
6018  pushback(c);
6019  break;
6020  }
6021  --*nest;
6022  }
6023  else if ((func & STR_FUNC_EXPAND) && c == '#' && lex_p < lex_pend) {
6024  int c2 = *lex_p;
6025  if (c2 == '$' || c2 == '@' || c2 == '{') {
6026  pushback(c);
6027  break;
6028  }
6029  }
6030  else if (c == '\\') {
6031  const char *beg = lex_p - 1;
6032  c = nextc();
6033  switch (c) {
6034  case '\n':
6035  if (func & STR_FUNC_QWORDS) break;
6036  if (func & STR_FUNC_EXPAND) continue;
6037  tokadd('\\');
6038  break;
6039 
6040  case '\\':
6041  if (func & STR_FUNC_ESCAPE) tokadd(c);
6042  break;
6043 
6044  case 'u':
6045  if ((func & STR_FUNC_EXPAND) == 0) {
6046  tokadd('\\');
6047  break;
6048  }
6049  parser_tokadd_utf8(parser, &enc, 1,
6050  func & STR_FUNC_SYMBOL,
6051  func & STR_FUNC_REGEXP);
6052  if (has_nonascii && enc != *encp) {
6053  mixed_escape(beg, enc, *encp);
6054  }
6055  continue;
6056 
6057  default:
6058  if (c == -1) return -1;
6059  if (!ISASCII(c)) {
6060  if ((func & STR_FUNC_EXPAND) == 0) tokadd('\\');
6061  goto non_ascii;
6062  }
6063  if (func & STR_FUNC_REGEXP) {
6064  if (c == term && !simple_re_meta(c)) {
6065  tokadd(c);
6066  continue;
6067  }
6068  pushback(c);
6069  if ((c = tokadd_escape(&enc)) < 0)
6070  return -1;
6071  if (has_nonascii && enc != *encp) {
6072  mixed_escape(beg, enc, *encp);
6073  }
6074  continue;
6075  }
6076  else if (func & STR_FUNC_EXPAND) {
6077  pushback(c);
6078  if (func & STR_FUNC_ESCAPE) tokadd('\\');
6079  c = read_escape(0, &enc);
6080  }
6081  else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6082  /* ignore backslashed spaces in %w */
6083  }
6084  else if (c != term && !(paren && c == paren)) {
6085  tokadd('\\');
6086  pushback(c);
6087  continue;
6088  }
6089  }
6090  }
6091  else if (!parser_isascii()) {
6092  non_ascii:
6093  has_nonascii = 1;
6094  if (enc != *encp) {
6095  mixed_error(enc, *encp);
6096  continue;
6097  }
6098  if (tokadd_mbchar(c) == -1) return -1;
6099  continue;
6100  }
6101  else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6102  pushback(c);
6103  break;
6104  }
6105  if (c & 0x80) {
6106  has_nonascii = 1;
6107  if (enc != *encp) {
6108  mixed_error(enc, *encp);
6109  continue;
6110  }
6111  }
6112  tokadd(c);
6113  }
6114  *encp = enc;
6115  return c;
6116 }
6117 
6118 #define NEW_STRTERM(func, term, paren) \
6119  rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
6120 
6121 #ifdef RIPPER
6122 static void
6123 ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc)
6124 {
6125  if (!NIL_P(parser->delayed)) {
6126  ptrdiff_t len = lex_p - parser->tokp;
6127  if (len > 0) {
6128  rb_enc_str_buf_cat(parser->delayed, parser->tokp, len, enc);
6129  }
6130  ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6131  parser->tokp = lex_p;
6132  }
6133 }
6134 
6135 #define flush_string_content(enc) ripper_flush_string_content(parser, (enc))
6136 #else
6137 #define flush_string_content(enc) ((void)(enc))
6138 #endif
6139 
6140 RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
6141 /* this can be shared with ripper, since it's independent from struct
6142  * parser_params. */
6143 #ifndef RIPPER
6144 #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
6145 #define SPECIAL_PUNCT(idx) ( \
6146  BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
6147  BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
6148  BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
6149  BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
6150  BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
6151  BIT('0', idx))
6152 const unsigned int ruby_global_name_punct_bits[] = {
6153  SPECIAL_PUNCT(0),
6154  SPECIAL_PUNCT(1),
6155  SPECIAL_PUNCT(2),
6156 };
6157 #undef BIT
6158 #undef SPECIAL_PUNCT
6159 #endif
6160 
6161 static inline int
6162 is_global_name_punct(const char c)
6163 {
6164  if (c <= 0x20 || 0x7e < c) return 0;
6165  return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
6166 }
6167 
6168 static int
6170 {
6171  int c;
6172  const char *p = lex_p;
6173 
6174  if (p + 1 >= lex_pend) return 0;
6175  c = *p++;
6176  switch (c) {
6177  case '$':
6178  if ((c = *p) == '-') {
6179  if (++p >= lex_pend) return 0;
6180  c = *p;
6181  }
6182  else if (is_global_name_punct(c) || ISDIGIT(c)) {
6183  return tSTRING_DVAR;
6184  }
6185  break;
6186  case '@':
6187  if ((c = *p) == '@') {
6188  if (++p >= lex_pend) return 0;
6189  c = *p;
6190  }
6191  break;
6192  case '{':
6193  lex_p = p;
6194  command_start = TRUE;
6195  return tSTRING_DBEG;
6196  default:
6197  return 0;
6198  }
6199  if (!ISASCII(c) || c == '_' || ISALPHA(c))
6200  return tSTRING_DVAR;
6201  return 0;
6202 }
6203 
6204 static int
6205 parser_parse_string(struct parser_params *parser, NODE *quote)
6206 {
6207  int func = (int)quote->nd_func;
6208  int term = nd_term(quote);
6209  int paren = nd_paren(quote);
6210  int c, space = 0;
6211  rb_encoding *enc = current_enc;
6212 
6213  if (func == -1) return tSTRING_END;
6214  c = nextc();
6215  if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6216  do {c = nextc();} while (ISSPACE(c));
6217  space = 1;
6218  }
6219  if (c == term && !quote->nd_nest) {
6220  if (func & STR_FUNC_QWORDS) {
6221  quote->nd_func = -1;
6222  return ' ';
6223  }
6224  if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
6226  return tREGEXP_END;
6227  }
6228  if (space) {
6229  pushback(c);
6230  return ' ';
6231  }
6232  newtok();
6233  if ((func & STR_FUNC_EXPAND) && c == '#') {
6234  int t = parser_peek_variable_name(parser);
6235  if (t) return t;
6236  tokadd('#');
6237  c = nextc();
6238  }
6239  pushback(c);
6240  if (tokadd_string(func, term, paren, &quote->nd_nest,
6241  &enc) == -1) {
6242  ruby_sourceline = nd_line(quote);
6243  if (func & STR_FUNC_REGEXP) {
6244  if (parser->eofp)
6245  compile_error(PARSER_ARG "unterminated regexp meets end of file");
6246  return tREGEXP_END;
6247  }
6248  else {
6249  if (parser->eofp)
6250  compile_error(PARSER_ARG "unterminated string meets end of file");
6251  return tSTRING_END;
6252  }
6253  }
6254 
6255  tokfix();
6256  set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
6257  flush_string_content(enc);
6258 
6259  return tSTRING_CONTENT;
6260 }
6261 
6262 static int
6264 {
6265  int c = nextc(), term, func = 0;
6266  long len;
6267 
6268  if (c == '-') {
6269  c = nextc();
6270  func = STR_FUNC_INDENT;
6271  }
6272  switch (c) {
6273  case '\'':
6274  func |= str_squote; goto quoted;
6275  case '"':
6276  func |= str_dquote; goto quoted;
6277  case '`':
6278  func |= str_xquote;
6279  quoted:
6280  newtok();
6281  tokadd(func);
6282  term = c;
6283  while ((c = nextc()) != -1 && c != term) {
6284  if (tokadd_mbchar(c) == -1) return 0;
6285  }
6286  if (c == -1) {
6287  compile_error(PARSER_ARG "unterminated here document identifier");
6288  return 0;
6289  }
6290  break;
6291 
6292  default:
6293  if (!parser_is_identchar()) {
6294  pushback(c);
6295  if (func & STR_FUNC_INDENT) {
6296  pushback('-');
6297  }
6298  return 0;
6299  }
6300  newtok();
6301  term = '"';
6302  tokadd(func |= str_dquote);
6303  do {
6304  if (tokadd_mbchar(c) == -1) return 0;
6305  } while ((c = nextc()) != -1 && parser_is_identchar());
6306  pushback(c);
6307  break;
6308  }
6309 
6310  tokfix();
6311 #ifdef RIPPER
6312  ripper_dispatch_scan_event(parser, tHEREDOC_BEG);
6313 #endif
6314  len = lex_p - lex_pbeg;
6315  lex_goto_eol(parser);
6317  STR_NEW(tok(), toklen()), /* nd_lit */
6318  len, /* nd_nth */
6319  lex_lastline); /* nd_orig */
6321  ripper_flush(parser);
6322  return term == '`' ? tXSTRING_BEG : tSTRING_BEG;
6323 }
6324 
6325 static void
6326 parser_heredoc_restore(struct parser_params *parser, NODE *here)
6327 {
6328  VALUE line;
6329 
6330  line = here->nd_orig;
6331  lex_lastline = line;
6332  lex_pbeg = RSTRING_PTR(line);
6333  lex_pend = lex_pbeg + RSTRING_LEN(line);
6334  lex_p = lex_pbeg + here->nd_nth;
6336  ruby_sourceline = nd_line(here);
6337  dispose_string(here->nd_lit);
6338  rb_gc_force_recycle((VALUE)here);
6339  ripper_flush(parser);
6340 }
6341 
6342 static int
6343 parser_whole_match_p(struct parser_params *parser,
6344  const char *eos, long len, int indent)
6345 {
6346  const char *p = lex_pbeg;
6347  long n;
6348 
6349  if (indent) {
6350  while (*p && ISSPACE(*p)) p++;
6351  }
6352  n = lex_pend - (p + len);
6353  if (n < 0 || (n > 0 && p[len] != '\n' && p[len] != '\r')) return FALSE;
6354  return strncmp(eos, p, len) == 0;
6355 }
6356 
6357 #ifdef RIPPER
6358 static void
6359 ripper_dispatch_heredoc_end(struct parser_params *parser)
6360 {
6361  if (!NIL_P(parser->delayed))
6362  ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6363  lex_goto_eol(parser);
6364  ripper_dispatch_ignored_scan_event(parser, tHEREDOC_END);
6365 }
6366 
6367 #define dispatch_heredoc_end() ripper_dispatch_heredoc_end(parser)
6368 #else
6369 #define dispatch_heredoc_end() ((void)0)
6370 #endif
6371 
6372 static int
6373 parser_here_document(struct parser_params *parser, NODE *here)
6374 {
6375  int c, func, indent = 0;
6376  const char *eos, *p, *pend;
6377  long len;
6378  VALUE str = 0;
6379  rb_encoding *enc = current_enc;
6380 
6381  eos = RSTRING_PTR(here->nd_lit);
6382  len = RSTRING_LEN(here->nd_lit) - 1;
6383  indent = (func = *eos++) & STR_FUNC_INDENT;
6384 
6385  if ((c = nextc()) == -1) {
6386  error:
6387  compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
6388 #ifdef RIPPER
6389  if (NIL_P(parser->delayed)) {
6390  ripper_dispatch_scan_event(parser, tSTRING_CONTENT);
6391  }
6392  else {
6393  if (str ||
6394  ((len = lex_p - parser->tokp) > 0 &&
6395  (str = STR_NEW3(parser->tokp, len, enc, func), 1))) {
6396  rb_str_append(parser->delayed, str);
6397  }
6398  ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6399  }
6400  lex_goto_eol(parser);
6401 #endif
6402  restore:
6404  lex_strterm = 0;
6405  return 0;
6406  }
6407  if (was_bol() && whole_match_p(eos, len, indent)) {
6410  return tSTRING_END;
6411  }
6412 
6413  if (!(func & STR_FUNC_EXPAND)) {
6414  do {
6416  pend = lex_pend;
6417  if (pend > p) {
6418  switch (pend[-1]) {
6419  case '\n':
6420  if (--pend == p || pend[-1] != '\r') {
6421  pend++;
6422  break;
6423  }
6424  case '\r':
6425  --pend;
6426  }
6427  }
6428  if (str)
6429  rb_str_cat(str, p, pend - p);
6430  else
6431  str = STR_NEW(p, pend - p);
6432  if (pend < lex_pend) rb_str_cat(str, "\n", 1);
6433  lex_goto_eol(parser);
6434  if (nextc() == -1) {
6435  if (str) dispose_string(str);
6436  goto error;
6437  }
6438  } while (!whole_match_p(eos, len, indent));
6439  }
6440  else {
6441  /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
6442  newtok();
6443  if (c == '#') {
6444  int t = parser_peek_variable_name(parser);
6445  if (t) return t;
6446  tokadd('#');
6447  c = nextc();
6448  }
6449  do {
6450  pushback(c);
6451  if ((c = tokadd_string(func, '\n', 0, NULL, &enc)) == -1) {
6452  if (parser->eofp) goto error;
6453  goto restore;
6454  }
6455  if (c != '\n') {
6456  set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
6457  flush_string_content(enc);
6458  return tSTRING_CONTENT;
6459  }
6460  tokadd(nextc());
6461  /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
6462  if ((c = nextc()) == -1) goto error;
6463  } while (!whole_match_p(eos, len, indent));
6464  str = STR_NEW3(tok(), toklen(), enc, func);
6465  }
6468  lex_strterm = NEW_STRTERM(-1, 0, 0);
6469  set_yylval_str(str);
6470  return tSTRING_CONTENT;
6471 }
6472 
6473 #include "lex.c"
6474 
6475 static void
6476 arg_ambiguous_gen(struct parser_params *parser)
6477 {
6478 #ifndef RIPPER
6479  rb_warning0("ambiguous first argument; put parentheses or even spaces");
6480 #else
6482 #endif
6483 }
6484 #define arg_ambiguous() (arg_ambiguous_gen(parser), 1)
6485 
6486 static ID
6487 formal_argument_gen(struct parser_params *parser, ID lhs)
6488 {
6489 #ifndef RIPPER
6490  if (!is_local_id(lhs))
6491  yyerror("formal argument must be local variable");
6492 #endif
6493  shadowing_lvar(lhs);
6494  return lhs;
6495 }
6496 
6497 static int
6498 lvar_defined_gen(struct parser_params *parser, ID id)
6499 {
6500  return (dyna_in_block() && dvar_defined_get(id)) || local_id(id);
6501 }
6502 
6503 /* emacsen -*- hack */
6504 static long
6505 parser_encode_length(struct parser_params *parser, const char *name, long len)
6506 {
6507  long nlen;
6508 
6509  if (len > 5 && name[nlen = len - 5] == '-') {
6510  if (rb_memcicmp(name + nlen + 1, "unix", 4) == 0)
6511  return nlen;
6512  }
6513  if (len > 4 && name[nlen = len - 4] == '-') {
6514  if (rb_memcicmp(name + nlen + 1, "dos", 3) == 0)
6515  return nlen;
6516  if (rb_memcicmp(name + nlen + 1, "mac", 3) == 0 &&
6517  !(len == 8 && rb_memcicmp(name, "utf8-mac", len) == 0))
6518  /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
6519  return nlen;
6520  }
6521  return len;
6522 }
6523 
6524 static void
6525 parser_set_encode(struct parser_params *parser, const char *name)
6526 {
6527  int idx = rb_enc_find_index(name);
6528  rb_encoding *enc;
6529  VALUE excargs[3];
6530 
6531  if (idx < 0) {
6532  excargs[1] = rb_sprintf("unknown encoding name: %s", name);
6533  error:
6534  excargs[0] = rb_eArgError;
6535  excargs[2] = rb_make_backtrace();
6536  rb_ary_unshift(excargs[2], rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline));
6537  rb_exc_raise(rb_make_exception(3, excargs));
6538  }
6539  enc = rb_enc_from_index(idx);
6540  if (!rb_enc_asciicompat(enc)) {
6541  excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
6542  goto error;
6543  }
6544  parser->enc = enc;
6545 #ifndef RIPPER
6546  if (ruby_debug_lines) {
6547  long i, n = RARRAY_LEN(ruby_debug_lines);
6548  const VALUE *p = RARRAY_PTR(ruby_debug_lines);
6549  for (i = 0; i < n; ++i) {
6550  rb_enc_associate_index(*p, idx);
6551  }
6552  }
6553 #endif
6554 }
6555 
6556 static int
6557 comment_at_top(struct parser_params *parser)
6558 {
6559  const char *p = lex_pbeg, *pend = lex_p - 1;
6560  if (parser->line_count != (parser->has_shebang ? 2 : 1)) return 0;
6561  while (p < pend) {
6562  if (!ISSPACE(*p)) return 0;
6563  p++;
6564  }
6565  return 1;
6566 }
6567 
6568 #ifndef RIPPER
6569 typedef long (*rb_magic_comment_length_t)(struct parser_params *parser, const char *name, long len);
6570 typedef void (*rb_magic_comment_setter_t)(struct parser_params *parser, const char *name, const char *val);
6571 
6572 static void
6573 magic_comment_encoding(struct parser_params *parser, const char *name, const char *val)
6574 {
6575  if (!comment_at_top(parser)) {
6576  return;
6577  }
6578  parser_set_encode(parser, val);
6579 }
6580 
6581 static void
6582 parser_set_token_info(struct parser_params *parser, const char *name, const char *val)
6583 {
6584  int *p = &parser->parser_token_info_enabled;
6585 
6586  switch (*val) {
6587  case 't': case 'T':
6588  if (strcasecmp(val, "true") == 0) {
6589  *p = TRUE;
6590  return;
6591  }
6592  break;
6593  case 'f': case 'F':
6594  if (strcasecmp(val, "false") == 0) {
6595  *p = FALSE;
6596  return;
6597  }
6598  break;
6599  }
6600  rb_compile_warning(ruby_sourcefile, ruby_sourceline, "invalid value for %s: %s", name, val);
6601 }
6602 
6603 struct magic_comment {
6604  const char *name;
6607 };
6608 
6609 static const struct magic_comment magic_comments[] = {
6612  {"warn_indent", parser_set_token_info},
6613 };
6614 #endif
6615 
6616 static const char *
6617 magic_comment_marker(const char *str, long len)
6618 {
6619  long i = 2;
6620 
6621  while (i < len) {
6622  switch (str[i]) {
6623  case '-':
6624  if (str[i-1] == '*' && str[i-2] == '-') {
6625  return str + i + 1;
6626  }
6627  i += 2;
6628  break;
6629  case '*':
6630  if (i + 1 >= len) return 0;
6631  if (str[i+1] != '-') {
6632  i += 4;
6633  }
6634  else if (str[i-1] != '-') {
6635  i += 2;
6636  }
6637  else {
6638  return str + i + 2;
6639  }
6640  break;
6641  default:
6642  i += 3;
6643  break;
6644  }
6645  }
6646  return 0;
6647 }
6648 
6649 static int
6650 parser_magic_comment(struct parser_params *parser, const char *str, long len)
6651 {
6652  VALUE name = 0, val = 0;
6653  const char *beg, *end, *vbeg, *vend;
6654 #define str_copy(_s, _p, _n) ((_s) \
6655  ? (void)(rb_str_resize((_s), (_n)), \
6656  MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
6657  : (void)((_s) = STR_NEW((_p), (_n))))
6658 
6659  if (len <= 7) return FALSE;
6660  if (!(beg = magic_comment_marker(str, len))) return FALSE;
6661  if (!(end = magic_comment_marker(beg, str + len - beg))) return FALSE;
6662  str = beg;
6663  len = end - beg - 3;
6664 
6665  /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
6666  while (len > 0) {
6667 #ifndef RIPPER
6668  const struct magic_comment *p = magic_comments;
6669 #endif
6670  char *s;
6671  int i;
6672  long n = 0;
6673 
6674  for (; len > 0 && *str; str++, --len) {
6675  switch (*str) {
6676  case '\'': case '"': case ':': case ';':
6677  continue;
6678  }
6679  if (!ISSPACE(*str)) break;
6680  }
6681  for (beg = str; len > 0; str++, --len) {
6682  switch (*str) {
6683  case '\'': case '"': case ':': case ';':
6684  break;
6685  default:
6686  if (ISSPACE(*str)) break;
6687  continue;
6688  }
6689  break;
6690  }
6691  for (end = str; len > 0 && ISSPACE(*str); str++, --len);
6692  if (!len) break;
6693  if (*str != ':') continue;
6694 
6695  do str++; while (--len > 0 && ISSPACE(*str));
6696  if (!len) break;
6697  if (*str == '"') {
6698  for (vbeg = ++str; --len > 0 && *str != '"'; str++) {
6699  if (*str == '\\') {
6700  --len;
6701  ++str;
6702  }
6703  }
6704  vend = str;
6705  if (len) {
6706  --len;
6707  ++str;
6708  }
6709  }
6710  else {
6711  for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
6712  vend = str;
6713  }
6714  while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
6715 
6716  n = end - beg;
6717  str_copy(name, beg, n);
6718  s = RSTRING_PTR(name);
6719  for (i = 0; i < n; ++i) {
6720  if (s[i] == '-') s[i] = '_';
6721  }
6722 #ifndef RIPPER
6723  do {
6724  if (STRNCASECMP(p->name, s, n) == 0) {
6725  n = vend - vbeg;
6726  if (p->length) {
6727  n = (*p->length)(parser, vbeg, n);
6728  }
6729  str_copy(val, vbeg, n);
6730  (*p->func)(parser, s, RSTRING_PTR(val));
6731  break;
6732  }
6733  } while (++p < magic_comments + numberof(magic_comments));
6734 #else
6735  str_copy(val, vbeg, vend - vbeg);
6736  dispatch2(magic_comment, name, val);
6737 #endif
6738  }
6739 
6740  return TRUE;
6741 }
6742 
6743 static void
6744 set_file_encoding(struct parser_params *parser, const char *str, const char *send)
6745 {
6746  int sep = 0;
6747  const char *beg = str;
6748  VALUE s;
6749 
6750  for (;;) {
6751  if (send - str <= 6) return;
6752  switch (str[6]) {
6753  case 'C': case 'c': str += 6; continue;
6754  case 'O': case 'o': str += 5; continue;
6755  case 'D': case 'd': str += 4; continue;
6756  case 'I': case 'i': str += 3; continue;
6757  case 'N': case 'n': str += 2; continue;
6758  case 'G': case 'g': str += 1; continue;
6759  case '=': case ':':
6760  sep = 1;
6761  str += 6;
6762  break;
6763  default:
6764  str += 6;
6765  if (ISSPACE(*str)) break;
6766  continue;
6767  }
6768  if (STRNCASECMP(str-6, "coding", 6) == 0) break;
6769  }
6770  for (;;) {
6771  do {
6772  if (++str >= send) return;
6773  } while (ISSPACE(*str));
6774  if (sep) break;
6775  if (*str != '=' && *str != ':') return;
6776  sep = 1;
6777  str++;
6778  }
6779  beg = str;
6780  while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
6781  s = rb_str_new(beg, parser_encode_length(parser, beg, str - beg));
6782  parser_set_encode(parser, RSTRING_PTR(s));
6783  rb_str_resize(s, 0);
6784 }
6785 
6786 static void
6787 parser_prepare(struct parser_params *parser)
6788 {
6789  int c = nextc();
6790  switch (c) {
6791  case '#':
6792  if (peek('!')) parser->has_shebang = 1;
6793  break;
6794  case 0xef: /* UTF-8 BOM marker */
6795  if (lex_pend - lex_p >= 2 &&
6796  (unsigned char)lex_p[0] == 0xbb &&
6797  (unsigned char)lex_p[1] == 0xbf) {
6798  parser->enc = rb_utf8_encoding();
6799  lex_p += 2;
6800  lex_pbeg = lex_p;
6801  return;
6802  }
6803  break;
6804  case EOF:
6805  return;
6806  }
6807  pushback(c);
6808  parser->enc = rb_enc_get(lex_lastline);
6809 }
6810 
6811 #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
6812 #define IS_END() IS_lex_state(EXPR_END_ANY)
6813 #define IS_BEG() IS_lex_state(EXPR_BEG_ANY)
6814 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
6815 #define IS_LABEL_POSSIBLE() ((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !cmd_state) || IS_ARG())
6816 #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
6817 #define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
6818 
6819 #ifndef RIPPER
6820 #define ambiguous_operator(op, syn) ( \
6821  rb_warning0("`"op"' after local variable is interpreted as binary operator"), \
6822  rb_warning0("even though it seems like "syn""))
6823 #else
6824 #define ambiguous_operator(op, syn) dispatch2(operator_ambiguous, ripper_intern(op), rb_str_new_cstr(syn))
6825 #endif
6826 #define warn_balanced(op, syn) ((void) \
6827  (!IS_lex_state_for(last_state, EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN|EXPR_ENDARG) && \
6828  space_seen && !ISSPACE(c) && \
6829  (ambiguous_operator(op, syn), 0)))
6830 
6831 static int
6832 parser_yylex(struct parser_params *parser)
6833 {
6834  register int c;
6835  int space_seen = 0;
6836  int cmd_state;
6837  enum lex_state_e last_state;
6838  rb_encoding *enc;
6839  int mb;
6840 #ifdef RIPPER
6841  int fallthru = FALSE;
6842 #endif
6843 
6844  if (lex_strterm) {
6845  int token;
6846  if (nd_type(lex_strterm) == NODE_HEREDOC) {
6847  token = here_document(lex_strterm);
6848  if (token == tSTRING_END) {
6849  lex_strterm = 0;
6850  lex_state = EXPR_END;
6851  }
6852  }
6853  else {
6854  token = parse_string(lex_strterm);
6855  if (token == tSTRING_END || token == tREGEXP_END) {
6857  lex_strterm = 0;
6858  lex_state = EXPR_END;
6859  }
6860  }
6861  return token;
6862  }
6863  cmd_state = command_start;
6864  command_start = FALSE;
6865  retry:
6866  last_state = lex_state;
6867  switch (c = nextc()) {
6868  case '\0': /* NUL */
6869  case '\004': /* ^D */
6870  case '\032': /* ^Z */
6871  case -1: /* end of script. */
6872  return 0;
6873 
6874  /* white spaces */
6875  case ' ': case '\t': case '\f': case '\r':
6876  case '\13': /* '\v' */
6877  space_seen = 1;
6878 #ifdef RIPPER
6879  while ((c = nextc())) {
6880  switch (c) {
6881  case ' ': case '\t': case '\f': case '\r':
6882  case '\13': /* '\v' */
6883  break;
6884  default:
6885  goto outofloop;
6886  }
6887  }
6888  outofloop:
6889  pushback(c);
6890  ripper_dispatch_scan_event(parser, tSP);
6891 #endif
6892  goto retry;
6893 
6894  case '#': /* it's a comment */
6895  /* no magic_comment in shebang line */
6896  if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
6897  if (comment_at_top(parser)) {
6898  set_file_encoding(parser, lex_p, lex_pend);
6899  }
6900  }
6901  lex_p = lex_pend;
6902 #ifdef RIPPER
6903  ripper_dispatch_scan_event(parser, tCOMMENT);
6904  fallthru = TRUE;
6905 #endif
6906  /* fall through */
6907  case '\n':
6908  if (IS_lex_state(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT)) {
6909 #ifdef RIPPER
6910  if (!fallthru) {
6911  ripper_dispatch_scan_event(parser, tIGNORED_NL);
6912  }
6913  fallthru = FALSE;
6914 #endif
6915  goto retry;
6916  }
6917  while ((c = nextc())) {
6918  switch (c) {
6919  case ' ': case '\t': case '\f': case '\r':
6920  case '\13': /* '\v' */
6921  space_seen = 1;
6922  break;
6923  case '.': {
6924  if ((c = nextc()) != '.') {
6925  pushback(c);
6926  pushback('.');
6927  goto retry;
6928  }
6929  }
6930  default:
6931  --ruby_sourceline;
6933  case -1: /* EOF no decrement*/
6934  lex_goto_eol(parser);
6935 #ifdef RIPPER
6936  if (c != -1) {
6937  parser->tokp = lex_p;
6938  }
6939 #endif
6940  goto normal_newline;
6941  }
6942  }
6943  normal_newline:
6944  command_start = TRUE;
6945  lex_state = EXPR_BEG;
6946  return '\n';
6947 
6948  case '*':
6949  if ((c = nextc()) == '*') {
6950  if ((c = nextc()) == '=') {
6952  lex_state = EXPR_BEG;
6953  return tOP_ASGN;
6954  }
6955  pushback(c);
6956  if (IS_SPCARG(c)) {
6957  rb_warning0("`**' interpreted as argument prefix");
6958  c = tDSTAR;
6959  }
6960  else if (IS_BEG()) {
6961  c = tDSTAR;
6962  }
6963  else {
6964  warn_balanced("**", "argument prefix");
6965  c = tPOW;
6966  }
6967  }
6968  else {
6969  if (c == '=') {
6970  set_yylval_id('*');
6971  lex_state = EXPR_BEG;
6972  return tOP_ASGN;
6973  }
6974  pushback(c);
6975  if (IS_SPCARG(c)) {
6976  rb_warning0("`*' interpreted as argument prefix");
6977  c = tSTAR;
6978  }
6979  else if (IS_BEG()) {
6980  c = tSTAR;
6981  }
6982  else {
6983  warn_balanced("*", "argument prefix");
6984  c = '*';
6985  }
6986  }
6987  lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
6988  return c;
6989 
6990  case '!':
6991  c = nextc();
6992  if (IS_AFTER_OPERATOR()) {
6993  lex_state = EXPR_ARG;
6994  if (c == '@') {
6995  return '!';
6996  }
6997  }
6998  else {
6999  lex_state = EXPR_BEG;
7000  }
7001  if (c == '=') {
7002  return tNEQ;
7003  }
7004  if (c == '~') {
7005  return tNMATCH;
7006  }
7007  pushback(c);
7008  return '!';
7009 
7010  case '=':
7011  if (was_bol()) {
7012  /* skip embedded rd document */
7013  if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
7014 #ifdef RIPPER
7015  int first_p = TRUE;
7016 
7017  lex_goto_eol(parser);
7018  ripper_dispatch_scan_event(parser, tEMBDOC_BEG);
7019 #endif
7020  for (;;) {
7021  lex_goto_eol(parser);
7022 #ifdef RIPPER
7023  if (!first_p) {
7024  ripper_dispatch_scan_event(parser, tEMBDOC);
7025  }
7026  first_p = FALSE;
7027 #endif
7028  c = nextc();
7029  if (c == -1) {
7030  compile_error(PARSER_ARG "embedded document meets end of file");
7031  return 0;
7032  }
7033  if (c != '=') continue;
7034  if (strncmp(lex_p, "end", 3) == 0 &&
7035  (lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {
7036  break;
7037  }
7038  }
7039  lex_goto_eol(parser);
7040 #ifdef RIPPER
7041  ripper_dispatch_scan_event(parser, tEMBDOC_END);
7042 #endif
7043  goto retry;
7044  }
7045  }
7046 
7047  lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7048  if ((c = nextc()) == '=') {
7049  if ((c = nextc()) == '=') {
7050  return tEQQ;
7051  }
7052  pushback(c);
7053  return tEQ;
7054  }
7055  if (c == '~') {
7056  return tMATCH;
7057  }
7058  else if (c == '>') {
7059  return tASSOC;
7060  }
7061  pushback(c);
7062  return '=';
7063 
7064  case '<':
7065  last_state = lex_state;
7066  c = nextc();
7067  if (c == '<' &&
7068  !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
7069  !IS_END() &&
7070  (!IS_ARG() || space_seen)) {
7071  int token = heredoc_identifier();
7072  if (token) return token;
7073  }
7074  if (IS_AFTER_OPERATOR()) {
7075  lex_state = EXPR_ARG;
7076  }
7077  else {
7078  if (IS_lex_state(EXPR_CLASS))
7079  command_start = TRUE;
7080  lex_state = EXPR_BEG;
7081  }
7082  if (c == '=') {
7083  if ((c = nextc()) == '>') {
7084  return tCMP;
7085  }
7086  pushback(c);
7087  return tLEQ;
7088  }
7089  if (c == '<') {
7090  if ((c = nextc()) == '=') {
7092  lex_state = EXPR_BEG;
7093  return tOP_ASGN;
7094  }
7095  pushback(c);
7096  warn_balanced("<<", "here document");
7097  return tLSHFT;
7098  }
7099  pushback(c);
7100  return '<';
7101 
7102  case '>':
7103  lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7104  if ((c = nextc()) == '=') {
7105  return tGEQ;
7106  }
7107  if (c == '>') {
7108  if ((c = nextc()) == '=') {
7110  lex_state = EXPR_BEG;
7111  return tOP_ASGN;
7112  }
7113  pushback(c);
7114  return tRSHFT;
7115  }
7116  pushback(c);
7117  return '>';
7118 
7119  case '"':
7120  lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
7121  return tSTRING_BEG;
7122 
7123  case '`':
7124  if (IS_lex_state(EXPR_FNAME)) {
7125  lex_state = EXPR_ENDFN;
7126  return c;
7127  }
7128  if (IS_lex_state(EXPR_DOT)) {
7129  if (cmd_state)
7130  lex_state = EXPR_CMDARG;
7131  else
7132  lex_state = EXPR_ARG;
7133  return c;
7134  }
7135  lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
7136  return tXSTRING_BEG;
7137 
7138  case '\'':
7139  lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
7140  return tSTRING_BEG;
7141 
7142  case '?':
7143  if (IS_END()) {
7144  lex_state = EXPR_VALUE;
7145  return '?';
7146  }
7147  c = nextc();
7148  if (c == -1) {
7149  compile_error(PARSER_ARG "incomplete character syntax");
7150  return 0;
7151  }
7152  if (rb_enc_isspace(c, current_enc)) {
7153  if (!IS_ARG()) {
7154  int c2 = 0;
7155  switch (c) {
7156  case ' ':
7157  c2 = 's';
7158  break;
7159  case '\n':
7160  c2 = 'n';
7161  break;
7162  case '\t':
7163  c2 = 't';
7164  break;
7165  case '\v':
7166  c2 = 'v';
7167  break;
7168  case '\r':
7169  c2 = 'r';
7170  break;
7171  case '\f':
7172  c2 = 'f';
7173  break;
7174  }
7175  if (c2) {
7176  rb_warnI("invalid character syntax; use ?\\%c", c2);
7177  }
7178  }
7179  ternary:
7180  pushback(c);
7181  lex_state = EXPR_VALUE;
7182  return '?';
7183  }
7184  newtok();
7185  enc = current_enc;
7186  if (!parser_isascii()) {
7187  if (tokadd_mbchar(c) == -1) return 0;
7188  }
7189  else if ((rb_enc_isalnum(c, current_enc) || c == '_') &&
7191  goto ternary;
7192  }
7193  else if (c == '\\') {
7194  if (peek('u')) {
7195  nextc();
7196  c = parser_tokadd_utf8(parser, &enc, 0, 0, 0);
7197  if (0x80 <= c) {
7198  tokaddmbc(c, enc);
7199  }
7200  else {
7201  tokadd(c);
7202  }
7203  }
7204  else if (!lex_eol_p() && !(c = *lex_p, ISASCII(c))) {
7205  nextc();
7206  if (tokadd_mbchar(c) == -1) return 0;
7207  }
7208  else {
7209  c = read_escape(0, &enc);
7210  tokadd(c);
7211  }
7212  }
7213  else {
7214  tokadd(c);
7215  }
7216  tokfix();
7217  set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0));
7218  lex_state = EXPR_END;
7219  return tCHAR;
7220 
7221  case '&':
7222  if ((c = nextc()) == '&') {
7223  lex_state = EXPR_BEG;
7224  if ((c = nextc()) == '=') {
7226  lex_state = EXPR_BEG;
7227  return tOP_ASGN;
7228  }
7229  pushback(c);
7230  return tANDOP;
7231  }
7232  else if (c == '=') {
7233  set_yylval_id('&');
7234  lex_state = EXPR_BEG;
7235  return tOP_ASGN;
7236  }
7237  pushback(c);
7238  if (IS_SPCARG(c)) {
7239  rb_warning0("`&' interpreted as argument prefix");
7240  c = tAMPER;
7241  }
7242  else if (IS_BEG()) {
7243  c = tAMPER;
7244  }
7245  else {
7246  warn_balanced("&", "argument prefix");
7247  c = '&';
7248  }
7249  lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7250  return c;
7251 
7252  case '|':
7253  if ((c = nextc()) == '|') {
7254  lex_state = EXPR_BEG;
7255  if ((c = nextc()) == '=') {
7257  lex_state = EXPR_BEG;
7258  return tOP_ASGN;
7259  }
7260  pushback(c);
7261  return tOROP;
7262  }
7263  if (c == '=') {
7264  set_yylval_id('|');
7265  lex_state = EXPR_BEG;
7266  return tOP_ASGN;
7267  }
7268  lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7269  pushback(c);
7270  return '|';
7271 
7272  case '+':
7273  c = nextc();
7274  if (IS_AFTER_OPERATOR()) {
7275  lex_state = EXPR_ARG;
7276  if (c == '@') {
7277  return tUPLUS;
7278  }
7279  pushback(c);
7280  return '+';
7281  }
7282  if (c == '=') {
7283  set_yylval_id('+');
7284  lex_state = EXPR_BEG;
7285  return tOP_ASGN;
7286  }
7287  if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7288  lex_state = EXPR_BEG;
7289  pushback(c);
7290  if (c != -1 && ISDIGIT(c)) {
7291  c = '+';
7292  goto start_num;
7293  }
7294  return tUPLUS;
7295  }
7296  lex_state = EXPR_BEG;
7297  pushback(c);
7298  warn_balanced("+", "unary operator");
7299  return '+';
7300 
7301  case '-':
7302  c = nextc();
7303  if (IS_AFTER_OPERATOR()) {
7304  lex_state = EXPR_ARG;
7305  if (c == '@') {
7306  return tUMINUS;
7307  }
7308  pushback(c);
7309  return '-';
7310  }
7311  if (c == '=') {
7312  set_yylval_id('-');
7313  lex_state = EXPR_BEG;
7314  return tOP_ASGN;
7315  }
7316  if (c == '>') {
7317  lex_state = EXPR_ENDFN;
7318  return tLAMBDA;
7319  }
7320  if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7321  lex_state = EXPR_BEG;
7322  pushback(c);
7323  if (c != -1 && ISDIGIT(c)) {
7324  return tUMINUS_NUM;
7325  }
7326  return tUMINUS;
7327  }
7328  lex_state = EXPR_BEG;
7329  pushback(c);
7330  warn_balanced("-", "unary operator");
7331  return '-';
7332 
7333  case '.':
7334  lex_state = EXPR_BEG;
7335  if ((c = nextc()) == '.') {
7336  if ((c = nextc()) == '.') {
7337  return tDOT3;
7338  }
7339  pushback(c);
7340  return tDOT2;
7341  }
7342  pushback(c);
7343  if (c != -1 && ISDIGIT(c)) {
7344  yyerror("no .<digit> floating literal anymore; put 0 before dot");
7345  }
7346  lex_state = EXPR_DOT;
7347  return '.';
7348 
7349  start_num:
7350  case '0': case '1': case '2': case '3': case '4':
7351  case '5': case '6': case '7': case '8': case '9':
7352  {
7353  int is_float, seen_point, seen_e, nondigit;
7354 
7355  is_float = seen_point = seen_e = nondigit = 0;
7356  lex_state = EXPR_END;
7357  newtok();
7358  if (c == '-' || c == '+') {
7359  tokadd(c);
7360  c = nextc();
7361  }
7362  if (c == '0') {
7363 #define no_digits() do {yyerror("numeric literal without digits"); return 0;} while (0)
7364  int start = toklen();
7365  c = nextc();
7366  if (c == 'x' || c == 'X') {
7367  /* hexadecimal */
7368  c = nextc();
7369  if (c != -1 && ISXDIGIT(c)) {
7370  do {
7371  if (c == '_') {
7372  if (nondigit) break;
7373  nondigit = c;
7374  continue;
7375  }
7376  if (!ISXDIGIT(c)) break;
7377  nondigit = 0;
7378  tokadd(c);
7379  } while ((c = nextc()) != -1);
7380  }
7381  pushback(c);
7382  tokfix();
7383  if (toklen() == start) {
7384  no_digits();
7385  }
7386  else if (nondigit) goto trailing_uc;
7388  return tINTEGER;
7389  }
7390  if (c == 'b' || c == 'B') {
7391  /* binary */
7392  c = nextc();
7393  if (c == '0' || c == '1') {
7394  do {
7395  if (c == '_') {
7396  if (nondigit) break;
7397  nondigit = c;
7398  continue;
7399  }
7400  if (c != '0' && c != '1') break;
7401  nondigit = 0;
7402  tokadd(c);
7403  } while ((c = nextc()) != -1);
7404  }
7405  pushback(c);
7406  tokfix();
7407  if (toklen() == start) {
7408  no_digits();
7409  }
7410  else if (nondigit) goto trailing_uc;
7412  return tINTEGER;
7413  }
7414  if (c == 'd' || c == 'D') {
7415  /* decimal */
7416  c = nextc();
7417  if (c != -1 && ISDIGIT(c)) {
7418  do {
7419  if (c == '_') {
7420  if (nondigit) break;
7421  nondigit = c;
7422  continue;
7423  }
7424  if (!ISDIGIT(c)) break;
7425  nondigit = 0;
7426  tokadd(c);
7427  } while ((c = nextc()) != -1);
7428  }
7429  pushback(c);
7430  tokfix();
7431  if (toklen() == start) {
7432  no_digits();
7433  }
7434  else if (nondigit) goto trailing_uc;
7436  return tINTEGER;
7437  }
7438  if (c == '_') {
7439  /* 0_0 */
7440  goto octal_number;
7441  }
7442  if (c == 'o' || c == 'O') {
7443  /* prefixed octal */
7444  c = nextc();
7445  if (c == -1 || c == '_' || !ISDIGIT(c)) {
7446  no_digits();
7447  }
7448  }
7449  if (c >= '0' && c <= '7') {
7450  /* octal */
7451  octal_number:
7452  do {
7453  if (c == '_') {
7454  if (nondigit) break;
7455  nondigit = c;
7456  continue;
7457  }
7458  if (c < '0' || c > '9') break;
7459  if (c > '7') goto invalid_octal;
7460  nondigit = 0;
7461  tokadd(c);
7462  } while ((c = nextc()) != -1);
7463  if (toklen() > start) {
7464  pushback(c);
7465  tokfix();
7466  if (nondigit) goto trailing_uc;
7468  return tINTEGER;
7469  }
7470  if (nondigit) {
7471  pushback(c);
7472  goto trailing_uc;
7473  }
7474  }
7475  if (c > '7' && c <= '9') {
7476  invalid_octal:
7477  yyerror("Invalid octal digit");
7478  }
7479  else if (c == '.' || c == 'e' || c == 'E') {
7480  tokadd('0');
7481  }
7482  else {
7483  pushback(c);
7485  return tINTEGER;
7486  }
7487  }
7488 
7489  for (;;) {
7490  switch (c) {
7491  case '0': case '1': case '2': case '3': case '4':
7492  case '5': case '6': case '7': case '8': case '9':
7493  nondigit = 0;
7494  tokadd(c);
7495  break;
7496 
7497  case '.':
7498  if (nondigit) goto trailing_uc;
7499  if (seen_point || seen_e) {
7500  goto decode_num;
7501  }
7502  else {
7503  int c0 = nextc();
7504  if (c0 == -1 || !ISDIGIT(c0)) {
7505  pushback(c0);
7506  goto decode_num;
7507  }
7508  c = c0;
7509  }
7510  tokadd('.');
7511  tokadd(c);
7512  is_float++;
7513  seen_point++;
7514  nondigit = 0;
7515  break;
7516 
7517  case 'e':
7518  case 'E':
7519  if (nondigit) {
7520  pushback(c);
7521  c = nondigit;
7522  goto decode_num;
7523  }
7524  if (seen_e) {
7525  goto decode_num;
7526  }
7527  tokadd(c);
7528  seen_e++;
7529  is_float++;
7530  nondigit = c;
7531  c = nextc();
7532  if (c != '-' && c != '+') continue;
7533  tokadd(c);
7534  nondigit = c;
7535  break;
7536 
7537  case '_': /* `_' in number just ignored */
7538  if (nondigit) goto decode_num;
7539  nondigit = c;
7540  break;
7541 
7542  default:
7543  goto decode_num;
7544  }
7545  c = nextc();
7546  }
7547 
7548  decode_num:
7549  pushback(c);
7550  if (nondigit) {
7551  char tmp[30];
7552  trailing_uc:
7553  snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
7554  yyerror(tmp);
7555  }
7556  tokfix();
7557  if (is_float) {
7558  double d = strtod(tok(), 0);
7559  if (errno == ERANGE) {
7560  rb_warningS("Float %s out of range", tok());
7561  errno = 0;
7562  }
7564  return tFLOAT;
7565  }
7567  return tINTEGER;
7568  }
7569 
7570  case ')':
7571  case ']':
7573  case '}':
7575  CMDARG_LEXPOP();
7576  if (c == ')')
7577  lex_state = EXPR_ENDFN;
7578  else
7579  lex_state = EXPR_ENDARG;
7580  if (c == '}') {
7581  if (!brace_nest--) c = tSTRING_DEND;
7582  }
7583  return c;
7584 
7585  case ':':
7586  c = nextc();
7587  if (c == ':') {
7588  if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
7589  lex_state = EXPR_BEG;
7590  return tCOLON3;
7591  }
7592  lex_state = EXPR_DOT;
7593  return tCOLON2;
7594  }
7595  if (IS_END() || ISSPACE(c)) {
7596  pushback(c);
7597  warn_balanced(":", "symbol literal");
7598  lex_state = EXPR_BEG;
7599  return ':';
7600  }
7601  switch (c) {
7602  case '\'':
7603  lex_strterm = NEW_STRTERM(str_ssym, c, 0);
7604  break;
7605  case '"':
7606  lex_strterm = NEW_STRTERM(str_dsym, c, 0);
7607  break;
7608  default:
7609  pushback(c);
7610  break;
7611  }
7612  lex_state = EXPR_FNAME;
7613  return tSYMBEG;
7614 
7615  case '/':
7616  if (IS_lex_state(EXPR_BEG_ANY)) {
7618  return tREGEXP_BEG;
7619  }
7620  if ((c = nextc()) == '=') {
7621  set_yylval_id('/');
7622  lex_state = EXPR_BEG;
7623  return tOP_ASGN;
7624  }
7625  pushback(c);
7626  if (IS_SPCARG(c)) {
7627  (void)arg_ambiguous();
7628  lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7629  return tREGEXP_BEG;
7630  }
7631  lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7632  warn_balanced("/", "regexp literal");
7633  return '/';
7634 
7635  case '^':
7636  if ((c = nextc()) == '=') {
7638  lex_state = EXPR_BEG;
7639  return tOP_ASGN;
7640  }
7641  lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7642  pushback(c);
7643  return '^';
7644 
7645  case ';':
7646  lex_state = EXPR_BEG;
7648  return ';';
7649 
7650  case ',':
7651  lex_state = EXPR_BEG;
7652  return ',';
7653 
7654  case '~':
7655  if (IS_AFTER_OPERATOR()) {
7656  if ((c = nextc()) != '@') {
7657  pushback(c);
7658  }
7659  lex_state = EXPR_ARG;
7660  }
7661  else {
7662  lex_state = EXPR_BEG;
7663  }
7664  return '~';
7665 
7666  case '(':
7667  if (IS_BEG()) {
7668  c = tLPAREN;
7669  }
7670  else if (IS_SPCARG(-1)) {
7671  c = tLPAREN_ARG;
7672  }
7673  paren_nest++;
7674  COND_PUSH(0);
7675  CMDARG_PUSH(0);
7676  lex_state = EXPR_BEG;
7677  return c;
7678 
7679  case '[':
7680  paren_nest++;
7681  if (IS_AFTER_OPERATOR()) {
7682  lex_state = EXPR_ARG;
7683  if ((c = nextc()) == ']') {
7684  if ((c = nextc()) == '=') {
7685  return tASET;
7686  }
7687  pushback(c);
7688  return tAREF;
7689  }
7690  pushback(c);
7691  return '[';
7692  }
7693  else if (IS_BEG()) {
7694  c = tLBRACK;
7695  }
7696  else if (IS_ARG() && space_seen) {
7697  c = tLBRACK;
7698  }
7699  lex_state = EXPR_BEG;
7700  COND_PUSH(0);
7701  CMDARG_PUSH(0);
7702  return c;
7703 
7704  case '{':
7705  ++brace_nest;
7706  if (lpar_beg && lpar_beg == paren_nest) {
7707  lex_state = EXPR_BEG;
7708  lpar_beg = 0;
7709  --paren_nest;
7710  COND_PUSH(0);
7711  CMDARG_PUSH(0);
7712  return tLAMBEG;
7713  }
7714  if (IS_ARG() || IS_lex_state(EXPR_END | EXPR_ENDFN))
7715  c = '{'; /* block (primary) */
7716  else if (IS_lex_state(EXPR_ENDARG))
7717  c = tLBRACE_ARG; /* block (expr) */
7718  else
7719  c = tLBRACE; /* hash */
7720  COND_PUSH(0);
7721  CMDARG_PUSH(0);
7722  lex_state = EXPR_BEG;
7723  if (c != tLBRACE) command_start = TRUE;
7724  return c;
7725 
7726  case '\\':
7727  c = nextc();
7728  if (c == '\n') {
7729  space_seen = 1;
7730 #ifdef RIPPER
7731  ripper_dispatch_scan_event(parser, tSP);
7732 #endif
7733  goto retry; /* skip \\n */
7734  }
7735  pushback(c);
7736  return '\\';
7737 
7738  case '%':
7739  if (IS_lex_state(EXPR_BEG_ANY)) {
7740  int term;
7741  int paren;
7742 
7743  c = nextc();
7744  quotation:
7745  if (c == -1 || !ISALNUM(c)) {
7746  term = c;
7747  c = 'Q';
7748  }
7749  else {
7750  term = nextc();
7751  if (rb_enc_isalnum(term, current_enc) || !parser_isascii()) {
7752  yyerror("unknown type of %string");
7753  return 0;
7754  }
7755  }
7756  if (c == -1 || term == -1) {
7757  compile_error(PARSER_ARG "unterminated quoted string meets end of file");
7758  return 0;
7759  }
7760  paren = term;
7761  if (term == '(') term = ')';
7762  else if (term == '[') term = ']';
7763  else if (term == '{') term = '}';
7764  else if (term == '<') term = '>';
7765  else paren = 0;
7766 
7767  switch (c) {
7768  case 'Q':
7769  lex_strterm = NEW_STRTERM(str_dquote, term, paren);
7770  return tSTRING_BEG;
7771 
7772  case 'q':
7773  lex_strterm = NEW_STRTERM(str_squote, term, paren);
7774  return tSTRING_BEG;
7775 
7776  case 'W':
7777  lex_strterm = NEW_STRTERM(str_dword, term, paren);
7778  do {c = nextc();} while (ISSPACE(c));
7779  pushback(c);
7780  return tWORDS_BEG;
7781 
7782  case 'w':
7783  lex_strterm = NEW_STRTERM(str_sword, term, paren);
7784  do {c = nextc();} while (ISSPACE(c));
7785  pushback(c);
7786  return tQWORDS_BEG;
7787 
7788  case 'I':
7789  lex_strterm = NEW_STRTERM(str_dword, term, paren);
7790  do {c = nextc();} while (ISSPACE(c));
7791  pushback(c);
7792  return tSYMBOLS_BEG;
7793 
7794  case 'i':
7795  lex_strterm = NEW_STRTERM(str_sword, term, paren);
7796  do {c = nextc();} while (ISSPACE(c));
7797  pushback(c);
7798  return tQSYMBOLS_BEG;
7799 
7800  case 'x':
7801  lex_strterm = NEW_STRTERM(str_xquote, term, paren);
7802  return tXSTRING_BEG;
7803 
7804  case 'r':
7805  lex_strterm = NEW_STRTERM(str_regexp, term, paren);
7806  return tREGEXP_BEG;
7807 
7808  case 's':
7809  lex_strterm = NEW_STRTERM(str_ssym, term, paren);
7810  lex_state = EXPR_FNAME;
7811  return tSYMBEG;
7812 
7813  default:
7814  yyerror("unknown type of %string");
7815  return 0;
7816  }
7817  }
7818  if ((c = nextc()) == '=') {
7819  set_yylval_id('%');
7820  lex_state = EXPR_BEG;
7821  return tOP_ASGN;
7822  }
7823  if (IS_SPCARG(c)) {
7824  goto quotation;
7825  }
7826  lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7827  pushback(c);
7828  warn_balanced("%%", "string literal");
7829  return '%';
7830 
7831  case '$':
7832  lex_state = EXPR_END;
7833  newtok();
7834  c = nextc();
7835  switch (c) {
7836  case '_': /* $_: last read line string */
7837  c = nextc();
7838  if (parser_is_identchar()) {
7839  tokadd('$');
7840  tokadd('_');
7841  break;
7842  }
7843  pushback(c);
7844  c = '_';
7845  /* fall through */
7846  case '~': /* $~: match-data */
7847  case '*': /* $*: argv */
7848  case '$': /* $$: pid */
7849  case '?': /* $?: last status */
7850  case '!': /* $!: error string */
7851  case '@': /* $@: error position */
7852  case '/': /* $/: input record separator */
7853  case '\\': /* $\: output record separator */
7854  case ';': /* $;: field separator */
7855  case ',': /* $,: output field separator */
7856  case '.': /* $.: last read line number */
7857  case '=': /* $=: ignorecase */
7858  case ':': /* $:: load path */
7859  case '<': /* $<: reading filename */
7860  case '>': /* $>: default output handle */
7861  case '\"': /* $": already loaded files */
7862  tokadd('$');
7863  tokadd(c);
7864  tokfix();
7866  return tGVAR;
7867 
7868  case '-':
7869  tokadd('$');
7870  tokadd(c);
7871  c = nextc();
7872  if (parser_is_identchar()) {
7873  if (tokadd_mbchar(c) == -1) return 0;
7874  }
7875  else {
7876  pushback(c);
7877  }
7878  gvar:
7879  tokfix();
7881  return tGVAR;
7882 
7883  case '&': /* $&: last match */
7884  case '`': /* $`: string before last match */
7885  case '\'': /* $': string after last match */
7886  case '+': /* $+: string matches last paren. */
7887  if (IS_lex_state_for(last_state, EXPR_FNAME)) {
7888  tokadd('$');
7889  tokadd(c);
7890  goto gvar;
7891  }
7893  return tBACK_REF;
7894 
7895  case '1': case '2': case '3':
7896  case '4': case '5': case '6':
7897  case '7': case '8': case '9':
7898  tokadd('$');
7899  do {
7900  tokadd(c);
7901  c = nextc();
7902  } while (c != -1 && ISDIGIT(c));
7903  pushback(c);
7904  if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
7905  tokfix();
7906  set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
7907  return tNTH_REF;
7908 
7909  default:
7910  if (!parser_is_identchar()) {
7911  pushback(c);
7912  compile_error(PARSER_ARG "`$%c' is not allowed as a global variable name", c);
7913  return 0;
7914  }
7915  case '0':
7916  tokadd('$');
7917  }
7918  break;
7919 
7920  case '@':
7921  c = nextc();
7922  newtok();
7923  tokadd('@');
7924  if (c == '@') {
7925  tokadd('@');
7926  c = nextc();
7927  }
7928  if (c != -1 && (ISDIGIT(c) || !parser_is_identchar())) {
7929  pushback(c);
7930  if (tokidx == 1) {
7931  compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
7932  }
7933  else {
7934  compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
7935  }
7936  return 0;
7937  }
7938  break;
7939 
7940  case '_':
7941  if (was_bol() && whole_match_p("__END__", 7, 0)) {
7942  ruby__end__seen = 1;
7943  parser->eofp = Qtrue;
7944 #ifndef RIPPER
7945  return -1;
7946 #else
7947  lex_goto_eol(parser);
7948  ripper_dispatch_scan_event(parser, k__END__);
7949  return 0;
7950 #endif
7951  }
7952  newtok();
7953  break;
7954 
7955  default:
7956  if (!parser_is_identchar()) {
7957  rb_compile_error(PARSER_ARG "Invalid char `\\x%02X' in expression", c);
7958  goto retry;
7959  }
7960 
7961  newtok();
7962  break;
7963  }
7964 
7965  mb = ENC_CODERANGE_7BIT;
7966  do {
7967  if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
7968  if (tokadd_mbchar(c) == -1) return 0;
7969  c = nextc();
7970  } while (parser_is_identchar());
7971  switch (tok()[0]) {
7972  case '@': case '$':
7973  pushback(c);
7974  break;
7975  default:
7976  if ((c == '!' || c == '?') && !peek('=')) {
7977  tokadd(c);
7978  }
7979  else {
7980  pushback(c);
7981  }
7982  }
7983  tokfix();
7984 
7985  {
7986  int result = 0;
7987 
7988  last_state = lex_state;
7989  switch (tok()[0]) {
7990  case '$':
7991  lex_state = EXPR_END;
7992  result = tGVAR;
7993  break;
7994  case '@':
7995  lex_state = EXPR_END;
7996  if (tok()[1] == '@')
7997  result = tCVAR;
7998  else
7999  result = tIVAR;
8000  break;
8001 
8002  default:
8003  if (toklast() == '!' || toklast() == '?') {
8004  result = tFID;
8005  }
8006  else {
8007  if (IS_lex_state(EXPR_FNAME)) {
8008  if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
8009  (!peek('=') || (peek_n('>', 1)))) {
8010  result = tIDENTIFIER;
8011  tokadd(c);
8012  tokfix();
8013  }
8014  else {
8015  pushback(c);
8016  }
8017  }
8018  if (result == 0 && ISUPPER(tok()[0])) {
8019  result = tCONSTANT;
8020  }
8021  else {
8022  result = tIDENTIFIER;
8023  }
8024  }
8025 
8026  if (IS_LABEL_POSSIBLE()) {
8027  if (IS_LABEL_SUFFIX(0)) {
8028  lex_state = EXPR_BEG;
8029  nextc();
8031  return tLABEL;
8032  }
8033  }
8034  if (mb == ENC_CODERANGE_7BIT && !IS_lex_state(EXPR_DOT)) {
8035  const struct kwtable *kw;
8036 
8037  /* See if it is a reserved word. */
8038  kw = rb_reserved_word(tok(), toklen());
8039  if (kw) {
8040  enum lex_state_e state = lex_state;
8041  lex_state = kw->state;
8042  if (state == EXPR_FNAME) {
8044  return kw->id[0];
8045  }
8046  if (lex_state == EXPR_BEG) {
8047  command_start = TRUE;
8048  }
8049  if (kw->id[0] == keyword_do) {
8050  if (lpar_beg && lpar_beg == paren_nest) {
8051  lpar_beg = 0;
8052  --paren_nest;
8053  return keyword_do_LAMBDA;
8054  }
8055  if (COND_P()) return keyword_do_cond;
8056  if (CMDARG_P() && state != EXPR_CMDARG)
8057  return keyword_do_block;
8058  if (state & (EXPR_BEG | EXPR_ENDARG))
8059  return keyword_do_block;
8060  return keyword_do;
8061  }
8062  if (state & (EXPR_BEG | EXPR_VALUE))
8063  return kw->id[0];
8064  else {
8065  if (kw->id[0] != kw->id[1])
8066  lex_state = EXPR_BEG;
8067  return kw->id[1];
8068  }
8069  }
8070  }
8071 
8072  if (IS_lex_state(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT)) {
8073  if (cmd_state) {
8074  lex_state = EXPR_CMDARG;
8075  }
8076  else {
8077  lex_state = EXPR_ARG;
8078  }
8079  }
8080  else if (lex_state == EXPR_FNAME) {
8081  lex_state = EXPR_ENDFN;
8082  }
8083  else {
8084  lex_state = EXPR_END;
8085  }
8086  }
8087  {
8088  ID ident = TOK_INTERN(!ENC_SINGLE(mb));
8089 
8090  set_yylval_name(ident);
8091  if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
8092  is_local_id(ident) && lvar_defined(ident)) {
8093  lex_state = EXPR_END;
8094  }
8095  }
8096  return result;
8097  }
8098 }
8099 
8100 #if YYPURE
8101 static int
8102 yylex(void *lval, void *p)
8103 #else
8104 yylex(void *p)
8105 #endif
8106 {
8107  struct parser_params *parser = (struct parser_params*)p;
8108  int t;
8109 
8110 #if YYPURE
8111  parser->parser_yylval = lval;
8112  parser->parser_yylval->val = Qundef;
8113 #endif
8114  t = parser_yylex(parser);
8115 #ifdef RIPPER
8116  if (!NIL_P(parser->delayed)) {
8117  ripper_dispatch_delayed_token(parser, t);
8118  return t;
8119  }
8120  if (t != 0)
8121  ripper_dispatch_scan_event(parser, t);
8122 #endif
8123 
8124  return t;
8125 }
8126 
8127 #ifndef RIPPER
8128 static NODE*
8129 node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
8130 {
8131  NODE *n = (rb_node_newnode)(type, a0, a1, a2);
8133  return n;
8134 }
8135 
8136 static enum node_type
8137 nodetype(NODE *node) /* for debug */
8138 {
8139  return (enum node_type)nd_type(node);
8140 }
8141 
8142 static int
8143 nodeline(NODE *node)
8144 {
8145  return nd_line(node);
8146 }
8147 
8148 static NODE*
8149 newline_node(NODE *node)
8150 {
8151  if (node) {
8152  node = remove_begin(node);
8153  node->flags |= NODE_FL_NEWLINE;
8154  }
8155  return node;
8156 }
8157 
8158 static void
8159 fixpos(NODE *node, NODE *orig)
8160 {
8161  if (!node) return;
8162  if (!orig) return;
8163  if (orig == (NODE*)1) return;
8164  nd_set_line(node, nd_line(orig));
8165 }
8166 
8167 static void
8168 parser_warning(struct parser_params *parser, NODE *node, const char *mesg)
8169 {
8170  rb_compile_warning(ruby_sourcefile, nd_line(node), "%s", mesg);
8171 }
8172 #define parser_warning(node, mesg) parser_warning(parser, (node), (mesg))
8173 
8174 static void
8175 parser_warn(struct parser_params *parser, NODE *node, const char *mesg)
8176 {
8177  rb_compile_warn(ruby_sourcefile, nd_line(node), "%s", mesg);
8178 }
8179 #define parser_warn(node, mesg) parser_warn(parser, (node), (mesg))
8180 
8181 static NODE*
8182 block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
8183 {
8184  NODE *end, *h = head, *nd;
8185 
8186  if (tail == 0) return head;
8187 
8188  if (h == 0) return tail;
8189  switch (nd_type(h)) {
8190  case NODE_LIT:
8191  case NODE_STR:
8192  case NODE_SELF:
8193  case NODE_TRUE:
8194  case NODE_FALSE:
8195  case NODE_NIL:
8196  parser_warning(h, "unused literal ignored");
8197  return tail;
8198  default:
8199  h = end = NEW_BLOCK(head);
8200  end->nd_end = end;
8201  fixpos(end, head);
8202  head = end;
8203  break;
8204  case NODE_BLOCK:
8205  end = h->nd_end;
8206  break;
8207  }
8208 
8209  nd = end->nd_head;
8210  switch (nd_type(nd)) {
8211  case NODE_RETURN:
8212  case NODE_BREAK:
8213  case NODE_NEXT:
8214  case NODE_REDO:
8215  case NODE_RETRY:
8216  if (RTEST(ruby_verbose)) {
8217  parser_warning(tail, "statement not reached");
8218  }
8219  break;
8220 
8221  default:
8222  break;
8223  }
8224 
8225  if (nd_type(tail) != NODE_BLOCK) {
8226  tail = NEW_BLOCK(tail);
8227  tail->nd_end = tail;
8228  }
8229  end->nd_next = tail;
8230  h->nd_end = tail->nd_end;
8231  return head;
8232 }
8233 
8234 /* append item to the list */
8235 static NODE*
8236 list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
8237 {
8238  NODE *last;
8239 
8240  if (list == 0) return NEW_LIST(item);
8241  if (list->nd_next) {
8242  last = list->nd_next->nd_end;
8243  }
8244  else {
8245  last = list;
8246  }
8247 
8248  list->nd_alen += 1;
8249  last->nd_next = NEW_LIST(item);
8250  list->nd_next->nd_end = last->nd_next;
8251  return list;
8252 }
8253 
8254 /* concat two lists */
8255 static NODE*
8256 list_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
8257 {
8258  NODE *last;
8259 
8260  if (head->nd_next) {
8261  last = head->nd_next->nd_end;
8262  }
8263  else {
8264  last = head;
8265  }
8266 
8267  head->nd_alen += tail->nd_alen;
8268  last->nd_next = tail;
8269  if (tail->nd_next) {
8270  head->nd_next->nd_end = tail->nd_next->nd_end;
8271  }
8272  else {
8273  head->nd_next->nd_end = tail;
8274  }
8275 
8276  return head;
8277 }
8278 
8279 static int
8280 literal_concat0(struct parser_params *parser, VALUE head, VALUE tail)
8281 {
8282  if (NIL_P(tail)) return 1;
8283  if (!rb_enc_compatible(head, tail)) {
8284  compile_error(PARSER_ARG "string literal encodings differ (%s / %s)",
8285  rb_enc_name(rb_enc_get(head)),
8286  rb_enc_name(rb_enc_get(tail)));
8287  rb_str_resize(head, 0);
8288  rb_str_resize(tail, 0);
8289  return 0;
8290  }
8291  rb_str_buf_append(head, tail);
8292  return 1;
8293 }
8294 
8295 /* concat two string literals */
8296 static NODE *
8297 literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
8298 {
8299  enum node_type htype;
8300  NODE *headlast;
8301  VALUE lit;
8302 
8303  if (!head) return tail;
8304  if (!tail) return head;
8305 
8306  htype = nd_type(head);
8307  if (htype == NODE_EVSTR) {
8308  NODE *node = NEW_DSTR(Qnil);
8309  head = list_append(node, head);
8310  htype = NODE_DSTR;
8311  }
8312  switch (nd_type(tail)) {
8313  case NODE_STR:
8314  if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
8315  nd_type(headlast) == NODE_STR) {
8316  htype = NODE_STR;
8317  lit = headlast->nd_lit;
8318  }
8319  else {
8320  lit = head->nd_lit;
8321  }
8322  if (htype == NODE_STR) {
8323  if (!literal_concat0(parser, lit, tail->nd_lit)) {
8324  error:
8325  rb_gc_force_recycle((VALUE)head);
8326  rb_gc_force_recycle((VALUE)tail);
8327  return 0;
8328  }
8329  rb_gc_force_recycle((VALUE)tail);
8330  }
8331  else {
8332  list_append(head, tail);
8333  }
8334  break;
8335 
8336  case NODE_DSTR:
8337  if (htype == NODE_STR) {
8338  if (!literal_concat0(parser, head->nd_lit, tail->nd_lit))
8339  goto error;
8340  tail->nd_lit = head->nd_lit;
8341  rb_gc_force_recycle((VALUE)head);
8342  head = tail;
8343  }
8344  else if (NIL_P(tail->nd_lit)) {
8345  append:
8346  head->nd_alen += tail->nd_alen - 1;
8347  head->nd_next->nd_end->nd_next = tail->nd_next;
8348  head->nd_next->nd_end = tail->nd_next->nd_end;
8349  rb_gc_force_recycle((VALUE)tail);
8350  }
8351  else if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
8352  nd_type(headlast) == NODE_STR) {
8353  lit = headlast->nd_lit;
8354  if (!literal_concat0(parser, lit, tail->nd_lit))
8355  goto error;
8356  tail->nd_lit = Qnil;
8357  goto append;
8358  }
8359  else {
8360  nd_set_type(tail, NODE_ARRAY);
8361  tail->nd_head = NEW_STR(tail->nd_lit);
8362  list_concat(head, tail);
8363  }
8364  break;
8365 
8366  case NODE_EVSTR:
8367  if (htype == NODE_STR) {
8368  nd_set_type(head, NODE_DSTR);
8369  head->nd_alen = 1;
8370  }
8371  list_append(head, tail);
8372  break;
8373  }
8374  return head;
8375 }
8376 
8377 static NODE *
8378 evstr2dstr_gen(struct parser_params *parser, NODE *node)
8379 {
8380  if (nd_type(node) == NODE_EVSTR) {
8381  node = list_append(NEW_DSTR(Qnil), node);
8382  }
8383  return node;
8384 }
8385 
8386 static NODE *
8387 new_evstr_gen(struct parser_params *parser, NODE *node)
8388 {
8389  NODE *head = node;
8390 
8391  if (node) {
8392  switch (nd_type(node)) {
8393  case NODE_STR: case NODE_DSTR: case NODE_EVSTR:
8394  return node;
8395  }
8396  }
8397  return NEW_EVSTR(head);
8398 }
8399 
8400 static NODE *
8401 call_bin_op_gen(struct parser_params *parser, NODE *recv, ID id, NODE *arg1)
8402 {
8403  value_expr(recv);
8404  value_expr(arg1);
8405  return NEW_CALL(recv, id, NEW_LIST(arg1));
8406 }
8407 
8408 static NODE *
8409 call_uni_op_gen(struct parser_params *parser, NODE *recv, ID id)
8410 {
8411  value_expr(recv);
8412  return NEW_CALL(recv, id, 0);
8413 }
8414 
8415 static NODE*
8416 match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8417 {
8418  value_expr(node1);
8419  value_expr(node2);
8420  if (node1) {
8421  switch (nd_type(node1)) {
8422  case NODE_DREGX:
8423  case NODE_DREGX_ONCE:
8424  return NEW_MATCH2(node1, node2);
8425 
8426  case NODE_LIT:
8427  if (RB_TYPE_P(node1->nd_lit, T_REGEXP)) {
8428  return NEW_MATCH2(node1, node2);
8429  }
8430  }
8431  }
8432 
8433  if (node2) {
8434  switch (nd_type(node2)) {
8435  case NODE_DREGX:
8436  case NODE_DREGX_ONCE:
8437  return NEW_MATCH3(node2, node1);
8438 
8439  case NODE_LIT:
8440  if (RB_TYPE_P(node2->nd_lit, T_REGEXP)) {
8441  return NEW_MATCH3(node2, node1);
8442  }
8443  }
8444  }
8445 
8446  return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
8447 }
8448 
8449 static NODE*
8450 gettable_gen(struct parser_params *parser, ID id)
8451 {
8452  switch (id) {
8453  case keyword_self:
8454  return NEW_SELF();
8455  case keyword_nil:
8456  return NEW_NIL();
8457  case keyword_true:
8458  return NEW_TRUE();
8459  case keyword_false:
8460  return NEW_FALSE();
8461  case keyword__FILE__:
8464  case keyword__LINE__:
8465  return NEW_LIT(INT2FIX(tokline));
8466  case keyword__ENCODING__:
8468  }
8469  switch (id_type(id)) {
8470  case ID_LOCAL:
8471  if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id);
8472  if (local_id(id)) return NEW_LVAR(id);
8473  /* method call without arguments */
8474  return NEW_VCALL(id);
8475  case ID_GLOBAL:
8476  return NEW_GVAR(id);
8477  case ID_INSTANCE:
8478  return NEW_IVAR(id);
8479  case ID_CONST:
8480  return NEW_CONST(id);
8481  case ID_CLASS:
8482  return NEW_CVAR(id);
8483  }
8484  compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
8485  return 0;
8486 }
8487 #else /* !RIPPER */
8488 static int
8489 id_is_var_gen(struct parser_params *parser, ID id)
8490 {
8491  if (is_notop_id(id)) {
8492  switch (id & ID_SCOPE_MASK) {
8493  case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
8494  return 1;
8495  case ID_LOCAL:
8496  if (dyna_in_block() && dvar_defined(id)) return 1;
8497  if (local_id(id)) return 1;
8498  /* method call without arguments */
8499  return 0;
8500  }
8501  }
8502  compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
8503  return 0;
8504 }
8505 #endif /* !RIPPER */
8506 
8507 #if PARSER_DEBUG
8508 static const char *
8509 lex_state_name(enum lex_state_e state)
8510 {
8511  static const char names[][12] = {
8512  "EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
8513  "EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
8514  "EXPR_VALUE",
8515  };
8516 
8517  if ((unsigned)state & ~(~0u << EXPR_MAX_STATE))
8518  return names[ffs(state)];
8519  return NULL;
8520 }
8521 #endif
8522 
8523 #ifdef RIPPER
8524 static VALUE
8525 assignable_gen(struct parser_params *parser, VALUE lhs)
8526 #else
8527 static NODE*
8528 assignable_gen(struct parser_params *parser, ID id, NODE *val)
8529 #endif
8530 {
8531 #ifdef RIPPER
8532  ID id = get_id(lhs);
8533 # define assignable_result(x) get_value(lhs)
8534 # define parser_yyerror(parser, x) dispatch1(assign_error, lhs)
8535 #else
8536 # define assignable_result(x) (x)
8537 #endif
8538  if (!id) return assignable_result(0);
8539  switch (id) {
8540  case keyword_self:
8541  yyerror("Can't change the value of self");
8542  goto error;
8543  case keyword_nil:
8544  yyerror("Can't assign to nil");
8545  goto error;
8546  case keyword_true:
8547  yyerror("Can't assign to true");
8548  goto error;
8549  case keyword_false:
8550  yyerror("Can't assign to false");
8551  goto error;
8552  case keyword__FILE__:
8553  yyerror("Can't assign to __FILE__");
8554  goto error;
8555  case keyword__LINE__:
8556  yyerror("Can't assign to __LINE__");
8557  goto error;
8558  case keyword__ENCODING__:
8559  yyerror("Can't assign to __ENCODING__");
8560  goto error;
8561  }
8562  switch (id_type(id)) {
8563  case ID_LOCAL:
8564  if (dyna_in_block()) {
8565  if (dvar_curr(id)) {
8566  return assignable_result(NEW_DASGN_CURR(id, val));
8567  }
8568  else if (dvar_defined(id)) {
8569  return assignable_result(NEW_DASGN(id, val));
8570  }
8571  else if (local_id(id)) {
8572  return assignable_result(NEW_LASGN(id, val));
8573  }
8574  else {
8575  dyna_var(id);
8576  return assignable_result(NEW_DASGN_CURR(id, val));
8577  }
8578  }
8579  else {
8580  if (!local_id(id)) {
8581  local_var(id);
8582  }
8583  return assignable_result(NEW_LASGN(id, val));
8584  }
8585  break;
8586  case ID_GLOBAL:
8587  return assignable_result(NEW_GASGN(id, val));
8588  case ID_INSTANCE:
8589  return assignable_result(NEW_IASGN(id, val));
8590  case ID_CONST:
8591  if (!in_def && !in_single)
8592  return assignable_result(NEW_CDECL(id, val, 0));
8593  yyerror("dynamic constant assignment");
8594  break;
8595  case ID_CLASS:
8596  return assignable_result(NEW_CVASGN(id, val));
8597  default:
8598  compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
8599  }
8600  error:
8601  return assignable_result(0);
8602 #undef assignable_result
8603 #undef parser_yyerror
8604 }
8605 
8606 static int
8607 is_private_local_id(ID name)
8608 {
8609  VALUE s;
8610  if (name == idUScore) return 1;
8611  if (!is_local_id(name)) return 0;
8612  s = rb_id2str(name);
8613  if (!s) return 0;
8614  return RSTRING_PTR(s)[0] == '_';
8615 }
8616 
8617 #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
8618 
8619 static ID
8620 shadowing_lvar_gen(struct parser_params *parser, ID name)
8621 {
8622  if (is_private_local_id(name)) return name;
8623  if (dyna_in_block()) {
8624  if (dvar_curr(name)) {
8625  yyerror("duplicated argument name");
8626  }
8627  else if (dvar_defined_get(name) || local_id(name)) {
8628  rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
8629  vtable_add(lvtbl->vars, name);
8630  if (lvtbl->used) {
8632  }
8633  }
8634  }
8635  else {
8636  if (local_id(name)) {
8637  yyerror("duplicated argument name");
8638  }
8639  }
8640  return name;
8641 }
8642 
8643 static void
8644 new_bv_gen(struct parser_params *parser, ID name)
8645 {
8646  if (!name) return;
8647  if (!is_local_id(name)) {
8648  compile_error(PARSER_ARG "invalid local variable - %s",
8649  rb_id2name(name));
8650  return;
8651  }
8652  shadowing_lvar(name);
8653  dyna_var(name);
8654 }
8655 
8656 #ifndef RIPPER
8657 static NODE *
8658 aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
8659 {
8660  if (recv && nd_type(recv) == NODE_SELF)
8661  recv = (NODE *)1;
8662  return NEW_ATTRASGN(recv, tASET, idx);
8663 }
8664 
8665 static void
8666 block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8667 {
8668  if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
8669  compile_error(PARSER_ARG "both block arg and actual block given");
8670  }
8671 }
8672 
8673 ID
8674 rb_id_attrset(ID id)
8675 {
8676  id &= ~ID_SCOPE_MASK;
8677  id |= ID_ATTRSET;
8678  return id;
8679 }
8680 
8681 static NODE *
8682 attrset_gen(struct parser_params *parser, NODE *recv, ID id)
8683 {
8684  if (recv && nd_type(recv) == NODE_SELF)
8685  recv = (NODE *)1;
8686  return NEW_ATTRASGN(recv, rb_id_attrset(id), 0);
8687 }
8688 
8689 static void
8690 rb_backref_error_gen(struct parser_params *parser, NODE *node)
8691 {
8692  switch (nd_type(node)) {
8693  case NODE_NTH_REF:
8694  compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
8695  break;
8696  case NODE_BACK_REF:
8697  compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
8698  break;
8699  }
8700 }
8701 
8702 static NODE *
8703 arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8704 {
8705  if (!node2) return node1;
8706  switch (nd_type(node1)) {
8707  case NODE_BLOCK_PASS:
8708  if (node1->nd_head)
8709  node1->nd_head = arg_concat(node1->nd_head, node2);
8710  else
8711  node1->nd_head = NEW_LIST(node2);
8712  return node1;
8713  case NODE_ARGSPUSH:
8714  if (nd_type(node2) != NODE_ARRAY) break;
8715  node1->nd_body = list_concat(NEW_LIST(node1->nd_body), node2);
8716  nd_set_type(node1, NODE_ARGSCAT);
8717  return node1;
8718  case NODE_ARGSCAT:
8719  if (nd_type(node2) != NODE_ARRAY ||
8720  nd_type(node1->nd_body) != NODE_ARRAY) break;
8721  node1->nd_body = list_concat(node1->nd_body, node2);
8722  return node1;
8723  }
8724  return NEW_ARGSCAT(node1, node2);
8725 }
8726 
8727 static NODE *
8728 arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8729 {
8730  if (!node1) return NEW_LIST(node2);
8731  switch (nd_type(node1)) {
8732  case NODE_ARRAY:
8733  return list_append(node1, node2);
8734  case NODE_BLOCK_PASS:
8735  node1->nd_head = arg_append(node1->nd_head, node2);
8736  return node1;
8737  case NODE_ARGSPUSH:
8738  node1->nd_body = list_append(NEW_LIST(node1->nd_body), node2);
8739  nd_set_type(node1, NODE_ARGSCAT);
8740  return node1;
8741  }
8742  return NEW_ARGSPUSH(node1, node2);
8743 }
8744 
8745 static NODE *
8746 splat_array(NODE* node)
8747 {
8748  if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
8749  if (nd_type(node) == NODE_ARRAY) return node;
8750  return 0;
8751 }
8752 
8753 static NODE *
8754 node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
8755 {
8756  if (!lhs) return 0;
8757 
8758  switch (nd_type(lhs)) {
8759  case NODE_GASGN:
8760  case NODE_IASGN:
8761  case NODE_IASGN2:
8762  case NODE_LASGN:
8763  case NODE_DASGN:
8764  case NODE_DASGN_CURR:
8765  case NODE_MASGN:
8766  case NODE_CDECL:
8767  case NODE_CVASGN:
8768  lhs->nd_value = rhs;
8769  break;
8770 
8771  case NODE_ATTRASGN:
8772  case NODE_CALL:
8773  lhs->nd_args = arg_append(lhs->nd_args, rhs);
8774  break;
8775 
8776  default:
8777  /* should not happen */
8778  break;
8779  }
8780 
8781  return lhs;
8782 }
8783 
8784 static int
8785 value_expr_gen(struct parser_params *parser, NODE *node)
8786 {
8787  int cond = 0;
8788 
8789  if (!node) {
8790  rb_warning0("empty expression");
8791  }
8792  while (node) {
8793  switch (nd_type(node)) {
8794  case NODE_DEFN:
8795  case NODE_DEFS:
8796  parser_warning(node, "void value expression");
8797  return FALSE;
8798 
8799  case NODE_RETURN:
8800  case NODE_BREAK:
8801  case NODE_NEXT:
8802  case NODE_REDO:
8803  case NODE_RETRY:
8804  if (!cond) yyerror("void value expression");
8805  /* or "control never reach"? */
8806  return FALSE;
8807 
8808  case NODE_BLOCK:
8809  while (node->nd_next) {
8810  node = node->nd_next;
8811  }
8812  node = node->nd_head;
8813  break;
8814 
8815  case NODE_BEGIN:
8816  node = node->nd_body;
8817  break;
8818 
8819  case NODE_IF:
8820  if (!node->nd_body) {
8821  node = node->nd_else;
8822  break;
8823  }
8824  else if (!node->nd_else) {
8825  node = node->nd_body;
8826  break;
8827  }
8828  if (!value_expr(node->nd_body)) return FALSE;
8829  node = node->nd_else;
8830  break;
8831 
8832  case NODE_AND:
8833  case NODE_OR:
8834  cond = 1;
8835  node = node->nd_2nd;
8836  break;
8837 
8838  default:
8839  return TRUE;
8840  }
8841  }
8842 
8843  return TRUE;
8844 }
8845 
8846 static void
8847 void_expr_gen(struct parser_params *parser, NODE *node)
8848 {
8849  const char *useless = 0;
8850 
8851  if (!RTEST(ruby_verbose)) return;
8852 
8853  if (!node) return;
8854  switch (nd_type(node)) {
8855  case NODE_CALL:
8856  switch (node->nd_mid) {
8857  case '+':
8858  case '-':
8859  case '*':
8860  case '/':
8861  case '%':
8862  case tPOW:
8863  case tUPLUS:
8864  case tUMINUS:
8865  case '|':
8866  case '^':
8867  case '&':
8868  case tCMP:
8869  case '>':
8870  case tGEQ:
8871  case '<':
8872  case tLEQ:
8873  case tEQ:
8874  case tNEQ:
8875  useless = rb_id2name(node->nd_mid);
8876  break;
8877  }
8878  break;
8879 
8880  case NODE_LVAR:
8881  case NODE_DVAR:
8882  case NODE_GVAR:
8883  case NODE_IVAR:
8884  case NODE_CVAR:
8885  case NODE_NTH_REF:
8886  case NODE_BACK_REF:
8887  useless = "a variable";
8888  break;
8889  case NODE_CONST:
8890  useless = "a constant";
8891  break;
8892  case NODE_LIT:
8893  case NODE_STR:
8894  case NODE_DSTR:
8895  case NODE_DREGX:
8896  case NODE_DREGX_ONCE:
8897  useless = "a literal";
8898  break;
8899  case NODE_COLON2:
8900  case NODE_COLON3:
8901  useless = "::";
8902  break;
8903  case NODE_DOT2:
8904  useless = "..";
8905  break;
8906  case NODE_DOT3:
8907  useless = "...";
8908  break;
8909  case NODE_SELF:
8910  useless = "self";
8911  break;
8912  case NODE_NIL:
8913  useless = "nil";
8914  break;
8915  case NODE_TRUE:
8916  useless = "true";
8917  break;
8918  case NODE_FALSE:
8919  useless = "false";
8920  break;
8921  case NODE_DEFINED:
8922  useless = "defined?";
8923  break;
8924  }
8925 
8926  if (useless) {
8927  int line = ruby_sourceline;
8928 
8929  ruby_sourceline = nd_line(node);
8930  rb_warnS("possibly useless use of %s in void context", useless);
8931  ruby_sourceline = line;
8932  }
8933 }
8934 
8935 static void
8936 void_stmts_gen(struct parser_params *parser, NODE *node)
8937 {
8938  if (!RTEST(ruby_verbose)) return;
8939  if (!node) return;
8940  if (nd_type(node) != NODE_BLOCK) return;
8941 
8942  for (;;) {
8943  if (!node->nd_next) return;
8944  void_expr0(node->nd_head);
8945  node = node->nd_next;
8946  }
8947 }
8948 
8949 static NODE *
8950 remove_begin(NODE *node)
8951 {
8952  NODE **n = &node, *n1 = node;
8953  while (n1 && nd_type(n1) == NODE_BEGIN && n1->nd_body) {
8954  *n = n1 = n1->nd_body;
8955  }
8956  return node;
8957 }
8958 
8959 static void
8960 reduce_nodes_gen(struct parser_params *parser, NODE **body)
8961 {
8962  NODE *node = *body;
8963 
8964  if (!node) {
8965  *body = NEW_NIL();
8966  return;
8967  }
8968 #define subnodes(n1, n2) \
8969  ((!node->n1) ? (node->n2 ? (body = &node->n2, 1) : 0) : \
8970  (!node->n2) ? (body = &node->n1, 1) : \
8971  (reduce_nodes(&node->n1), body = &node->n2, 1))
8972 
8973  while (node) {
8974  int newline = (int)(node->flags & NODE_FL_NEWLINE);
8975  switch (nd_type(node)) {
8976  end:
8977  case NODE_NIL:
8978  *body = 0;
8979  return;
8980  case NODE_RETURN:
8981  *body = node = node->nd_stts;
8982  if (newline && node) node->flags |= NODE_FL_NEWLINE;
8983  continue;
8984  case NODE_BEGIN:
8985  *body = node = node->nd_body;
8986  if (newline && node) node->flags |= NODE_FL_NEWLINE;
8987  continue;
8988  case NODE_BLOCK:
8989  body = &node->nd_end->nd_head;
8990  break;
8991  case NODE_IF:
8992  if (subnodes(nd_body, nd_else)) break;
8993  return;
8994  case NODE_CASE:
8995  body = &node->nd_body;
8996  break;
8997  case NODE_WHEN:
8998  if (!subnodes(nd_body, nd_next)) goto end;
8999  break;
9000  case NODE_ENSURE:
9001  if (!subnodes(nd_head, nd_resq)) goto end;
9002  break;
9003  case NODE_RESCUE:
9004  if (node->nd_else) {
9005  body = &node->nd_resq;
9006  break;
9007  }
9008  if (!subnodes(nd_head, nd_resq)) goto end;
9009  break;
9010  default:
9011  return;
9012  }
9013  node = *body;
9014  if (newline && node) node->flags |= NODE_FL_NEWLINE;
9015  }
9016 
9017 #undef subnodes
9018 }
9019 
9020 static int
9021 is_static_content(NODE *node)
9022 {
9023  if (!node) return 1;
9024  switch (nd_type(node)) {
9025  case NODE_HASH:
9026  if (!(node = node->nd_head)) break;
9027  case NODE_ARRAY:
9028  do {
9029  if (!is_static_content(node->nd_head)) return 0;
9030  } while ((node = node->nd_next) != 0);
9031  case NODE_LIT:
9032  case NODE_STR:
9033  case NODE_NIL:
9034  case NODE_TRUE:
9035  case NODE_FALSE:
9036  case NODE_ZARRAY:
9037  break;
9038  default:
9039  return 0;
9040  }
9041  return 1;
9042 }
9043 
9044 static int
9045 assign_in_cond(struct parser_params *parser, NODE *node)
9046 {
9047  switch (nd_type(node)) {
9048  case NODE_MASGN:
9049  yyerror("multiple assignment in conditional");
9050  return 1;
9051 
9052  case NODE_LASGN:
9053  case NODE_DASGN:
9054  case NODE_DASGN_CURR:
9055  case NODE_GASGN:
9056  case NODE_IASGN:
9057  break;
9058 
9059  default:
9060  return 0;
9061  }
9062 
9063  if (!node->nd_value) return 1;
9064  if (is_static_content(node->nd_value)) {
9065  /* reports always */
9066  parser_warn(node->nd_value, "found = in conditional, should be ==");
9067  }
9068  return 1;
9069 }
9070 
9071 static void
9072 warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
9073 {
9074  if (!e_option_supplied(parser)) parser_warn(node, str);
9075 }
9076 
9077 static void
9078 warning_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
9079 {
9080  if (!e_option_supplied(parser)) parser_warning(node, str);
9081 }
9082 
9083 static void
9084 fixup_nodes(NODE **rootnode)
9085 {
9086  NODE *node, *next, *head;
9087 
9088  for (node = *rootnode; node; node = next) {
9089  enum node_type type;
9090  VALUE val;
9091 
9092  next = node->nd_next;
9093  head = node->nd_head;
9094  rb_gc_force_recycle((VALUE)node);
9095  *rootnode = next;
9096  switch (type = nd_type(head)) {
9097  case NODE_DOT2:
9098  case NODE_DOT3:
9099  val = rb_range_new(head->nd_beg->nd_lit, head->nd_end->nd_lit,
9100  type == NODE_DOT3);
9101  rb_gc_force_recycle((VALUE)head->nd_beg);
9102  rb_gc_force_recycle((VALUE)head->nd_end);
9103  nd_set_type(head, NODE_LIT);
9104  head->nd_lit = val;
9105  break;
9106  default:
9107  break;
9108  }
9109  }
9110 }
9111 
9112 static NODE *cond0(struct parser_params*,NODE*);
9113 
9114 static NODE*
9115 range_op(struct parser_params *parser, NODE *node)
9116 {
9117  enum node_type type;
9118 
9119  if (node == 0) return 0;
9120 
9121  type = nd_type(node);
9122  value_expr(node);
9123  if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
9124  warn_unless_e_option(parser, node, "integer literal in conditional range");
9125  return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."))));
9126  }
9127  return cond0(parser, node);
9128 }
9129 
9130 static int
9131 literal_node(NODE *node)
9132 {
9133  if (!node) return 1; /* same as NODE_NIL */
9134  switch (nd_type(node)) {
9135  case NODE_LIT:
9136  case NODE_STR:
9137  case NODE_DSTR:
9138  case NODE_EVSTR:
9139  case NODE_DREGX:
9140  case NODE_DREGX_ONCE:
9141  case NODE_DSYM:
9142  return 2;
9143  case NODE_TRUE:
9144  case NODE_FALSE:
9145  case NODE_NIL:
9146  return 1;
9147  }
9148  return 0;
9149 }
9150 
9151 static NODE*
9152 cond0(struct parser_params *parser, NODE *node)
9153 {
9154  if (node == 0) return 0;
9155  assign_in_cond(parser, node);
9156 
9157  switch (nd_type(node)) {
9158  case NODE_DSTR:
9159  case NODE_EVSTR:
9160  case NODE_STR:
9161  rb_warn0("string literal in condition");
9162  break;
9163 
9164  case NODE_DREGX:
9165  case NODE_DREGX_ONCE:
9166  warning_unless_e_option(parser, node, "regex literal in condition");
9167  return NEW_MATCH2(node, NEW_GVAR(rb_intern("$_")));
9168 
9169  case NODE_AND:
9170  case NODE_OR:
9171  node->nd_1st = cond0(parser, node->nd_1st);
9172  node->nd_2nd = cond0(parser, node->nd_2nd);
9173  break;
9174 
9175  case NODE_DOT2:
9176  case NODE_DOT3:
9177  node->nd_beg = range_op(parser, node->nd_beg);
9178  node->nd_end = range_op(parser, node->nd_end);
9179  if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
9180  else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
9181  if (!e_option_supplied(parser)) {
9182  int b = literal_node(node->nd_beg);
9183  int e = literal_node(node->nd_end);
9184  if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
9185  parser_warn(node, "range literal in condition");
9186  }
9187  }
9188  break;
9189 
9190  case NODE_DSYM:
9191  parser_warning(node, "literal in condition");
9192  break;
9193 
9194  case NODE_LIT:
9195  if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
9196  warn_unless_e_option(parser, node, "regex literal in condition");
9197  nd_set_type(node, NODE_MATCH);
9198  }
9199  else {
9200  parser_warning(node, "literal in condition");
9201  }
9202  default:
9203  break;
9204  }
9205  return node;
9206 }
9207 
9208 static NODE*
9209 cond_gen(struct parser_params *parser, NODE *node)
9210 {
9211  if (node == 0) return 0;
9212  return cond0(parser, node);
9213 }
9214 
9215 static NODE*
9216 logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *right)
9217 {
9218  value_expr(left);
9219  if (left && (enum node_type)nd_type(left) == type) {
9220  NODE *node = left, *second;
9221  while ((second = node->nd_2nd) != 0 && (enum node_type)nd_type(second) == type) {
9222  node = second;
9223  }
9224  node->nd_2nd = NEW_NODE(type, second, right, 0);
9225  return left;
9226  }
9227  return NEW_NODE(type, left, right, 0);
9228 }
9229 
9230 static void
9231 no_blockarg(struct parser_params *parser, NODE *node)
9232 {
9233  if (node && nd_type(node) == NODE_BLOCK_PASS) {
9234  compile_error(PARSER_ARG "block argument should not be given");
9235  }
9236 }
9237 
9238 static NODE *
9239 ret_args_gen(struct parser_params *parser, NODE *node)
9240 {
9241  if (node) {
9242  no_blockarg(parser, node);
9243  if (nd_type(node) == NODE_ARRAY) {
9244  if (node->nd_next == 0) {
9245  node = node->nd_head;
9246  }
9247  else {
9248  nd_set_type(node, NODE_VALUES);
9249  }
9250  }
9251  }
9252  return node;
9253 }
9254 
9255 static NODE *
9256 new_yield_gen(struct parser_params *parser, NODE *node)
9257 {
9258  if (node) no_blockarg(parser, node);
9259 
9260  return NEW_YIELD(node);
9261 }
9262 
9263 static NODE*
9264 negate_lit(NODE *node)
9265 {
9266  switch (TYPE(node->nd_lit)) {
9267  case T_FIXNUM:
9268  node->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit));
9269  break;
9270  case T_BIGNUM:
9271  node->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0);
9272  break;
9273  case T_FLOAT:
9274 #if USE_FLONUM
9275  if (FLONUM_P(node->nd_lit)) {
9276  node->nd_lit = DBL2NUM(-RFLOAT_VALUE(node->nd_lit));
9277  }
9278  else {
9279  RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
9280  }
9281 #else
9282  RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
9283 #endif
9284  break;
9285  default:
9286  break;
9287  }
9288  return node;
9289 }
9290 
9291 static NODE *
9292 arg_blk_pass(NODE *node1, NODE *node2)
9293 {
9294  if (node2) {
9295  node2->nd_head = node1;
9296  return node2;
9297  }
9298  return node1;
9299 }
9300 
9301 
9302 static NODE*
9303 new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, NODE *tail)
9304 {
9305  int saved_line = ruby_sourceline;
9306  struct rb_args_info *args = tail->nd_ainfo;
9307 
9308  args->pre_args_num = m ? rb_long2int(m->nd_plen) : 0;
9309  args->pre_init = m ? m->nd_next : 0;
9310 
9311  args->post_args_num = p ? rb_long2int(p->nd_plen) : 0;
9312  args->post_init = p ? p->nd_next : 0;
9313  args->first_post_arg = p ? p->nd_pid : 0;
9314 
9315  args->rest_arg = r;
9316 
9317  args->opt_args = o;
9318 
9319  ruby_sourceline = saved_line;
9320 
9321  return tail;
9322 }
9323 
9324 static NODE*
9325 new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
9326 {
9327  int saved_line = ruby_sourceline;
9328  struct rb_args_info *args;
9329  NODE *kw_rest_arg = 0;
9330  NODE *node;
9331 
9332  args = ALLOC(struct rb_args_info);
9333  MEMZERO(args, struct rb_args_info, 1);
9334  node = NEW_NODE(NODE_ARGS, 0, 0, args);
9335 
9336  args->block_arg = b;
9337  args->kw_args = k;
9338  if (k && !kr) kr = internal_id();
9339  if (kr) {
9340  arg_var(kr);
9341  kw_rest_arg = NEW_DVAR(kr);
9342  }
9343  args->kw_rest_arg = kw_rest_arg;
9344 
9345  ruby_sourceline = saved_line;
9346  return node;
9347 }
9348 
9349 static NODE*
9350 dsym_node_gen(struct parser_params *parser, NODE *node)
9351 {
9352  VALUE lit;
9353 
9354  if (!node) {
9355  return NEW_LIT(ID2SYM(idNULL));
9356  }
9357 
9358  switch (nd_type(node)) {
9359  case NODE_DSTR:
9360  nd_set_type(node, NODE_DSYM);
9361  break;
9362  case NODE_STR:
9363  lit = node->nd_lit;
9364  node->nd_lit = ID2SYM(rb_intern_str(lit));
9365  nd_set_type(node, NODE_LIT);
9366  break;
9367  default:
9368  node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node));
9369  break;
9370  }
9371  return node;
9372 }
9373 #endif /* !RIPPER */
9374 
9375 #ifndef RIPPER
9376 static NODE *
9377 new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
9378 {
9379  NODE *asgn;
9380 
9381  if (lhs) {
9382  ID vid = lhs->nd_vid;
9383  if (op == tOROP) {
9384  lhs->nd_value = rhs;
9385  asgn = NEW_OP_ASGN_OR(gettable(vid), lhs);
9386  if (is_asgn_or_id(vid)) {
9387  asgn->nd_aid = vid;
9388  }
9389  }
9390  else if (op == tANDOP) {
9391  lhs->nd_value = rhs;
9392  asgn = NEW_OP_ASGN_AND(gettable(vid), lhs);
9393  }
9394  else {
9395  asgn = lhs;
9396  asgn->nd_value = NEW_CALL(gettable(vid), op, NEW_LIST(rhs));
9397  }
9398  }
9399  else {
9400  asgn = NEW_BEGIN(0);
9401  }
9402  return asgn;
9403 }
9404 
9405 static NODE *
9406 new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs)
9407 {
9408  NODE *asgn;
9409 
9410  if (op == tOROP) {
9411  op = 0;
9412  }
9413  else if (op == tANDOP) {
9414  op = 1;
9415  }
9416  asgn = NEW_OP_ASGN2(lhs, attr, op, rhs);
9417  fixpos(asgn, lhs);
9418  return asgn;
9419 }
9420 
9421 static NODE *
9422 new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
9423 {
9424  NODE *asgn;
9425 
9426  if (op == tOROP) {
9427  op = 0;
9428  }
9429  else if (op == tANDOP) {
9430  op = 1;
9431  }
9432  if (lhs) {
9433  asgn = NEW_OP_CDECL(lhs, op, rhs);
9434  }
9435  else {
9436  asgn = NEW_BEGIN(0);
9437  }
9438  fixpos(asgn, lhs);
9439  return asgn;
9440 }
9441 #else
9442 static VALUE
9443 new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs)
9444 {
9445  return dispatch3(opassign, lhs, op, rhs);
9446 }
9447 
9448 static VALUE
9449 new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs)
9450 {
9451  VALUE recv = dispatch3(field, lhs, type, attr);
9452  return dispatch3(opassign, recv, op, rhs);
9453 }
9454 #endif
9455 
9456 static void
9457 warn_unused_var(struct parser_params *parser, struct local_vars *local)
9458 {
9459  int i, cnt;
9460  ID *v, *u;
9461 
9462  if (!local->used) return;
9463  v = local->vars->tbl;
9464  u = local->used->tbl;
9465  cnt = local->used->pos;
9466  if (cnt != local->vars->pos) {
9467  rb_bug("local->used->pos != local->vars->pos");
9468  }
9469  for (i = 0; i < cnt; ++i) {
9470  if (!v[i] || (u[i] & LVAR_USED)) continue;
9471  if (is_private_local_id(v[i])) continue;
9472  rb_warn4S(ruby_sourcefile, (int)u[i], "assigned but unused variable - %s", rb_id2name(v[i]));
9473  }
9474 }
9475 
9476 static void
9477 local_push_gen(struct parser_params *parser, int inherit_dvars)
9478 {
9479  struct local_vars *local;
9480 
9481  local = ALLOC(struct local_vars);
9482  local->prev = lvtbl;
9483  local->args = vtable_alloc(0);
9484  local->vars = vtable_alloc(inherit_dvars ? DVARS_INHERIT : DVARS_TOPSCOPE);
9485  local->used = !(inherit_dvars &&
9487  RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
9488  lvtbl = local;
9489 }
9490 
9491 static void
9492 local_pop_gen(struct parser_params *parser)
9493 {
9494  struct local_vars *local = lvtbl->prev;
9495  if (lvtbl->used) {
9496  warn_unused_var(parser, lvtbl);
9497  vtable_free(lvtbl->used);
9498  }
9499  vtable_free(lvtbl->args);
9500  vtable_free(lvtbl->vars);
9501  xfree(lvtbl);
9502  lvtbl = local;
9503 }
9504 
9505 #ifndef RIPPER
9506 static ID*
9507 vtable_tblcpy(ID *buf, const struct vtable *src)
9508 {
9509  int i, cnt = vtable_size(src);
9510 
9511  if (cnt > 0) {
9512  buf[0] = cnt;
9513  for (i = 0; i < cnt; i++) {
9514  buf[i] = src->tbl[i];
9515  }
9516  return buf;
9517  }
9518  return 0;
9519 }
9520 
9521 static ID*
9522 local_tbl_gen(struct parser_params *parser)
9523 {
9524  int cnt = vtable_size(lvtbl->args) + vtable_size(lvtbl->vars);
9525  ID *buf;
9526 
9527  if (cnt <= 0) return 0;
9528  buf = ALLOC_N(ID, cnt + 1);
9529  vtable_tblcpy(buf+1, lvtbl->args);
9530  vtable_tblcpy(buf+vtable_size(lvtbl->args)+1, lvtbl->vars);
9531  buf[0] = cnt;
9532  return buf;
9533 }
9534 #endif
9535 
9536 static int
9537 arg_var_gen(struct parser_params *parser, ID id)
9538 {
9539  vtable_add(lvtbl->args, id);
9540  return vtable_size(lvtbl->args) - 1;
9541 }
9542 
9543 static int
9544 local_var_gen(struct parser_params *parser, ID id)
9545 {
9546  vtable_add(lvtbl->vars, id);
9547  if (lvtbl->used) {
9549  }
9550  return vtable_size(lvtbl->vars) - 1;
9551 }
9552 
9553 static int
9554 local_id_gen(struct parser_params *parser, ID id)
9555 {
9556  struct vtable *vars, *args, *used;
9557 
9558  vars = lvtbl->vars;
9559  args = lvtbl->args;
9560  used = lvtbl->used;
9561 
9562  while (vars && POINTER_P(vars->prev)) {
9563  vars = vars->prev;
9564  args = args->prev;
9565  if (used) used = used->prev;
9566  }
9567 
9568  if (vars && vars->prev == DVARS_INHERIT) {
9569  return rb_local_defined(id);
9570  }
9571  else if (vtable_included(args, id)) {
9572  return 1;
9573  }
9574  else {
9575  int i = vtable_included(vars, id);
9576  if (i && used) used->tbl[i-1] |= LVAR_USED;
9577  return i != 0;
9578  }
9579 }
9580 
9581 static const struct vtable *
9582 dyna_push_gen(struct parser_params *parser)
9583 {
9584  lvtbl->args = vtable_alloc(lvtbl->args);
9585  lvtbl->vars = vtable_alloc(lvtbl->vars);
9586  if (lvtbl->used) {
9587  lvtbl->used = vtable_alloc(lvtbl->used);
9588  }
9589  return lvtbl->args;
9590 }
9591 
9592 static void
9593 dyna_pop_1(struct parser_params *parser)
9594 {
9595  struct vtable *tmp;
9596 
9597  if ((tmp = lvtbl->used) != 0) {
9598  warn_unused_var(parser, lvtbl);
9599  lvtbl->used = lvtbl->used->prev;
9600  vtable_free(tmp);
9601  }
9602  tmp = lvtbl->args;
9603  lvtbl->args = lvtbl->args->prev;
9604  vtable_free(tmp);
9605  tmp = lvtbl->vars;
9606  lvtbl->vars = lvtbl->vars->prev;
9607  vtable_free(tmp);
9608 }
9609 
9610 static void
9611 dyna_pop_gen(struct parser_params *parser, const struct vtable *lvargs)
9612 {
9613  while (lvtbl->args != lvargs) {
9614  dyna_pop_1(parser);
9615  if (!lvtbl->args) {
9616  struct local_vars *local = lvtbl->prev;
9617  xfree(lvtbl);
9618  lvtbl = local;
9619  }
9620  }
9621  dyna_pop_1(parser);
9622 }
9623 
9624 static int
9625 dyna_in_block_gen(struct parser_params *parser)
9626 {
9627  return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
9628 }
9629 
9630 static int
9631 dvar_defined_gen(struct parser_params *parser, ID id, int get)
9632 {
9633  struct vtable *vars, *args, *used;
9634  int i;
9635 
9636  args = lvtbl->args;
9637  vars = lvtbl->vars;
9638  used = lvtbl->used;
9639 
9640  while (POINTER_P(vars)) {
9641  if (vtable_included(args, id)) {
9642  return 1;
9643  }
9644  if ((i = vtable_included(vars, id)) != 0) {
9645  if (used) used->tbl[i-1] |= LVAR_USED;
9646  return 1;
9647  }
9648  args = args->prev;
9649  vars = vars->prev;
9650  if (get) used = 0;
9651  if (used) used = used->prev;
9652  }
9653 
9654  if (vars == DVARS_INHERIT) {
9655  return rb_dvar_defined(id);
9656  }
9657 
9658  return 0;
9659 }
9660 
9661 static int
9662 dvar_curr_gen(struct parser_params *parser, ID id)
9663 {
9664  return (vtable_included(lvtbl->args, id) ||
9665  vtable_included(lvtbl->vars, id));
9666 }
9667 
9668 #ifndef RIPPER
9669 static void
9670 reg_fragment_setenc_gen(struct parser_params* parser, VALUE str, int options)
9671 {
9672  int c = RE_OPTION_ENCODING_IDX(options);
9673 
9674  if (c) {
9675  int opt, idx;
9676  rb_char_to_option_kcode(c, &opt, &idx);
9677  if (idx != ENCODING_GET(str) &&
9679  goto error;
9680  }
9681  ENCODING_SET(str, idx);
9682  }
9683  else if (RE_OPTION_ENCODING_NONE(options)) {
9684  if (!ENCODING_IS_ASCII8BIT(str) &&
9686  c = 'n';
9687  goto error;
9688  }
9690  }
9691  else if (current_enc == rb_usascii_encoding()) {
9693  /* raise in re.c */
9695  }
9696  else {
9698  }
9699  }
9700  return;
9701 
9702  error:
9704  "regexp encoding option '%c' differs from source encoding '%s'",
9705  c, rb_enc_name(rb_enc_get(str)));
9706 }
9707 
9708 static int
9709 reg_fragment_check_gen(struct parser_params* parser, VALUE str, int options)
9710 {
9711  VALUE err;
9712  reg_fragment_setenc(str, options);
9713  err = rb_reg_check_preprocess(str);
9714  if (err != Qnil) {
9715  err = rb_obj_as_string(err);
9716  compile_error(PARSER_ARG "%s", RSTRING_PTR(err));
9717  RB_GC_GUARD(err);
9718  return 0;
9719  }
9720  return 1;
9721 }
9722 
9723 typedef struct {
9724  struct parser_params* parser;
9725  rb_encoding *enc;
9726  NODE *succ_block;
9727  NODE *fail_block;
9728  int num;
9730 
9731 static int
9732 reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
9733  int back_num, int *back_refs, OnigRegex regex, void *arg0)
9734 {
9736  struct parser_params* parser = arg->parser;
9737  rb_encoding *enc = arg->enc;
9738  long len = name_end - name;
9739  const char *s = (const char *)name;
9740  ID var;
9741 
9742  arg->num++;
9743 
9744  if (arg->succ_block == 0) {
9745  arg->succ_block = NEW_BEGIN(0);
9746  arg->fail_block = NEW_BEGIN(0);
9747  }
9748 
9749  if (!len || (*name != '_' && ISASCII(*name) && !rb_enc_islower(*name, enc)) ||
9750  (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) ||
9751  !rb_enc_symname2_p(s, len, enc)) {
9752  return ST_CONTINUE;
9753  }
9754  var = rb_intern3(s, len, enc);
9755  if (dvar_defined(var) || local_id(var)) {
9756  rb_warningS("named capture conflicts a local variable - %s",
9757  rb_id2name(var));
9758  }
9759  arg->succ_block = block_append(arg->succ_block,
9761  NEW_CALL(
9762  gettable(rb_intern("$~")),
9763  idAREF,
9764  NEW_LIST(NEW_LIT(ID2SYM(var))))
9765  )));
9766  arg->fail_block = block_append(arg->fail_block,
9768  return ST_CONTINUE;
9769 }
9770 
9771 static NODE *
9772 reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match)
9773 {
9775 
9776  arg.parser = parser;
9777  arg.enc = rb_enc_get(regexp);
9778  arg.succ_block = 0;
9779  arg.fail_block = 0;
9780  arg.num = 0;
9782 
9783  if (arg.num == 0)
9784  return match;
9785 
9786  return
9787  block_append(
9788  newline_node(match),
9789  NEW_IF(gettable(rb_intern("$~")),
9790  block_append(
9791  newline_node(arg.succ_block),
9792  newline_node(
9793  NEW_CALL(
9794  gettable(rb_intern("$~")),
9795  rb_intern("begin"),
9796  NEW_LIST(NEW_LIT(INT2FIX(0)))))),
9797  block_append(
9798  newline_node(arg.fail_block),
9799  newline_node(
9800  NEW_LIT(Qnil)))));
9801 }
9802 
9803 static VALUE
9804 reg_compile_gen(struct parser_params* parser, VALUE str, int options)
9805 {
9806  VALUE re;
9807  VALUE err;
9808 
9809  reg_fragment_setenc(str, options);
9810  err = rb_errinfo();
9811  re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
9812  if (NIL_P(re)) {
9813  ID mesg = rb_intern("mesg");
9814  VALUE m = rb_attr_get(rb_errinfo(), mesg);
9815  rb_set_errinfo(err);
9816  if (!NIL_P(err)) {
9817  rb_str_append(rb_str_cat(rb_attr_get(err, mesg), "\n", 1), m);
9818  }
9819  else {
9821  }
9822  return Qnil;
9823  }
9824  return re;
9825 }
9826 
9827 void
9828 rb_gc_mark_parser(void)
9829 {
9830 }
9831 
9832 NODE*
9833 rb_parser_append_print(VALUE vparser, NODE *node)
9834 {
9835  NODE *prelude = 0;
9836  NODE *scope = node;
9837  struct parser_params *parser;
9838 
9839  if (!node) return node;
9840 
9841  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
9842 
9843  node = node->nd_body;
9844 
9845  if (nd_type(node) == NODE_PRELUDE) {
9846  prelude = node;
9847  node = node->nd_body;
9848  }
9849 
9850  node = block_append(node,
9851  NEW_FCALL(rb_intern("print"),
9852  NEW_ARRAY(NEW_GVAR(rb_intern("$_")))));
9853  if (prelude) {
9854  prelude->nd_body = node;
9855  scope->nd_body = prelude;
9856  }
9857  else {
9858  scope->nd_body = node;
9859  }
9860 
9861  return scope;
9862 }
9863 
9864 NODE *
9865 rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
9866 {
9867  NODE *prelude = 0;
9868  NODE *scope = node;
9869  struct parser_params *parser;
9870 
9871  if (!node) return node;
9872 
9873  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
9874 
9875  node = node->nd_body;
9876 
9877  if (nd_type(node) == NODE_PRELUDE) {
9878  prelude = node;
9879  node = node->nd_body;
9880  }
9881  if (split) {
9882  node = block_append(NEW_GASGN(rb_intern("$F"),
9883  NEW_CALL(NEW_GVAR(rb_intern("$_")),
9884  rb_intern("split"), 0)),
9885  node);
9886  }
9887  if (chop) {
9888  node = block_append(NEW_CALL(NEW_GVAR(rb_intern("$_")),
9889  rb_intern("chop!"), 0), node);
9890  }
9891 
9892  node = NEW_OPT_N(node);
9893 
9894  if (prelude) {
9895  prelude->nd_body = node;
9896  scope->nd_body = prelude;
9897  }
9898  else {
9899  scope->nd_body = node;
9900  }
9901 
9902  return scope;
9903 }
9904 
9905 static const struct {
9906  ID token;
9907  const char *name;
9908 } op_tbl[] = {
9909  {tDOT2, ".."},
9910  {tDOT3, "..."},
9911  {'+', "+(binary)"},
9912  {'-', "-(binary)"},
9913  {tPOW, "**"},
9914  {tDSTAR, "**"},
9915  {tUPLUS, "+@"},
9916  {tUMINUS, "-@"},
9917  {tCMP, "<=>"},
9918  {tGEQ, ">="},
9919  {tLEQ, "<="},
9920  {tEQ, "=="},
9921  {tEQQ, "==="},
9922  {tNEQ, "!="},
9923  {tMATCH, "=~"},
9924  {tNMATCH, "!~"},
9925  {tAREF, "[]"},
9926  {tASET, "[]="},
9927  {tLSHFT, "<<"},
9928  {tRSHFT, ">>"},
9929  {tCOLON2, "::"},
9930 };
9931 
9932 #define op_tbl_count numberof(op_tbl)
9933 
9934 #ifndef ENABLE_SELECTOR_NAMESPACE
9935 #define ENABLE_SELECTOR_NAMESPACE 0
9936 #endif
9937 
9938 static struct symbols {
9939  ID last_id;
9940  st_table *sym_id;
9941  st_table *id_str;
9942 #if ENABLE_SELECTOR_NAMESPACE
9943  st_table *ivar2_id;
9944  st_table *id_ivar2;
9945 #endif
9948 
9949 static const struct st_hash_type symhash = {
9951  rb_str_hash,
9952 };
9953 
9954 #if ENABLE_SELECTOR_NAMESPACE
9955 struct ivar2_key {
9956  ID id;
9957  VALUE klass;
9958 };
9959 
9960 static int
9961 ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2)
9962 {
9963  if (key1->id == key2->id && key1->klass == key2->klass) {
9964  return 0;
9965  }
9966  return 1;
9967 }
9968 
9969 static int
9970 ivar2_hash(struct ivar2_key *key)
9971 {
9972  return (key->id << 8) ^ (key->klass >> 2);
9973 }
9974 
9975 static const struct st_hash_type ivar2_hash_type = {
9976  ivar2_cmp,
9977  ivar2_hash,
9978 };
9979 #endif
9980 
9981 void
9982 Init_sym(void)
9983 {
9984  global_symbols.sym_id = st_init_table_with_size(&symhash, 1000);
9986 #if ENABLE_SELECTOR_NAMESPACE
9987  global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
9988  global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
9989 #endif
9990 
9991  (void)nodetype;
9992  (void)nodeline;
9993 #if PARSER_DEBUG
9994  (void)lex_state_name(-1);
9995 #endif
9996 
9997  Init_id();
9998 }
9999 
10000 void
10001 rb_gc_mark_symbols(void)
10002 {
10006 }
10007 #endif /* !RIPPER */
10008 
10009 static ID
10010 internal_id_gen(struct parser_params *parser)
10011 {
10012  ID id = (ID)vtable_size(lvtbl->args) + (ID)vtable_size(lvtbl->vars);
10013  id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1;
10014  return ID_INTERNAL | (id << ID_SCOPE_SHIFT);
10015 }
10016 
10017 #ifndef RIPPER
10018 static int
10019 is_special_global_name(const char *m, const char *e, rb_encoding *enc)
10020 {
10021  int mb = 0;
10022 
10023  if (m >= e) return 0;
10024  if (is_global_name_punct(*m)) {
10025  ++m;
10026  }
10027  else if (*m == '-') {
10028  ++m;
10029  if (m < e && is_identchar(m, e, enc)) {
10030  if (!ISASCII(*m)) mb = 1;
10031  m += rb_enc_mbclen(m, e, enc);
10032  }
10033  }
10034  else {
10035  if (!rb_enc_isdigit(*m, enc)) return 0;
10036  do {
10037  if (!ISASCII(*m)) mb = 1;
10038  ++m;
10039  } while (m < e && rb_enc_isdigit(*m, enc));
10040  }
10041  return m == e ? mb + 1 : 0;
10042 }
10043 
10044 int
10045 rb_symname_p(const char *name)
10046 {
10047  return rb_enc_symname_p(name, rb_ascii8bit_encoding());
10048 }
10049 
10050 int
10051 rb_enc_symname_p(const char *name, rb_encoding *enc)
10052 {
10053  return rb_enc_symname2_p(name, strlen(name), enc);
10054 }
10055 
10056 static int
10057 rb_enc_symname_type(const char *name, long len, rb_encoding *enc)
10058 {
10059  const char *m = name;
10060  const char *e = m + len;
10061  int type = ID_JUNK;
10062 
10063  if (!m || len <= 0) return -1;
10064  switch (*m) {
10065  case '\0':
10066  return -1;
10067 
10068  case '$':
10069  type = ID_GLOBAL;
10070  if (is_special_global_name(++m, e, enc)) return type;
10071  goto id;
10072 
10073  case '@':
10074  type = ID_INSTANCE;
10075  if (*++m == '@') {
10076  ++m;
10077  type = ID_CLASS;
10078  }
10079  goto id;
10080 
10081  case '<':
10082  switch (*++m) {
10083  case '<': ++m; break;
10084  case '=': if (*++m == '>') ++m; break;
10085  default: break;
10086  }
10087  break;
10088 
10089  case '>':
10090  switch (*++m) {
10091  case '>': case '=': ++m; break;
10092  }
10093  break;
10094 
10095  case '=':
10096  switch (*++m) {
10097  case '~': ++m; break;
10098  case '=': if (*++m == '=') ++m; break;
10099  default: return -1;
10100  }
10101  break;
10102 
10103  case '*':
10104  if (*++m == '*') ++m;
10105  break;
10106 
10107  case '+': case '-':
10108  if (*++m == '@') ++m;
10109  break;
10110 
10111  case '|': case '^': case '&': case '/': case '%': case '~': case '`':
10112  ++m;
10113  break;
10114 
10115  case '[':
10116  if (*++m != ']') return -1;
10117  if (*++m == '=') ++m;
10118  break;
10119 
10120  case '!':
10121  if (len == 1) return ID_JUNK;
10122  switch (*++m) {
10123  case '=': case '~': ++m; break;
10124  default: return -1;
10125  }
10126  break;
10127 
10128  default:
10129  type = rb_enc_isupper(*m, enc) ? ID_CONST : ID_LOCAL;
10130  id:
10131  if (m >= e || (*m != '_' && !rb_enc_isalpha(*m, enc) && ISASCII(*m)))
10132  return -1;
10133  while (m < e && is_identchar(m, e, enc)) m += rb_enc_mbclen(m, e, enc);
10134  switch (*m) {
10135  case '!': case '?':
10136  if (type == ID_GLOBAL || type == ID_CLASS || type == ID_INSTANCE) return -1;
10137  type = ID_JUNK;
10138  ++m;
10139  break;
10140  case '=':
10141  if (type != ID_CONST && type != ID_LOCAL) return -1;
10142  type = ID_ATTRSET;
10143  ++m;
10144  break;
10145  }
10146  break;
10147  }
10148  return m == e ? type : -1;
10149 }
10150 
10151 int
10152 rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
10153 {
10154  return rb_enc_symname_type(name, len, enc) != -1;
10155 }
10156 
10157 static int
10159 {
10160  const char *ptr = StringValuePtr(name);
10161  long len = RSTRING_LEN(name);
10162  int type = rb_enc_symname_type(ptr, len, rb_enc_get(name));
10163  RB_GC_GUARD(name);
10164  return type;
10165 }
10166 
10167 static ID
10168 register_symid(ID id, const char *name, long len, rb_encoding *enc)
10169 {
10170  VALUE str = rb_enc_str_new(name, len, enc);
10171  return register_symid_str(id, str);
10172 }
10173 
10174 static ID
10175 register_symid_str(ID id, VALUE str)
10176 {
10177  OBJ_FREEZE(str);
10180  return id;
10181 }
10182 
10183 static int
10185 {
10186  if (!rb_enc_asciicompat(rb_enc_get(str))) return FALSE;
10187  switch (rb_enc_str_coderange(str)) {
10188  case ENC_CODERANGE_BROKEN:
10189  rb_raise(rb_eEncodingError, "invalid encoding symbol");
10190  case ENC_CODERANGE_7BIT:
10191  return TRUE;
10192  }
10193  return FALSE;
10194 }
10195 
10196 /*
10197  * _str_ itself will be registered at the global symbol table. _str_
10198  * can be modified before the registration, since the encoding will be
10199  * set to ASCII-8BIT if it is a special global name.
10200  */
10201 static ID intern_str(VALUE str);
10202 
10203 ID
10204 rb_intern3(const char *name, long len, rb_encoding *enc)
10205 {
10206  VALUE str;
10207  st_data_t data;
10208  struct RString fake_str;
10209  fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10210  fake_str.basic.klass = rb_cString;
10211  fake_str.as.heap.len = len;
10212  fake_str.as.heap.ptr = (char *)name;
10213  fake_str.as.heap.aux.capa = len;
10214  str = (VALUE)&fake_str;
10215  rb_enc_associate(str, enc);
10216  OBJ_FREEZE(str);
10217 
10218  if (st_lookup(global_symbols.sym_id, str, &data))
10219  return (ID)data;
10220 
10221  str = rb_enc_str_new(name, len, enc); /* make true string */
10222  return intern_str(str);
10223 }
10224 
10225 static ID
10226 intern_str(VALUE str)
10227 {
10228  const char *name, *m, *e;
10229  long len, last;
10230  rb_encoding *enc, *symenc;
10231  unsigned char c;
10232  ID id;
10233  int mb;
10234 
10235  RSTRING_GETMEM(str, name, len);
10236  m = name;
10237  e = m + len;
10238  enc = rb_enc_get(str);
10239  symenc = enc;
10240 
10241  if (rb_cString && !rb_enc_asciicompat(enc)) {
10242  id = ID_JUNK;
10243  goto new_id;
10244  }
10245  last = len-1;
10246  id = 0;
10247  switch (*m) {
10248  case '$':
10249  id |= ID_GLOBAL;
10250  if ((mb = is_special_global_name(++m, e, enc)) != 0) {
10251  if (!--mb) symenc = rb_usascii_encoding();
10252  goto new_id;
10253  }
10254  break;
10255  case '@':
10256  if (m[1] == '@') {
10257  m++;
10258  id |= ID_CLASS;
10259  }
10260  else {
10261  id |= ID_INSTANCE;
10262  }
10263  m++;
10264  break;
10265  default:
10266  c = m[0];
10267  if (c != '_' && rb_enc_isascii(c, enc) && rb_enc_ispunct(c, enc)) {
10268  /* operators */
10269  int i;
10270 
10271  if (len == 1) {
10272  id = c;
10273  goto id_register;
10274  }
10275  for (i = 0; i < op_tbl_count; i++) {
10276  if (*op_tbl[i].name == *m &&
10277  strcmp(op_tbl[i].name, m) == 0) {
10278  id = op_tbl[i].token;
10279  goto id_register;
10280  }
10281  }
10282  }
10283 
10284  if (m[last] == '=') {
10285  /* attribute assignment */
10286  id = rb_intern3(name, last, enc);
10287  if (id > tLAST_OP_ID && !is_attrset_id(id)) {
10288  enc = rb_enc_get(rb_id2str(id));
10289  id = rb_id_attrset(id);
10290  goto id_register;
10291  }
10292  id = ID_ATTRSET;
10293  }
10294  else if (rb_enc_isupper(m[0], enc)) {
10295  id = ID_CONST;
10296  }
10297  else {
10298  id = ID_LOCAL;
10299  }
10300  break;
10301  }
10302  if (!rb_enc_isdigit(*m, enc)) {
10303  while (m <= name + last && is_identchar(m, e, enc)) {
10304  if (ISASCII(*m)) {
10305  m++;
10306  }
10307  else {
10308  m += rb_enc_mbclen(m, e, enc);
10309  }
10310  }
10311  }
10312  if (m - name < len) id = ID_JUNK;
10313  if (sym_check_asciionly(str)) symenc = rb_usascii_encoding();
10314  new_id:
10315  if (symenc != enc) rb_enc_associate(str, symenc);
10317  if (len > 20) {
10318  rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.20s...)",
10319  name);
10320  }
10321  else {
10322  rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.*s)",
10323  (int)len, name);
10324  }
10325  }
10327  id_register:
10328  return register_symid_str(id, str);
10329 }
10330 
10331 ID
10332 rb_intern2(const char *name, long len)
10333 {
10334  return rb_intern3(name, len, rb_usascii_encoding());
10335 }
10336 
10337 #undef rb_intern
10338 ID
10339 rb_intern(const char *name)
10340 {
10341  return rb_intern2(name, strlen(name));
10342 }
10343 
10344 ID
10345 rb_intern_str(VALUE str)
10346 {
10347  st_data_t id;
10348 
10349  if (st_lookup(global_symbols.sym_id, str, &id))
10350  return (ID)id;
10351  return intern_str(rb_str_dup(str));
10352 }
10353 
10354 VALUE
10355 rb_id2str(ID id)
10356 {
10357  st_data_t data;
10358 
10359  if (id < tLAST_TOKEN) {
10360  int i = 0;
10361 
10362  if (id < INT_MAX && rb_ispunct((int)id)) {
10363  VALUE str = global_symbols.op_sym[i = (int)id];
10364  if (!str) {
10365  char name[2];
10366  name[0] = (char)id;
10367  name[1] = 0;
10368  str = rb_usascii_str_new(name, 1);
10369  OBJ_FREEZE(str);
10371  }
10372  return str;
10373  }
10374  for (i = 0; i < op_tbl_count; i++) {
10375  if (op_tbl[i].token == id) {
10376  VALUE str = global_symbols.op_sym[i];
10377  if (!str) {
10378  str = rb_usascii_str_new2(op_tbl[i].name);
10379  OBJ_FREEZE(str);
10381  }
10382  return str;
10383  }
10384  }
10385  }
10386 
10387  if (st_lookup(global_symbols.id_str, id, &data)) {
10388  VALUE str = (VALUE)data;
10389  if (RBASIC(str)->klass == 0)
10390  RBASIC(str)->klass = rb_cString;
10391  return str;
10392  }
10393 
10394  if (is_attrset_id(id)) {
10395  ID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL;
10396  VALUE str;
10397 
10398  while (!(str = rb_id2str(id2))) {
10399  if (!is_local_id(id2)) return 0;
10400  id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;
10401  }
10402  str = rb_str_dup(str);
10403  rb_str_cat(str, "=", 1);
10404  rb_intern_str(str);
10405  if (st_lookup(global_symbols.id_str, id, &data)) {
10406  VALUE str = (VALUE)data;
10407  if (RBASIC(str)->klass == 0)
10408  RBASIC(str)->klass = rb_cString;
10409  return str;
10410  }
10411  }
10412  return 0;
10413 }
10414 
10415 const char *
10416 rb_id2name(ID id)
10417 {
10418  VALUE str = rb_id2str(id);
10419 
10420  if (!str) return 0;
10421  return RSTRING_PTR(str);
10422 }
10423 
10424 static int
10426 {
10427  rb_ary_push(ary, ID2SYM(value));
10428  return ST_CONTINUE;
10429 }
10430 
10431 /*
10432  * call-seq:
10433  * Symbol.all_symbols => array
10434  *
10435  * Returns an array of all the symbols currently in Ruby's symbol
10436  * table.
10437  *
10438  * Symbol.all_symbols.size #=> 903
10439  * Symbol.all_symbols[1,20] #=> [:floor, :ARGV, :Binding, :symlink,
10440  * :chown, :EOFError, :$;, :String,
10441  * :LOCK_SH, :"setuid?", :$<,
10442  * :default_proc, :compact, :extend,
10443  * :Tms, :getwd, :$=, :ThreadGroup,
10444  * :wait2, :$>]
10445  */
10446 
10447 VALUE
10448 rb_sym_all_symbols(void)
10449 {
10451 
10453  return ary;
10454 }
10455 
10456 int
10457 rb_is_const_id(ID id)
10458 {
10459  return is_const_id(id);
10460 }
10461 
10462 int
10463 rb_is_class_id(ID id)
10464 {
10465  return is_class_id(id);
10466 }
10467 
10468 int
10469 rb_is_global_id(ID id)
10470 {
10471  return is_global_id(id);
10472 }
10473 
10474 int
10476 {
10477  return is_instance_id(id);
10478 }
10479 
10480 int
10481 rb_is_attrset_id(ID id)
10482 {
10483  return is_attrset_id(id);
10484 }
10485 
10486 int
10487 rb_is_local_id(ID id)
10488 {
10489  return is_local_id(id);
10490 }
10491 
10492 int
10493 rb_is_junk_id(ID id)
10494 {
10495  return is_junk_id(id);
10496 }
10497 
10509 ID
10510 rb_check_id(volatile VALUE *namep)
10511 {
10512  st_data_t id;
10513  VALUE tmp;
10514  VALUE name = *namep;
10515 
10516  if (SYMBOL_P(name)) {
10517  return SYM2ID(name);
10518  }
10519  else if (!RB_TYPE_P(name, T_STRING)) {
10520  tmp = rb_check_string_type(name);
10521  if (NIL_P(tmp)) {
10522  tmp = rb_inspect(name);
10523  rb_raise(rb_eTypeError, "%s is not a symbol",
10524  RSTRING_PTR(tmp));
10525  }
10526  name = tmp;
10527  *namep = name;
10528  }
10529 
10530  sym_check_asciionly(name);
10531 
10532  if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10533  return (ID)id;
10534 
10535  if (rb_is_attrset_name(name)) {
10536  struct RString fake_str;
10537  const VALUE localname = (VALUE)&fake_str;
10538  /* make local name by chopping '=' */
10539  fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10540  fake_str.basic.klass = rb_cString;
10541  fake_str.as.heap.len = RSTRING_LEN(name) - 1;
10542  fake_str.as.heap.ptr = RSTRING_PTR(name);
10543  fake_str.as.heap.aux.capa = fake_str.as.heap.len;
10544  rb_enc_copy(localname, name);
10545  OBJ_FREEZE(localname);
10546 
10547  if (st_lookup(global_symbols.sym_id, (st_data_t)localname, &id)) {
10548  return rb_id_attrset((ID)id);
10549  }
10550  RB_GC_GUARD(name);
10551  }
10552 
10553  return (ID)0;
10554 }
10555 
10556 ID
10557 rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
10558 {
10559  st_data_t id;
10560  struct RString fake_str;
10561  const VALUE name = (VALUE)&fake_str;
10562  fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10563  fake_str.basic.klass = rb_cString;
10564  fake_str.as.heap.len = len;
10565  fake_str.as.heap.ptr = (char *)ptr;
10566  fake_str.as.heap.aux.capa = len;
10567  rb_enc_associate(name, enc);
10568 
10569  sym_check_asciionly(name);
10570 
10571  if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10572  return (ID)id;
10573 
10574  if (rb_is_attrset_name(name)) {
10575  fake_str.as.heap.len = len - 1;
10576  if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id)) {
10577  return rb_id_attrset((ID)id);
10578  }
10579  }
10580 
10581  return (ID)0;
10582 }
10583 
10584 int
10585 rb_is_const_name(VALUE name)
10586 {
10587  return rb_str_symname_type(name) == ID_CONST;
10588 }
10589 
10590 int
10591 rb_is_class_name(VALUE name)
10592 {
10593  return rb_str_symname_type(name) == ID_CLASS;
10594 }
10595 
10596 int
10598 {
10599  return rb_str_symname_type(name) == ID_GLOBAL;
10600 }
10601 
10602 int
10604 {
10605  return rb_str_symname_type(name) == ID_INSTANCE;
10606 }
10607 
10608 int
10610 {
10611  return rb_str_symname_type(name) == ID_ATTRSET;
10612 }
10613 
10614 int
10615 rb_is_local_name(VALUE name)
10616 {
10617  return rb_str_symname_type(name) == ID_LOCAL;
10618 }
10619 
10620 int
10622 {
10623  switch (rb_str_symname_type(name)) {
10624  case ID_LOCAL: case ID_ATTRSET: case ID_JUNK:
10625  return TRUE;
10626  }
10627  return FALSE;
10628 }
10629 
10630 int
10631 rb_is_junk_name(VALUE name)
10632 {
10633  return rb_str_symname_type(name) == -1;
10634 }
10635 
10636 #endif /* !RIPPER */
10637 
10638 static void
10639 parser_initialize(struct parser_params *parser)
10640 {
10641  parser->eofp = Qfalse;
10642 
10643  parser->parser_lex_strterm = 0;
10644  parser->parser_cond_stack = 0;
10645  parser->parser_cmdarg_stack = 0;
10646  parser->parser_class_nest = 0;
10647  parser->parser_paren_nest = 0;
10648  parser->parser_lpar_beg = 0;
10649  parser->parser_brace_nest = 0;
10650  parser->parser_in_single = 0;
10651  parser->parser_in_def = 0;
10652  parser->parser_in_defined = 0;
10653  parser->parser_compile_for_eval = 0;
10654  parser->parser_cur_mid = 0;
10655  parser->parser_tokenbuf = NULL;
10656  parser->parser_tokidx = 0;
10657  parser->parser_toksiz = 0;
10658  parser->parser_heredoc_end = 0;
10659  parser->parser_command_start = TRUE;
10660  parser->parser_deferred_nodes = 0;
10661  parser->parser_lex_pbeg = 0;
10662  parser->parser_lex_p = 0;
10663  parser->parser_lex_pend = 0;
10664  parser->parser_lvtbl = 0;
10665  parser->parser_ruby__end__seen = 0;
10666  parser->parser_ruby_sourcefile = 0;
10667 #ifndef RIPPER
10668  parser->is_ripper = 0;
10669  parser->parser_eval_tree_begin = 0;
10670  parser->parser_eval_tree = 0;
10671 #else
10672  parser->is_ripper = 1;
10673  parser->parser_ruby_sourcefile_string = Qnil;
10674  parser->delayed = Qnil;
10675 
10676  parser->result = Qnil;
10677  parser->parsing_thread = Qnil;
10678  parser->toplevel_p = TRUE;
10679 #endif
10680 #ifdef YYMALLOC
10681  parser->heap = NULL;
10682 #endif
10683  parser->enc = rb_utf8_encoding();
10684 }
10685 
10686 #ifdef RIPPER
10687 #define parser_mark ripper_parser_mark
10688 #define parser_free ripper_parser_free
10689 #endif
10690 
10691 static void
10692 parser_mark(void *ptr)
10693 {
10694  struct parser_params *p = (struct parser_params*)ptr;
10695 
10701 #ifndef RIPPER
10704  rb_gc_mark(p->debug_lines);
10705 #else
10706  rb_gc_mark(p->parser_ruby_sourcefile_string);
10707  rb_gc_mark(p->delayed);
10708  rb_gc_mark(p->value);
10709  rb_gc_mark(p->result);
10710  rb_gc_mark(p->parsing_thread);
10711 #endif
10712 #ifdef YYMALLOC
10713  rb_gc_mark((VALUE)p->heap);
10714 #endif
10715 }
10716 
10717 static void
10718 parser_free(void *ptr)
10719 {
10720  struct parser_params *p = (struct parser_params*)ptr;
10721  struct local_vars *local, *prev;
10722 
10723  if (p->parser_tokenbuf) {
10724  xfree(p->parser_tokenbuf);
10725  }
10726  for (local = p->parser_lvtbl; local; local = prev) {
10727  if (local->vars) xfree(local->vars);
10728  prev = local->prev;
10729  xfree(local);
10730  }
10731 #ifndef RIPPER
10733 #endif
10734  xfree(p);
10735 }
10736 
10737 static size_t
10738 parser_memsize(const void *ptr)
10739 {
10740  struct parser_params *p = (struct parser_params*)ptr;
10741  struct local_vars *local;
10742  size_t size = sizeof(*p);
10743 
10744  if (!ptr) return 0;
10745  size += p->parser_toksiz;
10746  for (local = p->parser_lvtbl; local; local = local->prev) {
10747  size += sizeof(*local);
10748  if (local->vars) size += local->vars->capa * sizeof(ID);
10749  }
10750 #ifndef RIPPER
10751  if (p->parser_ruby_sourcefile) {
10752  size += strlen(p->parser_ruby_sourcefile) + 1;
10753  }
10754 #endif
10755  return size;
10756 }
10757 
10758 static
10759 #ifndef RIPPER
10760 const
10761 #endif
10762 rb_data_type_t parser_data_type = {
10763  "parser",
10764  {
10765  parser_mark,
10766  parser_free,
10768  },
10769 };
10770 
10771 #ifndef RIPPER
10772 #undef rb_reserved_word
10773 
10774 const struct kwtable *
10775 rb_reserved_word(const char *str, unsigned int len)
10776 {
10777  return reserved_word(str, len);
10778 }
10779 
10780 static struct parser_params *
10781 parser_new(void)
10782 {
10783  struct parser_params *p;
10784 
10785  p = ALLOC_N(struct parser_params, 1);
10786  MEMZERO(p, struct parser_params, 1);
10787  parser_initialize(p);
10788  return p;
10789 }
10790 
10791 VALUE
10792 rb_parser_new(void)
10793 {
10794  struct parser_params *p = parser_new();
10795 
10796  return TypedData_Wrap_Struct(0, &parser_data_type, p);
10797 }
10798 
10799 /*
10800  * call-seq:
10801  * ripper#end_seen? -> Boolean
10802  *
10803  * Return true if parsed source ended by +\_\_END\_\_+.
10804  */
10805 VALUE
10806 rb_parser_end_seen_p(VALUE vparser)
10807 {
10808  struct parser_params *parser;
10809 
10810  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10811  return ruby__end__seen ? Qtrue : Qfalse;
10812 }
10813 
10814 /*
10815  * call-seq:
10816  * ripper#encoding -> encoding
10817  *
10818  * Return encoding of the source.
10819  */
10820 VALUE
10821 rb_parser_encoding(VALUE vparser)
10822 {
10823  struct parser_params *parser;
10824 
10825  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10827 }
10828 
10829 /*
10830  * call-seq:
10831  * ripper.yydebug -> true or false
10832  *
10833  * Get yydebug.
10834  */
10835 VALUE
10837 {
10838  struct parser_params *parser;
10839 
10840  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10841  return yydebug ? Qtrue : Qfalse;
10842 }
10843 
10844 /*
10845  * call-seq:
10846  * ripper.yydebug = flag
10847  *
10848  * Set yydebug.
10849  */
10850 VALUE
10852 {
10853  struct parser_params *parser;
10854 
10855  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10856  yydebug = RTEST(flag);
10857  return flag;
10858 }
10859 
10860 #ifdef YYMALLOC
10861 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
10862 #define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
10863 #define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
10864  (n)->u3.cnt = (c), (p))
10865 
10866 void *
10867 rb_parser_malloc(struct parser_params *parser, size_t size)
10868 {
10869  size_t cnt = HEAPCNT(1, size);
10870  NODE *n = NEWHEAP();
10871  void *ptr = xmalloc(size);
10872 
10873  return ADD2HEAP(n, cnt, ptr);
10874 }
10875 
10876 void *
10877 rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
10878 {
10879  size_t cnt = HEAPCNT(nelem, size);
10880  NODE *n = NEWHEAP();
10881  void *ptr = xcalloc(nelem, size);
10882 
10883  return ADD2HEAP(n, cnt, ptr);
10884 }
10885 
10886 void *
10887 rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
10888 {
10889  NODE *n;
10890  size_t cnt = HEAPCNT(1, size);
10891 
10892  if (ptr && (n = parser->heap) != NULL) {
10893  do {
10894  if (n->u1.node == ptr) {
10895  n->u1.node = ptr = xrealloc(ptr, size);
10896  if (n->u3.cnt) n->u3.cnt = cnt;
10897  return ptr;
10898  }
10899  } while ((n = n->u2.node) != NULL);
10900  }
10901  n = NEWHEAP();
10902  ptr = xrealloc(ptr, size);
10903  return ADD2HEAP(n, cnt, ptr);
10904 }
10905 
10906 void
10907 rb_parser_free(struct parser_params *parser, void *ptr)
10908 {
10909  NODE **prev = &parser->heap, *n;
10910 
10911  while ((n = *prev) != NULL) {
10912  if (n->u1.node == ptr) {
10913  *prev = n->u2.node;
10915  break;
10916  }
10917  prev = &n->u2.node;
10918  }
10919  xfree(ptr);
10920 }
10921 #endif
10922 #endif
10923 
10924 #ifdef RIPPER
10925 #ifdef RIPPER_DEBUG
10926 extern int rb_is_pointer_to_heap(VALUE);
10927 
10928 /* :nodoc: */
10929 static VALUE
10930 ripper_validate_object(VALUE self, VALUE x)
10931 {
10932  if (x == Qfalse) return x;
10933  if (x == Qtrue) return x;
10934  if (x == Qnil) return x;
10935  if (x == Qundef)
10936  rb_raise(rb_eArgError, "Qundef given");
10937  if (FIXNUM_P(x)) return x;
10938  if (SYMBOL_P(x)) return x;
10939  if (!rb_is_pointer_to_heap(x))
10940  rb_raise(rb_eArgError, "invalid pointer: %p", x);
10941  switch (TYPE(x)) {
10942  case T_STRING:
10943  case T_OBJECT:
10944  case T_ARRAY:
10945  case T_BIGNUM:
10946  case T_FLOAT:
10947  return x;
10948  case T_NODE:
10949  if (nd_type(x) != NODE_LASGN) {
10950  rb_raise(rb_eArgError, "NODE given: %p", x);
10951  }
10952  return ((NODE *)x)->nd_rval;
10953  default:
10954  rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
10955  x, rb_obj_classname(x));
10956  }
10957  return x;
10958 }
10959 #endif
10960 
10961 #define validate(x) ((x) = get_value(x))
10962 
10963 static VALUE
10964 ripper_dispatch0(struct parser_params *parser, ID mid)
10965 {
10966  return rb_funcall(parser->value, mid, 0);
10967 }
10968 
10969 static VALUE
10970 ripper_dispatch1(struct parser_params *parser, ID mid, VALUE a)
10971 {
10972  validate(a);
10973  return rb_funcall(parser->value, mid, 1, a);
10974 }
10975 
10976 static VALUE
10977 ripper_dispatch2(struct parser_params *parser, ID mid, VALUE a, VALUE b)
10978 {
10979  validate(a);
10980  validate(b);
10981  return rb_funcall(parser->value, mid, 2, a, b);
10982 }
10983 
10984 static VALUE
10985 ripper_dispatch3(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c)
10986 {
10987  validate(a);
10988  validate(b);
10989  validate(c);
10990  return rb_funcall(parser->value, mid, 3, a, b, c);
10991 }
10992 
10993 static VALUE
10994 ripper_dispatch4(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d)
10995 {
10996  validate(a);
10997  validate(b);
10998  validate(c);
10999  validate(d);
11000  return rb_funcall(parser->value, mid, 4, a, b, c, d);
11001 }
11002 
11003 static VALUE
11004 ripper_dispatch5(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e)
11005 {
11006  validate(a);
11007  validate(b);
11008  validate(c);
11009  validate(d);
11010  validate(e);
11011  return rb_funcall(parser->value, mid, 5, a, b, c, d, e);
11012 }
11013 
11014 static VALUE
11015 ripper_dispatch7(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g)
11016 {
11017  validate(a);
11018  validate(b);
11019  validate(c);
11020  validate(d);
11021  validate(e);
11022  validate(f);
11023  validate(g);
11024  return rb_funcall(parser->value, mid, 7, a, b, c, d, e, f, g);
11025 }
11026 
11027 static const struct kw_assoc {
11028  ID id;
11029  const char *name;
11030 } keyword_to_name[] = {
11031  {keyword_class, "class"},
11032  {keyword_module, "module"},
11033  {keyword_def, "def"},
11034  {keyword_undef, "undef"},
11035  {keyword_begin, "begin"},
11036  {keyword_rescue, "rescue"},
11037  {keyword_ensure, "ensure"},
11038  {keyword_end, "end"},
11039  {keyword_if, "if"},
11040  {keyword_unless, "unless"},
11041  {keyword_then, "then"},
11042  {keyword_elsif, "elsif"},
11043  {keyword_else, "else"},
11044  {keyword_case, "case"},
11045  {keyword_when, "when"},
11046  {keyword_while, "while"},
11047  {keyword_until, "until"},
11048  {keyword_for, "for"},
11049  {keyword_break, "break"},
11050  {keyword_next, "next"},
11051  {keyword_redo, "redo"},
11052  {keyword_retry, "retry"},
11053  {keyword_in, "in"},
11054  {keyword_do, "do"},
11055  {keyword_do_cond, "do"},
11056  {keyword_do_block, "do"},
11057  {keyword_return, "return"},
11058  {keyword_yield, "yield"},
11059  {keyword_super, "super"},
11060  {keyword_self, "self"},
11061  {keyword_nil, "nil"},
11062  {keyword_true, "true"},
11063  {keyword_false, "false"},
11064  {keyword_and, "and"},
11065  {keyword_or, "or"},
11066  {keyword_not, "not"},
11067  {modifier_if, "if"},
11068  {modifier_unless, "unless"},
11069  {modifier_while, "while"},
11070  {modifier_until, "until"},
11071  {modifier_rescue, "rescue"},
11072  {keyword_alias, "alias"},
11073  {keyword_defined, "defined?"},
11074  {keyword_BEGIN, "BEGIN"},
11075  {keyword_END, "END"},
11076  {keyword__LINE__, "__LINE__"},
11077  {keyword__FILE__, "__FILE__"},
11078  {keyword__ENCODING__, "__ENCODING__"},
11079  {0, NULL}
11080 };
11081 
11082 static const char*
11083 keyword_id_to_str(ID id)
11084 {
11085  const struct kw_assoc *a;
11086 
11087  for (a = keyword_to_name; a->id; a++) {
11088  if (a->id == id)
11089  return a->name;
11090  }
11091  return NULL;
11092 }
11093 
11094 #undef ripper_id2sym
11095 static VALUE
11096 ripper_id2sym(ID id)
11097 {
11098  const char *name;
11099  char buf[8];
11100 
11101  if (id <= 256) {
11102  buf[0] = (char)id;
11103  buf[1] = '\0';
11104  return ID2SYM(rb_intern2(buf, 1));
11105  }
11106  if ((name = keyword_id_to_str(id))) {
11107  return ID2SYM(rb_intern(name));
11108  }
11109  switch (id) {
11110  case tOROP:
11111  name = "||";
11112  break;
11113  case tANDOP:
11114  name = "&&";
11115  break;
11116  default:
11117  name = rb_id2name(id);
11118  if (!name) {
11119  rb_bug("cannot convert ID to string: %ld", (unsigned long)id);
11120  }
11121  return ID2SYM(id);
11122  }
11123  return ID2SYM(rb_intern(name));
11124 }
11125 
11126 static ID
11127 ripper_get_id(VALUE v)
11128 {
11129  NODE *nd;
11130  if (!RB_TYPE_P(v, T_NODE)) return 0;
11131  nd = (NODE *)v;
11132  if (nd_type(nd) != NODE_LASGN) return 0;
11133  return nd->nd_vid;
11134 }
11135 
11136 static VALUE
11137 ripper_get_value(VALUE v)
11138 {
11139  NODE *nd;
11140  if (v == Qundef) return Qnil;
11141  if (!RB_TYPE_P(v, T_NODE)) return v;
11142  nd = (NODE *)v;
11143  if (nd_type(nd) != NODE_LASGN) return Qnil;
11144  return nd->nd_rval;
11145 }
11146 
11147 static void
11148 ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
11149 {
11150  VALUE str;
11151  va_list args;
11152 
11153  va_start(args, fmt);
11154  str = rb_vsprintf(fmt, args);
11155  va_end(args);
11156  rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
11157 }
11158 
11159 static void
11160 ripper_warn0(struct parser_params *parser, const char *fmt)
11161 {
11162  rb_funcall(parser->value, rb_intern("warn"), 1, STR_NEW2(fmt));
11163 }
11164 
11165 static void
11166 ripper_warnI(struct parser_params *parser, const char *fmt, int a)
11167 {
11168  rb_funcall(parser->value, rb_intern("warn"), 2,
11169  STR_NEW2(fmt), INT2NUM(a));
11170 }
11171 
11172 static void
11173 ripper_warnS(struct parser_params *parser, const char *fmt, const char *str)
11174 {
11175  rb_funcall(parser->value, rb_intern("warn"), 2,
11176  STR_NEW2(fmt), STR_NEW2(str));
11177 }
11178 
11179 static void
11180 ripper_warning0(struct parser_params *parser, const char *fmt)
11181 {
11182  rb_funcall(parser->value, rb_intern("warning"), 1, STR_NEW2(fmt));
11183 }
11184 
11185 static void
11186 ripper_warningS(struct parser_params *parser, const char *fmt, const char *str)
11187 {
11188  rb_funcall(parser->value, rb_intern("warning"), 2,
11189  STR_NEW2(fmt), STR_NEW2(str));
11190 }
11191 
11192 static VALUE
11193 ripper_lex_get_generic(struct parser_params *parser, VALUE src)
11194 {
11195  return rb_io_gets(src);
11196 }
11197 
11198 static VALUE
11199 ripper_s_allocate(VALUE klass)
11200 {
11201  struct parser_params *p;
11202  VALUE self;
11203 
11204  p = ALLOC_N(struct parser_params, 1);
11205  MEMZERO(p, struct parser_params, 1);
11206  self = TypedData_Wrap_Struct(klass, &parser_data_type, p);
11207  p->value = self;
11208  return self;
11209 }
11210 
11211 #define ripper_initialized_p(r) ((r)->parser_lex_input != 0)
11212 
11213 /*
11214  * call-seq:
11215  * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
11216  *
11217  * Create a new Ripper object.
11218  * _src_ must be a String, an IO, or an Object which has #gets method.
11219  *
11220  * This method does not starts parsing.
11221  * See also Ripper#parse and Ripper.parse.
11222  */
11223 static VALUE
11224 ripper_initialize(int argc, VALUE *argv, VALUE self)
11225 {
11226  struct parser_params *parser;
11227  VALUE src, fname, lineno;
11228 
11229  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11230  rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
11231  if (RB_TYPE_P(src, T_FILE)) {
11232  parser->parser_lex_gets = ripper_lex_get_generic;
11233  }
11234  else {
11235  StringValue(src);
11236  parser->parser_lex_gets = lex_get_str;
11237  }
11238  parser->parser_lex_input = src;
11239  parser->eofp = Qfalse;
11240  if (NIL_P(fname)) {
11241  fname = STR_NEW2("(ripper)");
11242  }
11243  else {
11244  StringValue(fname);
11245  }
11246  parser_initialize(parser);
11247 
11248  parser->parser_ruby_sourcefile_string = fname;
11249  parser->parser_ruby_sourcefile = RSTRING_PTR(fname);
11250  parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
11251 
11252  return Qnil;
11253 }
11254 
11255 struct ripper_args {
11256  struct parser_params *parser;
11257  int argc;
11258  VALUE *argv;
11259 };
11260 
11261 static VALUE
11262 ripper_parse0(VALUE parser_v)
11263 {
11264  struct parser_params *parser;
11265 
11266  TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11267  parser_prepare(parser);
11268  ripper_yyparse((void*)parser);
11269  return parser->result;
11270 }
11271 
11272 static VALUE
11273 ripper_ensure(VALUE parser_v)
11274 {
11275  struct parser_params *parser;
11276 
11277  TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11278  parser->parsing_thread = Qnil;
11279  return Qnil;
11280 }
11281 
11282 /*
11283  * call-seq:
11284  * ripper#parse
11285  *
11286  * Start parsing and returns the value of the root action.
11287  */
11288 static VALUE
11289 ripper_parse(VALUE self)
11290 {
11291  struct parser_params *parser;
11292 
11293  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11294  if (!ripper_initialized_p(parser)) {
11295  rb_raise(rb_eArgError, "method called for uninitialized object");
11296  }
11297  if (!NIL_P(parser->parsing_thread)) {
11298  if (parser->parsing_thread == rb_thread_current())
11299  rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
11300  else
11301  rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
11302  }
11303  parser->parsing_thread = rb_thread_current();
11304  rb_ensure(ripper_parse0, self, ripper_ensure, self);
11305 
11306  return parser->result;
11307 }
11308 
11309 /*
11310  * call-seq:
11311  * ripper#column -> Integer
11312  *
11313  * Return column number of current parsing line.
11314  * This number starts from 0.
11315  */
11316 static VALUE
11317 ripper_column(VALUE self)
11318 {
11319  struct parser_params *parser;
11320  long col;
11321 
11322  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11323  if (!ripper_initialized_p(parser)) {
11324  rb_raise(rb_eArgError, "method called for uninitialized object");
11325  }
11326  if (NIL_P(parser->parsing_thread)) return Qnil;
11327  col = parser->tokp - parser->parser_lex_pbeg;
11328  return LONG2NUM(col);
11329 }
11330 
11331 /*
11332  * call-seq:
11333  * ripper#filename -> String
11334  *
11335  * Return current parsing filename.
11336  */
11337 static VALUE
11338 ripper_filename(VALUE self)
11339 {
11340  struct parser_params *parser;
11341 
11342  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11343  if (!ripper_initialized_p(parser)) {
11344  rb_raise(rb_eArgError, "method called for uninitialized object");
11345  }
11346  return parser->parser_ruby_sourcefile_string;
11347 }
11348 
11349 /*
11350  * call-seq:
11351  * ripper#lineno -> Integer
11352  *
11353  * Return line number of current parsing line.
11354  * This number starts from 1.
11355  */
11356 static VALUE
11357 ripper_lineno(VALUE self)
11358 {
11359  struct parser_params *parser;
11360 
11361  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11362  if (!ripper_initialized_p(parser)) {
11363  rb_raise(rb_eArgError, "method called for uninitialized object");
11364  }
11365  if (NIL_P(parser->parsing_thread)) return Qnil;
11366  return INT2NUM(parser->parser_ruby_sourceline);
11367 }
11368 
11369 #ifdef RIPPER_DEBUG
11370 /* :nodoc: */
11371 static VALUE
11372 ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
11373 {
11374  StringValue(msg);
11375  if (obj == Qundef) {
11376  rb_raise(rb_eArgError, "%s", RSTRING_PTR(msg));
11377  }
11378  return Qnil;
11379 }
11380 
11381 /* :nodoc: */
11382 static VALUE
11383 ripper_value(VALUE self, VALUE obj)
11384 {
11385  return ULONG2NUM(obj);
11386 }
11387 #endif
11388 
11389 
11390 void
11391 Init_ripper(void)
11392 {
11393  parser_data_type.parent = RTYPEDDATA_TYPE(rb_parser_new());
11394 
11397  /* ensure existing in symbol table */
11398  (void)rb_intern("||");
11399  (void)rb_intern("&&");
11400 
11401  InitVM(ripper);
11402 }
11403 
11404 void
11405 InitVM_ripper(void)
11406 {
11407  VALUE Ripper;
11408 
11409  Ripper = rb_define_class("Ripper", rb_cObject);
11410  rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
11411  rb_define_alloc_func(Ripper, ripper_s_allocate);
11412  rb_define_method(Ripper, "initialize", ripper_initialize, -1);
11413  rb_define_method(Ripper, "parse", ripper_parse, 0);
11414  rb_define_method(Ripper, "column", ripper_column, 0);
11415  rb_define_method(Ripper, "filename", ripper_filename, 0);
11416  rb_define_method(Ripper, "lineno", ripper_lineno, 0);
11417  rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
11418  rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
11419  rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
11420  rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
11421 #ifdef RIPPER_DEBUG
11422  rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
11423  rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
11424  rb_define_method(rb_mKernel, "validate_object", ripper_validate_object, 1);
11425 #endif
11426 
11429 
11430 # if 0
11431  /* Hack to let RDoc document SCRIPT_LINES__ */
11432 
11433  /*
11434  * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
11435  * after the assignment will be added as an Array of lines with the file
11436  * name as the key.
11437  */
11438  rb_define_global_const("SCRIPT_LINES__", Qnil);
11439 #endif
11440 
11441 }
11442 #endif /* RIPPER */
VALUE data
Definition: tcltklib.c:3368
#define STR_FUNC_QWORDS
#define rb_enc_islower(c, enc)
char * parser_ruby_sourcefile
Definition: ripper.c:560
#define RB_TYPE_P(obj, type)
#define keyword_when
Definition: ripper.c:200
VALUE val
Definition: parse.h:278
#define get_value(val)
Definition: ripper.y:459
#define deferred_nodes
Definition: ripper.c:628
#define nd_next
#define nd_type(n)
#define NEW_ARGSCAT(a, b)
#define NODE_DREGX_ONCE
VALUE rb_const_get_at(VALUE, ID)
Definition: variable.c:1877
#define yyparse
Definition: ripper.c:648
#define get_id(id)
Definition: ripper.y:458
#define ALLOC(type)
volatile VALUE tmp
Definition: tcltklib.c:10209
#define NEW_FALSE()
enum lex_state_e state
Definition: lex.c:33
struct local_vars * parser_lvtbl
Definition: ripper.c:556
#define NODE_IF
#define is_class_id(id)
Definition: ripper.y:58
VALUE rb_ary_unshift(VALUE ary, VALUE item)
Definition: array.c:1084
stmt_or_begin
Definition: ripper.y:999
static ID ripper_token2eventid(int tok)
Definition: eventids2.c:273
#define NODE_RESCUE
Definition: lex.c:33
#define local_id(id)
Definition: ripper.y:500
int rb_is_attrset_id(ID id)
Definition: ripper.c:16133
int rb_enc_codelen(int c, rb_encoding *enc)
Definition: encoding.c:952
#define NODE_RETRY
#define NODE_DEFN
static double zero(void)
Definition: isinf.c:51
#define lex_state
Definition: ripper.c:604
#define lex_eol_p()
ssize_t n
Definition: bigdecimal.c:5655
#define tLBRACE
Definition: ripper.c:276
VALUE sym
Definition: tkutil.c:1299
volatile VALUE ary
Definition: tcltklib.c:9713
#define NODE_FALSE
#define NEW_DOT3(b, e)
#define dyna_in_block()
Definition: ripper.y:509
static NODE * remove_begin(NODE *)
static NODE * reg_named_capture_assign_gen(struct parser_params *parser, VALUE regexp, NODE *match)
static struct parser_params * parser_new(void)
Definition: ripper.c:16433
#define RE_OPTION_ONCE
Definition: ripper.y:520
#define FLONUM_P(x)
VP_EXPORT int
Definition: bigdecimal.c:5050
#define NODE_OR
int onig_foreach_name(regex_t *reg, int(*func)(const UChar *, const UChar *, int, int *, regex_t *, void *), void *arg)
Definition: regparse.c:537
#define tokidx
Definition: ripper.y:325
st_table * st_init_table_with_size(const struct st_hash_type *, st_index_t)
Definition: st.c:229
#define NEW_IASGN(v, val)
VALUE rb_get_coverages(void)
Definition: thread.c:5155
static NODE * newline_node(NODE *)
#define NEW_NTH_REF(n)
void rb_bug(const char *fmt,...)
Definition: error.c:290
#define NEW_DASGN_CURR(v, val)
struct token_info * next
Definition: ripper.c:508
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:854
#define FALSE
Definition: nkf.h:174
#define modifier_if
Definition: ripper.c:223
#define tail
Definition: st.c:108
void rb_mark_tbl(struct st_table *)
Definition: gc.c:2541
int rb_is_class_name(VALUE name)
Definition: ripper.c:16243
struct vtable * used
Definition: ripper.c:425
#define tHEREDOC_BEG
Definition: eventids2.c:7
NODE * rb_parser_compile_file(volatile VALUE vparser, const char *f, VALUE file, int start)
Definition: ripper.c:11132
static int comment_at_top(struct parser_params *parser)
Definition: ripper.c:12209
#define keyword_unless
Definition: ripper.c:195
#define rb_gc_mark_locations(start, end)
Definition: gc.c:2346
size_t strlen(const char *)
static size_t parser_memsize(const void *ptr)
Definition: ripper.c:16390
VALUE parser_lex_nextline
Definition: ripper.c:547
#define rb_warning0(fmt)
Definition: ripper.y:636
VALUE rb_make_exception(int argc, VALUE *argv)
Definition: eval.c:642
static NODE * logop_gen(struct parser_params *, enum node_type, NODE *, NODE *)
static NODE * new_yield_gen(struct parser_params *, NODE *)
#define scan_oct(s, l, e)
Definition: util.h:52
VALUE stack_type
Definition: ripper.c:398
const char * rb_obj_classname(VALUE)
Definition: variable.c:391
VALUE rb_id2str(ID id)
Definition: ripper.c:16007
Win32OLEIDispatch * p
Definition: win32ole.c:786
int parser_ruby__end__seen
Definition: ripper.c:557
#define peek_n(c, n)
#define NODE_DSYM
int parser_command_start
Definition: ripper.c:552
static NODE * gettable_gen(struct parser_params *, ID)
#define logop(type, node1, node2)
Definition: ripper.y:364
static void fixpos(NODE *, NODE *)
Definition: ripper.c:13811
#define tokcopy(n)
#define NODE_DEFS
static NODE * match_op_gen(struct parser_params *, NODE *, NODE *)
#define NEW_CALL(r, m, a)
int st_lookup(st_table *, st_data_t, st_data_t *)
void st_add_direct(st_table *, st_data_t, st_data_t)
Definition: st.c:624
#define nd_body
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2098
#define is_notop_id(id)
Definition: ripper.y:52
#define NODE_HASH
#define keyword_do_LAMBDA
Definition: ripper.c:212
static ID shadowing_lvar_gen(struct parser_params *, ID)
#define NODE_DOT3
#define local_var(id)
Definition: ripper.y:496
const char * name
Definition: lex.c:33
#define lex_pend
Definition: ripper.y:333
#define tEMBDOC_BEG
Definition: eventids2.c:3
static int parser_tokadd_utf8(struct parser_params *parser, rb_encoding **encp, int string_literal, int symbol_literal, int regexp_literal)
Definition: ripper.c:11319
int parser_compile_for_eval
Definition: ripper.c:538
int parser_token_info_enabled
Definition: ripper.c:574
#define NEW_ALIAS(n, o)
#define NEW_OP_CDECL(v, op, val)
int parser_brace_nest
Definition: ripper.c:537
#define keyword_yield
Definition: ripper.c:214
#define IS_lex_state_for(x, ls)
Definition: ripper.y:99
mlhs_head mlhs_item
Definition: ripper.y:1513
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:108
static void parser_heredoc_restore(struct parser_params *parser, NODE *here)
Definition: ripper.c:11978
#define rb_usascii_str_new2
#define NEW_TRUE()
#define nd_resq
#define NODE_NTH_REF
void rb_define_global_const(const char *, VALUE)
Definition: variable.c:2211
void rb_gc_force_recycle(VALUE)
Definition: gc.c:2961
ssize_t i
Definition: bigdecimal.c:5655
#define newtok()
#define tEQ
Definition: ripper.c:253
#define NODE_TRUE
static NODE * new_args_gen(struct parser_params *, NODE *, NODE *, ID, NODE *, NODE *)
#define nd_term(node)
Definition: ripper.y:535
#define yydebug
Definition: ripper.y:344
#define tLOWEST
Definition: ripper.c:295
#define is_local_id(id)
Definition: ripper.y:53
static int dvar_defined_gen(struct parser_params *, ID, int)
static ID internal_id_gen(struct parser_params *)
#define T_NODE
static struct symbols global_symbols
#define keyword__ENCODING__
Definition: ripper.c:234
#define rb_enc_name(enc)
VALUE rb_parser_end_seen_p(VALUE vparser)
Definition: ripper.c:16458
static int literal_concat0(struct parser_params *, VALUE, VALUE)
#define ESCAPE_META
int line_count
Definition: ripper.c:558
#define brace_nest
Definition: ripper.y:318
#define reg_named_capture_assign(regexp, match)
Definition: ripper.y:456
#define NEW_EVSTR(n)
#define NODE_ARGS
#define NEW_NEXT(s)
struct token_info token_info
#define no_digits()
#define tRPAREN
Definition: ripper.c:274
stack_type parser_cmdarg_stack
Definition: ripper.c:531
#define keyword_return
Definition: ripper.c:213
#define RFLOAT_VALUE(v)
static void rb_backref_error_gen(struct parser_params *, NODE *)
#define assignable(id, node)
Definition: ripper.y:423
#define strcasecmp
Definition: win32.h:200
#define HEAPCNT(n, size)
#define ruby__end__seen
Definition: ripper.y:340
VALUE rb_enc_from_encoding(rb_encoding *encoding)
Definition: encoding.c:103
static NODE * block_append_gen(struct parser_params *, NODE *, NODE *)
#define NEW_NIL()
#define token_info_push(token)
Definition: ripper.c:967
#define tAMPER
Definition: ripper.c:280
#define ruby_debug_lines
Definition: ripper.y:349
#define lex_lastline
Definition: ripper.y:329
Real * a
Definition: bigdecimal.c:1182
static VALUE debug_lines(const char *f)
Definition: ripper.c:10909
#define NODE_ENSURE
VALUE rb_eTypeError
Definition: error.c:511
#define local_pop()
Definition: ripper.y:494
#define rb_enc_isalnum(c, enc)
static int parser_here_document(struct parser_params *, NODE *)
Definition: ripper.c:12025
#define OBJ_FREEZE(x)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
long(* rb_magic_comment_length_t)(struct parser_params *parser, const char *name, long len)
Definition: ripper.c:12221
#define NEW_ZARRAY()
st_table * names
Definition: encoding.c:53
#define rb_enc_prev_char(s, p, e, enc)
VALUE enc
Definition: tcltklib.c:10311
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
NODE * kw_args
Definition: ripper.y:517
#define MAX_WORD_LENGTH
Definition: lex.c:43
VALUE rb_eEncodingError
Definition: error.c:517
#define value_expr(node)
Definition: ripper.y:372
static int reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end, int back_num, int *back_refs, OnigRegex regex, void *arg0)
Definition: ripper.c:15384
static void warn_unused_var(struct parser_params *parser, struct local_vars *local)
Definition: ripper.c:15109
#define keyword_do_block
Definition: ripper.c:211
#define TYPE(x)
struct RBasic basic
Definition: ripper.y:843
#define is_const_id(id)
Definition: ripper.y:57
#define lex_gets_ptr
Definition: ripper.y:337
#define nd_else
rb_encoding * rb_enc_compatible(VALUE str1, VALUE str2)
Definition: encoding.c:787
#define NODE_PRELUDE
#define RSTRING_PTR(str)
#define NEW_MATCH2(n1, n2)
VALUE op_sym[tLAST_OP_ID]
Definition: ripper.c:15598
VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline)
Definition: re.c:2530
#define T_ARRAY
static NODE * arg_blk_pass(NODE *, NODE *)
VALUE debug_lines
Definition: ripper.c:570
#define tEQQ
Definition: ripper.c:254
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:439
#define lex_strterm
Definition: ripper.y:311
#define warn_balanced(op, syn)
Definition: ripper.c:12478
#define NEW_LAMBDA(a, b)
#define NEW_POSTEXE(b)
#define NEW_STR(s)
VALUE var
Definition: tcltklib.c:5517
#define set_yylval_str(x)
#define yyerrok
Definition: ripper.c:4447
#define NODE_EVSTR
#define xfree
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
#define cond_stack
Definition: ripper.y:313
#define tSYMBOLS_BEG
Definition: ripper.c:288
#define NODE_DXSTR
static void ripper_init_eventids1_table(VALUE self)
Definition: eventids1.c:270
#define NODE_CASE
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
static NODE * assignable_gen(struct parser_params *, ID, NODE *)
#define lex_p
Definition: ripper.y:332
#define T_HASH
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:764
#define keyword__FILE__
Definition: ripper.c:233
ID * tbl
Definition: ripper.c:416
void rb_compile_warn(const char *file, int line, const char *fmt,...)
Definition: error.c:172
static NODE * range_op(struct parser_params *parser, NODE *node)
Definition: ripper.c:14767
#define T_FILE
int pre_args_num
Definition: ripper.y:509
#define gettable(id)
Definition: ripper.y:421
static NODE * new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs)
#define IS_SPCARG(c)
#define tASSOC
Definition: ripper.c:271
#define NEW_CONST(v)
int parser_toksiz
Definition: ripper.c:543
#define tSTRING_DVAR
Definition: ripper.c:292
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:884
#define tLAST_TOKEN
Definition: ripper.c:297
#define current_enc
Definition: ripper.y:343
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
#define keyword_nil
Definition: ripper.c:217
static void parser_pushback(struct parser_params *parser, int c)
Definition: ripper.c:11247
NODE * kw_rest_arg
Definition: ripper.y:518
#define keyword_END
Definition: ripper.c:231
static void block_dup_check_gen(struct parser_params *, NODE *, NODE *)
static int parser_yyerror(struct parser_params *, const char *)
#define NODE_STR
#define parser_encoding_name()
#define tokadd_escape(e)
ID last_id
Definition: ripper.c:15591
#define RFLOAT(obj)
#define NODE_REDO
#define NODE_NEXT
const char * alias
Definition: nkf.c:1151
#define keyword_class
Definition: ripper.c:186
#define NEW_DVAR(v)
void(* rb_magic_comment_setter_t)(struct parser_params *parser, const char *name, const char *val)
Definition: ripper.c:12222
#define keyword_next
Definition: ripper.c:205
r
Definition: bigdecimal.c:1196
#define is_asgn_or_id(id)
Definition: ripper.y:62
#define ID_LOCAL
#define ruby_sourcefile
Definition: compile.c:424
static VALUE reg_compile_gen(struct parser_params *, VALUE, int)
Definition: ripper.y:82
#define NODE_XSTR
#define tLPAREN_ARG
Definition: ripper.c:273
#define tMATCH
Definition: ripper.c:260
#define yyerror(msg)
Definition: ripper.y:307
#define NEW_CVASGN(v, val)
static int parser_whole_match_p(struct parser_params *parser, const char *eos, long len, int indent)
Definition: ripper.c:11995
#define NODE_BLOCK_PASS
#define ruby_coverage
Definition: ripper.y:350
int state
Definition: tcltklib.c:1462
#define CMDARG_PUSH(n)
Definition: ripper.y:118
#define ISDIGIT(c)
mlhs_item mlhs_head
Definition: ripper.y:1585
#define RE_OPTION_MASK
Definition: ripper.y:525
#define NEW_BREAK(s)
unsigned int last
Definition: nkf.c:4310
#define NEW_OP_ASGN_OR(i, val)
static void parser_initialize(struct parser_params *parser)
Definition: ripper.c:16291
#define NEW_MASGN(l, r)
ID block_arg
Definition: ripper.y:515
#define ENCODING_IS_ASCII8BIT(obj)
static VALUE parse(int argc, VALUE *argv, VALUE self)
Definition: psych_parser.c:229
#define InitVM(ext)
static void local_pop_gen(struct parser_params *)
ID rb_check_id(volatile VALUE *namep)
Returns ID for the given name if it is interned already, or 0.
Definition: ripper.c:16162
#define STR_NEW3(p, n, e, func)
Definition: ripper.y:302
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
Definition: ripper.c:16209
static NODE * yycompile(struct parser_params *parser, const char *f, int line)
Definition: ripper.c:11009
struct RNode * node
Definition: ripper.y:244
static ID * vtable_tblcpy(ID *buf, const struct vtable *src)
Definition: ripper.c:15159
#define whole_match_p(e, l, i)
#define tLAMBEG
Definition: ripper.c:294
rb_encoding * rb_utf8_encoding(void)
Definition: encoding.c:1166
#define ID2SYM(x)
VALUE parser_lex_input
Definition: ripper.c:545
static long parser_encode_length(struct parser_params *parser, const char *name, long len)
Definition: ripper.c:12157
#define T_FLOAT
VALUE tbl
Definition: tkutil.c:1280
#define is_identchar(p, e, enc)
#define NEW_LVAR(v)
static NODE * call_bin_op_gen(struct parser_params *, NODE *, ID, NODE *)
VALUE VALUE args
Definition: tcltklib.c:2561
#define rb_enc_isdigit(c, enc)
#define T_OBJECT
#define parser_warn(node, mesg)
static enum node_type nodetype(NODE *node)
Definition: ripper.c:13789
#define ENC_CODERANGE_BROKEN
VALUE rb_sym_all_symbols(void)
Definition: ripper.c:16100
#define tSTRING_CONTENT
Definition: ripper.c:244
static VALUE lex_getline(struct parser_params *parser)
Definition: ripper.c:11048
error stmt
Definition: ripper.y:1015
#define CMDARG_P()
Definition: ripper.y:121
#define ID_INTERNAL
#define dvar_defined(id)
Definition: ripper.y:512
#define LONG2NUM(x)
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2114
#define RUBY_DTRACE_PARSE_BEGIN(arg0, arg1)
Definition: probes.h:68
int pos
Definition: ripper.c:417
#define tok()
#define NEW_FOR(v, i, b)
#define tBACK_REF
Definition: ripper.c:247
#define NEW_CLASS(n, b, s)
#define COND_LEXPOP()
Definition: ripper.y:115
#define IS_BEG()
#define reg_fragment_setenc(str, options)
Definition: ripper.y:452
#define evstr2dstr(n)
Definition: ripper.y:398
#define NODE_GASGN
int rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
Definition: ripper.c:15804
#define NEW_SPLAT(a)
#define node_assign(node1, node2)
Definition: ripper.y:433
#define rb_warnI(fmt, a)
Definition: ripper.y:633
#define ID_SCOPE_SHIFT
flag
Definition: tcltklib.c:2048
static int local_var_gen(struct parser_params *, ID)
VALUE rb_parser_set_yydebug(VALUE self, VALUE flag)
Definition: ripper.c:16503
#define dvar_defined_get(id)
Definition: ripper.y:513
#define NEW_PRELUDE(p, b)
#define void_expr0(node)
Definition: ripper.y:373
d
Definition: strlcat.c:58
gz lineno
Definition: zlib.c:2268
#define NEW_ITER(a, b)
#define regx_options()
#define head
Definition: st.c:107
const char * fmt
Definition: tcltklib.c:841
#define TOK_INTERN(mb)
Definition: ripper.y:304
#define ENCODING_GET(obj)
int parser_yydebug
Definition: ripper.c:564
#define dispatch_heredoc_end()
static int dvar_curr_gen(struct parser_params *, ID)
#define keyword_begin
Definition: ripper.c:190
st_table * id_str
Definition: ripper.c:15593
NODE * parser_eval_tree
Definition: ripper.c:569
NODE * parser_deferred_nodes
Definition: ripper.c:553
#define POINTER_P(val)
Definition: ripper.y:140
static int simple_re_meta(int c)
Definition: ripper.c:11624
#define NEW_GVAR(v)
command_asgn lhs
Definition: ripper.y:1266
Definition: ripper.y:240
static int e_option_supplied(struct parser_params *parser)
Definition: ripper.c:10943
Definition: parse.h:276
int has_shebang
Definition: ripper.c:559
#define NEW_DSTR(s)
#define nd_set_type(n, t)
#define peek(c)
static int assign_in_cond(struct parser_params *parser, NODE *node)
Definition: ripper.c:14697
#define ISALPHA(c)
Definition: ruby.h:1636
#define MEMZERO(p, type, n)
#define modifier_rescue
Definition: ripper.c:227
void rb_exc_raise(VALUE mesg)
Definition: eval.c:527
#define NEW_UNLESS(c, t, e)
static NODE * node_assign_gen(struct parser_params *, NODE *, NODE *)
#define NEW_MODULE(n, b)
unsigned long st_data_t
Definition: ripper.y:35
#define strtod(s, e)
Definition: util.h:76
VALUE rb_usascii_str_new(const char *, long)
Definition: string.c:431
static rb_encoding * must_be_ascii_compatible(VALUE s)
Definition: ripper.c:11018
#define parser_is_identchar()
struct vtable * prev
Definition: ripper.c:419
int rb_is_const_id(ID id)
Definition: ripper.c:16109
#define block_dup_check(n1, n2)
Definition: ripper.y:380
int rb_is_instance_id(ID id)
Definition: ripper.c:16127
#define tokadd(c)
#define RUBY_DTRACE_PARSE_END(arg0, arg1)
Definition: probes.h:72
static void local_push_gen(struct parser_params *, int)
#define is_junk_id(id)
Definition: ripper.y:59
static void new_bv_gen(struct parser_params *, ID)
static ID register_symid(ID, const char *, long, rb_encoding *)
static int parser_tokadd_string(struct parser_params *, int, int, int, long *, rb_encoding **)
Definition: ripper.c:11637
VALUE hash
Definition: tkutil.c:267
int rb_is_method_name(VALUE name)
Definition: ripper.c:16273
#define keyword_not
Definition: ripper.c:222
#define DVARS_INHERIT
Definition: ripper.y:137
#define NEW_OP_ASGN_AND(i, val)
rb_encoding * enc
Definition: ripper.c:562
#define nd_args
#define tCMP
Definition: ripper.c:252
#define NODE_LVAR
static int parser_regx_options(struct parser_params *)
Definition: ripper.c:11565
#define reg_fragment_check(str, options)
Definition: ripper.y:454
enum lex_state_e parser_lex_state
Definition: ripper.c:529
#define NODE_LASGN
#define IS_LABEL_POSSIBLE()
int capa
Definition: ripper.c:418
VALUE parser_lex_lastline
Definition: ripper.c:546
#define NEW_OPT_N(b)
#define lex_goto_eol(parser)
#define tLBRACK
Definition: ripper.c:275
#define tGEQ
Definition: ripper.c:256
NODE * rb_parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
Definition: ripper.c:11097
#define tRSHFT
Definition: ripper.c:267
#define NEW_KW_ARG(i, v)
BDIGIT m
Definition: bigdecimal.c:5085
#define DVARS_TOPSCOPE
Definition: ripper.y:138
static ID * local_tbl_gen(struct parser_params *)
static int parser_yylex(struct parser_params *parser)
Definition: ripper.c:12484
static VALUE parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *enc0)
Definition: ripper.c:11169
#define scan_hex(s, l, e)
Definition: util.h:54
#define FIXNUM_P(f)
#define rb_intern_str(string)
Definition: generator.h:17
#define tNMATCH
Definition: ripper.c:261
#define tDOT2
Definition: ripper.c:262
static NODE * aryset_gen(struct parser_params *, NODE *, NODE *)
int rb_char_to_option_kcode(int c, int *option, int *kcode)
Definition: re.c:301
static char * parser_tokspace(struct parser_params *parser, int n)
Definition: ripper.c:11280
#define TypedData_Get_Struct(obj, type, data_type, sval)
#define keyword_def
Definition: ripper.c:188
void rb_compile_error_append(const char *fmt,...)
Definition: error.c:150
#define RARRAY_LEN(a)
static void parser_free(void *ptr)
Definition: ripper.c:16370
#define tCHAR
Definition: ripper.c:245
#define NODE_WHEN
#define Qnil
Definition: tcltklib.c:1896
#define StringValuePtr(v)
static NODE * dsym_node_gen(struct parser_params *, NODE *)
#define val
Definition: tcltklib.c:1949
int rb_ispunct(int c)
Definition: encoding.c:1890
#define block_append(h, t)
Definition: ripper.y:383
VALUE rb_eRuntimeError
Definition: error.c:510
#define Qtrue
static int symbols_i(VALUE sym, ID value, VALUE ary)
Definition: ripper.c:16077
const rb_data_type_t * parent
Definition: ripper.y:969
#define ruby_eval_tree
Definition: ripper.y:347
#define NEW_RESCUE(b, res, e)
#define RARRAY(obj)
#define tFLOAT
Definition: ripper.c:243
static int parser_tokadd_escape(struct parser_params *parser, rb_encoding **encp)
Definition: ripper.c:11492
VALUE rb_parser_encoding(VALUE vparser)
Definition: ripper.c:16473
union RNode::@81 u2
#define cmdarg_stack
Definition: ripper.y:314
static void vtable_free(struct vtable *tbl)
Definition: ripper.y:168
#define in_single
Definition: ripper.y:319
static void void_expr_gen(struct parser_params *, NODE *)
struct parser_params * parser
Definition: ripper.c:15376
#define NODE_YIELD
#define NEW_NODE(t, a0, a1, a2)
#define NEW_LIST(a)
#define NEW_ENSURE(b, en)
RUBY_EXTERN VALUE rb_mKernel
Definition: ripper.y:1414
static struct @60 op_tbl[]
static VALUE char * str
Definition: tcltklib.c:3547
#define NODE_FLIP2
#define tCVAR
Definition: ripper.c:240
char * ruby_strdup(const char *)
Definition: util.c:454
#define NODE_BLOCK
#define ID_INSTANCE
#define keyword_rescue
Definition: ripper.c:191
NODE * rb_compile_string(const char *f, VALUE s, int line)
Definition: ripper.c:11090
#define keyword_end
Definition: ripper.c:193
#define NEW_BLOCK(a)
#define NEWHEAP()
static struct vtable * vtable_alloc(struct vtable *prev)
Definition: ripper.y:156
#define keyword_super
Definition: ripper.c:215
#define NODE_DASGN_CURR
int parser_paren_nest
Definition: ripper.c:533
VALUE rb_ary_new(void)
Definition: array.c:424
#define NODE_AND
int rb_ascii8bit_encindex(void)
Definition: encoding.c:1160
int flags
Definition: tcltklib.c:3023
unsigned long ID
Definition: ripper.y:105
static int is_global_name_punct(const char c)
Definition: ripper.c:11814
#define NEW_UNDEF(i)
#define ID_JUNK
#define keyword_if
Definition: ripper.c:194
va_end(args)
#define attrset(node, id)
Definition: ripper.y:428
void rb_gc_mark(VALUE)
Definition: gc.c:2598
#define ID_GLOBAL
static char * parser_newtok(struct parser_params *parser)
Definition: ripper.c:11264
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2197
#define mixed_escape(beg, enc1, enc2)
#define tLEQ
Definition: ripper.c:257
RUBY_EXTERN int ffs(int)
Definition: ffs.c:6
#define NEW_WHEN(c, t, e)
top_stmt escape_Qundef($1)
#define aryset(node1, node2)
Definition: ripper.y:426
#define ISASCII(c)
Definition: ruby.h:1629
#define IS_AFTER_OPERATOR()
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:499
#define VTBL_DEBUG
Definition: ripper.y:153
#define arg_append(h, t)
Definition: ripper.y:389
#define assignable_result(x)
static VALUE VALUE obj
Definition: tcltklib.c:3158
#define RSTRING_LEN(str)
static void parser_set_token_info(struct parser_params *parser, const char *name, const char *val)
Definition: ripper.c:12234
static struct st_hash_type symhash
Definition: ripper.c:15601
#define INT2FIX(i)
int idx
Definition: tcltklib.c:9716
#define parser_warning(node, mesg)
VALUE value
Definition: ripper.y:246
#define compile_for_eval
Definition: ripper.y:321
#define tSYMBEG
Definition: ripper.c:282
#define arg_var(id)
Definition: ripper.y:498
static void parser_tokadd(struct parser_params *parser, int c)
Definition: ripper.c:11292
#define FIX2LONG(x)
#define k__END__
Definition: eventids2.c:9
static void parser_mark(void *ptr)
Definition: ripper.c:16344
#define ISALNUM(c)
Definition: ruby.h:1635
#define op_tbl_count
#define LVAR_USED
#define T_STRING
#define lex_nextline
Definition: ripper.y:330
#define MBCLEN_CHARFOUND_P(ret)
#define keyword_defined
Definition: ripper.c:229
static double one(void)
Definition: isinf.c:52
static void dyna_pop_gen(struct parser_params *, const struct vtable *)
#define set_yylval_literal(x)
unsigned char OnigUChar
Definition: ripper.y:114
#define NODE_ARGSCAT
#define NODE_COLON2
#define new_args_tail(k, kr, b)
Definition: ripper.y:409
NODE * rb_parser_append_print(VALUE vparser, NODE *node)
Definition: ripper.c:15485
#define nd_set_line(n, l)
pure_parser parse param
Definition: ripper.y:684
#define xmalloc
#define xrealloc
static void ripper_init_eventids1(void)
Definition: eventids1.c:134
#define NIL_P(v)
#define lex_input
Definition: ripper.y:328
#define tSTRING_DBEG
Definition: ripper.c:290
#define parser_precise_mbclen()
#define rb_warn0(fmt)
Definition: ripper.y:632
static NODE * parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
Definition: ripper.c:11071
#define keyword_undef
Definition: ripper.c:189
#define list_concat(h, t)
Definition: ripper.y:387
#define NEW_ARGS_AUX(r, b)
#define TypedData_Wrap_Struct(klass, data_type, sval)
#define RSTRING_NOEMBED
static VALUE coverage(const char *f, int n)
Definition: ripper.c:10926
#define rb_warningS(fmt, a)
Definition: ripper.y:637
static VALUE lex_get_str(struct parser_params *parser, VALUE s)
Definition: ripper.c:11028
#define ISUPPER(c)
Definition: ruby.h:1633
#define RUBY_FUNC_EXPORTED
Definition: defines.h:184
#define literal_concat(h, t)
Definition: ripper.y:393
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
VALUE rb_suppress_tracing(VALUE(*func)(VALUE), VALUE arg)
Definition: vm_trace.c:344
static int rb_str_symname_type(VALUE name)
Definition: ripper.c:15810
#define is_global_id(id)
Definition: ripper.y:54
VALUE rb_enc_associate_index(VALUE obj, int idx)
Definition: encoding.c:746
int rb_parse_in_main(void)
Definition: compile.c:5882
static int parser_nextc(struct parser_params *parser)
Definition: ripper.c:11191
#define compile_error
Definition: ripper.y:659
int err
Definition: win32.c:87
#define dyna_pop(node)
Definition: ripper.c:799
#define tCONSTANT
Definition: ripper.c:239
#define tXSTRING_BEG
Definition: ripper.c:284
static VALUE VALUE assoc
Definition: tkutil.c:545
#define tSTRING_DEND
Definition: ripper.c:291
const char * parser_lex_pend
Definition: ripper.c:550
#define NEW_DEFINED(e)
#define DBL2NUM(dbl)
#define ALLOCA_N(type, n)
#define cur_mid
Definition: ripper.y:322
#define ENC_CODERANGE_UNKNOWN
void rb_gc_mark_symbols(void)
Definition: ripper.c:15653
long cnt
Definition: ripper.y:262
ID token
Definition: ripper.c:15558
static int VALUE key
Definition: tkutil.c:265
static ID intern_str(VALUE str)
Definition: ripper.c:15878
NODE * rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
Definition: ripper.c:15517
#define heredoc_end
Definition: ripper.y:334
NODE * rb_compile_cstr(const char *f, const char *s, int len, int line)
Definition: ripper.c:11104
token_info * parser_token_info
Definition: ripper.c:575
#define STR_FUNC_ESCAPE
#define tokaddmbc(c, enc)
static void magic_comment_encoding(struct parser_params *parser, const char *name, const char *val)
Definition: ripper.c:12225
int column
Definition: ripper.c:506
#define tREGEXP_BEG
Definition: ripper.c:285
#define END(no)
Definition: re.c:26
#define EOF
Definition: vsnprintf.c:207
#define keyword_self
Definition: ripper.c:216
#define set_yylval_name(x)
#define pushback(c)
VALUE rb_str_buf_cat(VALUE, const char *, long)
Definition: string.c:1940
#define STR_NEW2(p)
Definition: ripper.y:301
#define ruby_verbose
void * rb_parser_malloc(struct parser_params *parser, size_t size)
Definition: ripper.c:16519
VALUE rb_str_dup(VALUE)
Definition: string.c:946
#define DEF_EXPR(n)
Definition: ripper.c:375
#define tHEREDOC_END
Definition: eventids2.c:8
#define rb_long2int(n)
#define ID_CLASS
static int parser_peek_variable_name(struct parser_params *parser)
Definition: ripper.c:11821
static NODE * splat_array(NODE *)
#define NEW_LASGN(v, val)
node_type
Definition: ripper.y:23
static VALUE yycompile0(VALUE arg)
Definition: ripper.c:10949
VALUE rb_obj_as_string(VALUE)
Definition: string.c:895
VALUE * argv
Definition: tcltklib.c:1971
#define NODE_MEMO
#define tokenbuf
Definition: ripper.y:324
#define NEW_OPT_ARG(i, v)
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
#define in_defined
Definition: ripper.y:323
#define command_start
Definition: ripper.c:627
#define heredoc_identifier()
static int value_expr_gen(struct parser_params *, NODE *)
string_type
Definition: ripper.c:11157
int rb_dvar_defined(ID id)
Definition: compile.c:5832
static void dispose_string(VALUE str)
Definition: ripper.c:11601
VALUE rb_str_resize(VALUE, long)
Definition: string.c:1846
int parser_in_single
Definition: ripper.c:535
#define RTEST(v)
#define tCOLON3
Definition: ripper.c:269
lex_state_bits
Definition: ripper.c:359
const int id
Definition: nkf.c:209
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
Definition: st.c:1000
#define NEW_SCLASS(r, b)
#define tWORDS_BEG
Definition: ripper.c:286
#define RUBY_DTRACE_PARSE_END_ENABLED()
Definition: probes.h:71
#define cond(node)
Definition: ripper.y:362
#define tSTAR
Definition: ripper.c:278
static NODE * call_uni_op_gen(struct parser_params *, NODE *, ID)
ID rest_arg
Definition: ripper.y:514
#define ret_args(node)
Definition: ripper.y:413
#define new_const_op_assign(lhs, op, rhs)
Definition: ripper.y:439
static int reg_fragment_check_gen(struct parser_params *, VALUE, int)
int errno
#define TRUE
Definition: nkf.h:175
int rb_symname_p(const char *name)
Definition: ripper.c:15697
q result
Definition: tcltklib.c:7070
#define NODE_NIL
VALUE rb_thread_current(void)
Definition: thread.c:2350
#define modifier_until
Definition: ripper.c:226
mlhs_head tSTAR mlhs_node
Definition: ripper.y:1521
#define NODE_ATTRASGN
#define token_info_pop(token)
Definition: ripper.c:968
VALUE rb_range_new(VALUE, VALUE, int)
Definition: range.c:67
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1270
volatile VALUE value
Definition: tcltklib.c:9442
#define NODE_COLON3
#define StringValue(v)
#define NODE_DEFINED
#define rb_enc_mbcput(c, buf, enc)
#define rb_node_newnode(type, a1, a2, a3)
Definition: ripper.c:651
static void vtable_add(struct vtable *tbl, ID id)
Definition: ripper.y:180
keyword_super command_args
Definition: ripper.y:1439
static void set_file_encoding(struct parser_params *parser, const char *str, const char *send)
Definition: ripper.c:12396
#define NEW_DOT2(b, e)
#define NODE_MASGN
#define T_REGEXP
#define nd_nth
int rb_is_attrset_name(VALUE name)
Definition: ripper.c:16261
#define tOP_ASGN
Definition: ripper.c:270
#define NEW_DASGN(v, val)
register char * s
Definition: os2.c:56
#define NEW_VALIAS(n, o)
int rb_enc_symname_p(const char *name, rb_encoding *enc)
Definition: ripper.c:15703
#define NEW_POSTARG(i, v)
static int arg_var_gen(struct parser_params *, ID)
#define CONST_ID(var, str)
#define NEW_ERRINFO()
#define str_copy(_s, _p, _n)
void Init_sym(void)
Definition: ripper.c:15634
#define NODE_CONST
static int parser_parse_string(struct parser_params *, NODE *)
Definition: ripper.c:11857
#define tokadd_string(f, t, p, n, e)
VP_EXPORT void
Definition: bigdecimal.c:5083
#define void_stmts(node)
Definition: ripper.y:376
#define ENC_SINGLE(cr)
Definition: ripper.y:303
#define keyword_false
Definition: ripper.c:219
int rb_is_local_id(ID id)
Definition: ripper.c:16139
rb_magic_comment_length_t length
Definition: ripper.c:12258
int parser_in_def
Definition: ripper.c:536
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1566
#define NEW_SUPER(a)
#define keyword_or
Definition: ripper.c:221
mlhs mlhs_inner
Definition: ripper.y:1480
#define NEW_COLON2(c, i)
static NODE * new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
VALUE parser_cur_mid
Definition: ripper.c:539
VALUE rb_io_gets(VALUE)
Definition: io.c:3076
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:545
#define RE_OPTION_ENCODING_IDX(o)
Definition: ripper.y:523
static void Init_id(void)
Definition: ripper.y:15
long parser_lex_gets_ptr
Definition: ripper.c:554
#define NODE_GVAR
#define NODE_CDECL
rb_encoding * rb_usascii_encoding(void)
Definition: encoding.c:1181
#define new_args(f, o, r, p, t)
Definition: ripper.y:407
#define NEW_HASH(a)
#define RARRAY_PTR(a)
#define keyword_until
Definition: ripper.c:202
union RNode::@82 u3
static void arg_ambiguous_gen(struct parser_params *parser)
Definition: ripper.c:12128
#define nextc()
static void parser_prepare(struct parser_params *parser)
Definition: ripper.c:12439
#define reg_compile(str, options)
Definition: ripper.y:450
#define RB_GC_GUARD(v)
#define IS_lex_state(ls)
Definition: ripper.y:100
#define NODE_LIT
#define rb_reserved_word(str, len)
Definition: lex.c:37
int type
Definition: tcltklib.c:111
int id[2]
Definition: lex.c:33
#define NEW_UNTIL(c, b, n)
#define T_FIXNUM
#define tANDOP
Definition: ripper.c:258
#define tPOW
Definition: ripper.c:251
#define dsym_node(node)
Definition: ripper.y:418
#define NEW_MATCH3(r, n2)
struct parser_params * parser
Definition: ripper.c:4578
int argc
Definition: tcltklib.c:1970
#define STR_NEW(p, n)
Definition: ripper.y:299
VALUE rb_str_buf_new(long)
Definition: string.c:777
stack_type parser_cond_stack
Definition: ripper.c:530
#define STR_FUNC_SYMBOL
NODE * post_init
Definition: ripper.y:507
#define modifier_while
Definition: ripper.c:225
static void reduce_nodes_gen(struct parser_params *, NODE **)
#define set_yylval_num(x)
#define tokspace(n)
static void ripper_init_eventids2(void)
Definition: eventids2.c:64
int rb_const_defined_at(VALUE, ID)
Definition: variable.c:2104
int rb_is_junk_id(ID id)
Definition: ripper.c:16145
static void dyna_pop_1(struct parser_params *parser)
Definition: ripper.c:15245
#define nd_paren(node)
Definition: ripper.y:537
static int parser_read_escape(struct parser_params *parser, int flags, rb_encoding **encp)
Definition: ripper.c:11394
int parser_heredoc_end
Definition: ripper.c:551
#define ruby_sourceline
Definition: ripper.c:633
static int parser_heredoc_identifier(struct parser_params *parser)
Definition: ripper.c:11915
#define dyna_push()
Definition: ripper.y:505
ID rb_id_attrset(ID id)
Definition: ripper.c:14326
Definition: ripper.y:72
#define parse_string(n)
int post_args_num
Definition: ripper.y:510
int rb_is_global_id(ID id)
Definition: ripper.c:16121
#define tok_hex(numlen)
#define local_push(top)
Definition: ripper.y:492
#define COND_PUSH(n)
Definition: ripper.y:113
#define NEW_SELF()
#define new_attr_op_assign(lhs, type, attr, op, rhs)
Definition: ripper.y:437
static NODE * ret_args_gen(struct parser_params *, NODE *)
#define tQSYMBOLS_BEG
Definition: ripper.c:289
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1117
#define new_evstr(n)
Definition: ripper.y:396
#define rb_enc_ispunct(c, enc)
#define paren_nest
Definition: ripper.y:316
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:804
VALUE flags
Definition: ripper.y:700
#define NEW_RESBODY(a, ex, n)
#define NEW_RETURN(s)
#define NODE_ARGSPUSH
#define NODE_BACK_REF
#define NODE_MATCH
#define tokadd_mbchar(c)
static void reg_fragment_setenc_gen(struct parser_params *, VALUE, int)
#define rb_warn4S(file, line, fmt, a)
Definition: ripper.y:635
VALUE rb_reg_check_preprocess(VALUE)
Definition: re.c:2304
#define tOROP
Definition: ripper.c:259
VALUE flags
Definition: ripper.y:241
expr ripper_intern("and")
static int is_static_content(NODE *node)
Definition: ripper.c:14673
static void void_stmts_gen(struct parser_params *, NODE *)
#define tIVAR
Definition: ripper.c:238
#define void_expr(node)
Definition: ripper.y:374
const char * token
Definition: ripper.c:504
#define CMDARG_LEXPOP()
Definition: ripper.y:120
RUBY_EXTERN VALUE rb_cString
Definition: ripper.y:1456
Real * b
Definition: bigdecimal.c:1182
#define NEW_COLON3(i)
#define RUBY_DTRACE_PARSE_BEGIN_ENABLED()
Definition: probes.h:67
#define was_bol()
#define NEW_CASE(h, b)
#define lex_pbeg
Definition: ripper.y:331
return ptr
Definition: tcltklib.c:784
VpDivd * c
Definition: bigdecimal.c:1205
mlhs_head tSTAR mlhs_post
Definition: ripper.y:1529
#define reduce_nodes(n)
Definition: ripper.y:378
#define dyna_var(id)
Definition: ripper.y:510
#define STR_FUNC_EXPAND
static NODE * negate_lit(NODE *)
#define NODE_HEREDOC
Definition: ripper.y:529
#define NODE_DASGN
int parser_in_defined
Definition: ripper.c:540
volatile VALUE msg
Definition: tcltklib.c:3100
#define NEW_BACK_REF(n)
VALUE rb_vsprintf(const char *, va_list)
Definition: sprintf.c:1264
int parser_class_nest
Definition: ripper.c:532
#define T_BIGNUM
static int local_id_gen(struct parser_params *, ID)
#define MEMCPY(p1, p2, type, n)
#define new_op_assign(lhs, op, rhs)
Definition: ripper.y:482
mlhs_node keyword_variable
Definition: ripper.y:1642
#define tFID
Definition: ripper.c:236
#define Qfalse
Definition: tcltklib.c:6834
block_command cmd_brace_block
Definition: ripper.y:1337
gz end
Definition: zlib.c:2270
#define NEW_IF(c, t, e)
#define Qnone
Definition: ripper.y:624
static NODE * new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
static int lvar_defined_gen(struct parser_params *, ID)
#define NEW_GASGN(v, val)
static void warning_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
Definition: ripper.c:14730
#define keyword_in
Definition: ripper.c:208
#define NEW_ARGSPUSH(a, b)
#define lpar_beg
Definition: ripper.y:317
#define heredoc_restore(n)
int rb_is_const_name(VALUE name)
Definition: ripper.c:16237
static void parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc)
Definition: ripper.c:11485
int rb_is_local_name(VALUE name)
Definition: ripper.c:16267
arg
Definition: ripper.y:1312
#define rb_warnS(fmt, a)
Definition: ripper.y:634
static NODE * literal_concat_gen(struct parser_params *, NODE *, NODE *)
VALUE src
Definition: tcltklib.c:7953
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:1956
#define NEW_XSTR(s)
#define tNTH_REF
Definition: ripper.c:246
#define ENC_CODERANGE_7BIT
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:770
#define NEW_WHILE(c, b, n)
#define NEW_DEFS(r, i, a, d)
#define END_OF_INPUT
Definition: ripper.c:185
void rb_gc_mark_parser(void)
Definition: ripper.c:15480
int nonspc
Definition: ripper.c:507
int size
Definition: encoding.c:52
#define f
static int is_private_local_id(ID name)
Definition: ripper.c:14259
static void fixup_nodes(NODE **)
#define SYMBOL_P(x)
#define tIDENTIFIER
Definition: ripper.c:235
#define keyword_then
Definition: ripper.c:196
static int rb_enc_symname_type(const char *name, long len, rb_encoding *enc)
Definition: ripper.c:15709
static void no_blockarg(struct parser_params *parser, NODE *node)
Definition: ripper.c:14883
top_stmt
Definition: ripper.y:902
#define NODE_FLIP3
opt_block_param compstmt
Definition: ripper.y:1353
static NODE * cond_gen(struct parser_params *, NODE *)
void rb_parser_free(struct parser_params *parser, void *ptr)
Definition: ripper.c:16559
#define keyword_break
Definition: ripper.c:204
#define Qundef
int parser_tokidx
Definition: ripper.c:542
#define here_document(n)
#define NODE_DVAR
static struct magic_comment magic_comments[]
Definition: ripper.c:12261
#define match_op(node1, node2)
Definition: ripper.y:442
#define arg_concat(h, t)
Definition: ripper.y:391
static NODE * arg_concat_gen(struct parser_params *, NODE *, NODE *)
#define keyword_do_cond
Definition: ripper.c:210
#define lvtbl
Definition: ripper.y:339
#define rb_compile_error
Definition: ripper.c:950
#define call_uni_op(recv, id)
Definition: ripper.y:404
VALUE coverage
Definition: ripper.c:571
command_call
Definition: ripper.y:1304
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *)
Definition: string.c:569
int t
Definition: ripper.c:13760
void rb_set_errinfo(VALUE err)
Definition: eval.c:1436
#define tLBRACE_ARG
Definition: ripper.c:277
#define tAREF
Definition: ripper.c:264
#define rb_enc_isspace(c, enc)
NODE * parser_lex_strterm
Definition: ripper.c:528
#define RE_OPTION_ENCODING_NONE(o)
Definition: ripper.y:524
const char * name
Definition: ripper.c:12256
top_stmt bodystmt
Definition: ripper.y:921
#define NEW_IVAR(v)
top_stmts dispatch0(stmts_new)
#define tSP
Definition: eventids2.c:6
#define NEW_ATTRASGN(r, m, a)
#define tGVAR
Definition: ripper.c:237
#define NODE_ZARRAY
static int token_info_get_column(struct parser_params *parser, const char *token)
Definition: ripper.c:10771
#define tDOT3
Definition: ripper.c:263
#define formal_argument(id)
Definition: ripper.y:485
#define NEW_BEGIN(b)
NODE * pre_init
Definition: ripper.y:506
#define NEW_FCALL(m, a)
#define NODE_CVAR
static int yylex(void *, void *)
static NODE * list_append_gen(struct parser_params *, NODE *, NODE *)
#define NEW_SCOPE(a, b)
static int token_info_has_nonspaces(struct parser_params *parser, const char *token)
Definition: ripper.c:10785
st_index_t rb_str_hash(VALUE)
Definition: string.c:2237
#define NEW_OP_ASGN2(r, i, o, val)
#define tLABEL
Definition: ripper.c:241
#define NODE_BREAK
#define lex_gets
Definition: ripper.y:338
#define toklen()
static const rb_data_type_t parser_data_type
Definition: ripper.c:11068
rb_magic_comment_setter_t func
Definition: ripper.c:12257
int parser_lpar_beg
Definition: ripper.c:534
void rb_compile_warning(const char *file, int line, const char *fmt,...)
Definition: error.c:185
#define STR_FUNC_INDENT
st_table * sym_id
Definition: ripper.c:15592
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
#define ALLOC_N(type, n)
#define LONG2FIX(i)
#define NODE_FL_NEWLINE
#define RBASIC(obj)
struct local_vars * prev
Definition: ripper.c:426
#define NEW_VCALL(m)
#define keyword_while
Definition: ripper.c:201
static NODE * node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE)
struct vtable * vars
Definition: ripper.c:424
#define SPECIAL_PUNCT(idx)
static VALUE lex_io_gets(struct parser_params *parser, VALUE io)
Definition: ripper.c:11118
static NODE * arg_append_gen(struct parser_params *, NODE *, NODE *)
klass
Definition: tcltklib.c:3504
#define INT2NUM(x)
#define NODE_DSTR
struct rb_encoding_entry * list
Definition: encoding.c:50
#define tSTRING_END
Definition: ripper.c:293
#define NEW_RETRY()
void * rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
Definition: ripper.c:16529
#define STRNCASECMP(s1, s2, n)
rb_encoding * rb_filesystem_encoding(void)
Definition: encoding.c:1246
#define COND_P()
Definition: ripper.y:116
VALUE rb_make_backtrace(void)
Definition: vm_backtrace.c:772
#define keyword_BEGIN
Definition: ripper.c:230
#define RE_OPTION_ENCODING(e)
Definition: ripper.y:522
#define rb_backref_error(n)
Definition: ripper.y:431
#define ESCAPE_CONTROL
int linenum
Definition: ripper.c:505
#define parser_isascii()
#define NEW_CVAR(v)
#define shadowing_lvar(name)
Definition: ripper.y:487
#define keyword_for
Definition: ripper.c:203
#define tEMBDOC
Definition: eventids2.c:4
#define ADD2HEAP(n, c, p)
#define NODE_BEGIN
gz io
Definition: zlib.c:2261
#define in_def
Definition: ripper.y:320
char * parser_tokenbuf
Definition: ripper.c:541
VALUE rb_cArray
Definition: array.c:29
static const char * magic_comment_marker(const char *str, long len)
Definition: ripper.c:12269
#define keyword_do
Definition: ripper.c:209
#define BEG(no)
Definition: re.c:25
#define NEW_OP_ASGN1(p, id, a)
static NODE * list_concat_gen(struct parser_params *, NODE *, NODE *)
#define set_yylval_id(x)
static int parser_magic_comment(struct parser_params *parser, const char *str, long len)
Definition: ripper.c:12302
int parser_tokline
Definition: ripper.c:544
#define is_instance_id(id)
Definition: ripper.y:55
Definition: ripper.y:79
#define call_bin_op(recv, id, arg1)
Definition: ripper.y:402
#define read_escape(flags, e)
VALUE rb_ary_new2(long capa)
Definition: array.c:417
VALUE rb_str_new(const char *, long)
Definition: string.c:425
union RNode::@80 u1
const char * parser_lex_pbeg
Definition: ripper.c:548
int rb_is_class_id(ID id)
Definition: ripper.c:16115
#define keyword_true
Definition: ripper.c:218
#define tUPLUS
Definition: ripper.c:249
#define rb_safe_level()
Definition: tcltklib.c:94
VALUE rb_parser_new(void)
Definition: ripper.c:16444
#define NODE_CVASGN
Definition: ripper.c:415
static void parser_set_encode(struct parser_params *parser, const char *name)
Definition: ripper.c:12177
#define NEW_CDECL(v, val, path)
static int dyna_in_block_gen(struct parser_params *)
static int literal_node(NODE *node)
Definition: ripper.c:14783
#define tokfix()
const char * parser_lex_p
Definition: ripper.c:549
#define nd_lit
#define internal_id()
Definition: ripper.y:502
static int parser_tok_hex(struct parser_params *parser, size_t *numlen)
Definition: ripper.c:11302
#define keyword_else
Definition: ripper.c:198
#define rb_enc_asciicompat(enc)
lex_state_e
Definition: ripper.c:374
#define NUM2INT(x)
#define new_bv(id)
Definition: ripper.y:489
#define tASET
Definition: ripper.c:265
#define nd_head
static NODE * attrset_gen(struct parser_params *, NODE *, ID)
int rb_is_instance_name(VALUE name)
Definition: ripper.c:16255
int parser_ruby_sourceline
Definition: ripper.c:561
const char * rb_id2name(ID id)
Definition: ripper.c:16068
#define NODE_CALL
#define rb_errinfo()
Definition: tcltklib.c:89
#define tNEQ
Definition: ripper.c:255
#define tLPAREN
Definition: ripper.c:272
#define rb_enc_isupper(c, enc)
int cnt
Definition: tcltklib.c:6149
#define keyword__LINE__
Definition: ripper.c:232
#define modifier_unless
Definition: ripper.c:224
static int nodeline(NODE *node)
Definition: ripper.c:13795
#define numberof(array)
Definition: ripper.y:34
YYSTYPE * parser_yylval
Definition: ripper.c:525
static NODE * evstr2dstr_gen(struct parser_params *, NODE *)
#define list_append(l, i)
Definition: ripper.y:385
#define xcalloc
BDIGIT e
Definition: bigdecimal.c:5085
keyword_return call_args
Definition: ripper.y:1457
#define NEW_LIT(l)
#define rb_enc_isascii(c, enc)
static struct vtable * dyna_push_gen(struct parser_params *)
int rb_str_hash_cmp(VALUE, VALUE)
Definition: string.c:2247
#define keyword_module
Definition: ripper.c:187
#define STR_NEW0()
Definition: ripper.y:300
VALUE opts
Definition: tcltklib.c:6146
int is_ripper
Definition: ripper.c:522
unsigned long VALUE
Definition: ripper.y:104
static NODE * cond0(struct parser_params *, NODE *)
Definition: ripper.c:14804
options
Definition: tcltklib.c:4481
rb_encoding * rb_ascii8bit_encoding(void)
Definition: encoding.c:1151
int rb_is_junk_name(VALUE name)
Definition: ripper.c:16283
#define NODE_IVAR
static int vtable_size(const struct vtable *tbl)
Definition: ripper.y:143
#define RREGEXP(obj)
int rb_enc_find_index(const char *name)
Definition: encoding.c:633
VALUE eofp
Definition: ripper.c:526
#define new_yield(node)
Definition: ripper.y:416
#define lvar_defined(id)
Definition: ripper.y:518
static NODE * new_evstr_gen(struct parser_params *, NODE *)
RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e-0x20+31)/32]
Definition: ripper.c:11792
#define STR_FUNC_REGEXP
NODE * heap
Definition: ripper.c:523
#define RSTRING_GETMEM(str, ptrvar, lenvar)
#define keyword_and
Definition: ripper.c:220
static NODE * new_args_tail_gen(struct parser_params *, NODE *, ID, ID)
#define is_attrset_id(id)
Definition: ripper.y:56
ID rb_intern3(const char *name, long len, rb_encoding *enc)
Definition: ripper.c:15856
#define NODE_DOT2
encp
Definition: crypt.c:564
expr expr keyword_or expr
Definition: ripper.y:1288
#define keyword_retry
Definition: ripper.c:207
#define ID_SCOPE_MASK
#define NODE_DREGX
#define NODE_IASGN
#define NEW_DEFN(i, a, d, p)
#define tCOLON2
Definition: ripper.c:268
#define NODE_RETURN
#define snprintf
ID first_post_arg
Definition: ripper.y:512
#define COND_POP()
Definition: ripper.y:114
void * rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
Definition: ripper.c:16539
#define NEW_REDO()
st_table * st_init_numtable_with_size(st_index_t)
Definition: st.c:278
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck)
Definition: bignum.c:579
#define tLSHFT
Definition: ripper.c:266
#define NODE_ARRAY
#define NODE_SPLAT
#define tUMINUS_NUM
Definition: ripper.c:296
#define id_type(id)
Definition: ripper.y:60
#define tUMINUS
Definition: ripper.c:250
#define rb_intern(str)
int rb_parse_in_eval(void)
Definition: compile.c:5876
BDIGIT v
Definition: bigdecimal.c:5656
#define ENCODING_SET(obj, i)
#define keyword_ensure
Definition: ripper.c:192
int rb_memcicmp(const void *, const void *, long)
Definition: re.c:80
#define tCOMMENT
Definition: eventids2.c:2
#define NEW_ZSUPER()
ID rb_intern2(const char *name, long len)
Definition: ripper.c:15984
#define tREGEXP_END
Definition: ripper.c:248
#define keyword_redo
Definition: ripper.c:206
NODE * rb_compile_file(const char *f, VALUE file, int start)
Definition: ripper.c:11124
static int is_special_global_name(const char *m, const char *e, rb_encoding *enc)
Definition: ripper.c:15671
#define tQWORDS_BEG
Definition: ripper.c:287
#define nd_line(n)
VALUE rb_parser_get_yydebug(VALUE self)
Definition: ripper.c:16488
VALUE(* parser_lex_gets)(struct parser_params *, VALUE)
Definition: ripper.c:555
#define IS_LABEL_SUFFIX(n)
#define NULL
Definition: _sdbm.c:103
#define rb_enc_isalpha(c, enc)
const char * name
Definition: nkf.c:208
#define tIGNORED_NL
Definition: eventids2.c:1
NODE * rb_parser_compile_cstr(volatile VALUE vparser, const char *f, const char *s, int len, int line)
Definition: ripper.c:11111
#define subnodes(n1, n2)
#define keyword_alias
Definition: ripper.c:228
VALUE rb_check_string_type(VALUE)
Definition: string.c:1508
#define REALLOC_N(var, type, n)
#define NODE_SCOPE
#define NEW_STRTERM(func, term, paren)
#define set_yylval_node(x)
#define tINTEGER
Definition: ripper.c:242
static struct kwtable * reserved_word(const char *, unsigned int)
int rb_enc_str_coderange(VALUE)
Definition: string.c:327
#define ISXDIGIT(c)
Definition: ruby.h:1638
#define arg_ambiguous()
#define dvar_curr(id)
Definition: ripper.y:515
int rb_local_defined(ID id)
Definition: compile.c:5857
st_index_t num_entries
Definition: ripper.y:93
NODE * parser_eval_tree_begin
Definition: ripper.c:568
static int match(VALUE str, VALUE pat, VALUE hash, int(*cb)(VALUE, VALUE))
Definition: date_parse.c:273
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1340
#define tDSTAR
Definition: ripper.c:279
int retry
Definition: tcltklib.c:10151
#define flush_string_content(enc)
#define IS_ARG()
static void warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
Definition: ripper.c:14724
#define PARSER_ARG
Definition: ripper.y:660
#define NODE_IASGN2
#define ULONG2NUM(x)
#define NODE_SELF
#define ruby_eval_tree_begin
Definition: ripper.y:348
#define ripper_flush(p)
#define IS_END()
#define SYM2ID(x)
#define ID_CONST
#define toklast()
VALUE rb_eArgError
Definition: error.c:512
mlhs mlhs_basic
Definition: ripper.y:1480
#define tSTRING_BEG
Definition: ripper.c:283
#define ifndef_ripper(x)
Definition: ripper.y:625
#define NEW_ARRAY(a)
static ID formal_argument_gen(struct parser_params *, ID)
void rb_str_free(VALUE)
Definition: string.c:830
#define RTYPEDDATA_TYPE(v)
#define keyword_case
Definition: ripper.c:199
unsigned long ruby_scan_oct(const char *, size_t, size_t *)
Definition: util.c:28
#define NODE_VALUES
#define ID_ATTRSET
struct vtable * args
Definition: ripper.c:423
#define tLAMBDA
Definition: ripper.c:281
#define keyword_elsif
Definition: ripper.c:197
#define tEMBDOC_END
Definition: eventids2.c:5
#define toksiz
Definition: ripper.y:326
static void ripper_init_eventids2_table(VALUE self)
Definition: eventids2table.c:2
#define NEW_YIELD(a)
#define ISSPACE(c)
Definition: ruby.h:1632
#define tokline
Definition: ripper.y:327
VALUE rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *enc)
Definition: string.c:2067
static int vtable_included(const struct vtable *tbl, ID id)
Definition: ripper.y:195
VALUE rb_inspect(VALUE)
Definition: object.c:402
static int sym_check_asciionly(VALUE str)
Definition: ripper.c:15836
rb_encoding * rb_enc_from_index(int index)
Definition: encoding.c:548
#define mixed_error(enc1, enc2)
#define NEW_BLOCK_PASS(b)
NODE * opt_args
Definition: ripper.y:520
static ID register_symid_str(ID, VALUE)
int rb_is_global_name(VALUE name)
Definition: ripper.c:16249
static int parser_tokadd_mbchar(struct parser_params *parser, int c)
Definition: ripper.c:11608
size_t len
Definition: tcltklib.c:3568