Ruby  1.9.3p392(2013-02-22revision39386)
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  dispatch2(magic_comment, name, val);
6549 #endif
6550  }
6551 
6552  return TRUE;
6553 }
6554 
6555 static void
6556 set_file_encoding(struct parser_params *parser, const char *str, const char *send)
6557 {
6558  int sep = 0;
6559  const char *beg = str;
6560  VALUE s;
6561 
6562  for (;;) {
6563  if (send - str <= 6) return;
6564  switch (str[6]) {
6565  case 'C': case 'c': str += 6; continue;
6566  case 'O': case 'o': str += 5; continue;
6567  case 'D': case 'd': str += 4; continue;
6568  case 'I': case 'i': str += 3; continue;
6569  case 'N': case 'n': str += 2; continue;
6570  case 'G': case 'g': str += 1; continue;
6571  case '=': case ':':
6572  sep = 1;
6573  str += 6;
6574  break;
6575  default:
6576  str += 6;
6577  if (ISSPACE(*str)) break;
6578  continue;
6579  }
6580  if (STRNCASECMP(str-6, "coding", 6) == 0) break;
6581  }
6582  for (;;) {
6583  do {
6584  if (++str >= send) return;
6585  } while (ISSPACE(*str));
6586  if (sep) break;
6587  if (*str != '=' && *str != ':') return;
6588  sep = 1;
6589  str++;
6590  }
6591  beg = str;
6592  while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
6593  s = rb_str_new(beg, parser_encode_length(parser, beg, str - beg));
6594  parser_set_encode(parser, RSTRING_PTR(s));
6595  rb_str_resize(s, 0);
6596 }
6597 
6598 static void
6599 parser_prepare(struct parser_params *parser)
6600 {
6601  int c = nextc();
6602  switch (c) {
6603  case '#':
6604  if (peek('!')) parser->has_shebang = 1;
6605  break;
6606  case 0xef: /* UTF-8 BOM marker */
6607  if (lex_pend - lex_p >= 2 &&
6608  (unsigned char)lex_p[0] == 0xbb &&
6609  (unsigned char)lex_p[1] == 0xbf) {
6610  parser->enc = rb_utf8_encoding();
6611  lex_p += 2;
6612  lex_pbeg = lex_p;
6613  return;
6614  }
6615  break;
6616  case EOF:
6617  return;
6618  }
6619  pushback(c);
6620  parser->enc = rb_enc_get(lex_lastline);
6621 }
6622 
6623 #define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG)
6624 #define IS_END() (lex_state == EXPR_END || lex_state == EXPR_ENDARG || lex_state == EXPR_ENDFN)
6625 #define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_VALUE || lex_state == EXPR_CLASS)
6626 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
6627 #define IS_LABEL_POSSIBLE() ((lex_state == EXPR_BEG && !cmd_state) || IS_ARG())
6628 #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
6629 
6630 #ifndef RIPPER
6631 #define ambiguous_operator(op, syn) ( \
6632  rb_warning0("`"op"' after local variable is interpreted as binary operator"), \
6633  rb_warning0("even though it seems like "syn""))
6634 #else
6635 #define ambiguous_operator(op, syn) dispatch2(operator_ambiguous, ripper_intern(op), rb_str_new_cstr(syn))
6636 #endif
6637 #define warn_balanced(op, syn) ((void) \
6638  (last_state != EXPR_CLASS && last_state != EXPR_DOT && \
6639  last_state != EXPR_FNAME && last_state != EXPR_ENDFN && \
6640  last_state != EXPR_ENDARG && \
6641  space_seen && !ISSPACE(c) && \
6642  (ambiguous_operator(op, syn), 0)))
6643 
6644 static int
6645 parser_yylex(struct parser_params *parser)
6646 {
6647  register int c;
6648  int space_seen = 0;
6649  int cmd_state;
6650  enum lex_state_e last_state;
6651  rb_encoding *enc;
6652  int mb;
6653 #ifdef RIPPER
6654  int fallthru = FALSE;
6655 #endif
6656 
6657  if (lex_strterm) {
6658  int token;
6659  if (nd_type(lex_strterm) == NODE_HEREDOC) {
6660  token = here_document(lex_strterm);
6661  if (token == tSTRING_END) {
6662  lex_strterm = 0;
6663  lex_state = EXPR_END;
6664  }
6665  }
6666  else {
6667  token = parse_string(lex_strterm);
6668  if (token == tSTRING_END || token == tREGEXP_END) {
6670  lex_strterm = 0;
6671  lex_state = EXPR_END;
6672  }
6673  }
6674  return token;
6675  }
6676  cmd_state = command_start;
6677  command_start = FALSE;
6678  retry:
6679  last_state = lex_state;
6680  switch (c = nextc()) {
6681  case '\0': /* NUL */
6682  case '\004': /* ^D */
6683  case '\032': /* ^Z */
6684  case -1: /* end of script. */
6685  return 0;
6686 
6687  /* white spaces */
6688  case ' ': case '\t': case '\f': case '\r':
6689  case '\13': /* '\v' */
6690  space_seen = 1;
6691 #ifdef RIPPER
6692  while ((c = nextc())) {
6693  switch (c) {
6694  case ' ': case '\t': case '\f': case '\r':
6695  case '\13': /* '\v' */
6696  break;
6697  default:
6698  goto outofloop;
6699  }
6700  }
6701  outofloop:
6702  pushback(c);
6703  ripper_dispatch_scan_event(parser, tSP);
6704 #endif
6705  goto retry;
6706 
6707  case '#': /* it's a comment */
6708  /* no magic_comment in shebang line */
6709  if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
6710  if (comment_at_top(parser)) {
6711  set_file_encoding(parser, lex_p, lex_pend);
6712  }
6713  }
6714  lex_p = lex_pend;
6715 #ifdef RIPPER
6716  ripper_dispatch_scan_event(parser, tCOMMENT);
6717  fallthru = TRUE;
6718 #endif
6719  /* fall through */
6720  case '\n':
6721  switch (lex_state) {
6722  case EXPR_BEG:
6723  case EXPR_FNAME:
6724  case EXPR_DOT:
6725  case EXPR_CLASS:
6726  case EXPR_VALUE:
6727 #ifdef RIPPER
6728  if (!fallthru) {
6729  ripper_dispatch_scan_event(parser, tIGNORED_NL);
6730  }
6731  fallthru = FALSE;
6732 #endif
6733  goto retry;
6734  default:
6735  break;
6736  }
6737  while ((c = nextc())) {
6738  switch (c) {
6739  case ' ': case '\t': case '\f': case '\r':
6740  case '\13': /* '\v' */
6741  space_seen = 1;
6742  break;
6743  case '.': {
6744  if ((c = nextc()) != '.') {
6745  pushback(c);
6746  pushback('.');
6747  goto retry;
6748  }
6749  }
6750  default:
6751  --ruby_sourceline;
6753  case -1: /* EOF no decrement*/
6754  lex_goto_eol(parser);
6755 #ifdef RIPPER
6756  if (c != -1) {
6757  parser->tokp = lex_p;
6758  }
6759 #endif
6760  goto normal_newline;
6761  }
6762  }
6763  normal_newline:
6764  command_start = TRUE;
6765  lex_state = EXPR_BEG;
6766  return '\n';
6767 
6768  case '*':
6769  if ((c = nextc()) == '*') {
6770  if ((c = nextc()) == '=') {
6772  lex_state = EXPR_BEG;
6773  return tOP_ASGN;
6774  }
6775  pushback(c);
6776  c = tPOW;
6777  }
6778  else {
6779  if (c == '=') {
6780  set_yylval_id('*');
6781  lex_state = EXPR_BEG;
6782  return tOP_ASGN;
6783  }
6784  pushback(c);
6785  if (IS_SPCARG(c)) {
6786  rb_warning0("`*' interpreted as argument prefix");
6787  c = tSTAR;
6788  }
6789  else if (IS_BEG()) {
6790  c = tSTAR;
6791  }
6792  else {
6793  warn_balanced("*", "argument prefix");
6794  c = '*';
6795  }
6796  }
6797  switch (lex_state) {
6798  case EXPR_FNAME: case EXPR_DOT:
6799  lex_state = EXPR_ARG; break;
6800  default:
6801  lex_state = EXPR_BEG; break;
6802  }
6803  return c;
6804 
6805  case '!':
6806  c = nextc();
6807  if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
6808  lex_state = EXPR_ARG;
6809  if (c == '@') {
6810  return '!';
6811  }
6812  }
6813  else {
6814  lex_state = EXPR_BEG;
6815  }
6816  if (c == '=') {
6817  return tNEQ;
6818  }
6819  if (c == '~') {
6820  return tNMATCH;
6821  }
6822  pushback(c);
6823  return '!';
6824 
6825  case '=':
6826  if (was_bol()) {
6827  /* skip embedded rd document */
6828  if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
6829 #ifdef RIPPER
6830  int first_p = TRUE;
6831 
6832  lex_goto_eol(parser);
6833  ripper_dispatch_scan_event(parser, tEMBDOC_BEG);
6834 #endif
6835  for (;;) {
6836  lex_goto_eol(parser);
6837 #ifdef RIPPER
6838  if (!first_p) {
6839  ripper_dispatch_scan_event(parser, tEMBDOC);
6840  }
6841  first_p = FALSE;
6842 #endif
6843  c = nextc();
6844  if (c == -1) {
6845  compile_error(PARSER_ARG "embedded document meets end of file");
6846  return 0;
6847  }
6848  if (c != '=') continue;
6849  if (strncmp(lex_p, "end", 3) == 0 &&
6850  (lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {
6851  break;
6852  }
6853  }
6854  lex_goto_eol(parser);
6855 #ifdef RIPPER
6856  ripper_dispatch_scan_event(parser, tEMBDOC_END);
6857 #endif
6858  goto retry;
6859  }
6860  }
6861 
6862  switch (lex_state) {
6863  case EXPR_FNAME: case EXPR_DOT:
6864  lex_state = EXPR_ARG; break;
6865  default:
6866  lex_state = EXPR_BEG; break;
6867  }
6868  if ((c = nextc()) == '=') {
6869  if ((c = nextc()) == '=') {
6870  return tEQQ;
6871  }
6872  pushback(c);
6873  return tEQ;
6874  }
6875  if (c == '~') {
6876  return tMATCH;
6877  }
6878  else if (c == '>') {
6879  return tASSOC;
6880  }
6881  pushback(c);
6882  return '=';
6883 
6884  case '<':
6885  last_state = lex_state;
6886  c = nextc();
6887  if (c == '<' &&
6888  lex_state != EXPR_DOT &&
6889  lex_state != EXPR_CLASS &&
6890  !IS_END() &&
6891  (!IS_ARG() || space_seen)) {
6892  int token = heredoc_identifier();
6893  if (token) return token;
6894  }
6895  switch (lex_state) {
6896  case EXPR_FNAME: case EXPR_DOT:
6897  lex_state = EXPR_ARG; break;
6898  default:
6899  lex_state = EXPR_BEG; break;
6900  }
6901  if (c == '=') {
6902  if ((c = nextc()) == '>') {
6903  return tCMP;
6904  }
6905  pushback(c);
6906  return tLEQ;
6907  }
6908  if (c == '<') {
6909  if ((c = nextc()) == '=') {
6911  lex_state = EXPR_BEG;
6912  return tOP_ASGN;
6913  }
6914  pushback(c);
6915  warn_balanced("<<", "here document");
6916  return tLSHFT;
6917  }
6918  pushback(c);
6919  return '<';
6920 
6921  case '>':
6922  switch (lex_state) {
6923  case EXPR_FNAME: case EXPR_DOT:
6924  lex_state = EXPR_ARG; break;
6925  default:
6926  lex_state = EXPR_BEG; break;
6927  }
6928  if ((c = nextc()) == '=') {
6929  return tGEQ;
6930  }
6931  if (c == '>') {
6932  if ((c = nextc()) == '=') {
6934  lex_state = EXPR_BEG;
6935  return tOP_ASGN;
6936  }
6937  pushback(c);
6938  return tRSHFT;
6939  }
6940  pushback(c);
6941  return '>';
6942 
6943  case '"':
6944  lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
6945  return tSTRING_BEG;
6946 
6947  case '`':
6948  if (lex_state == EXPR_FNAME) {
6950  return c;
6951  }
6952  if (lex_state == EXPR_DOT) {
6953  if (cmd_state)
6955  else
6956  lex_state = EXPR_ARG;
6957  return c;
6958  }
6959  lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
6960  return tXSTRING_BEG;
6961 
6962  case '\'':
6963  lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
6964  return tSTRING_BEG;
6965 
6966  case '?':
6967  if (IS_END()) {
6969  return '?';
6970  }
6971  c = nextc();
6972  if (c == -1) {
6973  compile_error(PARSER_ARG "incomplete character syntax");
6974  return 0;
6975  }
6976  if (rb_enc_isspace(c, parser->enc)) {
6977  if (!IS_ARG()) {
6978  int c2 = 0;
6979  switch (c) {
6980  case ' ':
6981  c2 = 's';
6982  break;
6983  case '\n':
6984  c2 = 'n';
6985  break;
6986  case '\t':
6987  c2 = 't';
6988  break;
6989  case '\v':
6990  c2 = 'v';
6991  break;
6992  case '\r':
6993  c2 = 'r';
6994  break;
6995  case '\f':
6996  c2 = 'f';
6997  break;
6998  }
6999  if (c2) {
7000  rb_warnI("invalid character syntax; use ?\\%c", c2);
7001  }
7002  }
7003  ternary:
7004  pushback(c);
7006  return '?';
7007  }
7008  newtok();
7009  enc = parser->enc;
7010  if (!parser_isascii()) {
7011  if (tokadd_mbchar(c) == -1) return 0;
7012  }
7013  else if ((rb_enc_isalnum(c, parser->enc) || c == '_') &&
7014  lex_p < lex_pend && is_identchar(lex_p, lex_pend, parser->enc)) {
7015  goto ternary;
7016  }
7017  else if (c == '\\') {
7018  if (peek('u')) {
7019  nextc();
7020  c = parser_tokadd_utf8(parser, &enc, 0, 0, 0);
7021  if (0x80 <= c) {
7022  tokaddmbc(c, enc);
7023  }
7024  else {
7025  tokadd(c);
7026  }
7027  }
7028  else if (!lex_eol_p() && !(c = *lex_p, ISASCII(c))) {
7029  nextc();
7030  if (tokadd_mbchar(c) == -1) return 0;
7031  }
7032  else {
7033  c = read_escape(0, &enc);
7034  tokadd(c);
7035  }
7036  }
7037  else {
7038  tokadd(c);
7039  }
7040  tokfix();
7041  set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0));
7042  lex_state = EXPR_END;
7043  return tCHAR;
7044 
7045  case '&':
7046  if ((c = nextc()) == '&') {
7047  lex_state = EXPR_BEG;
7048  if ((c = nextc()) == '=') {
7050  lex_state = EXPR_BEG;
7051  return tOP_ASGN;
7052  }
7053  pushback(c);
7054  return tANDOP;
7055  }
7056  else if (c == '=') {
7057  set_yylval_id('&');
7058  lex_state = EXPR_BEG;
7059  return tOP_ASGN;
7060  }
7061  pushback(c);
7062  if (IS_SPCARG(c)) {
7063  rb_warning0("`&' interpreted as argument prefix");
7064  c = tAMPER;
7065  }
7066  else if (IS_BEG()) {
7067  c = tAMPER;
7068  }
7069  else {
7070  warn_balanced("&", "argument prefix");
7071  c = '&';
7072  }
7073  switch (lex_state) {
7074  case EXPR_FNAME: case EXPR_DOT:
7075  lex_state = EXPR_ARG; break;
7076  default:
7077  lex_state = EXPR_BEG;
7078  }
7079  return c;
7080 
7081  case '|':
7082  if ((c = nextc()) == '|') {
7083  lex_state = EXPR_BEG;
7084  if ((c = nextc()) == '=') {
7086  lex_state = EXPR_BEG;
7087  return tOP_ASGN;
7088  }
7089  pushback(c);
7090  return tOROP;
7091  }
7092  if (c == '=') {
7093  set_yylval_id('|');
7094  lex_state = EXPR_BEG;
7095  return tOP_ASGN;
7096  }
7097  if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
7098  lex_state = EXPR_ARG;
7099  }
7100  else {
7101  lex_state = EXPR_BEG;
7102  }
7103  pushback(c);
7104  return '|';
7105 
7106  case '+':
7107  c = nextc();
7108  if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
7109  lex_state = EXPR_ARG;
7110  if (c == '@') {
7111  return tUPLUS;
7112  }
7113  pushback(c);
7114  return '+';
7115  }
7116  if (c == '=') {
7117  set_yylval_id('+');
7118  lex_state = EXPR_BEG;
7119  return tOP_ASGN;
7120  }
7121  if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7122  lex_state = EXPR_BEG;
7123  pushback(c);
7124  if (c != -1 && ISDIGIT(c)) {
7125  c = '+';
7126  goto start_num;
7127  }
7128  return tUPLUS;
7129  }
7130  lex_state = EXPR_BEG;
7131  pushback(c);
7132  warn_balanced("+", "unary operator");
7133  return '+';
7134 
7135  case '-':
7136  c = nextc();
7137  if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
7138  lex_state = EXPR_ARG;
7139  if (c == '@') {
7140  return tUMINUS;
7141  }
7142  pushback(c);
7143  return '-';
7144  }
7145  if (c == '=') {
7146  set_yylval_id('-');
7147  lex_state = EXPR_BEG;
7148  return tOP_ASGN;
7149  }
7150  if (c == '>') {
7151  lex_state = EXPR_ARG;
7152  return tLAMBDA;
7153  }
7154  if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7155  lex_state = EXPR_BEG;
7156  pushback(c);
7157  if (c != -1 && ISDIGIT(c)) {
7158  return tUMINUS_NUM;
7159  }
7160  return tUMINUS;
7161  }
7162  lex_state = EXPR_BEG;
7163  pushback(c);
7164  warn_balanced("-", "unary operator");
7165  return '-';
7166 
7167  case '.':
7168  lex_state = EXPR_BEG;
7169  if ((c = nextc()) == '.') {
7170  if ((c = nextc()) == '.') {
7171  return tDOT3;
7172  }
7173  pushback(c);
7174  return tDOT2;
7175  }
7176  pushback(c);
7177  if (c != -1 && ISDIGIT(c)) {
7178  yyerror("no .<digit> floating literal anymore; put 0 before dot");
7179  }
7180  lex_state = EXPR_DOT;
7181  return '.';
7182 
7183  start_num:
7184  case '0': case '1': case '2': case '3': case '4':
7185  case '5': case '6': case '7': case '8': case '9':
7186  {
7187  int is_float, seen_point, seen_e, nondigit;
7188 
7189  is_float = seen_point = seen_e = nondigit = 0;
7190  lex_state = EXPR_END;
7191  newtok();
7192  if (c == '-' || c == '+') {
7193  tokadd(c);
7194  c = nextc();
7195  }
7196  if (c == '0') {
7197 #define no_digits() do {yyerror("numeric literal without digits"); return 0;} while (0)
7198  int start = toklen();
7199  c = nextc();
7200  if (c == 'x' || c == 'X') {
7201  /* hexadecimal */
7202  c = nextc();
7203  if (c != -1 && ISXDIGIT(c)) {
7204  do {
7205  if (c == '_') {
7206  if (nondigit) break;
7207  nondigit = c;
7208  continue;
7209  }
7210  if (!ISXDIGIT(c)) break;
7211  nondigit = 0;
7212  tokadd(c);
7213  } while ((c = nextc()) != -1);
7214  }
7215  pushback(c);
7216  tokfix();
7217  if (toklen() == start) {
7218  no_digits();
7219  }
7220  else if (nondigit) goto trailing_uc;
7221  set_yylval_literal(rb_cstr_to_inum(tok(), 16, FALSE));
7222  return tINTEGER;
7223  }
7224  if (c == 'b' || c == 'B') {
7225  /* binary */
7226  c = nextc();
7227  if (c == '0' || c == '1') {
7228  do {
7229  if (c == '_') {
7230  if (nondigit) break;
7231  nondigit = c;
7232  continue;
7233  }
7234  if (c != '0' && c != '1') break;
7235  nondigit = 0;
7236  tokadd(c);
7237  } while ((c = nextc()) != -1);
7238  }
7239  pushback(c);
7240  tokfix();
7241  if (toklen() == start) {
7242  no_digits();
7243  }
7244  else if (nondigit) goto trailing_uc;
7245  set_yylval_literal(rb_cstr_to_inum(tok(), 2, FALSE));
7246  return tINTEGER;
7247  }
7248  if (c == 'd' || c == 'D') {
7249  /* decimal */
7250  c = nextc();
7251  if (c != -1 && ISDIGIT(c)) {
7252  do {
7253  if (c == '_') {
7254  if (nondigit) break;
7255  nondigit = c;
7256  continue;
7257  }
7258  if (!ISDIGIT(c)) break;
7259  nondigit = 0;
7260  tokadd(c);
7261  } while ((c = nextc()) != -1);
7262  }
7263  pushback(c);
7264  tokfix();
7265  if (toklen() == start) {
7266  no_digits();
7267  }
7268  else if (nondigit) goto trailing_uc;
7269  set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
7270  return tINTEGER;
7271  }
7272  if (c == '_') {
7273  /* 0_0 */
7274  goto octal_number;
7275  }
7276  if (c == 'o' || c == 'O') {
7277  /* prefixed octal */
7278  c = nextc();
7279  if (c == -1 || c == '_' || !ISDIGIT(c)) {
7280  no_digits();
7281  }
7282  }
7283  if (c >= '0' && c <= '7') {
7284  /* octal */
7285  octal_number:
7286  do {
7287  if (c == '_') {
7288  if (nondigit) break;
7289  nondigit = c;
7290  continue;
7291  }
7292  if (c < '0' || c > '9') break;
7293  if (c > '7') goto invalid_octal;
7294  nondigit = 0;
7295  tokadd(c);
7296  } while ((c = nextc()) != -1);
7297  if (toklen() > start) {
7298  pushback(c);
7299  tokfix();
7300  if (nondigit) goto trailing_uc;
7301  set_yylval_literal(rb_cstr_to_inum(tok(), 8, FALSE));
7302  return tINTEGER;
7303  }
7304  if (nondigit) {
7305  pushback(c);
7306  goto trailing_uc;
7307  }
7308  }
7309  if (c > '7' && c <= '9') {
7310  invalid_octal:
7311  yyerror("Invalid octal digit");
7312  }
7313  else if (c == '.' || c == 'e' || c == 'E') {
7314  tokadd('0');
7315  }
7316  else {
7317  pushback(c);
7319  return tINTEGER;
7320  }
7321  }
7322 
7323  for (;;) {
7324  switch (c) {
7325  case '0': case '1': case '2': case '3': case '4':
7326  case '5': case '6': case '7': case '8': case '9':
7327  nondigit = 0;
7328  tokadd(c);
7329  break;
7330 
7331  case '.':
7332  if (nondigit) goto trailing_uc;
7333  if (seen_point || seen_e) {
7334  goto decode_num;
7335  }
7336  else {
7337  int c0 = nextc();
7338  if (c0 == -1 || !ISDIGIT(c0)) {
7339  pushback(c0);
7340  goto decode_num;
7341  }
7342  c = c0;
7343  }
7344  tokadd('.');
7345  tokadd(c);
7346  is_float++;
7347  seen_point++;
7348  nondigit = 0;
7349  break;
7350 
7351  case 'e':
7352  case 'E':
7353  if (nondigit) {
7354  pushback(c);
7355  c = nondigit;
7356  goto decode_num;
7357  }
7358  if (seen_e) {
7359  goto decode_num;
7360  }
7361  tokadd(c);
7362  seen_e++;
7363  is_float++;
7364  nondigit = c;
7365  c = nextc();
7366  if (c != '-' && c != '+') continue;
7367  tokadd(c);
7368  nondigit = c;
7369  break;
7370 
7371  case '_': /* `_' in number just ignored */
7372  if (nondigit) goto decode_num;
7373  nondigit = c;
7374  break;
7375 
7376  default:
7377  goto decode_num;
7378  }
7379  c = nextc();
7380  }
7381 
7382  decode_num:
7383  pushback(c);
7384  if (nondigit) {
7385  char tmp[30];
7386  trailing_uc:
7387  snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
7388  yyerror(tmp);
7389  }
7390  tokfix();
7391  if (is_float) {
7392  double d = strtod(tok(), 0);
7393  if (errno == ERANGE) {
7394  rb_warningS("Float %s out of range", tok());
7395  errno = 0;
7396  }
7398  return tFLOAT;
7399  }
7400  set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
7401  return tINTEGER;
7402  }
7403 
7404  case ')':
7405  case ']':
7406  paren_nest--;
7407  case '}':
7408  COND_LEXPOP();
7409  CMDARG_LEXPOP();
7410  if (c == ')')
7412  else
7414  return c;
7415 
7416  case ':':
7417  c = nextc();
7418  if (c == ':') {
7419  if (IS_BEG() || lex_state == EXPR_CLASS || IS_SPCARG(-1)) {
7420  lex_state = EXPR_BEG;
7421  return tCOLON3;
7422  }
7423  lex_state = EXPR_DOT;
7424  return tCOLON2;
7425  }
7426  if (IS_END() || ISSPACE(c)) {
7427  pushback(c);
7428  warn_balanced(":", "symbol literal");
7429  lex_state = EXPR_BEG;
7430  return ':';
7431  }
7432  switch (c) {
7433  case '\'':
7434  lex_strterm = NEW_STRTERM(str_ssym, c, 0);
7435  break;
7436  case '"':
7437  lex_strterm = NEW_STRTERM(str_dsym, c, 0);
7438  break;
7439  default:
7440  pushback(c);
7441  break;
7442  }
7444  return tSYMBEG;
7445 
7446  case '/':
7447  if (IS_BEG()) {
7448  lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7449  return tREGEXP_BEG;
7450  }
7451  if ((c = nextc()) == '=') {
7452  set_yylval_id('/');
7453  lex_state = EXPR_BEG;
7454  return tOP_ASGN;
7455  }
7456  pushback(c);
7457  if (IS_SPCARG(c)) {
7458  (void)arg_ambiguous();
7459  lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7460  return tREGEXP_BEG;
7461  }
7462  switch (lex_state) {
7463  case EXPR_FNAME: case EXPR_DOT:
7464  lex_state = EXPR_ARG; break;
7465  default:
7466  lex_state = EXPR_BEG; break;
7467  }
7468  warn_balanced("/", "regexp literal");
7469  return '/';
7470 
7471  case '^':
7472  if ((c = nextc()) == '=') {
7473  set_yylval_id('^');
7474  lex_state = EXPR_BEG;
7475  return tOP_ASGN;
7476  }
7477  switch (lex_state) {
7478  case EXPR_FNAME: case EXPR_DOT:
7479  lex_state = EXPR_ARG; break;
7480  default:
7481  lex_state = EXPR_BEG; break;
7482  }
7483  pushback(c);
7484  return '^';
7485 
7486  case ';':
7487  lex_state = EXPR_BEG;
7488  command_start = TRUE;
7489  return ';';
7490 
7491  case ',':
7492  lex_state = EXPR_BEG;
7493  return ',';
7494 
7495  case '~':
7496  if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
7497  if ((c = nextc()) != '@') {
7498  pushback(c);
7499  }
7500  lex_state = EXPR_ARG;
7501  }
7502  else {
7503  lex_state = EXPR_BEG;
7504  }
7505  return '~';
7506 
7507  case '(':
7508  if (IS_BEG()) {
7509  c = tLPAREN;
7510  }
7511  else if (IS_SPCARG(-1)) {
7512  c = tLPAREN_ARG;
7513  }
7514  paren_nest++;
7515  COND_PUSH(0);
7516  CMDARG_PUSH(0);
7517  lex_state = EXPR_BEG;
7518  return c;
7519 
7520  case '[':
7521  paren_nest++;
7522  if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
7523  lex_state = EXPR_ARG;
7524  if ((c = nextc()) == ']') {
7525  if ((c = nextc()) == '=') {
7526  return tASET;
7527  }
7528  pushback(c);
7529  return tAREF;
7530  }
7531  pushback(c);
7532  return '[';
7533  }
7534  else if (IS_BEG()) {
7535  c = tLBRACK;
7536  }
7537  else if (IS_ARG() && space_seen) {
7538  c = tLBRACK;
7539  }
7540  lex_state = EXPR_BEG;
7541  COND_PUSH(0);
7542  CMDARG_PUSH(0);
7543  return c;
7544 
7545  case '{':
7546  if (lpar_beg && lpar_beg == paren_nest) {
7547  lex_state = EXPR_BEG;
7548  lpar_beg = 0;
7549  --paren_nest;
7550  COND_PUSH(0);
7551  CMDARG_PUSH(0);
7552  return tLAMBEG;
7553  }
7554  if (IS_ARG() || lex_state == EXPR_END || lex_state == EXPR_ENDFN)
7555  c = '{'; /* block (primary) */
7556  else if (lex_state == EXPR_ENDARG)
7557  c = tLBRACE_ARG; /* block (expr) */
7558  else
7559  c = tLBRACE; /* hash */
7560  COND_PUSH(0);
7561  CMDARG_PUSH(0);
7562  lex_state = EXPR_BEG;
7563  if (c != tLBRACE) command_start = TRUE;
7564  return c;
7565 
7566  case '\\':
7567  c = nextc();
7568  if (c == '\n') {
7569  space_seen = 1;
7570 #ifdef RIPPER
7571  ripper_dispatch_scan_event(parser, tSP);
7572 #endif
7573  goto retry; /* skip \\n */
7574  }
7575  pushback(c);
7576  return '\\';
7577 
7578  case '%':
7579  if (IS_BEG()) {
7580  int term;
7581  int paren;
7582 
7583  c = nextc();
7584  quotation:
7585  if (c == -1 || !ISALNUM(c)) {
7586  term = c;
7587  c = 'Q';
7588  }
7589  else {
7590  term = nextc();
7591  if (rb_enc_isalnum(term, parser->enc) || !parser_isascii()) {
7592  yyerror("unknown type of %string");
7593  return 0;
7594  }
7595  }
7596  if (c == -1 || term == -1) {
7597  compile_error(PARSER_ARG "unterminated quoted string meets end of file");
7598  return 0;
7599  }
7600  paren = term;
7601  if (term == '(') term = ')';
7602  else if (term == '[') term = ']';
7603  else if (term == '{') term = '}';
7604  else if (term == '<') term = '>';
7605  else paren = 0;
7606 
7607  switch (c) {
7608  case 'Q':
7609  lex_strterm = NEW_STRTERM(str_dquote, term, paren);
7610  return tSTRING_BEG;
7611 
7612  case 'q':
7613  lex_strterm = NEW_STRTERM(str_squote, term, paren);
7614  return tSTRING_BEG;
7615 
7616  case 'W':
7617  lex_strterm = NEW_STRTERM(str_dword, term, paren);
7618  do {c = nextc();} while (ISSPACE(c));
7619  pushback(c);
7620  return tWORDS_BEG;
7621 
7622  case 'w':
7623  lex_strterm = NEW_STRTERM(str_sword, term, paren);
7624  do {c = nextc();} while (ISSPACE(c));
7625  pushback(c);
7626  return tQWORDS_BEG;
7627 
7628  case 'x':
7629  lex_strterm = NEW_STRTERM(str_xquote, term, paren);
7630  return tXSTRING_BEG;
7631 
7632  case 'r':
7633  lex_strterm = NEW_STRTERM(str_regexp, term, paren);
7634  return tREGEXP_BEG;
7635 
7636  case 's':
7637  lex_strterm = NEW_STRTERM(str_ssym, term, paren);
7639  return tSYMBEG;
7640 
7641  default:
7642  yyerror("unknown type of %string");
7643  return 0;
7644  }
7645  }
7646  if ((c = nextc()) == '=') {
7647  set_yylval_id('%');
7648  lex_state = EXPR_BEG;
7649  return tOP_ASGN;
7650  }
7651  if (IS_SPCARG(c)) {
7652  goto quotation;
7653  }
7654  switch (lex_state) {
7655  case EXPR_FNAME: case EXPR_DOT:
7656  lex_state = EXPR_ARG; break;
7657  default:
7658  lex_state = EXPR_BEG; break;
7659  }
7660  pushback(c);
7661  warn_balanced("%%", "string literal");
7662  return '%';
7663 
7664  case '$':
7665  lex_state = EXPR_END;
7666  newtok();
7667  c = nextc();
7668  switch (c) {
7669  case '_': /* $_: last read line string */
7670  c = nextc();
7671  if (parser_is_identchar()) {
7672  tokadd('$');
7673  tokadd('_');
7674  break;
7675  }
7676  pushback(c);
7677  c = '_';
7678  /* fall through */
7679  case '~': /* $~: match-data */
7680  case '*': /* $*: argv */
7681  case '$': /* $$: pid */
7682  case '?': /* $?: last status */
7683  case '!': /* $!: error string */
7684  case '@': /* $@: error position */
7685  case '/': /* $/: input record separator */
7686  case '\\': /* $\: output record separator */
7687  case ';': /* $;: field separator */
7688  case ',': /* $,: output field separator */
7689  case '.': /* $.: last read line number */
7690  case '=': /* $=: ignorecase */
7691  case ':': /* $:: load path */
7692  case '<': /* $<: reading filename */
7693  case '>': /* $>: default output handle */
7694  case '\"': /* $": already loaded files */
7695  tokadd('$');
7696  tokadd(c);
7697  tokfix();
7699  return tGVAR;
7700 
7701  case '-':
7702  tokadd('$');
7703  tokadd(c);
7704  c = nextc();
7705  if (parser_is_identchar()) {
7706  if (tokadd_mbchar(c) == -1) return 0;
7707  }
7708  else {
7709  pushback(c);
7710  }
7711  gvar:
7712  tokfix();
7714  return tGVAR;
7715 
7716  case '&': /* $&: last match */
7717  case '`': /* $`: string before last match */
7718  case '\'': /* $': string after last match */
7719  case '+': /* $+: string matches last paren. */
7720  if (last_state == EXPR_FNAME) {
7721  tokadd('$');
7722  tokadd(c);
7723  goto gvar;
7724  }
7726  return tBACK_REF;
7727 
7728  case '1': case '2': case '3':
7729  case '4': case '5': case '6':
7730  case '7': case '8': case '9':
7731  tokadd('$');
7732  do {
7733  tokadd(c);
7734  c = nextc();
7735  } while (c != -1 && ISDIGIT(c));
7736  pushback(c);
7737  if (last_state == EXPR_FNAME) goto gvar;
7738  tokfix();
7739  set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
7740  return tNTH_REF;
7741 
7742  default:
7743  if (!parser_is_identchar()) {
7744  pushback(c);
7745  return '$';
7746  }
7747  case '0':
7748  tokadd('$');
7749  }
7750  break;
7751 
7752  case '@':
7753  c = nextc();
7754  newtok();
7755  tokadd('@');
7756  if (c == '@') {
7757  tokadd('@');
7758  c = nextc();
7759  }
7760  if (c != -1 && ISDIGIT(c)) {
7761  if (tokidx == 1) {
7762  compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
7763  }
7764  else {
7765  compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
7766  }
7767  return 0;
7768  }
7769  if (!parser_is_identchar()) {
7770  pushback(c);
7771  return '@';
7772  }
7773  break;
7774 
7775  case '_':
7776  if (was_bol() && whole_match_p("__END__", 7, 0)) {
7777  ruby__end__seen = 1;
7778  parser->eofp = Qtrue;
7779 #ifndef RIPPER
7780  return -1;
7781 #else
7782  lex_goto_eol(parser);
7783  ripper_dispatch_scan_event(parser, k__END__);
7784  return 0;
7785 #endif
7786  }
7787  newtok();
7788  break;
7789 
7790  default:
7791  if (!parser_is_identchar()) {
7792  rb_compile_error(PARSER_ARG "Invalid char `\\x%02X' in expression", c);
7793  goto retry;
7794  }
7795 
7796  newtok();
7797  break;
7798  }
7799 
7800  mb = ENC_CODERANGE_7BIT;
7801  do {
7802  if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
7803  if (tokadd_mbchar(c) == -1) return 0;
7804  c = nextc();
7805  } while (parser_is_identchar());
7806  switch (tok()[0]) {
7807  case '@': case '$':
7808  pushback(c);
7809  break;
7810  default:
7811  if ((c == '!' || c == '?') && !peek('=')) {
7812  tokadd(c);
7813  }
7814  else {
7815  pushback(c);
7816  }
7817  }
7818  tokfix();
7819 
7820  {
7821  int result = 0;
7822 
7823  last_state = lex_state;
7824  switch (tok()[0]) {
7825  case '$':
7826  lex_state = EXPR_END;
7827  result = tGVAR;
7828  break;
7829  case '@':
7830  lex_state = EXPR_END;
7831  if (tok()[1] == '@')
7832  result = tCVAR;
7833  else
7834  result = tIVAR;
7835  break;
7836 
7837  default:
7838  if (toklast() == '!' || toklast() == '?') {
7839  result = tFID;
7840  }
7841  else {
7842  if (lex_state == EXPR_FNAME) {
7843  if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
7844  (!peek('=') || (peek_n('>', 1)))) {
7845  result = tIDENTIFIER;
7846  tokadd(c);
7847  tokfix();
7848  }
7849  else {
7850  pushback(c);
7851  }
7852  }
7853  if (result == 0 && ISUPPER(tok()[0])) {
7854  result = tCONSTANT;
7855  }
7856  else {
7857  result = tIDENTIFIER;
7858  }
7859  }
7860 
7861  if (IS_LABEL_POSSIBLE()) {
7862  if (IS_LABEL_SUFFIX(0)) {
7863  lex_state = EXPR_BEG;
7864  nextc();
7866  return tLABEL;
7867  }
7868  }
7869  if (mb == ENC_CODERANGE_7BIT && lex_state != EXPR_DOT) {
7870  const struct kwtable *kw;
7871 
7872  /* See if it is a reserved word. */
7873  kw = rb_reserved_word(tok(), toklen());
7874  if (kw) {
7875  enum lex_state_e state = lex_state;
7876  lex_state = kw->state;
7877  if (state == EXPR_FNAME) {
7879  return kw->id[0];
7880  }
7881  if (kw->id[0] == keyword_do) {
7882  command_start = TRUE;
7883  if (lpar_beg && lpar_beg == paren_nest) {
7884  lpar_beg = 0;
7885  --paren_nest;
7886  return keyword_do_LAMBDA;
7887  }
7888  if (COND_P()) return keyword_do_cond;
7889  if (CMDARG_P() && state != EXPR_CMDARG)
7890  return keyword_do_block;
7891  if (state == EXPR_ENDARG || state == EXPR_BEG)
7892  return keyword_do_block;
7893  return keyword_do;
7894  }
7895  if (state == EXPR_BEG || state == EXPR_VALUE)
7896  return kw->id[0];
7897  else {
7898  if (kw->id[0] != kw->id[1])
7899  lex_state = EXPR_BEG;
7900  return kw->id[1];
7901  }
7902  }
7903  }
7904 
7905  if (IS_BEG() ||
7906  lex_state == EXPR_DOT ||
7907  IS_ARG()) {
7908  if (cmd_state) {
7910  }
7911  else {
7912  lex_state = EXPR_ARG;
7913  }
7914  }
7915  else if (lex_state == EXPR_FNAME) {
7917  }
7918  else {
7919  lex_state = EXPR_END;
7920  }
7921  }
7922  {
7923  ID ident = TOK_INTERN(!ENC_SINGLE(mb));
7924 
7925  set_yylval_name(ident);
7926  if (last_state != EXPR_DOT && last_state != EXPR_FNAME &&
7927  is_local_id(ident) && lvar_defined(ident)) {
7928  lex_state = EXPR_END;
7929  }
7930  }
7931  return result;
7932  }
7933 }
7934 
7935 #if YYPURE
7936 static int
7937 yylex(void *lval, void *p)
7938 #else
7939 yylex(void *p)
7940 #endif
7941 {
7942  struct parser_params *parser = (struct parser_params*)p;
7943  int t;
7944 
7945 #if YYPURE
7946  parser->parser_yylval = lval;
7947  parser->parser_yylval->val = Qundef;
7948 #endif
7949  t = parser_yylex(parser);
7950 #ifdef RIPPER
7951  if (!NIL_P(parser->delayed)) {
7952  ripper_dispatch_delayed_token(parser, t);
7953  return t;
7954  }
7955  if (t != 0)
7956  ripper_dispatch_scan_event(parser, t);
7957 #endif
7958 
7959  return t;
7960 }
7961 
7962 #ifndef RIPPER
7963 static NODE*
7964 node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
7965 {
7966  NODE *n = (rb_node_newnode)(type, a0, a1, a2);
7968  return n;
7969 }
7970 
7971 enum node_type
7972 nodetype(NODE *node) /* for debug */
7973 {
7974  return (enum node_type)nd_type(node);
7975 }
7976 
7977 int
7978 nodeline(NODE *node)
7979 {
7980  return nd_line(node);
7981 }
7982 
7983 static NODE*
7984 newline_node(NODE *node)
7985 {
7986  if (node) {
7987  node = remove_begin(node);
7988  node->flags |= NODE_FL_NEWLINE;
7989  }
7990  return node;
7991 }
7992 
7993 static void
7994 fixpos(NODE *node, NODE *orig)
7995 {
7996  if (!node) return;
7997  if (!orig) return;
7998  if (orig == (NODE*)1) return;
7999  nd_set_line(node, nd_line(orig));
8000 }
8001 
8002 static void
8003 parser_warning(struct parser_params *parser, NODE *node, const char *mesg)
8004 {
8005  rb_compile_warning(ruby_sourcefile, nd_line(node), "%s", mesg);
8006 }
8007 #define parser_warning(node, mesg) parser_warning(parser, (node), (mesg))
8008 
8009 static void
8010 parser_warn(struct parser_params *parser, NODE *node, const char *mesg)
8011 {
8012  rb_compile_warn(ruby_sourcefile, nd_line(node), "%s", mesg);
8013 }
8014 #define parser_warn(node, mesg) parser_warn(parser, (node), (mesg))
8015 
8016 static NODE*
8017 block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
8018 {
8019  NODE *end, *h = head, *nd;
8020 
8021  if (tail == 0) return head;
8022 
8023  if (h == 0) return tail;
8024  switch (nd_type(h)) {
8025  case NODE_LIT:
8026  case NODE_STR:
8027  case NODE_SELF:
8028  case NODE_TRUE:
8029  case NODE_FALSE:
8030  case NODE_NIL:
8031  parser_warning(h, "unused literal ignored");
8032  return tail;
8033  default:
8034  h = end = NEW_BLOCK(head);
8035  end->nd_end = end;
8036  fixpos(end, head);
8037  head = end;
8038  break;
8039  case NODE_BLOCK:
8040  end = h->nd_end;
8041  break;
8042  }
8043 
8044  nd = end->nd_head;
8045  switch (nd_type(nd)) {
8046  case NODE_RETURN:
8047  case NODE_BREAK:
8048  case NODE_NEXT:
8049  case NODE_REDO:
8050  case NODE_RETRY:
8051  if (RTEST(ruby_verbose)) {
8052  parser_warning(nd, "statement not reached");
8053  }
8054  break;
8055 
8056  default:
8057  break;
8058  }
8059 
8060  if (nd_type(tail) != NODE_BLOCK) {
8061  tail = NEW_BLOCK(tail);
8062  tail->nd_end = tail;
8063  }
8064  end->nd_next = tail;
8065  h->nd_end = tail->nd_end;
8066  return head;
8067 }
8068 
8069 /* append item to the list */
8070 static NODE*
8071 list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
8072 {
8073  NODE *last;
8074 
8075  if (list == 0) return NEW_LIST(item);
8076  if (list->nd_next) {
8077  last = list->nd_next->nd_end;
8078  }
8079  else {
8080  last = list;
8081  }
8082 
8083  list->nd_alen += 1;
8084  last->nd_next = NEW_LIST(item);
8085  list->nd_next->nd_end = last->nd_next;
8086  return list;
8087 }
8088 
8089 /* concat two lists */
8090 static NODE*
8091 list_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
8092 {
8093  NODE *last;
8094 
8095  if (head->nd_next) {
8096  last = head->nd_next->nd_end;
8097  }
8098  else {
8099  last = head;
8100  }
8101 
8102  head->nd_alen += tail->nd_alen;
8103  last->nd_next = tail;
8104  if (tail->nd_next) {
8105  head->nd_next->nd_end = tail->nd_next->nd_end;
8106  }
8107  else {
8108  head->nd_next->nd_end = tail;
8109  }
8110 
8111  return head;
8112 }
8113 
8114 static int
8115 literal_concat0(struct parser_params *parser, VALUE head, VALUE tail)
8116 {
8117  if (NIL_P(tail)) return 1;
8118  if (!rb_enc_compatible(head, tail)) {
8119  compile_error(PARSER_ARG "string literal encodings differ (%s / %s)",
8120  rb_enc_name(rb_enc_get(head)),
8121  rb_enc_name(rb_enc_get(tail)));
8122  rb_str_resize(head, 0);
8123  rb_str_resize(tail, 0);
8124  return 0;
8125  }
8126  rb_str_buf_append(head, tail);
8127  return 1;
8128 }
8129 
8130 /* concat two string literals */
8131 static NODE *
8132 literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
8133 {
8134  enum node_type htype;
8135 
8136  if (!head) return tail;
8137  if (!tail) return head;
8138 
8139  htype = nd_type(head);
8140  if (htype == NODE_EVSTR) {
8141  NODE *node = NEW_DSTR(Qnil);
8142  head = list_append(node, head);
8143  }
8144  switch (nd_type(tail)) {
8145  case NODE_STR:
8146  if (htype == NODE_STR) {
8147  if (!literal_concat0(parser, head->nd_lit, tail->nd_lit)) {
8148  error:
8149  rb_gc_force_recycle((VALUE)head);
8150  rb_gc_force_recycle((VALUE)tail);
8151  return 0;
8152  }
8153  rb_gc_force_recycle((VALUE)tail);
8154  }
8155  else {
8156  list_append(head, tail);
8157  }
8158  break;
8159 
8160  case NODE_DSTR:
8161  if (htype == NODE_STR) {
8162  if (!literal_concat0(parser, head->nd_lit, tail->nd_lit))
8163  goto error;
8164  tail->nd_lit = head->nd_lit;
8165  rb_gc_force_recycle((VALUE)head);
8166  head = tail;
8167  }
8168  else if (NIL_P(tail->nd_lit)) {
8169  head->nd_alen += tail->nd_alen - 1;
8170  head->nd_next->nd_end->nd_next = tail->nd_next;
8171  head->nd_next->nd_end = tail->nd_next->nd_end;
8172  rb_gc_force_recycle((VALUE)tail);
8173  }
8174  else {
8175  nd_set_type(tail, NODE_ARRAY);
8176  tail->nd_head = NEW_STR(tail->nd_lit);
8177  list_concat(head, tail);
8178  }
8179  break;
8180 
8181  case NODE_EVSTR:
8182  if (htype == NODE_STR) {
8183  nd_set_type(head, NODE_DSTR);
8184  head->nd_alen = 1;
8185  }
8186  list_append(head, tail);
8187  break;
8188  }
8189  return head;
8190 }
8191 
8192 static NODE *
8193 evstr2dstr_gen(struct parser_params *parser, NODE *node)
8194 {
8195  if (nd_type(node) == NODE_EVSTR) {
8196  node = list_append(NEW_DSTR(Qnil), node);
8197  }
8198  return node;
8199 }
8200 
8201 static NODE *
8202 new_evstr_gen(struct parser_params *parser, NODE *node)
8203 {
8204  NODE *head = node;
8205 
8206  if (node) {
8207  switch (nd_type(node)) {
8208  case NODE_STR: case NODE_DSTR: case NODE_EVSTR:
8209  return node;
8210  }
8211  }
8212  return NEW_EVSTR(head);
8213 }
8214 
8215 static NODE *
8216 call_bin_op_gen(struct parser_params *parser, NODE *recv, ID id, NODE *arg1)
8217 {
8218  value_expr(recv);
8219  value_expr(arg1);
8220  return NEW_CALL(recv, id, NEW_LIST(arg1));
8221 }
8222 
8223 static NODE *
8224 call_uni_op_gen(struct parser_params *parser, NODE *recv, ID id)
8225 {
8226  value_expr(recv);
8227  return NEW_CALL(recv, id, 0);
8228 }
8229 
8230 static NODE*
8231 match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8232 {
8233  value_expr(node1);
8234  value_expr(node2);
8235  if (node1) {
8236  switch (nd_type(node1)) {
8237  case NODE_DREGX:
8238  case NODE_DREGX_ONCE:
8239  return NEW_MATCH2(node1, node2);
8240 
8241  case NODE_LIT:
8242  if (TYPE(node1->nd_lit) == T_REGEXP) {
8243  return NEW_MATCH2(node1, node2);
8244  }
8245  }
8246  }
8247 
8248  if (node2) {
8249  switch (nd_type(node2)) {
8250  case NODE_DREGX:
8251  case NODE_DREGX_ONCE:
8252  return NEW_MATCH3(node2, node1);
8253 
8254  case NODE_LIT:
8255  if (TYPE(node2->nd_lit) == T_REGEXP) {
8256  return NEW_MATCH3(node2, node1);
8257  }
8258  }
8259  }
8260 
8261  return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
8262 }
8263 
8264 static NODE*
8265 gettable_gen(struct parser_params *parser, ID id)
8266 {
8267  if (id == keyword_self) {
8268  return NEW_SELF();
8269  }
8270  else if (id == keyword_nil) {
8271  return NEW_NIL();
8272  }
8273  else if (id == keyword_true) {
8274  return NEW_TRUE();
8275  }
8276  else if (id == keyword_false) {
8277  return NEW_FALSE();
8278  }
8279  else if (id == keyword__FILE__) {
8282  }
8283  else if (id == keyword__LINE__) {
8284  return NEW_LIT(INT2FIX(ruby_sourceline));
8285  }
8286  else if (id == keyword__ENCODING__) {
8287  return NEW_LIT(rb_enc_from_encoding(parser->enc));
8288  }
8289  else if (is_local_id(id)) {
8290  if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id);
8291  if (local_id(id)) return NEW_LVAR(id);
8292  /* method call without arguments */
8293  return NEW_VCALL(id);
8294  }
8295  else if (is_global_id(id)) {
8296  return NEW_GVAR(id);
8297  }
8298  else if (is_instance_id(id)) {
8299  return NEW_IVAR(id);
8300  }
8301  else if (is_const_id(id)) {
8302  return NEW_CONST(id);
8303  }
8304  else if (is_class_id(id)) {
8305  return NEW_CVAR(id);
8306  }
8307  compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
8308  return 0;
8309 }
8310 #else /* !RIPPER */
8311 static int
8312 id_is_var_gen(struct parser_params *parser, ID id)
8313 {
8314  if (is_notop_id(id)) {
8315  switch (id & ID_SCOPE_MASK) {
8316  case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
8317  return 1;
8318  case ID_LOCAL:
8319  if (dyna_in_block() && dvar_defined(id)) return 1;
8320  if (local_id(id)) return 1;
8321  /* method call without arguments */
8322  return 0;
8323  }
8324  }
8325  compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
8326  return 0;
8327 }
8328 #endif /* !RIPPER */
8329 
8330 #ifdef RIPPER
8331 static VALUE
8332 assignable_gen(struct parser_params *parser, VALUE lhs)
8333 #else
8334 static NODE*
8335 assignable_gen(struct parser_params *parser, ID id, NODE *val)
8336 #endif
8337 {
8338 #ifdef RIPPER
8339  ID id = get_id(lhs);
8340 # define assignable_result(x) get_value(lhs)
8341 # define parser_yyerror(parser, x) dispatch1(assign_error, lhs)
8342 #else
8343 # define assignable_result(x) (x)
8344 #endif
8345  if (!id) return assignable_result(0);
8346  if (id == keyword_self) {
8347  yyerror("Can't change the value of self");
8348  }
8349  else if (id == keyword_nil) {
8350  yyerror("Can't assign to nil");
8351  }
8352  else if (id == keyword_true) {
8353  yyerror("Can't assign to true");
8354  }
8355  else if (id == keyword_false) {
8356  yyerror("Can't assign to false");
8357  }
8358  else if (id == keyword__FILE__) {
8359  yyerror("Can't assign to __FILE__");
8360  }
8361  else if (id == keyword__LINE__) {
8362  yyerror("Can't assign to __LINE__");
8363  }
8364  else if (id == keyword__ENCODING__) {
8365  yyerror("Can't assign to __ENCODING__");
8366  }
8367  else if (is_local_id(id)) {
8368  if (dyna_in_block()) {
8369  if (dvar_curr(id)) {
8370  return assignable_result(NEW_DASGN_CURR(id, val));
8371  }
8372  else if (dvar_defined(id)) {
8373  return assignable_result(NEW_DASGN(id, val));
8374  }
8375  else if (local_id(id)) {
8376  return assignable_result(NEW_LASGN(id, val));
8377  }
8378  else {
8379  dyna_var(id);
8380  return assignable_result(NEW_DASGN_CURR(id, val));
8381  }
8382  }
8383  else {
8384  if (!local_id(id)) {
8385  local_var(id);
8386  }
8387  return assignable_result(NEW_LASGN(id, val));
8388  }
8389  }
8390  else if (is_global_id(id)) {
8391  return assignable_result(NEW_GASGN(id, val));
8392  }
8393  else if (is_instance_id(id)) {
8394  return assignable_result(NEW_IASGN(id, val));
8395  }
8396  else if (is_const_id(id)) {
8397  if (!in_def && !in_single)
8398  return assignable_result(NEW_CDECL(id, val, 0));
8399  yyerror("dynamic constant assignment");
8400  }
8401  else if (is_class_id(id)) {
8402  return assignable_result(NEW_CVASGN(id, val));
8403  }
8404  else {
8405  compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
8406  }
8407  return assignable_result(0);
8408 #undef assignable_result
8409 #undef parser_yyerror
8410 }
8411 
8412 #define LVAR_USED ((int)1 << (sizeof(int) * CHAR_BIT - 1))
8413 
8414 static ID
8415 shadowing_lvar_gen(struct parser_params *parser, ID name)
8416 {
8417  if (idUScore == name) return name;
8418  if (dyna_in_block()) {
8419  if (dvar_curr(name)) {
8420  yyerror("duplicated argument name");
8421  }
8422  else if (dvar_defined_get(name) || local_id(name)) {
8423  rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
8424  vtable_add(lvtbl->vars, name);
8425  if (lvtbl->used) {
8426  vtable_add(lvtbl->used, (ID)ruby_sourceline | LVAR_USED);
8427  }
8428  }
8429  }
8430  else {
8431  if (local_id(name)) {
8432  yyerror("duplicated argument name");
8433  }
8434  }
8435  return name;
8436 }
8437 
8438 static void
8439 new_bv_gen(struct parser_params *parser, ID name)
8440 {
8441  if (!name) return;
8442  if (!is_local_id(name)) {
8443  compile_error(PARSER_ARG "invalid local variable - %s",
8444  rb_id2name(name));
8445  return;
8446  }
8447  shadowing_lvar(name);
8448  dyna_var(name);
8449 }
8450 
8451 #ifndef RIPPER
8452 static NODE *
8453 aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
8454 {
8455  if (recv && nd_type(recv) == NODE_SELF)
8456  recv = (NODE *)1;
8457  return NEW_ATTRASGN(recv, tASET, idx);
8458 }
8459 
8460 static void
8461 block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8462 {
8463  if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
8464  compile_error(PARSER_ARG "both block arg and actual block given");
8465  }
8466 }
8467 
8468 ID
8469 rb_id_attrset(ID id)
8470 {
8471  id &= ~ID_SCOPE_MASK;
8472  id |= ID_ATTRSET;
8473  return id;
8474 }
8475 
8476 static NODE *
8477 attrset_gen(struct parser_params *parser, NODE *recv, ID id)
8478 {
8479  if (recv && nd_type(recv) == NODE_SELF)
8480  recv = (NODE *)1;
8481  return NEW_ATTRASGN(recv, rb_id_attrset(id), 0);
8482 }
8483 
8484 static void
8485 rb_backref_error_gen(struct parser_params *parser, NODE *node)
8486 {
8487  switch (nd_type(node)) {
8488  case NODE_NTH_REF:
8489  compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
8490  break;
8491  case NODE_BACK_REF:
8492  compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
8493  break;
8494  }
8495 }
8496 
8497 static NODE *
8498 arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8499 {
8500  if (!node2) return node1;
8501  switch (nd_type(node1)) {
8502  case NODE_BLOCK_PASS:
8503  if (node1->nd_head)
8504  node1->nd_head = arg_concat(node1->nd_head, node2);
8505  else
8506  node1->nd_head = NEW_LIST(node2);
8507  return node1;
8508  case NODE_ARGSPUSH:
8509  if (nd_type(node2) != NODE_ARRAY) break;
8510  node1->nd_body = list_concat(NEW_LIST(node1->nd_body), node2);
8511  nd_set_type(node1, NODE_ARGSCAT);
8512  return node1;
8513  case NODE_ARGSCAT:
8514  if (nd_type(node2) != NODE_ARRAY ||
8515  nd_type(node1->nd_body) != NODE_ARRAY) break;
8516  node1->nd_body = list_concat(node1->nd_body, node2);
8517  return node1;
8518  }
8519  return NEW_ARGSCAT(node1, node2);
8520 }
8521 
8522 static NODE *
8523 arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
8524 {
8525  if (!node1) return NEW_LIST(node2);
8526  switch (nd_type(node1)) {
8527  case NODE_ARRAY:
8528  return list_append(node1, node2);
8529  case NODE_BLOCK_PASS:
8530  node1->nd_head = arg_append(node1->nd_head, node2);
8531  return node1;
8532  case NODE_ARGSPUSH:
8533  node1->nd_body = list_append(NEW_LIST(node1->nd_body), node2);
8534  nd_set_type(node1, NODE_ARGSCAT);
8535  return node1;
8536  }
8537  return NEW_ARGSPUSH(node1, node2);
8538 }
8539 
8540 static NODE *
8541 splat_array(NODE* node)
8542 {
8543  if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
8544  if (nd_type(node) == NODE_ARRAY) return node;
8545  return 0;
8546 }
8547 
8548 static NODE *
8549 node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
8550 {
8551  if (!lhs) return 0;
8552 
8553  switch (nd_type(lhs)) {
8554  case NODE_GASGN:
8555  case NODE_IASGN:
8556  case NODE_IASGN2:
8557  case NODE_LASGN:
8558  case NODE_DASGN:
8559  case NODE_DASGN_CURR:
8560  case NODE_MASGN:
8561  case NODE_CDECL:
8562  case NODE_CVASGN:
8563  lhs->nd_value = rhs;
8564  break;
8565 
8566  case NODE_ATTRASGN:
8567  case NODE_CALL:
8568  lhs->nd_args = arg_append(lhs->nd_args, rhs);
8569  break;
8570 
8571  default:
8572  /* should not happen */
8573  break;
8574  }
8575 
8576  return lhs;
8577 }
8578 
8579 static int
8580 value_expr_gen(struct parser_params *parser, NODE *node)
8581 {
8582  int cond = 0;
8583 
8584  if (!node) {
8585  rb_warning0("empty expression");
8586  }
8587  while (node) {
8588  switch (nd_type(node)) {
8589  case NODE_DEFN:
8590  case NODE_DEFS:
8591  parser_warning(node, "void value expression");
8592  return FALSE;
8593 
8594  case NODE_RETURN:
8595  case NODE_BREAK:
8596  case NODE_NEXT:
8597  case NODE_REDO:
8598  case NODE_RETRY:
8599  if (!cond) yyerror("void value expression");
8600  /* or "control never reach"? */
8601  return FALSE;
8602 
8603  case NODE_BLOCK:
8604  while (node->nd_next) {
8605  node = node->nd_next;
8606  }
8607  node = node->nd_head;
8608  break;
8609 
8610  case NODE_BEGIN:
8611  node = node->nd_body;
8612  break;
8613 
8614  case NODE_IF:
8615  if (!node->nd_body) {
8616  node = node->nd_else;
8617  break;
8618  }
8619  else if (!node->nd_else) {
8620  node = node->nd_body;
8621  break;
8622  }
8623  if (!value_expr(node->nd_body)) return FALSE;
8624  node = node->nd_else;
8625  break;
8626 
8627  case NODE_AND:
8628  case NODE_OR:
8629  cond = 1;
8630  node = node->nd_2nd;
8631  break;
8632 
8633  default:
8634  return TRUE;
8635  }
8636  }
8637 
8638  return TRUE;
8639 }
8640 
8641 static void
8642 void_expr_gen(struct parser_params *parser, NODE *node)
8643 {
8644  const char *useless = 0;
8645 
8646  if (!RTEST(ruby_verbose)) return;
8647 
8648  if (!node) return;
8649  switch (nd_type(node)) {
8650  case NODE_CALL:
8651  switch (node->nd_mid) {
8652  case '+':
8653  case '-':
8654  case '*':
8655  case '/':
8656  case '%':
8657  case tPOW:
8658  case tUPLUS:
8659  case tUMINUS:
8660  case '|':
8661  case '^':
8662  case '&':
8663  case tCMP:
8664  case '>':
8665  case tGEQ:
8666  case '<':
8667  case tLEQ:
8668  case tEQ:
8669  case tNEQ:
8670  useless = rb_id2name(node->nd_mid);
8671  break;
8672  }
8673  break;
8674 
8675  case NODE_LVAR:
8676  case NODE_DVAR:
8677  case NODE_GVAR:
8678  case NODE_IVAR:
8679  case NODE_CVAR:
8680  case NODE_NTH_REF:
8681  case NODE_BACK_REF:
8682  useless = "a variable";
8683  break;
8684  case NODE_CONST:
8685  useless = "a constant";
8686  break;
8687  case NODE_LIT:
8688  case NODE_STR:
8689  case NODE_DSTR:
8690  case NODE_DREGX:
8691  case NODE_DREGX_ONCE:
8692  useless = "a literal";
8693  break;
8694  case NODE_COLON2:
8695  case NODE_COLON3:
8696  useless = "::";
8697  break;
8698  case NODE_DOT2:
8699  useless = "..";
8700  break;
8701  case NODE_DOT3:
8702  useless = "...";
8703  break;
8704  case NODE_SELF:
8705  useless = "self";
8706  break;
8707  case NODE_NIL:
8708  useless = "nil";
8709  break;
8710  case NODE_TRUE:
8711  useless = "true";
8712  break;
8713  case NODE_FALSE:
8714  useless = "false";
8715  break;
8716  case NODE_DEFINED:
8717  useless = "defined?";
8718  break;
8719  }
8720 
8721  if (useless) {
8722  int line = ruby_sourceline;
8723 
8724  ruby_sourceline = nd_line(node);
8725  rb_warnS("possibly useless use of %s in void context", useless);
8726  ruby_sourceline = line;
8727  }
8728 }
8729 
8730 static void
8731 void_stmts_gen(struct parser_params *parser, NODE *node)
8732 {
8733  if (!RTEST(ruby_verbose)) return;
8734  if (!node) return;
8735  if (nd_type(node) != NODE_BLOCK) return;
8736 
8737  for (;;) {
8738  if (!node->nd_next) return;
8739  void_expr0(node->nd_head);
8740  node = node->nd_next;
8741  }
8742 }
8743 
8744 static NODE *
8745 remove_begin(NODE *node)
8746 {
8747  NODE **n = &node, *n1 = node;
8748  while (n1 && nd_type(n1) == NODE_BEGIN && n1->nd_body) {
8749  *n = n1 = n1->nd_body;
8750  }
8751  return node;
8752 }
8753 
8754 static void
8755 reduce_nodes_gen(struct parser_params *parser, NODE **body)
8756 {
8757  NODE *node = *body;
8758 
8759  if (!node) {
8760  *body = NEW_NIL();
8761  return;
8762  }
8763 #define subnodes(n1, n2) \
8764  ((!node->n1) ? (node->n2 ? (body = &node->n2, 1) : 0) : \
8765  (!node->n2) ? (body = &node->n1, 1) : \
8766  (reduce_nodes(&node->n1), body = &node->n2, 1))
8767 
8768  while (node) {
8769  int newline = (int)(node->flags & NODE_FL_NEWLINE);
8770  switch (nd_type(node)) {
8771  end:
8772  case NODE_NIL:
8773  *body = 0;
8774  return;
8775  case NODE_RETURN:
8776  *body = node = node->nd_stts;
8777  if (newline && node) node->flags |= NODE_FL_NEWLINE;
8778  continue;
8779  case NODE_BEGIN:
8780  *body = node = node->nd_body;
8781  if (newline && node) node->flags |= NODE_FL_NEWLINE;
8782  continue;
8783  case NODE_BLOCK:
8784  body = &node->nd_end->nd_head;
8785  break;
8786  case NODE_IF:
8787  if (subnodes(nd_body, nd_else)) break;
8788  return;
8789  case NODE_CASE:
8790  body = &node->nd_body;
8791  break;
8792  case NODE_WHEN:
8793  if (!subnodes(nd_body, nd_next)) goto end;
8794  break;
8795  case NODE_ENSURE:
8796  if (!subnodes(nd_head, nd_resq)) goto end;
8797  break;
8798  case NODE_RESCUE:
8799  if (node->nd_else) {
8800  body = &node->nd_resq;
8801  break;
8802  }
8803  if (!subnodes(nd_head, nd_resq)) goto end;
8804  break;
8805  default:
8806  return;
8807  }
8808  node = *body;
8809  if (newline && node) node->flags |= NODE_FL_NEWLINE;
8810  }
8811 
8812 #undef subnodes
8813 }
8814 
8815 static int
8816 assign_in_cond(struct parser_params *parser, NODE *node)
8817 {
8818  switch (nd_type(node)) {
8819  case NODE_MASGN:
8820  yyerror("multiple assignment in conditional");
8821  return 1;
8822 
8823  case NODE_LASGN:
8824  case NODE_DASGN:
8825  case NODE_DASGN_CURR:
8826  case NODE_GASGN:
8827  case NODE_IASGN:
8828  break;
8829 
8830  default:
8831  return 0;
8832  }
8833 
8834  if (!node->nd_value) return 1;
8835  switch (nd_type(node->nd_value)) {
8836  case NODE_LIT:
8837  case NODE_STR:
8838  case NODE_NIL:
8839  case NODE_TRUE:
8840  case NODE_FALSE:
8841  /* reports always */
8842  parser_warn(node->nd_value, "found = in conditional, should be ==");
8843  return 1;
8844 
8845  case NODE_DSTR:
8846  case NODE_XSTR:
8847  case NODE_DXSTR:
8848  case NODE_EVSTR:
8849  case NODE_DREGX:
8850  default:
8851  break;
8852  }
8853  return 1;
8854 }
8855 
8856 static void
8857 warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
8858 {
8859  if (!e_option_supplied(parser)) parser_warn(node, str);
8860 }
8861 
8862 static void
8863 warning_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
8864 {
8865  if (!e_option_supplied(parser)) parser_warning(node, str);
8866 }
8867 
8868 static void
8869 fixup_nodes(NODE **rootnode)
8870 {
8871  NODE *node, *next, *head;
8872 
8873  for (node = *rootnode; node; node = next) {
8874  enum node_type type;
8875  VALUE val;
8876 
8877  next = node->nd_next;
8878  head = node->nd_head;
8879  rb_gc_force_recycle((VALUE)node);
8880  *rootnode = next;
8881  switch (type = nd_type(head)) {
8882  case NODE_DOT2:
8883  case NODE_DOT3:
8884  val = rb_range_new(head->nd_beg->nd_lit, head->nd_end->nd_lit,
8885  type == NODE_DOT3);
8886  rb_gc_force_recycle((VALUE)head->nd_beg);
8887  rb_gc_force_recycle((VALUE)head->nd_end);
8888  nd_set_type(head, NODE_LIT);
8889  head->nd_lit = val;
8890  break;
8891  default:
8892  break;
8893  }
8894  }
8895 }
8896 
8897 static NODE *cond0(struct parser_params*,NODE*);
8898 
8899 static NODE*
8900 range_op(struct parser_params *parser, NODE *node)
8901 {
8902  enum node_type type;
8903 
8904  if (node == 0) return 0;
8905 
8906  type = nd_type(node);
8907  value_expr(node);
8908  if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
8909  warn_unless_e_option(parser, node, "integer literal in conditional range");
8910  return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."))));
8911  }
8912  return cond0(parser, node);
8913 }
8914 
8915 static int
8916 literal_node(NODE *node)
8917 {
8918  if (!node) return 1; /* same as NODE_NIL */
8919  switch (nd_type(node)) {
8920  case NODE_LIT:
8921  case NODE_STR:
8922  case NODE_DSTR:
8923  case NODE_EVSTR:
8924  case NODE_DREGX:
8925  case NODE_DREGX_ONCE:
8926  case NODE_DSYM:
8927  return 2;
8928  case NODE_TRUE:
8929  case NODE_FALSE:
8930  case NODE_NIL:
8931  return 1;
8932  }
8933  return 0;
8934 }
8935 
8936 static NODE*
8937 cond0(struct parser_params *parser, NODE *node)
8938 {
8939  if (node == 0) return 0;
8940  assign_in_cond(parser, node);
8941 
8942  switch (nd_type(node)) {
8943  case NODE_DSTR:
8944  case NODE_EVSTR:
8945  case NODE_STR:
8946  rb_warn0("string literal in condition");
8947  break;
8948 
8949  case NODE_DREGX:
8950  case NODE_DREGX_ONCE:
8951  warning_unless_e_option(parser, node, "regex literal in condition");
8952  return NEW_MATCH2(node, NEW_GVAR(rb_intern("$_")));
8953 
8954  case NODE_AND:
8955  case NODE_OR:
8956  node->nd_1st = cond0(parser, node->nd_1st);
8957  node->nd_2nd = cond0(parser, node->nd_2nd);
8958  break;
8959 
8960  case NODE_DOT2:
8961  case NODE_DOT3:
8962  node->nd_beg = range_op(parser, node->nd_beg);
8963  node->nd_end = range_op(parser, node->nd_end);
8964  if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
8965  else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
8966  if (!e_option_supplied(parser)) {
8967  int b = literal_node(node->nd_beg);
8968  int e = literal_node(node->nd_end);
8969  if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
8970  parser_warn(node, "range literal in condition");
8971  }
8972  }
8973  break;
8974 
8975  case NODE_DSYM:
8976  parser_warning(node, "literal in condition");
8977  break;
8978 
8979  case NODE_LIT:
8980  if (TYPE(node->nd_lit) == T_REGEXP) {
8981  warn_unless_e_option(parser, node, "regex literal in condition");
8982  nd_set_type(node, NODE_MATCH);
8983  }
8984  else {
8985  parser_warning(node, "literal in condition");
8986  }
8987  default:
8988  break;
8989  }
8990  return node;
8991 }
8992 
8993 static NODE*
8994 cond_gen(struct parser_params *parser, NODE *node)
8995 {
8996  if (node == 0) return 0;
8997  return cond0(parser, node);
8998 }
8999 
9000 static NODE*
9001 logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *right)
9002 {
9003  value_expr(left);
9004  if (left && (enum node_type)nd_type(left) == type) {
9005  NODE *node = left, *second;
9006  while ((second = node->nd_2nd) != 0 && (enum node_type)nd_type(second) == type) {
9007  node = second;
9008  }
9009  node->nd_2nd = NEW_NODE(type, second, right, 0);
9010  return left;
9011  }
9012  return NEW_NODE(type, left, right, 0);
9013 }
9014 
9015 static void
9016 no_blockarg(struct parser_params *parser, NODE *node)
9017 {
9018  if (node && nd_type(node) == NODE_BLOCK_PASS) {
9019  compile_error(PARSER_ARG "block argument should not be given");
9020  }
9021 }
9022 
9023 static NODE *
9024 ret_args_gen(struct parser_params *parser, NODE *node)
9025 {
9026  if (node) {
9027  no_blockarg(parser, node);
9028  if (nd_type(node) == NODE_ARRAY) {
9029  if (node->nd_next == 0) {
9030  node = node->nd_head;
9031  }
9032  else {
9033  nd_set_type(node, NODE_VALUES);
9034  }
9035  }
9036  }
9037  return node;
9038 }
9039 
9040 static NODE *
9041 new_yield_gen(struct parser_params *parser, NODE *node)
9042 {
9043  long state = Qtrue;
9044 
9045  if (node) {
9046  no_blockarg(parser, node);
9047  if (node && nd_type(node) == NODE_SPLAT) {
9048  state = Qtrue;
9049  }
9050  }
9051  else {
9052  state = Qfalse;
9053  }
9054  return NEW_YIELD(node, state);
9055 }
9056 
9057 static NODE*
9058 negate_lit(NODE *node)
9059 {
9060  switch (TYPE(node->nd_lit)) {
9061  case T_FIXNUM:
9062  node->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit));
9063  break;
9064  case T_BIGNUM:
9065  node->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0);
9066  break;
9067  case T_FLOAT:
9068  RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
9069  break;
9070  default:
9071  break;
9072  }
9073  return node;
9074 }
9075 
9076 static NODE *
9077 arg_blk_pass(NODE *node1, NODE *node2)
9078 {
9079  if (node2) {
9080  node2->nd_head = node1;
9081  return node2;
9082  }
9083  return node1;
9084 }
9085 
9086 static NODE*
9087 new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, ID b)
9088 {
9089  int saved_line = ruby_sourceline;
9090  NODE *node;
9091  NODE *i1, *i2 = 0;
9092 
9093  node = NEW_ARGS(m ? m->nd_plen : 0, o);
9094  i1 = m ? m->nd_next : 0;
9095  node->nd_next = NEW_ARGS_AUX(r, b);
9096 
9097  if (p) {
9098  i2 = p->nd_next;
9099  node->nd_next->nd_next = NEW_ARGS_AUX(p->nd_pid, p->nd_plen);
9100  }
9101  else if (i1) {
9102  node->nd_next->nd_next = NEW_ARGS_AUX(0, 0);
9103  }
9104  if (i1 || i2) {
9105  node->nd_next->nd_next->nd_next = NEW_NODE(NODE_AND, i1, i2, 0);
9106  }
9107  ruby_sourceline = saved_line;
9108  return node;
9109 }
9110 #endif /* !RIPPER */
9111 
9112 static void
9113 warn_unused_var(struct parser_params *parser, struct local_vars *local)
9114 {
9115  int i, cnt;
9116  ID *v, *u;
9117 
9118  if (!local->used) return;
9119  v = local->vars->tbl;
9120  u = local->used->tbl;
9121  cnt = local->used->pos;
9122  if (cnt != local->vars->pos) {
9123  rb_bug("local->used->pos != local->vars->pos");
9124  }
9125  for (i = 0; i < cnt; ++i) {
9126  if (!v[i] || (u[i] & LVAR_USED)) continue;
9127  if (idUScore == v[i]) continue;
9128  rb_compile_warn(ruby_sourcefile, (int)u[i], "assigned but unused variable - %s", rb_id2name(v[i]));
9129  }
9130 }
9131 
9132 static void
9133 local_push_gen(struct parser_params *parser, int inherit_dvars)
9134 {
9135  struct local_vars *local;
9136 
9137  local = ALLOC(struct local_vars);
9138  local->prev = lvtbl;
9139  local->args = vtable_alloc(0);
9140  local->vars = vtable_alloc(inherit_dvars ? DVARS_INHERIT : DVARS_TOPSCOPE);
9141  local->used = !inherit_dvars && RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
9142  lvtbl = local;
9143 }
9144 
9145 static void
9146 local_pop_gen(struct parser_params *parser)
9147 {
9148  struct local_vars *local = lvtbl->prev;
9149  if (lvtbl->used) {
9150  warn_unused_var(parser, lvtbl);
9151  vtable_free(lvtbl->used);
9152  }
9153  vtable_free(lvtbl->args);
9154  vtable_free(lvtbl->vars);
9155  xfree(lvtbl);
9156  lvtbl = local;
9157 }
9158 
9159 #ifndef RIPPER
9160 static ID*
9161 vtable_tblcpy(ID *buf, const struct vtable *src)
9162 {
9163  int i, cnt = vtable_size(src);
9164 
9165  if (cnt > 0) {
9166  buf[0] = cnt;
9167  for (i = 0; i < cnt; i++) {
9168  buf[i] = src->tbl[i];
9169  }
9170  return buf;
9171  }
9172  return 0;
9173 }
9174 
9175 static ID*
9176 local_tbl_gen(struct parser_params *parser)
9177 {
9178  int cnt = vtable_size(lvtbl->args) + vtable_size(lvtbl->vars);
9179  ID *buf;
9180 
9181  if (cnt <= 0) return 0;
9182  buf = ALLOC_N(ID, cnt + 1);
9183  vtable_tblcpy(buf+1, lvtbl->args);
9184  vtable_tblcpy(buf+vtable_size(lvtbl->args)+1, lvtbl->vars);
9185  buf[0] = cnt;
9186  return buf;
9187 }
9188 #endif
9189 
9190 static int
9191 arg_var_gen(struct parser_params *parser, ID id)
9192 {
9193  vtable_add(lvtbl->args, id);
9194  return vtable_size(lvtbl->args) - 1;
9195 }
9196 
9197 static int
9198 local_var_gen(struct parser_params *parser, ID id)
9199 {
9200  vtable_add(lvtbl->vars, id);
9201  if (lvtbl->used) {
9203  }
9204  return vtable_size(lvtbl->vars) - 1;
9205 }
9206 
9207 static int
9208 local_id_gen(struct parser_params *parser, ID id)
9209 {
9210  struct vtable *vars, *args, *used;
9211 
9212  vars = lvtbl->vars;
9213  args = lvtbl->args;
9214  used = lvtbl->used;
9215 
9216  while (vars && POINTER_P(vars->prev)) {
9217  vars = vars->prev;
9218  args = args->prev;
9219  if (used) used = used->prev;
9220  }
9221 
9222  if (vars && vars->prev == DVARS_INHERIT) {
9223  return rb_local_defined(id);
9224  }
9225  else if (vtable_included(args, id)) {
9226  return 1;
9227  }
9228  else {
9229  int i = vtable_included(vars, id);
9230  if (i && used) used->tbl[i-1] |= LVAR_USED;
9231  return i != 0;
9232  }
9233 }
9234 
9235 static const struct vtable *
9236 dyna_push_gen(struct parser_params *parser)
9237 {
9238  lvtbl->args = vtable_alloc(lvtbl->args);
9239  lvtbl->vars = vtable_alloc(lvtbl->vars);
9240  if (lvtbl->used) {
9241  lvtbl->used = vtable_alloc(lvtbl->used);
9242  }
9243  return lvtbl->args;
9244 }
9245 
9246 static void
9247 dyna_pop_1(struct parser_params *parser)
9248 {
9249  struct vtable *tmp;
9250 
9251  if ((tmp = lvtbl->used) != 0) {
9252  warn_unused_var(parser, lvtbl);
9253  lvtbl->used = lvtbl->used->prev;
9254  vtable_free(tmp);
9255  }
9256  tmp = lvtbl->args;
9257  lvtbl->args = lvtbl->args->prev;
9258  vtable_free(tmp);
9259  tmp = lvtbl->vars;
9260  lvtbl->vars = lvtbl->vars->prev;
9261  vtable_free(tmp);
9262 }
9263 
9264 static void
9265 dyna_pop_gen(struct parser_params *parser, const struct vtable *lvargs)
9266 {
9267  while (lvtbl->args != lvargs) {
9268  dyna_pop_1(parser);
9269  if (!lvtbl->args) {
9270  struct local_vars *local = lvtbl->prev;
9271  xfree(lvtbl);
9272  lvtbl = local;
9273  }
9274  }
9275  dyna_pop_1(parser);
9276 }
9277 
9278 static int
9279 dyna_in_block_gen(struct parser_params *parser)
9280 {
9281  return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
9282 }
9283 
9284 static int
9285 dvar_defined_gen(struct parser_params *parser, ID id, int get)
9286 {
9287  struct vtable *vars, *args, *used;
9288  int i;
9289 
9290  args = lvtbl->args;
9291  vars = lvtbl->vars;
9292  used = lvtbl->used;
9293 
9294  while (POINTER_P(vars)) {
9295  if (vtable_included(args, id)) {
9296  return 1;
9297  }
9298  if ((i = vtable_included(vars, id)) != 0) {
9299  if (used) used->tbl[i-1] |= LVAR_USED;
9300  return 1;
9301  }
9302  args = args->prev;
9303  vars = vars->prev;
9304  if (get) used = 0;
9305  if (used) used = used->prev;
9306  }
9307 
9308  if (vars == DVARS_INHERIT) {
9309  return rb_dvar_defined(id);
9310  }
9311 
9312  return 0;
9313 }
9314 
9315 static int
9316 dvar_curr_gen(struct parser_params *parser, ID id)
9317 {
9318  return (vtable_included(lvtbl->args, id) ||
9319  vtable_included(lvtbl->vars, id));
9320 }
9321 
9322 #ifndef RIPPER
9323 static void
9324 reg_fragment_setenc_gen(struct parser_params* parser, VALUE str, int options)
9325 {
9326  int c = RE_OPTION_ENCODING_IDX(options);
9327 
9328  if (c) {
9329  int opt, idx;
9330  rb_char_to_option_kcode(c, &opt, &idx);
9331  if (idx != ENCODING_GET(str) &&
9333  goto error;
9334  }
9335  ENCODING_SET(str, idx);
9336  }
9337  else if (RE_OPTION_ENCODING_NONE(options)) {
9338  if (!ENCODING_IS_ASCII8BIT(str) &&
9340  c = 'n';
9341  goto error;
9342  }
9344  }
9345  else if (parser->enc == rb_usascii_encoding()) {
9347  /* raise in re.c */
9349  }
9350  else {
9352  }
9353  }
9354  return;
9355 
9356  error:
9358  "regexp encoding option '%c' differs from source encoding '%s'",
9359  c, rb_enc_name(rb_enc_get(str)));
9360 }
9361 
9362 static int
9363 reg_fragment_check_gen(struct parser_params* parser, VALUE str, int options)
9364 {
9365  VALUE err;
9366  reg_fragment_setenc(str, options);
9367  err = rb_reg_check_preprocess(str);
9368  if (err != Qnil) {
9369  err = rb_obj_as_string(err);
9370  compile_error(PARSER_ARG "%s", RSTRING_PTR(err));
9371  RB_GC_GUARD(err);
9372  return 0;
9373  }
9374  return 1;
9375 }
9376 
9377 typedef struct {
9378  struct parser_params* parser;
9379  rb_encoding *enc;
9380  NODE *succ_block;
9381  NODE *fail_block;
9382  int num;
9384 
9385 static int
9386 reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
9387  int back_num, int *back_refs, OnigRegex regex, void *arg0)
9388 {
9390  struct parser_params* parser = arg->parser;
9391  rb_encoding *enc = arg->enc;
9392  long len = name_end - name;
9393  const char *s = (const char *)name;
9394  ID var;
9395 
9396  arg->num++;
9397 
9398  if (arg->succ_block == 0) {
9399  arg->succ_block = NEW_BEGIN(0);
9400  arg->fail_block = NEW_BEGIN(0);
9401  }
9402 
9403  if (!len || (*name != '_' && ISASCII(*name) && !rb_enc_islower(*name, enc)) ||
9404  (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) ||
9405  !rb_enc_symname2_p(s, len, enc)) {
9406  return ST_CONTINUE;
9407  }
9408  var = rb_intern3(s, len, enc);
9409  if (dvar_defined(var) || local_id(var)) {
9410  rb_warningS("named capture conflicts a local variable - %s",
9411  rb_id2name(var));
9412  }
9413  arg->succ_block = block_append(arg->succ_block,
9415  NEW_CALL(
9416  gettable(rb_intern("$~")),
9417  idAREF,
9418  NEW_LIST(NEW_LIT(ID2SYM(var))))
9419  )));
9420  arg->fail_block = block_append(arg->fail_block,
9422  return ST_CONTINUE;
9423 }
9424 
9425 static NODE *
9426 reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match)
9427 {
9429 
9430  arg.parser = parser;
9431  arg.enc = rb_enc_get(regexp);
9432  arg.succ_block = 0;
9433  arg.fail_block = 0;
9434  arg.num = 0;
9435  onig_foreach_name(RREGEXP(regexp)->ptr, reg_named_capture_assign_iter, (void*)&arg);
9436 
9437  if (arg.num == 0)
9438  return match;
9439 
9440  return
9441  block_append(
9442  newline_node(match),
9443  NEW_IF(gettable(rb_intern("$~")),
9444  block_append(
9445  newline_node(arg.succ_block),
9446  newline_node(
9447  NEW_CALL(
9448  gettable(rb_intern("$~")),
9449  rb_intern("begin"),
9450  NEW_LIST(NEW_LIT(INT2FIX(0)))))),
9451  block_append(
9452  newline_node(arg.fail_block),
9453  newline_node(
9454  NEW_LIT(Qnil)))));
9455 }
9456 
9457 static VALUE
9458 reg_compile_gen(struct parser_params* parser, VALUE str, int options)
9459 {
9460  VALUE re;
9461  VALUE err;
9462 
9463  reg_fragment_setenc(str, options);
9464  err = rb_errinfo();
9465  re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
9466  if (NIL_P(re)) {
9467  ID mesg = rb_intern("mesg");
9468  VALUE m = rb_attr_get(rb_errinfo(), mesg);
9469  rb_set_errinfo(err);
9470  if (!NIL_P(err)) {
9471  rb_str_append(rb_str_cat(rb_attr_get(err, mesg), "\n", 1), m);
9472  }
9473  else {
9475  }
9476  return Qnil;
9477  }
9478  return re;
9479 }
9480 
9481 void
9482 rb_gc_mark_parser(void)
9483 {
9484 }
9485 
9486 NODE*
9487 rb_parser_append_print(VALUE vparser, NODE *node)
9488 {
9489  NODE *prelude = 0;
9490  NODE *scope = node;
9491  struct parser_params *parser;
9492 
9493  if (!node) return node;
9494 
9495  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
9496 
9497  node = node->nd_body;
9498 
9499  if (nd_type(node) == NODE_PRELUDE) {
9500  prelude = node;
9501  node = node->nd_body;
9502  }
9503 
9504  node = block_append(node,
9505  NEW_FCALL(rb_intern("print"),
9506  NEW_ARRAY(NEW_GVAR(rb_intern("$_")))));
9507  if (prelude) {
9508  prelude->nd_body = node;
9509  scope->nd_body = prelude;
9510  }
9511  else {
9512  scope->nd_body = node;
9513  }
9514 
9515  return scope;
9516 }
9517 
9518 NODE *
9519 rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
9520 {
9521  NODE *prelude = 0;
9522  NODE *scope = node;
9523  struct parser_params *parser;
9524 
9525  if (!node) return node;
9526 
9527  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
9528 
9529  node = node->nd_body;
9530 
9531  if (nd_type(node) == NODE_PRELUDE) {
9532  prelude = node;
9533  node = node->nd_body;
9534  }
9535  if (split) {
9536  node = block_append(NEW_GASGN(rb_intern("$F"),
9537  NEW_CALL(NEW_GVAR(rb_intern("$_")),
9538  rb_intern("split"), 0)),
9539  node);
9540  }
9541  if (chop) {
9542  node = block_append(NEW_CALL(NEW_GVAR(rb_intern("$_")),
9543  rb_intern("chop!"), 0), node);
9544  }
9545 
9546  node = NEW_OPT_N(node);
9547 
9548  if (prelude) {
9549  prelude->nd_body = node;
9550  scope->nd_body = prelude;
9551  }
9552  else {
9553  scope->nd_body = node;
9554  }
9555 
9556  return scope;
9557 }
9558 
9559 static const struct {
9560  ID token;
9561  const char *name;
9562 } op_tbl[] = {
9563  {tDOT2, ".."},
9564  {tDOT3, "..."},
9565  {'+', "+(binary)"},
9566  {'-', "-(binary)"},
9567  {tPOW, "**"},
9568  {tUPLUS, "+@"},
9569  {tUMINUS, "-@"},
9570  {tCMP, "<=>"},
9571  {tGEQ, ">="},
9572  {tLEQ, "<="},
9573  {tEQ, "=="},
9574  {tEQQ, "==="},
9575  {tNEQ, "!="},
9576  {tMATCH, "=~"},
9577  {tNMATCH, "!~"},
9578  {tAREF, "[]"},
9579  {tASET, "[]="},
9580  {tLSHFT, "<<"},
9581  {tRSHFT, ">>"},
9582  {tCOLON2, "::"},
9583 };
9584 
9585 #define op_tbl_count numberof(op_tbl)
9586 
9587 #ifndef ENABLE_SELECTOR_NAMESPACE
9588 #define ENABLE_SELECTOR_NAMESPACE 0
9589 #endif
9590 
9591 static struct symbols {
9592  ID last_id;
9593  st_table *sym_id;
9594  st_table *id_str;
9595 #if ENABLE_SELECTOR_NAMESPACE
9596  st_table *ivar2_id;
9597  st_table *id_ivar2;
9598 #endif
9600 } global_symbols = {tLAST_ID};
9601 
9602 static const struct st_hash_type symhash = {
9604  rb_str_hash,
9605 };
9606 
9607 #if ENABLE_SELECTOR_NAMESPACE
9608 struct ivar2_key {
9609  ID id;
9610  VALUE klass;
9611 };
9612 
9613 static int
9614 ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2)
9615 {
9616  if (key1->id == key2->id && key1->klass == key2->klass) {
9617  return 0;
9618  }
9619  return 1;
9620 }
9621 
9622 static int
9623 ivar2_hash(struct ivar2_key *key)
9624 {
9625  return (key->id << 8) ^ (key->klass >> 2);
9626 }
9627 
9628 static const struct st_hash_type ivar2_hash_type = {
9629  ivar2_cmp,
9630  ivar2_hash,
9631 };
9632 #endif
9633 
9634 void
9635 Init_sym(void)
9636 {
9637  global_symbols.sym_id = st_init_table_with_size(&symhash, 1000);
9639 #if ENABLE_SELECTOR_NAMESPACE
9640  global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
9641  global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
9642 #endif
9643 
9644  Init_id();
9645 }
9646 
9647 void
9648 rb_gc_mark_symbols(void)
9649 {
9653 }
9654 #endif /* !RIPPER */
9655 
9656 static ID
9657 internal_id_gen(struct parser_params *parser)
9658 {
9659  ID id = (ID)vtable_size(lvtbl->args) + (ID)vtable_size(lvtbl->vars);
9660  id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1;
9661  return ID_INTERNAL | (id << ID_SCOPE_SHIFT);
9662 }
9663 
9664 #ifndef RIPPER
9665 static int
9666 is_special_global_name(const char *m, const char *e, rb_encoding *enc)
9667 {
9668  int mb = 0;
9669 
9670  if (m >= e) return 0;
9671  switch (*m) {
9672  case '~': case '*': case '$': case '?': case '!': case '@':
9673  case '/': case '\\': case ';': case ',': case '.': case '=':
9674  case ':': case '<': case '>': case '\"':
9675  case '&': case '`': case '\'': case '+':
9676  case '0':
9677  ++m;
9678  break;
9679  case '-':
9680  ++m;
9681  if (m < e && is_identchar(m, e, enc)) {
9682  if (!ISASCII(*m)) mb = 1;
9683  m += rb_enc_mbclen(m, e, enc);
9684  }
9685  break;
9686  default:
9687  if (!rb_enc_isdigit(*m, enc)) return 0;
9688  do {
9689  if (!ISASCII(*m)) mb = 1;
9690  ++m;
9691  } while (m < e && rb_enc_isdigit(*m, enc));
9692  }
9693  return m == e ? mb + 1 : 0;
9694 }
9695 
9696 int
9697 rb_symname_p(const char *name)
9698 {
9699  return rb_enc_symname_p(name, rb_ascii8bit_encoding());
9700 }
9701 
9702 int
9703 rb_enc_symname_p(const char *name, rb_encoding *enc)
9704 {
9705  return rb_enc_symname2_p(name, strlen(name), enc);
9706 }
9707 
9708 int
9709 rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
9710 {
9711  const char *m = name;
9712  const char *e = m + len;
9713  int localid = FALSE;
9714 
9715  if (!m || len <= 0) return FALSE;
9716  switch (*m) {
9717  case '\0':
9718  return FALSE;
9719 
9720  case '$':
9721  if (is_special_global_name(++m, e, enc)) return TRUE;
9722  goto id;
9723 
9724  case '@':
9725  if (*++m == '@') ++m;
9726  goto id;
9727 
9728  case '<':
9729  switch (*++m) {
9730  case '<': ++m; break;
9731  case '=': if (*++m == '>') ++m; break;
9732  default: break;
9733  }
9734  break;
9735 
9736  case '>':
9737  switch (*++m) {
9738  case '>': case '=': ++m; break;
9739  }
9740  break;
9741 
9742  case '=':
9743  switch (*++m) {
9744  case '~': ++m; break;
9745  case '=': if (*++m == '=') ++m; break;
9746  default: return FALSE;
9747  }
9748  break;
9749 
9750  case '*':
9751  if (*++m == '*') ++m;
9752  break;
9753 
9754  case '+': case '-':
9755  if (*++m == '@') ++m;
9756  break;
9757 
9758  case '|': case '^': case '&': case '/': case '%': case '~': case '`':
9759  ++m;
9760  break;
9761 
9762  case '[':
9763  if (*++m != ']') return FALSE;
9764  if (*++m == '=') ++m;
9765  break;
9766 
9767  case '!':
9768  if (len == 1) return TRUE;
9769  switch (*++m) {
9770  case '=': case '~': ++m; break;
9771  default: return FALSE;
9772  }
9773  break;
9774 
9775  default:
9776  localid = !rb_enc_isupper(*m, enc);
9777  id:
9778  if (m >= e || (*m != '_' && !rb_enc_isalpha(*m, enc) && ISASCII(*m)))
9779  return FALSE;
9780  while (m < e && is_identchar(m, e, enc)) m += rb_enc_mbclen(m, e, enc);
9781  if (localid) {
9782  switch (*m) {
9783  case '!': case '?': case '=': ++m;
9784  }
9785  }
9786  break;
9787  }
9788  return m == e;
9789 }
9790 
9791 static ID
9792 register_symid(ID id, const char *name, long len, rb_encoding *enc)
9793 {
9794  VALUE str = rb_enc_str_new(name, len, enc);
9795  OBJ_FREEZE(str);
9798  return id;
9799 }
9800 
9801 ID
9802 rb_intern3(const char *name, long len, rb_encoding *enc)
9803 {
9804  const char *m = name;
9805  const char *e = m + len;
9806  unsigned char c;
9807  VALUE str;
9808  ID id;
9809  long last;
9810  int mb;
9811  st_data_t data;
9812  struct RString fake_str;
9813  fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
9814  fake_str.basic.klass = rb_cString;
9815  fake_str.as.heap.len = len;
9816  fake_str.as.heap.ptr = (char *)name;
9817  fake_str.as.heap.aux.capa = len;
9818  str = (VALUE)&fake_str;
9819  rb_enc_associate(str, enc);
9820  OBJ_FREEZE(str);
9821 
9823  rb_raise(rb_eEncodingError, "invalid encoding symbol");
9824  }
9825 
9826  if (st_lookup(global_symbols.sym_id, str, &data))
9827  return (ID)data;
9828 
9829  if (rb_cString && !rb_enc_asciicompat(enc)) {
9830  id = ID_JUNK;
9831  goto new_id;
9832  }
9833  last = len-1;
9834  id = 0;
9835  switch (*m) {
9836  case '$':
9837  id |= ID_GLOBAL;
9838  if ((mb = is_special_global_name(++m, e, enc)) != 0) {
9839  if (!--mb) enc = rb_ascii8bit_encoding();
9840  goto new_id;
9841  }
9842  break;
9843  case '@':
9844  if (m[1] == '@') {
9845  m++;
9846  id |= ID_CLASS;
9847  }
9848  else {
9849  id |= ID_INSTANCE;
9850  }
9851  m++;
9852  break;
9853  default:
9854  c = m[0];
9855  if (c != '_' && rb_enc_isascii(c, enc) && rb_enc_ispunct(c, enc)) {
9856  /* operators */
9857  int i;
9858 
9859  if (len == 1) {
9860  id = c;
9861  goto id_register;
9862  }
9863  for (i = 0; i < op_tbl_count; i++) {
9864  if (*op_tbl[i].name == *m &&
9865  strcmp(op_tbl[i].name, m) == 0) {
9866  id = op_tbl[i].token;
9867  goto id_register;
9868  }
9869  }
9870  }
9871 
9872  if (m[last] == '=') {
9873  /* attribute assignment */
9874  id = rb_intern3(name, last, enc);
9875  if (id > tLAST_TOKEN && !is_attrset_id(id)) {
9876  enc = rb_enc_get(rb_id2str(id));
9877  id = rb_id_attrset(id);
9878  goto id_register;
9879  }
9880  id = ID_ATTRSET;
9881  }
9882  else if (rb_enc_isupper(m[0], enc)) {
9883  id = ID_CONST;
9884  }
9885  else {
9886  id = ID_LOCAL;
9887  }
9888  break;
9889  }
9890  mb = 0;
9891  if (!rb_enc_isdigit(*m, enc)) {
9892  while (m <= name + last && is_identchar(m, e, enc)) {
9893  if (ISASCII(*m)) {
9894  m++;
9895  }
9896  else {
9897  mb = 1;
9898  m += rb_enc_mbclen(m, e, enc);
9899  }
9900  }
9901  }
9902  if (m - name < len) id = ID_JUNK;
9903  if (enc != rb_usascii_encoding()) {
9904  /*
9905  * this clause makes sense only when called from other than
9906  * rb_intern_str() taking care of code-range.
9907  */
9908  if (!mb) {
9909  for (; m <= name + len; ++m) {
9910  if (!ISASCII(*m)) goto mbstr;
9911  }
9912  enc = rb_usascii_encoding();
9913  }
9914  mbstr:;
9915  }
9916  new_id:
9917  if (global_symbols.last_id >= ~(ID)0 >> (ID_SCOPE_SHIFT+RUBY_SPECIAL_SHIFT)) {
9918  if (len > 20) {
9919  rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.20s...)",
9920  name);
9921  }
9922  else {
9923  rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.*s)",
9924  (int)len, name);
9925  }
9926  }
9928  id_register:
9929  return register_symid(id, name, len, enc);
9930 }
9931 
9932 ID
9933 rb_intern2(const char *name, long len)
9934 {
9935  return rb_intern3(name, len, rb_usascii_encoding());
9936 }
9937 
9938 #undef rb_intern
9939 ID
9940 rb_intern(const char *name)
9941 {
9942  return rb_intern2(name, strlen(name));
9943 }
9944 
9945 ID
9946 rb_intern_str(VALUE str)
9947 {
9948  rb_encoding *enc;
9949  ID id;
9950 
9952  enc = rb_usascii_encoding();
9953  }
9954  else {
9955  enc = rb_enc_get(str);
9956  }
9957  id = rb_intern3(RSTRING_PTR(str), RSTRING_LEN(str), enc);
9958  RB_GC_GUARD(str);
9959  return id;
9960 }
9961 
9962 VALUE
9963 rb_id2str(ID id)
9964 {
9965  st_data_t data;
9966 
9967  if (id < tLAST_TOKEN) {
9968  int i = 0;
9969 
9970  if (id < INT_MAX && rb_ispunct((int)id)) {
9971  VALUE str = global_symbols.op_sym[i = (int)id];
9972  if (!str) {
9973  char name[2];
9974  name[0] = (char)id;
9975  name[1] = 0;
9976  str = rb_usascii_str_new(name, 1);
9977  OBJ_FREEZE(str);
9978  global_symbols.op_sym[i] = str;
9979  }
9980  return str;
9981  }
9982  for (i = 0; i < op_tbl_count; i++) {
9983  if (op_tbl[i].token == id) {
9984  VALUE str = global_symbols.op_sym[i];
9985  if (!str) {
9986  str = rb_usascii_str_new2(op_tbl[i].name);
9987  OBJ_FREEZE(str);
9988  global_symbols.op_sym[i] = str;
9989  }
9990  return str;
9991  }
9992  }
9993  }
9994 
9995  if (st_lookup(global_symbols.id_str, id, &data)) {
9996  VALUE str = (VALUE)data;
9997  if (RBASIC(str)->klass == 0)
9998  RBASIC(str)->klass = rb_cString;
9999  return str;
10000  }
10001 
10002  if (is_attrset_id(id)) {
10003  ID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL;
10004  VALUE str;
10005 
10006  while (!(str = rb_id2str(id2))) {
10007  if (!is_local_id(id2)) return 0;
10008  id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;
10009  }
10010  str = rb_str_dup(str);
10011  rb_str_cat(str, "=", 1);
10012  rb_intern_str(str);
10013  if (st_lookup(global_symbols.id_str, id, &data)) {
10014  VALUE str = (VALUE)data;
10015  if (RBASIC(str)->klass == 0)
10016  RBASIC(str)->klass = rb_cString;
10017  return str;
10018  }
10019  }
10020  return 0;
10021 }
10022 
10023 const char *
10024 rb_id2name(ID id)
10025 {
10026  VALUE str = rb_id2str(id);
10027 
10028  if (!str) return 0;
10029  return RSTRING_PTR(str);
10030 }
10031 
10032 static int
10033 symbols_i(VALUE sym, ID value, VALUE ary)
10034 {
10035  rb_ary_push(ary, ID2SYM(value));
10036  return ST_CONTINUE;
10037 }
10038 
10039 /*
10040  * call-seq:
10041  * Symbol.all_symbols => array
10042  *
10043  * Returns an array of all the symbols currently in Ruby's symbol
10044  * table.
10045  *
10046  * Symbol.all_symbols.size #=> 903
10047  * Symbol.all_symbols[1,20] #=> [:floor, :ARGV, :Binding, :symlink,
10048  * :chown, :EOFError, :$;, :String,
10049  * :LOCK_SH, :"setuid?", :$<,
10050  * :default_proc, :compact, :extend,
10051  * :Tms, :getwd, :$=, :ThreadGroup,
10052  * :wait2, :$>]
10053  */
10054 
10055 VALUE
10056 rb_sym_all_symbols(void)
10057 {
10059 
10061  return ary;
10062 }
10063 
10064 int
10065 rb_is_const_id(ID id)
10066 {
10067  return is_const_id(id);
10068 }
10069 
10070 int
10071 rb_is_class_id(ID id)
10072 {
10073  return is_class_id(id);
10074 }
10075 
10076 int
10078 {
10079  return is_instance_id(id);
10080 }
10081 
10082 int
10083 rb_is_local_id(ID id)
10084 {
10085  return is_local_id(id);
10086 }
10087 
10088 int
10089 rb_is_junk_id(ID id)
10090 {
10091  return is_junk_id(id);
10092 }
10093 
10094 #endif /* !RIPPER */
10095 
10096 static void
10097 parser_initialize(struct parser_params *parser)
10098 {
10099  parser->eofp = Qfalse;
10100 
10101  parser->parser_lex_strterm = 0;
10102  parser->parser_cond_stack = 0;
10103  parser->parser_cmdarg_stack = 0;
10104  parser->parser_class_nest = 0;
10105  parser->parser_paren_nest = 0;
10106  parser->parser_lpar_beg = 0;
10107  parser->parser_in_single = 0;
10108  parser->parser_in_def = 0;
10109  parser->parser_in_defined = 0;
10110  parser->parser_compile_for_eval = 0;
10111  parser->parser_cur_mid = 0;
10112  parser->parser_tokenbuf = NULL;
10113  parser->parser_tokidx = 0;
10114  parser->parser_toksiz = 0;
10115  parser->parser_heredoc_end = 0;
10116  parser->parser_command_start = TRUE;
10117  parser->parser_deferred_nodes = 0;
10118  parser->parser_lex_pbeg = 0;
10119  parser->parser_lex_p = 0;
10120  parser->parser_lex_pend = 0;
10121  parser->parser_lvtbl = 0;
10122  parser->parser_ruby__end__seen = 0;
10123  parser->parser_ruby_sourcefile = 0;
10124 #ifndef RIPPER
10125  parser->is_ripper = 0;
10126  parser->parser_eval_tree_begin = 0;
10127  parser->parser_eval_tree = 0;
10128 #else
10129  parser->is_ripper = 1;
10130  parser->parser_ruby_sourcefile_string = Qnil;
10131  parser->delayed = Qnil;
10132 
10133  parser->result = Qnil;
10134  parser->parsing_thread = Qnil;
10135  parser->toplevel_p = TRUE;
10136 #endif
10137 #ifdef YYMALLOC
10138  parser->heap = NULL;
10139 #endif
10140  parser->enc = rb_usascii_encoding();
10141 }
10142 
10143 #ifdef RIPPER
10144 #define parser_mark ripper_parser_mark
10145 #define parser_free ripper_parser_free
10146 #endif
10147 
10148 static void
10149 parser_mark(void *ptr)
10150 {
10151  struct parser_params *p = (struct parser_params*)ptr;
10152 
10158 #ifndef RIPPER
10161  rb_gc_mark(p->debug_lines);
10162 #else
10163  rb_gc_mark(p->parser_ruby_sourcefile_string);
10164  rb_gc_mark(p->delayed);
10165  rb_gc_mark(p->value);
10166  rb_gc_mark(p->result);
10167  rb_gc_mark(p->parsing_thread);
10168 #endif
10169 #ifdef YYMALLOC
10170  rb_gc_mark((VALUE)p->heap);
10171 #endif
10172 }
10173 
10174 static void
10175 parser_free(void *ptr)
10176 {
10177  struct parser_params *p = (struct parser_params*)ptr;
10178  struct local_vars *local, *prev;
10179 
10180  if (p->parser_tokenbuf) {
10181  xfree(p->parser_tokenbuf);
10182  }
10183  for (local = p->parser_lvtbl; local; local = prev) {
10184  if (local->vars) xfree(local->vars);
10185  prev = local->prev;
10186  xfree(local);
10187  }
10188 #ifndef RIPPER
10190 #endif
10191  xfree(p);
10192 }
10193 
10194 static size_t
10195 parser_memsize(const void *ptr)
10196 {
10197  struct parser_params *p = (struct parser_params*)ptr;
10198  struct local_vars *local;
10199  size_t size = sizeof(*p);
10200 
10201  if (!ptr) return 0;
10202  size += p->parser_toksiz;
10203  for (local = p->parser_lvtbl; local; local = local->prev) {
10204  size += sizeof(*local);
10205  if (local->vars) size += local->vars->capa * sizeof(ID);
10206  }
10207 #ifndef RIPPER
10208  if (p->parser_ruby_sourcefile) {
10209  size += strlen(p->parser_ruby_sourcefile) + 1;
10210  }
10211 #endif
10212  return size;
10213 }
10214 
10215 static
10216 #ifndef RIPPER
10217 const
10218 #endif
10219 rb_data_type_t parser_data_type = {
10220  "parser",
10221  {
10222  parser_mark,
10223  parser_free,
10225  },
10226 };
10227 
10228 #ifndef RIPPER
10229 #undef rb_reserved_word
10230 
10231 const struct kwtable *
10232 rb_reserved_word(const char *str, unsigned int len)
10233 {
10234  return reserved_word(str, len);
10235 }
10236 
10237 static struct parser_params *
10238 parser_new(void)
10239 {
10240  struct parser_params *p;
10241 
10242  p = ALLOC_N(struct parser_params, 1);
10243  MEMZERO(p, struct parser_params, 1);
10244  parser_initialize(p);
10245  return p;
10246 }
10247 
10248 VALUE
10249 rb_parser_new(void)
10250 {
10251  struct parser_params *p = parser_new();
10252 
10253  return TypedData_Wrap_Struct(0, &parser_data_type, p);
10254 }
10255 
10256 /*
10257  * call-seq:
10258  * ripper#end_seen? -> Boolean
10259  *
10260  * Return true if parsed source ended by +\_\_END\_\_+.
10261  */
10262 VALUE
10263 rb_parser_end_seen_p(VALUE vparser)
10264 {
10265  struct parser_params *parser;
10266 
10267  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10268  return ruby__end__seen ? Qtrue : Qfalse;
10269 }
10270 
10271 /*
10272  * call-seq:
10273  * ripper#encoding -> encoding
10274  *
10275  * Return encoding of the source.
10276  */
10277 VALUE
10278 rb_parser_encoding(VALUE vparser)
10279 {
10280  struct parser_params *parser;
10281 
10282  TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10283  return rb_enc_from_encoding(parser->enc);
10284 }
10285 
10286 /*
10287  * call-seq:
10288  * ripper.yydebug -> true or false
10289  *
10290  * Get yydebug.
10291  */
10292 VALUE
10294 {
10295  struct parser_params *parser;
10296 
10297  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10298  return yydebug ? Qtrue : Qfalse;
10299 }
10300 
10301 /*
10302  * call-seq:
10303  * ripper.yydebug = flag
10304  *
10305  * Set yydebug.
10306  */
10307 VALUE
10308 rb_parser_set_yydebug(VALUE self, VALUE flag)
10309 {
10310  struct parser_params *parser;
10311 
10312  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10313  yydebug = RTEST(flag);
10314  return flag;
10315 }
10316 
10317 #ifdef YYMALLOC
10318 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
10319 #define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
10320 #define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
10321  (n)->u3.cnt = (c), (p))
10322 
10323 void *
10324 rb_parser_malloc(struct parser_params *parser, size_t size)
10325 {
10326  size_t cnt = HEAPCNT(1, size);
10327  NODE *n = NEWHEAP();
10328  void *ptr = xmalloc(size);
10329 
10330  return ADD2HEAP(n, cnt, ptr);
10331 }
10332 
10333 void *
10334 rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
10335 {
10336  size_t cnt = HEAPCNT(nelem, size);
10337  NODE *n = NEWHEAP();
10338  void *ptr = xcalloc(nelem, size);
10339 
10340  return ADD2HEAP(n, cnt, ptr);
10341 }
10342 
10343 void *
10344 rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
10345 {
10346  NODE *n;
10347  size_t cnt = HEAPCNT(1, size);
10348 
10349  if (ptr && (n = parser->heap) != NULL) {
10350  do {
10351  if (n->u1.node == ptr) {
10352  n->u1.node = ptr = xrealloc(ptr, size);
10353  if (n->u3.cnt) n->u3.cnt = cnt;
10354  return ptr;
10355  }
10356  } while ((n = n->u2.node) != NULL);
10357  }
10358  n = NEWHEAP();
10359  ptr = xrealloc(ptr, size);
10360  return ADD2HEAP(n, cnt, ptr);
10361 }
10362 
10363 void
10364 rb_parser_free(struct parser_params *parser, void *ptr)
10365 {
10366  NODE **prev = &parser->heap, *n;
10367 
10368  while ((n = *prev) != NULL) {
10369  if (n->u1.node == ptr) {
10370  *prev = n->u2.node;
10372  break;
10373  }
10374  prev = &n->u2.node;
10375  }
10376  xfree(ptr);
10377 }
10378 #endif
10379 #endif
10380 
10381 #ifdef RIPPER
10382 #ifdef RIPPER_DEBUG
10383 extern int rb_is_pointer_to_heap(VALUE);
10384 
10385 /* :nodoc: */
10386 static VALUE
10387 ripper_validate_object(VALUE self, VALUE x)
10388 {
10389  if (x == Qfalse) return x;
10390  if (x == Qtrue) return x;
10391  if (x == Qnil) return x;
10392  if (x == Qundef)
10393  rb_raise(rb_eArgError, "Qundef given");
10394  if (FIXNUM_P(x)) return x;
10395  if (SYMBOL_P(x)) return x;
10396  if (!rb_is_pointer_to_heap(x))
10397  rb_raise(rb_eArgError, "invalid pointer: %p", x);
10398  switch (TYPE(x)) {
10399  case T_STRING:
10400  case T_OBJECT:
10401  case T_ARRAY:
10402  case T_BIGNUM:
10403  case T_FLOAT:
10404  return x;
10405  case T_NODE:
10406  if (nd_type(x) != NODE_LASGN) {
10407  rb_raise(rb_eArgError, "NODE given: %p", x);
10408  }
10409  return ((NODE *)x)->nd_rval;
10410  default:
10411  rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
10412  x, rb_obj_classname(x));
10413  }
10414  return x;
10415 }
10416 #endif
10417 
10418 #define validate(x) ((x) = get_value(x))
10419 
10420 static VALUE
10421 ripper_dispatch0(struct parser_params *parser, ID mid)
10422 {
10423  return rb_funcall(parser->value, mid, 0);
10424 }
10425 
10426 static VALUE
10427 ripper_dispatch1(struct parser_params *parser, ID mid, VALUE a)
10428 {
10429  validate(a);
10430  return rb_funcall(parser->value, mid, 1, a);
10431 }
10432 
10433 static VALUE
10434 ripper_dispatch2(struct parser_params *parser, ID mid, VALUE a, VALUE b)
10435 {
10436  validate(a);
10437  validate(b);
10438  return rb_funcall(parser->value, mid, 2, a, b);
10439 }
10440 
10441 static VALUE
10442 ripper_dispatch3(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c)
10443 {
10444  validate(a);
10445  validate(b);
10446  validate(c);
10447  return rb_funcall(parser->value, mid, 3, a, b, c);
10448 }
10449 
10450 static VALUE
10451 ripper_dispatch4(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d)
10452 {
10453  validate(a);
10454  validate(b);
10455  validate(c);
10456  validate(d);
10457  return rb_funcall(parser->value, mid, 4, a, b, c, d);
10458 }
10459 
10460 static VALUE
10461 ripper_dispatch5(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e)
10462 {
10463  validate(a);
10464  validate(b);
10465  validate(c);
10466  validate(d);
10467  validate(e);
10468  return rb_funcall(parser->value, mid, 5, a, b, c, d, e);
10469 }
10470 
10471 static const struct kw_assoc {
10472  ID id;
10473  const char *name;
10474 } keyword_to_name[] = {
10475  {keyword_class, "class"},
10476  {keyword_module, "module"},
10477  {keyword_def, "def"},
10478  {keyword_undef, "undef"},
10479  {keyword_begin, "begin"},
10480  {keyword_rescue, "rescue"},
10481  {keyword_ensure, "ensure"},
10482  {keyword_end, "end"},
10483  {keyword_if, "if"},
10484  {keyword_unless, "unless"},
10485  {keyword_then, "then"},
10486  {keyword_elsif, "elsif"},
10487  {keyword_else, "else"},
10488  {keyword_case, "case"},
10489  {keyword_when, "when"},
10490  {keyword_while, "while"},
10491  {keyword_until, "until"},
10492  {keyword_for, "for"},
10493  {keyword_break, "break"},
10494  {keyword_next, "next"},
10495  {keyword_redo, "redo"},
10496  {keyword_retry, "retry"},
10497  {keyword_in, "in"},
10498  {keyword_do, "do"},
10499  {keyword_do_cond, "do"},
10500  {keyword_do_block, "do"},
10501  {keyword_return, "return"},
10502  {keyword_yield, "yield"},
10503  {keyword_super, "super"},
10504  {keyword_self, "self"},
10505  {keyword_nil, "nil"},
10506  {keyword_true, "true"},
10507  {keyword_false, "false"},
10508  {keyword_and, "and"},
10509  {keyword_or, "or"},
10510  {keyword_not, "not"},
10511  {modifier_if, "if"},
10512  {modifier_unless, "unless"},
10513  {modifier_while, "while"},
10514  {modifier_until, "until"},
10515  {modifier_rescue, "rescue"},
10516  {keyword_alias, "alias"},
10517  {keyword_defined, "defined?"},
10518  {keyword_BEGIN, "BEGIN"},
10519  {keyword_END, "END"},
10520  {keyword__LINE__, "__LINE__"},
10521  {keyword__FILE__, "__FILE__"},
10522  {keyword__ENCODING__, "__ENCODING__"},
10523  {0, NULL}
10524 };
10525 
10526 static const char*
10527 keyword_id_to_str(ID id)
10528 {
10529  const struct kw_assoc *a;
10530 
10531  for (a = keyword_to_name; a->id; a++) {
10532  if (a->id == id)
10533  return a->name;
10534  }
10535  return NULL;
10536 }
10537 
10538 #undef ripper_id2sym
10539 static VALUE
10540 ripper_id2sym(ID id)
10541 {
10542  const char *name;
10543  char buf[8];
10544 
10545  if (id <= 256) {
10546  buf[0] = (char)id;
10547  buf[1] = '\0';
10548  return ID2SYM(rb_intern2(buf, 1));
10549  }
10550  if ((name = keyword_id_to_str(id))) {
10551  return ID2SYM(rb_intern(name));
10552  }
10553  switch (id) {
10554  case tOROP:
10555  name = "||";
10556  break;
10557  case tANDOP:
10558  name = "&&";
10559  break;
10560  default:
10561  name = rb_id2name(id);
10562  if (!name) {
10563  rb_bug("cannot convert ID to string: %ld", (unsigned long)id);
10564  }
10565  return ID2SYM(id);
10566  }
10567  return ID2SYM(rb_intern(name));
10568 }
10569 
10570 static ID
10571 ripper_get_id(VALUE v)
10572 {
10573  NODE *nd;
10574  if (!RB_TYPE_P(v, T_NODE)) return 0;
10575  nd = (NODE *)v;
10576  if (nd_type(nd) != NODE_LASGN) return 0;
10577  return nd->nd_vid;
10578 }
10579 
10580 static VALUE
10581 ripper_get_value(VALUE v)
10582 {
10583  NODE *nd;
10584  if (v == Qundef) return Qnil;
10585  if (!RB_TYPE_P(v, T_NODE)) return v;
10586  nd = (NODE *)v;
10587  if (nd_type(nd) != NODE_LASGN) return Qnil;
10588  return nd->nd_rval;
10589 }
10590 
10591 static void
10592 ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
10593 {
10594  VALUE str;
10595  va_list args;
10596 
10597  va_start(args, fmt);
10598  str = rb_vsprintf(fmt, args);
10599  va_end(args);
10600  rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
10601 }
10602 
10603 static void
10604 ripper_warn0(struct parser_params *parser, const char *fmt)
10605 {
10606  rb_funcall(parser->value, rb_intern("warn"), 1, STR_NEW2(fmt));
10607 }
10608 
10609 static void
10610 ripper_warnI(struct parser_params *parser, const char *fmt, int a)
10611 {
10612  rb_funcall(parser->value, rb_intern("warn"), 2,
10613  STR_NEW2(fmt), INT2NUM(a));
10614 }
10615 
10616 #if 0
10617 static void
10618 ripper_warnS(struct parser_params *parser, const char *fmt, const char *str)
10619 {
10620  rb_funcall(parser->value, rb_intern("warn"), 2,
10621  STR_NEW2(fmt), STR_NEW2(str));
10622 }
10623 #endif
10624 
10625 static void
10626 ripper_warning0(struct parser_params *parser, const char *fmt)
10627 {
10628  rb_funcall(parser->value, rb_intern("warning"), 1, STR_NEW2(fmt));
10629 }
10630 
10631 static void
10632 ripper_warningS(struct parser_params *parser, const char *fmt, const char *str)
10633 {
10634  rb_funcall(parser->value, rb_intern("warning"), 2,
10635  STR_NEW2(fmt), STR_NEW2(str));
10636 }
10637 
10638 static VALUE
10639 ripper_lex_get_generic(struct parser_params *parser, VALUE src)
10640 {
10641  return rb_funcall(src, ripper_id_gets, 0);
10642 }
10643 
10644 static VALUE
10645 ripper_s_allocate(VALUE klass)
10646 {
10647  struct parser_params *p;
10648  VALUE self;
10649 
10650  p = ALLOC_N(struct parser_params, 1);
10651  MEMZERO(p, struct parser_params, 1);
10652  self = TypedData_Wrap_Struct(klass, &parser_data_type, p);
10653  p->value = self;
10654  return self;
10655 }
10656 
10657 #define ripper_initialized_p(r) ((r)->parser_lex_input != 0)
10658 
10659 /*
10660  * call-seq:
10661  * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
10662  *
10663  * Create a new Ripper object.
10664  * _src_ must be a String, an IO, or an Object which has #gets method.
10665  *
10666  * This method does not starts parsing.
10667  * See also Ripper#parse and Ripper.parse.
10668  */
10669 static VALUE
10670 ripper_initialize(int argc, VALUE *argv, VALUE self)
10671 {
10672  struct parser_params *parser;
10673  VALUE src, fname, lineno;
10674 
10675  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10676  rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
10677  if (rb_obj_respond_to(src, ripper_id_gets, 0)) {
10678  parser->parser_lex_gets = ripper_lex_get_generic;
10679  }
10680  else {
10681  StringValue(src);
10682  parser->parser_lex_gets = lex_get_str;
10683  }
10684  parser->parser_lex_input = src;
10685  parser->eofp = Qfalse;
10686  if (NIL_P(fname)) {
10687  fname = STR_NEW2("(ripper)");
10688  }
10689  else {
10690  StringValue(fname);
10691  }
10692  parser_initialize(parser);
10693 
10694  parser->parser_ruby_sourcefile_string = fname;
10695  parser->parser_ruby_sourcefile = RSTRING_PTR(fname);
10696  parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
10697 
10698  return Qnil;
10699 }
10700 
10701 struct ripper_args {
10702  struct parser_params *parser;
10703  int argc;
10704  VALUE *argv;
10705 };
10706 
10707 static VALUE
10708 ripper_parse0(VALUE parser_v)
10709 {
10710  struct parser_params *parser;
10711 
10712  TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
10713  parser_prepare(parser);
10714  ripper_yyparse((void*)parser);
10715  return parser->result;
10716 }
10717 
10718 static VALUE
10719 ripper_ensure(VALUE parser_v)
10720 {
10721  struct parser_params *parser;
10722 
10723  TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
10724  parser->parsing_thread = Qnil;
10725  return Qnil;
10726 }
10727 
10728 /*
10729  * call-seq:
10730  * ripper#parse
10731  *
10732  * Start parsing and returns the value of the root action.
10733  */
10734 static VALUE
10735 ripper_parse(VALUE self)
10736 {
10737  struct parser_params *parser;
10738 
10739  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10740  if (!ripper_initialized_p(parser)) {
10741  rb_raise(rb_eArgError, "method called for uninitialized object");
10742  }
10743  if (!NIL_P(parser->parsing_thread)) {
10744  if (parser->parsing_thread == rb_thread_current())
10745  rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
10746  else
10747  rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
10748  }
10749  parser->parsing_thread = rb_thread_current();
10750  rb_ensure(ripper_parse0, self, ripper_ensure, self);
10751 
10752  return parser->result;
10753 }
10754 
10755 /*
10756  * call-seq:
10757  * ripper#column -> Integer
10758  *
10759  * Return column number of current parsing line.
10760  * This number starts from 0.
10761  */
10762 static VALUE
10763 ripper_column(VALUE self)
10764 {
10765  struct parser_params *parser;
10766  long col;
10767 
10768  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10769  if (!ripper_initialized_p(parser)) {
10770  rb_raise(rb_eArgError, "method called for uninitialized object");
10771  }
10772  if (NIL_P(parser->parsing_thread)) return Qnil;
10773  col = parser->tokp - parser->parser_lex_pbeg;
10774  return LONG2NUM(col);
10775 }
10776 
10777 /*
10778  * call-seq:
10779  * ripper#filename -> String
10780  *
10781  * Return current parsing filename.
10782  */
10783 static VALUE
10784 ripper_filename(VALUE self)
10785 {
10786  struct parser_params *parser;
10787 
10788  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10789  if (!ripper_initialized_p(parser)) {
10790  rb_raise(rb_eArgError, "method called for uninitialized object");
10791  }
10792  return parser->parser_ruby_sourcefile_string;
10793 }
10794 
10795 /*
10796  * call-seq:
10797  * ripper#lineno -> Integer
10798  *
10799  * Return line number of current parsing line.
10800  * This number starts from 1.
10801  */
10802 static VALUE
10803 ripper_lineno(VALUE self)
10804 {
10805  struct parser_params *parser;
10806 
10807  TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10808  if (!ripper_initialized_p(parser)) {
10809  rb_raise(rb_eArgError, "method called for uninitialized object");
10810  }
10811  if (NIL_P(parser->parsing_thread)) return Qnil;
10812  return INT2NUM(parser->parser_ruby_sourceline);
10813 }
10814 
10815 #ifdef RIPPER_DEBUG
10816 /* :nodoc: */
10817 static VALUE
10818 ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
10819 {
10820  StringValue(msg);
10821  if (obj == Qundef) {
10822  rb_raise(rb_eArgError, "%s", RSTRING_PTR(msg));
10823  }
10824  return Qnil;
10825 }
10826 
10827 /* :nodoc: */
10828 static VALUE
10829 ripper_value(VALUE self, VALUE obj)
10830 {
10831  return ULONG2NUM(obj);
10832 }
10833 #endif
10834 
10835 
10836 void
10837 InitVM_ripper(void)
10838 {
10839  parser_data_type.parent = RTYPEDDATA_TYPE(rb_parser_new());
10840 }
10841 
10842 void
10843 Init_ripper(void)
10844 {
10845  VALUE Ripper;
10846 
10847  InitVM(ripper);
10848  Ripper = rb_define_class("Ripper", rb_cObject);
10849  rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
10850  rb_define_alloc_func(Ripper, ripper_s_allocate);
10851  rb_define_method(Ripper, "initialize", ripper_initialize, -1);
10852  rb_define_method(Ripper, "parse", ripper_parse, 0);
10853  rb_define_method(Ripper, "column", ripper_column, 0);
10854  rb_define_method(Ripper, "filename", ripper_filename, 0);
10855  rb_define_method(Ripper, "lineno", ripper_lineno, 0);
10856  rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
10857  rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
10858  rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
10859  rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
10860 #ifdef RIPPER_DEBUG
10861  rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
10862  rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
10863  rb_define_method(rb_mKernel, "validate_object", ripper_validate_object, 1);
10864 #endif
10865 
10866  ripper_id_gets = rb_intern("gets");
10867  ripper_init_eventids1(Ripper);
10868  ripper_init_eventids2(Ripper);
10869  /* ensure existing in symbol table */
10870  (void)rb_intern("||");
10871  (void)rb_intern("&&");
10872 
10873 # if 0
10874  /* Hack to let RDoc document SCRIPT_LINES__ */
10875 
10876  /*
10877  * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
10878  * after the assignment will be added as an Array of lines with the file
10879  * name as the key.
10880  */
10881  rb_define_global_const("SCRIPT_LINES__", Qnil);
10882 #endif
10883 
10884 }
10885 #endif /* RIPPER */
10886