The Ruby Cross Reference

Implementation: mri jruby rubinius
Version: 1.8.7-p374 1.9.1-p431 1.9.2-p381 1.9.3-p484 2.0.0-p353 2.1.0-p0 HEAD
001 /**********************************************************************
002 
003   parse.y -
004 
005   $Author$
006   created at: Fri May 28 18:02:42 JST 1993
007 
008   Copyright (C) 1993-2007 Yukihiro Matsumoto
009 
010 **********************************************************************/
011 
012 %{
013 
014 #ifndef PARSER_DEBUG
015 #define PARSER_DEBUG 0
016 #endif
017 #define YYDEBUG 1
018 #define YYERROR_VERBOSE 1
019 #define YYSTACK_USE_ALLOCA 0
020 
021 #include "ruby/ruby.h"
022 #include "ruby/st.h"
023 #include "ruby/encoding.h"
024 #include "internal.h"
025 #include "node.h"
026 #include "parse.h"
027 #include "id.h"
028 #include "regenc.h"
029 #include <stdio.h>
030 #include <errno.h>
031 #include <ctype.h>
032 #include "probes.h"
033 
034 #define YYMALLOC(size)          rb_parser_malloc(parser, (size))
035 #define YYREALLOC(ptr, size)    rb_parser_realloc(parser, (ptr), (size))
036 #define YYCALLOC(nelem, size)   rb_parser_calloc(parser, (nelem), (size))
037 #define YYFREE(ptr)             rb_parser_free(parser, (ptr))
038 #define malloc  YYMALLOC
039 #define realloc YYREALLOC
040 #define calloc  YYCALLOC
041 #define free    YYFREE
042 
043 #ifndef RIPPER
044 static ID register_symid(ID, const char *, long, rb_encoding *);
045 static ID register_symid_str(ID, VALUE);
046 #define REGISTER_SYMID(id, name) register_symid((id), (name), strlen(name), enc)
047 #include "id.c"
048 #endif
049 
050 #define is_notop_id(id) ((id)>tLAST_OP_ID)
051 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
052 #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
053 #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
054 #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
055 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
056 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
057 #define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
058 #define id_type(id) (is_notop_id(id) ? (int)((id)&ID_SCOPE_MASK) : -1)
059 
060 #define is_asgn_or_id(id) ((is_notop_id(id)) && \
061         (((id)&ID_SCOPE_MASK) == ID_GLOBAL || \
062          ((id)&ID_SCOPE_MASK) == ID_INSTANCE || \
063          ((id)&ID_SCOPE_MASK) == ID_CLASS))
064 
065 enum lex_state_bits {
066     EXPR_BEG_bit,               /* ignore newline, +/- is a sign. */
067     EXPR_END_bit,               /* newline significant, +/- is an operator. */
068     EXPR_ENDARG_bit,            /* ditto, and unbound braces. */
069     EXPR_ENDFN_bit,             /* ditto, and unbound braces. */
070     EXPR_ARG_bit,               /* newline significant, +/- is an operator. */
071     EXPR_CMDARG_bit,            /* newline significant, +/- is an operator. */
072     EXPR_MID_bit,               /* newline significant, +/- is an operator. */
073     EXPR_FNAME_bit,             /* ignore newline, no reserved words. */
074     EXPR_DOT_bit,               /* right after `.' or `::', no reserved words. */
075     EXPR_CLASS_bit,             /* immediate after `class', no here document. */
076     EXPR_VALUE_bit,             /* alike EXPR_BEG but label is disallowed. */
077     EXPR_MAX_STATE
078 };
079 /* examine combinations */
080 enum lex_state_e {
081 #define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
082     DEF_EXPR(BEG),
083     DEF_EXPR(END),
084     DEF_EXPR(ENDARG),
085     DEF_EXPR(ENDFN),
086     DEF_EXPR(ARG),
087     DEF_EXPR(CMDARG),
088     DEF_EXPR(MID),
089     DEF_EXPR(FNAME),
090     DEF_EXPR(DOT),
091     DEF_EXPR(CLASS),
092     DEF_EXPR(VALUE),
093     EXPR_BEG_ANY  =  (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS),
094     EXPR_ARG_ANY  =  (EXPR_ARG | EXPR_CMDARG),
095     EXPR_END_ANY  =  (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
096 };
097 #define IS_lex_state_for(x, ls) ((x) & (ls))
098 #define IS_lex_state(ls)        IS_lex_state_for(lex_state, (ls))
099 
100 #if PARSER_DEBUG
101 static const char *lex_state_name(enum lex_state_e state);
102 #endif
103 
104 typedef VALUE stack_type;
105 
106 # define BITSTACK_PUSH(stack, n)        ((stack) = ((stack)<<1)|((n)&1))
107 # define BITSTACK_POP(stack)    ((stack) = (stack) >> 1)
108 # define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
109 # define BITSTACK_SET_P(stack)  ((stack)&1)
110 
111 #define COND_PUSH(n)    BITSTACK_PUSH(cond_stack, (n))
112 #define COND_POP()      BITSTACK_POP(cond_stack)
113 #define COND_LEXPOP()   BITSTACK_LEXPOP(cond_stack)
114 #define COND_P()        BITSTACK_SET_P(cond_stack)
115 
116 #define CMDARG_PUSH(n)  BITSTACK_PUSH(cmdarg_stack, (n))
117 #define CMDARG_POP()    BITSTACK_POP(cmdarg_stack)
118 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
119 #define CMDARG_P()      BITSTACK_SET_P(cmdarg_stack)
120 
121 struct vtable {
122     ID *tbl;
123     int pos;
124     int capa;
125     struct vtable *prev;
126 };
127 
128 struct local_vars {
129     struct vtable *args;
130     struct vtable *vars;
131     struct vtable *used;
132     struct local_vars *prev;
133 };
134 
135 #define DVARS_INHERIT ((void*)1)
136 #define DVARS_TOPSCOPE NULL
137 #define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
138 #define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
139 
140 static int
141 vtable_size(const struct vtable *tbl)
142 {
143     if (POINTER_P(tbl)) {
144         return tbl->pos;
145     }
146     else {
147         return 0;
148     }
149 }
150 
151 #define VTBL_DEBUG 0
152 
153 static struct vtable *
154 vtable_alloc(struct vtable *prev)
155 {
156     struct vtable *tbl = ALLOC(struct vtable);
157     tbl->pos = 0;
158     tbl->capa = 8;
159     tbl->tbl = ALLOC_N(ID, tbl->capa);
160     tbl->prev = prev;
161     if (VTBL_DEBUG) printf("vtable_alloc: %p\n", (void *)tbl);
162     return tbl;
163 }
164 
165 static void
166 vtable_free(struct vtable *tbl)
167 {
168     if (VTBL_DEBUG)printf("vtable_free: %p\n", (void *)tbl);
169     if (POINTER_P(tbl)) {
170         if (tbl->tbl) {
171             xfree(tbl->tbl);
172         }
173         xfree(tbl);
174     }
175 }
176 
177 static void
178 vtable_add(struct vtable *tbl, ID id)
179 {
180     if (!POINTER_P(tbl)) {
181         rb_bug("vtable_add: vtable is not allocated (%p)", (void *)tbl);
182     }
183     if (VTBL_DEBUG) printf("vtable_add: %p, %s\n", (void *)tbl, rb_id2name(id));
184 
185     if (tbl->pos == tbl->capa) {
186         tbl->capa = tbl->capa * 2;
187         REALLOC_N(tbl->tbl, ID, tbl->capa);
188     }
189     tbl->tbl[tbl->pos++] = id;
190 }
191 
192 static int
193 vtable_included(const struct vtable * tbl, ID id)
194 {
195     int i;
196 
197     if (POINTER_P(tbl)) {
198         for (i = 0; i < tbl->pos; i++) {
199             if (tbl->tbl[i] == id) {
200                 return i+1;
201             }
202         }
203     }
204     return 0;
205 }
206 
207 
208 #ifndef RIPPER
209 typedef struct token_info {
210     const char *token;
211     int linenum;
212     int column;
213     int nonspc;
214     struct token_info *next;
215 } token_info;
216 #endif
217 
218 /*
219     Structure of Lexer Buffer:
220 
221  lex_pbeg      tokp         lex_p        lex_pend
222     |           |              |            |
223     |-----------+--------------+------------|
224                 |<------------>|
225                      token
226 */
227 struct parser_params {
228     int is_ripper;
229     NODE *heap;
230 
231     YYSTYPE *parser_yylval;
232     VALUE eofp;
233 
234     NODE *parser_lex_strterm;
235     enum lex_state_e parser_lex_state;
236     stack_type parser_cond_stack;
237     stack_type parser_cmdarg_stack;
238     int parser_class_nest;
239     int parser_paren_nest;
240     int parser_lpar_beg;
241     int parser_in_single;
242     int parser_in_def;
243     int parser_brace_nest;
244     int parser_compile_for_eval;
245     VALUE parser_cur_mid;
246     int parser_in_defined;
247     char *parser_tokenbuf;
248     int parser_tokidx;
249     int parser_toksiz;
250     int parser_tokline;
251     VALUE parser_lex_input;
252     VALUE parser_lex_lastline;
253     VALUE parser_lex_nextline;
254     const char *parser_lex_pbeg;
255     const char *parser_lex_p;
256     const char *parser_lex_pend;
257     int parser_heredoc_end;
258     int parser_command_start;
259     NODE *parser_deferred_nodes;
260     long parser_lex_gets_ptr;
261     VALUE (*parser_lex_gets)(struct parser_params*,VALUE);
262     struct local_vars *parser_lvtbl;
263     int parser_ruby__end__seen;
264     int line_count;
265     int has_shebang;
266     char *parser_ruby_sourcefile; /* current source file */
267     int parser_ruby_sourceline; /* current line no. */
268     rb_encoding *enc;
269 
270     int parser_yydebug;
271 
272 #ifndef RIPPER
273     /* Ruby core only */
274     NODE *parser_eval_tree_begin;
275     NODE *parser_eval_tree;
276     VALUE debug_lines;
277     VALUE coverage;
278     int nerr;
279 
280     int parser_token_info_enabled;
281     token_info *parser_token_info;
282 #else
283     /* Ripper only */
284     VALUE parser_ruby_sourcefile_string;
285     const char *tokp;
286     VALUE delayed;
287     int delayed_line;
288     int delayed_col;
289 
290     VALUE value;
291     VALUE result;
292     VALUE parsing_thread;
293     int toplevel_p;
294 #endif
295 };
296 
297 #define STR_NEW(p,n) rb_enc_str_new((p),(n),current_enc)
298 #define STR_NEW0() rb_enc_str_new(0,0,current_enc)
299 #define STR_NEW2(p) rb_enc_str_new((p),strlen(p),current_enc)
300 #define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),current_enc)
301 #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT)
302 #define TOK_INTERN(mb) rb_intern3(tok(), toklen(), current_enc)
303 
304 static int parser_yyerror(struct parser_params*, const char*);
305 #define yyerror(msg) parser_yyerror(parser, (msg))
306 
307 #define YYLEX_PARAM parser
308 
309 #define lex_strterm             (parser->parser_lex_strterm)
310 #define lex_state               (parser->parser_lex_state)
311 #define cond_stack              (parser->parser_cond_stack)
312 #define cmdarg_stack            (parser->parser_cmdarg_stack)
313 #define class_nest              (parser->parser_class_nest)
314 #define paren_nest              (parser->parser_paren_nest)
315 #define lpar_beg                (parser->parser_lpar_beg)
316 #define brace_nest              (parser->parser_brace_nest)
317 #define in_single               (parser->parser_in_single)
318 #define in_def                  (parser->parser_in_def)
319 #define compile_for_eval        (parser->parser_compile_for_eval)
320 #define cur_mid                 (parser->parser_cur_mid)
321 #define in_defined              (parser->parser_in_defined)
322 #define tokenbuf                (parser->parser_tokenbuf)
323 #define tokidx                  (parser->parser_tokidx)
324 #define toksiz                  (parser->parser_toksiz)
325 #define tokline                 (parser->parser_tokline)
326 #define lex_input               (parser->parser_lex_input)
327 #define lex_lastline            (parser->parser_lex_lastline)
328 #define lex_nextline            (parser->parser_lex_nextline)
329 #define lex_pbeg                (parser->parser_lex_pbeg)
330 #define lex_p                   (parser->parser_lex_p)
331 #define lex_pend                (parser->parser_lex_pend)
332 #define heredoc_end             (parser->parser_heredoc_end)
333 #define command_start           (parser->parser_command_start)
334 #define deferred_nodes          (parser->parser_deferred_nodes)
335 #define lex_gets_ptr            (parser->parser_lex_gets_ptr)
336 #define lex_gets                (parser->parser_lex_gets)
337 #define lvtbl                   (parser->parser_lvtbl)
338 #define ruby__end__seen         (parser->parser_ruby__end__seen)
339 #define ruby_sourceline         (parser->parser_ruby_sourceline)
340 #define ruby_sourcefile         (parser->parser_ruby_sourcefile)
341 #define current_enc             (parser->enc)
342 #define yydebug                 (parser->parser_yydebug)
343 #ifdef RIPPER
344 #else
345 #define ruby_eval_tree          (parser->parser_eval_tree)
346 #define ruby_eval_tree_begin    (parser->parser_eval_tree_begin)
347 #define ruby_debug_lines        (parser->debug_lines)
348 #define ruby_coverage           (parser->coverage)
349 #endif
350 
351 static int yylex(void*, void*);
352 
353 #ifndef RIPPER
354 #define yyparse ruby_yyparse
355 
356 static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE);
357 #define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, (type), (a1), (a2), (a3))
358 
359 static NODE *cond_gen(struct parser_params*,NODE*);
360 #define cond(node) cond_gen(parser, (node))
361 static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
362 #define logop(type,node1,node2) logop_gen(parser, (type), (node1), (node2))
363 
364 static NODE *newline_node(NODE*);
365 static void fixpos(NODE*,NODE*);
366 
367 static int value_expr_gen(struct parser_params*,NODE*);
368 static void void_expr_gen(struct parser_params*,NODE*);
369 static NODE *remove_begin(NODE*);
370 static NODE *remove_begin_all(NODE*);
371 #define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
372 #define void_expr0(node) void_expr_gen(parser, (node))
373 #define void_expr(node) void_expr0((node) = remove_begin(node))
374 static void void_stmts_gen(struct parser_params*,NODE*);
375 #define void_stmts(node) void_stmts_gen(parser, (node))
376 static void reduce_nodes_gen(struct parser_params*,NODE**);
377 #define reduce_nodes(n) reduce_nodes_gen(parser,(n))
378 static void block_dup_check_gen(struct parser_params*,NODE*,NODE*);
379 #define block_dup_check(n1,n2) block_dup_check_gen(parser,(n1),(n2))
380 
381 static NODE *block_append_gen(struct parser_params*,NODE*,NODE*);
382 #define block_append(h,t) block_append_gen(parser,(h),(t))
383 static NODE *list_append_gen(struct parser_params*,NODE*,NODE*);
384 #define list_append(l,i) list_append_gen(parser,(l),(i))
385 static NODE *list_concat_gen(struct parser_params*,NODE*,NODE*);
386 #define list_concat(h,t) list_concat_gen(parser,(h),(t))
387 static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*);
388 #define arg_append(h,t) arg_append_gen(parser,(h),(t))
389 static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
390 #define arg_concat(h,t) arg_concat_gen(parser,(h),(t))
391 static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
392 #define literal_concat(h,t) literal_concat_gen(parser,(h),(t))
393 static int literal_concat0(struct parser_params *, VALUE, VALUE);
394 static NODE *new_evstr_gen(struct parser_params*,NODE*);
395 #define new_evstr(n) new_evstr_gen(parser,(n))
396 static NODE *evstr2dstr_gen(struct parser_params*,NODE*);
397 #define evstr2dstr(n) evstr2dstr_gen(parser,(n))
398 static NODE *splat_array(NODE*);
399 
400 static NODE *call_bin_op_gen(struct parser_params*,NODE*,ID,NODE*);
401 #define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, (recv),(id),(arg1))
402 static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID);
403 #define call_uni_op(recv,id) call_uni_op_gen(parser, (recv),(id))
404 
405 static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*);
406 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
407 static NODE *new_args_tail_gen(struct parser_params*,NODE*,ID,ID);
408 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
409 
410 static NODE *negate_lit(NODE*);
411 static NODE *ret_args_gen(struct parser_params*,NODE*);
412 #define ret_args(node) ret_args_gen(parser, (node))
413 static NODE *arg_blk_pass(NODE*,NODE*);
414 static NODE *new_yield_gen(struct parser_params*,NODE*);
415 #define new_yield(node) new_yield_gen(parser, (node))
416 static NODE *dsym_node_gen(struct parser_params*,NODE*);
417 #define dsym_node(node) dsym_node_gen(parser, (node))
418 
419 static NODE *gettable_gen(struct parser_params*,ID);
420 #define gettable(id) gettable_gen(parser,(id))
421 static NODE *assignable_gen(struct parser_params*,ID,NODE*);
422 #define assignable(id,node) assignable_gen(parser, (id), (node))
423 
424 static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
425 #define aryset(node1,node2) aryset_gen(parser, (node1), (node2))
426 static NODE *attrset_gen(struct parser_params*,NODE*,ID);
427 #define attrset(node,id) attrset_gen(parser, (node), (id))
428 
429 static void rb_backref_error_gen(struct parser_params*,NODE*);
430 #define rb_backref_error(n) rb_backref_error_gen(parser,(n))
431 static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
432 #define node_assign(node1, node2) node_assign_gen(parser, (node1), (node2))
433 
434 static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
435 static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs);
436 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (attr), (op), (rhs))
437 static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
438 #define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs))
439 
440 #define new_defined(expr) NEW_DEFINED(remove_begin_all(expr))
441 
442 static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
443 #define match_op(node1,node2) match_op_gen(parser, (node1), (node2))
444 
445 static ID  *local_tbl_gen(struct parser_params*);
446 #define local_tbl() local_tbl_gen(parser)
447 
448 static void fixup_nodes(NODE **);
449 
450 static VALUE reg_compile_gen(struct parser_params*, VALUE, int);
451 #define reg_compile(str,options) reg_compile_gen(parser, (str), (options))
452 static void reg_fragment_setenc_gen(struct parser_params*, VALUE, int);
453 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, (str), (options))
454 static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
455 #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, (str), (options))
456 static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match);
457 #define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
458 
459 #define get_id(id) (id)
460 #define get_value(val) (val)
461 #else
462 #define value_expr(node) ((void)(node))
463 #define remove_begin(node) (node)
464 #define rb_dvar_defined(id) 0
465 #define rb_local_defined(id) 0
466 static ID ripper_get_id(VALUE);
467 #define get_id(id) ripper_get_id(id)
468 static VALUE ripper_get_value(VALUE);
469 #define get_value(val) ripper_get_value(val)
470 static VALUE assignable_gen(struct parser_params*,VALUE);
471 #define assignable(lhs,node) assignable_gen(parser, (lhs))
472 static int id_is_var_gen(struct parser_params *parser, ID id);
473 #define id_is_var(id) id_is_var_gen(parser, (id))
474 
475 #define node_assign(node1, node2) dispatch2(assign, (node1), (node2))
476 
477 static VALUE new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs);
478 static VALUE new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs);
479 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs))
480 
481 #endif /* !RIPPER */
482 
483 #define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs))
484 
485 static ID formal_argument_gen(struct parser_params*, ID);
486 #define formal_argument(id) formal_argument_gen(parser, (id))
487 static ID shadowing_lvar_gen(struct parser_params*,ID);
488 #define shadowing_lvar(name) shadowing_lvar_gen(parser, (name))
489 static void new_bv_gen(struct parser_params*,ID);
490 #define new_bv(id) new_bv_gen(parser, (id))
491 
492 static void local_push_gen(struct parser_params*,int);
493 #define local_push(top) local_push_gen(parser,(top))
494 static void local_pop_gen(struct parser_params*);
495 #define local_pop() local_pop_gen(parser)
496 static int local_var_gen(struct parser_params*, ID);
497 #define local_var(id) local_var_gen(parser, (id))
498 static int arg_var_gen(struct parser_params*, ID);
499 #define arg_var(id) arg_var_gen(parser, (id))
500 static int  local_id_gen(struct parser_params*, ID);
501 #define local_id(id) local_id_gen(parser, (id))
502 static ID   internal_id_gen(struct parser_params*);
503 #define internal_id() internal_id_gen(parser)
504 
505 static const struct vtable *dyna_push_gen(struct parser_params *);
506 #define dyna_push() dyna_push_gen(parser)
507 static void dyna_pop_gen(struct parser_params*, const struct vtable *);
508 #define dyna_pop(node) dyna_pop_gen(parser, (node))
509 static int dyna_in_block_gen(struct parser_params*);
510 #define dyna_in_block() dyna_in_block_gen(parser)
511 #define dyna_var(id) local_var(id)
512 static int dvar_defined_gen(struct parser_params*,ID,int);
513 #define dvar_defined(id) dvar_defined_gen(parser, (id), 0)
514 #define dvar_defined_get(id) dvar_defined_gen(parser, (id), 1)
515 static int dvar_curr_gen(struct parser_params*,ID);
516 #define dvar_curr(id) dvar_curr_gen(parser, (id))
517 
518 static int lvar_defined_gen(struct parser_params*, ID);
519 #define lvar_defined(id) lvar_defined_gen(parser, (id))
520 
521 #define RE_OPTION_ONCE (1<<16)
522 #define RE_OPTION_ENCODING_SHIFT 8
523 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
524 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
525 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
526 #define RE_OPTION_MASK  0xff
527 #define RE_OPTION_ARG_ENCODING_NONE 32
528 
529 #define NODE_STRTERM NODE_ZARRAY        /* nothing to gc */
530 #define NODE_HEREDOC NODE_ARRAY         /* 1, 3 to gc */
531 #define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
532 #define nd_func u1.id
533 #if SIZEOF_SHORT == 2
534 #define nd_term(node) ((signed short)(node)->u2.id)
535 #else
536 #define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
537 #endif
538 #define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
539 #define nd_nest u3.cnt
540 
541 /****** Ripper *******/
542 
543 #ifdef RIPPER
544 #define RIPPER_VERSION "0.1.0"
545 
546 #include "eventids1.c"
547 #include "eventids2.c"
548 
549 static VALUE ripper_dispatch0(struct parser_params*,ID);
550 static VALUE ripper_dispatch1(struct parser_params*,ID,VALUE);
551 static VALUE ripper_dispatch2(struct parser_params*,ID,VALUE,VALUE);
552 static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
553 static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
554 static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
555 static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
556 
557 #define dispatch0(n)            ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
558 #define dispatch1(n,a)          ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
559 #define dispatch2(n,a,b)        ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), (a), (b))
560 #define dispatch3(n,a,b,c)      ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
561 #define dispatch4(n,a,b,c,d)    ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
562 #define dispatch5(n,a,b,c,d,e)  ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
563 #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))
564 
565 #define yyparse ripper_yyparse
566 
567 #define ripper_intern(s) ID2SYM(rb_intern(s))
568 static VALUE ripper_id2sym(ID);
569 #ifdef __GNUC__
570 #define ripper_id2sym(id) ((id) < 256 && rb_ispunct(id) ? \
571                            ID2SYM(id) : ripper_id2sym(id))
572 #endif
573 
574 #define arg_new() dispatch0(args_new)
575 #define arg_add(l,a) dispatch2(args_add, (l), (a))
576 #define arg_add_star(l,a) dispatch2(args_add_star, (l), (a))
577 #define arg_add_block(l,b) dispatch2(args_add_block, (l), (b))
578 #define arg_add_optblock(l,b) ((b)==Qundef? (l) : dispatch2(args_add_block, (l), (b)))
579 #define bare_assoc(v) dispatch1(bare_assoc_hash, (v))
580 #define arg_add_assocs(l,b) arg_add((l), bare_assoc(b))
581 
582 #define args2mrhs(a) dispatch1(mrhs_new_from_args, (a))
583 #define mrhs_new() dispatch0(mrhs_new)
584 #define mrhs_add(l,a) dispatch2(mrhs_add, (l), (a))
585 #define mrhs_add_star(l,a) dispatch2(mrhs_add_star, (l), (a))
586 
587 #define mlhs_new() dispatch0(mlhs_new)
588 #define mlhs_add(l,a) dispatch2(mlhs_add, (l), (a))
589 #define mlhs_add_star(l,a) dispatch2(mlhs_add_star, (l), (a))
590 
591 #define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
592         dispatch7(params, (pars), (opts), (rest), (pars2), (kws), (kwrest), (blk))
593 
594 #define blockvar_new(p,v) dispatch2(block_var, (p), (v))
595 #define blockvar_add_star(l,a) dispatch2(block_var_add_star, (l), (a))
596 #define blockvar_add_block(l,a) dispatch2(block_var_add_block, (l), (a))
597 
598 #define method_optarg(m,a) ((a)==Qundef ? (m) : dispatch2(method_add_arg,(m),(a)))
599 #define method_arg(m,a) dispatch2(method_add_arg,(m),(a))
600 #define method_add_block(m,b) dispatch2(method_add_block, (m), (b))
601 
602 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
603 
604 static inline VALUE
605 new_args_gen(struct parser_params *parser, VALUE f, VALUE o, VALUE r, VALUE p, VALUE tail)
606 {
607     NODE *t = (NODE *)tail;
608     VALUE k = t->u1.value, kr = t->u2.value, b = t->u3.value;
609     return params_new(f, o, r, p, k, kr, escape_Qundef(b));
610 }
611 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
612 
613 static inline VALUE
614 new_args_tail_gen(struct parser_params *parser, VALUE k, VALUE kr, VALUE b)
615 {
616     return (VALUE)rb_node_newnode(NODE_MEMO, k, kr, b);
617 }
618 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
619 
620 #define new_defined(expr) dispatch1(defined, (expr))
621 
622 #define FIXME 0
623 
624 #endif /* RIPPER */
625 
626 #ifndef RIPPER
627 # define Qnone 0
628 # define ifndef_ripper(x) (x)
629 #else
630 # define Qnone Qnil
631 # define ifndef_ripper(x)
632 #endif
633 
634 #ifndef RIPPER
635 # define rb_warn0(fmt)    rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt))
636 # define rb_warnI(fmt,a)  rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
637 # define rb_warnS(fmt,a)  rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
638 # define rb_warn4S(file,line,fmt,a)  rb_compile_warn((file), (line), (fmt), (a))
639 # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt))
640 # define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt), (a))
641 #else
642 # define rb_warn0(fmt)    ripper_warn0(parser, (fmt))
643 # define rb_warnI(fmt,a)  ripper_warnI(parser, (fmt), (a))
644 # define rb_warnS(fmt,a)  ripper_warnS(parser, (fmt), (a))
645 # define rb_warn4S(file,line,fmt,a)  ripper_warnS(parser, (fmt), (a))
646 # define rb_warning0(fmt) ripper_warning0(parser, (fmt))
647 # define rb_warningS(fmt,a) ripper_warningS(parser, (fmt), (a))
648 static void ripper_warn0(struct parser_params*, const char*);
649 static void ripper_warnI(struct parser_params*, const char*, int);
650 static void ripper_warnS(struct parser_params*, const char*, const char*);
651 static void ripper_warning0(struct parser_params*, const char*);
652 static void ripper_warningS(struct parser_params*, const char*, const char*);
653 #endif
654 
655 #ifdef RIPPER
656 static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
657 # define rb_compile_error ripper_compile_error
658 # define compile_error ripper_compile_error
659 # define PARSER_ARG parser,
660 #else
661 # define rb_compile_error rb_compile_error_with_enc
662 # define compile_error parser->nerr++,rb_compile_error_with_enc
663 # define PARSER_ARG ruby_sourcefile, ruby_sourceline, current_enc,
664 #endif
665 
666 /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
667    for instance).  This is too low for Ruby to parse some files, such as
668    date/format.rb, therefore bump the value up to at least Bison's default. */
669 #ifdef OLD_YACC
670 #ifndef YYMAXDEPTH
671 #define YYMAXDEPTH 10000
672 #endif
673 #endif
674 
675 #ifndef RIPPER
676 static void token_info_push(struct parser_params*, const char *token);
677 static void token_info_pop(struct parser_params*, const char *token);
678 #define token_info_push(token) (RTEST(ruby_verbose) ? token_info_push(parser, (token)) : (void)0)
679 #define token_info_pop(token) (RTEST(ruby_verbose) ? token_info_pop(parser, (token)) : (void)0)
680 #else
681 #define token_info_push(token) /* nothing */
682 #define token_info_pop(token) /* nothing */
683 #endif
684 %}
685 
686 %pure_parser
687 %parse-param {struct parser_params *parser}
688 
689 %union {
690     VALUE val;
691     NODE *node;
692     ID id;
693     int num;
694     const struct vtable *vars;
695 }
696 
697 /*%%%*/
698 %token
699 /*%
700 %token <val>
701 %*/
702         keyword_class
703         keyword_module
704         keyword_def
705         keyword_undef
706         keyword_begin
707         keyword_rescue
708         keyword_ensure
709         keyword_end
710         keyword_if
711         keyword_unless
712         keyword_then
713         keyword_elsif
714         keyword_else
715         keyword_case
716         keyword_when
717         keyword_while
718         keyword_until
719         keyword_for
720         keyword_break
721         keyword_next
722         keyword_redo
723         keyword_retry
724         keyword_in
725         keyword_do
726         keyword_do_cond
727         keyword_do_block
728         keyword_do_LAMBDA
729         keyword_return
730         keyword_yield
731         keyword_super
732         keyword_self
733         keyword_nil
734         keyword_true
735         keyword_false
736         keyword_and
737         keyword_or
738         keyword_not
739         modifier_if
740         modifier_unless
741         modifier_while
742         modifier_until
743         modifier_rescue
744         keyword_alias
745         keyword_defined
746         keyword_BEGIN
747         keyword_END
748         keyword__LINE__
749         keyword__FILE__
750         keyword__ENCODING__
751 
752 %token <id>   tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
753 %token <node> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
754 %token <node> tNTH_REF tBACK_REF
755 %token <num>  tREGEXP_END
756 
757 %type <node> singleton strings string string1 xstring regexp
758 %type <node> string_contents xstring_contents regexp_contents string_content
759 %type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
760 %type <node> literal numeric dsym cpath
761 %type <node> top_compstmt top_stmts top_stmt
762 %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
763 %type <node> expr_value arg_value primary_value fcall
764 %type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
765 %type <node> args call_args opt_call_args
766 %type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
767 %type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
768 %type <node> command_asgn mrhs mrhs_arg superclass block_call block_command
769 %type <node> f_block_optarg f_block_opt
770 %type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
771 %type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
772 %type <node> block_param opt_block_param block_param_def f_opt
773 %type <node> f_kwarg f_kw f_block_kwarg f_block_kw
774 %type <node> bv_decls opt_bv_decl bvar
775 %type <node> lambda f_larglist lambda_body
776 %type <node> brace_block cmd_brace_block do_block lhs none fitem
777 %type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
778 %type <id>   fsym keyword_variable user_variable sym symbol operation operation2 operation3
779 %type <id>   cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
780 %type <id>   f_kwrest
781 /*%%%*/
782 /*%
783 %type <val> program reswords then do dot_or_colon
784 %*/
785 %token END_OF_INPUT 0   "end-of-input"
786 %token tUPLUS           RUBY_TOKEN(UPLUS)  "unary+"
787 %token tUMINUS          RUBY_TOKEN(UMINUS) "unary-"
788 %token tPOW             RUBY_TOKEN(POW)    "**"
789 %token tCMP             RUBY_TOKEN(CMP)    "<=>"
790 %token tEQ              RUBY_TOKEN(EQ)     "=="
791 %token tEQQ             RUBY_TOKEN(EQQ)    "==="
792 %token tNEQ             RUBY_TOKEN(NEQ)    "!="
793 %token tGEQ             RUBY_TOKEN(GEQ)    ">="
794 %token tLEQ             RUBY_TOKEN(LEQ)    "<="
795 %token tANDOP           "&&"
796 %token tOROP            "||"
797 %token tMATCH           RUBY_TOKEN(MATCH)  "=~"
798 %token tNMATCH          RUBY_TOKEN(NMATCH) "!~"
799 %token tDOT2            RUBY_TOKEN(DOT2)   ".."
800 %token tDOT3            RUBY_TOKEN(DOT3)   "..."
801 %token tAREF            RUBY_TOKEN(AREF)   "[]"
802 %token tASET            RUBY_TOKEN(ASET)   "[]="
803 %token tLSHFT           RUBY_TOKEN(LSHFT)  "<<"
804 %token tRSHFT           RUBY_TOKEN(RSHFT)  ">>"
805 %token tCOLON2          "::"
806 %token tCOLON3          ":: at EXPR_BEG"
807 %token <id> tOP_ASGN    /* +=, -=  etc. */
808 %token tASSOC           "=>"
809 %token tLPAREN          "("
810 %token tLPAREN_ARG      "( arg"
811 %token tRPAREN          ")"
812 %token tLBRACK          "["
813 %token tLBRACE          "{"
814 %token tLBRACE_ARG      "{ arg"
815 %token tSTAR            "*"
816 %token tDSTAR           "**arg"
817 %token tAMPER           "&"
818 %token tLAMBDA          "->"
819 %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
820 %token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG
821 
822 /*
823  *      precedence table
824  */
825 
826 %nonassoc tLOWEST
827 %nonassoc tLBRACE_ARG
828 
829 %nonassoc  modifier_if modifier_unless modifier_while modifier_until
830 %left  keyword_or keyword_and
831 %right keyword_not
832 %nonassoc keyword_defined
833 %right '=' tOP_ASGN
834 %left modifier_rescue
835 %right '?' ':'
836 %nonassoc tDOT2 tDOT3
837 %left  tOROP
838 %left  tANDOP
839 %nonassoc  tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
840 %left  '>' tGEQ '<' tLEQ
841 %left  '|' '^'
842 %left  '&'
843 %left  tLSHFT tRSHFT
844 %left  '+' '-'
845 %left  '*' '/' '%'
846 %right tUMINUS_NUM tUMINUS
847 %right tPOW
848 %right '!' '~' tUPLUS
849 
850 %token tLAST_TOKEN
851 
852 %%
853 program         :  {
854                         lex_state = EXPR_BEG;
855                     /*%%%*/
856                         local_push(compile_for_eval || rb_parse_in_main());
857                     /*%
858                         local_push(0);
859                     %*/
860                     }
861                   top_compstmt
862                     {
863                     /*%%%*/
864                         if ($2 && !compile_for_eval) {
865                             /* last expression should not be void */
866                             if (nd_type($2) != NODE_BLOCK) void_expr($2);
867                             else {
868                                 NODE *node = $2;
869                                 while (node->nd_next) {
870                                     node = node->nd_next;
871                                 }
872                                 void_expr(node->nd_head);
873                             }
874                         }
875                         ruby_eval_tree = NEW_SCOPE(0, block_append(ruby_eval_tree, $2));
876                     /*%
877                         $$ = $2;
878                         parser->result = dispatch1(program, $$);
879                     %*/
880                         local_pop();
881                     }
882                 ;
883 
884 top_compstmt    : top_stmts opt_terms
885                     {
886                     /*%%%*/
887                         void_stmts($1);
888                         fixup_nodes(&deferred_nodes);
889                     /*%
890                     %*/
891                         $$ = $1;
892                     }
893                 ;
894 
895 top_stmts       : none
896                     {
897                     /*%%%*/
898                         $$ = NEW_BEGIN(0);
899                     /*%
900                         $$ = dispatch2(stmts_add, dispatch0(stmts_new),
901                                                   dispatch0(void_stmt));
902                     %*/
903                     }
904                 | top_stmt
905                     {
906                     /*%%%*/
907                         $$ = newline_node($1);
908                     /*%
909                         $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
910                     %*/
911                     }
912                 | top_stmts terms top_stmt
913                     {
914                     /*%%%*/
915                         $$ = block_append($1, newline_node($3));
916                     /*%
917                         $$ = dispatch2(stmts_add, $1, $3);
918                     %*/
919                     }
920                 | error top_stmt
921                     {
922                         $$ = remove_begin($2);
923                     }
924                 ;
925 
926 top_stmt        : stmt
927                 | keyword_BEGIN
928                     {
929                     /*%%%*/
930                         /* local_push(0); */
931                     /*%
932                     %*/
933                     }
934                   '{' top_compstmt '}'
935                     {
936                     /*%%%*/
937                         ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
938                                                             $4);
939                         /* NEW_PREEXE($4)); */
940                         /* local_pop(); */
941                         $$ = NEW_BEGIN(0);
942                     /*%
943                         $$ = dispatch1(BEGIN, $4);
944                     %*/
945                     }
946                 ;
947 
948 bodystmt        : compstmt
949                   opt_rescue
950                   opt_else
951                   opt_ensure
952                     {
953                     /*%%%*/
954                         $$ = $1;
955                         if ($2) {
956                             $$ = NEW_RESCUE($1, $2, $3);
957                         }
958                         else if ($3) {
959                             rb_warn0("else without rescue is useless");
960                             $$ = block_append($$, $3);
961                         }
962                         if ($4) {
963                             if ($$) {
964                                 $$ = NEW_ENSURE($$, $4);
965                             }
966                             else {
967                                 $$ = block_append($4, NEW_NIL());
968                             }
969                         }
970                         fixpos($$, $1);
971                     /*%
972                         $$ = dispatch4(bodystmt,
973                                        escape_Qundef($1),
974                                        escape_Qundef($2),
975                                        escape_Qundef($3),
976                                        escape_Qundef($4));
977                     %*/
978                     }
979                 ;
980 
981 compstmt        : stmts opt_terms
982                     {
983                     /*%%%*/
984                         void_stmts($1);
985                         fixup_nodes(&deferred_nodes);
986                     /*%
987                     %*/
988                         $$ = $1;
989                     }
990                 ;
991 
992 stmts           : none
993                     {
994                     /*%%%*/
995                         $$ = NEW_BEGIN(0);
996                     /*%
997                         $$ = dispatch2(stmts_add, dispatch0(stmts_new),
998                                                   dispatch0(void_stmt));
999                     %*/
1000                     }
1001                 | stmt_or_begin
1002                     {
1003                     /*%%%*/
1004                         $$ = newline_node($1);
1005                     /*%
1006                         $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
1007                     %*/
1008                     }
1009                 | stmts terms stmt_or_begin
1010                     {
1011                     /*%%%*/
1012                         $$ = block_append($1, newline_node($3));
1013                     /*%
1014                         $$ = dispatch2(stmts_add, $1, $3);
1015                     %*/
1016                     }
1017                 | error stmt
1018                     {
1019                         $$ = remove_begin($2);
1020                     }
1021                 ;
1022 
1023 stmt_or_begin   : stmt
1024                     {
1025                         $$ = $1;
1026                     }
1027                 | keyword_BEGIN
1028                     {
1029                         yyerror("BEGIN is permitted only at toplevel");
1030                     /*%%%*/
1031                         /* local_push(0); */
1032                     /*%
1033                     %*/
1034                     }
1035                   '{' top_compstmt '}'
1036                     {
1037                     /*%%%*/
1038                         ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
1039                                                             $4);
1040                         /* NEW_PREEXE($4)); */
1041                         /* local_pop(); */
1042                         $$ = NEW_BEGIN(0);
1043                     /*%
1044                         $$ = dispatch1(BEGIN, $4);
1045                     %*/
1046                     }
1047 
1048 stmt            : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
1049                     {
1050                     /*%%%*/
1051                         $$ = NEW_ALIAS($2, $4);
1052                     /*%
1053                         $$ = dispatch2(alias, $2, $4);
1054                     %*/
1055                     }
1056                 | keyword_alias tGVAR tGVAR
1057                     {
1058                     /*%%%*/
1059                         $$ = NEW_VALIAS($2, $3);
1060                     /*%
1061                         $$ = dispatch2(var_alias, $2, $3);
1062                     %*/
1063                     }
1064                 | keyword_alias tGVAR tBACK_REF
1065                     {
1066                     /*%%%*/
1067                         char buf[2];
1068                         buf[0] = '$';
1069                         buf[1] = (char)$3->nd_nth;
1070                         $$ = NEW_VALIAS($2, rb_intern2(buf, 2));
1071                     /*%
1072                         $$ = dispatch2(var_alias, $2, $3);
1073                     %*/
1074                     }
1075                 | keyword_alias tGVAR tNTH_REF
1076                     {
1077                     /*%%%*/
1078                         yyerror("can't make alias for the number variables");
1079                         $$ = NEW_BEGIN(0);
1080                     /*%
1081                         $$ = dispatch2(var_alias, $2, $3);
1082                         $$ = dispatch1(alias_error, $$);
1083                     %*/
1084                     }
1085                 | keyword_undef undef_list
1086                     {
1087                     /*%%%*/
1088                         $$ = $2;
1089                     /*%
1090                         $$ = dispatch1(undef, $2);
1091                     %*/
1092                     }
1093                 | stmt modifier_if expr_value
1094                     {
1095                     /*%%%*/
1096                         $$ = NEW_IF(cond($3), remove_begin($1), 0);
1097                         fixpos($$, $3);
1098                     /*%
1099                         $$ = dispatch2(if_mod, $3, $1);
1100                     %*/
1101                     }
1102                 | stmt modifier_unless expr_value
1103                     {
1104                     /*%%%*/
1105                         $$ = NEW_UNLESS(cond($3), remove_begin($1), 0);
1106                         fixpos($$, $3);
1107                     /*%
1108                         $$ = dispatch2(unless_mod, $3, $1);
1109                     %*/
1110                     }
1111                 | stmt modifier_while expr_value
1112                     {
1113                     /*%%%*/
1114                         if ($1 && nd_type($1) == NODE_BEGIN) {
1115                             $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
1116                         }
1117                         else {
1118                             $$ = NEW_WHILE(cond($3), $1, 1);
1119                         }
1120                     /*%
1121                         $$ = dispatch2(while_mod, $3, $1);
1122                     %*/
1123                     }
1124                 | stmt modifier_until expr_value
1125                     {
1126                     /*%%%*/
1127                         if ($1 && nd_type($1) == NODE_BEGIN) {
1128                             $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
1129                         }
1130                         else {
1131                             $$ = NEW_UNTIL(cond($3), $1, 1);
1132                         }
1133                     /*%
1134                         $$ = dispatch2(until_mod, $3, $1);
1135                     %*/
1136                     }
1137                 | stmt modifier_rescue stmt
1138                     {
1139                     /*%%%*/
1140                         NODE *resq = NEW_RESBODY(0, remove_begin($3), 0);
1141                         $$ = NEW_RESCUE(remove_begin($1), resq, 0);
1142                     /*%
1143                         $$ = dispatch2(rescue_mod, $1, $3);
1144                     %*/
1145                     }
1146                 | keyword_END '{' compstmt '}'
1147                     {
1148                         if (in_def || in_single) {
1149                             rb_warn0("END in method; use at_exit");
1150                         }
1151                     /*%%%*/
1152                         $$ = NEW_POSTEXE(NEW_NODE(
1153                             NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */));
1154                     /*%
1155                         $$ = dispatch1(END, $3);
1156                     %*/
1157                     }
1158                 | command_asgn
1159                 | mlhs '=' command_call
1160                     {
1161                     /*%%%*/
1162                         value_expr($3);
1163                         $1->nd_value = $3;
1164                         $$ = $1;
1165                     /*%
1166                         $$ = dispatch2(massign, $1, $3);
1167                     %*/
1168                     }
1169                 | var_lhs tOP_ASGN command_call
1170                     {
1171                         value_expr($3);
1172                         $$ = new_op_assign($1, $2, $3);
1173                     }
1174                 | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
1175                     {
1176                     /*%%%*/
1177                         NODE *args;
1178 
1179                         value_expr($6);
1180                         if (!$3) $3 = NEW_ZARRAY();
1181                         args = arg_concat($3, $6);
1182                         if ($5 == tOROP) {
1183                             $5 = 0;
1184                         }
1185                         else if ($5 == tANDOP) {
1186                             $5 = 1;
1187                         }
1188                         $$ = NEW_OP_ASGN1($1, $5, args);
1189                         fixpos($$, $1);
1190                     /*%
1191                         $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1192                         $$ = dispatch3(opassign, $$, $5, $6);
1193                     %*/
1194                     }
1195                 | primary_value '.' tIDENTIFIER tOP_ASGN command_call
1196                     {
1197                         value_expr($5);
1198                         $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1199                     }
1200                 | primary_value '.' tCONSTANT tOP_ASGN command_call
1201                     {
1202                         value_expr($5);
1203                         $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1204                     }
1205                 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
1206                     {
1207                     /*%%%*/
1208                         $$ = NEW_COLON2($1, $3);
1209                         $$ = new_const_op_assign($$, $4, $5);
1210                     /*%
1211                         $$ = dispatch2(const_path_field, $1, $3);
1212                         $$ = dispatch3(opassign, $$, $4, $5);
1213                     %*/
1214                     }
1215                 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
1216                     {
1217                         value_expr($5);
1218                         $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
1219                     }
1220                 | backref tOP_ASGN command_call
1221                     {
1222                     /*%%%*/
1223                         rb_backref_error($1);
1224                         $$ = NEW_BEGIN(0);
1225                     /*%
1226                         $$ = dispatch2(assign, dispatch1(var_field, $1), $3);
1227                         $$ = dispatch1(assign_error, $$);
1228                     %*/
1229                     }
1230                 | lhs '=' mrhs
1231                     {
1232                     /*%%%*/
1233                         value_expr($3);
1234                         $$ = node_assign($1, $3);
1235                     /*%
1236                         $$ = dispatch2(assign, $1, $3);
1237                     %*/
1238                     }
1239                 | mlhs '=' mrhs_arg
1240                     {
1241                     /*%%%*/
1242                         $1->nd_value = $3;
1243                         $$ = $1;
1244                     /*%
1245                         $$ = dispatch2(massign, $1, $3);
1246                     %*/
1247                     }
1248                 | expr
1249                 ;
1250 
1251 command_asgn    : lhs '=' command_call
1252                     {
1253                     /*%%%*/
1254                         value_expr($3);
1255                         $$ = node_assign($1, $3);
1256                     /*%
1257                         $$ = dispatch2(assign, $1, $3);
1258                     %*/
1259                     }
1260                 | lhs '=' command_asgn
1261                     {
1262                     /*%%%*/
1263                         value_expr($3);
1264                         $$ = node_assign($1, $3);
1265                     /*%
1266                         $$ = dispatch2(assign, $1, $3);
1267                     %*/
1268                     }
1269                 ;
1270 
1271 
1272 expr            : command_call
1273                 | expr keyword_and expr
1274                     {
1275                     /*%%%*/
1276                         $$ = logop(NODE_AND, $1, $3);
1277                     /*%
1278                         $$ = dispatch3(binary, $1, ripper_intern("and"), $3);
1279                     %*/
1280                     }
1281                 | expr keyword_or expr
1282                     {
1283                     /*%%%*/
1284                         $$ = logop(NODE_OR, $1, $3);
1285                     /*%
1286                         $$ = dispatch3(binary, $1, ripper_intern("or"), $3);
1287                     %*/
1288                     }
1289                 | keyword_not opt_nl expr
1290                     {
1291                     /*%%%*/
1292                         $$ = call_uni_op(cond($3), '!');
1293                     /*%
1294                         $$ = dispatch2(unary, ripper_intern("not"), $3);
1295                     %*/
1296                     }
1297                 | '!' command_call
1298                     {
1299                     /*%%%*/
1300                         $$ = call_uni_op(cond($2), '!');
1301                     /*%
1302                         $$ = dispatch2(unary, ripper_id2sym('!'), $2);
1303                     %*/
1304                     }
1305                 | arg
1306                 ;
1307 
1308 expr_value      : expr
1309                     {
1310                     /*%%%*/
1311                         value_expr($1);
1312                         $$ = $1;
1313                         if (!$$) $$ = NEW_NIL();
1314                     /*%
1315                         $$ = $1;
1316                     %*/
1317                     }
1318                 ;
1319 
1320 command_call    : command
1321                 | block_command
1322                 ;
1323 
1324 block_command   : block_call
1325                 | block_call dot_or_colon operation2 command_args
1326                     {
1327                     /*%%%*/
1328                         $$ = NEW_CALL($1, $3, $4);
1329                     /*%
1330                         $$ = dispatch3(call, $1, $2, $3);
1331                         $$ = method_arg($$, $4);
1332                     %*/
1333                     }
1334                 ;
1335 
1336 cmd_brace_block : tLBRACE_ARG
1337                     {
1338                         $<vars>1 = dyna_push();
1339                     /*%%%*/
1340                         $<num>$ = ruby_sourceline;
1341                     /*%
1342                     %*/
1343                     }
1344                   opt_block_param
1345                   compstmt
1346                   '}'
1347                     {
1348                     /*%%%*/
1349                         $$ = NEW_ITER($3,$4);
1350                         nd_set_line($$, $<num>2);
1351                     /*%
1352                         $$ = dispatch2(brace_block, escape_Qundef($3), $4);
1353                     %*/
1354                         dyna_pop($<vars>1);
1355                     }
1356                 ;
1357 
1358 fcall           : operation
1359                     {
1360                     /*%%%*/
1361                         $$ = NEW_FCALL($1, 0);
1362                         nd_set_line($$, tokline);
1363                     /*%
1364                     %*/
1365                     }
1366                 ;
1367 
1368 command         : fcall command_args       %prec tLOWEST
1369                     {
1370                     /*%%%*/
1371                         $$ = $1;
1372                         $$->nd_args = $2;
1373                     /*%
1374                         $$ = dispatch2(command, $1, $2);
1375                     %*/
1376                     }
1377                 | fcall command_args cmd_brace_block
1378                     {
1379                     /*%%%*/
1380                         block_dup_check($2,$3);
1381                         $1->nd_args = $2;
1382                         $3->nd_iter = $1;
1383                         $$ = $3;
1384                         fixpos($$, $1);
1385                     /*%
1386                         $$ = dispatch2(command, $1, $2);
1387                         $$ = method_add_block($$, $3);
1388                     %*/
1389                     }
1390                 | primary_value '.' operation2 command_args     %prec tLOWEST
1391                     {
1392                     /*%%%*/
1393                         $$ = NEW_CALL($1, $3, $4);
1394                         fixpos($$, $1);
1395                     /*%
1396                         $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1397                     %*/
1398                     }
1399                 | primary_value '.' operation2 command_args cmd_brace_block
1400                     {
1401                     /*%%%*/
1402                         block_dup_check($4,$5);
1403                         $5->nd_iter = NEW_CALL($1, $3, $4);
1404                         $$ = $5;
1405                         fixpos($$, $1);
1406                     /*%
1407                         $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1408                         $$ = method_add_block($$, $5);
1409                     %*/
1410                    }
1411                 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1412                     {
1413                     /*%%%*/
1414                         $$ = NEW_CALL($1, $3, $4);
1415                         fixpos($$, $1);
1416                     /*%
1417                         $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1418                     %*/
1419                     }
1420                 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1421                     {
1422                     /*%%%*/
1423                         block_dup_check($4,$5);
1424                         $5->nd_iter = NEW_CALL($1, $3, $4);
1425                         $$ = $5;
1426                         fixpos($$, $1);
1427                     /*%
1428                         $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1429                         $$ = method_add_block($$, $5);
1430                     %*/
1431                    }
1432                 | keyword_super command_args
1433                     {
1434                     /*%%%*/
1435                         $$ = NEW_SUPER($2);
1436                         fixpos($$, $2);
1437                     /*%
1438                         $$ = dispatch1(super, $2);
1439                     %*/
1440                     }
1441                 | keyword_yield command_args
1442                     {
1443                     /*%%%*/
1444                         $$ = new_yield($2);
1445                         fixpos($$, $2);
1446                     /*%
1447                         $$ = dispatch1(yield, $2);
1448                     %*/
1449                     }
1450                 | keyword_return call_args
1451                     {
1452                     /*%%%*/
1453                         $$ = NEW_RETURN(ret_args($2));
1454                     /*%
1455                         $$ = dispatch1(return, $2);
1456                     %*/
1457                     }
1458                 | keyword_break call_args
1459                     {
1460                     /*%%%*/
1461                         $$ = NEW_BREAK(ret_args($2));
1462                     /*%
1463                         $$ = dispatch1(break, $2);
1464                     %*/
1465                     }
1466                 | keyword_next call_args
1467                     {
1468                     /*%%%*/
1469                         $$ = NEW_NEXT(ret_args($2));
1470                     /*%
1471                         $$ = dispatch1(next, $2);
1472                     %*/
1473                     }
1474                 ;
1475 
1476 mlhs            : mlhs_basic
1477                 | tLPAREN mlhs_inner rparen
1478                     {
1479                     /*%%%*/
1480                         $$ = $2;
1481                     /*%
1482                         $$ = dispatch1(mlhs_paren, $2);
1483                     %*/
1484                     }
1485                 ;
1486 
1487 mlhs_inner      : mlhs_basic
1488                 | tLPAREN mlhs_inner rparen
1489                     {
1490                     /*%%%*/
1491                         $$ = NEW_MASGN(NEW_LIST($2), 0);
1492                     /*%
1493                         $$ = dispatch1(mlhs_paren, $2);
1494                     %*/
1495                     }
1496                 ;
1497 
1498 mlhs_basic      : mlhs_head
1499                     {
1500                     /*%%%*/
1501                         $$ = NEW_MASGN($1, 0);
1502                     /*%
1503                         $$ = $1;
1504                     %*/
1505                     }
1506                 | mlhs_head mlhs_item
1507                     {
1508                     /*%%%*/
1509                         $$ = NEW_MASGN(list_append($1,$2), 0);
1510                     /*%
1511                         $$ = mlhs_add($1, $2);
1512                     %*/
1513                     }
1514                 | mlhs_head tSTAR mlhs_node
1515                     {
1516                     /*%%%*/
1517                         $$ = NEW_MASGN($1, $3);
1518                     /*%
1519                         $$ = mlhs_add_star($1, $3);
1520                     %*/
1521                     }
1522                 | mlhs_head tSTAR mlhs_node ',' mlhs_post
1523                     {
1524                     /*%%%*/
1525                         $$ = NEW_MASGN($1, NEW_POSTARG($3,$5));
1526                     /*%
1527                         $1 = mlhs_add_star($1, $3);
1528                         $$ = mlhs_add($1, $5);
1529                     %*/
1530                     }
1531                 | mlhs_head tSTAR
1532                     {
1533                     /*%%%*/
1534                         $$ = NEW_MASGN($1, -1);
1535                     /*%
1536                         $$ = mlhs_add_star($1, Qnil);
1537                     %*/
1538                     }
1539                 | mlhs_head tSTAR ',' mlhs_post
1540                     {
1541                     /*%%%*/
1542                         $$ = NEW_MASGN($1, NEW_POSTARG(-1, $4));
1543                     /*%
1544                         $1 = mlhs_add_star($1, Qnil);
1545                         $$ = mlhs_add($1, $4);
1546                     %*/
1547                     }
1548                 | tSTAR mlhs_node
1549                     {
1550                     /*%%%*/
1551                         $$ = NEW_MASGN(0, $2);
1552                     /*%
1553                         $$ = mlhs_add_star(mlhs_new(), $2);
1554                     %*/
1555                     }
1556                 | tSTAR mlhs_node ',' mlhs_post
1557                     {
1558                     /*%%%*/
1559                         $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
1560                     /*%
1561                         $2 = mlhs_add_star(mlhs_new(), $2);
1562                         $$ = mlhs_add($2, $4);
1563                     %*/
1564                     }
1565                 | tSTAR
1566                     {
1567                     /*%%%*/
1568                         $$ = NEW_MASGN(0, -1);
1569                     /*%
1570                         $$ = mlhs_add_star(mlhs_new(), Qnil);
1571                     %*/
1572                     }
1573                 | tSTAR ',' mlhs_post
1574                     {
1575                     /*%%%*/
1576                         $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
1577                     /*%
1578                         $$ = mlhs_add_star(mlhs_new(), Qnil);
1579                         $$ = mlhs_add($$, $3);
1580                     %*/
1581                     }
1582                 ;
1583 
1584 mlhs_item       : mlhs_node
1585                 | tLPAREN mlhs_inner rparen
1586                     {
1587                     /*%%%*/
1588                         $$ = $2;
1589                     /*%
1590                         $$ = dispatch1(mlhs_paren, $2);
1591                     %*/
1592                     }
1593                 ;
1594 
1595 mlhs_head       : mlhs_item ','
1596                     {
1597                     /*%%%*/
1598                         $$ = NEW_LIST($1);
1599                     /*%
1600                         $$ = mlhs_add(mlhs_new(), $1);
1601                     %*/
1602                     }
1603                 | mlhs_head mlhs_item ','
1604                     {
1605                     /*%%%*/
1606                         $$ = list_append($1, $2);
1607                     /*%
1608                         $$ = mlhs_add($1, $2);
1609                     %*/
1610                     }
1611                 ;
1612 
1613 mlhs_post       : mlhs_item
1614                     {
1615                     /*%%%*/
1616                         $$ = NEW_LIST($1);
1617                     /*%
1618                         $$ = mlhs_add(mlhs_new(), $1);
1619                     %*/
1620                     }
1621                 | mlhs_post ',' mlhs_item
1622                     {
1623                     /*%%%*/
1624                         $$ = list_append($1, $3);
1625                     /*%
1626                         $$ = mlhs_add($1, $3);
1627                     %*/
1628                     }
1629                 ;
1630 
1631 mlhs_node       : user_variable
1632                     {
1633                         $$ = assignable($1, 0);
1634                     }
1635                 | keyword_variable
1636                     {
1637                         $$ = assignable($1, 0);
1638                     }
1639                 | primary_value '[' opt_call_args rbracket
1640                     {
1641                     /*%%%*/
1642                         $$ = aryset($1, $3);
1643                     /*%
1644                         $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1645                     %*/
1646                     }
1647                 | primary_value '.' tIDENTIFIER
1648                     {
1649                     /*%%%*/
1650                         $$ = attrset($1, $3);
1651                     /*%
1652                         $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1653                     %*/
1654                     }
1655                 | primary_value tCOLON2 tIDENTIFIER
1656                     {
1657                     /*%%%*/
1658                         $$ = attrset($1, $3);
1659                     /*%
1660                         $$ = dispatch2(const_path_field, $1, $3);
1661                     %*/
1662                     }
1663                 | primary_value '.' tCONSTANT
1664                     {
1665                     /*%%%*/
1666                         $$ = attrset($1, $3);
1667                     /*%
1668                         $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1669                     %*/
1670                     }
1671                 | primary_value tCOLON2 tCONSTANT
1672                     {
1673                     /*%%%*/
1674                         if (in_def || in_single)
1675                             yyerror("dynamic constant assignment");
1676                         $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
1677                     /*%
1678                         if (in_def || in_single)
1679                             yyerror("dynamic constant assignment");
1680                         $$ = dispatch2(const_path_field, $1, $3);
1681                     %*/
1682                     }
1683                 | tCOLON3 tCONSTANT
1684                     {
1685                     /*%%%*/
1686                         if (in_def || in_single)
1687                             yyerror("dynamic constant assignment");
1688                         $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
1689                     /*%
1690                         $$ = dispatch1(top_const_field, $2);
1691                     %*/
1692                     }
1693                 | backref
1694                     {
1695                     /*%%%*/
1696                         rb_backref_error($1);
1697                         $$ = NEW_BEGIN(0);
1698                     /*%
1699                         $$ = dispatch1(var_field, $1);
1700                         $$ = dispatch1(assign_error, $$);
1701                     %*/
1702                     }
1703                 ;
1704 
1705 lhs             : user_variable
1706                     {
1707                         $$ = assignable($1, 0);
1708                     /*%%%*/
1709                         if (!$$) $$ = NEW_BEGIN(0);
1710                     /*%
1711                         $$ = dispatch1(var_field, $$);
1712                     %*/
1713                     }
1714                 | keyword_variable
1715                     {
1716                         $$ = assignable($1, 0);
1717                     /*%%%*/
1718                         if (!$$) $$ = NEW_BEGIN(0);
1719                     /*%
1720                         $$ = dispatch1(var_field, $$);
1721                     %*/
1722                     }
1723                 | primary_value '[' opt_call_args rbracket
1724                     {
1725                     /*%%%*/
1726                         $$ = aryset($1, $3);
1727                     /*%
1728                         $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1729                     %*/
1730                     }
1731                 | primary_value '.' tIDENTIFIER
1732                     {
1733                     /*%%%*/
1734                         $$ = attrset($1, $3);
1735                     /*%
1736                         $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1737                     %*/
1738                     }
1739                 | primary_value tCOLON2 tIDENTIFIER
1740                     {
1741                     /*%%%*/
1742                         $$ = attrset($1, $3);
1743                     /*%
1744                         $$ = dispatch3(field, $1, ripper_intern("::"), $3);
1745                     %*/
1746                     }
1747                 | primary_value '.' tCONSTANT
1748                     {
1749                     /*%%%*/
1750                         $$ = attrset($1, $3);
1751                     /*%
1752                         $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1753                     %*/
1754                     }
1755                 | primary_value tCOLON2 tCONSTANT
1756                     {
1757                     /*%%%*/
1758                         if (in_def || in_single)
1759                             yyerror("dynamic constant assignment");
1760                         $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
1761                     /*%
1762                         $$ = dispatch2(const_path_field, $1, $3);
1763                         if (in_def || in_single) {
1764                             $$ = dispatch1(assign_error, $$);
1765                         }
1766                     %*/
1767                     }
1768                 | tCOLON3 tCONSTANT
1769                     {
1770                     /*%%%*/
1771                         if (in_def || in_single)
1772                             yyerror("dynamic constant assignment");
1773                         $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
1774                     /*%
1775                         $$ = dispatch1(top_const_field, $2);
1776                         if (in_def || in_single) {
1777                             $$ = dispatch1(assign_error, $$);
1778                         }
1779                     %*/
1780                     }
1781                 | backref
1782                     {
1783                     /*%%%*/
1784                         rb_backref_error($1);
1785                         $$ = NEW_BEGIN(0);
1786                     /*%
1787                         $$ = dispatch1(assign_error, $1);
1788                     %*/
1789                     }
1790                 ;
1791 
1792 cname           : tIDENTIFIER
1793                     {
1794                     /*%%%*/
1795                         yyerror("class/module name must be CONSTANT");
1796                     /*%
1797                         $$ = dispatch1(class_name_error, $1);
1798                     %*/
1799                     }
1800                 | tCONSTANT
1801                 ;
1802 
1803 cpath           : tCOLON3 cname
1804                     {
1805                     /*%%%*/
1806                         $$ = NEW_COLON3($2);
1807                     /*%
1808                         $$ = dispatch1(top_const_ref, $2);
1809                     %*/
1810                     }
1811                 | cname
1812                     {
1813                     /*%%%*/
1814                         $$ = NEW_COLON2(0, $$);
1815                     /*%
1816                         $$ = dispatch1(const_ref, $1);
1817                     %*/
1818                     }
1819                 | primary_value tCOLON2 cname
1820                     {
1821                     /*%%%*/
1822                         $$ = NEW_COLON2($1, $3);
1823                     /*%
1824                         $$ = dispatch2(const_path_ref, $1, $3);
1825                     %*/
1826                     }
1827                 ;
1828 
1829 fname           : tIDENTIFIER
1830                 | tCONSTANT
1831                 | tFID
1832                 | op
1833                     {
1834                         lex_state = EXPR_ENDFN;
1835                         $$ = $1;
1836                     }
1837                 | reswords
1838                     {
1839                         lex_state = EXPR_ENDFN;
1840                     /*%%%*/
1841                         $$ = $<id>1;
1842                     /*%
1843                         $$ = $1;
1844                     %*/
1845                     }
1846                 ;
1847 
1848 fsym            : fname
1849                 | symbol
1850                 ;
1851 
1852 fitem           : fsym
1853                     {
1854                     /*%%%*/
1855                         $$ = NEW_LIT(ID2SYM($1));
1856                     /*%
1857                         $$ = dispatch1(symbol_literal, $1);
1858                     %*/
1859                     }
1860                 | dsym
1861                 ;
1862 
1863 undef_list      : fitem
1864                     {
1865                     /*%%%*/
1866                         $$ = NEW_UNDEF($1);
1867                     /*%
1868                         $$ = rb_ary_new3(1, $1);
1869                     %*/
1870                     }
1871                 | undef_list ',' {lex_state = EXPR_FNAME;} fitem
1872                     {
1873                     /*%%%*/
1874                         $$ = block_append($1, NEW_UNDEF($4));
1875                     /*%
1876                         rb_ary_push($1, $4);
1877                     %*/
1878                     }
1879                 ;
1880 
1881 op              : '|'           { ifndef_ripper($$ = '|'); }
1882                 | '^'           { ifndef_ripper($$ = '^'); }
1883                 | '&'           { ifndef_ripper($$ = '&'); }
1884                 | tCMP          { ifndef_ripper($$ = tCMP); }
1885                 | tEQ           { ifndef_ripper($$ = tEQ); }
1886                 | tEQQ          { ifndef_ripper($$ = tEQQ); }
1887                 | tMATCH        { ifndef_ripper($$ = tMATCH); }
1888                 | tNMATCH       { ifndef_ripper($$ = tNMATCH); }
1889                 | '>'           { ifndef_ripper($$ = '>'); }
1890                 | tGEQ          { ifndef_ripper($$ = tGEQ); }
1891                 | '<'           { ifndef_ripper($$ = '<'); }
1892                 | tLEQ          { ifndef_ripper($$ = tLEQ); }
1893                 | tNEQ          { ifndef_ripper($$ = tNEQ); }
1894                 | tLSHFT        { ifndef_ripper($$ = tLSHFT); }
1895                 | tRSHFT        { ifndef_ripper($$ = tRSHFT); }
1896                 | '+'           { ifndef_ripper($$ = '+'); }
1897                 | '-'           { ifndef_ripper($$ = '-'); }
1898                 | '*'           { ifndef_ripper($$ = '*'); }
1899                 | tSTAR         { ifndef_ripper($$ = '*'); }
1900                 | '/'           { ifndef_ripper($$ = '/'); }
1901                 | '%'           { ifndef_ripper($$ = '%'); }
1902                 | tPOW          { ifndef_ripper($$ = tPOW); }
1903                 | tDSTAR        { ifndef_ripper($$ = tDSTAR); }
1904                 | '!'           { ifndef_ripper($$ = '!'); }
1905                 | '~'           { ifndef_ripper($$ = '~'); }
1906                 | tUPLUS        { ifndef_ripper($$ = tUPLUS); }
1907                 | tUMINUS       { ifndef_ripper($$ = tUMINUS); }
1908                 | tAREF         { ifndef_ripper($$ = tAREF); }
1909                 | tASET         { ifndef_ripper($$ = tASET); }
1910                 | '`'           { ifndef_ripper($$ = '`'); }
1911                 ;
1912 
1913 reswords        : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
1914                 | keyword_BEGIN | keyword_END
1915                 | keyword_alias | keyword_and | keyword_begin
1916                 | keyword_break | keyword_case | keyword_class | keyword_def
1917                 | keyword_defined | keyword_do | keyword_else | keyword_elsif
1918                 | keyword_end | keyword_ensure | keyword_false
1919                 | keyword_for | keyword_in | keyword_module | keyword_next
1920                 | keyword_nil | keyword_not | keyword_or | keyword_redo
1921                 | keyword_rescue | keyword_retry | keyword_return | keyword_self
1922                 | keyword_super | keyword_then | keyword_true | keyword_undef
1923                 | keyword_when | keyword_yield | keyword_if | keyword_unless
1924                 | keyword_while | keyword_until
1925                 ;
1926 
1927 arg             : lhs '=' arg
1928                     {
1929                     /*%%%*/
1930                         value_expr($3);
1931                         $$ = node_assign($1, $3);
1932                     /*%
1933                         $$ = dispatch2(assign, $1, $3);
1934                     %*/
1935                     }
1936                 | lhs '=' arg modifier_rescue arg
1937                     {
1938                     /*%%%*/
1939                         value_expr($3);
1940                         $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
1941                         $$ = node_assign($1, $3);
1942                     /*%
1943                         $$ = dispatch2(assign, $1, dispatch2(rescue_mod, $3, $5));
1944                     %*/
1945                     }
1946                 | var_lhs tOP_ASGN arg
1947                     {
1948                         value_expr($3);
1949                         $$ = new_op_assign($1, $2, $3);
1950                     }
1951                 | var_lhs tOP_ASGN arg modifier_rescue arg
1952                     {
1953                     /*%%%*/
1954                         value_expr($3);
1955                         $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
1956                     /*%
1957                         $3 = dispatch2(rescue_mod, $3, $5);
1958                     %*/
1959                         $$ = new_op_assign($1, $2, $3);
1960                     }
1961                 | primary_value '[' opt_call_args rbracket tOP_ASGN arg
1962                     {
1963                     /*%%%*/
1964                         NODE *args;
1965 
1966                         value_expr($6);
1967                         if (!$3) $3 = NEW_ZARRAY();
1968                         if (nd_type($3) == NODE_BLOCK_PASS) {
1969                             args = NEW_ARGSCAT($3, $6);
1970                         }
1971                         else {
1972                             args = arg_concat($3, $6);
1973                         }
1974                         if ($5 == tOROP) {
1975                             $5 = 0;
1976                         }
1977                         else if ($5 == tANDOP) {
1978                             $5 = 1;
1979                         }
1980                         $$ = NEW_OP_ASGN1($1, $5, args);
1981                         fixpos($$, $1);
1982                     /*%
1983                         $1 = dispatch2(aref_field, $1, escape_Qundef($3));
1984                         $$ = dispatch3(opassign, $1, $5, $6);
1985                     %*/
1986                     }
1987                 | primary_value '.' tIDENTIFIER tOP_ASGN arg
1988                     {
1989                         value_expr($5);
1990                         $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1991                     }
1992                 | primary_value '.' tCONSTANT tOP_ASGN arg
1993                     {
1994                         value_expr($5);
1995                         $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
1996                     }
1997                 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
1998                     {
1999                         value_expr($5);
2000                         $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
2001                     }
2002                 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
2003                     {
2004                     /*%%%*/
2005                         $$ = NEW_COLON2($1, $3);
2006                         $$ = new_const_op_assign($$, $4, $5);
2007                     /*%
2008                         $$ = dispatch2(const_path_field, $1, $3);
2009                         $$ = dispatch3(opassign, $$, $4, $5);
2010                     %*/
2011                     }
2012                 | tCOLON3 tCONSTANT tOP_ASGN arg
2013                     {
2014                     /*%%%*/
2015                         $$ = NEW_COLON3($2);
2016                         $$ = new_const_op_assign($$, $3, $4);
2017                     /*%
2018                         $$ = dispatch1(top_const_field, $2);
2019                         $$ = dispatch3(opassign, $$, $3, $4);
2020                     %*/
2021                     }
2022                 | backref tOP_ASGN arg
2023                     {
2024                     /*%%%*/
2025                         rb_backref_error($1);
2026                         $$ = NEW_BEGIN(0);
2027                     /*%
2028                         $$ = dispatch1(var_field, $1);
2029                         $$ = dispatch3(opassign, $$, $2, $3);
2030                         $$ = dispatch1(assign_error, $$);
2031                     %*/
2032                     }
2033                 | arg tDOT2 arg
2034                     {
2035                     /*%%%*/
2036                         value_expr($1);
2037                         value_expr($3);
2038                         $$ = NEW_DOT2($1, $3);
2039                         if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
2040                             nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
2041                             deferred_nodes = list_append(deferred_nodes, $$);
2042                         }
2043                     /*%
2044                         $$ = dispatch2(dot2, $1, $3);
2045                     %*/
2046                     }
2047                 | arg tDOT3 arg
2048                     {
2049                     /*%%%*/
2050                         value_expr($1);
2051                         value_expr($3);
2052                         $$ = NEW_DOT3($1, $3);
2053                         if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
2054                             nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
2055                             deferred_nodes = list_append(deferred_nodes, $$);
2056                         }
2057                     /*%
2058                         $$ = dispatch2(dot3, $1, $3);
2059                     %*/
2060                     }
2061                 | arg '+' arg
2062                     {
2063                     /*%%%*/
2064                         $$ = call_bin_op($1, '+', $3);
2065                     /*%
2066                         $$ = dispatch3(binary, $1, ID2SYM('+'), $3);
2067                     %*/
2068                     }
2069                 | arg '-' arg
2070                     {
2071                     /*%%%*/
2072                         $$ = call_bin_op($1, '-', $3);
2073                     /*%
2074                         $$ = dispatch3(binary, $1, ID2SYM('-'), $3);
2075                     %*/
2076                     }
2077                 | arg '*' arg
2078                     {
2079                     /*%%%*/
2080                         $$ = call_bin_op($1, '*', $3);
2081                     /*%
2082                         $$ = dispatch3(binary, $1, ID2SYM('*'), $3);
2083                     %*/
2084                     }
2085                 | arg '/' arg
2086                     {
2087                     /*%%%*/
2088                         $$ = call_bin_op($1, '/', $3);
2089                     /*%
2090                         $$ = dispatch3(binary, $1, ID2SYM('/'), $3);
2091                     %*/
2092                     }
2093                 | arg '%' arg
2094                     {
2095                     /*%%%*/
2096                         $$ = call_bin_op($1, '%', $3);
2097                     /*%
2098                         $$ = dispatch3(binary, $1, ID2SYM('%'), $3);
2099                     %*/
2100                     }
2101                 | arg tPOW arg
2102                     {
2103                     /*%%%*/
2104                         $$ = call_bin_op($1, tPOW, $3);
2105                     /*%
2106                         $$ = dispatch3(binary, $1, ripper_intern("**"), $3);
2107                     %*/
2108                     }
2109                 | tUMINUS_NUM tINTEGER tPOW arg
2110                     {
2111                     /*%%%*/
2112                         $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
2113                     /*%
2114                         $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2115                         $$ = dispatch2(unary, ripper_intern("-@"), $$);
2116                     %*/
2117                     }
2118                 | tUMINUS_NUM tFLOAT tPOW arg
2119                     {
2120                     /*%%%*/
2121                         $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
2122                     /*%
2123                         $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2124                         $$ = dispatch2(unary, ripper_intern("-@"), $$);
2125                     %*/
2126                     }
2127                 | tUPLUS arg
2128                     {
2129                     /*%%%*/
2130                         $$ = call_uni_op($2, tUPLUS);
2131                     /*%
2132                         $$ = dispatch2(unary, ripper_intern("+@"), $2);
2133                     %*/
2134                     }
2135                 | tUMINUS arg
2136                     {
2137                     /*%%%*/
2138                         $$ = call_uni_op($2, tUMINUS);
2139                     /*%
2140                         $$ = dispatch2(unary, ripper_intern("-@"), $2);
2141                     %*/
2142                     }
2143                 | arg '|' arg
2144                     {
2145                     /*%%%*/
2146                         $$ = call_bin_op($1, '|', $3);
2147                     /*%
2148                         $$ = dispatch3(binary, $1, ID2SYM('|'), $3);
2149                     %*/
2150                     }
2151                 | arg '^' arg
2152                     {
2153                     /*%%%*/
2154                         $$ = call_bin_op($1, '^', $3);
2155                     /*%
2156                         $$ = dispatch3(binary, $1, ID2SYM('^'), $3);
2157                     %*/
2158                     }
2159                 | arg '&' arg
2160                     {
2161                     /*%%%*/
2162                         $$ = call_bin_op($1, '&', $3);
2163                     /*%
2164                         $$ = dispatch3(binary, $1, ID2SYM('&'), $3);
2165                     %*/
2166                     }
2167                 | arg tCMP arg
2168                     {
2169                     /*%%%*/
2170                         $$ = call_bin_op($1, tCMP, $3);
2171                     /*%
2172                         $$ = dispatch3(binary, $1, ripper_intern("<=>"), $3);
2173                     %*/
2174                     }
2175                 | arg '>' arg
2176                     {
2177                     /*%%%*/
2178                         $$ = call_bin_op($1, '>', $3);
2179                     /*%
2180                         $$ = dispatch3(binary, $1, ID2SYM('>'), $3);
2181                     %*/
2182                     }
2183                 | arg tGEQ arg
2184                     {
2185                     /*%%%*/
2186                         $$ = call_bin_op($1, tGEQ, $3);
2187                     /*%
2188                         $$ = dispatch3(binary, $1, ripper_intern(">="), $3);
2189                     %*/
2190                     }
2191                 | arg '<' arg
2192                     {
2193                     /*%%%*/
2194                         $$ = call_bin_op($1, '<', $3);
2195                     /*%
2196                         $$ = dispatch3(binary, $1, ID2SYM('<'), $3);
2197                     %*/
2198                     }
2199                 | arg tLEQ arg
2200                     {
2201                     /*%%%*/
2202                         $$ = call_bin_op($1, tLEQ, $3);
2203                     /*%
2204                         $$ = dispatch3(binary, $1, ripper_intern("<="), $3);
2205                     %*/
2206                     }
2207                 | arg tEQ arg
2208                     {
2209                     /*%%%*/
2210                         $$ = call_bin_op($1, tEQ, $3);
2211                     /*%
2212                         $$ = dispatch3(binary, $1, ripper_intern("=="), $3);
2213                     %*/
2214                     }
2215                 | arg tEQQ arg
2216                     {
2217                     /*%%%*/
2218                         $$ = call_bin_op($1, tEQQ, $3);
2219                     /*%
2220                         $$ = dispatch3(binary, $1, ripper_intern("==="), $3);
2221                     %*/
2222                     }
2223                 | arg tNEQ arg
2224                     {
2225                     /*%%%*/
2226                         $$ = call_bin_op($1, tNEQ, $3);
2227                     /*%
2228                         $$ = dispatch3(binary, $1, ripper_intern("!="), $3);
2229                     %*/
2230                     }
2231                 | arg tMATCH arg
2232                     {
2233                     /*%%%*/
2234                         $$ = match_op($1, $3);
2235                         if (nd_type($1) == NODE_LIT && RB_TYPE_P($1->nd_lit, T_REGEXP)) {
2236                             $$ = reg_named_capture_assign($1->nd_lit, $$);
2237                         }
2238                     /*%
2239                         $$ = dispatch3(binary, $1, ripper_intern("=~"), $3);
2240                     %*/
2241                     }
2242                 | arg tNMATCH arg
2243                     {
2244                     /*%%%*/
2245                         $$ = call_bin_op($1, tNMATCH, $3);
2246                     /*%
2247                         $$ = dispatch3(binary, $1, ripper_intern("!~"), $3);
2248                     %*/
2249                     }
2250                 | '!' arg
2251                     {
2252                     /*%%%*/
2253                         $$ = call_uni_op(cond($2), '!');
2254                     /*%
2255                         $$ = dispatch2(unary, ID2SYM('!'), $2);
2256                     %*/
2257                     }
2258                 | '~' arg
2259                     {
2260                     /*%%%*/
2261                         $$ = call_uni_op($2, '~');
2262                     /*%
2263                         $$ = dispatch2(unary, ID2SYM('~'), $2);
2264                     %*/
2265                     }
2266                 | arg tLSHFT arg
2267                     {
2268                     /*%%%*/
2269                         $$ = call_bin_op($1, tLSHFT, $3);
2270                     /*%
2271                         $$ = dispatch3(binary, $1, ripper_intern("<<"), $3);
2272                     %*/
2273                     }
2274                 | arg tRSHFT arg
2275                     {
2276                     /*%%%*/
2277                         $$ = call_bin_op($1, tRSHFT, $3);
2278                     /*%
2279                         $$ = dispatch3(binary, $1, ripper_intern(">>"), $3);
2280                     %*/
2281                     }
2282                 | arg tANDOP arg
2283                     {
2284                     /*%%%*/
2285                         $$ = logop(NODE_AND, $1, $3);
2286                     /*%
2287                         $$ = dispatch3(binary, $1, ripper_intern("&&"), $3);
2288                     %*/
2289                     }
2290                 | arg tOROP arg
2291                     {
2292                     /*%%%*/
2293                         $$ = logop(NODE_OR, $1, $3);
2294                     /*%
2295                         $$ = dispatch3(binary, $1, ripper_intern("||"), $3);
2296                     %*/
2297                     }
2298                 | keyword_defined opt_nl {in_defined = 1;} arg
2299                     {
2300                     /*%%%*/
2301                         in_defined = 0;
2302                         $$ = new_defined($4);
2303                     /*%
2304                         in_defined = 0;
2305                         $$ = dispatch1(defined, $4);
2306                     %*/
2307                     }
2308                 | arg '?' arg opt_nl ':' arg
2309                     {
2310                     /*%%%*/
2311                         value_expr($1);
2312                         $$ = NEW_IF(cond($1), $3, $6);
2313                         fixpos($$, $1);
2314                     /*%
2315                         $$ = dispatch3(ifop, $1, $3, $6);
2316                     %*/
2317                     }
2318                 | primary
2319                     {
2320                         $$ = $1;
2321                     }
2322                 ;
2323 
2324 arg_value       : arg
2325                     {
2326                     /*%%%*/
2327                         value_expr($1);
2328                         $$ = $1;
2329                         if (!$$) $$ = NEW_NIL();
2330                     /*%
2331                         $$ = $1;
2332                     %*/
2333                     }
2334                 ;
2335 
2336 aref_args       : none
2337                 | args trailer
2338                     {
2339                         $$ = $1;
2340                     }
2341                 | args ',' assocs trailer
2342                     {
2343                     /*%%%*/
2344                         $$ = arg_append($1, NEW_HASH($3));
2345                     /*%
2346                         $$ = arg_add_assocs($1, $3);
2347                     %*/
2348                     }
2349                 | assocs trailer
2350                     {
2351                     /*%%%*/
2352                         $$ = NEW_LIST(NEW_HASH($1));
2353                     /*%
2354                         $$ = arg_add_assocs(arg_new(), $1);
2355                     %*/
2356                     }
2357                 ;
2358 
2359 paren_args      : '(' opt_call_args rparen
2360                     {
2361                     /*%%%*/
2362                         $$ = $2;
2363                     /*%
2364                         $$ = dispatch1(arg_paren, escape_Qundef($2));
2365                     %*/
2366                     }
2367                 ;
2368 
2369 opt_paren_args  : none
2370                 | paren_args
2371                 ;
2372 
2373 opt_call_args   : none
2374                 | call_args
2375                 | args ','
2376                     {
2377                       $$ = $1;
2378                     }
2379                 | args ',' assocs ','
2380                     {
2381                     /*%%%*/
2382                         $$ = arg_append($1, NEW_HASH($3));
2383                     /*%
2384                         $$ = arg_add_assocs($1, $3);
2385                     %*/
2386                     }
2387                 | assocs ','
2388                     {
2389                     /*%%%*/
2390                         $$ = NEW_LIST(NEW_HASH($1));
2391                     /*%
2392                         $$ = arg_add_assocs(arg_new(), $1);
2393                     %*/
2394                     }
2395                 ;
2396 
2397 call_args       : command
2398                     {
2399                     /*%%%*/
2400                         value_expr($1);
2401                         $$ = NEW_LIST($1);
2402                     /*%
2403                         $$ = arg_add(arg_new(), $1);
2404                     %*/
2405                     }
2406                 | args opt_block_arg
2407                     {
2408                     /*%%%*/
2409                         $$ = arg_blk_pass($1, $2);
2410                     /*%
2411                         $$ = arg_add_optblock($1, $2);
2412                     %*/
2413                     }
2414                 | assocs opt_block_arg
2415                     {
2416                     /*%%%*/
2417                         $$ = NEW_LIST(NEW_HASH($1));
2418                         $$ = arg_blk_pass($$, $2);
2419                     /*%
2420                         $$ = arg_add_assocs(arg_new(), $1);
2421                         $$ = arg_add_optblock($$, $2);
2422                     %*/
2423                     }
2424                 | args ',' assocs opt_block_arg
2425                     {
2426                     /*%%%*/
2427                         $$ = arg_append($1, NEW_HASH($3));
2428                         $$ = arg_blk_pass($$, $4);
2429                     /*%
2430                         $$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
2431                     %*/
2432                     }
2433                 | block_arg
2434                     /*%c%*/
2435                     /*%c
2436                     {
2437                         $$ = arg_add_block(arg_new(), $1);
2438                     }
2439                     %*/
2440                 ;
2441 
2442 command_args    :  {
2443                         $<val>$ = cmdarg_stack;
2444                         CMDARG_PUSH(1);
2445                     }
2446                   call_args
2447                     {
2448                         /* CMDARG_POP() */
2449                         cmdarg_stack = $<val>1;
2450                         $$ = $2;
2451                     }
2452                 ;
2453 
2454 block_arg       : tAMPER arg_value
2455                     {
2456                     /*%%%*/
2457                         $$ = NEW_BLOCK_PASS($2);
2458                     /*%
2459                         $$ = $2;
2460                     %*/
2461                     }
2462                 ;
2463 
2464 opt_block_arg   : ',' block_arg
2465                     {
2466                         $$ = $2;
2467                     }
2468                 | none
2469                     {
2470                         $$ = 0;
2471                     }
2472                 ;
2473 
2474 args            : arg_value
2475                     {
2476                     /*%%%*/
2477                         $$ = NEW_LIST($1);
2478                     /*%
2479                         $$ = arg_add(arg_new(), $1);
2480                     %*/
2481                     }
2482                 | tSTAR arg_value
2483                     {
2484                     /*%%%*/
2485                         $$ = NEW_SPLAT($2);
2486                     /*%
2487                         $$ = arg_add_star(arg_new(), $2);
2488                     %*/
2489                     }
2490                 | args ',' arg_value
2491                     {
2492                     /*%%%*/
2493                         NODE *n1;
2494                         if ((n1 = splat_array($1)) != 0) {
2495                             $$ = list_append(n1, $3);
2496                         }
2497                         else {
2498                             $$ = arg_append($1, $3);
2499                         }
2500                     /*%
2501                         $$ = arg_add($1, $3);
2502                     %*/
2503                     }
2504                 | args ',' tSTAR arg_value
2505                     {
2506                     /*%%%*/
2507                         NODE *n1;
2508                         if ((nd_type($4) == NODE_ARRAY) && (n1 = splat_array($1)) != 0) {
2509                             $$ = list_concat(n1, $4);
2510                         }
2511                         else {
2512                             $$ = arg_concat($1, $4);
2513                         }
2514                     /*%
2515                         $$ = arg_add_star($1, $4);
2516                     %*/
2517                     }
2518                 ;
2519 
2520 mrhs_arg        : mrhs
2521                 | arg_value
2522                 ;
2523 
2524 mrhs            : args ',' arg_value
2525                     {
2526                     /*%%%*/
2527                         NODE *n1;
2528                         if ((n1 = splat_array($1)) != 0) {
2529                             $$ = list_append(n1, $3);
2530                         }
2531                         else {
2532                             $$ = arg_append($1, $3);
2533                         }
2534                     /*%
2535                         $$ = mrhs_add(args2mrhs($1), $3);
2536                     %*/
2537                     }
2538                 | args ',' tSTAR arg_value
2539                     {
2540                     /*%%%*/
2541                         NODE *n1;
2542                         if (nd_type($4) == NODE_ARRAY &&
2543                             (n1 = splat_array($1)) != 0) {
2544                             $$ = list_concat(n1, $4);
2545                         }
2546                         else {
2547                             $$ = arg_concat($1, $4);
2548                         }
2549                     /*%
2550                         $$ = mrhs_add_star(args2mrhs($1), $4);
2551                     %*/
2552                     }
2553                 | tSTAR arg_value
2554                     {
2555                     /*%%%*/
2556                         $$ = NEW_SPLAT($2);
2557                     /*%
2558                         $$ = mrhs_add_star(mrhs_new(), $2);
2559                     %*/
2560                     }
2561                 ;
2562 
2563 primary         : literal
2564                 | strings
2565                 | xstring
2566                 | regexp
2567                 | words
2568                 | qwords
2569                 | symbols
2570                 | qsymbols
2571                 | var_ref
2572                 | backref
2573                 | tFID
2574                     {
2575                     /*%%%*/
2576                         $$ = NEW_FCALL($1, 0);
2577                     /*%
2578                         $$ = method_arg(dispatch1(fcall, $1), arg_new());
2579                     %*/
2580                     }
2581                 | k_begin
2582                     {
2583                         $<val>1 = cmdarg_stack;
2584                         cmdarg_stack = 0;
2585                     /*%%%*/
2586                         $<num>$ = ruby_sourceline;
2587                     /*%
2588                     %*/
2589                     }
2590                   bodystmt
2591                   k_end
2592                     {
2593                         cmdarg_stack = $<val>1;
2594                     /*%%%*/
2595                         if ($3 == NULL) {
2596                             $$ = NEW_NIL();
2597                         }
2598                         else {
2599                             if (nd_type($3) == NODE_RESCUE ||
2600                                 nd_type($3) == NODE_ENSURE)
2601                                 nd_set_line($3, $<num>2);
2602                             $$ = NEW_BEGIN($3);
2603                         }
2604                         nd_set_line($$, $<num>2);
2605                     /*%
2606                         $$ = dispatch1(begin, $3);
2607                     %*/
2608                     }
2609                 | tLPAREN_ARG {lex_state = EXPR_ENDARG;} rparen
2610                     {
2611                     /*%%%*/
2612                         $$ = 0;
2613                     /*%
2614                         $$ = dispatch1(paren, 0);
2615                     %*/
2616                     }
2617                 | tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} rparen
2618                     {
2619                     /*%%%*/
2620                         $$ = $2;
2621                     /*%
2622                         $$ = dispatch1(paren, $2);
2623                     %*/
2624                     }
2625                 | tLPAREN compstmt ')'
2626                     {
2627                     /*%%%*/
2628                         $$ = $2;
2629                     /*%
2630                         $$ = dispatch1(paren, $2);
2631                     %*/
2632                     }
2633                 | primary_value tCOLON2 tCONSTANT
2634                     {
2635                     /*%%%*/
2636                         $$ = NEW_COLON2($1, $3);
2637                     /*%
2638                         $$ = dispatch2(const_path_ref, $1, $3);
2639                     %*/
2640                     }
2641                 | tCOLON3 tCONSTANT
2642                     {
2643                     /*%%%*/
2644                         $$ = NEW_COLON3($2);
2645                     /*%
2646                         $$ = dispatch1(top_const_ref, $2);
2647                     %*/
2648                     }
2649                 | tLBRACK aref_args ']'
2650                     {
2651                     /*%%%*/
2652                         if ($2 == 0) {
2653                             $$ = NEW_ZARRAY(); /* zero length array*/
2654                         }
2655                         else {
2656                             $$ = $2;
2657                         }
2658                     /*%
2659                         $$ = dispatch1(array, escape_Qundef($2));
2660                     %*/
2661                     }
2662                 | tLBRACE assoc_list '}'
2663                     {
2664                     /*%%%*/
2665                         $$ = NEW_HASH($2);
2666                     /*%
2667                         $$ = dispatch1(hash, escape_Qundef($2));
2668                     %*/
2669                     }
2670                 | keyword_return
2671                     {
2672                     /*%%%*/
2673                         $$ = NEW_RETURN(0);
2674                     /*%
2675                         $$ = dispatch0(return0);
2676                     %*/
2677                     }
2678                 | keyword_yield '(' call_args rparen
2679                     {
2680                     /*%%%*/
2681                         $$ = new_yield($3);
2682                     /*%
2683                         $$ = dispatch1(yield, dispatch1(paren, $3));
2684                     %*/
2685                     }
2686                 | keyword_yield '(' rparen
2687                     {
2688                     /*%%%*/
2689                         $$ = NEW_YIELD(0);
2690                     /*%
2691                         $$ = dispatch1(yield, dispatch1(paren, arg_new()));
2692                     %*/
2693                     }
2694                 | keyword_yield
2695                     {
2696                     /*%%%*/
2697                         $$ = NEW_YIELD(0);
2698                     /*%
2699                         $$ = dispatch0(yield0);
2700                     %*/
2701                     }
2702                 | keyword_defined opt_nl '(' {in_defined = 1;} expr rparen
2703                     {
2704                     /*%%%*/
2705                         in_defined = 0;
2706                         $$ = new_defined($5);
2707                     /*%
2708                         in_defined = 0;
2709                         $$ = dispatch1(defined, $5);
2710                     %*/
2711                     }
2712                 | keyword_not '(' expr rparen
2713                     {
2714                     /*%%%*/
2715                         $$ = call_uni_op(cond($3), '!');
2716                     /*%
2717                         $$ = dispatch2(unary, ripper_intern("not"), $3);
2718                     %*/
2719                     }
2720                 | keyword_not '(' rparen
2721                     {
2722                     /*%%%*/
2723                         $$ = call_uni_op(cond(NEW_NIL()), '!');
2724                     /*%
2725                         $$ = dispatch2(unary, ripper_intern("not"), Qnil);
2726                     %*/
2727                     }
2728                 | fcall brace_block
2729                     {
2730                     /*%%%*/
2731                         $2->nd_iter = $1;
2732                         $$ = $2;
2733                     /*%
2734                         $$ = method_arg(dispatch1(fcall, $1), arg_new());
2735                         $$ = method_add_block($$, $2);
2736                     %*/
2737                     }
2738                 | method_call
2739                 | method_call brace_block
2740                     {
2741                     /*%%%*/
2742                         block_dup_check($1->nd_args, $2);
2743                         $2->nd_iter = $1;
2744                         $$ = $2;
2745                     /*%
2746                         $$ = method_add_block($1, $2);
2747                     %*/
2748                     }
2749                 | tLAMBDA lambda
2750                     {
2751                         $$ = $2;
2752                     }
2753                 | k_if expr_value then
2754                   compstmt
2755                   if_tail
2756                   k_end
2757                     {
2758                     /*%%%*/
2759                         $$ = NEW_IF(cond($2), $4, $5);
2760                         fixpos($$, $2);
2761                     /*%
2762                         $$ = dispatch3(if, $2, $4, escape_Qundef($5));
2763                     %*/
2764                     }
2765                 | k_unless expr_value then
2766                   compstmt
2767                   opt_else
2768                   k_end
2769                     {
2770                     /*%%%*/
2771                         $$ = NEW_UNLESS(cond($2), $4, $5);
2772                         fixpos($$, $2);
2773                     /*%
2774                         $$ = dispatch3(unless, $2, $4, escape_Qundef($5));
2775                     %*/
2776                     }
2777                 | k_while {COND_PUSH(1);} expr_value do {COND_POP();}
2778                   compstmt
2779                   k_end
2780                     {
2781                     /*%%%*/
2782                         $$ = NEW_WHILE(cond($3), $6, 1);
2783                         fixpos($$, $3);
2784                     /*%
2785                         $$ = dispatch2(while, $3, $6);
2786                     %*/
2787                     }
2788                 | k_until {COND_PUSH(1);} expr_value do {COND_POP();}
2789                   compstmt
2790                   k_end
2791                     {
2792                     /*%%%*/
2793                         $$ = NEW_UNTIL(cond($3), $6, 1);
2794                         fixpos($$, $3);
2795                     /*%
2796                         $$ = dispatch2(until, $3, $6);
2797                     %*/
2798                     }
2799                 | k_case expr_value opt_terms
2800                   case_body
2801                   k_end
2802                     {
2803                     /*%%%*/
2804                         $$ = NEW_CASE($2, $4);
2805                         fixpos($$, $2);
2806                     /*%
2807                         $$ = dispatch2(case, $2, $4);
2808                     %*/
2809                     }
2810                 | k_case opt_terms case_body k_end
2811                     {
2812                     /*%%%*/
2813                         $$ = NEW_CASE(0, $3);
2814                     /*%
2815                         $$ = dispatch2(case, Qnil, $3);
2816                     %*/
2817                     }
2818                 | k_for for_var keyword_in
2819                   {COND_PUSH(1);}
2820                   expr_value do
2821                   {COND_POP();}
2822                   compstmt
2823                   k_end
2824                     {
2825                     /*%%%*/
2826                         /*
2827                          *  for a, b, c in e
2828                          *  #=>
2829                          *  e.each{|*x| a, b, c = x
2830                          *
2831                          *  for a in e
2832                          *  #=>
2833                          *  e.each{|x| a, = x}
2834                          */
2835                         ID id = internal_id();
2836                         ID *tbl = ALLOC_N(ID, 2);
2837                         NODE *m = NEW_ARGS_AUX(0, 0);
2838                         NODE *args, *scope;
2839 
2840                         if (nd_type($2) == NODE_MASGN) {
2841                             /* if args.length == 1 && args[0].kind_of?(Array)
2842                              *   args = args[0]
2843                              * end
2844                              */
2845                             NODE *one = NEW_LIST(NEW_LIT(INT2FIX(1)));
2846                             NODE *zero = NEW_LIST(NEW_LIT(INT2FIX(0)));
2847                             m->nd_next = block_append(
2848                                 NEW_IF(
2849                                     NEW_NODE(NODE_AND,
2850                                              NEW_CALL(NEW_CALL(NEW_DVAR(id), idLength, 0),
2851                                                       idEq, one),
2852                                              NEW_CALL(NEW_CALL(NEW_DVAR(id), idAREF, zero),
2853                                                       rb_intern("kind_of?"), NEW_LIST(NEW_LIT(rb_cArray))),
2854                                              0),
2855                                     NEW_DASGN_CURR(id,
2856                                                    NEW_CALL(NEW_DVAR(id), idAREF, zero)),
2857                                     0),
2858                                 node_assign($2, NEW_DVAR(id)));
2859 
2860                             args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
2861                         }
2862                         else {
2863                             if (nd_type($2) == NODE_LASGN ||
2864                                 nd_type($2) == NODE_DASGN ||
2865                                 nd_type($2) == NODE_DASGN_CURR) {
2866                                 $2->nd_value = NEW_DVAR(id);
2867                                 m->nd_plen = 1;
2868                                 m->nd_next = $2;
2869                                 args = new_args(m, 0, 0, 0, new_args_tail(0, 0, 0));
2870                             }
2871                             else {
2872                                 m->nd_next = node_assign(NEW_MASGN(NEW_LIST($2), 0), NEW_DVAR(id));
2873                                 args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
2874                             }
2875                         }
2876                         scope = NEW_NODE(NODE_SCOPE, tbl, $8, args);
2877                         tbl[0] = 1; tbl[1] = id;
2878                         $$ = NEW_FOR(0, $5, scope);
2879                         fixpos($$, $2);
2880                     /*%
2881                         $$ = dispatch3(for, $2, $5, $8);
2882                     %*/
2883                     }
2884                 | k_class cpath superclass
2885                     {
2886                         if (in_def || in_single)
2887                             yyerror("class definition in method body");
2888                         local_push(0);
2889                     /*%%%*/
2890                         $<num>$ = ruby_sourceline;
2891                     /*%
2892                     %*/
2893                     }
2894                   bodystmt
2895                   k_end
2896                     {
2897                     /*%%%*/
2898                         $$ = NEW_CLASS($2, $5, $3);
2899                         nd_set_line($$, $<num>4);
2900                     /*%
2901                         $$ = dispatch3(class, $2, $3, $5);
2902                     %*/
2903                         local_pop();
2904                     }
2905                 | k_class tLSHFT expr
2906                     {
2907                         $<num>$ = in_def;
2908                         in_def = 0;
2909                     }
2910                   term
2911                     {
2912                         $<num>$ = in_single;
2913                         in_single = 0;
2914                         local_push(0);
2915                     }
2916                   bodystmt
2917                   k_end
2918                     {
2919                     /*%%%*/
2920                         $$ = NEW_SCLASS($3, $7);
2921                         fixpos($$, $3);
2922                     /*%
2923                         $$ = dispatch2(sclass, $3, $7);
2924                     %*/
2925                         local_pop();
2926                         in_def = $<num>4;
2927                         in_single = $<num>6;
2928                     }
2929                 | k_module cpath
2930                     {
2931                         if (in_def || in_single)
2932                             yyerror("module definition in method body");
2933                         local_push(0);
2934                     /*%%%*/
2935                         $<num>$ = ruby_sourceline;
2936                     /*%
2937                     %*/
2938                     }
2939                   bodystmt
2940                   k_end
2941                     {
2942                     /*%%%*/
2943                         $$ = NEW_MODULE($2, $4);
2944                         nd_set_line($$, $<num>3);
2945                     /*%
2946                         $$ = dispatch2(module, $2, $4);
2947                     %*/
2948                         local_pop();
2949                     }
2950                 | k_def fname
2951                     {
2952                         $<id>$ = cur_mid;
2953                         cur_mid = $2;
2954                         in_def++;
2955                         local_push(0);
2956                     }
2957                   f_arglist
2958                   bodystmt
2959                   k_end
2960                     {
2961                     /*%%%*/
2962                         NODE *body = remove_begin($5);
2963                         reduce_nodes(&body);
2964                         $$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE);
2965                         nd_set_line($$, $<num>1);
2966                     /*%
2967                         $$ = dispatch3(def, $2, $4, $5);
2968                     %*/
2969                         local_pop();
2970                         in_def--;
2971                         cur_mid = $<id>3;
2972                     }
2973                 | k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
2974                     {
2975                         in_single++;
2976                         lex_state = EXPR_ENDFN; /* force for args */
2977                         local_push(0);
2978                     }
2979                   f_arglist
2980                   bodystmt
2981                   k_end
2982                     {
2983                     /*%%%*/
2984                         NODE *body = remove_begin($8);
2985                         reduce_nodes(&body);
2986                         $$ = NEW_DEFS($2, $5, $7, body);
2987                         nd_set_line($$, $<num>1);
2988                     /*%
2989                         $$ = dispatch5(defs, $2, $3, $5, $7, $8);
2990                     %*/
2991                         local_pop();
2992                         in_single--;
2993                     }
2994                 | keyword_break
2995                     {
2996                     /*%%%*/
2997                         $$ = NEW_BREAK(0);
2998                     /*%
2999                         $$ = dispatch1(break, arg_new());
3000                     %*/
3001                     }
3002                 | keyword_next
3003                     {
3004                     /*%%%*/
3005                         $$ = NEW_NEXT(0);
3006                     /*%
3007                         $$ = dispatch1(next, arg_new());
3008                     %*/
3009                     }
3010                 | keyword_redo
3011                     {
3012                     /*%%%*/
3013                         $$ = NEW_REDO();
3014                     /*%
3015                         $$ = dispatch0(redo);
3016                     %*/
3017                     }
3018                 | keyword_retry
3019                     {
3020                     /*%%%*/
3021                         $$ = NEW_RETRY();
3022                     /*%
3023                         $$ = dispatch0(retry);
3024                     %*/
3025                     }
3026                 ;
3027 
3028 primary_value   : primary
3029                     {
3030                     /*%%%*/
3031                         value_expr($1);
3032                         $$ = $1;
3033                         if (!$$) $$ = NEW_NIL();
3034                     /*%
3035                         $$ = $1;
3036                     %*/
3037                     }
3038                 ;
3039 
3040 k_begin         : keyword_begin
3041                     {
3042                         token_info_push("begin");
3043                     }
3044                 ;
3045 
3046 k_if            : keyword_if
3047                     {
3048                         token_info_push("if");
3049                     }
3050                 ;
3051 
3052 k_unless        : keyword_unless
3053                     {
3054                         token_info_push("unless");
3055                     }
3056                 ;
3057 
3058 k_while         : keyword_while
3059                     {
3060                         token_info_push("while");
3061                     }
3062                 ;
3063 
3064 k_until         : keyword_until
3065                     {
3066                         token_info_push("until");
3067                     }
3068                 ;
3069 
3070 k_case          : keyword_case
3071                     {
3072                         token_info_push("case");
3073                     }
3074                 ;
3075 
3076 k_for           : keyword_for
3077                     {
3078                         token_info_push("for");
3079                     }
3080                 ;
3081 
3082 k_class         : keyword_class
3083                     {
3084                         token_info_push("class");
3085                     }
3086                 ;
3087 
3088 k_module        : keyword_module
3089                     {
3090                         token_info_push("module");
3091                     }
3092                 ;
3093 
3094 k_def           : keyword_def
3095                     {
3096                         token_info_push("def");
3097                     /*%%%*/
3098                         $<num>$ = ruby_sourceline;
3099                     /*%
3100                     %*/
3101                     }
3102                 ;
3103 
3104 k_end           : keyword_end
3105                     {
3106                         token_info_pop("end");
3107                     }
3108                 ;
3109 
3110 then            : term
3111                     /*%c%*/
3112                     /*%c
3113                     { $$ = Qnil; }
3114                     %*/
3115                 | keyword_then
3116                 | term keyword_then
3117                     /*%c%*/
3118                     /*%c
3119                     { $$ = $2; }
3120                     %*/
3121                 ;
3122 
3123 do              : term
3124                     /*%c%*/
3125                     /*%c
3126                     { $$ = Qnil; }
3127                     %*/
3128                 | keyword_do_cond
3129                 ;
3130 
3131 if_tail         : opt_else
3132                 | keyword_elsif expr_value then
3133                   compstmt
3134                   if_tail
3135                     {
3136                     /*%%%*/
3137                         $$ = NEW_IF(cond($2), $4, $5);
3138                         fixpos($$, $2);
3139                     /*%
3140                         $$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
3141                     %*/
3142                     }
3143                 ;
3144 
3145 opt_else        : none
3146                 | keyword_else compstmt
3147                     {
3148                     /*%%%*/
3149                         $$ = $2;
3150                     /*%
3151                         $$ = dispatch1(else, $2);
3152                     %*/
3153                     }
3154                 ;
3155 
3156 for_var         : lhs
3157                 | mlhs
3158                 ;
3159 
3160 f_marg          : f_norm_arg
3161                     {
3162                         $$ = assignable($1, 0);
3163                     /*%%%*/
3164                     /*%
3165                         $$ = dispatch1(mlhs_paren, $$);
3166                     %*/
3167                     }
3168                 | tLPAREN f_margs rparen
3169                     {
3170                     /*%%%*/
3171                         $$ = $2;
3172                     /*%
3173                         $$ = dispatch1(mlhs_paren, $2);
3174                     %*/
3175                     }
3176                 ;
3177 
3178 f_marg_list     : f_marg
3179                     {
3180                     /*%%%*/
3181                         $$ = NEW_LIST($1);
3182                     /*%
3183                         $$ = mlhs_add(mlhs_new(), $1);
3184                     %*/
3185                     }
3186                 | f_marg_list ',' f_marg
3187                     {
3188                     /*%%%*/
3189                         $$ = list_append($1, $3);
3190                     /*%
3191                         $$ = mlhs_add($1, $3);
3192                     %*/
3193                     }
3194                 ;
3195 
3196 f_margs         : f_marg_list
3197                     {
3198                     /*%%%*/
3199                         $$ = NEW_MASGN($1, 0);
3200                     /*%
3201                         $$ = $1;
3202                     %*/
3203                     }
3204                 | f_marg_list ',' tSTAR f_norm_arg
3205                     {
3206                         $$ = assignable($4, 0);
3207                     /*%%%*/
3208                         $$ = NEW_MASGN($1, $$);
3209                     /*%
3210                         $$ = mlhs_add_star($1, $$);
3211                     %*/
3212                     }
3213                 | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
3214                     {
3215                         $$ = assignable($4, 0);
3216                     /*%%%*/
3217                         $$ = NEW_MASGN($1, NEW_POSTARG($$, $6));
3218                     /*%
3219                         $$ = mlhs_add_star($1, $$);
3220                     %*/
3221                     }
3222                 | f_marg_list ',' tSTAR
3223                     {
3224                     /*%%%*/
3225                         $$ = NEW_MASGN($1, -1);
3226                     /*%
3227                         $$ = mlhs_add_star($1, Qnil);
3228                     %*/
3229                     }
3230                 | f_marg_list ',' tSTAR ',' f_marg_list
3231                     {
3232                     /*%%%*/
3233                         $$ = NEW_MASGN($1, NEW_POSTARG(-1, $5));
3234                     /*%
3235                         $$ = mlhs_add_star($1, $5);
3236                     %*/
3237                     }
3238                 | tSTAR f_norm_arg
3239                     {
3240                         $$ = assignable($2, 0);
3241                     /*%%%*/
3242                         $$ = NEW_MASGN(0, $$);
3243                     /*%
3244                         $$ = mlhs_add_star(mlhs_new(), $$);
3245                     %*/
3246                     }
3247                 | tSTAR f_norm_arg ',' f_marg_list
3248                     {
3249                         $$ = assignable($2, 0);
3250                     /*%%%*/
3251                         $$ = NEW_MASGN(0, NEW_POSTARG($$, $4));
3252                     /*%
3253                       #if 0
3254                       TODO: Check me
3255                       #endif
3256                         $$ = mlhs_add_star($$, $4);
3257                     %*/
3258                     }
3259                 | tSTAR
3260                     {
3261                     /*%%%*/
3262                         $$ = NEW_MASGN(0, -1);
3263                     /*%
3264                         $$ = mlhs_add_star(mlhs_new(), Qnil);
3265                     %*/
3266                     }
3267                 | tSTAR ',' f_marg_list
3268                     {
3269                     /*%%%*/
3270                         $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
3271                     /*%
3272                         $$ = mlhs_add_star(mlhs_new(), Qnil);
3273                     %*/
3274                     }
3275                 ;
3276 
3277 
3278 block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
3279                     {
3280                         $$ = new_args_tail($1, $3, $4);
3281                     }
3282                 | f_block_kwarg opt_f_block_arg
3283                     {
3284                         $$ = new_args_tail($1, Qnone, $2);
3285                     }
3286                 | f_kwrest opt_f_block_arg
3287                     {
3288                         $$ = new_args_tail(Qnone, $1, $2);
3289                     }
3290                 | f_block_arg
3291                     {
3292                         $$ = new_args_tail(Qnone, Qnone, $1);
3293                     }
3294                 ;
3295 
3296 opt_block_args_tail : ',' block_args_tail
3297                     {
3298                         $$ = $2;
3299                     }
3300                 | /* none */
3301                     {
3302                         $$ = new_args_tail(Qnone, Qnone, Qnone);
3303                     }
3304                 ;
3305 
3306 block_param     : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
3307                     {
3308                         $$ = new_args($1, $3, $5, Qnone, $6);
3309                     }
3310                 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
3311                     {
3312                         $$ = new_args($1, $3, $5, $7, $8);
3313                     }
3314                 | f_arg ',' f_block_optarg opt_block_args_tail
3315                     {
3316                         $$ = new_args($1, $3, Qnone, Qnone, $4);
3317                     }
3318                 | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
3319                     {
3320                         $$ = new_args($1, $3, Qnone, $5, $6);
3321                     }
3322                 | f_arg ',' f_rest_arg opt_block_args_tail
3323                     {
3324                         $$ = new_args($1, Qnone, $3, Qnone, $4);
3325                     }
3326                 | f_arg ','
3327                     {
3328                         $$ = new_args($1, Qnone, 1, Qnone, new_args_tail(Qnone, Qnone, Qnone));
3329                     /*%%%*/
3330                     /*%
3331                         dispatch1(excessed_comma, $$);
3332                     %*/
3333                     }
3334                 | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
3335                     {
3336                         $$ = new_args($1, Qnone, $3, $5, $6);
3337                     }
3338                 | f_arg opt_block_args_tail
3339                     {
3340                         $$ = new_args($1, Qnone, Qnone, Qnone, $2);
3341                     }
3342                 | f_block_optarg ',' f_rest_arg opt_block_args_tail
3343                     {
3344                         $$ = new_args(Qnone, $1, $3, Qnone, $4);
3345                     }
3346                 | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
3347                     {
3348                         $$ = new_args(Qnone, $1, $3, $5, $6);
3349                     }
3350                 | f_block_optarg opt_block_args_tail
3351                     {
3352                         $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
3353                     }
3354                 | f_block_optarg ',' f_arg opt_block_args_tail
3355                     {
3356                         $$ = new_args(Qnone, $1, Qnone, $3, $4);
3357                     }
3358                 | f_rest_arg opt_block_args_tail
3359                     {
3360                         $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
3361                     }
3362                 | f_rest_arg ',' f_arg opt_block_args_tail
3363                     {
3364                         $$ = new_args(Qnone, Qnone, $1, $3, $4);
3365                     }
3366                 | block_args_tail
3367                     {
3368                         $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
3369                     }
3370                 ;
3371 
3372 opt_block_param : none
3373                 | block_param_def
3374                     {
3375                         command_start = TRUE;
3376                     }
3377                 ;
3378 
3379 block_param_def : '|' opt_bv_decl '|'
3380                     {
3381                     /*%%%*/
3382                         $$ = 0;
3383                     /*%
3384                         $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
3385                                           escape_Qundef($2));
3386                     %*/
3387                     }
3388                 | tOROP
3389                     {
3390                     /*%%%*/
3391                         $$ = 0;
3392                     /*%
3393                         $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
3394                                           Qnil);
3395                     %*/
3396                     }
3397                 | '|' block_param opt_bv_decl '|'
3398                     {
3399                     /*%%%*/
3400                         $$ = $2;
3401                     /*%
3402                         $$ = blockvar_new(escape_Qundef($2), escape_Qundef($3));
3403                     %*/
3404                     }
3405                 ;
3406 
3407 
3408 opt_bv_decl     : opt_nl
3409                     {
3410                       $$ = 0;
3411                     }
3412                 | opt_nl ';' bv_decls opt_nl
3413                     {
3414                     /*%%%*/
3415                         $$ = 0;
3416                     /*%
3417                         $$ = $3;
3418                     %*/
3419                     }
3420                 ;
3421 
3422 bv_decls        : bvar
3423                     /*%c%*/
3424                     /*%c
3425                     {
3426                         $$ = rb_ary_new3(1, $1);
3427                     }
3428                     %*/
3429                 | bv_decls ',' bvar
3430                     /*%c%*/
3431                     /*%c
3432                     {
3433                         rb_ary_push($1, $3);
3434                     }
3435                     %*/
3436                 ;
3437 
3438 bvar            : tIDENTIFIER
3439                     {
3440                         new_bv(get_id($1));
3441                     /*%%%*/
3442                     /*%
3443                         $$ = get_value($1);
3444                     %*/
3445                     }
3446                 | f_bad_arg
3447                     {
3448                         $$ = 0;
3449                     }
3450                 ;
3451 
3452 lambda          :   {
3453                         $<vars>$ = dyna_push();
3454                     }
3455                     {
3456                         $<num>$ = lpar_beg;
3457                         lpar_beg = ++paren_nest;
3458                     }
3459                   f_larglist
3460                   lambda_body
3461                     {
3462                         lpar_beg = $<num>2;
3463                     /*%%%*/
3464                         $$ = NEW_LAMBDA($3, $4);
3465                     /*%
3466                         $$ = dispatch2(lambda, $3, $4);
3467                     %*/
3468                         dyna_pop($<vars>1);
3469                     }
3470                 ;
3471 
3472 f_larglist      : '(' f_args opt_bv_decl ')'
3473                     {
3474                     /*%%%*/
3475                         $$ = $2;
3476                     /*%
3477                         $$ = dispatch1(paren, $2);
3478                     %*/
3479                     }
3480                 | f_args
3481                     {
3482                     /*%%%*/
3483                         $$ = $1;
3484                     /*%
3485                         $$ = $1;
3486                     %*/
3487                     }
3488                 ;
3489 
3490 lambda_body     : tLAMBEG compstmt '}'
3491                     {
3492                         $$ = $2;
3493                     }
3494                 | keyword_do_LAMBDA compstmt keyword_end
3495                     {
3496                         $$ = $2;
3497                     }
3498                 ;
3499 
3500 do_block        : keyword_do_block
3501                     {
3502                         $<vars>1 = dyna_push();
3503                     /*%%%*/
3504                         $<num>$ = ruby_sourceline;
3505                     /*% %*/
3506                     }
3507                   opt_block_param
3508                   compstmt
3509                   keyword_end
3510                     {
3511                     /*%%%*/
3512                         $$ = NEW_ITER($3,$4);
3513                         nd_set_line($$, $<num>2);
3514                     /*%
3515                         $$ = dispatch2(do_block, escape_Qundef($3), $4);
3516                     %*/
3517                         dyna_pop($<vars>1);
3518                     }
3519                 ;
3520 
3521 block_call      : command do_block
3522                     {
3523                     /*%%%*/
3524                         if (nd_type($1) == NODE_YIELD) {
3525                             compile_error(PARSER_ARG "block given to yield");
3526                         }
3527                         else {
3528                             block_dup_check($1->nd_args, $2);
3529                         }
3530                         $2->nd_iter = $1;
3531                         $$ = $2;
3532                         fixpos($$, $1);
3533                     /*%
3534                         $$ = method_add_block($1, $2);
3535                     %*/
3536                     }
3537                 | block_call dot_or_colon operation2 opt_paren_args
3538                     {
3539                     /*%%%*/
3540                         $$ = NEW_CALL($1, $3, $4);
3541                     /*%
3542                         $$ = dispatch3(call, $1, $2, $3);
3543                         $$ = method_optarg($$, $4);
3544                     %*/
3545                     }
3546                 | block_call dot_or_colon operation2 opt_paren_args brace_block
3547                     {
3548                     /*%%%*/
3549                         block_dup_check($4, $5);
3550                         $5->nd_iter = NEW_CALL($1, $3, $4);
3551                         $$ = $5;
3552                         fixpos($$, $1);
3553                     /*%
3554                         $$ = dispatch4(command_call, $1, $2, $3, $4);
3555                         $$ = method_add_block($$, $5);
3556                     %*/
3557                     }
3558                 | block_call dot_or_colon operation2 command_args do_block
3559                     {
3560                     /*%%%*/
3561                         block_dup_check($4, $5);
3562                         $5->nd_iter = NEW_CALL($1, $3, $4);
3563                         $$ = $5;
3564                         fixpos($$, $1);
3565                     /*%
3566                         $$ = dispatch4(command_call, $1, $2, $3, $4);
3567                         $$ = method_add_block($$, $5);
3568                     %*/
3569                     }
3570                 ;
3571 
3572 method_call     : fcall paren_args
3573                     {
3574                     /*%%%*/
3575                         $$ = $1;
3576                         $$->nd_args = $2;
3577                     /*%
3578                         $$ = method_arg(dispatch1(fcall, $1), $2);
3579                     %*/
3580                     }
3581                 | primary_value '.' operation2
3582                     {
3583                     /*%%%*/
3584                         $<num>$ = ruby_sourceline;
3585                     /*% %*/
3586                     }
3587                   opt_paren_args
3588                     {
3589                     /*%%%*/
3590                         $$ = NEW_CALL($1, $3, $5);
3591                         nd_set_line($$, $<num>4);
3592                     /*%
3593                         $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3594                         $$ = method_optarg($$, $5);
3595                     %*/
3596                     }
3597                 | primary_value tCOLON2 operation2
3598                     {
3599                     /*%%%*/
3600                         $<num>$ = ruby_sourceline;
3601                     /*% %*/
3602                     }
3603                   paren_args
3604                     {
3605                     /*%%%*/
3606                         $$ = NEW_CALL($1, $3, $5);
3607                         nd_set_line($$, $<num>4);
3608                     /*%
3609                         $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3610                         $$ = method_optarg($$, $5);
3611                     %*/
3612                     }
3613                 | primary_value tCOLON2 operation3
3614                     {
3615                     /*%%%*/
3616                         $$ = NEW_CALL($1, $3, 0);
3617                     /*%
3618                         $$ = dispatch3(call, $1, ripper_intern("::"), $3);
3619                     %*/
3620                     }
3621                 | primary_value '.'
3622                     {
3623                     /*%%%*/
3624                         $<num>$ = ruby_sourceline;
3625                     /*% %*/
3626                     }
3627                   paren_args
3628                     {
3629                     /*%%%*/
3630                         $$ = NEW_CALL($1, rb_intern("call"), $4);
3631                         nd_set_line($$, $<num>3);
3632                     /*%
3633                         $$ = dispatch3(call, $1, ripper_id2sym('.'),
3634                                        ripper_intern("call"));
3635                         $$ = method_optarg($$, $4);
3636                     %*/
3637                     }
3638                 | primary_value tCOLON2
3639                     {
3640                     /*%%%*/
3641                         $<num>$ = ruby_sourceline;
3642                     /*% %*/
3643                     }
3644                   paren_args
3645                     {
3646                     /*%%%*/
3647                         $$ = NEW_CALL($1, rb_intern("call"), $4);
3648                         nd_set_line($$, $<num>3);
3649                     /*%
3650                         $$ = dispatch3(call, $1, ripper_intern("::"),
3651                                        ripper_intern("call"));
3652                         $$ = method_optarg($$, $4);
3653                     %*/
3654                     }
3655                 | keyword_super paren_args
3656                     {
3657                     /*%%%*/
3658                         $$ = NEW_SUPER($2);
3659                     /*%
3660                         $$ = dispatch1(super, $2);
3661                     %*/
3662                     }
3663                 | keyword_super
3664                     {
3665                     /*%%%*/
3666                         $$ = NEW_ZSUPER();
3667                     /*%
3668                         $$ = dispatch0(zsuper);
3669                     %*/
3670                     }
3671                 | primary_value '[' opt_call_args rbracket
3672                     {
3673                     /*%%%*/
3674                         if ($1 && nd_type($1) == NODE_SELF)
3675                             $$ = NEW_FCALL(tAREF, $3);
3676                         else
3677                             $$ = NEW_CALL($1, tAREF, $3);
3678                         fixpos($$, $1);
3679                     /*%
3680                         $$ = dispatch2(aref, $1, escape_Qundef($3));
3681                     %*/
3682                     }
3683                 ;
3684 
3685 brace_block     : '{'
3686                     {
3687                         $<vars>1 = dyna_push();
3688                     /*%%%*/
3689                         $<num>$ = ruby_sourceline;
3690                     /*%
3691                     %*/
3692                     }
3693                   opt_block_param
3694                   compstmt '}'
3695                     {
3696                     /*%%%*/
3697                         $$ = NEW_ITER($3,$4);
3698                         nd_set_line($$, $<num>2);
3699                     /*%
3700                         $$ = dispatch2(brace_block, escape_Qundef($3), $4);
3701                     %*/
3702                         dyna_pop($<vars>1);
3703                     }
3704                 | keyword_do
3705                     {
3706                         $<vars>1 = dyna_push();
3707                     /*%%%*/
3708                         $<num>$ = ruby_sourceline;
3709                     /*%
3710                     %*/
3711                     }
3712                   opt_block_param
3713                   compstmt keyword_end
3714                     {
3715                     /*%%%*/
3716                         $$ = NEW_ITER($3,$4);
3717                         nd_set_line($$, $<num>2);
3718                     /*%
3719                         $$ = dispatch2(do_block, escape_Qundef($3), $4);
3720                     %*/
3721                         dyna_pop($<vars>1);
3722                     }
3723                 ;
3724 
3725 case_body       : keyword_when args then
3726                   compstmt
3727                   cases
3728                     {
3729                     /*%%%*/
3730                         $$ = NEW_WHEN($2, $4, $5);
3731                     /*%
3732                         $$ = dispatch3(when, $2, $4, escape_Qundef($5));
3733                     %*/
3734                     }
3735                 ;
3736 
3737 cases           : opt_else
3738                 | case_body
3739                 ;
3740 
3741 opt_rescue      : keyword_rescue exc_list exc_var then
3742                   compstmt
3743                   opt_rescue
3744                     {
3745                     /*%%%*/
3746                         if ($3) {
3747                             $3 = node_assign($3, NEW_ERRINFO());
3748                             $5 = block_append($3, $5);
3749                         }
3750                         $$ = NEW_RESBODY($2, $5, $6);
3751                         fixpos($$, $2?$2:$5);
3752                     /*%
3753                         $$ = dispatch4(rescue,
3754                                        escape_Qundef($2),
3755                                        escape_Qundef($3),
3756                                        escape_Qundef($5),
3757                                        escape_Qundef($6));
3758                     %*/
3759                     }
3760                 | none
3761                 ;
3762 
3763 exc_list        : arg_value
3764                     {
3765                     /*%%%*/
3766                         $$ = NEW_LIST($1);
3767                     /*%
3768                         $$ = rb_ary_new3(1, $1);
3769                     %*/
3770                     }
3771                 | mrhs
3772                     {
3773                     /*%%%*/
3774                         if (!($$ = splat_array($1))) $$ = $1;
3775                     /*%
3776                         $$ = $1;
3777                     %*/
3778                     }
3779                 | none
3780                 ;
3781 
3782 exc_var         : tASSOC lhs
3783                     {
3784                         $$ = $2;
3785                     }
3786                 | none
3787                 ;
3788 
3789 opt_ensure      : keyword_ensure compstmt
3790                     {
3791                     /*%%%*/
3792                         $$ = $2;
3793                     /*%
3794                         $$ = dispatch1(ensure, $2);
3795                     %*/
3796                     }
3797                 | none
3798                 ;
3799 
3800 literal         : numeric
3801                 | symbol
3802                     {
3803                     /*%%%*/
3804                         $$ = NEW_LIT(ID2SYM($1));
3805                     /*%
3806                         $$ = dispatch1(symbol_literal, $1);
3807                     %*/
3808                     }
3809                 | dsym
3810                 ;
3811 
3812 strings         : string
3813                     {
3814                     /*%%%*/
3815                         NODE *node = $1;
3816                         if (!node) {
3817                             node = NEW_STR(STR_NEW0());
3818                         }
3819                         else {
3820                             node = evstr2dstr(node);
3821                         }
3822                         $$ = node;
3823                     /*%
3824                         $$ = $1;
3825                     %*/
3826                     }
3827                 ;
3828 
3829 string          : tCHAR
3830                 | string1
3831                 | string string1
3832                     {
3833                     /*%%%*/
3834                         $$ = literal_concat($1, $2);
3835                     /*%
3836                         $$ = dispatch2(string_concat, $1, $2);
3837                     %*/
3838                     }
3839                 ;
3840 
3841 string1         : tSTRING_BEG string_contents tSTRING_END
3842                     {
3843                     /*%%%*/
3844                         $$ = $2;
3845                     /*%
3846                         $$ = dispatch1(string_literal, $2);
3847                     %*/
3848                     }
3849                 ;
3850 
3851 xstring         : tXSTRING_BEG xstring_contents tSTRING_END
3852                     {
3853                     /*%%%*/
3854                         NODE *node = $2;
3855                         if (!node) {
3856                             node = NEW_XSTR(STR_NEW0());
3857                         }
3858                         else {
3859                             switch (nd_type(node)) {
3860                               case NODE_STR:
3861                                 nd_set_type(node, NODE_XSTR);
3862                                 break;
3863                               case NODE_DSTR:
3864                                 nd_set_type(node, NODE_DXSTR);
3865                                 break;
3866                               default:
3867                                 node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node));
3868                                 break;
3869                             }
3870                         }
3871                         $$ = node;
3872                     /*%
3873                         $$ = dispatch1(xstring_literal, $2);
3874                     %*/
3875                     }
3876                 ;
3877 
3878 regexp          : tREGEXP_BEG regexp_contents tREGEXP_END
3879                     {
3880                     /*%%%*/
3881                         int options = $3;
3882                         NODE *node = $2;
3883                         NODE *list, *prev;
3884                         if (!node) {
3885                             node = NEW_LIT(reg_compile(STR_NEW0(), options));
3886                         }
3887                         else switch (nd_type(node)) {
3888                           case NODE_STR:
3889                             {
3890                                 VALUE src = node->nd_lit;
3891                                 nd_set_type(node, NODE_LIT);
3892                                 node->nd_lit = reg_compile(src, options);
3893                             }
3894                             break;
3895                           default:
3896                             node = NEW_NODE(NODE_DSTR, STR_NEW0(), 1, NEW_LIST(node));
3897                           case NODE_DSTR:
3898                             if (options & RE_OPTION_ONCE) {
3899                                 nd_set_type(node, NODE_DREGX_ONCE);
3900                             }
3901                             else {
3902                                 nd_set_type(node, NODE_DREGX);
3903                             }
3904                             node->nd_cflag = options & RE_OPTION_MASK;
3905                             if (!NIL_P(node->nd_lit)) reg_fragment_check(node->nd_lit, options);
3906                             for (list = (prev = node)->nd_next; list; list = list->nd_next) {
3907                                 if (nd_type(list->nd_head) == NODE_STR) {
3908                                     VALUE tail = list->nd_head->nd_lit;
3909                                     if (reg_fragment_check(tail, options) && prev && !NIL_P(prev->nd_lit)) {
3910                                         VALUE lit = prev == node ? prev->nd_lit : prev->nd_head->nd_lit;
3911                                         if (!literal_concat0(parser, lit, tail)) {
3912                                             node = 0;
3913                                             break;
3914                                         }
3915                                         rb_str_resize(tail, 0);
3916                                         prev->nd_next = list->nd_next;
3917                                         rb_gc_force_recycle((VALUE)list->nd_head);
3918                                         rb_gc_force_recycle((VALUE)list);
3919                                         list = prev;
3920                                     }
3921                                     else {
3922                                         prev = list;
3923                                     }
3924                                 }
3925                                 else {
3926                                     prev = 0;
3927                                 }
3928                             }
3929                             if (!node->nd_next) {
3930                                 VALUE src = node->nd_lit;
3931                                 nd_set_type(node, NODE_LIT);
3932                                 node->nd_lit = reg_compile(src, options);
3933                             }
3934                             break;
3935                         }
3936                         $$ = node;
3937                     /*%
3938                         $$ = dispatch2(regexp_literal, $2, $3);
3939                     %*/
3940                     }
3941                 ;
3942 
3943 words           : tWORDS_BEG ' ' tSTRING_END
3944                     {
3945                     /*%%%*/
3946                         $$ = NEW_ZARRAY();
3947                     /*%
3948                         $$ = dispatch0(words_new);
3949                         $$ = dispatch1(array, $$);
3950                     %*/
3951                     }
3952                 | tWORDS_BEG word_list tSTRING_END
3953                     {
3954                     /*%%%*/
3955                         $$ = $2;
3956                     /*%
3957                         $$ = dispatch1(array, $2);
3958                     %*/
3959                     }
3960                 ;
3961 
3962 word_list       : /* none */
3963                     {
3964                     /*%%%*/
3965                         $$ = 0;
3966                     /*%
3967                         $$ = dispatch0(words_new);
3968                     %*/
3969                     }
3970                 | word_list word ' '
3971                     {
3972                     /*%%%*/
3973                         $$ = list_append($1, evstr2dstr($2));
3974                     /*%
3975                         $$ = dispatch2(words_add, $1, $2);
3976                     %*/
3977                     }
3978                 ;
3979 
3980 word            : string_content
3981                     /*%c%*/
3982                     /*%c
3983                     {
3984                         $$ = dispatch0(word_new);
3985                         $$ = dispatch2(word_add, $$, $1);
3986                     }
3987                     %*/
3988                 | word string_content
3989                     {
3990                     /*%%%*/
3991                         $$ = literal_concat($1, $2);
3992                     /*%
3993                         $$ = dispatch2(word_add, $1, $2);
3994                     %*/
3995                     }
3996                 ;
3997 
3998 symbols         : tSYMBOLS_BEG ' ' tSTRING_END
3999                     {
4000                     /*%%%*/
4001                         $$ = NEW_ZARRAY();
4002                     /*%
4003                         $$ = dispatch0(symbols_new);
4004                         $$ = dispatch1(array, $$);
4005                     %*/
4006                     }
4007                 | tSYMBOLS_BEG symbol_list tSTRING_END
4008                     {
4009                     /*%%%*/
4010                         $$ = $2;
4011                     /*%
4012                         $$ = dispatch1(array, $2);
4013                     %*/
4014                     }
4015                 ;
4016 
4017 symbol_list     : /* none */
4018                     {
4019                     /*%%%*/
4020                         $$ = 0;
4021                     /*%
4022                         $$ = dispatch0(symbols_new);
4023                     %*/
4024                     }
4025                 | symbol_list word ' '
4026                     {
4027                     /*%%%*/
4028                         $2 = evstr2dstr($2);
4029                         nd_set_type($2, NODE_DSYM);
4030                         $$ = list_append($1, $2);
4031                     /*%
4032                         $$ = dispatch2(symbols_add, $1, $2);
4033                     %*/
4034                     }
4035                 ;
4036 
4037 qwords          : tQWORDS_BEG ' ' tSTRING_END
4038                     {
4039                     /*%%%*/
4040                         $$ = NEW_ZARRAY();
4041                     /*%
4042                         $$ = dispatch0(qwords_new);
4043                         $$ = dispatch1(array, $$);
4044                     %*/
4045                     }
4046                 | tQWORDS_BEG qword_list tSTRING_END
4047                     {
4048                     /*%%%*/
4049                         $$ = $2;
4050                     /*%
4051                         $$ = dispatch1(array, $2);
4052                     %*/
4053                     }
4054                 ;
4055 
4056 qsymbols        : tQSYMBOLS_BEG ' ' tSTRING_END
4057                     {
4058                     /*%%%*/
4059                         $$ = NEW_ZARRAY();
4060                     /*%
4061                         $$ = dispatch0(qsymbols_new);
4062                         $$ = dispatch1(array, $$);
4063                     %*/
4064                     }
4065                 | tQSYMBOLS_BEG qsym_list tSTRING_END
4066                     {
4067                     /*%%%*/
4068                         $$ = $2;
4069                     /*%
4070                         $$ = dispatch1(array, $2);
4071                     %*/
4072                     }
4073                 ;
4074 
4075 qword_list      : /* none */
4076                     {
4077                     /*%%%*/
4078                         $$ = 0;
4079                     /*%
4080                         $$ = dispatch0(qwords_new);
4081                     %*/
4082                     }
4083                 | qword_list tSTRING_CONTENT ' '
4084                     {
4085                     /*%%%*/
4086                         $$ = list_append($1, $2);
4087                     /*%
4088                         $$ = dispatch2(qwords_add, $1, $2);
4089                     %*/
4090                     }
4091                 ;
4092 
4093 qsym_list       : /* none */
4094                     {
4095                     /*%%%*/
4096                         $$ = 0;
4097                     /*%
4098                         $$ = dispatch0(qsymbols_new);
4099                     %*/
4100                     }
4101                 | qsym_list tSTRING_CONTENT ' '
4102                     {
4103                     /*%%%*/
4104                         VALUE lit;
4105                         lit = $2->nd_lit;
4106                         $2->nd_lit = ID2SYM(rb_intern_str(lit));
4107                         nd_set_type($2, NODE_LIT);
4108                         $$ = list_append($1, $2);
4109                     /*%
4110                         $$ = dispatch2(qsymbols_add, $1, $2);
4111                     %*/
4112                     }
4113                 ;
4114 
4115 string_contents : /* none */
4116                     {
4117                     /*%%%*/
4118                         $$ = 0;
4119                     /*%
4120                         $$ = dispatch0(string_content);
4121                     %*/
4122                     }
4123                 | string_contents string_content
4124                     {
4125                     /*%%%*/
4126                         $$ = literal_concat($1, $2);
4127                     /*%
4128                         $$ = dispatch2(string_add, $1, $2);
4129                     %*/
4130                     }
4131                 ;
4132 
4133 xstring_contents: /* none */
4134                     {
4135                     /*%%%*/
4136                         $$ = 0;
4137                     /*%
4138                         $$ = dispatch0(xstring_new);
4139                     %*/
4140                     }
4141                 | xstring_contents string_content
4142                     {
4143                     /*%%%*/
4144                         $$ = literal_concat($1, $2);
4145                     /*%
4146                         $$ = dispatch2(xstring_add, $1, $2);
4147                     %*/
4148                     }
4149                 ;
4150 
4151 regexp_contents: /* none */
4152                     {
4153                     /*%%%*/
4154                         $$ = 0;
4155                     /*%
4156                         $$ = dispatch0(regexp_new);
4157                     %*/
4158                     }
4159                 | regexp_contents string_content
4160                     {
4161                     /*%%%*/
4162                         NODE *head = $1, *tail = $2;
4163                         if (!head) {
4164                             $$ = tail;
4165                         }
4166                         else if (!tail) {
4167                             $$ = head;
4168                         }
4169                         else {
4170                             switch (nd_type(head)) {
4171                               case NODE_STR:
4172                                 nd_set_type(head, NODE_DSTR);
4173                                 break;
4174                               case NODE_DSTR:
4175                                 break;
4176                               default:
4177                                 head = list_append(NEW_DSTR(Qnil), head);
4178                                 break;
4179                             }
4180                             $$ = list_append(head, tail);
4181                         }
4182                     /*%
4183                         $$ = dispatch2(regexp_add, $1, $2);
4184                     %*/
4185                     }
4186                 ;
4187 
4188 string_content  : tSTRING_CONTENT
4189                 | tSTRING_DVAR
4190                     {
4191                         $<node>$ = lex_strterm;
4192                         lex_strterm = 0;
4193                         lex_state = EXPR_BEG;
4194                     }
4195                   string_dvar
4196                     {
4197                     /*%%%*/
4198                         lex_strterm = $<node>2;
4199                         $$ = NEW_EVSTR($3);
4200                     /*%
4201                         lex_strterm = $<node>2;
4202                         $$ = dispatch1(string_dvar, $3);
4203                     %*/
4204                     }
4205                 | tSTRING_DBEG
4206                     {
4207                         $<val>1 = cond_stack;
4208                         $<val>$ = cmdarg_stack;
4209                         cond_stack = 0;
4210                         cmdarg_stack = 0;
4211                     }
4212                     {
4213                         $<node>$ = lex_strterm;
4214                         lex_strterm = 0;
4215                         lex_state = EXPR_BEG;
4216                     }
4217                     {
4218                         $<num>$ = brace_nest;
4219                         brace_nest = 0;
4220                     }
4221                   compstmt tSTRING_DEND
4222                     {
4223                         cond_stack = $<val>1;
4224                         cmdarg_stack = $<val>2;
4225                         lex_strterm = $<node>3;
4226                         brace_nest = $<num>4;
4227                     /*%%%*/
4228                         if ($5) $5->flags &= ~NODE_FL_NEWLINE;
4229                         $$ = new_evstr($5);
4230                     /*%
4231                         $$ = dispatch1(string_embexpr, $5);
4232                     %*/
4233                     }
4234                 ;
4235 
4236 string_dvar     : tGVAR
4237                     {
4238                     /*%%%*/
4239                         $$ = NEW_GVAR($1);
4240                     /*%
4241                         $$ = dispatch1(var_ref, $1);
4242                     %*/
4243                     }
4244                 | tIVAR
4245                     {
4246                     /*%%%*/
4247                         $$ = NEW_IVAR($1);
4248                     /*%
4249                         $$ = dispatch1(var_ref, $1);
4250                     %*/
4251                     }
4252                 | tCVAR
4253                     {
4254                     /*%%%*/
4255                         $$ = NEW_CVAR($1);
4256                     /*%
4257                         $$ = dispatch1(var_ref, $1);
4258                     %*/
4259                     }
4260                 | backref
4261                 ;
4262 
4263 symbol          : tSYMBEG sym
4264                     {
4265                         lex_state = EXPR_END;
4266                     /*%%%*/
4267                         $$ = $2;
4268                     /*%
4269                         $$ = dispatch1(symbol, $2);
4270                     %*/
4271                     }
4272                 ;
4273 
4274 sym             : fname
4275                 | tIVAR
4276                 | tGVAR
4277                 | tCVAR
4278                 ;
4279 
4280 dsym            : tSYMBEG xstring_contents tSTRING_END
4281                     {
4282                         lex_state = EXPR_END;
4283                     /*%%%*/
4284                         $$ = dsym_node($2);
4285                     /*%
4286                         $$ = dispatch1(dyna_symbol, $2);
4287                     %*/
4288                     }
4289                 ;
4290 
4291 numeric         : tINTEGER
4292                 | tFLOAT
4293                 | tUMINUS_NUM tINTEGER         %prec tLOWEST
4294                     {
4295                     /*%%%*/
4296                         $$ = negate_lit($2);
4297                     /*%
4298                         $$ = dispatch2(unary, ripper_intern("-@"), $2);
4299                     %*/
4300                     }
4301                 | tUMINUS_NUM tFLOAT           %prec tLOWEST
4302                     {
4303                     /*%%%*/
4304                         $$ = negate_lit($2);
4305                     /*%
4306                         $$ = dispatch2(unary, ripper_intern("-@"), $2);
4307                     %*/
4308                     }
4309                 ;
4310 
4311 user_variable   : tIDENTIFIER
4312                 | tIVAR
4313                 | tGVAR
4314                 | tCONSTANT
4315                 | tCVAR
4316                 ;
4317 
4318 keyword_variable: keyword_nil {ifndef_ripper($$ = keyword_nil);}
4319                 | keyword_self {ifndef_ripper($$ = keyword_self);}
4320                 | keyword_true {ifndef_ripper($$ = keyword_true);}
4321                 | keyword_false {ifndef_ripper($$ = keyword_false);}
4322                 | keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);}
4323                 | keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);}
4324                 | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING__);}
4325                 ;
4326 
4327 var_ref         : user_variable
4328                     {
4329                     /*%%%*/
4330                         if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
4331                     /*%
4332                         if (id_is_var(get_id($1))) {
4333                             $$ = dispatch1(var_ref, $1);
4334                         }
4335                         else {
4336                             $$ = dispatch1(vcall, $1);
4337                         }
4338                     %*/
4339                     }
4340                 | keyword_variable
4341                     {
4342                     /*%%%*/
4343                         if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
4344                     /*%
4345                         $$ = dispatch1(var_ref, $1);
4346                     %*/
4347                     }
4348                 ;
4349 
4350 var_lhs         : user_variable
4351                     {
4352                         $$ = assignable($1, 0);
4353                     /*%%%*/
4354                     /*%
4355                         $$ = dispatch1(var_field, $$);
4356                     %*/
4357                     }
4358                 | keyword_variable
4359                     {
4360                         $$ = assignable($1, 0);
4361                     /*%%%*/
4362                     /*%
4363                         $$ = dispatch1(var_field, $$);
4364                     %*/
4365                     }
4366                 ;
4367 
4368 backref         : tNTH_REF
4369                 | tBACK_REF
4370                 ;
4371 
4372 superclass      : term
4373                     {
4374                     /*%%%*/
4375                         $$ = 0;
4376                     /*%
4377                         $$ = Qnil;
4378                     %*/
4379                     }
4380                 | '<'
4381                     {
4382                         lex_state = EXPR_BEG;
4383                         command_start = TRUE;
4384                     }
4385                   expr_value term
4386                     {
4387                         $$ = $3;
4388                     }
4389                 | error term
4390                     {
4391                     /*%%%*/
4392                         yyerrok;
4393                         $$ = 0;
4394                     /*%
4395                         yyerrok;
4396                         $$ = Qnil;
4397                     %*/
4398                     }
4399                 ;
4400 
4401 f_arglist       : '(' f_args rparen
4402                     {
4403                     /*%%%*/
4404                         $$ = $2;
4405                     /*%
4406                         $$ = dispatch1(paren, $2);
4407                     %*/
4408                         lex_state = EXPR_BEG;
4409                         command_start = TRUE;
4410                     }
4411                 | f_args term
4412                     {
4413                         $$ = $1;
4414                         lex_state = EXPR_BEG;
4415                         command_start = TRUE;
4416                     }
4417                 ;
4418 
4419 args_tail       : f_kwarg ',' f_kwrest opt_f_block_arg
4420                     {
4421                         $$ = new_args_tail($1, $3, $4);
4422                     }
4423                 | f_kwarg opt_f_block_arg
4424                     {
4425                         $$ = new_args_tail($1, Qnone, $2);
4426                     }
4427                 | f_kwrest opt_f_block_arg
4428                     {
4429                         $$ = new_args_tail(Qnone, $1, $2);
4430                     }
4431                 | f_block_arg
4432                     {
4433                         $$ = new_args_tail(Qnone, Qnone, $1);
4434                     }
4435                 ;
4436 
4437 opt_args_tail   : ',' args_tail
4438                     {
4439                         $$ = $2;
4440                     }
4441                 | /* none */
4442                     {
4443                         $$ = new_args_tail(Qnone, Qnone, Qnone);
4444                     }
4445                 ;
4446 
4447 f_args          : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
4448                     {
4449                         $$ = new_args($1, $3, $5, Qnone, $6);
4450                     }
4451                 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
4452                     {
4453                         $$ = new_args($1, $3, $5, $7, $8);
4454                     }
4455                 | f_arg ',' f_optarg opt_args_tail
4456                     {
4457                         $$ = new_args($1, $3, Qnone, Qnone, $4);
4458                     }
4459                 | f_arg ',' f_optarg ',' f_arg opt_args_tail
4460                     {
4461                         $$ = new_args($1, $3, Qnone, $5, $6);
4462                     }
4463                 | f_arg ',' f_rest_arg opt_args_tail
4464                     {
4465                         $$ = new_args($1, Qnone, $3, Qnone, $4);
4466                     }
4467                 | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
4468                     {
4469                         $$ = new_args($1, Qnone, $3, $5, $6);
4470                     }
4471                 | f_arg opt_args_tail
4472                     {
4473                         $$ = new_args($1, Qnone, Qnone, Qnone, $2);
4474                     }
4475                 | f_optarg ',' f_rest_arg opt_args_tail
4476                     {
4477                         $$ = new_args(Qnone, $1, $3, Qnone, $4);
4478                     }
4479                 | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
4480                     {
4481                         $$ = new_args(Qnone, $1, $3, $5, $6);
4482                     }
4483                 | f_optarg opt_args_tail
4484                     {
4485                         $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
4486                     }
4487                 | f_optarg ',' f_arg opt_args_tail
4488                     {
4489                         $$ = new_args(Qnone, $1, Qnone, $3, $4);
4490                     }
4491                 | f_rest_arg opt_args_tail
4492                     {
4493                         $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
4494                     }
4495                 | f_rest_arg ',' f_arg opt_args_tail
4496                     {
4497                         $$ = new_args(Qnone, Qnone, $1, $3, $4);
4498                     }
4499                 | args_tail
4500                     {
4501                         $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
4502                     }
4503                 | /* none */
4504                     {
4505                         $$ = new_args_tail(Qnone, Qnone, Qnone);
4506                         $$ = new_args(Qnone, Qnone, Qnone, Qnone, $$);
4507                     }
4508                 ;
4509 
4510 f_bad_arg       : tCONSTANT
4511                     {
4512                     /*%%%*/
4513                         yyerror("formal argument cannot be a constant");
4514                         $$ = 0;
4515                     /*%
4516                         $$ = dispatch1(param_error, $1);
4517                     %*/
4518                     }
4519                 | tIVAR
4520                     {
4521                     /*%%%*/
4522                         yyerror("formal argument cannot be an instance variable");
4523                         $$ = 0;
4524                     /*%
4525                         $$ = dispatch1(param_error, $1);
4526                     %*/
4527                     }
4528                 | tGVAR
4529                     {
4530                     /*%%%*/
4531                         yyerror("formal argument cannot be a global variable");
4532                         $$ = 0;
4533                     /*%
4534                         $$ = dispatch1(param_error, $1);
4535                     %*/
4536                     }
4537                 | tCVAR
4538                     {
4539                     /*%%%*/
4540                         yyerror("formal argument cannot be a class variable");
4541                         $$ = 0;
4542                     /*%
4543                         $$ = dispatch1(param_error, $1);
4544                     %*/
4545                     }
4546                 ;
4547 
4548 f_norm_arg      : f_bad_arg
4549                 | tIDENTIFIER
4550                     {
4551                         formal_argument(get_id($1));
4552                         $$ = $1;
4553                     }
4554                 ;
4555 
4556 f_arg_item      : f_norm_arg
4557                     {
4558                         arg_var(get_id($1));
4559                     /*%%%*/
4560                         $$ = NEW_ARGS_AUX($1, 1);
4561                     /*%
4562                         $$ = get_value($1);
4563                     %*/
4564                     }
4565                 | tLPAREN f_margs rparen
4566                     {
4567                         ID tid = internal_id();
4568                         arg_var(tid);
4569                     /*%%%*/
4570                         if (dyna_in_block()) {
4571                             $2->nd_value = NEW_DVAR(tid);
4572                         }
4573                         else {
4574                             $2->nd_value = NEW_LVAR(tid);
4575                         }
4576                         $$ = NEW_ARGS_AUX(tid, 1);
4577                         $$->nd_next = $2;
4578                     /*%
4579                         $$ = dispatch1(mlhs_paren, $2);
4580                     %*/
4581                     }
4582                 ;
4583 
4584 f_arg           : f_arg_item
4585                     /*%c%*/
4586                     /*%c
4587                     {
4588                         $$ = rb_ary_new3(1, $1);
4589                     }
4590                     c%*/
4591                 | f_arg ',' f_arg_item
4592                     {
4593                     /*%%%*/
4594                         $$ = $1;
4595                         $$->nd_plen++;
4596                         $$->nd_next = block_append($$->nd_next, $3->nd_next);
4597                         rb_gc_force_recycle((VALUE)$3);
4598                     /*%
4599                         $$ = rb_ary_push($1, $3);
4600                     %*/
4601                     }
4602                 ;
4603 
4604 f_kw            : tLABEL arg_value
4605                     {
4606                         arg_var(formal_argument(get_id($1)));
4607                         $$ = assignable($1, $2);
4608                     /*%%%*/
4609                         $$ = NEW_KW_ARG(0, $$);
4610                     /*%
4611                         $$ = rb_assoc_new($$, $2);
4612                     %*/
4613                     }
4614                 | tLABEL
4615                     {
4616                         arg_var(formal_argument(get_id($1)));
4617                         $$ = assignable($1, (NODE *)-1);
4618                     /*%%%*/
4619                         $$ = NEW_KW_ARG(0, $$);
4620                     /*%
4621                         $$ = rb_assoc_new($$, 0);
4622                     %*/
4623                     }
4624                 ;
4625 
4626 f_block_kw      : tLABEL primary_value
4627                     {
4628                         arg_var(formal_argument(get_id($1)));
4629                         $$ = assignable($1, $2);
4630                     /*%%%*/
4631                         $$ = NEW_KW_ARG(0, $$);
4632                     /*%
4633                         $$ = rb_assoc_new($$, $2);
4634                     %*/
4635                     }
4636                 | tLABEL
4637                     {
4638                         arg_var(formal_argument(get_id($1)));
4639                         $$ = assignable($1, (NODE *)-1);
4640                     /*%%%*/
4641                         $$ = NEW_KW_ARG(0, $$);
4642                     /*%
4643                         $$ = rb_assoc_new($$, 0);
4644                     %*/
4645                     }
4646                 ;
4647 
4648 f_block_kwarg   : f_block_kw
4649                     {
4650                     /*%%%*/
4651                         $$ = $1;
4652                     /*%
4653                         $$ = rb_ary_new3(1, $1);
4654                     %*/
4655                     }
4656                 | f_block_kwarg ',' f_block_kw
4657                     {
4658                     /*%%%*/
4659                         NODE *kws = $1;
4660 
4661                         while (kws->nd_next) {
4662                             kws = kws->nd_next;
4663                         }
4664                         kws->nd_next = $3;
4665                         $$ = $1;
4666                     /*%
4667                         $$ = rb_ary_push($1, $3);
4668                     %*/
4669                     }
4670                 ;
4671 
4672 
4673 f_kwarg         : f_kw
4674                     {
4675                     /*%%%*/
4676                         $$ = $1;
4677                     /*%
4678                         $$ = rb_ary_new3(1, $1);
4679                     %*/
4680                     }
4681                 | f_kwarg ',' f_kw
4682                     {
4683                     /*%%%*/
4684                         NODE *kws = $1;
4685 
4686                         while (kws->nd_next) {
4687                             kws = kws->nd_next;
4688                         }
4689                         kws->nd_next = $3;
4690                         $$ = $1;
4691                     /*%
4692                         $$ = rb_ary_push($1, $3);
4693                     %*/
4694                     }
4695                 ;
4696 
4697 kwrest_mark     : tPOW
4698                 | tDSTAR
4699                 ;
4700 
4701 f_kwrest        : kwrest_mark tIDENTIFIER
4702                     {
4703                         shadowing_lvar(get_id($2));
4704                         $$ = $2;
4705                     }
4706                 | kwrest_mark
4707                     {
4708                         $$ = internal_id();
4709                     }
4710                 ;
4711 
4712 f_opt           : tIDENTIFIER '=' arg_value
4713                     {
4714                         arg_var(formal_argument(get_id($1)));
4715                         $$ = assignable($1, $3);
4716                     /*%%%*/
4717                         $$ = NEW_OPT_ARG(0, $$);
4718                     /*%
4719                         $$ = rb_assoc_new($$, $3);
4720                     %*/
4721                     }
4722                 ;
4723 
4724 f_block_opt     : tIDENTIFIER '=' primary_value
4725                     {
4726                         arg_var(formal_argument(get_id($1)));
4727                         $$ = assignable($1, $3);
4728                     /*%%%*/
4729                         $$ = NEW_OPT_ARG(0, $$);
4730                     /*%
4731                         $$ = rb_assoc_new($$, $3);
4732                     %*/
4733                     }
4734                 ;
4735 
4736 f_block_optarg  : f_block_opt
4737                     {
4738                     /*%%%*/
4739                         $$ = $1;
4740                     /*%
4741                         $$ = rb_ary_new3(1, $1);
4742                     %*/
4743                     }
4744                 | f_block_optarg ',' f_block_opt
4745                     {
4746                     /*%%%*/
4747                         NODE *opts = $1;
4748 
4749                         while (opts->nd_next) {
4750                             opts = opts->nd_next;
4751                         }
4752                         opts->nd_next = $3;
4753                         $$ = $1;
4754                     /*%
4755                         $$ = rb_ary_push($1, $3);
4756                     %*/
4757                     }
4758                 ;
4759 
4760 f_optarg        : f_opt
4761                     {
4762                     /*%%%*/
4763                         $$ = $1;
4764                     /*%
4765                         $$ = rb_ary_new3(1, $1);
4766                     %*/
4767                     }
4768                 | f_optarg ',' f_opt
4769                     {
4770                     /*%%%*/
4771                         NODE *opts = $1;
4772 
4773                         while (opts->nd_next) {
4774                             opts = opts->nd_next;
4775                         }
4776                         opts->nd_next = $3;
4777                         $$ = $1;
4778                     /*%
4779                         $$ = rb_ary_push($1, $3);
4780                     %*/
4781                     }
4782                 ;
4783 
4784 restarg_mark    : '*'
4785                 | tSTAR
4786                 ;
4787 
4788 f_rest_arg      : restarg_mark tIDENTIFIER
4789                     {
4790                     /*%%%*/
4791                         if (!is_local_id($2))
4792                             yyerror("rest argument must be local variable");
4793                     /*% %*/
4794                         arg_var(shadowing_lvar(get_id($2)));
4795                     /*%%%*/
4796                         $$ = $2;
4797                     /*%
4798                         $$ = dispatch1(rest_param, $2);
4799                     %*/
4800                     }
4801                 | restarg_mark
4802                     {
4803                     /*%%%*/
4804                         $$ = internal_id();
4805                         arg_var($$);
4806                     /*%
4807                         $$ = dispatch1(rest_param, Qnil);
4808                     %*/
4809                     }
4810                 ;
4811 
4812 blkarg_mark     : '&'
4813                 | tAMPER
4814                 ;
4815 
4816 f_block_arg     : blkarg_mark tIDENTIFIER
4817                     {
4818                     /*%%%*/
4819                         if (!is_local_id($2))
4820                             yyerror("block argument must be local variable");
4821                         else if (!dyna_in_block() && local_id($2))
4822                             yyerror("duplicated block argument name");
4823                     /*% %*/
4824                         arg_var(shadowing_lvar(get_id($2)));
4825                     /*%%%*/
4826                         $$ = $2;
4827                     /*%
4828                         $$ = dispatch1(blockarg, $2);
4829                     %*/
4830                     }
4831                 ;
4832 
4833 opt_f_block_arg : ',' f_block_arg
4834                     {
4835                         $$ = $2;
4836                     }
4837                 | none
4838                     {
4839                     /*%%%*/
4840                         $$ = 0;
4841                     /*%
4842                         $$ = Qundef;
4843                     %*/
4844                     }
4845                 ;
4846 
4847 singleton       : var_ref
4848                     {
4849                     /*%%%*/
4850                         value_expr($1);
4851                         $$ = $1;
4852                         if (!$$) $$ = NEW_NIL();
4853                     /*%
4854                         $$ = $1;
4855                     %*/
4856                     }
4857                 | '(' {lex_state = EXPR_BEG;} expr rparen
4858                     {
4859                     /*%%%*/
4860                         if ($3 == 0) {
4861                             yyerror("can't define singleton method for ().");
4862                         }
4863                         else {
4864                             switch (nd_type($3)) {
4865                               case NODE_STR:
4866                               case NODE_DSTR:
4867                               case NODE_XSTR:
4868                               case NODE_DXSTR:
4869                               case NODE_DREGX:
4870                               case NODE_LIT:
4871                               case NODE_ARRAY:
4872                               case NODE_ZARRAY:
4873                                 yyerror("can't define singleton method for literals");
4874                               default:
4875                                 value_expr($3);
4876                                 break;
4877                             }
4878                         }
4879                         $$ = $3;
4880                     /*%
4881                         $$ = dispatch1(paren, $3);
4882                     %*/
4883                     }
4884                 ;
4885 
4886 assoc_list      : none
4887                 | assocs trailer
4888                     {
4889                     /*%%%*/
4890                         $$ = $1;
4891                     /*%
4892                         $$ = dispatch1(assoclist_from_args, $1);
4893                     %*/
4894                     }
4895                 ;
4896 
4897 assocs          : assoc
4898                     /*%c%*/
4899                     /*%c
4900                     {
4901                         $$ = rb_ary_new3(1, $1);
4902                     }
4903                     %*/
4904                 | assocs ',' assoc
4905                     {
4906                     /*%%%*/
4907                         $$ = list_concat($1, $3);
4908                     /*%
4909                         $$ = rb_ary_push($1, $3);
4910                     %*/
4911                     }
4912                 ;
4913 
4914 assoc           : arg_value tASSOC arg_value
4915                     {
4916                     /*%%%*/
4917                         $$ = list_append(NEW_LIST($1), $3);
4918                     /*%
4919                         $$ = dispatch2(assoc_new, $1, $3);
4920                     %*/
4921                     }
4922                 | tLABEL arg_value
4923                     {
4924                     /*%%%*/
4925                         $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
4926                     /*%
4927                         $$ = dispatch2(assoc_new, $1, $2);
4928                     %*/
4929                     }
4930                 | tDSTAR arg_value
4931                     {
4932                     /*%%%*/
4933                         $$ = list_append(NEW_LIST(0), $2);
4934                     /*%
4935                         $$ = dispatch1(assoc_splat, $2);
4936                     %*/
4937                     }
4938                 ;
4939 
4940                 ;
4941 
4942 operation       : tIDENTIFIER
4943                 | tCONSTANT
4944                 | tFID
4945                 ;
4946 
4947 operation2      : tIDENTIFIER
4948                 | tCONSTANT
4949                 | tFID
4950                 | op
4951                 ;
4952 
4953 operation3      : tIDENTIFIER
4954                 | tFID
4955                 | op
4956                 ;
4957 
4958 dot_or_colon    : '.'
4959                     /*%c%*/
4960                     /*%c
4961                     { $$ = $<val>1; }
4962                     %*/
4963                 | tCOLON2
4964                     /*%c%*/
4965                     /*%c
4966                     { $$ = $<val>1; }
4967                     %*/
4968                 ;
4969 
4970 opt_terms       : /* none */
4971                 | terms
4972                 ;
4973 
4974 opt_nl          : /* none */
4975                 | '\n'
4976                 ;
4977 
4978 rparen          : opt_nl ')'
4979                 ;
4980 
4981 rbracket        : opt_nl ']'
4982                 ;
4983 
4984 trailer         : /* none */
4985                 | '\n'
4986                 | ','
4987                 ;
4988 
4989 term            : ';' {yyerrok;}
4990                 | '\n'
4991                 ;
4992 
4993 terms           : term
4994                 | terms ';' {yyerrok;}
4995                 ;
4996 
4997 none            : /* none */
4998                     {
4999                     /*%%%*/
5000                         $$ = 0;
5001                     /*%
5002                         $$ = Qundef;
5003                     %*/
5004                     }
5005                 ;
5006 %%
5007 # undef parser
5008 # undef yylex
5009 # undef yylval
5010 # define yylval  (*((YYSTYPE*)(parser->parser_yylval)))
5011 
5012 static int parser_regx_options(struct parser_params*);
5013 static int parser_tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**);
5014 static void parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc);
5015 static int parser_parse_string(struct parser_params*,NODE*);
5016 static int parser_here_document(struct parser_params*,NODE*);
5017 
5018 
5019 # define nextc()                   parser_nextc(parser)
5020 # define pushback(c)               parser_pushback(parser, (c))
5021 # define newtok()                  parser_newtok(parser)
5022 # define tokspace(n)               parser_tokspace(parser, (n))
5023 # define tokadd(c)                 parser_tokadd(parser, (c))
5024 # define tok_hex(numlen)           parser_tok_hex(parser, (numlen))
5025 # define read_escape(flags,e)      parser_read_escape(parser, (flags), (e))
5026 # define tokadd_escape(e)          parser_tokadd_escape(parser, (e))
5027 # define regx_options()            parser_regx_options(parser)
5028 # define tokadd_string(f,t,p,n,e)  parser_tokadd_string(parser,(f),(t),(p),(n),(e))
5029 # define parse_string(n)           parser_parse_string(parser,(n))
5030 # define tokaddmbc(c, enc)         parser_tokaddmbc(parser, (c), (enc))
5031 # define here_document(n)          parser_here_document(parser,(n))
5032 # define heredoc_identifier()      parser_heredoc_identifier(parser)
5033 # define heredoc_restore(n)        parser_heredoc_restore(parser,(n))
5034 # define whole_match_p(e,l,i)      parser_whole_match_p(parser,(e),(l),(i))
5035 
5036 #ifndef RIPPER
5037 # define set_yylval_str(x) (yylval.node = NEW_STR(x))
5038 # define set_yylval_num(x) (yylval.num = (x))
5039 # define set_yylval_id(x)  (yylval.id = (x))
5040 # define set_yylval_name(x)  (yylval.id = (x))
5041 # define set_yylval_literal(x) (yylval.node = NEW_LIT(x))
5042 # define set_yylval_node(x) (yylval.node = (x))
5043 # define yylval_id() (yylval.id)
5044 #else
5045 static inline VALUE
5046 ripper_yylval_id(ID x)
5047 {
5048     return (VALUE)NEW_LASGN(x, ID2SYM(x));
5049 }
5050 # define set_yylval_str(x) (void)(x)
5051 # define set_yylval_num(x) (void)(x)
5052 # define set_yylval_id(x)  (void)(x)
5053 # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x))
5054 # define set_yylval_literal(x) (void)(x)
5055 # define set_yylval_node(x) (void)(x)
5056 # define yylval_id() yylval.id
5057 #endif
5058 
5059 #ifndef RIPPER
5060 #define ripper_flush(p) (void)(p)
5061 #else
5062 #define ripper_flush(p) ((p)->tokp = (p)->parser_lex_p)
5063 
5064 #define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
5065 
5066 static int
5067 ripper_has_scan_event(struct parser_params *parser)
5068 {
5069 
5070     if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp");
5071     return lex_p > parser->tokp;
5072 }
5073 
5074 static VALUE
5075 ripper_scan_event_val(struct parser_params *parser, int t)
5076 {
5077     VALUE str = STR_NEW(parser->tokp, lex_p - parser->tokp);
5078     VALUE rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
5079     ripper_flush(parser);
5080     return rval;
5081 }
5082 
5083 static void
5084 ripper_dispatch_scan_event(struct parser_params *parser, int t)
5085 {
5086     if (!ripper_has_scan_event(parser)) return;
5087     yylval_rval = ripper_scan_event_val(parser, t);
5088 }
5089 
5090 static void
5091 ripper_dispatch_ignored_scan_event(struct parser_params *parser, int t)
5092 {
5093     if (!ripper_has_scan_event(parser)) return;
5094     (void)ripper_scan_event_val(parser, t);
5095 }
5096 
5097 static void
5098 ripper_dispatch_delayed_token(struct parser_params *parser, int t)
5099 {
5100     int saved_line = ruby_sourceline;
5101     const char *saved_tokp = parser->tokp;
5102 
5103     ruby_sourceline = parser->delayed_line;
5104     parser->tokp = lex_pbeg + parser->delayed_col;
5105     yylval_rval = ripper_dispatch1(parser, ripper_token2eventid(t), parser->delayed);
5106     parser->delayed = Qnil;
5107     ruby_sourceline = saved_line;
5108     parser->tokp = saved_tokp;
5109 }
5110 #endif /* RIPPER */
5111 
5112 #include "ruby/regex.h"
5113 #include "ruby/util.h"
5114 
5115 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
5116    since ours (we hope) works properly with all combinations of
5117    machines, compilers, `char' and `unsigned char' argument types.
5118    (Per Bothner suggested the basic approach.)  */
5119 #undef SIGN_EXTEND_CHAR
5120 #if __STDC__
5121 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
5122 #else  /* not __STDC__ */
5123 /* As in Harbison and Steele.  */
5124 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
5125 #endif
5126 
5127 #define parser_encoding_name()  (current_enc->name)
5128 #define parser_mbclen()  mbclen((lex_p-1),lex_pend,current_enc)
5129 #define parser_precise_mbclen()  rb_enc_precise_mbclen((lex_p-1),lex_pend,current_enc)
5130 #define is_identchar(p,e,enc) (rb_enc_isalnum((unsigned char)(*(p)),(enc)) || (*(p)) == '_' || !ISASCII(*(p)))
5131 #define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,current_enc))
5132 
5133 #define parser_isascii() ISASCII(*(lex_p-1))
5134 
5135 #ifndef RIPPER
5136 static int
5137 token_info_get_column(struct parser_params *parser, const char *token)
5138 {
5139     int column = 1;
5140     const char *p, *pend = lex_p - strlen(token);
5141     for (p = lex_pbeg; p < pend; p++) {
5142         if (*p == '\t') {
5143             column = (((column - 1) / 8) + 1) * 8;
5144         }
5145         column++;
5146     }
5147     return column;
5148 }
5149 
5150 static int
5151 token_info_has_nonspaces(struct parser_params *parser, const char *token)
5152 {
5153     const char *p, *pend = lex_p - strlen(token);
5154     for (p = lex_pbeg; p < pend; p++) {
5155         if (*p != ' ' && *p != '\t') {
5156             return 1;
5157         }
5158     }
5159     return 0;
5160 }
5161 
5162 #undef token_info_push
5163 static void
5164 token_info_push(struct parser_params *parser, const char *token)
5165 {
5166     token_info *ptinfo;
5167 
5168     if (!parser->parser_token_info_enabled) return;
5169     ptinfo = ALLOC(token_info);
5170     ptinfo->token = token;
5171     ptinfo->linenum = ruby_sourceline;
5172     ptinfo->column = token_info_get_column(parser, token);
5173     ptinfo->nonspc = token_info_has_nonspaces(parser, token);
5174     ptinfo->next = parser->parser_token_info;
5175 
5176     parser->parser_token_info = ptinfo;
5177 }
5178 
5179 #undef token_info_pop
5180 static void
5181 token_info_pop(struct parser_params *parser, const char *token)
5182 {
5183     int linenum;
5184     token_info *ptinfo = parser->parser_token_info;
5185 
5186     if (!ptinfo) return;
5187     parser->parser_token_info = ptinfo->next;
5188     if (token_info_get_column(parser, token) == ptinfo->column) { /* OK */
5189         goto finish;
5190     }
5191     linenum = ruby_sourceline;
5192     if (linenum == ptinfo->linenum) { /* SKIP */
5193         goto finish;
5194     }
5195     if (token_info_has_nonspaces(parser, token) || ptinfo->nonspc) { /* SKIP */
5196         goto finish;
5197     }
5198     if (parser->parser_token_info_enabled) {
5199         rb_compile_warn(ruby_sourcefile, linenum,
5200                         "mismatched indentations at '%s' with '%s' at %d",
5201                         token, ptinfo->token, ptinfo->linenum);
5202     }
5203 
5204   finish:
5205     xfree(ptinfo);
5206 }
5207 #endif  /* RIPPER */
5208 
5209 static int
5210 parser_yyerror(struct parser_params *parser, const char *msg)
5211 {
5212 #ifndef RIPPER
5213     const int max_line_margin = 30;
5214     const char *p, *pe;
5215     char *buf;
5216     long len;
5217     int i;
5218 
5219     compile_error(PARSER_ARG "%s", msg);
5220     p = lex_p;
5221     while (lex_pbeg <= p) {
5222         if (*p == '\n') break;
5223         p--;
5224     }
5225     p++;
5226 
5227     pe = lex_p;
5228     while (pe < lex_pend) {
5229         if (*pe == '\n') break;
5230         pe++;
5231     }
5232 
5233     len = pe - p;
5234     if (len > 4) {
5235         char *p2;
5236         const char *pre = "", *post = "";
5237 
5238         if (len > max_line_margin * 2 + 10) {
5239             if (lex_p - p > max_line_margin) {
5240                 p = rb_enc_prev_char(p, lex_p - max_line_margin, pe, rb_enc_get(lex_lastline));
5241                 pre = "...";
5242             }
5243             if (pe - lex_p > max_line_margin) {
5244                 pe = rb_enc_prev_char(lex_p, lex_p + max_line_margin, pe, rb_enc_get(lex_lastline));
5245                 post = "...";
5246             }
5247             len = pe - p;
5248         }
5249         buf = ALLOCA_N(char, len+2);
5250         MEMCPY(buf, p, char, len);
5251         buf[len] = '\0';
5252         rb_compile_error_append("%s%s%s", pre, buf, post);
5253 
5254         i = (int)(lex_p - p);
5255         p2 = buf; pe = buf + len;
5256 
5257         while (p2 < pe) {
5258             if (*p2 != '\t') *p2 = ' ';
5259             p2++;
5260         }
5261         buf[i] = '^';
5262         buf[i+1] = '\0';
5263         rb_compile_error_append("%s%s", pre, buf);
5264     }
5265 #else
5266     dispatch1(parse_error, STR_NEW2(msg));
5267 #endif /* !RIPPER */
5268     return 0;
5269 }
5270 
5271 static void parser_prepare(struct parser_params *parser);
5272 
5273 #ifndef RIPPER
5274 static VALUE
5275 debug_lines(const char *f)
5276 {
5277     ID script_lines;
5278     CONST_ID(script_lines, "SCRIPT_LINES__");
5279     if (rb_const_defined_at(rb_cObject, script_lines)) {
5280         VALUE hash = rb_const_get_at(rb_cObject, script_lines);
5281         if (RB_TYPE_P(hash, T_HASH)) {
5282             VALUE fname = rb_external_str_new_with_enc(f, strlen(f), rb_filesystem_encoding());
5283             VALUE lines = rb_ary_new();
5284             rb_hash_aset(hash, fname, lines);
5285             return lines;
5286         }
5287     }
5288     return 0;
5289 }
5290 
5291 static VALUE
5292 coverage(const char *f, int n)
5293 {
5294     VALUE coverages = rb_get_coverages();
5295     if (RTEST(coverages) && RBASIC(coverages)->klass == 0) {
5296         VALUE fname = rb_external_str_new_with_enc(f, strlen(f), rb_filesystem_encoding());
5297         VALUE lines = rb_ary_new2(n);
5298         int i;
5299         RBASIC_CLEAR_CLASS(lines);
5300         for (i = 0; i < n; i++) RARRAY_ASET(lines, i, Qnil);
5301         RARRAY(lines)->as.heap.len = n;
5302         rb_hash_aset(coverages, fname, lines);
5303         return lines;
5304     }
5305     return 0;
5306 }
5307 
5308 static int
5309 e_option_supplied(struct parser_params *parser)
5310 {
5311     return strcmp(ruby_sourcefile, "-e") == 0;
5312 }
5313 
5314 static VALUE
5315 yycompile0(VALUE arg)
5316 {
5317     int n;
5318     NODE *tree;
5319     struct parser_params *parser = (struct parser_params *)arg;
5320 
5321     if (!compile_for_eval && rb_safe_level() == 0) {
5322         ruby_debug_lines = debug_lines(ruby_sourcefile);
5323         if (ruby_debug_lines && ruby_sourceline > 0) {
5324             VALUE str = STR_NEW0();
5325             n = ruby_sourceline;
5326             do {
5327                 rb_ary_push(ruby_debug_lines, str);
5328             } while (--n);
5329         }
5330 
5331         if (!e_option_supplied(parser)) {
5332             ruby_coverage = coverage(ruby_sourcefile, ruby_sourceline);
5333         }
5334     }
5335 
5336     parser_prepare(parser);
5337     deferred_nodes = 0;
5338 #ifndef RIPPER
5339     parser->parser_token_info_enabled = !compile_for_eval && RTEST(ruby_verbose);
5340 #endif
5341 #ifndef RIPPER
5342     if (RUBY_DTRACE_PARSE_BEGIN_ENABLED()) {
5343         RUBY_DTRACE_PARSE_BEGIN(parser->parser_ruby_sourcefile,
5344                                 parser->parser_ruby_sourceline);
5345     }
5346 #endif
5347     n = yyparse((void*)parser);
5348 #ifndef RIPPER
5349     if (RUBY_DTRACE_PARSE_END_ENABLED()) {
5350         RUBY_DTRACE_PARSE_END(parser->parser_ruby_sourcefile,
5351                               parser->parser_ruby_sourceline);
5352     }
5353 #endif
5354     ruby_debug_lines = 0;
5355     ruby_coverage = 0;
5356     compile_for_eval = 0;
5357 
5358     lex_strterm = 0;
5359     lex_p = lex_pbeg = lex_pend = 0;
5360     lex_lastline = lex_nextline = 0;
5361     if (parser->nerr) {
5362         return 0;
5363     }
5364     tree = ruby_eval_tree;
5365     if (!tree) {
5366         tree = NEW_NIL();
5367     }
5368     else if (ruby_eval_tree_begin) {
5369         tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body);
5370     }
5371     return (VALUE)tree;
5372 }
5373 
5374 static NODE*
5375 yycompile(struct parser_params *parser, const char *f, int line)
5376 {
5377     ruby_sourcefile = ruby_strdup(f);
5378     ruby_sourceline = line - 1;
5379     return (NODE *)rb_suppress_tracing(yycompile0, (VALUE)parser);
5380 }
5381 #endif /* !RIPPER */
5382 
5383 static rb_encoding *
5384 must_be_ascii_compatible(VALUE s)
5385 {
5386     rb_encoding *enc = rb_enc_get(s);
5387     if (!rb_enc_asciicompat(enc)) {
5388         rb_raise(rb_eArgError, "invalid source encoding");
5389     }
5390     return enc;
5391 }
5392 
5393 static VALUE
5394 lex_get_str(struct parser_params *parser, VALUE s)
5395 {
5396     char *beg, *end, *pend;
5397     rb_encoding *enc = must_be_ascii_compatible(s);
5398 
5399     beg = RSTRING_PTR(s);
5400     if (lex_gets_ptr) {
5401         if (RSTRING_LEN(s) == lex_gets_ptr) return Qnil;
5402         beg += lex_gets_ptr;
5403     }
5404     pend = RSTRING_PTR(s) + RSTRING_LEN(s);
5405     end = beg;
5406     while (end < pend) {
5407         if (*end++ == '\n') break;
5408     }
5409     lex_gets_ptr = end - RSTRING_PTR(s);
5410     return rb_enc_str_new(beg, end - beg, enc);
5411 }
5412 
5413 static VALUE
5414 lex_getline(struct parser_params *parser)
5415 {
5416     VALUE line = (*parser->parser_lex_gets)(parser, parser->parser_lex_input);
5417     if (NIL_P(line)) return line;
5418     must_be_ascii_compatible(line);
5419 #ifndef RIPPER
5420     if (ruby_debug_lines) {
5421         rb_enc_associate(line, current_enc);
5422         rb_ary_push(ruby_debug_lines, line);
5423     }
5424     if (ruby_coverage) {
5425         rb_ary_push(ruby_coverage, Qnil);
5426     }
5427 #endif
5428     return line;
5429 }
5430 
5431 #ifdef RIPPER
5432 static rb_data_type_t parser_data_type;
5433 #else
5434 static const rb_data_type_t parser_data_type;
5435 
5436 static NODE*
5437 parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
5438 {
5439     struct parser_params *parser;
5440     NODE *node;
5441 
5442     TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
5443     lex_gets = lex_get_str;
5444     lex_gets_ptr = 0;
5445     lex_input = s;
5446     lex_pbeg = lex_p = lex_pend = 0;
5447     compile_for_eval = rb_parse_in_eval();
5448 
5449     node = yycompile(parser, f, line);
5450     RB_GC_GUARD(vparser); /* prohibit tail call optimization */
5451 
5452     return node;
5453 }
5454 
5455 NODE*
5456 rb_compile_string(const char *f, VALUE s, int line)
5457 {
5458     must_be_ascii_compatible(s);
5459     return parser_compile_string(rb_parser_new(), f, s, line);
5460 }
5461 
5462 NODE*
5463 rb_parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
5464 {
5465     must_be_ascii_compatible(s);
5466     return parser_compile_string(vparser, f, s, line);
5467 }
5468 
5469 NODE*
5470 rb_compile_cstr(const char *f, const char *s, int len, int line)
5471 {
5472     VALUE str = rb_str_new(s, len);
5473     return parser_compile_string(rb_parser_new(), f, str, line);
5474 }
5475 
5476 NODE*
5477 rb_parser_compile_cstr(volatile VALUE vparser, const char *f, const char *s, int len, int line)
5478 {
5479     VALUE str = rb_str_new(s, len);
5480     return parser_compile_string(vparser, f, str, line);
5481 }
5482 
5483 static VALUE
5484 lex_io_gets(struct parser_params *parser, VALUE io)
5485 {
5486     return rb_io_gets(io);
5487 }
5488 
5489 NODE*
5490 rb_compile_file(const char *f, VALUE file, int start)
5491 {
5492     VALUE volatile vparser = rb_parser_new();
5493 
5494     return rb_parser_compile_file(vparser, f, file, start);
5495 }
5496 
5497 NODE*
5498 rb_parser_compile_file(volatile VALUE vparser, const char *f, VALUE file, int start)
5499 {
5500     struct parser_params *parser;
5501     NODE *node;
5502 
5503     TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
5504     lex_gets = lex_io_gets;
5505     lex_input = file;
5506     lex_pbeg = lex_p = lex_pend = 0;
5507     compile_for_eval = rb_parse_in_eval();
5508 
5509     node = yycompile(parser, f, start);
5510     RB_GC_GUARD(vparser); /* prohibit tail call optimization */
5511 
5512     return node;
5513 }
5514 #endif  /* !RIPPER */
5515 
5516 #define STR_FUNC_ESCAPE 0x01
5517 #define STR_FUNC_EXPAND 0x02
5518 #define STR_FUNC_REGEXP 0x04
5519 #define STR_FUNC_QWORDS 0x08
5520 #define STR_FUNC_SYMBOL 0x10
5521 #define STR_FUNC_INDENT 0x20
5522 
5523 enum string_type {
5524     str_squote = (0),
5525     str_dquote = (STR_FUNC_EXPAND),
5526     str_xquote = (STR_FUNC_EXPAND),
5527     str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
5528     str_sword  = (STR_FUNC_QWORDS),
5529     str_dword  = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
5530     str_ssym   = (STR_FUNC_SYMBOL),
5531     str_dsym   = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND)
5532 };
5533 
5534 static VALUE
5535 parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *enc0)
5536 {
5537     VALUE str;
5538 
5539     str = rb_enc_str_new(p, n, enc);
5540     if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
5541         if (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) {
5542         }
5543         else if (enc0 == rb_usascii_encoding() && enc != rb_utf8_encoding()) {
5544             rb_enc_associate(str, rb_ascii8bit_encoding());
5545         }
5546     }
5547 
5548     return str;
5549 }
5550 
5551 #define lex_goto_eol(parser) ((parser)->parser_lex_p = (parser)->parser_lex_pend)
5552 #define lex_eol_p() (lex_p >= lex_pend)
5553 #define peek(c) peek_n((c), 0)
5554 #define peek_n(c,n) (lex_p+(n) < lex_pend && (c) == (unsigned char)lex_p[n])
5555 
5556 static inline int
5557 parser_nextc(struct parser_params *parser)
5558 {
5559     int c;
5560 
5561     if (lex_p == lex_pend) {
5562         VALUE v = lex_nextline;
5563         lex_nextline = 0;
5564         if (!v) {
5565             if (parser->eofp)
5566                 return -1;
5567 
5568             if (!lex_input || NIL_P(v = lex_getline(parser))) {
5569                 parser->eofp = Qtrue;
5570                 lex_goto_eol(parser);
5571                 return -1;
5572             }
5573         }
5574         {
5575 #ifdef RIPPER
5576             if (parser->tokp < lex_pend) {
5577                 if (NIL_P(parser->delayed)) {
5578                     parser->delayed = rb_str_buf_new(1024);
5579                     rb_enc_associate(parser->delayed, current_enc);
5580                     rb_str_buf_cat(parser->delayed,
5581                                    parser->tokp, lex_pend - parser->tokp);
5582                     parser->delayed_line = ruby_sourceline;
5583                     parser->delayed_col = (int)(parser->tokp - lex_pbeg);
5584                 }
5585                 else {
5586                     rb_str_buf_cat(parser->delayed,
5587                                    parser->tokp, lex_pend - parser->tokp);
5588                 }
5589             }
5590 #endif
5591             if (heredoc_end > 0) {
5592                 ruby_sourceline = heredoc_end;
5593                 heredoc_end = 0;
5594             }
5595             ruby_sourceline++;
5596             parser->line_count++;
5597             lex_pbeg = lex_p = RSTRING_PTR(v);
5598             lex_pend = lex_p + RSTRING_LEN(v);
5599             ripper_flush(parser);
5600             lex_lastline = v;
5601         }
5602     }
5603     c = (unsigned char)*lex_p++;
5604     if (c == '\r' && peek('\n')) {
5605         lex_p++;
5606         c = '\n';
5607     }
5608 
5609     return c;
5610 }
5611 
5612 static void
5613 parser_pushback(struct parser_params *parser, int c)
5614 {
5615     if (c == -1) return;
5616     lex_p--;
5617     if (lex_p > lex_pbeg && lex_p[0] == '\n' && lex_p[-1] == '\r') {
5618         lex_p--;
5619     }
5620 }
5621 
5622 #define was_bol() (lex_p == lex_pbeg + 1)
5623 
5624 #define tokfix() (tokenbuf[tokidx]='\0')
5625 #define tok() tokenbuf
5626 #define toklen() tokidx
5627 #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
5628 
5629 static char*
5630 parser_newtok(struct parser_params *parser)
5631 {
5632     tokidx = 0;
5633     tokline = ruby_sourceline;
5634     if (!tokenbuf) {
5635         toksiz = 60;
5636         tokenbuf = ALLOC_N(char, 60);
5637     }
5638     if (toksiz > 4096) {
5639         toksiz = 60;
5640         REALLOC_N(tokenbuf, char, 60);
5641     }
5642     return tokenbuf;
5643 }
5644 
5645 static char *
5646 parser_tokspace(struct parser_params *parser, int n)
5647 {
5648     tokidx += n;
5649 
5650     if (tokidx >= toksiz) {
5651         do {toksiz *= 2;} while (toksiz < tokidx);
5652         REALLOC_N(tokenbuf, char, toksiz);
5653     }
5654     return &tokenbuf[tokidx-n];
5655 }
5656 
5657 static void
5658 parser_tokadd(struct parser_params *parser, int c)
5659 {
5660     tokenbuf[tokidx++] = (char)c;
5661     if (tokidx >= toksiz) {
5662         toksiz *= 2;
5663         REALLOC_N(tokenbuf, char, toksiz);
5664     }
5665 }
5666 
5667 static int
5668 parser_tok_hex(struct parser_params *parser, size_t *numlen)
5669 {
5670     int c;
5671 
5672     c = scan_hex(lex_p, 2, numlen);
5673     if (!*numlen) {
5674         yyerror("invalid hex escape");
5675         return 0;
5676     }
5677     lex_p += *numlen;
5678     return c;
5679 }
5680 
5681 #define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
5682 
5683 /* return value is for ?\u3042 */
5684 static int
5685 parser_tokadd_utf8(struct parser_params *parser, rb_encoding **encp,
5686                    int string_literal, int symbol_literal, int regexp_literal)
5687 {
5688     /*
5689      * If string_literal is true, then we allow multiple codepoints
5690      * in \u{}, and add the codepoints to the current token.
5691      * Otherwise we're parsing a character literal and return a single
5692      * codepoint without adding it
5693      */
5694 
5695     int codepoint;
5696     size_t numlen;
5697 
5698     if (regexp_literal) { tokadd('\\'); tokadd('u'); }
5699 
5700     if (peek('{')) {  /* handle \u{...} form */
5701         do {
5702             if (regexp_literal) { tokadd(*lex_p); }
5703             nextc();
5704             codepoint = scan_hex(lex_p, 6, &numlen);
5705             if (numlen == 0)  {
5706                 yyerror("invalid Unicode escape");
5707                 return 0;
5708             }
5709             if (codepoint > 0x10ffff) {
5710                 yyerror("invalid Unicode codepoint (too large)");
5711                 return 0;
5712             }
5713             lex_p += numlen;
5714             if (regexp_literal) {
5715                 tokcopy((int)numlen);
5716             }
5717             else if (codepoint >= 0x80) {
5718                 *encp = rb_utf8_encoding();
5719                 if (string_literal) tokaddmbc(codepoint, *encp);
5720             }
5721             else if (string_literal) {
5722                 tokadd(codepoint);
5723             }
5724         } while (string_literal && (peek(' ') || peek('\t')));
5725 
5726         if (!peek('}')) {
5727             yyerror("unterminated Unicode escape");
5728             return 0;
5729         }
5730 
5731         if (regexp_literal) { tokadd('}'); }
5732         nextc();
5733     }
5734     else {                      /* handle \uxxxx form */
5735         codepoint = scan_hex(lex_p, 4, &numlen);
5736         if (numlen < 4) {
5737             yyerror("invalid Unicode escape");
5738             return 0;
5739         }
5740         lex_p += 4;
5741         if (regexp_literal) {
5742             tokcopy(4);
5743         }
5744         else if (codepoint >= 0x80) {
5745             *encp = rb_utf8_encoding();
5746             if (string_literal) tokaddmbc(codepoint, *encp);
5747         }
5748         else if (string_literal) {
5749             tokadd(codepoint);
5750         }
5751     }
5752 
5753     return codepoint;
5754 }
5755 
5756 #define ESCAPE_CONTROL 1
5757 #define ESCAPE_META    2
5758 
5759 static int
5760 parser_read_escape(struct parser_params *parser, int flags,
5761                    rb_encoding **encp)
5762 {
5763     int c;
5764     size_t numlen;
5765 
5766     switch (c = nextc()) {
5767       case '\\':        /* Backslash */
5768         return c;
5769 
5770       case 'n': /* newline */
5771         return '\n';
5772 
5773       case 't': /* horizontal tab */
5774         return '\t';
5775 
5776       case 'r': /* carriage-return */
5777         return '\r';
5778 
5779       case 'f': /* form-feed */
5780         return '\f';
5781 
5782       case 'v': /* vertical tab */
5783         return '\13';
5784 
5785       case 'a': /* alarm(bell) */
5786         return '\007';
5787 
5788       case 'e': /* escape */
5789         return 033;
5790 
5791       case '0': case '1': case '2': case '3': /* octal constant */
5792       case '4': case '5': case '6': case '7':
5793         pushback(c);
5794         c = scan_oct(lex_p, 3, &numlen);
5795         lex_p += numlen;
5796         return c;
5797 
5798       case 'x': /* hex constant */
5799         c = tok_hex(&numlen);
5800         if (numlen == 0) return 0;
5801         return c;
5802 
5803       case 'b': /* backspace */
5804         return '\010';
5805 
5806       case 's': /* space */
5807         return ' ';
5808 
5809       case 'M':
5810         if (flags & ESCAPE_META) goto eof;
5811         if ((c = nextc()) != '-') {
5812             pushback(c);
5813             goto eof;
5814         }
5815         if ((c = nextc()) == '\\') {
5816             if (peek('u')) goto eof;
5817             return read_escape(flags|ESCAPE_META, encp) | 0x80;
5818         }
5819         else if (c == -1 || !ISASCII(c)) goto eof;
5820         else {
5821             return ((c & 0xff) | 0x80);
5822         }
5823 
5824       case 'C':
5825         if ((c = nextc()) != '-') {
5826             pushback(c);
5827             goto eof;
5828         }
5829       case 'c':
5830         if (flags & ESCAPE_CONTROL) goto eof;
5831         if ((c = nextc())== '\\') {
5832             if (peek('u')) goto eof;
5833             c = read_escape(flags|ESCAPE_CONTROL, encp);
5834         }
5835         else if (c == '?')
5836             return 0177;
5837         else if (c == -1 || !ISASCII(c)) goto eof;
5838         return c & 0x9f;
5839 
5840       eof:
5841       case -1:
5842         yyerror("Invalid escape character syntax");
5843         return '\0';
5844 
5845       default:
5846         return c;
5847     }
5848 }
5849 
5850 static void
5851 parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc)
5852 {
5853     int len = rb_enc_codelen(c, enc);
5854     rb_enc_mbcput(c, tokspace(len), enc);
5855 }
5856 
5857 static int
5858 parser_tokadd_escape(struct parser_params *parser, rb_encoding **encp)
5859 {
5860     int c;
5861     int flags = 0;
5862     size_t numlen;
5863 
5864   first:
5865     switch (c = nextc()) {
5866       case '\n':
5867         return 0;               /* just ignore */
5868 
5869       case '0': case '1': case '2': case '3': /* octal constant */
5870       case '4': case '5': case '6': case '7':
5871         {
5872             ruby_scan_oct(--lex_p, 3, &numlen);
5873             if (numlen == 0) goto eof;
5874             lex_p += numlen;
5875             tokcopy((int)numlen + 1);
5876         }
5877         return 0;
5878 
5879       case 'x': /* hex constant */
5880         {
5881             tok_hex(&numlen);
5882             if (numlen == 0) return -1;
5883             tokcopy((int)numlen + 2);
5884         }
5885         return 0;
5886 
5887       case 'M':
5888         if (flags & ESCAPE_META) goto eof;
5889         if ((c = nextc()) != '-') {
5890             pushback(c);
5891             goto eof;
5892         }
5893         tokcopy(3);
5894         flags |= ESCAPE_META;
5895         goto escaped;
5896 
5897       case 'C':
5898         if (flags & ESCAPE_CONTROL) goto eof;
5899         if ((c = nextc()) != '-') {
5900             pushback(c);
5901             goto eof;
5902         }
5903         tokcopy(3);
5904         goto escaped;
5905 
5906       case 'c':
5907         if (flags & ESCAPE_CONTROL) goto eof;
5908         tokcopy(2);
5909         flags |= ESCAPE_CONTROL;
5910       escaped:
5911         if ((c = nextc()) == '\\') {
5912             goto first;
5913         }
5914         else if (c == -1) goto eof;
5915         tokadd(c);
5916         return 0;
5917 
5918       eof:
5919       case -1:
5920         yyerror("Invalid escape character syntax");
5921         return -1;
5922 
5923       default:
5924         tokadd('\\');
5925         tokadd(c);
5926     }
5927     return 0;
5928 }
5929 
5930 static int
5931 parser_regx_options(struct parser_params *parser)
5932 {
5933     int kcode = 0;
5934     int kopt = 0;
5935     int options = 0;
5936     int c, opt, kc;
5937 
5938     newtok();
5939     while (c = nextc(), ISALPHA(c)) {
5940         if (c == 'o') {
5941             options |= RE_OPTION_ONCE;
5942         }
5943         else if (rb_char_to_option_kcode(c, &opt, &kc)) {
5944             if (kc >= 0) {
5945                 if (kc != rb_ascii8bit_encindex()) kcode = c;
5946                 kopt = opt;
5947             }
5948             else {
5949                 options |= opt;
5950             }
5951         }
5952         else {
5953             tokadd(c);
5954         }
5955     }
5956     options |= kopt;
5957     pushback(c);
5958     if (toklen()) {
5959         tokfix();
5960         compile_error(PARSER_ARG "unknown regexp option%s - %s",
5961                       toklen() > 1 ? "s" : "", tok());
5962     }
5963     return options | RE_OPTION_ENCODING(kcode);
5964 }
5965 
5966 static void
5967 dispose_string(VALUE str)
5968 {
5969     rb_str_free(str);
5970     rb_gc_force_recycle(str);
5971 }
5972 
5973 static int
5974 parser_tokadd_mbchar(struct parser_params *parser, int c)
5975 {
5976     int len = parser_precise_mbclen();
5977     if (!MBCLEN_CHARFOUND_P(len)) {
5978         compile_error(PARSER_ARG "invalid multibyte char (%s)", parser_encoding_name());
5979         return -1;
5980     }
5981     tokadd(c);
5982     lex_p += --len;
5983     if (len > 0) tokcopy(len);
5984     return c;
5985 }
5986 
5987 #define tokadd_mbchar(c) parser_tokadd_mbchar(parser, (c))
5988 
5989 static inline int
5990 simple_re_meta(int c)
5991 {
5992     switch (c) {
5993       case '$': case '*': case '+': case '.':
5994       case '?': case '^': case '|':
5995       case ')': case ']': case '}': case '>':
5996         return TRUE;
5997       default:
5998         return FALSE;
5999     }
6000 }
6001 
6002 static int
6003 parser_tokadd_string(struct parser_params *parser,
6004                      int func, int term, int paren, long *nest,
6005                      rb_encoding **encp)
6006 {
6007     int c;
6008     int has_nonascii = 0;
6009     rb_encoding *enc = *encp;
6010     char *errbuf = 0;
6011     static const char mixed_msg[] = "%s mixed within %s source";
6012 
6013 #define mixed_error(enc1, enc2) if (!errbuf) {  \
6014         size_t len = sizeof(mixed_msg) - 4;     \
6015         len += strlen(rb_enc_name(enc1));       \
6016         len += strlen(rb_enc_name(enc2));       \
6017         errbuf = ALLOCA_N(char, len);           \
6018         snprintf(errbuf, len, mixed_msg,        \
6019                  rb_enc_name(enc1),             \
6020                  rb_enc_name(enc2));            \
6021         yyerror(errbuf);                        \
6022     }
6023 #define mixed_escape(beg, enc1, enc2) do {      \
6024         const char *pos = lex_p;                \
6025         lex_p = (beg);                          \
6026         mixed_error((enc1), (enc2));            \
6027         lex_p = pos;                            \
6028     } while (0)
6029 
6030     while ((c = nextc()) != -1) {
6031         if (paren && c == paren) {
6032             ++*nest;
6033         }
6034         else if (c == term) {
6035             if (!nest || !*nest) {
6036                 pushback(c);
6037                 break;
6038             }
6039             --*nest;
6040         }
6041         else if ((func & STR_FUNC_EXPAND) && c == '#' && lex_p < lex_pend) {
6042             int c2 = *lex_p;
6043             if (c2 == '$' || c2 == '@' || c2 == '{') {
6044                 pushback(c);
6045                 break;
6046             }
6047         }
6048         else if (c == '\\') {
6049             const char *beg = lex_p - 1;
6050             c = nextc();
6051             switch (c) {
6052               case '\n':
6053                 if (func & STR_FUNC_QWORDS) break;
6054                 if (func & STR_FUNC_EXPAND) continue;
6055                 tokadd('\\');
6056                 break;
6057 
6058               case '\\':
6059                 if (func & STR_FUNC_ESCAPE) tokadd(c);
6060                 break;
6061 
6062               case 'u':
6063                 if ((func & STR_FUNC_EXPAND) == 0) {
6064                     tokadd('\\');
6065                     break;
6066                 }
6067                 parser_tokadd_utf8(parser, &enc, 1,
6068                                    func & STR_FUNC_SYMBOL,
6069                                    func & STR_FUNC_REGEXP);
6070                 if (has_nonascii && enc != *encp) {
6071                     mixed_escape(beg, enc, *encp);
6072                 }
6073                 continue;
6074 
6075               default:
6076                 if (c == -1) return -1;
6077                 if (!ISASCII(c)) {
6078                     if ((func & STR_FUNC_EXPAND) == 0) tokadd('\\');
6079                     goto non_ascii;
6080                 }
6081                 if (func & STR_FUNC_REGEXP) {
6082                     if (c == term && !simple_re_meta(c)) {
6083                         tokadd(c);
6084                         continue;
6085                     }
6086                     pushback(c);
6087                     if ((c = tokadd_escape(&enc)) < 0)
6088                         return -1;
6089                     if (has_nonascii && enc != *encp) {
6090                         mixed_escape(beg, enc, *encp);
6091                     }
6092                     continue;
6093                 }
6094                 else if (func & STR_FUNC_EXPAND) {
6095                     pushback(c);
6096                     if (func & STR_FUNC_ESCAPE) tokadd('\\');
6097                     c = read_escape(0, &enc);
6098                 }
6099                 else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6100                     /* ignore backslashed spaces in %w */
6101                 }
6102                 else if (c != term && !(paren && c == paren)) {
6103                     tokadd('\\');
6104                     pushback(c);
6105                     continue;
6106                 }
6107             }
6108         }
6109         else if (!parser_isascii()) {
6110           non_ascii:
6111             has_nonascii = 1;
6112             if (enc != *encp) {
6113                 mixed_error(enc, *encp);
6114                 continue;
6115             }
6116             if (tokadd_mbchar(c) == -1) return -1;
6117             continue;
6118         }
6119         else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6120             pushback(c);
6121             break;
6122         }
6123         if (c & 0x80) {
6124             has_nonascii = 1;
6125             if (enc != *encp) {
6126                 mixed_error(enc, *encp);
6127                 continue;
6128             }
6129         }
6130         tokadd(c);
6131     }
6132     *encp = enc;
6133     return c;
6134 }
6135 
6136 #define NEW_STRTERM(func, term, paren) \
6137         rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
6138 
6139 #ifdef RIPPER
6140 static void
6141 ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc)
6142 {
6143     if (!NIL_P(parser->delayed)) {
6144         ptrdiff_t len = lex_p - parser->tokp;
6145         if (len > 0) {
6146             rb_enc_str_buf_cat(parser->delayed, parser->tokp, len, enc);
6147         }
6148         ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6149         parser->tokp = lex_p;
6150     }
6151 }
6152 
6153 #define flush_string_content(enc) ripper_flush_string_content(parser, (enc))
6154 #else
6155 #define flush_string_content(enc) ((void)(enc))
6156 #endif
6157 
6158 RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
6159 /* this can be shared with ripper, since it's independent from struct
6160  * parser_params. */
6161 #ifndef RIPPER
6162 #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
6163 #define SPECIAL_PUNCT(idx) ( \
6164         BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
6165         BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
6166         BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
6167         BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
6168         BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
6169         BIT('0', idx))
6170 const unsigned int ruby_global_name_punct_bits[] = {
6171     SPECIAL_PUNCT(0),
6172     SPECIAL_PUNCT(1),
6173     SPECIAL_PUNCT(2),
6174 };
6175 #undef BIT
6176 #undef SPECIAL_PUNCT
6177 #endif
6178 
6179 static inline int
6180 is_global_name_punct(const int c)
6181 {
6182     if (c <= 0x20 || 0x7e < c) return 0;
6183     return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
6184 }
6185 
6186 static int
6187 parser_peek_variable_name(struct parser_params *parser)
6188 {
6189     int c;
6190     const char *p = lex_p;
6191 
6192     if (p + 1 >= lex_pend) return 0;
6193     c = *p++;
6194     switch (c) {
6195       case '$':
6196         if ((c = *p) == '-') {
6197             if (++p >= lex_pend) return 0;
6198             c = *p;
6199         }
6200         else if (is_global_name_punct(c) || ISDIGIT(c)) {
6201             return tSTRING_DVAR;
6202         }
6203         break;
6204       case '@':
6205         if ((c = *p) == '@') {
6206             if (++p >= lex_pend) return 0;
6207             c = *p;
6208         }
6209         break;
6210       case '{':
6211         lex_p = p;
6212         command_start = TRUE;
6213         return tSTRING_DBEG;
6214       default:
6215         return 0;
6216     }
6217     if (!ISASCII(c) || c == '_' || ISALPHA(c))
6218         return tSTRING_DVAR;
6219     return 0;
6220 }
6221 
6222 static int
6223 parser_parse_string(struct parser_params *parser, NODE *quote)
6224 {
6225     int func = (int)quote->nd_func;
6226     int term = nd_term(quote);
6227     int paren = nd_paren(quote);
6228     int c, space = 0;
6229     rb_encoding *enc = current_enc;
6230 
6231     if (func == -1) return tSTRING_END;
6232     c = nextc();
6233     if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
6234         do {c = nextc();} while (ISSPACE(c));
6235         space = 1;
6236     }
6237     if (c == term && !quote->nd_nest) {
6238         if (func & STR_FUNC_QWORDS) {
6239             quote->nd_func = -1;
6240             return ' ';
6241         }
6242         if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
6243         set_yylval_num(regx_options());
6244         return tREGEXP_END;
6245     }
6246     if (space) {
6247         pushback(c);
6248         return ' ';
6249     }
6250     newtok();
6251     if ((func & STR_FUNC_EXPAND) && c == '#') {
6252         int t = parser_peek_variable_name(parser);
6253         if (t) return t;
6254         tokadd('#');
6255         c = nextc();
6256     }
6257     pushback(c);
6258     if (tokadd_string(func, term, paren, &quote->nd_nest,
6259                       &enc) == -1) {
6260         ruby_sourceline = nd_line(quote);
6261         if (func & STR_FUNC_REGEXP) {
6262             if (parser->eofp)
6263                 compile_error(PARSER_ARG "unterminated regexp meets end of file");
6264             return tREGEXP_END;
6265         }
6266         else {
6267             if (parser->eofp)
6268                 compile_error(PARSER_ARG "unterminated string meets end of file");
6269             return tSTRING_END;
6270         }
6271     }
6272 
6273     tokfix();
6274     set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
6275     flush_string_content(enc);
6276 
6277     return tSTRING_CONTENT;
6278 }
6279 
6280 static int
6281 parser_heredoc_identifier(struct parser_params *parser)
6282 {
6283     int c = nextc(), term, func = 0;
6284     long len;
6285 
6286     if (c == '-') {
6287         c = nextc();
6288         func = STR_FUNC_INDENT;
6289     }
6290     switch (c) {
6291       case '\'':
6292         func |= str_squote; goto quoted;
6293       case '"':
6294         func |= str_dquote; goto quoted;
6295       case '`':
6296         func |= str_xquote;
6297       quoted:
6298         newtok();
6299         tokadd(func);
6300         term = c;
6301         while ((c = nextc()) != -1 && c != term) {
6302             if (tokadd_mbchar(c) == -1) return 0;
6303         }
6304         if (c == -1) {
6305             compile_error(PARSER_ARG "unterminated here document identifier");
6306             return 0;
6307         }
6308         break;
6309 
6310       default:
6311         if (!parser_is_identchar()) {
6312             pushback(c);
6313             if (func & STR_FUNC_INDENT) {
6314                 pushback('-');
6315             }
6316             return 0;
6317         }
6318         newtok();
6319         term = '"';
6320         tokadd(func |= str_dquote);
6321         do {
6322             if (tokadd_mbchar(c) == -1) return 0;
6323         } while ((c = nextc()) != -1 && parser_is_identchar());
6324         pushback(c);
6325         break;
6326     }
6327 
6328     tokfix();
6329 #ifdef RIPPER
6330     ripper_dispatch_scan_event(parser, tHEREDOC_BEG);
6331 #endif
6332     len = lex_p - lex_pbeg;
6333     lex_goto_eol(parser);
6334     lex_strterm = rb_node_newnode(NODE_HEREDOC,
6335                                   STR_NEW(tok(), toklen()),     /* nd_lit */
6336                                   len,                          /* nd_nth */
6337                                   lex_lastline);                /* nd_orig */
6338     nd_set_line(lex_strterm, ruby_sourceline);
6339     ripper_flush(parser);
6340     return term == '`' ? tXSTRING_BEG : tSTRING_BEG;
6341 }
6342 
6343 static void
6344 parser_heredoc_restore(struct parser_params *parser, NODE *here)
6345 {
6346     VALUE line;
6347 
6348     lex_strterm = 0;
6349     line = here->nd_orig;
6350     lex_lastline = line;
6351     lex_pbeg = RSTRING_PTR(line);
6352     lex_pend = lex_pbeg + RSTRING_LEN(line);
6353     lex_p = lex_pbeg + here->nd_nth;
6354     heredoc_end = ruby_sourceline;
6355     ruby_sourceline = nd_line(here);
6356     dispose_string(here->nd_lit);
6357     rb_gc_force_recycle((VALUE)here);
6358     ripper_flush(parser);
6359 }
6360 
6361 static int
6362 parser_whole_match_p(struct parser_params *parser,
6363     const char *eos, long len, int indent)
6364 {
6365     const char *p = lex_pbeg;
6366     long n;
6367 
6368     if (indent) {
6369         while (*p && ISSPACE(*p)) p++;
6370     }
6371     n = lex_pend - (p + len);
6372     if (n < 0 || (n > 0 && p[len] != '\n' && p[len] != '\r')) return FALSE;
6373     return strncmp(eos, p, len) == 0;
6374 }
6375 
6376 #ifdef RIPPER
6377 static void
6378 ripper_dispatch_heredoc_end(struct parser_params *parser)
6379 {
6380     if (!NIL_P(parser->delayed))
6381         ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6382     lex_goto_eol(parser);
6383     ripper_dispatch_ignored_scan_event(parser, tHEREDOC_END);
6384 }
6385 
6386 #define dispatch_heredoc_end() ripper_dispatch_heredoc_end(parser)
6387 #else
6388 #define dispatch_heredoc_end() ((void)0)
6389 #endif
6390 
6391 static int
6392 parser_here_document(struct parser_params *parser, NODE *here)
6393 {
6394     int c, func, indent = 0;
6395     const char *eos, *p, *pend;
6396     long len;
6397     VALUE str = 0;
6398     rb_encoding *enc = current_enc;
6399 
6400     eos = RSTRING_PTR(here->nd_lit);
6401     len = RSTRING_LEN(here->nd_lit) - 1;
6402     indent = (func = *eos++) & STR_FUNC_INDENT;
6403 
6404     if ((c = nextc()) == -1) {
6405       error:
6406         compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
6407 #ifdef RIPPER
6408         if (NIL_P(parser->delayed)) {
6409             ripper_dispatch_scan_event(parser, tSTRING_CONTENT);
6410         }
6411         else {
6412             if (str ||
6413                 ((len = lex_p - parser->tokp) > 0 &&
6414                  (str = STR_NEW3(parser->tokp, len, enc, func), 1))) {
6415                 rb_str_append(parser->delayed, str);
6416             }
6417             ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
6418         }
6419         lex_goto_eol(parser);
6420 #endif
6421       restore:
6422         heredoc_restore(lex_strterm);
6423         return 0;
6424     }
6425     if (was_bol() && whole_match_p(eos, len, indent)) {
6426         dispatch_heredoc_end();
6427         heredoc_restore(lex_strterm);
6428         return tSTRING_END;
6429     }
6430 
6431     if (!(func & STR_FUNC_EXPAND)) {
6432         do {
6433             p = RSTRING_PTR(lex_lastline);
6434             pend = lex_pend;
6435             if (pend > p) {
6436                 switch (pend[-1]) {
6437                   case '\n':
6438                     if (--pend == p || pend[-1] != '\r') {
6439                         pend++;
6440                         break;
6441                     }
6442                   case '\r':
6443                     --pend;
6444                 }
6445             }
6446             if (str)
6447                 rb_str_cat(str, p, pend - p);
6448             else
6449                 str = STR_NEW(p, pend - p);
6450             if (pend < lex_pend) rb_str_cat(str, "\n", 1);
6451             lex_goto_eol(parser);
6452             if (nextc() == -1) {
6453                 if (str) dispose_string(str);
6454                 goto error;
6455             }
6456         } while (!whole_match_p(eos, len, indent));
6457     }
6458     else {
6459         /*      int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
6460         newtok();
6461         if (c == '#') {
6462             int t = parser_peek_variable_name(parser);
6463             if (t) return t;
6464             tokadd('#');
6465             c = nextc();
6466         }
6467         do {
6468             pushback(c);
6469             if ((c = tokadd_string(func, '\n', 0, NULL, &enc)) == -1) {
6470                 if (parser->eofp) goto error;
6471                 goto restore;
6472             }
6473             if (c != '\n') {
6474                 set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
6475                 flush_string_content(enc);
6476                 return tSTRING_CONTENT;
6477             }
6478             tokadd(nextc());
6479             /*      if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
6480             if ((c = nextc()) == -1) goto error;
6481         } while (!whole_match_p(eos, len, indent));
6482         str = STR_NEW3(tok(), toklen(), enc, func);
6483     }
6484     dispatch_heredoc_end();
6485     heredoc_restore(lex_strterm);
6486     lex_strterm = NEW_STRTERM(-1, 0, 0);
6487     set_yylval_str(str);
6488     return tSTRING_CONTENT;
6489 }
6490 
6491 #include "lex.c"
6492 
6493 static void
6494 arg_ambiguous_gen(struct parser_params *parser)
6495 {
6496 #ifndef RIPPER
6497     rb_warning0("ambiguous first argument; put parentheses or even spaces");
6498 #else
6499     dispatch0(arg_ambiguous);
6500 #endif
6501 }
6502 #define arg_ambiguous() (arg_ambiguous_gen(parser), 1)
6503 
6504 static ID
6505 formal_argument_gen(struct parser_params *parser, ID lhs)
6506 {
6507 #ifndef RIPPER
6508     if (!is_local_id(lhs))
6509         yyerror("formal argument must be local variable");
6510 #endif
6511     shadowing_lvar(lhs);
6512     return lhs;
6513 }
6514 
6515 static int
6516 lvar_defined_gen(struct parser_params *parser, ID id)
6517 {
6518     return (dyna_in_block() && dvar_defined_get(id)) || local_id(id);
6519 }
6520 
6521 /* emacsen -*- hack */
6522 static long
6523 parser_encode_length(struct parser_params *parser, const char *name, long len)
6524 {
6525     long nlen;
6526 
6527     if (len > 5 && name[nlen = len - 5] == '-') {
6528         if (rb_memcicmp(name + nlen + 1, "unix", 4) == 0)
6529             return nlen;
6530     }
6531     if (len > 4 && name[nlen = len - 4] == '-') {
6532         if (rb_memcicmp(name + nlen + 1, "dos", 3) == 0)
6533             return nlen;
6534         if (rb_memcicmp(name + nlen + 1, "mac", 3) == 0 &&
6535             !(len == 8 && rb_memcicmp(name, "utf8-mac", len) == 0))
6536             /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
6537             return nlen;
6538     }
6539     return len;
6540 }
6541 
6542 static void
6543 parser_set_encode(struct parser_params *parser, const char *name)
6544 {
6545     int idx = rb_enc_find_index(name);
6546     rb_encoding *enc;
6547     VALUE excargs[3];
6548 
6549     if (idx < 0) {
6550         excargs[1] = rb_sprintf("unknown encoding name: %s", name);
6551       error:
6552         excargs[0] = rb_eArgError;
6553         excargs[2] = rb_make_backtrace();
6554         rb_ary_unshift(excargs[2], rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline));
6555         rb_exc_raise(rb_make_exception(3, excargs));
6556     }
6557     enc = rb_enc_from_index(idx);
6558     if (!rb_enc_asciicompat(enc)) {
6559         excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
6560         goto error;
6561     }
6562     parser->enc = enc;
6563 #ifndef RIPPER
6564     if (ruby_debug_lines) {
6565         VALUE lines = ruby_debug_lines;
6566         long i, n = RARRAY_LEN(lines);
6567         for (i = 0; i < n; ++i) {
6568             rb_enc_associate_index(RARRAY_AREF(lines, i), idx);
6569         }
6570     }
6571 #endif
6572 }
6573 
6574 static int
6575 comment_at_top(struct parser_params *parser)
6576 {
6577     const char *p = lex_pbeg, *pend = lex_p - 1;
6578     if (parser->line_count != (parser->has_shebang ? 2 : 1)) return 0;
6579     while (p < pend) {
6580         if (!ISSPACE(*p)) return 0;
6581         p++;
6582     }
6583     return 1;
6584 }
6585 
6586 #ifndef RIPPER
6587 typedef long (*rb_magic_comment_length_t)(struct parser_params *parser, const char *name, long len);
6588 typedef void (*rb_magic_comment_setter_t)(struct parser_params *parser, const char *name, const char *val);
6589 
6590 static void
6591 magic_comment_encoding(struct parser_params *parser, const char *name, const char *val)
6592 {
6593     if (!comment_at_top(parser)) {
6594         return;
6595     }
6596     parser_set_encode(parser, val);
6597 }
6598 
6599 static void
6600 parser_set_token_info(struct parser_params *parser, const char *name, const char *val)
6601 {
6602     int *p = &parser->parser_token_info_enabled;
6603 
6604     switch (*val) {
6605       case 't': case 'T':
6606         if (strcasecmp(val, "true") == 0) {
6607             *p = TRUE;
6608             return;
6609         }
6610         break;
6611       case 'f': case 'F':
6612         if (strcasecmp(val, "false") == 0) {
6613             *p = FALSE;
6614             return;
6615         }
6616         break;
6617     }
6618     rb_compile_warning(ruby_sourcefile, ruby_sourceline, "invalid value for %s: %s", name, val);
6619 }
6620 
6621 struct magic_comment {
6622     const char *name;
6623     rb_magic_comment_setter_t func;
6624     rb_magic_comment_length_t length;
6625 };
6626 
6627 static const struct magic_comment magic_comments[] = {
6628     {"coding", magic_comment_encoding, parser_encode_length},
6629     {"encoding", magic_comment_encoding, parser_encode_length},
6630     {"warn_indent", parser_set_token_info},
6631 };
6632 #endif
6633 
6634 static const char *
6635 magic_comment_marker(const char *str, long len)
6636 {
6637     long i = 2;
6638 
6639     while (i < len) {
6640         switch (str[i]) {
6641           case '-':
6642             if (str[i-1] == '*' && str[i-2] == '-') {
6643                 return str + i + 1;
6644             }
6645             i += 2;
6646             break;
6647           case '*':
6648             if (i + 1 >= len) return 0;
6649             if (str[i+1] != '-') {
6650                 i += 4;
6651             }
6652             else if (str[i-1] != '-') {
6653                 i += 2;
6654             }
6655             else {
6656                 return str + i + 2;
6657             }
6658             break;
6659           default:
6660             i += 3;
6661             break;
6662         }
6663     }
6664     return 0;
6665 }
6666 
6667 static int
6668 parser_magic_comment(struct parser_params *parser, const char *str, long len)
6669 {
6670     VALUE name = 0, val = 0;
6671     const char *beg, *end, *vbeg, *vend;
6672 #define str_copy(_s, _p, _n) ((_s) \
6673         ? (void)(rb_str_resize((_s), (_n)), \
6674            MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
6675         : (void)((_s) = STR_NEW((_p), (_n))))
6676 
6677     if (len <= 7) return FALSE;
6678     if (!(beg = magic_comment_marker(str, len))) return FALSE;
6679     if (!(end = magic_comment_marker(beg, str + len - beg))) return FALSE;
6680     str = beg;
6681     len = end - beg - 3;
6682 
6683     /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
6684     while (len > 0) {
6685 #ifndef RIPPER
6686         const struct magic_comment *p = magic_comments;
6687 #endif
6688         char *s;
6689         int i;
6690         long n = 0;
6691 
6692         for (; len > 0 && *str; str++, --len) {
6693             switch (*str) {
6694               case '\'': case '"': case ':': case ';':
6695                 continue;
6696             }
6697             if (!ISSPACE(*str)) break;
6698         }
6699         for (beg = str; len > 0; str++, --len) {
6700             switch (*str) {
6701               case '\'': case '"': case ':': case ';':
6702                 break;
6703               default:
6704                 if (ISSPACE(*str)) break;
6705                 continue;
6706             }
6707             break;
6708         }
6709         for (end = str; len > 0 && ISSPACE(*str); str++, --len);
6710         if (!len) break;
6711         if (*str != ':') continue;
6712 
6713         do str++; while (--len > 0 && ISSPACE(*str));
6714         if (!len) break;
6715         if (*str == '"') {
6716             for (vbeg = ++str; --len > 0 && *str != '"'; str++) {
6717                 if (*str == '\\') {
6718                     --len;
6719                     ++str;
6720                 }
6721             }
6722             vend = str;
6723             if (len) {
6724                 --len;
6725                 ++str;
6726             }
6727         }
6728         else {
6729             for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
6730             vend = str;
6731         }
6732         while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
6733 
6734         n = end - beg;
6735         str_copy(name, beg, n);
6736         s = RSTRING_PTR(name);
6737         for (i = 0; i < n; ++i) {
6738             if (s[i] == '-') s[i] = '_';
6739         }
6740 #ifndef RIPPER
6741         do {
6742             if (STRNCASECMP(p->name, s, n) == 0) {
6743                 n = vend - vbeg;
6744                 if (p->length) {
6745                     n = (*p->length)(parser, vbeg, n);
6746                 }
6747                 str_copy(val, vbeg, n);
6748                 (*p->func)(parser, s, RSTRING_PTR(val));
6749                 break;
6750             }
6751         } while (++p < magic_comments + numberof(magic_comments));
6752 #else
6753         str_copy(val, vbeg, vend - vbeg);
6754         dispatch2(magic_comment, name, val);
6755 #endif
6756     }
6757 
6758     return TRUE;
6759 }
6760 
6761 static void
6762 set_file_encoding(struct parser_params *parser, const char *str, const char *send)
6763 {
6764     int sep = 0;
6765     const char *beg = str;
6766     VALUE s;
6767 
6768     for (;;) {
6769         if (send - str <= 6) return;
6770         switch (str[6]) {
6771           case 'C': case 'c': str += 6; continue;
6772           case 'O': case 'o': str += 5; continue;
6773           case 'D': case 'd': str += 4; continue;
6774           case 'I': case 'i': str += 3; continue;
6775           case 'N': case 'n': str += 2; continue;
6776           case 'G': case 'g': str += 1; continue;
6777           case '=': case ':':
6778             sep = 1;
6779             str += 6;
6780             break;
6781           default:
6782             str += 6;
6783             if (ISSPACE(*str)) break;
6784             continue;
6785         }
6786         if (STRNCASECMP(str-6, "coding", 6) == 0) break;
6787     }
6788     for (;;) {
6789         do {
6790             if (++str >= send) return;
6791         } while (ISSPACE(*str));
6792         if (sep) break;
6793         if (*str != '=' && *str != ':') return;
6794         sep = 1;
6795         str++;
6796     }
6797     beg = str;
6798     while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
6799     s = rb_str_new(beg, parser_encode_length(parser, beg, str - beg));
6800     parser_set_encode(parser, RSTRING_PTR(s));
6801     rb_str_resize(s, 0);
6802 }
6803 
6804 static void
6805 parser_prepare(struct parser_params *parser)
6806 {
6807     int c = nextc();
6808     switch (c) {
6809       case '#':
6810         if (peek('!')) parser->has_shebang = 1;
6811         break;
6812       case 0xef:                /* UTF-8 BOM marker */
6813         if (lex_pend - lex_p >= 2 &&
6814             (unsigned char)lex_p[0] == 0xbb &&
6815             (unsigned char)lex_p[1] == 0xbf) {
6816             parser->enc = rb_utf8_encoding();
6817             lex_p += 2;
6818             lex_pbeg = lex_p;
6819             return;
6820         }
6821         break;
6822       case EOF:
6823         return;
6824     }
6825     pushback(c);
6826     parser->enc = rb_enc_get(lex_lastline);
6827 }
6828 
6829 #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
6830 #define IS_END() IS_lex_state(EXPR_END_ANY)
6831 #define IS_BEG() IS_lex_state(EXPR_BEG_ANY)
6832 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
6833 #define IS_LABEL_POSSIBLE() ((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !cmd_state) || IS_ARG())
6834 #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
6835 #define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
6836 
6837 #ifndef RIPPER
6838 #define ambiguous_operator(op, syn) ( \
6839     rb_warning0("`"op"' after local variable or literal is interpreted as binary operator"), \
6840     rb_warning0("even though it seems like "syn""))
6841 #else
6842 #define ambiguous_operator(op, syn) dispatch2(operator_ambiguous, ripper_intern(op), rb_str_new_cstr(syn))
6843 #endif
6844 #define warn_balanced(op, syn) ((void) \
6845     (!IS_lex_state_for(last_state, EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN|EXPR_ENDARG) && \
6846      space_seen && !ISSPACE(c) && \
6847      (ambiguous_operator(op, syn), 0)))
6848 
6849 static int
6850 parser_yylex(struct parser_params *parser)
6851 {
6852     register int c;
6853     int space_seen = 0;
6854     int cmd_state;
6855     enum lex_state_e last_state;
6856     rb_encoding *enc;
6857     int mb;
6858 #ifdef RIPPER
6859     int fallthru = FALSE;
6860 #endif
6861 
6862     if (lex_strterm) {
6863         int token;
6864         if (nd_type(lex_strterm) == NODE_HEREDOC) {
6865             token = here_document(lex_strterm);
6866             if (token == tSTRING_END) {
6867                 lex_strterm = 0;
6868                 lex_state = EXPR_END;
6869             }
6870         }
6871         else {
6872             token = parse_string(lex_strterm);
6873             if (token == tSTRING_END || token == tREGEXP_END) {
6874                 rb_gc_force_recycle((VALUE)lex_strterm);
6875                 lex_strterm = 0;
6876                 lex_state = EXPR_END;
6877             }
6878         }
6879         return token;
6880     }
6881     cmd_state = command_start;
6882     command_start = FALSE;
6883   retry:
6884     last_state = lex_state;
6885     switch (c = nextc()) {
6886       case '\0':                /* NUL */
6887       case '\004':              /* ^D */
6888       case '\032':              /* ^Z */
6889       case -1:                  /* end of script. */
6890         return 0;
6891 
6892         /* white spaces */
6893       case ' ': case '\t': case '\f': case '\r':
6894       case '\13': /* '\v' */
6895         space_seen = 1;
6896 #ifdef RIPPER
6897         while ((c = nextc())) {
6898             switch (c) {
6899               case ' ': case '\t': case '\f': case '\r':
6900               case '\13': /* '\v' */
6901                 break;
6902               default:
6903                 goto outofloop;
6904             }
6905         }
6906       outofloop:
6907         pushback(c);
6908         ripper_dispatch_scan_event(parser, tSP);
6909 #endif
6910         goto retry;
6911 
6912       case '#':         /* it's a comment */
6913         /* no magic_comment in shebang line */
6914         if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
6915             if (comment_at_top(parser)) {
6916                 set_file_encoding(parser, lex_p, lex_pend);
6917             }
6918         }
6919         lex_p = lex_pend;
6920 #ifdef RIPPER
6921         ripper_dispatch_scan_event(parser, tCOMMENT);
6922         fallthru = TRUE;
6923 #endif
6924         /* fall through */
6925       case '\n':
6926         if (IS_lex_state(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT)) {
6927 #ifdef RIPPER
6928             if (!fallthru) {
6929                 ripper_dispatch_scan_event(parser, tIGNORED_NL);
6930             }
6931             fallthru = FALSE;
6932 #endif
6933             goto retry;
6934         }
6935         while ((c = nextc())) {
6936             switch (c) {
6937               case ' ': case '\t': case '\f': case '\r':
6938               case '\13': /* '\v' */
6939                 space_seen = 1;
6940                 break;
6941               case '.': {
6942                   if ((c = nextc()) != '.') {
6943                       pushback(c);
6944                       pushback('.');
6945                       goto retry;
6946                   }
6947               }
6948               default:
6949                 --ruby_sourceline;
6950                 lex_nextline = lex_lastline;
6951               case -1:          /* EOF no decrement*/
6952                 lex_goto_eol(parser);
6953 #ifdef RIPPER
6954                 if (c != -1) {
6955                     parser->tokp = lex_p;
6956                 }
6957 #endif
6958                 goto normal_newline;
6959             }
6960         }
6961       normal_newline:
6962         command_start = TRUE;
6963         lex_state = EXPR_BEG;
6964         return '\n';
6965 
6966       case '*':
6967         if ((c = nextc()) == '*') {
6968             if ((c = nextc()) == '=') {
6969                 set_yylval_id(tPOW);
6970                 lex_state = EXPR_BEG;
6971                 return tOP_ASGN;
6972             }
6973             pushback(c);
6974             if (IS_SPCARG(c)) {
6975                 rb_warning0("`**' interpreted as argument prefix");
6976                 c = tDSTAR;
6977             }
6978             else if (IS_BEG()) {
6979                 c = tDSTAR;
6980             }
6981             else {
6982                 warn_balanced("**", "argument prefix");
6983                 c = tPOW;
6984             }
6985         }
6986         else {
6987             if (c == '=') {
6988                 set_yylval_id('*');
6989                 lex_state = EXPR_BEG;
6990                 return tOP_ASGN;
6991             }
6992             pushback(c);
6993             if (IS_SPCARG(c)) {
6994                 rb_warning0("`*' interpreted as argument prefix");
6995                 c = tSTAR;
6996             }
6997             else if (IS_BEG()) {
6998                 c = tSTAR;
6999             }
7000             else {
7001                 warn_balanced("*", "argument prefix");
7002                 c = '*';
7003             }
7004         }
7005         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7006         return c;
7007 
7008       case '!':
7009         c = nextc();
7010         if (IS_AFTER_OPERATOR()) {
7011             lex_state = EXPR_ARG;
7012             if (c == '@') {
7013                 return '!';
7014             }
7015         }
7016         else {
7017             lex_state = EXPR_BEG;
7018         }
7019         if (c == '=') {
7020             return tNEQ;
7021         }
7022         if (c == '~') {
7023             return tNMATCH;
7024         }
7025         pushback(c);
7026         return '!';
7027 
7028       case '=':
7029         if (was_bol()) {
7030             /* skip embedded rd document */
7031             if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
7032 #ifdef RIPPER
7033                 int first_p = TRUE;
7034 
7035                 lex_goto_eol(parser);
7036                 ripper_dispatch_scan_event(parser, tEMBDOC_BEG);
7037 #endif
7038                 for (;;) {
7039                     lex_goto_eol(parser);
7040 #ifdef RIPPER
7041                     if (!first_p) {
7042                         ripper_dispatch_scan_event(parser, tEMBDOC);
7043                     }
7044                     first_p = FALSE;
7045 #endif
7046                     c = nextc();
7047                     if (c == -1) {
7048                         compile_error(PARSER_ARG "embedded document meets end of file");
7049                         return 0;
7050                     }
7051                     if (c != '=') continue;
7052                     if (strncmp(lex_p, "end", 3) == 0 &&
7053                         (lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {
7054                         break;
7055                     }
7056                 }
7057                 lex_goto_eol(parser);
7058 #ifdef RIPPER
7059                 ripper_dispatch_scan_event(parser, tEMBDOC_END);
7060 #endif
7061                 goto retry;
7062             }
7063         }
7064 
7065         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7066         if ((c = nextc()) == '=') {
7067             if ((c = nextc()) == '=') {
7068                 return tEQQ;
7069             }
7070             pushback(c);
7071             return tEQ;
7072         }
7073         if (c == '~') {
7074             return tMATCH;
7075         }
7076         else if (c == '>') {
7077             return tASSOC;
7078         }
7079         pushback(c);
7080         return '=';
7081 
7082       case '<':
7083         last_state = lex_state;
7084         c = nextc();
7085         if (c == '<' &&
7086             !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
7087             !IS_END() &&
7088             (!IS_ARG() || space_seen)) {
7089             int token = heredoc_identifier();
7090             if (token) return token;
7091         }
7092         if (IS_AFTER_OPERATOR()) {
7093             lex_state = EXPR_ARG;
7094         }
7095         else {
7096             if (IS_lex_state(EXPR_CLASS))
7097                 command_start = TRUE;
7098             lex_state = EXPR_BEG;
7099         }
7100         if (c == '=') {
7101             if ((c = nextc()) == '>') {
7102                 return tCMP;
7103             }
7104             pushback(c);
7105             return tLEQ;
7106         }
7107         if (c == '<') {
7108             if ((c = nextc()) == '=') {
7109                 set_yylval_id(tLSHFT);
7110                 lex_state = EXPR_BEG;
7111                 return tOP_ASGN;
7112             }
7113             pushback(c);
7114             warn_balanced("<<", "here document");
7115             return tLSHFT;
7116         }
7117         pushback(c);
7118         return '<';
7119 
7120       case '>':
7121         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7122         if ((c = nextc()) == '=') {
7123             return tGEQ;
7124         }
7125         if (c == '>') {
7126             if ((c = nextc()) == '=') {
7127                 set_yylval_id(tRSHFT);
7128                 lex_state = EXPR_BEG;
7129                 return tOP_ASGN;
7130             }
7131             pushback(c);
7132             return tRSHFT;
7133         }
7134         pushback(c);
7135         return '>';
7136 
7137       case '"':
7138         lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
7139         return tSTRING_BEG;
7140 
7141       case '`':
7142         if (IS_lex_state(EXPR_FNAME)) {
7143             lex_state = EXPR_ENDFN;
7144             return c;
7145         }
7146         if (IS_lex_state(EXPR_DOT)) {
7147             if (cmd_state)
7148                 lex_state = EXPR_CMDARG;
7149             else
7150                 lex_state = EXPR_ARG;
7151             return c;
7152         }
7153         lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
7154         return tXSTRING_BEG;
7155 
7156       case '\'':
7157         lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
7158         return tSTRING_BEG;
7159 
7160       case '?':
7161         if (IS_END()) {
7162             lex_state = EXPR_VALUE;
7163             return '?';
7164         }
7165         c = nextc();
7166         if (c == -1) {
7167             compile_error(PARSER_ARG "incomplete character syntax");
7168             return 0;
7169         }
7170         if (rb_enc_isspace(c, current_enc)) {
7171             if (!IS_ARG()) {
7172                 int c2 = 0;
7173                 switch (c) {
7174                   case ' ':
7175                     c2 = 's';
7176                     break;
7177                   case '\n':
7178                     c2 = 'n';
7179                     break;
7180                   case '\t':
7181                     c2 = 't';
7182                     break;
7183                   case '\v':
7184                     c2 = 'v';
7185                     break;
7186                   case '\r':
7187                     c2 = 'r';
7188                     break;
7189                   case '\f':
7190                     c2 = 'f';
7191                     break;
7192                 }
7193                 if (c2) {
7194                     rb_warnI("invalid character syntax; use ?\\%c", c2);
7195                 }
7196             }
7197           ternary:
7198             pushback(c);
7199             lex_state = EXPR_VALUE;
7200             return '?';
7201         }
7202         newtok();
7203         enc = current_enc;
7204         if (!parser_isascii()) {
7205             if (tokadd_mbchar(c) == -1) return 0;
7206         }
7207         else if ((rb_enc_isalnum(c, current_enc) || c == '_') &&
7208                  lex_p < lex_pend && is_identchar(lex_p, lex_pend, current_enc)) {
7209             goto ternary;
7210         }
7211         else if (c == '\\') {
7212             if (peek('u')) {
7213                 nextc();
7214                 c = parser_tokadd_utf8(parser, &enc, 0, 0, 0);
7215                 if (0x80 <= c) {
7216                     tokaddmbc(c, enc);
7217                 }
7218                 else {
7219                     tokadd(c);
7220                 }
7221             }
7222             else if (!lex_eol_p() && !(c = *lex_p, ISASCII(c))) {
7223                 nextc();
7224                 if (tokadd_mbchar(c) == -1) return 0;
7225             }
7226             else {
7227                 c = read_escape(0, &enc);
7228                 tokadd(c);
7229             }
7230         }
7231         else {
7232             tokadd(c);
7233         }
7234         tokfix();
7235         set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0));
7236         lex_state = EXPR_END;
7237         return tCHAR;
7238 
7239       case '&':
7240         if ((c = nextc()) == '&') {
7241             lex_state = EXPR_BEG;
7242             if ((c = nextc()) == '=') {
7243                 set_yylval_id(tANDOP);
7244                 lex_state = EXPR_BEG;
7245                 return tOP_ASGN;
7246             }
7247             pushback(c);
7248             return tANDOP;
7249         }
7250         else if (c == '=') {
7251             set_yylval_id('&');
7252             lex_state = EXPR_BEG;
7253             return tOP_ASGN;
7254         }
7255         pushback(c);
7256         if (IS_SPCARG(c)) {
7257             rb_warning0("`&' interpreted as argument prefix");
7258             c = tAMPER;
7259         }
7260         else if (IS_BEG()) {
7261             c = tAMPER;
7262         }
7263         else {
7264             warn_balanced("&", "argument prefix");
7265             c = '&';
7266         }
7267         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7268         return c;
7269 
7270       case '|':
7271         if ((c = nextc()) == '|') {
7272             lex_state = EXPR_BEG;
7273             if ((c = nextc()) == '=') {
7274                 set_yylval_id(tOROP);
7275                 lex_state = EXPR_BEG;
7276                 return tOP_ASGN;
7277             }
7278             pushback(c);
7279             return tOROP;
7280         }
7281         if (c == '=') {
7282             set_yylval_id('|');
7283             lex_state = EXPR_BEG;
7284             return tOP_ASGN;
7285         }
7286         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7287         pushback(c);
7288         return '|';
7289 
7290       case '+':
7291         c = nextc();
7292         if (IS_AFTER_OPERATOR()) {
7293             lex_state = EXPR_ARG;
7294             if (c == '@') {
7295                 return tUPLUS;
7296             }
7297             pushback(c);
7298             return '+';
7299         }
7300         if (c == '=') {
7301             set_yylval_id('+');
7302             lex_state = EXPR_BEG;
7303             return tOP_ASGN;
7304         }
7305         if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7306             lex_state = EXPR_BEG;
7307             pushback(c);
7308             if (c != -1 && ISDIGIT(c)) {
7309                 c = '+';
7310                 goto start_num;
7311             }
7312             return tUPLUS;
7313         }
7314         lex_state = EXPR_BEG;
7315         pushback(c);
7316         warn_balanced("+", "unary operator");
7317         return '+';
7318 
7319       case '-':
7320         c = nextc();
7321         if (IS_AFTER_OPERATOR()) {
7322             lex_state = EXPR_ARG;
7323             if (c == '@') {
7324                 return tUMINUS;
7325             }
7326             pushback(c);
7327             return '-';
7328         }
7329         if (c == '=') {
7330             set_yylval_id('-');
7331             lex_state = EXPR_BEG;
7332             return tOP_ASGN;
7333         }
7334         if (c == '>') {
7335             lex_state = EXPR_ENDFN;
7336             return tLAMBDA;
7337         }
7338         if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
7339             lex_state = EXPR_BEG;
7340             pushback(c);
7341             if (c != -1 && ISDIGIT(c)) {
7342                 return tUMINUS_NUM;
7343             }
7344             return tUMINUS;
7345         }
7346         lex_state = EXPR_BEG;
7347         pushback(c);
7348         warn_balanced("-", "unary operator");
7349         return '-';
7350 
7351       case '.':
7352         lex_state = EXPR_BEG;
7353         if ((c = nextc()) == '.') {
7354             if ((c = nextc()) == '.') {
7355                 return tDOT3;
7356             }
7357             pushback(c);
7358             return tDOT2;
7359         }
7360         pushback(c);
7361         if (c != -1 && ISDIGIT(c)) {
7362             yyerror("no .<digit> floating literal anymore; put 0 before dot");
7363         }
7364         lex_state = EXPR_DOT;
7365         return '.';
7366 
7367       start_num:
7368       case '0': case '1': case '2': case '3': case '4':
7369       case '5': case '6': case '7': case '8': case '9':
7370         {
7371             int is_float, seen_point, seen_e, nondigit;
7372 
7373             is_float = seen_point = seen_e = nondigit = 0;
7374             lex_state = EXPR_END;
7375             newtok();
7376             if (c == '-' || c == '+') {
7377                 tokadd(c);
7378                 c = nextc();
7379             }
7380             if (c == '0') {
7381 #define no_digits() do {yyerror("numeric literal without digits"); return 0;} while (0)
7382                 int start = toklen();
7383                 c = nextc();
7384                 if (c == 'x' || c == 'X') {
7385                     /* hexadecimal */
7386                     c = nextc();
7387                     if (c != -1 && ISXDIGIT(c)) {
7388                         do {
7389                             if (c == '_') {
7390                                 if (nondigit) break;
7391                                 nondigit = c;
7392                                 continue;
7393                             }
7394                             if (!ISXDIGIT(c)) break;
7395                             nondigit = 0;
7396                             tokadd(c);
7397                         } while ((c = nextc()) != -1);
7398                     }
7399                     pushback(c);
7400                     tokfix();
7401                     if (toklen() == start) {
7402                         no_digits();
7403                     }
7404                     else if (nondigit) goto trailing_uc;
7405                     set_yylval_literal(rb_cstr_to_inum(tok(), 16, FALSE));
7406                     return tINTEGER;
7407                 }
7408                 if (c == 'b' || c == 'B') {
7409                     /* binary */
7410                     c = nextc();
7411                     if (c == '0' || c == '1') {
7412                         do {
7413                             if (c == '_') {
7414                                 if (nondigit) break;
7415                                 nondigit = c;
7416                                 continue;
7417                             }
7418                             if (c != '0' && c != '1') break;
7419                             nondigit = 0;
7420                             tokadd(c);
7421                         } while ((c = nextc()) != -1);
7422                     }
7423                     pushback(c);
7424                     tokfix();
7425                     if (toklen() == start) {
7426                         no_digits();
7427                     }
7428                     else if (nondigit) goto trailing_uc;
7429                     set_yylval_literal(rb_cstr_to_inum(tok(), 2, FALSE));
7430                     return tINTEGER;
7431                 }
7432                 if (c == 'd' || c == 'D') {
7433                     /* decimal */
7434                     c = nextc();
7435                     if (c != -1 && ISDIGIT(c)) {
7436                         do {
7437                             if (c == '_') {
7438                                 if (nondigit) break;
7439                                 nondigit = c;
7440                                 continue;
7441                             }
7442                             if (!ISDIGIT(c)) break;
7443                             nondigit = 0;
7444                             tokadd(c);
7445                         } while ((c = nextc()) != -1);
7446                     }
7447                     pushback(c);
7448                     tokfix();
7449                     if (toklen() == start) {
7450                         no_digits();
7451                     }
7452                     else if (nondigit) goto trailing_uc;
7453                     set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
7454                     return tINTEGER;
7455                 }
7456                 if (c == '_') {
7457                     /* 0_0 */
7458                     goto octal_number;
7459                 }
7460                 if (c == 'o' || c == 'O') {
7461                     /* prefixed octal */
7462                     c = nextc();
7463                     if (c == -1 || c == '_' || !ISDIGIT(c)) {
7464                         no_digits();
7465                     }
7466                 }
7467                 if (c >= '0' && c <= '7') {
7468                     /* octal */
7469                   octal_number:
7470                     do {
7471                         if (c == '_') {
7472                             if (nondigit) break;
7473                             nondigit = c;
7474                             continue;
7475                         }
7476                         if (c < '0' || c > '9') break;
7477                         if (c > '7') goto invalid_octal;
7478                         nondigit = 0;
7479                         tokadd(c);
7480                     } while ((c = nextc()) != -1);
7481                     if (toklen() > start) {
7482                         pushback(c);
7483                         tokfix();
7484                         if (nondigit) goto trailing_uc;
7485                         set_yylval_literal(rb_cstr_to_inum(tok(), 8, FALSE));
7486                         return tINTEGER;
7487                     }
7488                     if (nondigit) {
7489                         pushback(c);
7490                         goto trailing_uc;
7491                     }
7492                 }
7493                 if (c > '7' && c <= '9') {
7494                   invalid_octal:
7495                     yyerror("Invalid octal digit");
7496                 }
7497                 else if (c == '.' || c == 'e' || c == 'E') {
7498                     tokadd('0');
7499                 }
7500                 else {
7501                     pushback(c);
7502                     set_yylval_literal(INT2FIX(0));
7503                     return tINTEGER;
7504                 }
7505             }
7506 
7507             for (;;) {
7508                 switch (c) {
7509                   case '0': case '1': case '2': case '3': case '4':
7510                   case '5': case '6': case '7': case '8': case '9':
7511                     nondigit = 0;
7512                     tokadd(c);
7513                     break;
7514 
7515                   case '.':
7516                     if (nondigit) goto trailing_uc;
7517                     if (seen_point || seen_e) {
7518                         goto decode_num;
7519                     }
7520                     else {
7521                         int c0 = nextc();
7522                         if (c0 == -1 || !ISDIGIT(c0)) {
7523                             pushback(c0);
7524                             goto decode_num;
7525                         }
7526                         c = c0;
7527                     }
7528                     tokadd('.');
7529                     tokadd(c);
7530                     is_float++;
7531                     seen_point++;
7532                     nondigit = 0;
7533                     break;
7534 
7535                   case 'e':
7536                   case 'E':
7537                     if (nondigit) {
7538                         pushback(c);
7539                         c = nondigit;
7540                         goto decode_num;
7541                     }
7542                     if (seen_e) {
7543                         goto decode_num;
7544                     }
7545                     tokadd(c);
7546                     seen_e++;
7547                     is_float++;
7548                     nondigit = c;
7549                     c = nextc();
7550                     if (c != '-' && c != '+') continue;
7551                     tokadd(c);
7552                     nondigit = c;
7553                     break;
7554 
7555                   case '_':     /* `_' in number just ignored */
7556                     if (nondigit) goto decode_num;
7557                     nondigit = c;
7558                     break;
7559 
7560                   default:
7561                     goto decode_num;
7562                 }
7563                 c = nextc();
7564             }
7565 
7566           decode_num:
7567             pushback(c);
7568             if (nondigit) {
7569                 char tmp[30];
7570               trailing_uc:
7571                 snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
7572                 yyerror(tmp);
7573             }
7574             tokfix();
7575             if (is_float) {
7576                 double d = strtod(tok(), 0);
7577                 if (errno == ERANGE) {
7578                     rb_warningS("Float %s out of range", tok());
7579                     errno = 0;
7580                 }
7581                 set_yylval_literal(DBL2NUM(d));
7582                 return tFLOAT;
7583             }
7584             set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
7585             return tINTEGER;
7586         }
7587 
7588       case ')':
7589       case ']':
7590         paren_nest--;
7591       case '}':
7592         COND_LEXPOP();
7593         CMDARG_LEXPOP();
7594         if (c == ')')
7595             lex_state = EXPR_ENDFN;
7596         else
7597             lex_state = EXPR_ENDARG;
7598         if (c == '}') {
7599             if (!brace_nest--) c = tSTRING_DEND;
7600         }
7601         return c;
7602 
7603       case ':':
7604         c = nextc();
7605         if (c == ':') {
7606             if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
7607                 lex_state = EXPR_BEG;
7608                 return tCOLON3;
7609             }
7610             lex_state = EXPR_DOT;
7611             return tCOLON2;
7612         }
7613         if (IS_END() || ISSPACE(c)) {
7614             pushback(c);
7615             warn_balanced(":", "symbol literal");
7616             lex_state = EXPR_BEG;
7617             return ':';
7618         }
7619         switch (c) {
7620           case '\'':
7621             lex_strterm = NEW_STRTERM(str_ssym, c, 0);
7622             break;
7623           case '"':
7624             lex_strterm = NEW_STRTERM(str_dsym, c, 0);
7625             break;
7626           default:
7627             pushback(c);
7628             break;
7629         }
7630         lex_state = EXPR_FNAME;
7631         return tSYMBEG;
7632 
7633       case '/':
7634         if (IS_lex_state(EXPR_BEG_ANY)) {
7635             lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7636             return tREGEXP_BEG;
7637         }
7638         if ((c = nextc()) == '=') {
7639             set_yylval_id('/');
7640             lex_state = EXPR_BEG;
7641             return tOP_ASGN;
7642         }
7643         pushback(c);
7644         if (IS_SPCARG(c)) {
7645             (void)arg_ambiguous();
7646             lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
7647             return tREGEXP_BEG;
7648         }
7649         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7650         warn_balanced("/", "regexp literal");
7651         return '/';
7652 
7653       case '^':
7654         if ((c = nextc()) == '=') {
7655             set_yylval_id('^');
7656             lex_state = EXPR_BEG;
7657             return tOP_ASGN;
7658         }
7659         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
7660         pushback(c);
7661         return '^';
7662 
7663       case ';':
7664         lex_state = EXPR_BEG;
7665         command_start = TRUE;
7666         return ';';
7667 
7668       case ',':
7669         lex_state = EXPR_BEG;
7670         return ',';
7671 
7672       case '~':
7673         if (IS_AFTER_OPERATOR()) {
7674             if ((c = nextc()) != '@') {
7675                 pushback(c);
7676             }
7677             lex_state = EXPR_ARG;
7678         }
7679         else {
7680             lex_state = EXPR_BEG;
7681         }
7682         return '~';
7683 
7684       case '(':
7685         if (IS_BEG()) {
7686             c = tLPAREN;
7687         }
7688         else if (IS_SPCARG(-1)) {
7689             c = tLPAREN_ARG;
7690         }
7691         paren_nest++;
7692         COND_PUSH(0);
7693         CMDARG_PUSH(0);
7694         lex_state = EXPR_BEG;
7695         return c;
7696 
7697       case '[':
7698         paren_nest++;
7699         if (IS_AFTER_OPERATOR()) {
7700             lex_state = EXPR_ARG;
7701             if ((c = nextc()) == ']') {
7702                 if ((c = nextc()) == '=') {
7703                     return tASET;
7704                 }
7705                 pushback(c);
7706                 return tAREF;
7707             }
7708             pushback(c);
7709             return '[';
7710         }
7711         else if (IS_BEG()) {
7712             c = tLBRACK;
7713         }
7714         else if (IS_ARG() && space_seen) {
7715             c = tLBRACK;
7716         }
7717         lex_state = EXPR_BEG;
7718         COND_PUSH(0);
7719         CMDARG_PUSH(0);
7720         return c;
7721 
7722       case '{':
7723         ++brace_nest;
7724         if (lpar_beg && lpar_beg == paren_nest) {
7725             lex_state = EXPR_BEG;
7726             lpar_beg = 0;
7727             --paren_nest;
7728             COND_PUSH(0);
7729             CMDARG_PUSH(0);
7730             return tLAMBEG;
7731         }
7732         if (IS_ARG() || IS_lex_state(EXPR_END | EXPR_ENDFN))
7733             c = '{';          /* block (primary) */
7734         else if (IS_lex_state(EXPR_ENDARG))
7735             c = tLBRACE_ARG;  /* block (expr) */
7736         else
7737             c = tLBRACE;      /* hash */
7738         COND_PUSH(0);
7739         CMDARG_PUSH(0);
7740         lex_state = EXPR_BEG;
7741         if (c != tLBRACE) command_start = TRUE;
7742         return c;
7743 
7744       case '\\':
7745         c = nextc();
7746         if (c == '\n') {
7747             space_seen = 1;
7748 #ifdef RIPPER
7749             ripper_dispatch_scan_event(parser, tSP);
7750 #endif
7751             goto retry; /* skip \\n */
7752         }
7753         pushback(c);
7754         return '\\';
7755 
7756       case '%':
7757         if (IS_lex_state(EXPR_BEG_ANY)) {
7758             int term;
7759             int paren;
7760 
7761             c = nextc();
7762           quotation:
7763             if (c == -1 || !ISALNUM(c)) {
7764                 term = c;
7765                 c = 'Q';
7766             }
7767             else {
7768                 term = nextc();
7769                 if (rb_enc_isalnum(term, current_enc) || !parser_isascii()) {
7770                     yyerror("unknown type of %string");
7771                     return 0;
7772                 }
7773             }
7774             if (c == -1 || term == -1) {
7775                 compile_error(PARSER_ARG "unterminated quoted string meets end of file");
7776                 return 0;
7777             }
7778             paren = term;
7779             if (term == '(') term = ')';
7780             else if (term == '[') term = ']';
7781             else if (term == '{') term = '}';
7782             else if (term == '<') term = '>';
7783             else paren = 0;
7784 
7785             switch (c) {
7786               case 'Q':
7787                 lex_strterm = NEW_STRTERM(str_dquote, term, paren);
7788                 return tSTRING_BEG;
7789 
7790               case 'q':
7791                 lex_strterm = NEW_STRTERM(str_squote, term, paren);
7792                 return tSTRING_BEG;
7793 
7794               case 'W':
7795                 lex_strterm = NEW_STRTERM(str_dword, term, paren);
7796                 do {c = nextc();} while (ISSPACE(c));
7797                 pushback(c);
7798                 return tWORDS_BEG;
7799 
7800               case 'w':
7801                 lex_strterm = NEW_STRTERM(str_sword, term, paren);
7802                 do {c = nextc();} while (ISSPACE(c));
7803                 pushback(c);
7804                 return tQWORDS_BEG;
7805 
7806               case 'I':
7807                 lex_strterm = NEW_STRTERM(str_dword, term, paren);
7808                 do {c = nextc();} while (ISSPACE(c));
7809                 pushback(c);
7810                 return tSYMBOLS_BEG;
7811 
7812               case 'i':
7813                 lex_strterm = NEW_STRTERM(str_sword, term, paren);
7814                 do {c = nextc();} while (ISSPACE(c));
7815                 pushback(c);
7816                 return tQSYMBOLS_BEG;
7817 
7818               case 'x':
7819                 lex_strterm =