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