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