Ruby  2.0.0p481(2014-05-08revision45883)
parse.y
Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   parse.y -
00004 
00005   $Author: nagachika $
00006   created at: Fri May 28 18:02:42 JST 1993
00007 
00008   Copyright (C) 1993-2007 Yukihiro Matsumoto
00009 
00010 **********************************************************************/
00011 
00012 %{
00013 
00014 #ifndef PARSER_DEBUG
00015 #define PARSER_DEBUG 0
00016 #endif
00017 #define YYDEBUG 1
00018 #define YYERROR_VERBOSE 1
00019 #define YYSTACK_USE_ALLOCA 0
00020 
00021 #include "ruby/ruby.h"
00022 #include "ruby/st.h"
00023 #include "ruby/encoding.h"
00024 #include "internal.h"
00025 #include "node.h"
00026 #include "parse.h"
00027 #include "id.h"
00028 #include "regenc.h"
00029 #include <stdio.h>
00030 #include <errno.h>
00031 #include <ctype.h>
00032 #include "probes.h"
00033 
00034 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
00035 
00036 #define YYMALLOC(size)          rb_parser_malloc(parser, (size))
00037 #define YYREALLOC(ptr, size)    rb_parser_realloc(parser, (ptr), (size))
00038 #define YYCALLOC(nelem, size)   rb_parser_calloc(parser, (nelem), (size))
00039 #define YYFREE(ptr)             rb_parser_free(parser, (ptr))
00040 #define malloc  YYMALLOC
00041 #define realloc YYREALLOC
00042 #define calloc  YYCALLOC
00043 #define free    YYFREE
00044 
00045 #ifndef RIPPER
00046 static ID register_symid(ID, const char *, long, rb_encoding *);
00047 static ID register_symid_str(ID, VALUE);
00048 #define REGISTER_SYMID(id, name) register_symid((id), (name), strlen(name), enc)
00049 #include "id.c"
00050 #endif
00051 
00052 #define is_notop_id(id) ((id)>tLAST_OP_ID)
00053 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
00054 #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
00055 #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
00056 #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
00057 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
00058 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
00059 #define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
00060 #define id_type(id) (is_notop_id(id) ? (int)((id)&ID_SCOPE_MASK) : -1)
00061 
00062 #define is_asgn_or_id(id) ((is_notop_id(id)) && \
00063         (((id)&ID_SCOPE_MASK) == ID_GLOBAL || \
00064          ((id)&ID_SCOPE_MASK) == ID_INSTANCE || \
00065          ((id)&ID_SCOPE_MASK) == ID_CLASS))
00066 
00067 enum lex_state_bits {
00068     EXPR_BEG_bit,               /* ignore newline, +/- is a sign. */
00069     EXPR_END_bit,               /* newline significant, +/- is an operator. */
00070     EXPR_ENDARG_bit,            /* ditto, and unbound braces. */
00071     EXPR_ENDFN_bit,             /* ditto, and unbound braces. */
00072     EXPR_ARG_bit,               /* newline significant, +/- is an operator. */
00073     EXPR_CMDARG_bit,            /* newline significant, +/- is an operator. */
00074     EXPR_MID_bit,               /* newline significant, +/- is an operator. */
00075     EXPR_FNAME_bit,             /* ignore newline, no reserved words. */
00076     EXPR_DOT_bit,               /* right after `.' or `::', no reserved words. */
00077     EXPR_CLASS_bit,             /* immediate after `class', no here document. */
00078     EXPR_VALUE_bit,             /* alike EXPR_BEG but label is disallowed. */
00079     EXPR_MAX_STATE
00080 };
00081 /* examine combinations */
00082 enum lex_state_e {
00083 #define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
00084     DEF_EXPR(BEG),
00085     DEF_EXPR(END),
00086     DEF_EXPR(ENDARG),
00087     DEF_EXPR(ENDFN),
00088     DEF_EXPR(ARG),
00089     DEF_EXPR(CMDARG),
00090     DEF_EXPR(MID),
00091     DEF_EXPR(FNAME),
00092     DEF_EXPR(DOT),
00093     DEF_EXPR(CLASS),
00094     DEF_EXPR(VALUE),
00095     EXPR_BEG_ANY  =  (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS),
00096     EXPR_ARG_ANY  =  (EXPR_ARG | EXPR_CMDARG),
00097     EXPR_END_ANY  =  (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
00098 };
00099 #define IS_lex_state_for(x, ls) ((x) & (ls))
00100 #define IS_lex_state(ls)        IS_lex_state_for(lex_state, (ls))
00101 
00102 #if PARSER_DEBUG
00103 static const char *lex_state_name(enum lex_state_e state);
00104 #endif
00105 
00106 typedef VALUE stack_type;
00107 
00108 # define BITSTACK_PUSH(stack, n)        ((stack) = ((stack)<<1)|((n)&1))
00109 # define BITSTACK_POP(stack)    ((stack) = (stack) >> 1)
00110 # define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
00111 # define BITSTACK_SET_P(stack)  ((stack)&1)
00112 
00113 #define COND_PUSH(n)    BITSTACK_PUSH(cond_stack, (n))
00114 #define COND_POP()      BITSTACK_POP(cond_stack)
00115 #define COND_LEXPOP()   BITSTACK_LEXPOP(cond_stack)
00116 #define COND_P()        BITSTACK_SET_P(cond_stack)
00117 
00118 #define CMDARG_PUSH(n)  BITSTACK_PUSH(cmdarg_stack, (n))
00119 #define CMDARG_POP()    BITSTACK_POP(cmdarg_stack)
00120 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
00121 #define CMDARG_P()      BITSTACK_SET_P(cmdarg_stack)
00122 
00123 struct vtable {
00124     ID *tbl;
00125     int pos;
00126     int capa;
00127     struct vtable *prev;
00128 };
00129 
00130 struct local_vars {
00131     struct vtable *args;
00132     struct vtable *vars;
00133     struct vtable *used;
00134     struct local_vars *prev;
00135     stack_type cmdargs;
00136 };
00137 
00138 #define DVARS_INHERIT ((void*)1)
00139 #define DVARS_TOPSCOPE NULL
00140 #define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
00141 #define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
00142 
00143 static int
00144 vtable_size(const struct vtable *tbl)
00145 {
00146     if (POINTER_P(tbl)) {
00147         return tbl->pos;
00148     }
00149     else {
00150         return 0;
00151     }
00152 }
00153 
00154 #define VTBL_DEBUG 0
00155 
00156 static struct vtable *
00157 vtable_alloc(struct vtable *prev)
00158 {
00159     struct vtable *tbl = ALLOC(struct vtable);
00160     tbl->pos = 0;
00161     tbl->capa = 8;
00162     tbl->tbl = ALLOC_N(ID, tbl->capa);
00163     tbl->prev = prev;
00164     if (VTBL_DEBUG) printf("vtable_alloc: %p\n", (void *)tbl);
00165     return tbl;
00166 }
00167 
00168 static void
00169 vtable_free(struct vtable *tbl)
00170 {
00171     if (VTBL_DEBUG)printf("vtable_free: %p\n", (void *)tbl);
00172     if (POINTER_P(tbl)) {
00173         if (tbl->tbl) {
00174             xfree(tbl->tbl);
00175         }
00176         xfree(tbl);
00177     }
00178 }
00179 
00180 static void
00181 vtable_add(struct vtable *tbl, ID id)
00182 {
00183     if (!POINTER_P(tbl)) {
00184         rb_bug("vtable_add: vtable is not allocated (%p)", (void *)tbl);
00185     }
00186     if (VTBL_DEBUG) printf("vtable_add: %p, %s\n", (void *)tbl, rb_id2name(id));
00187 
00188     if (tbl->pos == tbl->capa) {
00189         tbl->capa = tbl->capa * 2;
00190         REALLOC_N(tbl->tbl, ID, tbl->capa);
00191     }
00192     tbl->tbl[tbl->pos++] = id;
00193 }
00194 
00195 static int
00196 vtable_included(const struct vtable * tbl, ID id)
00197 {
00198     int i;
00199 
00200     if (POINTER_P(tbl)) {
00201         for (i = 0; i < tbl->pos; i++) {
00202             if (tbl->tbl[i] == id) {
00203                 return i+1;
00204             }
00205         }
00206     }
00207     return 0;
00208 }
00209 
00210 
00211 #ifndef RIPPER
00212 typedef struct token_info {
00213     const char *token;
00214     int linenum;
00215     int column;
00216     int nonspc;
00217     struct token_info *next;
00218 } token_info;
00219 #endif
00220 
00221 /*
00222     Structure of Lexer Buffer:
00223 
00224  lex_pbeg      tokp         lex_p        lex_pend
00225     |           |              |            |
00226     |-----------+--------------+------------|
00227                 |<------------>|
00228                      token
00229 */
00230 struct parser_params {
00231     int is_ripper;
00232     NODE *heap;
00233 
00234     YYSTYPE *parser_yylval;
00235     VALUE eofp;
00236 
00237     NODE *parser_lex_strterm;
00238     enum lex_state_e parser_lex_state;
00239     stack_type parser_cond_stack;
00240     stack_type parser_cmdarg_stack;
00241     int parser_class_nest;
00242     int parser_paren_nest;
00243     int parser_lpar_beg;
00244     int parser_in_single;
00245     int parser_in_def;
00246     int parser_brace_nest;
00247     int parser_compile_for_eval;
00248     VALUE parser_cur_mid;
00249     int parser_in_defined;
00250     char *parser_tokenbuf;
00251     int parser_tokidx;
00252     int parser_toksiz;
00253     int parser_tokline;
00254     VALUE parser_lex_input;
00255     VALUE parser_lex_lastline;
00256     VALUE parser_lex_nextline;
00257     const char *parser_lex_pbeg;
00258     const char *parser_lex_p;
00259     const char *parser_lex_pend;
00260     int parser_heredoc_end;
00261     int parser_command_start;
00262     NODE *parser_deferred_nodes;
00263     long parser_lex_gets_ptr;
00264     VALUE (*parser_lex_gets)(struct parser_params*,VALUE);
00265     struct local_vars *parser_lvtbl;
00266     int parser_ruby__end__seen;
00267     int line_count;
00268     int has_shebang;
00269     char *parser_ruby_sourcefile; /* current source file */
00270     int parser_ruby_sourceline; /* current line no. */
00271     VALUE parser_ruby_sourcefile_string;
00272     rb_encoding *enc;
00273 
00274     int parser_yydebug;
00275 
00276 #ifndef RIPPER
00277     /* Ruby core only */
00278     NODE *parser_eval_tree_begin;
00279     NODE *parser_eval_tree;
00280     VALUE debug_lines;
00281     VALUE coverage;
00282     int nerr;
00283 
00284     int parser_token_info_enabled;
00285     token_info *parser_token_info;
00286 #else
00287     /* Ripper only */
00288     const char *tokp;
00289     VALUE delayed;
00290     int delayed_line;
00291     int delayed_col;
00292 
00293     VALUE value;
00294     VALUE result;
00295     VALUE parsing_thread;
00296     int toplevel_p;
00297 #endif
00298 };
00299 
00300 #define STR_NEW(p,n) rb_enc_str_new((p),(n),current_enc)
00301 #define STR_NEW0() rb_enc_str_new(0,0,current_enc)
00302 #define STR_NEW2(p) rb_enc_str_new((p),strlen(p),current_enc)
00303 #define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),current_enc)
00304 #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT)
00305 #define TOK_INTERN(mb) rb_intern3(tok(), toklen(), current_enc)
00306 
00307 static int parser_yyerror(struct parser_params*, const char*);
00308 #define yyerror(msg) parser_yyerror(parser, (msg))
00309 
00310 #define lex_strterm             (parser->parser_lex_strterm)
00311 #define lex_state               (parser->parser_lex_state)
00312 #define cond_stack              (parser->parser_cond_stack)
00313 #define cmdarg_stack            (parser->parser_cmdarg_stack)
00314 #define class_nest              (parser->parser_class_nest)
00315 #define paren_nest              (parser->parser_paren_nest)
00316 #define lpar_beg                (parser->parser_lpar_beg)
00317 #define brace_nest              (parser->parser_brace_nest)
00318 #define in_single               (parser->parser_in_single)
00319 #define in_def                  (parser->parser_in_def)
00320 #define compile_for_eval        (parser->parser_compile_for_eval)
00321 #define cur_mid                 (parser->parser_cur_mid)
00322 #define in_defined              (parser->parser_in_defined)
00323 #define tokenbuf                (parser->parser_tokenbuf)
00324 #define tokidx                  (parser->parser_tokidx)
00325 #define toksiz                  (parser->parser_toksiz)
00326 #define tokline                 (parser->parser_tokline)
00327 #define lex_input               (parser->parser_lex_input)
00328 #define lex_lastline            (parser->parser_lex_lastline)
00329 #define lex_nextline            (parser->parser_lex_nextline)
00330 #define lex_pbeg                (parser->parser_lex_pbeg)
00331 #define lex_p                   (parser->parser_lex_p)
00332 #define lex_pend                (parser->parser_lex_pend)
00333 #define heredoc_end             (parser->parser_heredoc_end)
00334 #define command_start           (parser->parser_command_start)
00335 #define deferred_nodes          (parser->parser_deferred_nodes)
00336 #define lex_gets_ptr            (parser->parser_lex_gets_ptr)
00337 #define lex_gets                (parser->parser_lex_gets)
00338 #define lvtbl                   (parser->parser_lvtbl)
00339 #define ruby__end__seen         (parser->parser_ruby__end__seen)
00340 #define ruby_sourceline         (parser->parser_ruby_sourceline)
00341 #define ruby_sourcefile         (parser->parser_ruby_sourcefile)
00342 #define ruby_sourcefile_string  (parser->parser_ruby_sourcefile_string)
00343 #define current_enc             (parser->enc)
00344 #define yydebug                 (parser->parser_yydebug)
00345 #ifdef RIPPER
00346 #else
00347 #define ruby_eval_tree          (parser->parser_eval_tree)
00348 #define ruby_eval_tree_begin    (parser->parser_eval_tree_begin)
00349 #define ruby_debug_lines        (parser->debug_lines)
00350 #define ruby_coverage           (parser->coverage)
00351 #endif
00352 
00353 #if YYPURE
00354 static int yylex(void*, void*);
00355 #else
00356 static int yylex(void*);
00357 #endif
00358 
00359 #ifndef RIPPER
00360 #define yyparse ruby_yyparse
00361 
00362 static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE);
00363 #define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, (type), (a1), (a2), (a3))
00364 
00365 static NODE *cond_gen(struct parser_params*,NODE*);
00366 #define cond(node) cond_gen(parser, (node))
00367 static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
00368 #define logop(type,node1,node2) logop_gen(parser, (type), (node1), (node2))
00369 
00370 static NODE *newline_node(NODE*);
00371 static void fixpos(NODE*,NODE*);
00372 
00373 static int value_expr_gen(struct parser_params*,NODE*);
00374 static void void_expr_gen(struct parser_params*,NODE*);
00375 static NODE *remove_begin(NODE*);
00376 #define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
00377 #define void_expr0(node) void_expr_gen(parser, (node))
00378 #define void_expr(node) void_expr0((node) = remove_begin(node))
00379 static void void_stmts_gen(struct parser_params*,NODE*);
00380 #define void_stmts(node) void_stmts_gen(parser, (node))
00381 static void reduce_nodes_gen(struct parser_params*,NODE**);
00382 #define reduce_nodes(n) reduce_nodes_gen(parser,(n))
00383 static void block_dup_check_gen(struct parser_params*,NODE*,NODE*);
00384 #define block_dup_check(n1,n2) block_dup_check_gen(parser,(n1),(n2))
00385 
00386 static NODE *block_append_gen(struct parser_params*,NODE*,NODE*);
00387 #define block_append(h,t) block_append_gen(parser,(h),(t))
00388 static NODE *list_append_gen(struct parser_params*,NODE*,NODE*);
00389 #define list_append(l,i) list_append_gen(parser,(l),(i))
00390 static NODE *list_concat_gen(struct parser_params*,NODE*,NODE*);
00391 #define list_concat(h,t) list_concat_gen(parser,(h),(t))
00392 static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*);
00393 #define arg_append(h,t) arg_append_gen(parser,(h),(t))
00394 static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
00395 #define arg_concat(h,t) arg_concat_gen(parser,(h),(t))
00396 static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
00397 #define literal_concat(h,t) literal_concat_gen(parser,(h),(t))
00398 static int literal_concat0(struct parser_params *, VALUE, VALUE);
00399 static NODE *new_evstr_gen(struct parser_params*,NODE*);
00400 #define new_evstr(n) new_evstr_gen(parser,(n))
00401 static NODE *evstr2dstr_gen(struct parser_params*,NODE*);
00402 #define evstr2dstr(n) evstr2dstr_gen(parser,(n))
00403 static NODE *splat_array(NODE*);
00404 
00405 static NODE *call_bin_op_gen(struct parser_params*,NODE*,ID,NODE*);
00406 #define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, (recv),(id),(arg1))
00407 static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID);
00408 #define call_uni_op(recv,id) call_uni_op_gen(parser, (recv),(id))
00409 
00410 static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*);
00411 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
00412 static NODE *new_args_tail_gen(struct parser_params*,NODE*,ID,ID);
00413 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
00414 
00415 static NODE *negate_lit(NODE*);
00416 static NODE *ret_args_gen(struct parser_params*,NODE*);
00417 #define ret_args(node) ret_args_gen(parser, (node))
00418 static NODE *arg_blk_pass(NODE*,NODE*);
00419 static NODE *new_yield_gen(struct parser_params*,NODE*);
00420 #define new_yield(node) new_yield_gen(parser, (node))
00421 static NODE *dsym_node_gen(struct parser_params*,NODE*);
00422 #define dsym_node(node) dsym_node_gen(parser, (node))
00423 
00424 static NODE *gettable_gen(struct parser_params*,ID);
00425 #define gettable(id) gettable_gen(parser,(id))
00426 static NODE *assignable_gen(struct parser_params*,ID,NODE*);
00427 #define assignable(id,node) assignable_gen(parser, (id), (node))
00428 
00429 static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
00430 #define aryset(node1,node2) aryset_gen(parser, (node1), (node2))
00431 static NODE *attrset_gen(struct parser_params*,NODE*,ID);
00432 #define attrset(node,id) attrset_gen(parser, (node), (id))
00433 
00434 static void rb_backref_error_gen(struct parser_params*,NODE*);
00435 #define rb_backref_error(n) rb_backref_error_gen(parser,(n))
00436 static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
00437 #define node_assign(node1, node2) node_assign_gen(parser, (node1), (node2))
00438 
00439 static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
00440 static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs);
00441 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (attr), (op), (rhs))
00442 static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
00443 #define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs))
00444 
00445 static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
00446 #define match_op(node1,node2) match_op_gen(parser, (node1), (node2))
00447 
00448 static ID  *local_tbl_gen(struct parser_params*);
00449 #define local_tbl() local_tbl_gen(parser)
00450 
00451 static void fixup_nodes(NODE **);
00452 
00453 static VALUE reg_compile_gen(struct parser_params*, VALUE, int);
00454 #define reg_compile(str,options) reg_compile_gen(parser, (str), (options))
00455 static void reg_fragment_setenc_gen(struct parser_params*, VALUE, int);
00456 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, (str), (options))
00457 static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
00458 #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, (str), (options))
00459 static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match);
00460 #define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
00461 
00462 #define get_id(id) (id)
00463 #define get_value(val) (val)
00464 #else
00465 #define value_expr(node) ((void)(node))
00466 #define remove_begin(node) (node)
00467 #define rb_dvar_defined(id) 0
00468 #define rb_local_defined(id) 0
00469 static ID ripper_get_id(VALUE);
00470 #define get_id(id) ripper_get_id(id)
00471 static VALUE ripper_get_value(VALUE);
00472 #define get_value(val) ripper_get_value(val)
00473 static VALUE assignable_gen(struct parser_params*,VALUE);
00474 #define assignable(lhs,node) assignable_gen(parser, (lhs))
00475 static int id_is_var_gen(struct parser_params *parser, ID id);
00476 #define id_is_var(id) id_is_var_gen(parser, (id))
00477 
00478 #define node_assign(node1, node2) dispatch2(assign, (node1), (node2))
00479 
00480 static VALUE new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs);
00481 static VALUE new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs);
00482 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs))
00483 
00484 #endif /* !RIPPER */
00485 
00486 #define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs))
00487 
00488 static ID formal_argument_gen(struct parser_params*, ID);
00489 #define formal_argument(id) formal_argument_gen(parser, (id))
00490 static ID shadowing_lvar_gen(struct parser_params*,ID);
00491 #define shadowing_lvar(name) shadowing_lvar_gen(parser, (name))
00492 static void new_bv_gen(struct parser_params*,ID);
00493 #define new_bv(id) new_bv_gen(parser, (id))
00494 
00495 static void local_push_gen(struct parser_params*,int);
00496 #define local_push(top) local_push_gen(parser,(top))
00497 static void local_pop_gen(struct parser_params*);
00498 #define local_pop() local_pop_gen(parser)
00499 static int local_var_gen(struct parser_params*, ID);
00500 #define local_var(id) local_var_gen(parser, (id))
00501 static int arg_var_gen(struct parser_params*, ID);
00502 #define arg_var(id) arg_var_gen(parser, (id))
00503 static int  local_id_gen(struct parser_params*, ID);
00504 #define local_id(id) local_id_gen(parser, (id))
00505 static ID   internal_id_gen(struct parser_params*);
00506 #define internal_id() internal_id_gen(parser)
00507 
00508 static const struct vtable *dyna_push_gen(struct parser_params *);
00509 #define dyna_push() dyna_push_gen(parser)
00510 static void dyna_pop_gen(struct parser_params*, const struct vtable *);
00511 #define dyna_pop(node) dyna_pop_gen(parser, (node))
00512 static int dyna_in_block_gen(struct parser_params*);
00513 #define dyna_in_block() dyna_in_block_gen(parser)
00514 #define dyna_var(id) local_var(id)
00515 static int dvar_defined_gen(struct parser_params*,ID,int);
00516 #define dvar_defined(id) dvar_defined_gen(parser, (id), 0)
00517 #define dvar_defined_get(id) dvar_defined_gen(parser, (id), 1)
00518 static int dvar_curr_gen(struct parser_params*,ID);
00519 #define dvar_curr(id) dvar_curr_gen(parser, (id))
00520 
00521 static int lvar_defined_gen(struct parser_params*, ID);
00522 #define lvar_defined(id) lvar_defined_gen(parser, (id))
00523 
00524 #define RE_OPTION_ONCE (1<<16)
00525 #define RE_OPTION_ENCODING_SHIFT 8
00526 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
00527 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
00528 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
00529 #define RE_OPTION_MASK  0xff
00530 #define RE_OPTION_ARG_ENCODING_NONE 32
00531 
00532 #define NODE_STRTERM NODE_ZARRAY        /* nothing to gc */
00533 #define NODE_HEREDOC NODE_ARRAY         /* 1, 3 to gc */
00534 #define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
00535 #define nd_func u1.id
00536 #if SIZEOF_SHORT == 2
00537 #define nd_term(node) ((signed short)(node)->u2.id)
00538 #else
00539 #define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
00540 #endif
00541 #define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
00542 #define nd_nest u3.cnt
00543 
00544 /****** Ripper *******/
00545 
00546 #ifdef RIPPER
00547 #define RIPPER_VERSION "0.1.0"
00548 
00549 #include "eventids1.c"
00550 #include "eventids2.c"
00551 
00552 static VALUE ripper_dispatch0(struct parser_params*,ID);
00553 static VALUE ripper_dispatch1(struct parser_params*,ID,VALUE);
00554 static VALUE ripper_dispatch2(struct parser_params*,ID,VALUE,VALUE);
00555 static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
00556 static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
00557 static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
00558 static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
00559 
00560 #define dispatch0(n)            ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
00561 #define dispatch1(n,a)          ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
00562 #define dispatch2(n,a,b)        ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), (a), (b))
00563 #define dispatch3(n,a,b,c)      ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
00564 #define dispatch4(n,a,b,c,d)    ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
00565 #define dispatch5(n,a,b,c,d,e)  ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
00566 #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))
00567 
00568 #define yyparse ripper_yyparse
00569 
00570 #define ripper_intern(s) ID2SYM(rb_intern(s))
00571 static VALUE ripper_id2sym(ID);
00572 #ifdef __GNUC__
00573 #define ripper_id2sym(id) ((id) < 256 && rb_ispunct(id) ? \
00574                            ID2SYM(id) : ripper_id2sym(id))
00575 #endif
00576 
00577 #define arg_new() dispatch0(args_new)
00578 #define arg_add(l,a) dispatch2(args_add, (l), (a))
00579 #define arg_add_star(l,a) dispatch2(args_add_star, (l), (a))
00580 #define arg_add_block(l,b) dispatch2(args_add_block, (l), (b))
00581 #define arg_add_optblock(l,b) ((b)==Qundef? (l) : dispatch2(args_add_block, (l), (b)))
00582 #define bare_assoc(v) dispatch1(bare_assoc_hash, (v))
00583 #define arg_add_assocs(l,b) arg_add((l), bare_assoc(b))
00584 
00585 #define args2mrhs(a) dispatch1(mrhs_new_from_args, (a))
00586 #define mrhs_new() dispatch0(mrhs_new)
00587 #define mrhs_add(l,a) dispatch2(mrhs_add, (l), (a))
00588 #define mrhs_add_star(l,a) dispatch2(mrhs_add_star, (l), (a))
00589 
00590 #define mlhs_new() dispatch0(mlhs_new)
00591 #define mlhs_add(l,a) dispatch2(mlhs_add, (l), (a))
00592 #define mlhs_add_star(l,a) dispatch2(mlhs_add_star, (l), (a))
00593 
00594 #define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
00595         dispatch7(params, (pars), (opts), (rest), (pars2), (kws), (kwrest), (blk))
00596 
00597 #define blockvar_new(p,v) dispatch2(block_var, (p), (v))
00598 #define blockvar_add_star(l,a) dispatch2(block_var_add_star, (l), (a))
00599 #define blockvar_add_block(l,a) dispatch2(block_var_add_block, (l), (a))
00600 
00601 #define method_optarg(m,a) ((a)==Qundef ? (m) : dispatch2(method_add_arg,(m),(a)))
00602 #define method_arg(m,a) dispatch2(method_add_arg,(m),(a))
00603 #define method_add_block(m,b) dispatch2(method_add_block, (m), (b))
00604 
00605 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
00606 
00607 static inline VALUE
00608 new_args_gen(struct parser_params *parser, VALUE f, VALUE o, VALUE r, VALUE p, VALUE tail)
00609 {
00610     NODE *t = (NODE *)tail;
00611     VALUE k = t->u1.value, kr = t->u2.value, b = t->u3.value;
00612     return params_new(f, o, r, p, k, kr, escape_Qundef(b));
00613 }
00614 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
00615 
00616 static inline VALUE
00617 new_args_tail_gen(struct parser_params *parser, VALUE k, VALUE kr, VALUE b)
00618 {
00619     return (VALUE)rb_node_newnode(NODE_MEMO, k, kr, b);
00620 }
00621 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
00622 
00623 #define FIXME 0
00624 
00625 #endif /* RIPPER */
00626 
00627 #ifndef RIPPER
00628 # define Qnone 0
00629 # define ifndef_ripper(x) (x)
00630 #else
00631 # define Qnone Qnil
00632 # define ifndef_ripper(x)
00633 #endif
00634 
00635 #ifndef RIPPER
00636 # define rb_warn0(fmt)    rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt))
00637 # define rb_warnI(fmt,a)  rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
00638 # define rb_warnS(fmt,a)  rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
00639 # define rb_warn4S(file,line,fmt,a)  rb_compile_warn((file), (line), (fmt), (a))
00640 # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt))
00641 # define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt), (a))
00642 #else
00643 # define rb_warn0(fmt)    ripper_warn0(parser, (fmt))
00644 # define rb_warnI(fmt,a)  ripper_warnI(parser, (fmt), (a))
00645 # define rb_warnS(fmt,a)  ripper_warnS(parser, (fmt), (a))
00646 # define rb_warn4S(file,line,fmt,a)  ripper_warnS(parser, (fmt), (a))
00647 # define rb_warning0(fmt) ripper_warning0(parser, (fmt))
00648 # define rb_warningS(fmt,a) ripper_warningS(parser, (fmt), (a))
00649 static void ripper_warn0(struct parser_params*, const char*);
00650 static void ripper_warnI(struct parser_params*, const char*, int);
00651 static void ripper_warnS(struct parser_params*, const char*, const char*);
00652 static void ripper_warning0(struct parser_params*, const char*);
00653 static void ripper_warningS(struct parser_params*, const char*, const char*);
00654 #endif
00655 
00656 #ifdef RIPPER
00657 static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
00658 # define rb_compile_error ripper_compile_error
00659 # define compile_error ripper_compile_error
00660 # define PARSER_ARG parser,
00661 #else
00662 # define rb_compile_error rb_compile_error_with_enc
00663 # define compile_error parser->nerr++,rb_compile_error_with_enc
00664 # define PARSER_ARG ruby_sourcefile, ruby_sourceline, current_enc,
00665 #endif
00666 
00667 /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
00668    for instance).  This is too low for Ruby to parse some files, such as
00669    date/format.rb, therefore bump the value up to at least Bison's default. */
00670 #ifdef OLD_YACC
00671 #ifndef YYMAXDEPTH
00672 #define YYMAXDEPTH 10000
00673 #endif
00674 #endif
00675 
00676 #ifndef RIPPER
00677 static void token_info_push(struct parser_params*, const char *token);
00678 static void token_info_pop(struct parser_params*, const char *token);
00679 #define token_info_push(token) (RTEST(ruby_verbose) ? token_info_push(parser, (token)) : (void)0)
00680 #define token_info_pop(token) (RTEST(ruby_verbose) ? token_info_pop(parser, (token)) : (void)0)
00681 #else
00682 #define token_info_push(token) /* nothing */
00683 #define token_info_pop(token) /* nothing */
00684 #endif
00685 %}
00686 
00687 %pure-parser
00688 %lex-param {struct parser_params *parser}
00689 %parse-param {struct parser_params *parser}
00690 
00691 %union {
00692     VALUE val;
00693     NODE *node;
00694     ID id;
00695     int num;
00696     const struct vtable *vars;
00697 }
00698 
00699 /*%%%*/
00700 %token
00701 /*%
00702 %token <val>
00703 %*/
00704         keyword_class
00705         keyword_module
00706         keyword_def
00707         keyword_undef
00708         keyword_begin
00709         keyword_rescue
00710         keyword_ensure
00711         keyword_end
00712         keyword_if
00713         keyword_unless
00714         keyword_then
00715         keyword_elsif
00716         keyword_else
00717         keyword_case
00718         keyword_when
00719         keyword_while
00720         keyword_until
00721         keyword_for
00722         keyword_break
00723         keyword_next
00724         keyword_redo
00725         keyword_retry
00726         keyword_in
00727         keyword_do
00728         keyword_do_cond
00729         keyword_do_block
00730         keyword_do_LAMBDA
00731         keyword_return
00732         keyword_yield
00733         keyword_super
00734         keyword_self
00735         keyword_nil
00736         keyword_true
00737         keyword_false
00738         keyword_and
00739         keyword_or
00740         keyword_not
00741         modifier_if
00742         modifier_unless
00743         modifier_while
00744         modifier_until
00745         modifier_rescue
00746         keyword_alias
00747         keyword_defined
00748         keyword_BEGIN
00749         keyword_END
00750         keyword__LINE__
00751         keyword__FILE__
00752         keyword__ENCODING__
00753 
00754 %token <id>   tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
00755 %token <node> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
00756 %token <node> tNTH_REF tBACK_REF
00757 %token <num>  tREGEXP_END
00758 
00759 %type <node> singleton strings string string1 xstring regexp
00760 %type <node> string_contents xstring_contents regexp_contents string_content
00761 %type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
00762 %type <node> literal numeric dsym cpath
00763 %type <node> top_compstmt top_stmts top_stmt
00764 %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
00765 %type <node> expr_value arg_value primary_value fcall
00766 %type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
00767 %type <node> args call_args opt_call_args
00768 %type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
00769 %type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
00770 %type <node> command_asgn mrhs superclass block_call block_command
00771 %type <node> f_block_optarg f_block_opt
00772 %type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
00773 %type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
00774 %type <node> block_param opt_block_param block_param_def f_opt
00775 %type <node> f_kwarg f_kw f_block_kwarg f_block_kw
00776 %type <node> bv_decls opt_bv_decl bvar
00777 %type <node> lambda f_larglist lambda_body
00778 %type <node> brace_block cmd_brace_block do_block lhs none fitem
00779 %type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
00780 %type <id>   fsym keyword_variable user_variable sym symbol operation operation2 operation3
00781 %type <id>   cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
00782 %type <id>   f_kwrest
00783 /*%%%*/
00784 /*%
00785 %type <val> program reswords then do dot_or_colon
00786 %*/
00787 %token END_OF_INPUT 0   "end-of-input"
00788 %token tUPLUS           RUBY_TOKEN(UPLUS)  "unary+"
00789 %token tUMINUS          RUBY_TOKEN(UMINUS) "unary-"
00790 %token tPOW             RUBY_TOKEN(POW)    "**"
00791 %token tCMP             RUBY_TOKEN(CMP)    "<=>"
00792 %token tEQ              RUBY_TOKEN(EQ)     "=="
00793 %token tEQQ             RUBY_TOKEN(EQQ)    "==="
00794 %token tNEQ             RUBY_TOKEN(NEQ)    "!="
00795 %token tGEQ             RUBY_TOKEN(GEQ)    ">="
00796 %token tLEQ             RUBY_TOKEN(LEQ)    "<="
00797 %token tANDOP           "&&"
00798 %token tOROP            "||"
00799 %token tMATCH           RUBY_TOKEN(MATCH)  "=~"
00800 %token tNMATCH          RUBY_TOKEN(NMATCH) "!~"
00801 %token tDOT2            RUBY_TOKEN(DOT2)   ".."
00802 %token tDOT3            RUBY_TOKEN(DOT3)   "..."
00803 %token tAREF            RUBY_TOKEN(AREF)   "[]"
00804 %token tASET            RUBY_TOKEN(ASET)   "[]="
00805 %token tLSHFT           RUBY_TOKEN(LSHFT)  "<<"
00806 %token tRSHFT           RUBY_TOKEN(RSHFT)  ">>"
00807 %token tCOLON2          "::"
00808 %token tCOLON3          ":: at EXPR_BEG"
00809 %token <id> tOP_ASGN    /* +=, -=  etc. */
00810 %token tASSOC           "=>"
00811 %token tLPAREN          "("
00812 %token tLPAREN_ARG      "( arg"
00813 %token tRPAREN          ")"
00814 %token tLBRACK          "["
00815 %token tLBRACE          "{"
00816 %token tLBRACE_ARG      "{ arg"
00817 %token tSTAR            "*"
00818 %token tDSTAR           "**arg"
00819 %token tAMPER           "&"
00820 %token tLAMBDA          "->"
00821 %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
00822 %token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG
00823 
00824 /*
00825  *      precedence table
00826  */
00827 
00828 %nonassoc tLOWEST
00829 %nonassoc tLBRACE_ARG
00830 
00831 %nonassoc  modifier_if modifier_unless modifier_while modifier_until
00832 %left  keyword_or keyword_and
00833 %right keyword_not
00834 %nonassoc keyword_defined
00835 %right '=' tOP_ASGN
00836 %left modifier_rescue
00837 %right '?' ':'
00838 %nonassoc tDOT2 tDOT3
00839 %left  tOROP
00840 %left  tANDOP
00841 %nonassoc  tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
00842 %left  '>' tGEQ '<' tLEQ
00843 %left  '|' '^'
00844 %left  '&'
00845 %left  tLSHFT tRSHFT
00846 %left  '+' '-'
00847 %left  '*' '/' '%'
00848 %right tUMINUS_NUM tUMINUS
00849 %right tPOW
00850 %right '!' '~' tUPLUS
00851 
00852 %token tLAST_TOKEN
00853 
00854 %%
00855 program         :  {
00856                         lex_state = EXPR_BEG;
00857                     /*%%%*/
00858                         local_push(compile_for_eval || rb_parse_in_main());
00859                     /*%
00860                         local_push(0);
00861                     %*/
00862                     }
00863                   top_compstmt
00864                     {
00865                     /*%%%*/
00866                         if ($2 && !compile_for_eval) {
00867                             /* last expression should not be void */
00868                             if (nd_type($2) != NODE_BLOCK) void_expr($2);
00869                             else {
00870                                 NODE *node = $2;
00871                                 while (node->nd_next) {
00872                                     node = node->nd_next;
00873                                 }
00874                                 void_expr(node->nd_head);
00875                             }
00876                         }
00877                         ruby_eval_tree = NEW_SCOPE(0, block_append(ruby_eval_tree, $2));
00878                     /*%
00879                         $$ = $2;
00880                         parser->result = dispatch1(program, $$);
00881                     %*/
00882                         local_pop();
00883                     }
00884                 ;
00885 
00886 top_compstmt    : top_stmts opt_terms
00887                     {
00888                     /*%%%*/
00889                         void_stmts($1);
00890                         fixup_nodes(&deferred_nodes);
00891                     /*%
00892                     %*/
00893                         $$ = $1;
00894                     }
00895                 ;
00896 
00897 top_stmts       : none
00898                     {
00899                     /*%%%*/
00900                         $$ = NEW_BEGIN(0);
00901                     /*%
00902                         $$ = dispatch2(stmts_add, dispatch0(stmts_new),
00903                                                   dispatch0(void_stmt));
00904                     %*/
00905                     }
00906                 | top_stmt
00907                     {
00908                     /*%%%*/
00909                         $$ = newline_node($1);
00910                     /*%
00911                         $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
00912                     %*/
00913                     }
00914                 | top_stmts terms top_stmt
00915                     {
00916                     /*%%%*/
00917                         $$ = block_append($1, newline_node($3));
00918                     /*%
00919                         $$ = dispatch2(stmts_add, $1, $3);
00920                     %*/
00921                     }
00922                 | error top_stmt
00923                     {
00924                         $$ = remove_begin($2);
00925                     }
00926                 ;
00927 
00928 top_stmt        : stmt
00929                 | keyword_BEGIN
00930                     {
00931                     /*%%%*/
00932                         /* local_push(0); */
00933                     /*%
00934                     %*/
00935                     }
00936                   '{' top_compstmt '}'
00937                     {
00938                     /*%%%*/
00939                         ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
00940                                                             $4);
00941                         /* NEW_PREEXE($4)); */
00942                         /* local_pop(); */
00943                         $$ = NEW_BEGIN(0);
00944                     /*%
00945                         $$ = dispatch1(BEGIN, $4);
00946                     %*/
00947                     }
00948                 ;
00949 
00950 bodystmt        : compstmt
00951                   opt_rescue
00952                   opt_else
00953                   opt_ensure
00954                     {
00955                     /*%%%*/
00956                         $$ = $1;
00957                         if ($2) {
00958                             $$ = NEW_RESCUE($1, $2, $3);
00959                         }
00960                         else if ($3) {
00961                             rb_warn0("else without rescue is useless");
00962                             $$ = block_append($$, $3);
00963                         }
00964                         if ($4) {
00965                             if ($$) {
00966                                 $$ = NEW_ENSURE($$, $4);
00967                             }
00968                             else {
00969                                 $$ = block_append($4, NEW_NIL());
00970                             }
00971                         }
00972                         fixpos($$, $1);
00973                     /*%
00974                         $$ = dispatch4(bodystmt,
00975                                        escape_Qundef($1),
00976                                        escape_Qundef($2),
00977                                        escape_Qundef($3),
00978                                        escape_Qundef($4));
00979                     %*/
00980                     }
00981                 ;
00982 
00983 compstmt        : stmts opt_terms
00984                     {
00985                     /*%%%*/
00986                         void_stmts($1);
00987                         fixup_nodes(&deferred_nodes);
00988                     /*%
00989                     %*/
00990                         $$ = $1;
00991                     }
00992                 ;
00993 
00994 stmts           : none
00995                     {
00996                     /*%%%*/
00997                         $$ = NEW_BEGIN(0);
00998                     /*%
00999                         $$ = dispatch2(stmts_add, dispatch0(stmts_new),
01000                                                   dispatch0(void_stmt));
01001                     %*/
01002                     }
01003                 | stmt_or_begin
01004                     {
01005                     /*%%%*/
01006                         $$ = newline_node($1);
01007                     /*%
01008                         $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
01009                     %*/
01010                     }
01011                 | stmts terms stmt_or_begin
01012                     {
01013                     /*%%%*/
01014                         $$ = block_append($1, newline_node($3));
01015                     /*%
01016                         $$ = dispatch2(stmts_add, $1, $3);
01017                     %*/
01018                     }
01019                 | error stmt
01020                     {
01021                         $$ = remove_begin($2);
01022                     }
01023                 ;
01024 
01025 stmt_or_begin   : stmt
01026                     {
01027                         $$ = $1;
01028                     }
01029                 | keyword_BEGIN
01030                     {
01031                         yyerror("BEGIN is permitted only at toplevel");
01032                     /*%%%*/
01033                         /* local_push(0); */
01034                     /*%
01035                     %*/
01036                     }
01037                   '{' top_compstmt '}'
01038                     {
01039                     /*%%%*/
01040                         ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
01041                                                             $4);
01042                         /* NEW_PREEXE($4)); */
01043                         /* local_pop(); */
01044                         $$ = NEW_BEGIN(0);
01045                     /*%
01046                         $$ = dispatch1(BEGIN, $4);
01047                     %*/
01048                     }
01049 
01050 stmt            : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
01051                     {
01052                     /*%%%*/
01053                         $$ = NEW_ALIAS($2, $4);
01054                     /*%
01055                         $$ = dispatch2(alias, $2, $4);
01056                     %*/
01057                     }
01058                 | keyword_alias tGVAR tGVAR
01059                     {
01060                     /*%%%*/
01061                         $$ = NEW_VALIAS($2, $3);
01062                     /*%
01063                         $$ = dispatch2(var_alias, $2, $3);
01064                     %*/
01065                     }
01066                 | keyword_alias tGVAR tBACK_REF
01067                     {
01068                     /*%%%*/
01069                         char buf[2];
01070                         buf[0] = '$';
01071                         buf[1] = (char)$3->nd_nth;
01072                         $$ = NEW_VALIAS($2, rb_intern2(buf, 2));
01073                     /*%
01074                         $$ = dispatch2(var_alias, $2, $3);
01075                     %*/
01076                     }
01077                 | keyword_alias tGVAR tNTH_REF
01078                     {
01079                     /*%%%*/
01080                         yyerror("can't make alias for the number variables");
01081                         $$ = NEW_BEGIN(0);
01082                     /*%
01083                         $$ = dispatch2(var_alias, $2, $3);
01084                         $$ = dispatch1(alias_error, $$);
01085                     %*/
01086                     }
01087                 | keyword_undef undef_list
01088                     {
01089                     /*%%%*/
01090                         $$ = $2;
01091                     /*%
01092                         $$ = dispatch1(undef, $2);
01093                     %*/
01094                     }
01095                 | stmt modifier_if expr_value
01096                     {
01097                     /*%%%*/
01098                         $$ = NEW_IF(cond($3), remove_begin($1), 0);
01099                         fixpos($$, $3);
01100                     /*%
01101                         $$ = dispatch2(if_mod, $3, $1);
01102                     %*/
01103                     }
01104                 | stmt modifier_unless expr_value
01105                     {
01106                     /*%%%*/
01107                         $$ = NEW_UNLESS(cond($3), remove_begin($1), 0);
01108                         fixpos($$, $3);
01109                     /*%
01110                         $$ = dispatch2(unless_mod, $3, $1);
01111                     %*/
01112                     }
01113                 | stmt modifier_while expr_value
01114                     {
01115                     /*%%%*/
01116                         if ($1 && nd_type($1) == NODE_BEGIN) {
01117                             $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
01118                         }
01119                         else {
01120                             $$ = NEW_WHILE(cond($3), $1, 1);
01121                         }
01122                     /*%
01123                         $$ = dispatch2(while_mod, $3, $1);
01124                     %*/
01125                     }
01126                 | stmt modifier_until expr_value
01127                     {
01128                     /*%%%*/
01129                         if ($1 && nd_type($1) == NODE_BEGIN) {
01130                             $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
01131                         }
01132                         else {
01133                             $$ = NEW_UNTIL(cond($3), $1, 1);
01134                         }
01135                     /*%
01136                         $$ = dispatch2(until_mod, $3, $1);
01137                     %*/
01138                     }
01139                 | stmt modifier_rescue stmt
01140                     {
01141                     /*%%%*/
01142                         NODE *resq = NEW_RESBODY(0, remove_begin($3), 0);
01143                         $$ = NEW_RESCUE(remove_begin($1), resq, 0);
01144                     /*%
01145                         $$ = dispatch2(rescue_mod, $1, $3);
01146                     %*/
01147                     }
01148                 | keyword_END '{' compstmt '}'
01149                     {
01150                         if (in_def || in_single) {
01151                             rb_warn0("END in method; use at_exit");
01152                         }
01153                     /*%%%*/
01154                         $$ = NEW_POSTEXE(NEW_NODE(
01155                             NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */));
01156                     /*%
01157                         $$ = dispatch1(END, $3);
01158                     %*/
01159                     }
01160                 | command_asgn
01161                 | mlhs '=' command_call
01162                     {
01163                     /*%%%*/
01164                         value_expr($3);
01165                         $1->nd_value = $3;
01166                         $$ = $1;
01167                     /*%
01168                         $$ = dispatch2(massign, $1, $3);
01169                     %*/
01170                     }
01171                 | var_lhs tOP_ASGN command_call
01172                     {
01173                         value_expr($3);
01174                         $$ = new_op_assign($1, $2, $3);
01175                     }
01176                 | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
01177                     {
01178                     /*%%%*/
01179                         NODE *args;
01180 
01181                         value_expr($6);
01182                         if (!$3) $3 = NEW_ZARRAY();
01183                         args = arg_concat($3, $6);
01184                         if ($5 == tOROP) {
01185                             $5 = 0;
01186                         }
01187                         else if ($5 == tANDOP) {
01188                             $5 = 1;
01189                         }
01190                         $$ = NEW_OP_ASGN1($1, $5, args);
01191                         fixpos($$, $1);
01192                     /*%
01193                         $$ = dispatch2(aref_field, $1, escape_Qundef($3));
01194                         $$ = dispatch3(opassign, $$, $5, $6);
01195                     %*/
01196                     }
01197                 | primary_value '.' tIDENTIFIER tOP_ASGN command_call
01198                     {
01199                         value_expr($5);
01200                         $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
01201                     }
01202                 | primary_value '.' tCONSTANT tOP_ASGN command_call
01203                     {
01204                         value_expr($5);
01205                         $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
01206                     }
01207                 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
01208                     {
01209                     /*%%%*/
01210                         $$ = NEW_COLON2($1, $3);
01211                         $$ = new_const_op_assign($$, $4, $5);
01212                     /*%
01213                         $$ = dispatch2(const_path_field, $1, $3);
01214                         $$ = dispatch3(opassign, $$, $4, $5);
01215                     %*/
01216                     }
01217                 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
01218                     {
01219                         value_expr($5);
01220                         $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
01221                     }
01222                 | backref tOP_ASGN command_call
01223                     {
01224                     /*%%%*/
01225                         rb_backref_error($1);
01226                         $$ = NEW_BEGIN(0);
01227                     /*%
01228                         $$ = dispatch2(assign, dispatch1(var_field, $1), $3);
01229                         $$ = dispatch1(assign_error, $$);
01230                     %*/
01231                     }
01232                 | lhs '=' mrhs
01233                     {
01234                     /*%%%*/
01235                         value_expr($3);
01236                         $$ = node_assign($1, $3);
01237                     /*%
01238                         $$ = dispatch2(assign, $1, $3);
01239                     %*/
01240                     }
01241                 | mlhs '=' arg_value
01242                     {
01243                     /*%%%*/
01244                         $1->nd_value = $3;
01245                         $$ = $1;
01246                     /*%
01247                         $$ = dispatch2(massign, $1, $3);
01248                     %*/
01249                     }
01250                 | mlhs '=' mrhs
01251                     {
01252                     /*%%%*/
01253                         $1->nd_value = $3;
01254                         $$ = $1;
01255                     /*%
01256                         $$ = dispatch2(massign, $1, $3);
01257                     %*/
01258                     }
01259                 | expr
01260                 ;
01261 
01262 command_asgn    : lhs '=' command_call
01263                     {
01264                     /*%%%*/
01265                         value_expr($3);
01266                         $$ = node_assign($1, $3);
01267                     /*%
01268                         $$ = dispatch2(assign, $1, $3);
01269                     %*/
01270                     }
01271                 | lhs '=' command_asgn
01272                     {
01273                     /*%%%*/
01274                         value_expr($3);
01275                         $$ = node_assign($1, $3);
01276                     /*%
01277                         $$ = dispatch2(assign, $1, $3);
01278                     %*/
01279                     }
01280                 ;
01281 
01282 
01283 expr            : command_call
01284                 | expr keyword_and expr
01285                     {
01286                     /*%%%*/
01287                         $$ = logop(NODE_AND, $1, $3);
01288                     /*%
01289                         $$ = dispatch3(binary, $1, ripper_intern("and"), $3);
01290                     %*/
01291                     }
01292                 | expr keyword_or expr
01293                     {
01294                     /*%%%*/
01295                         $$ = logop(NODE_OR, $1, $3);
01296                     /*%
01297                         $$ = dispatch3(binary, $1, ripper_intern("or"), $3);
01298                     %*/
01299                     }
01300                 | keyword_not opt_nl expr
01301                     {
01302                     /*%%%*/
01303                         $$ = call_uni_op(cond($3), '!');
01304                     /*%
01305                         $$ = dispatch2(unary, ripper_intern("not"), $3);
01306                     %*/
01307                     }
01308                 | '!' command_call
01309                     {
01310                     /*%%%*/
01311                         $$ = call_uni_op(cond($2), '!');
01312                     /*%
01313                         $$ = dispatch2(unary, ripper_id2sym('!'), $2);
01314                     %*/
01315                     }
01316                 | arg
01317                 ;
01318 
01319 expr_value      : expr
01320                     {
01321                     /*%%%*/
01322                         value_expr($1);
01323                         $$ = $1;
01324                         if (!$$) $$ = NEW_NIL();
01325                     /*%
01326                         $$ = $1;
01327                     %*/
01328                     }
01329                 ;
01330 
01331 command_call    : command
01332                 | block_command
01333                 ;
01334 
01335 block_command   : block_call
01336                 | block_call dot_or_colon operation2 command_args
01337                     {
01338                     /*%%%*/
01339                         $$ = NEW_CALL($1, $3, $4);
01340                     /*%
01341                         $$ = dispatch3(call, $1, $2, $3);
01342                         $$ = method_arg($$, $4);
01343                     %*/
01344                     }
01345                 ;
01346 
01347 cmd_brace_block : tLBRACE_ARG
01348                     {
01349                         $<vars>1 = dyna_push();
01350                     /*%%%*/
01351                         $<num>$ = ruby_sourceline;
01352                     /*%
01353                     %*/
01354                     }
01355                   opt_block_param
01356                   compstmt
01357                   '}'
01358                     {
01359                     /*%%%*/
01360                         $$ = NEW_ITER($3,$4);
01361                         nd_set_line($$, $<num>2);
01362                     /*%
01363                         $$ = dispatch2(brace_block, escape_Qundef($3), $4);
01364                     %*/
01365                         dyna_pop($<vars>1);
01366                     }
01367                 ;
01368 
01369 fcall           : operation
01370                     {
01371                     /*%%%*/
01372                         $$ = NEW_FCALL($1, 0);
01373                         nd_set_line($$, tokline);
01374                     /*%
01375                     %*/
01376                     }
01377                 ;
01378 
01379 command         : fcall command_args       %prec tLOWEST
01380                     {
01381                     /*%%%*/
01382                         $$ = $1;
01383                         $$->nd_args = $2;
01384                     /*%
01385                         $$ = dispatch2(command, $1, $2);
01386                     %*/
01387                     }
01388                 | fcall command_args cmd_brace_block
01389                     {
01390                     /*%%%*/
01391                         block_dup_check($2,$3);
01392                         $1->nd_args = $2;
01393                         $3->nd_iter = $1;
01394                         $$ = $3;
01395                         fixpos($$, $1);
01396                     /*%
01397                         $$ = dispatch2(command, $1, $2);
01398                         $$ = method_add_block($$, $3);
01399                     %*/
01400                     }
01401                 | primary_value '.' operation2 command_args     %prec tLOWEST
01402                     {
01403                     /*%%%*/
01404                         $$ = NEW_CALL($1, $3, $4);
01405                         fixpos($$, $1);
01406                     /*%
01407                         $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
01408                     %*/
01409                     }
01410                 | primary_value '.' operation2 command_args cmd_brace_block
01411                     {
01412                     /*%%%*/
01413                         block_dup_check($4,$5);
01414                         $5->nd_iter = NEW_CALL($1, $3, $4);
01415                         $$ = $5;
01416                         fixpos($$, $1);
01417                     /*%
01418                         $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
01419                         $$ = method_add_block($$, $5);
01420                     %*/
01421                    }
01422                 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
01423                     {
01424                     /*%%%*/
01425                         $$ = NEW_CALL($1, $3, $4);
01426                         fixpos($$, $1);
01427                     /*%
01428                         $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
01429                     %*/
01430                     }
01431                 | primary_value tCOLON2 operation2 command_args cmd_brace_block
01432                     {
01433                     /*%%%*/
01434                         block_dup_check($4,$5);
01435                         $5->nd_iter = NEW_CALL($1, $3, $4);
01436                         $$ = $5;
01437                         fixpos($$, $1);
01438                     /*%
01439                         $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
01440                         $$ = method_add_block($$, $5);
01441                     %*/
01442                    }
01443                 | keyword_super command_args
01444                     {
01445                     /*%%%*/
01446                         $$ = NEW_SUPER($2);
01447                         fixpos($$, $2);
01448                     /*%
01449                         $$ = dispatch1(super, $2);
01450                     %*/
01451                     }
01452                 | keyword_yield command_args
01453                     {
01454                     /*%%%*/
01455                         $$ = new_yield($2);
01456                         fixpos($$, $2);
01457                     /*%
01458                         $$ = dispatch1(yield, $2);
01459                     %*/
01460                     }
01461                 | keyword_return call_args
01462                     {
01463                     /*%%%*/
01464                         $$ = NEW_RETURN(ret_args($2));
01465                     /*%
01466                         $$ = dispatch1(return, $2);
01467                     %*/
01468                     }
01469                 | keyword_break call_args
01470                     {
01471                     /*%%%*/
01472                         $$ = NEW_BREAK(ret_args($2));
01473                     /*%
01474                         $$ = dispatch1(break, $2);
01475                     %*/
01476                     }
01477                 | keyword_next call_args
01478                     {
01479                     /*%%%*/
01480                         $$ = NEW_NEXT(ret_args($2));
01481                     /*%
01482                         $$ = dispatch1(next, $2);
01483                     %*/
01484                     }
01485                 ;
01486 
01487 mlhs            : mlhs_basic
01488                 | tLPAREN mlhs_inner rparen
01489                     {
01490                     /*%%%*/
01491                         $$ = $2;
01492                     /*%
01493                         $$ = dispatch1(mlhs_paren, $2);
01494                     %*/
01495                     }
01496                 ;
01497 
01498 mlhs_inner      : mlhs_basic
01499                 | tLPAREN mlhs_inner rparen
01500                     {
01501                     /*%%%*/
01502                         $$ = NEW_MASGN(NEW_LIST($2), 0);
01503                     /*%
01504                         $$ = dispatch1(mlhs_paren, $2);
01505                     %*/
01506                     }
01507                 ;
01508 
01509 mlhs_basic      : mlhs_head
01510                     {
01511                     /*%%%*/
01512                         $$ = NEW_MASGN($1, 0);
01513                     /*%
01514                         $$ = $1;
01515                     %*/
01516                     }
01517                 | mlhs_head mlhs_item
01518                     {
01519                     /*%%%*/
01520                         $$ = NEW_MASGN(list_append($1,$2), 0);
01521                     /*%
01522                         $$ = mlhs_add($1, $2);
01523                     %*/
01524                     }
01525                 | mlhs_head tSTAR mlhs_node
01526                     {
01527                     /*%%%*/
01528                         $$ = NEW_MASGN($1, $3);
01529                     /*%
01530                         $$ = mlhs_add_star($1, $3);
01531                     %*/
01532                     }
01533                 | mlhs_head tSTAR mlhs_node ',' mlhs_post
01534                     {
01535                     /*%%%*/
01536                         $$ = NEW_MASGN($1, NEW_POSTARG($3,$5));
01537                     /*%
01538                         $1 = mlhs_add_star($1, $3);
01539                         $$ = mlhs_add($1, $5);
01540                     %*/
01541                     }
01542                 | mlhs_head tSTAR
01543                     {
01544                     /*%%%*/
01545                         $$ = NEW_MASGN($1, -1);
01546                     /*%
01547                         $$ = mlhs_add_star($1, Qnil);
01548                     %*/
01549                     }
01550                 | mlhs_head tSTAR ',' mlhs_post
01551                     {
01552                     /*%%%*/
01553                         $$ = NEW_MASGN($1, NEW_POSTARG(-1, $4));
01554                     /*%
01555                         $1 = mlhs_add_star($1, Qnil);
01556                         $$ = mlhs_add($1, $4);
01557                     %*/
01558                     }
01559                 | tSTAR mlhs_node
01560                     {
01561                     /*%%%*/
01562                         $$ = NEW_MASGN(0, $2);
01563                     /*%
01564                         $$ = mlhs_add_star(mlhs_new(), $2);
01565                     %*/
01566                     }
01567                 | tSTAR mlhs_node ',' mlhs_post
01568                     {
01569                     /*%%%*/
01570                         $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
01571                     /*%
01572                         $2 = mlhs_add_star(mlhs_new(), $2);
01573                         $$ = mlhs_add($2, $4);
01574                     %*/
01575                     }
01576                 | tSTAR
01577                     {
01578                     /*%%%*/
01579                         $$ = NEW_MASGN(0, -1);
01580                     /*%
01581                         $$ = mlhs_add_star(mlhs_new(), Qnil);
01582                     %*/
01583                     }
01584                 | tSTAR ',' mlhs_post
01585                     {
01586                     /*%%%*/
01587                         $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
01588                     /*%
01589                         $$ = mlhs_add_star(mlhs_new(), Qnil);
01590                         $$ = mlhs_add($$, $3);
01591                     %*/
01592                     }
01593                 ;
01594 
01595 mlhs_item       : mlhs_node
01596                 | tLPAREN mlhs_inner rparen
01597                     {
01598                     /*%%%*/
01599                         $$ = $2;
01600                     /*%
01601                         $$ = dispatch1(mlhs_paren, $2);
01602                     %*/
01603                     }
01604                 ;
01605 
01606 mlhs_head       : mlhs_item ','
01607                     {
01608                     /*%%%*/
01609                         $$ = NEW_LIST($1);
01610                     /*%
01611                         $$ = mlhs_add(mlhs_new(), $1);
01612                     %*/
01613                     }
01614                 | mlhs_head mlhs_item ','
01615                     {
01616                     /*%%%*/
01617                         $$ = list_append($1, $2);
01618                     /*%
01619                         $$ = mlhs_add($1, $2);
01620                     %*/
01621                     }
01622                 ;
01623 
01624 mlhs_post       : mlhs_item
01625                     {
01626                     /*%%%*/
01627                         $$ = NEW_LIST($1);
01628                     /*%
01629                         $$ = mlhs_add(mlhs_new(), $1);
01630                     %*/
01631                     }
01632                 | mlhs_post ',' mlhs_item
01633                     {
01634                     /*%%%*/
01635                         $$ = list_append($1, $3);
01636                     /*%
01637                         $$ = mlhs_add($1, $3);
01638                     %*/
01639                     }
01640                 ;
01641 
01642 mlhs_node       : user_variable
01643                     {
01644                         $$ = assignable($1, 0);
01645                     }
01646                 | keyword_variable
01647                     {
01648                         $$ = assignable($1, 0);
01649                     }
01650                 | primary_value '[' opt_call_args rbracket
01651                     {
01652                     /*%%%*/
01653                         $$ = aryset($1, $3);
01654                     /*%
01655                         $$ = dispatch2(aref_field, $1, escape_Qundef($3));
01656                     %*/
01657                     }
01658                 | primary_value '.' tIDENTIFIER
01659                     {
01660                     /*%%%*/
01661                         $$ = attrset($1, $3);
01662                     /*%
01663                         $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
01664                     %*/
01665                     }
01666                 | primary_value tCOLON2 tIDENTIFIER
01667                     {
01668                     /*%%%*/
01669                         $$ = attrset($1, $3);
01670                     /*%
01671                         $$ = dispatch2(const_path_field, $1, $3);
01672                     %*/
01673                     }
01674                 | primary_value '.' tCONSTANT
01675                     {
01676                     /*%%%*/
01677                         $$ = attrset($1, $3);
01678                     /*%
01679                         $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
01680                     %*/
01681                     }
01682                 | primary_value tCOLON2 tCONSTANT
01683                     {
01684                     /*%%%*/
01685                         if (in_def || in_single)
01686                             yyerror("dynamic constant assignment");
01687                         $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
01688                     /*%
01689                         if (in_def || in_single)
01690                             yyerror("dynamic constant assignment");
01691                         $$ = dispatch2(const_path_field, $1, $3);
01692                     %*/
01693                     }
01694                 | tCOLON3 tCONSTANT
01695                     {
01696                     /*%%%*/
01697                         if (in_def || in_single)
01698                             yyerror("dynamic constant assignment");
01699                         $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
01700                     /*%
01701                         $$ = dispatch1(top_const_field, $2);
01702                     %*/
01703                     }
01704                 | backref
01705                     {
01706                     /*%%%*/
01707                         rb_backref_error($1);
01708                         $$ = NEW_BEGIN(0);
01709                     /*%
01710                         $$ = dispatch1(var_field, $1);
01711                         $$ = dispatch1(assign_error, $$);
01712                     %*/
01713                     }
01714                 ;
01715 
01716 lhs             : user_variable
01717                     {
01718                         $$ = assignable($1, 0);
01719                     /*%%%*/
01720                         if (!$$) $$ = NEW_BEGIN(0);
01721                     /*%
01722                         $$ = dispatch1(var_field, $$);
01723                     %*/
01724                     }
01725                 | keyword_variable
01726                     {
01727                         $$ = assignable($1, 0);
01728                     /*%%%*/
01729                         if (!$$) $$ = NEW_BEGIN(0);
01730                     /*%
01731                         $$ = dispatch1(var_field, $$);
01732                     %*/
01733                     }
01734                 | primary_value '[' opt_call_args rbracket
01735                     {
01736                     /*%%%*/
01737                         $$ = aryset($1, $3);
01738                     /*%
01739                         $$ = dispatch2(aref_field, $1, escape_Qundef($3));
01740                     %*/
01741                     }
01742                 | primary_value '.' tIDENTIFIER
01743                     {
01744                     /*%%%*/
01745                         $$ = attrset($1, $3);
01746                     /*%
01747                         $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
01748                     %*/
01749                     }
01750                 | primary_value tCOLON2 tIDENTIFIER
01751                     {
01752                     /*%%%*/
01753                         $$ = attrset($1, $3);
01754                     /*%
01755                         $$ = dispatch3(field, $1, ripper_intern("::"), $3);
01756                     %*/
01757                     }
01758                 | primary_value '.' tCONSTANT
01759                     {
01760                     /*%%%*/
01761                         $$ = attrset($1, $3);
01762                     /*%
01763                         $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
01764                     %*/
01765                     }
01766                 | primary_value tCOLON2 tCONSTANT
01767                     {
01768                     /*%%%*/
01769                         if (in_def || in_single)
01770                             yyerror("dynamic constant assignment");
01771                         $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
01772                     /*%
01773                         $$ = dispatch2(const_path_field, $1, $3);
01774                         if (in_def || in_single) {
01775                             $$ = dispatch1(assign_error, $$);
01776                         }
01777                     %*/
01778                     }
01779                 | tCOLON3 tCONSTANT
01780                     {
01781                     /*%%%*/
01782                         if (in_def || in_single)
01783                             yyerror("dynamic constant assignment");
01784                         $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
01785                     /*%
01786                         $$ = dispatch1(top_const_field, $2);
01787                         if (in_def || in_single) {
01788                             $$ = dispatch1(assign_error, $$);
01789                         }
01790                     %*/
01791                     }
01792                 | backref
01793                     {
01794                     /*%%%*/
01795                         rb_backref_error($1);
01796                         $$ = NEW_BEGIN(0);
01797                     /*%
01798                         $$ = dispatch1(assign_error, $1);
01799                     %*/
01800                     }
01801                 ;
01802 
01803 cname           : tIDENTIFIER
01804                     {
01805                     /*%%%*/
01806                         yyerror("class/module name must be CONSTANT");
01807                     /*%
01808                         $$ = dispatch1(class_name_error, $1);
01809                     %*/
01810                     }
01811                 | tCONSTANT
01812                 ;
01813 
01814 cpath           : tCOLON3 cname
01815                     {
01816                     /*%%%*/
01817                         $$ = NEW_COLON3($2);
01818                     /*%
01819                         $$ = dispatch1(top_const_ref, $2);
01820                     %*/
01821                     }
01822                 | cname
01823                     {
01824                     /*%%%*/
01825                         $$ = NEW_COLON2(0, $$);
01826                     /*%
01827                         $$ = dispatch1(const_ref, $1);
01828                     %*/
01829                     }
01830                 | primary_value tCOLON2 cname
01831                     {
01832                     /*%%%*/
01833                         $$ = NEW_COLON2($1, $3);
01834                     /*%
01835                         $$ = dispatch2(const_path_ref, $1, $3);
01836                     %*/
01837                     }
01838                 ;
01839 
01840 fname           : tIDENTIFIER
01841                 | tCONSTANT
01842                 | tFID
01843                 | op
01844                     {
01845                         lex_state = EXPR_ENDFN;
01846                         $$ = $1;
01847                     }
01848                 | reswords
01849                     {
01850                         lex_state = EXPR_ENDFN;
01851                     /*%%%*/
01852                         $$ = $<id>1;
01853                     /*%
01854                         $$ = $1;
01855                     %*/
01856                     }
01857                 ;
01858 
01859 fsym            : fname
01860                 | symbol
01861                 ;
01862 
01863 fitem           : fsym
01864                     {
01865                     /*%%%*/
01866                         $$ = NEW_LIT(ID2SYM($1));
01867                     /*%
01868                         $$ = dispatch1(symbol_literal, $1);
01869                     %*/
01870                     }
01871                 | dsym
01872                 ;
01873 
01874 undef_list      : fitem
01875                     {
01876                     /*%%%*/
01877                         $$ = NEW_UNDEF($1);
01878                     /*%
01879                         $$ = rb_ary_new3(1, $1);
01880                     %*/
01881                     }
01882                 | undef_list ',' {lex_state = EXPR_FNAME;} fitem
01883                     {
01884                     /*%%%*/
01885                         $$ = block_append($1, NEW_UNDEF($4));
01886                     /*%
01887                         rb_ary_push($1, $4);
01888                     %*/
01889                     }
01890                 ;
01891 
01892 op              : '|'           { ifndef_ripper($$ = '|'); }
01893                 | '^'           { ifndef_ripper($$ = '^'); }
01894                 | '&'           { ifndef_ripper($$ = '&'); }
01895                 | tCMP          { ifndef_ripper($$ = tCMP); }
01896                 | tEQ           { ifndef_ripper($$ = tEQ); }
01897                 | tEQQ          { ifndef_ripper($$ = tEQQ); }
01898                 | tMATCH        { ifndef_ripper($$ = tMATCH); }
01899                 | tNMATCH       { ifndef_ripper($$ = tNMATCH); }
01900                 | '>'           { ifndef_ripper($$ = '>'); }
01901                 | tGEQ          { ifndef_ripper($$ = tGEQ); }
01902                 | '<'           { ifndef_ripper($$ = '<'); }
01903                 | tLEQ          { ifndef_ripper($$ = tLEQ); }
01904                 | tNEQ          { ifndef_ripper($$ = tNEQ); }
01905                 | tLSHFT        { ifndef_ripper($$ = tLSHFT); }
01906                 | tRSHFT        { ifndef_ripper($$ = tRSHFT); }
01907                 | '+'           { ifndef_ripper($$ = '+'); }
01908                 | '-'           { ifndef_ripper($$ = '-'); }
01909                 | '*'           { ifndef_ripper($$ = '*'); }
01910                 | tSTAR         { ifndef_ripper($$ = '*'); }
01911                 | '/'           { ifndef_ripper($$ = '/'); }
01912                 | '%'           { ifndef_ripper($$ = '%'); }
01913                 | tPOW          { ifndef_ripper($$ = tPOW); }
01914                 | tDSTAR        { ifndef_ripper($$ = tDSTAR); }
01915                 | '!'           { ifndef_ripper($$ = '!'); }
01916                 | '~'           { ifndef_ripper($$ = '~'); }
01917                 | tUPLUS        { ifndef_ripper($$ = tUPLUS); }
01918                 | tUMINUS       { ifndef_ripper($$ = tUMINUS); }
01919                 | tAREF         { ifndef_ripper($$ = tAREF); }
01920                 | tASET         { ifndef_ripper($$ = tASET); }
01921                 | '`'           { ifndef_ripper($$ = '`'); }
01922                 ;
01923 
01924 reswords        : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
01925                 | keyword_BEGIN | keyword_END
01926                 | keyword_alias | keyword_and | keyword_begin
01927                 | keyword_break | keyword_case | keyword_class | keyword_def
01928                 | keyword_defined | keyword_do | keyword_else | keyword_elsif
01929                 | keyword_end | keyword_ensure | keyword_false
01930                 | keyword_for | keyword_in | keyword_module | keyword_next
01931                 | keyword_nil | keyword_not | keyword_or | keyword_redo
01932                 | keyword_rescue | keyword_retry | keyword_return | keyword_self
01933                 | keyword_super | keyword_then | keyword_true | keyword_undef
01934                 | keyword_when | keyword_yield | keyword_if | keyword_unless
01935                 | keyword_while | keyword_until
01936                 ;
01937 
01938 arg             : lhs '=' arg
01939                     {
01940                     /*%%%*/
01941                         value_expr($3);
01942                         $$ = node_assign($1, $3);
01943                     /*%
01944                         $$ = dispatch2(assign, $1, $3);
01945                     %*/
01946                     }
01947                 | lhs '=' arg modifier_rescue arg
01948                     {
01949                     /*%%%*/
01950                         value_expr($3);
01951                         $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
01952                         $$ = node_assign($1, $3);
01953                     /*%
01954                         $$ = dispatch2(assign, $1, dispatch2(rescue_mod, $3, $5));
01955                     %*/
01956                     }
01957                 | var_lhs tOP_ASGN arg
01958                     {
01959                         value_expr($3);
01960                         $$ = new_op_assign($1, $2, $3);
01961                     }
01962                 | var_lhs tOP_ASGN arg modifier_rescue arg
01963                     {
01964                     /*%%%*/
01965                         value_expr($3);
01966                         $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
01967                     /*%
01968                         $3 = dispatch2(rescue_mod, $3, $5);
01969                     %*/
01970                         $$ = new_op_assign($1, $2, $3);
01971                     }
01972                 | primary_value '[' opt_call_args rbracket tOP_ASGN arg
01973                     {
01974                     /*%%%*/
01975                         NODE *args;
01976 
01977                         value_expr($6);
01978                         if (!$3) $3 = NEW_ZARRAY();
01979                         if (nd_type($3) == NODE_BLOCK_PASS) {
01980                             args = NEW_ARGSCAT($3, $6);
01981                         }
01982                         else {
01983                             args = arg_concat($3, $6);
01984                         }
01985                         if ($5 == tOROP) {
01986                             $5 = 0;
01987                         }
01988                         else if ($5 == tANDOP) {
01989                             $5 = 1;
01990                         }
01991                         $$ = NEW_OP_ASGN1($1, $5, args);
01992                         fixpos($$, $1);
01993                     /*%
01994                         $1 = dispatch2(aref_field, $1, escape_Qundef($3));
01995                         $$ = dispatch3(opassign, $1, $5, $6);
01996                     %*/
01997                     }
01998                 | primary_value '.' tIDENTIFIER tOP_ASGN arg
01999                     {
02000                         value_expr($5);
02001                         $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
02002                     }
02003                 | primary_value '.' tCONSTANT tOP_ASGN arg
02004                     {
02005                         value_expr($5);
02006                         $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
02007                     }
02008                 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
02009                     {
02010                         value_expr($5);
02011                         $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
02012                     }
02013                 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
02014                     {
02015                     /*%%%*/
02016                         $$ = NEW_COLON2($1, $3);
02017                         $$ = new_const_op_assign($$, $4, $5);
02018                     /*%
02019                         $$ = dispatch2(const_path_field, $1, $3);
02020                         $$ = dispatch3(opassign, $$, $4, $5);
02021                     %*/
02022                     }
02023                 | tCOLON3 tCONSTANT tOP_ASGN arg
02024                     {
02025                     /*%%%*/
02026                         $$ = NEW_COLON3($2);
02027                         $$ = new_const_op_assign($$, $3, $4);
02028                     /*%
02029                         $$ = dispatch1(top_const_field, $2);
02030                         $$ = dispatch3(opassign, $$, $3, $4);
02031                     %*/
02032                     }
02033                 | backref tOP_ASGN arg
02034                     {
02035                     /*%%%*/
02036                         rb_backref_error($1);
02037                         $$ = NEW_BEGIN(0);
02038                     /*%
02039                         $$ = dispatch1(var_field, $1);
02040                         $$ = dispatch3(opassign, $$, $2, $3);
02041                         $$ = dispatch1(assign_error, $$);
02042                     %*/
02043                     }
02044                 | arg tDOT2 arg
02045                     {
02046                     /*%%%*/
02047                         value_expr($1);
02048                         value_expr($3);
02049                         $$ = NEW_DOT2($1, $3);
02050                         if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
02051                             nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
02052                             deferred_nodes = list_append(deferred_nodes, $$);
02053                         }
02054                     /*%
02055                         $$ = dispatch2(dot2, $1, $3);
02056                     %*/
02057                     }
02058                 | arg tDOT3 arg
02059                     {
02060                     /*%%%*/
02061                         value_expr($1);
02062                         value_expr($3);
02063                         $$ = NEW_DOT3($1, $3);
02064                         if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
02065                             nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
02066                             deferred_nodes = list_append(deferred_nodes, $$);
02067                         }
02068                     /*%
02069                         $$ = dispatch2(dot3, $1, $3);
02070                     %*/
02071                     }
02072                 | arg '+' arg
02073                     {
02074                     /*%%%*/
02075                         $$ = call_bin_op($1, '+', $3);
02076                     /*%
02077                         $$ = dispatch3(binary, $1, ID2SYM('+'), $3);
02078                     %*/
02079                     }
02080                 | arg '-' arg
02081                     {
02082                     /*%%%*/
02083                         $$ = call_bin_op($1, '-', $3);
02084                     /*%
02085                         $$ = dispatch3(binary, $1, ID2SYM('-'), $3);
02086                     %*/
02087                     }
02088                 | arg '*' arg
02089                     {
02090                     /*%%%*/
02091                         $$ = call_bin_op($1, '*', $3);
02092                     /*%
02093                         $$ = dispatch3(binary, $1, ID2SYM('*'), $3);
02094                     %*/
02095                     }
02096                 | arg '/' arg
02097                     {
02098                     /*%%%*/
02099                         $$ = call_bin_op($1, '/', $3);
02100                     /*%
02101                         $$ = dispatch3(binary, $1, ID2SYM('/'), $3);
02102                     %*/
02103                     }
02104                 | arg '%' arg
02105                     {
02106                     /*%%%*/
02107                         $$ = call_bin_op($1, '%', $3);
02108                     /*%
02109                         $$ = dispatch3(binary, $1, ID2SYM('%'), $3);
02110                     %*/
02111                     }
02112                 | arg tPOW arg
02113                     {
02114                     /*%%%*/
02115                         $$ = call_bin_op($1, tPOW, $3);
02116                     /*%
02117                         $$ = dispatch3(binary, $1, ripper_intern("**"), $3);
02118                     %*/
02119                     }
02120                 | tUMINUS_NUM tINTEGER tPOW arg
02121                     {
02122                     /*%%%*/
02123                         $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
02124                     /*%
02125                         $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
02126                         $$ = dispatch2(unary, ripper_intern("-@"), $$);
02127                     %*/
02128                     }
02129                 | tUMINUS_NUM tFLOAT tPOW arg
02130                     {
02131                     /*%%%*/
02132                         $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
02133                     /*%
02134                         $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
02135                         $$ = dispatch2(unary, ripper_intern("-@"), $$);
02136                     %*/
02137                     }
02138                 | tUPLUS arg
02139                     {
02140                     /*%%%*/
02141                         $$ = call_uni_op($2, tUPLUS);
02142                     /*%
02143                         $$ = dispatch2(unary, ripper_intern("+@"), $2);
02144                     %*/
02145                     }
02146                 | tUMINUS arg
02147                     {
02148                     /*%%%*/
02149                         $$ = call_uni_op($2, tUMINUS);
02150                     /*%
02151                         $$ = dispatch2(unary, ripper_intern("-@"), $2);
02152                     %*/
02153                     }
02154                 | arg '|' arg
02155                     {
02156                     /*%%%*/
02157                         $$ = call_bin_op($1, '|', $3);
02158                     /*%
02159                         $$ = dispatch3(binary, $1, ID2SYM('|'), $3);
02160                     %*/
02161                     }
02162                 | arg '^' arg
02163                     {
02164                     /*%%%*/
02165                         $$ = call_bin_op($1, '^', $3);
02166                     /*%
02167                         $$ = dispatch3(binary, $1, ID2SYM('^'), $3);
02168                     %*/
02169                     }
02170                 | arg '&' arg
02171                     {
02172                     /*%%%*/
02173                         $$ = call_bin_op($1, '&', $3);
02174                     /*%
02175                         $$ = dispatch3(binary, $1, ID2SYM('&'), $3);
02176                     %*/
02177                     }
02178                 | arg tCMP arg
02179                     {
02180                     /*%%%*/
02181                         $$ = call_bin_op($1, tCMP, $3);
02182                     /*%
02183                         $$ = dispatch3(binary, $1, ripper_intern("<=>"), $3);
02184                     %*/
02185                     }
02186                 | arg '>' arg
02187                     {
02188                     /*%%%*/
02189                         $$ = call_bin_op($1, '>', $3);
02190                     /*%
02191                         $$ = dispatch3(binary, $1, ID2SYM('>'), $3);
02192                     %*/
02193                     }
02194                 | arg tGEQ arg
02195                     {
02196                     /*%%%*/
02197                         $$ = call_bin_op($1, tGEQ, $3);
02198                     /*%
02199                         $$ = dispatch3(binary, $1, ripper_intern(">="), $3);
02200                     %*/
02201                     }
02202                 | arg '<' arg
02203                     {
02204                     /*%%%*/
02205                         $$ = call_bin_op($1, '<', $3);
02206                     /*%
02207                         $$ = dispatch3(binary, $1, ID2SYM('<'), $3);
02208                     %*/
02209                     }
02210                 | arg tLEQ arg
02211                     {
02212                     /*%%%*/
02213                         $$ = call_bin_op($1, tLEQ, $3);
02214                     /*%
02215                         $$ = dispatch3(binary, $1, ripper_intern("<="), $3);
02216                     %*/
02217                     }
02218                 | arg tEQ arg
02219                     {
02220                     /*%%%*/
02221                         $$ = call_bin_op($1, tEQ, $3);
02222                     /*%
02223                         $$ = dispatch3(binary, $1, ripper_intern("=="), $3);
02224                     %*/
02225                     }
02226                 | arg tEQQ arg
02227                     {
02228                     /*%%%*/
02229                         $$ = call_bin_op($1, tEQQ, $3);
02230                     /*%
02231                         $$ = dispatch3(binary, $1, ripper_intern("==="), $3);
02232                     %*/
02233                     }
02234                 | arg tNEQ arg
02235                     {
02236                     /*%%%*/
02237                         $$ = call_bin_op($1, tNEQ, $3);
02238                     /*%
02239                         $$ = dispatch3(binary, $1, ripper_intern("!="), $3);
02240                     %*/
02241                     }
02242                 | arg tMATCH arg
02243                     {
02244                     /*%%%*/
02245                         $$ = match_op($1, $3);
02246                         if (nd_type($1) == NODE_LIT && RB_TYPE_P($1->nd_lit, T_REGEXP)) {
02247                             $$ = reg_named_capture_assign($1->nd_lit, $$);
02248                         }
02249                     /*%
02250                         $$ = dispatch3(binary, $1, ripper_intern("=~"), $3);
02251                     %*/
02252                     }
02253                 | arg tNMATCH arg
02254                     {
02255                     /*%%%*/
02256                         $$ = call_bin_op($1, tNMATCH, $3);
02257                     /*%
02258                         $$ = dispatch3(binary, $1, ripper_intern("!~"), $3);
02259                     %*/
02260                     }
02261                 | '!' arg
02262                     {
02263                     /*%%%*/
02264                         $$ = call_uni_op(cond($2), '!');
02265                     /*%
02266                         $$ = dispatch2(unary, ID2SYM('!'), $2);
02267                     %*/
02268                     }
02269                 | '~' arg
02270                     {
02271                     /*%%%*/
02272                         $$ = call_uni_op($2, '~');
02273                     /*%
02274                         $$ = dispatch2(unary, ID2SYM('~'), $2);
02275                     %*/
02276                     }
02277                 | arg tLSHFT arg
02278                     {
02279                     /*%%%*/
02280                         $$ = call_bin_op($1, tLSHFT, $3);
02281                     /*%
02282                         $$ = dispatch3(binary, $1, ripper_intern("<<"), $3);
02283                     %*/
02284                     }
02285                 | arg tRSHFT arg
02286                     {
02287                     /*%%%*/
02288                         $$ = call_bin_op($1, tRSHFT, $3);
02289                     /*%
02290                         $$ = dispatch3(binary, $1, ripper_intern(">>"), $3);
02291                     %*/
02292                     }
02293                 | arg tANDOP arg
02294                     {
02295                     /*%%%*/
02296                         $$ = logop(NODE_AND, $1, $3);
02297                     /*%
02298                         $$ = dispatch3(binary, $1, ripper_intern("&&"), $3);
02299                     %*/
02300                     }
02301                 | arg tOROP arg
02302                     {
02303                     /*%%%*/
02304                         $$ = logop(NODE_OR, $1, $3);
02305                     /*%
02306                         $$ = dispatch3(binary, $1, ripper_intern("||"), $3);
02307                     %*/
02308                     }
02309                 | keyword_defined opt_nl {in_defined = 1;} arg
02310                     {
02311                     /*%%%*/
02312                         in_defined = 0;
02313                         $$ = NEW_DEFINED($4);
02314                     /*%
02315                         in_defined = 0;
02316                         $$ = dispatch1(defined, $4);
02317                     %*/
02318                     }
02319                 | arg '?' arg opt_nl ':' arg
02320                     {
02321                     /*%%%*/
02322                         value_expr($1);
02323                         $$ = NEW_IF(cond($1), $3, $6);
02324                         fixpos($$, $1);
02325                     /*%
02326                         $$ = dispatch3(ifop, $1, $3, $6);
02327                     %*/
02328                     }
02329                 | primary
02330                     {
02331                         $$ = $1;
02332                     }
02333                 ;
02334 
02335 arg_value       : arg
02336                     {
02337                     /*%%%*/
02338                         value_expr($1);
02339                         $$ = $1;
02340                         if (!$$) $$ = NEW_NIL();
02341                     /*%
02342                         $$ = $1;
02343                     %*/
02344                     }
02345                 ;
02346 
02347 aref_args       : none
02348                 | args trailer
02349                     {
02350                         $$ = $1;
02351                     }
02352                 | args ',' assocs trailer
02353                     {
02354                     /*%%%*/
02355                         $$ = arg_append($1, NEW_HASH($3));
02356                     /*%
02357                         $$ = arg_add_assocs($1, $3);
02358                     %*/
02359                     }
02360                 | assocs trailer
02361                     {
02362                     /*%%%*/
02363                         $$ = NEW_LIST(NEW_HASH($1));
02364                     /*%
02365                         $$ = arg_add_assocs(arg_new(), $1);
02366                     %*/
02367                     }
02368                 ;
02369 
02370 paren_args      : '(' opt_call_args rparen
02371                     {
02372                     /*%%%*/
02373                         $$ = $2;
02374                     /*%
02375                         $$ = dispatch1(arg_paren, escape_Qundef($2));
02376                     %*/
02377                     }
02378                 ;
02379 
02380 opt_paren_args  : none
02381                 | paren_args
02382                 ;
02383 
02384 opt_call_args   : none
02385                 | call_args
02386                 | args ','
02387                     {
02388                       $$ = $1;
02389                     }
02390                 | args ',' assocs ','
02391                     {
02392                     /*%%%*/
02393                         $$ = arg_append($1, NEW_HASH($3));
02394                     /*%
02395                         $$ = arg_add_assocs($1, $3);
02396                     %*/
02397                     }
02398                 | assocs ','
02399                     {
02400                     /*%%%*/
02401                         $$ = NEW_LIST(NEW_HASH($1));
02402                     /*%
02403                         $$ = arg_add_assocs(arg_new(), $1);
02404                     %*/
02405                     }
02406                 ;
02407 
02408 call_args       : command
02409                     {
02410                     /*%%%*/
02411                         value_expr($1);
02412                         $$ = NEW_LIST($1);
02413                     /*%
02414                         $$ = arg_add(arg_new(), $1);
02415                     %*/
02416                     }
02417                 | args opt_block_arg
02418                     {
02419                     /*%%%*/
02420                         $$ = arg_blk_pass($1, $2);
02421                     /*%
02422                         $$ = arg_add_optblock($1, $2);
02423                     %*/
02424                     }
02425                 | assocs opt_block_arg
02426                     {
02427                     /*%%%*/
02428                         $$ = NEW_LIST(NEW_HASH($1));
02429                         $$ = arg_blk_pass($$, $2);
02430                     /*%
02431                         $$ = arg_add_assocs(arg_new(), $1);
02432                         $$ = arg_add_optblock($$, $2);
02433                     %*/
02434                     }
02435                 | args ',' assocs opt_block_arg
02436                     {
02437                     /*%%%*/
02438                         $$ = arg_append($1, NEW_HASH($3));
02439                         $$ = arg_blk_pass($$, $4);
02440                     /*%
02441                         $$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
02442                     %*/
02443                     }
02444                 | block_arg
02445                     /*%c%*/
02446                     /*%c
02447                     {
02448                         $$ = arg_add_block(arg_new(), $1);
02449                     }
02450                     %*/
02451                 ;
02452 
02453 command_args    :  {
02454                         $<val>$ = cmdarg_stack;
02455                         CMDARG_PUSH(1);
02456                     }
02457                   call_args
02458                     {
02459                         /* CMDARG_POP() */
02460                         cmdarg_stack = $<val>1;
02461                         $$ = $2;
02462                     }
02463                 ;
02464 
02465 block_arg       : tAMPER arg_value
02466                     {
02467                     /*%%%*/
02468                         $$ = NEW_BLOCK_PASS($2);
02469                     /*%
02470                         $$ = $2;
02471                     %*/
02472                     }
02473                 ;
02474 
02475 opt_block_arg   : ',' block_arg
02476                     {
02477                         $$ = $2;
02478                     }
02479                 | none
02480                     {
02481                         $$ = 0;
02482                     }
02483                 ;
02484 
02485 args            : arg_value
02486                     {
02487                     /*%%%*/
02488                         $$ = NEW_LIST($1);
02489                     /*%
02490                         $$ = arg_add(arg_new(), $1);
02491                     %*/
02492                     }
02493                 | tSTAR arg_value
02494                     {
02495                     /*%%%*/
02496                         $$ = NEW_SPLAT($2);
02497                     /*%
02498                         $$ = arg_add_star(arg_new(), $2);
02499                     %*/
02500                     }
02501                 | args ',' arg_value
02502                     {
02503                     /*%%%*/
02504                         NODE *n1;
02505                         if ((n1 = splat_array($1)) != 0) {
02506                             $$ = list_append(n1, $3);
02507                         }
02508                         else {
02509                             $$ = arg_append($1, $3);
02510                         }
02511                     /*%
02512                         $$ = arg_add($1, $3);
02513                     %*/
02514                     }
02515                 | args ',' tSTAR arg_value
02516                     {
02517                     /*%%%*/
02518                         NODE *n1;
02519                         if ((nd_type($4) == NODE_ARRAY) && (n1 = splat_array($1)) != 0) {
02520                             $$ = list_concat(n1, $4);
02521                         }
02522                         else {
02523                             $$ = arg_concat($1, $4);
02524                         }
02525                     /*%
02526                         $$ = arg_add_star($1, $4);
02527                     %*/
02528                     }
02529                 ;
02530 
02531 mrhs            : args ',' arg_value
02532                     {
02533                     /*%%%*/
02534                         NODE *n1;
02535                         if ((n1 = splat_array($1)) != 0) {
02536                             $$ = list_append(n1, $3);
02537                         }
02538                         else {
02539                             $$ = arg_append($1, $3);
02540                         }
02541                     /*%
02542                         $$ = mrhs_add(args2mrhs($1), $3);
02543                     %*/
02544                     }
02545                 | args ',' tSTAR arg_value
02546                     {
02547                     /*%%%*/
02548                         NODE *n1;
02549                         if (nd_type($4) == NODE_ARRAY &&
02550                             (n1 = splat_array($1)) != 0) {
02551                             $$ = list_concat(n1, $4);
02552                         }
02553                         else {
02554                             $$ = arg_concat($1, $4);
02555                         }
02556                     /*%
02557                         $$ = mrhs_add_star(args2mrhs($1), $4);
02558                     %*/
02559                     }
02560                 | tSTAR arg_value
02561                     {
02562                     /*%%%*/
02563                         $$ = NEW_SPLAT($2);
02564                     /*%
02565                         $$ = mrhs_add_star(mrhs_new(), $2);
02566                     %*/
02567                     }
02568                 ;
02569 
02570 primary         : literal
02571                 | strings
02572                 | xstring
02573                 | regexp
02574                 | words
02575                 | qwords
02576                 | symbols
02577                 | qsymbols
02578                 | var_ref
02579                 | backref
02580                 | tFID
02581                     {
02582                     /*%%%*/
02583                         $$ = NEW_FCALL($1, 0);
02584                     /*%
02585                         $$ = method_arg(dispatch1(fcall, $1), arg_new());
02586                     %*/
02587                     }
02588                 | k_begin
02589                     {
02590                         $<val>1 = cmdarg_stack;
02591                         cmdarg_stack = 0;
02592                     /*%%%*/
02593                         $<num>$ = ruby_sourceline;
02594                     /*%
02595                     %*/
02596                     }
02597                   bodystmt
02598                   k_end
02599                     {
02600                         cmdarg_stack = $<val>1;
02601                     /*%%%*/
02602                         if ($3 == NULL) {
02603                             $$ = NEW_NIL();
02604                         }
02605                         else {
02606                             if (nd_type($3) == NODE_RESCUE ||
02607                                 nd_type($3) == NODE_ENSURE)
02608                                 nd_set_line($3, $<num>2);
02609                             $$ = NEW_BEGIN($3);
02610                         }
02611                         nd_set_line($$, $<num>2);
02612                     /*%
02613                         $$ = dispatch1(begin, $3);
02614                     %*/
02615                     }
02616                 | tLPAREN_ARG {lex_state = EXPR_ENDARG;} rparen
02617                     {
02618                     /*%%%*/
02619                         $$ = 0;
02620                     /*%
02621                         $$ = dispatch1(paren, 0);
02622                     %*/
02623                     }
02624                 | tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} rparen
02625                     {
02626                     /*%%%*/
02627                         $$ = $2;
02628                     /*%
02629                         $$ = dispatch1(paren, $2);
02630                     %*/
02631                     }
02632                 | tLPAREN compstmt ')'
02633                     {
02634                     /*%%%*/
02635                         $$ = $2;
02636                     /*%
02637                         $$ = dispatch1(paren, $2);
02638                     %*/
02639                     }
02640                 | primary_value tCOLON2 tCONSTANT
02641                     {
02642                     /*%%%*/
02643                         $$ = NEW_COLON2($1, $3);
02644                     /*%
02645                         $$ = dispatch2(const_path_ref, $1, $3);
02646                     %*/
02647                     }
02648                 | tCOLON3 tCONSTANT
02649                     {
02650                     /*%%%*/
02651                         $$ = NEW_COLON3($2);
02652                     /*%
02653                         $$ = dispatch1(top_const_ref, $2);
02654                     %*/
02655                     }
02656                 | tLBRACK aref_args ']'
02657                     {
02658                     /*%%%*/
02659                         if ($2 == 0) {
02660                             $$ = NEW_ZARRAY(); /* zero length array*/
02661                         }
02662                         else {
02663                             $$ = $2;
02664                         }
02665                     /*%
02666                         $$ = dispatch1(array, escape_Qundef($2));
02667                     %*/
02668                     }
02669                 | tLBRACE assoc_list '}'
02670                     {
02671                     /*%%%*/
02672                         $$ = NEW_HASH($2);
02673                     /*%
02674                         $$ = dispatch1(hash, escape_Qundef($2));
02675                     %*/
02676                     }
02677                 | keyword_return
02678                     {
02679                     /*%%%*/
02680                         $$ = NEW_RETURN(0);
02681                     /*%
02682                         $$ = dispatch0(return0);
02683                     %*/
02684                     }
02685                 | keyword_yield '(' call_args rparen
02686                     {
02687                     /*%%%*/
02688                         $$ = new_yield($3);
02689                     /*%
02690                         $$ = dispatch1(yield, dispatch1(paren, $3));
02691                     %*/
02692                     }
02693                 | keyword_yield '(' rparen
02694                     {
02695                     /*%%%*/
02696                         $$ = NEW_YIELD(0);
02697                     /*%
02698                         $$ = dispatch1(yield, dispatch1(paren, arg_new()));
02699                     %*/
02700                     }
02701                 | keyword_yield
02702                     {
02703                     /*%%%*/
02704                         $$ = NEW_YIELD(0);
02705                     /*%
02706                         $$ = dispatch0(yield0);
02707                     %*/
02708                     }
02709                 | keyword_defined opt_nl '(' {in_defined = 1;} expr rparen
02710                     {
02711                     /*%%%*/
02712                         in_defined = 0;
02713                         $$ = NEW_DEFINED($5);
02714                     /*%
02715                         in_defined = 0;
02716                         $$ = dispatch1(defined, $5);
02717                     %*/
02718                     }
02719                 | keyword_not '(' expr rparen
02720                     {
02721                     /*%%%*/
02722                         $$ = call_uni_op(cond($3), '!');
02723                     /*%
02724                         $$ = dispatch2(unary, ripper_intern("not"), $3);
02725                     %*/
02726                     }
02727                 | keyword_not '(' rparen
02728                     {
02729                     /*%%%*/
02730                         $$ = call_uni_op(cond(NEW_NIL()), '!');
02731                     /*%
02732                         $$ = dispatch2(unary, ripper_intern("not"), Qnil);
02733                     %*/
02734                     }
02735                 | fcall brace_block
02736                     {
02737                     /*%%%*/
02738                         $2->nd_iter = $1;
02739                         $$ = $2;
02740                     /*%
02741                         $$ = method_arg(dispatch1(fcall, $1), arg_new());
02742                         $$ = method_add_block($$, $2);
02743                     %*/
02744                     }
02745                 | method_call
02746                 | method_call brace_block
02747                     {
02748                     /*%%%*/
02749                         block_dup_check($1->nd_args, $2);
02750                         $2->nd_iter = $1;
02751                         $$ = $2;
02752                     /*%
02753                         $$ = method_add_block($1, $2);
02754                     %*/
02755                     }
02756                 | tLAMBDA lambda
02757                     {
02758                         $$ = $2;
02759                     }
02760                 | k_if expr_value then
02761                   compstmt
02762                   if_tail
02763                   k_end
02764                     {
02765                     /*%%%*/
02766                         $$ = NEW_IF(cond($2), $4, $5);
02767                         fixpos($$, $2);
02768                     /*%
02769                         $$ = dispatch3(if, $2, $4, escape_Qundef($5));
02770                     %*/
02771                     }
02772                 | k_unless expr_value then
02773                   compstmt
02774                   opt_else
02775                   k_end
02776                     {
02777                     /*%%%*/
02778                         $$ = NEW_UNLESS(cond($2), $4, $5);
02779                         fixpos($$, $2);
02780                     /*%
02781                         $$ = dispatch3(unless, $2, $4, escape_Qundef($5));
02782                     %*/
02783                     }
02784                 | k_while {COND_PUSH(1);} expr_value do {COND_POP();}
02785                   compstmt
02786                   k_end
02787                     {
02788                     /*%%%*/
02789                         $$ = NEW_WHILE(cond($3), $6, 1);
02790                         fixpos($$, $3);
02791                     /*%
02792                         $$ = dispatch2(while, $3, $6);
02793                     %*/
02794                     }
02795                 | k_until {COND_PUSH(1);} expr_value do {COND_POP();}
02796                   compstmt
02797                   k_end
02798                     {
02799                     /*%%%*/
02800                         $$ = NEW_UNTIL(cond($3), $6, 1);
02801                         fixpos($$, $3);
02802                     /*%
02803                         $$ = dispatch2(until, $3, $6);
02804                     %*/
02805                     }
02806                 | k_case expr_value opt_terms
02807                   case_body
02808                   k_end
02809                     {
02810                     /*%%%*/
02811                         $$ = NEW_CASE($2, $4);
02812                         fixpos($$, $2);
02813                     /*%
02814                         $$ = dispatch2(case, $2, $4);
02815                     %*/
02816                     }
02817                 | k_case opt_terms case_body k_end
02818                     {
02819                     /*%%%*/
02820                         $$ = NEW_CASE(0, $3);
02821                     /*%
02822                         $$ = dispatch2(case, Qnil, $3);
02823                     %*/
02824                     }
02825                 | k_for for_var keyword_in
02826                   {COND_PUSH(1);}
02827                   expr_value do
02828                   {COND_POP();}
02829                   compstmt
02830                   k_end
02831                     {
02832                     /*%%%*/
02833                         /*
02834                          *  for a, b, c in e
02835                          *  #=>
02836                          *  e.each{|*x| a, b, c = x
02837                          *
02838                          *  for a in e
02839                          *  #=>
02840                          *  e.each{|x| a, = x}
02841                          */
02842                         ID id = internal_id();
02843                         ID *tbl = ALLOC_N(ID, 2);
02844                         NODE *m = NEW_ARGS_AUX(0, 0);
02845                         NODE *args, *scope;
02846 
02847                         if (nd_type($2) == NODE_MASGN) {
02848                             /* if args.length == 1 && args[0].kind_of?(Array)
02849                              *   args = args[0]
02850                              * end
02851                              */
02852                             NODE *one = NEW_LIST(NEW_LIT(INT2FIX(1)));
02853                             NODE *zero = NEW_LIST(NEW_LIT(INT2FIX(0)));
02854                             m->nd_next = block_append(
02855                                 NEW_IF(
02856                                     NEW_NODE(NODE_AND,
02857                                              NEW_CALL(NEW_CALL(NEW_DVAR(id), idLength, 0),
02858                                                       idEq, one),
02859                                              NEW_CALL(NEW_CALL(NEW_DVAR(id), idAREF, zero),
02860                                                       rb_intern("kind_of?"), NEW_LIST(NEW_LIT(rb_cArray))),
02861                                              0),
02862                                     NEW_DASGN_CURR(id,
02863                                                    NEW_CALL(NEW_DVAR(id), idAREF, zero)),
02864                                     0),
02865                                 node_assign($2, NEW_DVAR(id)));
02866 
02867                             args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
02868                         }
02869                         else {
02870                             if (nd_type($2) == NODE_LASGN ||
02871                                 nd_type($2) == NODE_DASGN ||
02872                                 nd_type($2) == NODE_DASGN_CURR) {
02873                                 $2->nd_value = NEW_DVAR(id);
02874                                 m->nd_plen = 1;
02875                                 m->nd_next = $2;
02876                                 args = new_args(m, 0, 0, 0, new_args_tail(0, 0, 0));
02877                             }
02878                             else {
02879                                 m->nd_next = node_assign(NEW_MASGN(NEW_LIST($2), 0), NEW_DVAR(id));
02880                                 args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
02881                             }
02882                         }
02883                         scope = NEW_NODE(NODE_SCOPE, tbl, $8, args);
02884                         tbl[0] = 1; tbl[1] = id;
02885                         $$ = NEW_FOR(0, $5, scope);
02886                         fixpos($$, $2);
02887                     /*%
02888                         $$ = dispatch3(for, $2, $5, $8);
02889                     %*/
02890                     }
02891                 | k_class cpath superclass
02892                     {
02893                         if (in_def || in_single)
02894                             yyerror("class definition in method body");
02895                         local_push(0);
02896                     /*%%%*/
02897                         $<num>$ = ruby_sourceline;
02898                     /*%
02899                     %*/
02900                     }
02901                   bodystmt
02902                   k_end
02903                     {
02904                     /*%%%*/
02905                         $$ = NEW_CLASS($2, $5, $3);
02906                         nd_set_line($$, $<num>4);
02907                     /*%
02908                         $$ = dispatch3(class, $2, $3, $5);
02909                     %*/
02910                         local_pop();
02911                     }
02912                 | k_class tLSHFT expr
02913                     {
02914                         $<num>$ = in_def;
02915                         in_def = 0;
02916                     }
02917                   term
02918                     {
02919                         $<num>$ = in_single;
02920                         in_single = 0;
02921                         local_push(0);
02922                     }
02923                   bodystmt
02924                   k_end
02925                     {
02926                     /*%%%*/
02927                         $$ = NEW_SCLASS($3, $7);
02928                         fixpos($$, $3);
02929                     /*%
02930                         $$ = dispatch2(sclass, $3, $7);
02931                     %*/
02932                         local_pop();
02933                         in_def = $<num>4;
02934                         in_single = $<num>6;
02935                     }
02936                 | k_module cpath
02937                     {
02938                         if (in_def || in_single)
02939                             yyerror("module definition in method body");
02940                         local_push(0);
02941                     /*%%%*/
02942                         $<num>$ = ruby_sourceline;
02943                     /*%
02944                     %*/
02945                     }
02946                   bodystmt
02947                   k_end
02948                     {
02949                     /*%%%*/
02950                         $$ = NEW_MODULE($2, $4);
02951                         nd_set_line($$, $<num>3);
02952                     /*%
02953                         $$ = dispatch2(module, $2, $4);
02954                     %*/
02955                         local_pop();
02956                     }
02957                 | k_def fname
02958                     {
02959                         $<id>$ = cur_mid;
02960                         cur_mid = $2;
02961                         in_def++;
02962                         local_push(0);
02963                     }
02964                   f_arglist
02965                   bodystmt
02966                   k_end
02967                     {
02968                     /*%%%*/
02969                         NODE *body = remove_begin($5);
02970                         reduce_nodes(&body);
02971                         $$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE);
02972                         nd_set_line($$, $<num>1);
02973                     /*%
02974                         $$ = dispatch3(def, $2, $4, $5);
02975                     %*/
02976                         local_pop();
02977                         in_def--;
02978                         cur_mid = $<id>3;
02979                     }
02980                 | k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
02981                     {
02982                         in_single++;
02983                         lex_state = EXPR_ENDFN; /* force for args */
02984                         local_push(0);
02985                     }
02986                   f_arglist
02987                   bodystmt
02988                   k_end
02989                     {
02990                     /*%%%*/
02991                         NODE *body = remove_begin($8);
02992                         reduce_nodes(&body);
02993                         $$ = NEW_DEFS($2, $5, $7, body);
02994                         nd_set_line($$, $<num>1);
02995                     /*%
02996                         $$ = dispatch5(defs, $2, $3, $5, $7, $8);
02997                     %*/
02998                         local_pop();
02999                         in_single--;
03000                     }
03001                 | keyword_break
03002                     {
03003                     /*%%%*/
03004                         $$ = NEW_BREAK(0);
03005                     /*%
03006                         $$ = dispatch1(break, arg_new());
03007                     %*/
03008                     }
03009                 | keyword_next
03010                     {
03011                     /*%%%*/
03012                         $$ = NEW_NEXT(0);
03013                     /*%
03014                         $$ = dispatch1(next, arg_new());
03015                     %*/
03016                     }
03017                 | keyword_redo
03018                     {
03019                     /*%%%*/
03020                         $$ = NEW_REDO();
03021                     /*%
03022                         $$ = dispatch0(redo);
03023                     %*/
03024                     }
03025                 | keyword_retry
03026                     {
03027                     /*%%%*/
03028                         $$ = NEW_RETRY();
03029                     /*%
03030                         $$ = dispatch0(retry);
03031                     %*/
03032                     }
03033                 ;
03034 
03035 primary_value   : primary
03036                     {
03037                     /*%%%*/
03038                         value_expr($1);
03039                         $$ = $1;
03040                         if (!$$) $$ = NEW_NIL();
03041                     /*%
03042                         $$ = $1;
03043                     %*/
03044                     }
03045                 ;
03046 
03047 k_begin         : keyword_begin
03048                     {
03049                         token_info_push("begin");
03050                     }
03051                 ;
03052 
03053 k_if            : keyword_if
03054                     {
03055                         token_info_push("if");
03056                     }
03057                 ;
03058 
03059 k_unless        : keyword_unless
03060                     {
03061                         token_info_push("unless");
03062                     }
03063                 ;
03064 
03065 k_while         : keyword_while
03066                     {
03067                         token_info_push("while");
03068                     }
03069                 ;
03070 
03071 k_until         : keyword_until
03072                     {
03073                         token_info_push("until");
03074                     }
03075                 ;
03076 
03077 k_case          : keyword_case
03078                     {
03079                         token_info_push("case");
03080                     }
03081                 ;
03082 
03083 k_for           : keyword_for
03084                     {
03085                         token_info_push("for");
03086                     }
03087                 ;
03088 
03089 k_class         : keyword_class
03090                     {
03091                         token_info_push("class");
03092                     }
03093                 ;
03094 
03095 k_module        : keyword_module
03096                     {
03097                         token_info_push("module");
03098                     }
03099                 ;
03100 
03101 k_def           : keyword_def
03102                     {
03103                         token_info_push("def");
03104                     /*%%%*/
03105                         $<num>$ = ruby_sourceline;
03106                     /*%
03107                     %*/
03108                     }
03109                 ;
03110 
03111 k_end           : keyword_end
03112                     {
03113                         token_info_pop("end");
03114                     }
03115                 ;
03116 
03117 then            : term
03118                     /*%c%*/
03119                     /*%c
03120                     { $$ = Qnil; }
03121                     %*/
03122                 | keyword_then
03123                 | term keyword_then
03124                     /*%c%*/
03125                     /*%c
03126                     { $$ = $2; }
03127                     %*/
03128                 ;
03129 
03130 do              : term
03131                     /*%c%*/
03132                     /*%c
03133                     { $$ = Qnil; }
03134                     %*/
03135                 | keyword_do_cond
03136                 ;
03137 
03138 if_tail         : opt_else
03139                 | keyword_elsif expr_value then
03140                   compstmt
03141                   if_tail
03142                     {
03143                     /*%%%*/
03144                         $$ = NEW_IF(cond($2), $4, $5);
03145                         fixpos($$, $2);
03146                     /*%
03147                         $$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
03148                     %*/
03149                     }
03150                 ;
03151 
03152 opt_else        : none
03153                 | keyword_else compstmt
03154                     {
03155                     /*%%%*/
03156                         $$ = $2;
03157                     /*%
03158                         $$ = dispatch1(else, $2);
03159                     %*/
03160                     }
03161                 ;
03162 
03163 for_var         : lhs
03164                 | mlhs
03165                 ;
03166 
03167 f_marg          : f_norm_arg
03168                     {
03169                         $$ = assignable($1, 0);
03170                     /*%%%*/
03171                     /*%
03172                         $$ = dispatch1(mlhs_paren, $$);
03173                     %*/
03174                     }
03175                 | tLPAREN f_margs rparen
03176                     {
03177                     /*%%%*/
03178                         $$ = $2;
03179                     /*%
03180                         $$ = dispatch1(mlhs_paren, $2);
03181                     %*/
03182                     }
03183                 ;
03184 
03185 f_marg_list     : f_marg
03186                     {
03187                     /*%%%*/
03188                         $$ = NEW_LIST($1);
03189                     /*%
03190                         $$ = mlhs_add(mlhs_new(), $1);
03191                     %*/
03192                     }
03193                 | f_marg_list ',' f_marg
03194                     {
03195                     /*%%%*/
03196                         $$ = list_append($1, $3);
03197                     /*%
03198                         $$ = mlhs_add($1, $3);
03199                     %*/
03200                     }
03201                 ;
03202 
03203 f_margs         : f_marg_list
03204                     {
03205                     /*%%%*/
03206                         $$ = NEW_MASGN($1, 0);
03207                     /*%
03208                         $$ = $1;
03209                     %*/
03210                     }
03211                 | f_marg_list ',' tSTAR f_norm_arg
03212                     {
03213                         $$ = assignable($4, 0);
03214                     /*%%%*/
03215                         $$ = NEW_MASGN($1, $$);
03216                     /*%
03217                         $$ = mlhs_add_star($1, $$);
03218                     %*/
03219                     }
03220                 | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
03221                     {
03222                         $$ = assignable($4, 0);
03223                     /*%%%*/
03224                         $$ = NEW_MASGN($1, NEW_POSTARG($$, $6));
03225                     /*%
03226                         $$ = mlhs_add_star($1, $$);
03227                     %*/
03228                     }
03229                 | f_marg_list ',' tSTAR
03230                     {
03231                     /*%%%*/
03232                         $$ = NEW_MASGN($1, -1);
03233                     /*%
03234                         $$ = mlhs_add_star($1, Qnil);
03235                     %*/
03236                     }
03237                 | f_marg_list ',' tSTAR ',' f_marg_list
03238                     {
03239                     /*%%%*/
03240                         $$ = NEW_MASGN($1, NEW_POSTARG(-1, $5));
03241                     /*%
03242                         $$ = mlhs_add_star($1, $5);
03243                     %*/
03244                     }
03245                 | tSTAR f_norm_arg
03246                     {
03247                         $$ = assignable($2, 0);
03248                     /*%%%*/
03249                         $$ = NEW_MASGN(0, $$);
03250                     /*%
03251                         $$ = mlhs_add_star(mlhs_new(), $$);
03252                     %*/
03253                     }
03254                 | tSTAR f_norm_arg ',' f_marg_list
03255                     {
03256                         $$ = assignable($2, 0);
03257                     /*%%%*/
03258                         $$ = NEW_MASGN(0, NEW_POSTARG($$, $4));
03259                     /*%
03260                       #if 0
03261                       TODO: Check me
03262                       #endif
03263                         $$ = mlhs_add_star($$, $4);
03264                     %*/
03265                     }
03266                 | tSTAR
03267                     {
03268                     /*%%%*/
03269                         $$ = NEW_MASGN(0, -1);
03270                     /*%
03271                         $$ = mlhs_add_star(mlhs_new(), Qnil);
03272                     %*/
03273                     }
03274                 | tSTAR ',' f_marg_list
03275                     {
03276                     /*%%%*/
03277                         $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
03278                     /*%
03279                         $$ = mlhs_add_star(mlhs_new(), Qnil);
03280                     %*/
03281                     }
03282                 ;
03283 
03284 
03285 block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
03286                     {
03287                         $$ = new_args_tail($1, $3, $4);
03288                     }
03289                 | f_block_kwarg opt_f_block_arg
03290                     {
03291                         $$ = new_args_tail($1, Qnone, $2);
03292                     }
03293                 | f_kwrest opt_f_block_arg
03294                     {
03295                         $$ = new_args_tail(Qnone, $1, $2);
03296                     }
03297                 | f_block_arg
03298                     {
03299                         $$ = new_args_tail(Qnone, Qnone, $1);
03300                     }
03301                 ;
03302 
03303 opt_block_args_tail : ',' block_args_tail
03304                     {
03305                         $$ = $2;
03306                     }
03307                 | /* none */
03308                     {
03309                         $$ = new_args_tail(Qnone, Qnone, Qnone);
03310                     }
03311                 ;
03312 
03313 block_param     : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
03314                     {
03315                         $$ = new_args($1, $3, $5, Qnone, $6);
03316                     }
03317                 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
03318                     {
03319                         $$ = new_args($1, $3, $5, $7, $8);
03320                     }
03321                 | f_arg ',' f_block_optarg opt_block_args_tail
03322                     {
03323                         $$ = new_args($1, $3, Qnone, Qnone, $4);
03324                     }
03325                 | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
03326                     {
03327                         $$ = new_args($1, $3, Qnone, $5, $6);
03328                     }
03329                 | f_arg ',' f_rest_arg opt_block_args_tail
03330                     {
03331                         $$ = new_args($1, Qnone, $3, Qnone, $4);
03332                     }
03333                 | f_arg ','
03334                     {
03335                         $$ = new_args($1, Qnone, 1, Qnone, new_args_tail(Qnone, Qnone, Qnone));
03336                     /*%%%*/
03337                     /*%
03338                         dispatch1(excessed_comma, $$);
03339                     %*/
03340                     }
03341                 | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
03342                     {
03343                         $$ = new_args($1, Qnone, $3, $5, $6);
03344                     }
03345                 | f_arg opt_block_args_tail
03346                     {
03347                         $$ = new_args($1, Qnone, Qnone, Qnone, $2);
03348                     }
03349                 | f_block_optarg ',' f_rest_arg opt_block_args_tail
03350                     {
03351                         $$ = new_args(Qnone, $1, $3, Qnone, $4);
03352                     }
03353                 | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
03354                     {
03355                         $$ = new_args(Qnone, $1, $3, $5, $6);
03356                     }
03357                 | f_block_optarg opt_block_args_tail
03358                     {
03359                         $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
03360                     }
03361                 | f_block_optarg ',' f_arg opt_block_args_tail
03362                     {
03363                         $$ = new_args(Qnone, $1, Qnone, $3, $4);
03364                     }
03365                 | f_rest_arg opt_block_args_tail
03366                     {
03367                         $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
03368                     }
03369                 | f_rest_arg ',' f_arg opt_block_args_tail
03370                     {
03371                         $$ = new_args(Qnone, Qnone, $1, $3, $4);
03372                     }
03373                 | block_args_tail
03374                     {
03375                         $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
03376                     }
03377                 ;
03378 
03379 opt_block_param : none
03380                 | block_param_def
03381                     {
03382                         command_start = TRUE;
03383                     }
03384                 ;
03385 
03386 block_param_def : '|' opt_bv_decl '|'
03387                     {
03388                     /*%%%*/
03389                         $$ = 0;
03390                     /*%
03391                         $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
03392                                           escape_Qundef($2));
03393                     %*/
03394                     }
03395                 | tOROP
03396                     {
03397                     /*%%%*/
03398                         $$ = 0;
03399                     /*%
03400                         $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil),
03401                                           Qnil);
03402                     %*/
03403                     }
03404                 | '|' block_param opt_bv_decl '|'
03405                     {
03406                     /*%%%*/
03407                         $$ = $2;
03408                     /*%
03409                         $$ = blockvar_new(escape_Qundef($2), escape_Qundef($3));
03410                     %*/
03411                     }
03412                 ;
03413 
03414 
03415 opt_bv_decl     : opt_nl
03416                     {
03417                       $$ = 0;
03418                     }
03419                 | opt_nl ';' bv_decls opt_nl
03420                     {
03421                     /*%%%*/
03422                         $$ = 0;
03423                     /*%
03424                         $$ = $3;
03425                     %*/
03426                     }
03427                 ;
03428 
03429 bv_decls        : bvar
03430                     /*%c%*/
03431                     /*%c
03432                     {
03433                         $$ = rb_ary_new3(1, $1);
03434                     }
03435                     %*/
03436                 | bv_decls ',' bvar
03437                     /*%c%*/
03438                     /*%c
03439                     {
03440                         rb_ary_push($1, $3);
03441                     }
03442                     %*/
03443                 ;
03444 
03445 bvar            : tIDENTIFIER
03446                     {
03447                         new_bv(get_id($1));
03448                     /*%%%*/
03449                     /*%
03450                         $$ = get_value($1);
03451                     %*/
03452                     }
03453                 | f_bad_arg
03454                     {
03455                         $$ = 0;
03456                     }
03457                 ;
03458 
03459 lambda          :   {
03460                         $<vars>$ = dyna_push();
03461                     }
03462                     {
03463                         $<num>$ = lpar_beg;
03464                         lpar_beg = ++paren_nest;
03465                     }
03466                   f_larglist
03467                     {
03468                         $<num>$ = ruby_sourceline;
03469                     }
03470                   lambda_body
03471                     {
03472                         lpar_beg = $<num>2;
03473                     /*%%%*/
03474                         $$ = NEW_LAMBDA($3, $5);
03475                         nd_set_line($$, $<num>4);
03476                     /*%
03477                         $$ = dispatch2(lambda, $3, $5);
03478                     %*/
03479                         dyna_pop($<vars>1);
03480                     }
03481                 ;
03482 
03483 f_larglist      : '(' f_args opt_bv_decl ')'
03484                     {
03485                     /*%%%*/
03486                         $$ = $2;
03487                     /*%
03488                         $$ = dispatch1(paren, $2);
03489                     %*/
03490                     }
03491                 | f_args
03492                     {
03493                     /*%%%*/
03494                         $$ = $1;
03495                     /*%
03496                         $$ = $1;
03497                     %*/
03498                     }
03499                 ;
03500 
03501 lambda_body     : tLAMBEG compstmt '}'
03502                     {
03503                         $$ = $2;
03504                     }
03505                 | keyword_do_LAMBDA compstmt keyword_end
03506                     {
03507                         $$ = $2;
03508                     }
03509                 ;
03510 
03511 do_block        : keyword_do_block
03512                     {
03513                         $<vars>1 = dyna_push();
03514                     /*%%%*/
03515                         $<num>$ = ruby_sourceline;
03516                     /*% %*/
03517                     }
03518                   opt_block_param
03519                   compstmt
03520                   keyword_end
03521                     {
03522                     /*%%%*/
03523                         $$ = NEW_ITER($3,$4);
03524                         nd_set_line($$, $<num>2);
03525                     /*%
03526                         $$ = dispatch2(do_block, escape_Qundef($3), $4);
03527                     %*/
03528                         dyna_pop($<vars>1);
03529                     }
03530                 ;
03531 
03532 block_call      : command do_block
03533                     {
03534                     /*%%%*/
03535                         if (nd_type($1) == NODE_YIELD) {
03536                             compile_error(PARSER_ARG "block given to yield");
03537                         }
03538                         else {
03539                             block_dup_check($1->nd_args, $2);
03540                         }
03541                         $2->nd_iter = $1;
03542                         $$ = $2;
03543                         fixpos($$, $1);
03544                     /*%
03545                         $$ = method_add_block($1, $2);
03546                     %*/
03547                     }
03548                 | block_call dot_or_colon operation2 opt_paren_args
03549                     {
03550                     /*%%%*/
03551                         $$ = NEW_CALL($1, $3, $4);
03552                     /*%
03553                         $$ = dispatch3(call, $1, $2, $3);
03554                         $$ = method_optarg($$, $4);
03555                     %*/
03556                     }
03557                 | block_call dot_or_colon operation2 opt_paren_args brace_block
03558                     {
03559                     /*%%%*/
03560                         block_dup_check($4, $5);
03561                         $5->nd_iter = NEW_CALL($1, $3, $4);
03562                         $$ = $5;
03563                         fixpos($$, $1);
03564                     /*%
03565                         $$ = dispatch4(command_call, $1, $2, $3, $4);
03566                         $$ = method_add_block($$, $5);
03567                     %*/
03568                     }
03569                 | block_call dot_or_colon operation2 command_args do_block
03570                     {
03571                     /*%%%*/
03572                         block_dup_check($4, $5);
03573                         $5->nd_iter = NEW_CALL($1, $3, $4);
03574                         $$ = $5;
03575                         fixpos($$, $1);
03576                     /*%
03577                         $$ = dispatch4(command_call, $1, $2, $3, $4);
03578                         $$ = method_add_block($$, $5);
03579                     %*/
03580                     }
03581                 ;
03582 
03583 method_call     : fcall paren_args
03584                     {
03585                     /*%%%*/
03586                         $$ = $1;
03587                         $$->nd_args = $2;
03588                     /*%
03589                         $$ = method_arg(dispatch1(fcall, $1), $2);
03590                     %*/
03591                     }
03592                 | primary_value '.' operation2
03593                     {
03594                     /*%%%*/
03595                         $<num>$ = ruby_sourceline;
03596                     /*% %*/
03597                     }
03598                   opt_paren_args
03599                     {
03600                     /*%%%*/
03601                         $$ = NEW_CALL($1, $3, $5);
03602                         nd_set_line($$, $<num>4);
03603                     /*%
03604                         $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
03605                         $$ = method_optarg($$, $5);
03606                     %*/
03607                     }
03608                 | primary_value tCOLON2 operation2
03609                     {
03610                     /*%%%*/
03611                         $<num>$ = ruby_sourceline;
03612                     /*% %*/
03613                     }
03614                   paren_args
03615                     {
03616                     /*%%%*/
03617                         $$ = NEW_CALL($1, $3, $5);
03618                         nd_set_line($$, $<num>4);
03619                     /*%
03620                         $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
03621                         $$ = method_optarg($$, $5);
03622                     %*/
03623                     }
03624                 | primary_value tCOLON2 operation3
03625                     {
03626                     /*%%%*/
03627                         $$ = NEW_CALL($1, $3, 0);
03628                     /*%
03629                         $$ = dispatch3(call, $1, ripper_intern("::"), $3);
03630                     %*/
03631                     }
03632                 | primary_value '.'
03633                     {
03634                     /*%%%*/
03635                         $<num>$ = ruby_sourceline;
03636                     /*% %*/
03637                     }
03638                   paren_args
03639                     {
03640                     /*%%%*/
03641                         $$ = NEW_CALL($1, rb_intern("call"), $4);
03642                         nd_set_line($$, $<num>3);
03643                     /*%
03644                         $$ = dispatch3(call, $1, ripper_id2sym('.'),
03645                                        ripper_intern("call"));
03646                         $$ = method_optarg($$, $4);
03647                     %*/
03648                     }
03649                 | primary_value tCOLON2
03650                     {
03651                     /*%%%*/
03652                         $<num>$ = ruby_sourceline;
03653                     /*% %*/
03654                     }
03655                   paren_args
03656                     {
03657                     /*%%%*/
03658                         $$ = NEW_CALL($1, rb_intern("call"), $4);
03659                         nd_set_line($$, $<num>3);
03660                     /*%
03661                         $$ = dispatch3(call, $1, ripper_intern("::"),
03662                                        ripper_intern("call"));
03663                         $$ = method_optarg($$, $4);
03664                     %*/
03665                     }
03666                 | keyword_super paren_args
03667                     {
03668                     /*%%%*/
03669                         $$ = NEW_SUPER($2);
03670                     /*%
03671                         $$ = dispatch1(super, $2);
03672                     %*/
03673                     }
03674                 | keyword_super
03675                     {
03676                     /*%%%*/
03677                         $$ = NEW_ZSUPER();
03678                     /*%
03679                         $$ = dispatch0(zsuper);
03680                     %*/
03681                     }
03682                 | primary_value '[' opt_call_args rbracket
03683                     {
03684                     /*%%%*/
03685                         if ($1 && nd_type($1) == NODE_SELF)
03686                             $$ = NEW_FCALL(tAREF, $3);
03687                         else
03688                             $$ = NEW_CALL($1, tAREF, $3);
03689                         fixpos($$, $1);
03690                     /*%
03691                         $$ = dispatch2(aref, $1, escape_Qundef($3));
03692                     %*/
03693                     }
03694                 ;
03695 
03696 brace_block     : '{'
03697                     {
03698                         $<vars>1 = dyna_push();
03699                     /*%%%*/
03700                         $<num>$ = ruby_sourceline;
03701                     /*%
03702                     %*/
03703                     }
03704                   opt_block_param
03705                   compstmt '}'
03706                     {
03707                     /*%%%*/
03708                         $$ = NEW_ITER($3,$4);
03709                         nd_set_line($$, $<num>2);
03710                     /*%
03711                         $$ = dispatch2(brace_block, escape_Qundef($3), $4);
03712                     %*/
03713                         dyna_pop($<vars>1);
03714                     }
03715                 | keyword_do
03716                     {
03717                         $<vars>1 = dyna_push();
03718                     /*%%%*/
03719                         $<num>$ = ruby_sourceline;
03720                     /*%
03721                     %*/
03722                     }
03723                   opt_block_param
03724                   compstmt keyword_end
03725                     {
03726                     /*%%%*/
03727                         $$ = NEW_ITER($3,$4);
03728                         nd_set_line($$, $<num>2);
03729                     /*%
03730                         $$ = dispatch2(do_block, escape_Qundef($3), $4);
03731                     %*/
03732                         dyna_pop($<vars>1);
03733                     }
03734                 ;
03735 
03736 case_body       : keyword_when args then
03737                   compstmt
03738                   cases
03739                     {
03740                     /*%%%*/
03741                         $$ = NEW_WHEN($2, $4, $5);
03742                     /*%
03743                         $$ = dispatch3(when, $2, $4, escape_Qundef($5));
03744                     %*/
03745                     }
03746                 ;
03747 
03748 cases           : opt_else
03749                 | case_body
03750                 ;
03751 
03752 opt_rescue      : keyword_rescue exc_list exc_var then
03753                   compstmt
03754                   opt_rescue
03755                     {
03756                     /*%%%*/
03757                         if ($3) {
03758                             $3 = node_assign($3, NEW_ERRINFO());
03759                             $5 = block_append($3, $5);
03760                         }
03761                         $$ = NEW_RESBODY($2, $5, $6);
03762                         fixpos($$, $2?$2:$5);
03763                     /*%
03764                         $$ = dispatch4(rescue,
03765                                        escape_Qundef($2),
03766                                        escape_Qundef($3),
03767                                        escape_Qundef($5),
03768                                        escape_Qundef($6));
03769                     %*/
03770                     }
03771                 | none
03772                 ;
03773 
03774 exc_list        : arg_value
03775                     {
03776                     /*%%%*/
03777                         $$ = NEW_LIST($1);
03778                     /*%
03779                         $$ = rb_ary_new3(1, $1);
03780                     %*/
03781                     }
03782                 | mrhs
03783                     {
03784                     /*%%%*/
03785                         if (!($$ = splat_array($1))) $$ = $1;
03786                     /*%
03787                         $$ = $1;
03788                     %*/
03789                     }
03790                 | none
03791                 ;
03792 
03793 exc_var         : tASSOC lhs
03794                     {
03795                         $$ = $2;
03796                     }
03797                 | none
03798                 ;
03799 
03800 opt_ensure      : keyword_ensure compstmt
03801                     {
03802                     /*%%%*/
03803                         $$ = $2;
03804                     /*%
03805                         $$ = dispatch1(ensure, $2);
03806                     %*/
03807                     }
03808                 | none
03809                 ;
03810 
03811 literal         : numeric
03812                 | symbol
03813                     {
03814                     /*%%%*/
03815                         $$ = NEW_LIT(ID2SYM($1));
03816                     /*%
03817                         $$ = dispatch1(symbol_literal, $1);
03818                     %*/
03819                     }
03820                 | dsym
03821                 ;
03822 
03823 strings         : string
03824                     {
03825                     /*%%%*/
03826                         NODE *node = $1;
03827                         if (!node) {
03828                             node = NEW_STR(STR_NEW0());
03829                         }
03830                         else {
03831                             node = evstr2dstr(node);
03832                         }
03833                         $$ = node;
03834                     /*%
03835                         $$ = $1;
03836                     %*/
03837                     }
03838                 ;
03839 
03840 string          : tCHAR
03841                 | string1
03842                 | string string1
03843                     {
03844                     /*%%%*/
03845                         $$ = literal_concat($1, $2);
03846                     /*%
03847                         $$ = dispatch2(string_concat, $1, $2);
03848                     %*/
03849                     }
03850                 ;
03851 
03852 string1         : tSTRING_BEG string_contents tSTRING_END
03853                     {
03854                     /*%%%*/
03855                         $$ = $2;
03856                     /*%
03857                         $$ = dispatch1(string_literal, $2);
03858                     %*/
03859                     }
03860                 ;
03861 
03862 xstring         : tXSTRING_BEG xstring_contents tSTRING_END
03863                     {
03864                     /*%%%*/
03865                         NODE *node = $2;
03866                         if (!node) {
03867                             node = NEW_XSTR(STR_NEW0());
03868                         }
03869                         else {
03870                             switch (nd_type(node)) {
03871                               case NODE_STR:
03872                                 nd_set_type(node, NODE_XSTR);
03873                                 break;
03874                               case NODE_DSTR:
03875                                 nd_set_type(node, NODE_DXSTR);
03876                                 break;
03877                               default:
03878                                 node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node));
03879                                 break;
03880                             }
03881                         }
03882                         $$ = node;
03883                     /*%
03884                         $$ = dispatch1(xstring_literal, $2);
03885                     %*/
03886                     }
03887                 ;
03888 
03889 regexp          : tREGEXP_BEG regexp_contents tREGEXP_END
03890                     {
03891                     /*%%%*/
03892                         int options = $3;
03893                         NODE *node = $2;
03894                         NODE *list, *prev;
03895                         if (!node) {
03896                             node = NEW_LIT(reg_compile(STR_NEW0(), options));
03897                         }
03898                         else switch (nd_type(node)) {
03899                           case NODE_STR:
03900                             {
03901                                 VALUE src = node->nd_lit;
03902                                 nd_set_type(node, NODE_LIT);
03903                                 node->nd_lit = reg_compile(src, options);
03904                             }
03905                             break;
03906                           default:
03907                             node = NEW_NODE(NODE_DSTR, STR_NEW0(), 1, NEW_LIST(node));
03908                           case NODE_DSTR:
03909                             if (options & RE_OPTION_ONCE) {
03910                                 nd_set_type(node, NODE_DREGX_ONCE);
03911                             }
03912                             else {
03913                                 nd_set_type(node, NODE_DREGX);
03914                             }
03915                             node->nd_cflag = options & RE_OPTION_MASK;
03916                             if (!NIL_P(node->nd_lit)) reg_fragment_check(node->nd_lit, options);
03917                             for (list = (prev = node)->nd_next; list; list = list->nd_next) {
03918                                 if (nd_type(list->nd_head) == NODE_STR) {
03919                                     VALUE tail = list->nd_head->nd_lit;
03920                                     if (reg_fragment_check(tail, options) && prev && !NIL_P(prev->nd_lit)) {
03921                                         VALUE lit = prev == node ? prev->nd_lit : prev->nd_head->nd_lit;
03922                                         if (!literal_concat0(parser, lit, tail)) {
03923                                             node = 0;
03924                                             break;
03925                                         }
03926                                         rb_str_resize(tail, 0);
03927                                         prev->nd_next = list->nd_next;
03928                                         rb_gc_force_recycle((VALUE)list->nd_head);
03929                                         rb_gc_force_recycle((VALUE)list);
03930                                         list = prev;
03931                                     }
03932                                     else {
03933                                         prev = list;
03934                                     }
03935                                 }
03936                                 else {
03937                                     prev = 0;
03938                                 }
03939                             }
03940                             if (!node->nd_next) {
03941                                 VALUE src = node->nd_lit;
03942                                 nd_set_type(node, NODE_LIT);
03943                                 node->nd_lit = reg_compile(src, options);
03944                             }
03945                             break;
03946                         }
03947                         $$ = node;
03948                     /*%
03949                         $$ = dispatch2(regexp_literal, $2, $3);
03950                     %*/
03951                     }
03952                 ;
03953 
03954 words           : tWORDS_BEG ' ' tSTRING_END
03955                     {
03956                     /*%%%*/
03957                         $$ = NEW_ZARRAY();
03958                     /*%
03959                         $$ = dispatch0(words_new);
03960                         $$ = dispatch1(array, $$);
03961                     %*/
03962                     }
03963                 | tWORDS_BEG word_list tSTRING_END
03964                     {
03965                     /*%%%*/
03966                         $$ = $2;
03967                     /*%
03968                         $$ = dispatch1(array, $2);
03969                     %*/
03970                     }
03971                 ;
03972 
03973 word_list       : /* none */
03974                     {
03975                     /*%%%*/
03976                         $$ = 0;
03977                     /*%
03978                         $$ = dispatch0(words_new);
03979                     %*/
03980                     }
03981                 | word_list word ' '
03982                     {
03983                     /*%%%*/
03984                         $$ = list_append($1, evstr2dstr($2));
03985                     /*%
03986                         $$ = dispatch2(words_add, $1, $2);
03987                     %*/
03988                     }
03989                 ;
03990 
03991 word            : string_content
03992                     /*%c%*/
03993                     /*%c
03994                     {
03995                         $$ = dispatch0(word_new);
03996                         $$ = dispatch2(word_add, $$, $1);
03997                     }
03998                     %*/
03999                 | word string_content
04000                     {
04001                     /*%%%*/
04002                         $$ = literal_concat($1, $2);
04003                     /*%
04004                         $$ = dispatch2(word_add, $1, $2);
04005                     %*/
04006                     }
04007                 ;
04008 
04009 symbols         : tSYMBOLS_BEG ' ' tSTRING_END
04010                     {
04011                     /*%%%*/
04012                         $$ = NEW_ZARRAY();
04013                     /*%
04014                         $$ = dispatch0(symbols_new);
04015                         $$ = dispatch1(array, $$);
04016                     %*/
04017                     }
04018                 | tSYMBOLS_BEG symbol_list tSTRING_END
04019                     {
04020                     /*%%%*/
04021                         $$ = $2;
04022                     /*%
04023                         $$ = dispatch1(array, $2);
04024                     %*/
04025                     }
04026                 ;
04027 
04028 symbol_list     : /* none */
04029                     {
04030                     /*%%%*/
04031                         $$ = 0;
04032                     /*%
04033                         $$ = dispatch0(symbols_new);
04034                     %*/
04035                     }
04036                 | symbol_list word ' '
04037                     {
04038                     /*%%%*/
04039                         $2 = evstr2dstr($2);
04040                         nd_set_type($2, NODE_DSYM);
04041                         $$ = list_append($1, $2);
04042                     /*%
04043                         $$ = dispatch2(symbols_add, $1, $2);
04044                     %*/
04045                     }
04046                 ;
04047 
04048 qwords          : tQWORDS_BEG ' ' tSTRING_END
04049                     {
04050                     /*%%%*/
04051                         $$ = NEW_ZARRAY();
04052                     /*%
04053                         $$ = dispatch0(qwords_new);
04054                         $$ = dispatch1(array, $$);
04055                     %*/
04056                     }
04057                 | tQWORDS_BEG qword_list tSTRING_END
04058                     {
04059                     /*%%%*/
04060                         $$ = $2;
04061                     /*%
04062                         $$ = dispatch1(array, $2);
04063                     %*/
04064                     }
04065                 ;
04066 
04067 qsymbols        : tQSYMBOLS_BEG ' ' tSTRING_END
04068                     {
04069                     /*%%%*/
04070                         $$ = NEW_ZARRAY();
04071                     /*%
04072                         $$ = dispatch0(qsymbols_new);
04073                         $$ = dispatch1(array, $$);
04074                     %*/
04075                     }
04076                 | tQSYMBOLS_BEG qsym_list tSTRING_END
04077                     {
04078                     /*%%%*/
04079                         $$ = $2;
04080                     /*%
04081                         $$ = dispatch1(array, $2);
04082                     %*/
04083                     }
04084                 ;
04085 
04086 qword_list      : /* none */
04087                     {
04088                     /*%%%*/
04089                         $$ = 0;
04090                     /*%
04091                         $$ = dispatch0(qwords_new);
04092                     %*/
04093                     }
04094                 | qword_list tSTRING_CONTENT ' '
04095                     {
04096                     /*%%%*/
04097                         $$ = list_append($1, $2);
04098                     /*%
04099                         $$ = dispatch2(qwords_add, $1, $2);
04100                     %*/
04101                     }
04102                 ;
04103 
04104 qsym_list       : /* none */
04105                     {
04106                     /*%%%*/
04107                         $$ = 0;
04108                     /*%
04109                         $$ = dispatch0(qsymbols_new);
04110                     %*/
04111                     }
04112                 | qsym_list tSTRING_CONTENT ' '
04113                     {
04114                     /*%%%*/
04115                         VALUE lit;
04116                         lit = $2->nd_lit;
04117                         $2->nd_lit = ID2SYM(rb_intern_str(lit));
04118                         nd_set_type($2, NODE_LIT);
04119                         $$ = list_append($1, $2);
04120                     /*%
04121                         $$ = dispatch2(qsymbols_add, $1, $2);
04122                     %*/
04123                     }
04124                 ;
04125 
04126 string_contents : /* none */
04127                     {
04128                     /*%%%*/
04129                         $$ = 0;
04130                     /*%
04131                         $$ = dispatch0(string_content);
04132                     %*/
04133                     }
04134                 | string_contents string_content
04135                     {
04136                     /*%%%*/
04137                         $$ = literal_concat($1, $2);
04138                     /*%
04139                         $$ = dispatch2(string_add, $1, $2);
04140                     %*/
04141                     }
04142                 ;
04143 
04144 xstring_contents: /* none */
04145                     {
04146                     /*%%%*/
04147                         $$ = 0;
04148                     /*%
04149                         $$ = dispatch0(xstring_new);
04150                     %*/
04151                     }
04152                 | xstring_contents string_content
04153                     {
04154                     /*%%%*/
04155                         $$ = literal_concat($1, $2);
04156                     /*%
04157                         $$ = dispatch2(xstring_add, $1, $2);
04158                     %*/
04159                     }
04160                 ;
04161 
04162 regexp_contents: /* none */
04163                     {
04164                     /*%%%*/
04165                         $$ = 0;
04166                     /*%
04167                         $$ = dispatch0(regexp_new);
04168                     %*/
04169                     }
04170                 | regexp_contents string_content
04171                     {
04172                     /*%%%*/
04173                         NODE *head = $1, *tail = $2;
04174                         if (!head) {
04175                             $$ = tail;
04176                         }
04177                         else if (!tail) {
04178                             $$ = head;
04179                         }
04180                         else {
04181                             switch (nd_type(head)) {
04182                               case NODE_STR:
04183                                 nd_set_type(head, NODE_DSTR);
04184                                 break;
04185                               case NODE_DSTR:
04186                                 break;
04187                               default:
04188                                 head = list_append(NEW_DSTR(Qnil), head);
04189                                 break;
04190                             }
04191                             $$ = list_append(head, tail);
04192                         }
04193                     /*%
04194                         $$ = dispatch2(regexp_add, $1, $2);
04195                     %*/
04196                     }
04197                 ;
04198 
04199 string_content  : tSTRING_CONTENT
04200                 | tSTRING_DVAR
04201                     {
04202                         $<node>$ = lex_strterm;
04203                         lex_strterm = 0;
04204                         lex_state = EXPR_BEG;
04205                     }
04206                   string_dvar
04207                     {
04208                     /*%%%*/
04209                         lex_strterm = $<node>2;
04210                         $$ = NEW_EVSTR($3);
04211                     /*%
04212                         lex_strterm = $<node>2;
04213                         $$ = dispatch1(string_dvar, $3);
04214                     %*/
04215                     }
04216                 | tSTRING_DBEG
04217                     {
04218                         $<val>1 = cond_stack;
04219                         $<val>$ = cmdarg_stack;
04220                         cond_stack = 0;
04221                         cmdarg_stack = 0;
04222                     }
04223                     {
04224                         $<node>$ = lex_strterm;
04225                         lex_strterm = 0;
04226                         lex_state = EXPR_BEG;
04227                     }
04228                     {
04229                         $<num>$ = brace_nest;
04230                         brace_nest = 0;
04231                     }
04232                   compstmt tSTRING_DEND
04233                     {
04234                         cond_stack = $<val>1;
04235                         cmdarg_stack = $<val>2;
04236                         lex_strterm = $<node>3;
04237                         brace_nest = $<num>4;
04238                     /*%%%*/
04239                         if ($5) $5->flags &= ~NODE_FL_NEWLINE;
04240                         $$ = new_evstr($5);
04241                     /*%
04242                         $$ = dispatch1(string_embexpr, $5);
04243                     %*/
04244                     }
04245                 ;
04246 
04247 string_dvar     : tGVAR
04248                     {
04249                     /*%%%*/
04250                         $$ = NEW_GVAR($1);
04251                     /*%
04252                         $$ = dispatch1(var_ref, $1);
04253                     %*/
04254                     }
04255                 | tIVAR
04256                     {
04257                     /*%%%*/
04258                         $$ = NEW_IVAR($1);
04259                     /*%
04260                         $$ = dispatch1(var_ref, $1);
04261                     %*/
04262                     }
04263                 | tCVAR
04264                     {
04265                     /*%%%*/
04266                         $$ = NEW_CVAR($1);
04267                     /*%
04268                         $$ = dispatch1(var_ref, $1);
04269                     %*/
04270                     }
04271                 | backref
04272                 ;
04273 
04274 symbol          : tSYMBEG sym
04275                     {
04276                         lex_state = EXPR_END;
04277                     /*%%%*/
04278                         $$ = $2;
04279                     /*%
04280                         $$ = dispatch1(symbol, $2);
04281                     %*/
04282                     }
04283                 ;
04284 
04285 sym             : fname
04286                 | tIVAR
04287                 | tGVAR
04288                 | tCVAR
04289                 ;
04290 
04291 dsym            : tSYMBEG xstring_contents tSTRING_END
04292                     {
04293                         lex_state = EXPR_END;
04294                     /*%%%*/
04295                         $$ = dsym_node($2);
04296                     /*%
04297                         $$ = dispatch1(dyna_symbol, $2);
04298                     %*/
04299                     }
04300                 ;
04301 
04302 numeric         : tINTEGER
04303                 | tFLOAT
04304                 | tUMINUS_NUM tINTEGER         %prec tLOWEST
04305                     {
04306                     /*%%%*/
04307                         $$ = negate_lit($2);
04308                     /*%
04309                         $$ = dispatch2(unary, ripper_intern("-@"), $2);
04310                     %*/
04311                     }
04312                 | tUMINUS_NUM tFLOAT           %prec tLOWEST
04313                     {
04314                     /*%%%*/
04315                         $$ = negate_lit($2);
04316                     /*%
04317                         $$ = dispatch2(unary, ripper_intern("-@"), $2);
04318                     %*/
04319                     }
04320                 ;
04321 
04322 user_variable   : tIDENTIFIER
04323                 | tIVAR
04324                 | tGVAR
04325                 | tCONSTANT
04326                 | tCVAR
04327                 ;
04328 
04329 keyword_variable: keyword_nil {ifndef_ripper($$ = keyword_nil);}
04330                 | keyword_self {ifndef_ripper($$ = keyword_self);}
04331                 | keyword_true {ifndef_ripper($$ = keyword_true);}
04332                 | keyword_false {ifndef_ripper($$ = keyword_false);}
04333                 | keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);}
04334                 | keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);}
04335                 | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING__);}
04336                 ;
04337 
04338 var_ref         : user_variable
04339                     {
04340                     /*%%%*/
04341                         if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
04342                     /*%
04343                         if (id_is_var(get_id($1))) {
04344                             $$ = dispatch1(var_ref, $1);
04345                         }
04346                         else {
04347                             $$ = dispatch1(vcall, $1);
04348                         }
04349                     %*/
04350                     }
04351                 | keyword_variable
04352                     {
04353                     /*%%%*/
04354                         if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
04355                     /*%
04356                         $$ = dispatch1(var_ref, $1);
04357                     %*/
04358                     }
04359                 ;
04360 
04361 var_lhs         : user_variable
04362                     {
04363                         $$ = assignable($1, 0);
04364                     /*%%%*/
04365                     /*%
04366                         $$ = dispatch1(var_field, $$);
04367                     %*/
04368                     }
04369                 | keyword_variable
04370                     {
04371                         $$ = assignable($1, 0);
04372                     /*%%%*/
04373                     /*%
04374                         $$ = dispatch1(var_field, $$);
04375                     %*/
04376                     }
04377                 ;
04378 
04379 backref         : tNTH_REF
04380                 | tBACK_REF
04381                 ;
04382 
04383 superclass      : term
04384                     {
04385                     /*%%%*/
04386                         $$ = 0;
04387                     /*%
04388                         $$ = Qnil;
04389                     %*/
04390                     }
04391                 | '<'
04392                     {
04393                         lex_state = EXPR_BEG;
04394                         command_start = TRUE;
04395                     }
04396                   expr_value term
04397                     {
04398                         $$ = $3;
04399                     }
04400                 | error term
04401                     {
04402                     /*%%%*/
04403                         yyerrok;
04404                         $$ = 0;
04405                     /*%
04406                         yyerrok;
04407                         $$ = Qnil;
04408                     %*/
04409                     }
04410                 ;
04411 
04412 f_arglist       : '(' f_args rparen
04413                     {
04414                     /*%%%*/
04415                         $$ = $2;
04416                     /*%
04417                         $$ = dispatch1(paren, $2);
04418                     %*/
04419                         lex_state = EXPR_BEG;
04420                         command_start = TRUE;
04421                     }
04422                 | f_args term
04423                     {
04424                         $$ = $1;
04425                         lex_state = EXPR_BEG;
04426                         command_start = TRUE;
04427                     }
04428                 ;
04429 
04430 args_tail       : f_kwarg ',' f_kwrest opt_f_block_arg
04431                     {
04432                         $$ = new_args_tail($1, $3, $4);
04433                     }
04434                 | f_kwarg opt_f_block_arg
04435                     {
04436                         $$ = new_args_tail($1, Qnone, $2);
04437                     }
04438                 | f_kwrest opt_f_block_arg
04439                     {
04440                         $$ = new_args_tail(Qnone, $1, $2);
04441                     }
04442                 | f_block_arg
04443                     {
04444                         $$ = new_args_tail(Qnone, Qnone, $1);
04445                     }
04446                 ;
04447 
04448 opt_args_tail   : ',' args_tail
04449                     {
04450                         $$ = $2;
04451                     }
04452                 | /* none */
04453                     {
04454                         $$ = new_args_tail(Qnone, Qnone, Qnone);
04455                     }
04456                 ;
04457 
04458 f_args          : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
04459                     {
04460                         $$ = new_args($1, $3, $5, Qnone, $6);
04461                     }
04462                 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
04463                     {
04464                         $$ = new_args($1, $3, $5, $7, $8);
04465                     }
04466                 | f_arg ',' f_optarg opt_args_tail
04467                     {
04468                         $$ = new_args($1, $3, Qnone, Qnone, $4);
04469                     }
04470                 | f_arg ',' f_optarg ',' f_arg opt_args_tail
04471                     {
04472                         $$ = new_args($1, $3, Qnone, $5, $6);
04473                     }
04474                 | f_arg ',' f_rest_arg opt_args_tail
04475                     {
04476                         $$ = new_args($1, Qnone, $3, Qnone, $4);
04477                     }
04478                 | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
04479                     {
04480                         $$ = new_args($1, Qnone, $3, $5, $6);
04481                     }
04482                 | f_arg opt_args_tail
04483                     {
04484                         $$ = new_args($1, Qnone, Qnone, Qnone, $2);
04485                     }
04486                 | f_optarg ',' f_rest_arg opt_args_tail
04487                     {
04488                         $$ = new_args(Qnone, $1, $3, Qnone, $4);
04489                     }
04490                 | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
04491                     {
04492                         $$ = new_args(Qnone, $1, $3, $5, $6);
04493                     }
04494                 | f_optarg opt_args_tail
04495                     {
04496                         $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
04497                     }
04498                 | f_optarg ',' f_arg opt_args_tail
04499                     {
04500                         $$ = new_args(Qnone, $1, Qnone, $3, $4);
04501                     }
04502                 | f_rest_arg opt_args_tail
04503                     {
04504                         $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
04505                     }
04506                 | f_rest_arg ',' f_arg opt_args_tail
04507                     {
04508                         $$ = new_args(Qnone, Qnone, $1, $3, $4);
04509                     }
04510                 | args_tail
04511                     {
04512                         $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
04513                     }
04514                 | /* none */
04515                     {
04516                         $$ = new_args_tail(Qnone, Qnone, Qnone);
04517                         $$ = new_args(Qnone, Qnone, Qnone, Qnone, $$);
04518                     }
04519                 ;
04520 
04521 f_bad_arg       : tCONSTANT
04522                     {
04523                     /*%%%*/
04524                         yyerror("formal argument cannot be a constant");
04525                         $$ = 0;
04526                     /*%
04527                         $$ = dispatch1(param_error, $1);
04528                     %*/
04529                     }
04530                 | tIVAR
04531                     {
04532                     /*%%%*/
04533                         yyerror("formal argument cannot be an instance variable");
04534                         $$ = 0;
04535                     /*%
04536                         $$ = dispatch1(param_error, $1);
04537                     %*/
04538                     }
04539                 | tGVAR
04540                     {
04541                     /*%%%*/
04542                         yyerror("formal argument cannot be a global variable");
04543                         $$ = 0;
04544                     /*%
04545                         $$ = dispatch1(param_error, $1);
04546                     %*/
04547                     }
04548                 | tCVAR
04549                     {
04550                     /*%%%*/
04551                         yyerror("formal argument cannot be a class variable");
04552                         $$ = 0;
04553                     /*%
04554                         $$ = dispatch1(param_error, $1);
04555                     %*/
04556                     }
04557                 ;
04558 
04559 f_norm_arg      : f_bad_arg
04560                 | tIDENTIFIER
04561                     {
04562                         formal_argument(get_id($1));
04563                         $$ = $1;
04564                     }
04565                 ;
04566 
04567 f_arg_item      : f_norm_arg
04568                     {
04569                         arg_var(get_id($1));
04570                     /*%%%*/
04571                         $$ = NEW_ARGS_AUX($1, 1);
04572                     /*%
04573                         $$ = get_value($1);
04574                     %*/
04575                     }
04576                 | tLPAREN f_margs rparen
04577                     {
04578                         ID tid = internal_id();
04579                         arg_var(tid);
04580                     /*%%%*/
04581                         if (dyna_in_block()) {
04582                             $2->nd_value = NEW_DVAR(tid);
04583                         }
04584                         else {
04585                             $2->nd_value = NEW_LVAR(tid);
04586                         }
04587                         $$ = NEW_ARGS_AUX(tid, 1);
04588                         $$->nd_next = $2;
04589                     /*%
04590                         $$ = dispatch1(mlhs_paren, $2);
04591                     %*/
04592                     }
04593                 ;
04594 
04595 f_arg           : f_arg_item
04596                     /*%c%*/
04597                     /*%c
04598                     {
04599                         $$ = rb_ary_new3(1, $1);
04600                     }
04601                     c%*/
04602                 | f_arg ',' f_arg_item
04603                     {
04604                     /*%%%*/
04605                         $$ = $1;
04606                         $$->nd_plen++;
04607                         $$->nd_next = block_append($$->nd_next, $3->nd_next);
04608                         rb_gc_force_recycle((VALUE)$3);
04609                     /*%
04610                         $$ = rb_ary_push($1, $3);
04611                     %*/
04612                     }
04613                 ;
04614 
04615 f_kw            : tLABEL arg_value
04616                     {
04617                         arg_var(formal_argument(get_id($1)));
04618                         $$ = assignable($1, $2);
04619                     /*%%%*/
04620                         $$ = NEW_KW_ARG(0, $$);
04621                     /*%
04622                         $$ = rb_assoc_new($$, $2);
04623                     %*/
04624                     }
04625                 ;
04626 
04627 f_block_kw      : tLABEL primary_value
04628                     {
04629                         arg_var(formal_argument(get_id($1)));
04630                         $$ = assignable($1, $2);
04631                     /*%%%*/
04632                         $$ = NEW_KW_ARG(0, $$);
04633                     /*%
04634                         $$ = rb_assoc_new($$, $2);
04635                     %*/
04636                     }
04637                 ;
04638 
04639 f_block_kwarg   : f_block_kw
04640                     {
04641                     /*%%%*/
04642                         $$ = $1;
04643                     /*%
04644                         $$ = rb_ary_new3(1, $1);
04645                     %*/
04646                     }
04647                 | f_block_kwarg ',' f_block_kw
04648                     {
04649                     /*%%%*/
04650                         NODE *kws = $1;
04651 
04652                         while (kws->nd_next) {
04653                             kws = kws->nd_next;
04654                         }
04655                         kws->nd_next = $3;
04656                         $$ = $1;
04657                     /*%
04658                         $$ = rb_ary_push($1, $3);
04659                     %*/
04660                     }
04661                 ;
04662 
04663 
04664 f_kwarg         : f_kw
04665                     {
04666                     /*%%%*/
04667                         $$ = $1;
04668                     /*%
04669                         $$ = rb_ary_new3(1, $1);
04670                     %*/
04671                     }
04672                 | f_kwarg ',' f_kw
04673                     {
04674                     /*%%%*/
04675                         NODE *kws = $1;
04676 
04677                         while (kws->nd_next) {
04678                             kws = kws->nd_next;
04679                         }
04680                         kws->nd_next = $3;
04681                         $$ = $1;
04682                     /*%
04683                         $$ = rb_ary_push($1, $3);
04684                     %*/
04685                     }
04686                 ;
04687 
04688 kwrest_mark     : tPOW
04689                 | tDSTAR
04690                 ;
04691 
04692 f_kwrest        : kwrest_mark tIDENTIFIER
04693                     {
04694                         shadowing_lvar(get_id($2));
04695                         $$ = $2;
04696                     }
04697                 | kwrest_mark
04698                     {
04699                         $$ = internal_id();
04700                     }
04701                 ;
04702 
04703 f_opt           : tIDENTIFIER '=' arg_value
04704                     {
04705                         arg_var(formal_argument(get_id($1)));
04706                         $$ = assignable($1, $3);
04707                     /*%%%*/
04708                         $$ = NEW_OPT_ARG(0, $$);
04709                     /*%
04710                         $$ = rb_assoc_new($$, $3);
04711                     %*/
04712                     }
04713                 ;
04714 
04715 f_block_opt     : tIDENTIFIER '=' primary_value
04716                     {
04717                         arg_var(formal_argument(get_id($1)));
04718                         $$ = assignable($1, $3);
04719                     /*%%%*/
04720                         $$ = NEW_OPT_ARG(0, $$);
04721                     /*%
04722                         $$ = rb_assoc_new($$, $3);
04723                     %*/
04724                     }
04725                 ;
04726 
04727 f_block_optarg  : f_block_opt
04728                     {
04729                     /*%%%*/
04730                         $$ = $1;
04731                     /*%
04732                         $$ = rb_ary_new3(1, $1);
04733                     %*/
04734                     }
04735                 | f_block_optarg ',' f_block_opt
04736                     {
04737                     /*%%%*/
04738                         NODE *opts = $1;
04739 
04740                         while (opts->nd_next) {
04741                             opts = opts->nd_next;
04742                         }
04743                         opts->nd_next = $3;
04744                         $$ = $1;
04745                     /*%
04746                         $$ = rb_ary_push($1, $3);
04747                     %*/
04748                     }
04749                 ;
04750 
04751 f_optarg        : f_opt
04752                     {
04753                     /*%%%*/
04754                         $$ = $1;
04755                     /*%
04756                         $$ = rb_ary_new3(1, $1);
04757                     %*/
04758                     }
04759                 | f_optarg ',' f_opt
04760                     {
04761                     /*%%%*/
04762                         NODE *opts = $1;
04763 
04764                         while (opts->nd_next) {
04765                             opts = opts->nd_next;
04766                         }
04767                         opts->nd_next = $3;
04768                         $$ = $1;
04769                     /*%
04770                         $$ = rb_ary_push($1, $3);
04771                     %*/
04772                     }
04773                 ;
04774 
04775 restarg_mark    : '*'
04776                 | tSTAR
04777                 ;
04778 
04779 f_rest_arg      : restarg_mark tIDENTIFIER
04780                     {
04781                     /*%%%*/
04782                         if (!is_local_id($2))
04783                             yyerror("rest argument must be local variable");
04784                     /*% %*/
04785                         arg_var(shadowing_lvar(get_id($2)));
04786                     /*%%%*/
04787                         $$ = $2;
04788                     /*%
04789                         $$ = dispatch1(rest_param, $2);
04790                     %*/
04791                     }
04792                 | restarg_mark
04793                     {
04794                     /*%%%*/
04795                         $$ = internal_id();
04796                         arg_var($$);
04797                     /*%
04798                         $$ = dispatch1(rest_param, Qnil);
04799                     %*/
04800                     }
04801                 ;
04802 
04803 blkarg_mark     : '&'
04804                 | tAMPER
04805                 ;
04806 
04807 f_block_arg     : blkarg_mark tIDENTIFIER
04808                     {
04809                     /*%%%*/
04810                         if (!is_local_id($2))
04811                             yyerror("block argument must be local variable");
04812                         else if (!dyna_in_block() && local_id($2))
04813                             yyerror("duplicated block argument name");
04814                     /*% %*/
04815                         arg_var(shadowing_lvar(get_id($2)));
04816                     /*%%%*/
04817                         $$ = $2;
04818                     /*%
04819                         $$ = dispatch1(blockarg, $2);
04820                     %*/
04821                     }
04822                 ;
04823 
04824 opt_f_block_arg : ',' f_block_arg
04825                     {
04826                         $$ = $2;
04827                     }
04828                 | none
04829                     {
04830                     /*%%%*/
04831                         $$ = 0;
04832                     /*%
04833                         $$ = Qundef;
04834                     %*/
04835                     }
04836                 ;
04837 
04838 singleton       : var_ref
04839                     {
04840                     /*%%%*/
04841                         value_expr($1);
04842                         $$ = $1;
04843                         if (!$$) $$ = NEW_NIL();
04844                     /*%
04845                         $$ = $1;
04846                     %*/
04847                     }
04848                 | '(' {lex_state = EXPR_BEG;} expr rparen
04849                     {
04850                     /*%%%*/
04851                         if ($3 == 0) {
04852                             yyerror("can't define singleton method for ().");
04853                         }
04854                         else {
04855                             switch (nd_type($3)) {
04856                               case NODE_STR:
04857                               case NODE_DSTR:
04858                               case NODE_XSTR:
04859                               case NODE_DXSTR:
04860                               case NODE_DREGX:
04861                               case NODE_LIT:
04862                               case NODE_ARRAY:
04863                               case NODE_ZARRAY:
04864                                 yyerror("can't define singleton method for literals");
04865                               default:
04866                                 value_expr($3);
04867                                 break;
04868                             }
04869                         }
04870                         $$ = $3;
04871                     /*%
04872                         $$ = dispatch1(paren, $3);
04873                     %*/
04874                     }
04875                 ;
04876 
04877 assoc_list      : none
04878                 | assocs trailer
04879                     {
04880                     /*%%%*/
04881                         $$ = $1;
04882                     /*%
04883                         $$ = dispatch1(assoclist_from_args, $1);
04884                     %*/
04885                     }
04886                 ;
04887 
04888 assocs          : assoc
04889                     /*%c%*/
04890                     /*%c
04891                     {
04892                         $$ = rb_ary_new3(1, $1);
04893                     }
04894                     %*/
04895                 | assocs ',' assoc
04896                     {
04897                     /*%%%*/
04898                         $$ = list_concat($1, $3);
04899                     /*%
04900                         $$ = rb_ary_push($1, $3);
04901                     %*/
04902                     }
04903                 ;
04904 
04905 assoc           : arg_value tASSOC arg_value
04906                     {
04907                     /*%%%*/
04908                         $$ = list_append(NEW_LIST($1), $3);
04909                     /*%
04910                         $$ = dispatch2(assoc_new, $1, $3);
04911                     %*/
04912                     }
04913                 | tLABEL arg_value
04914                     {
04915                     /*%%%*/
04916                         $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
04917                     /*%
04918                         $$ = dispatch2(assoc_new, $1, $2);
04919                     %*/
04920                     }
04921                 | tDSTAR arg_value
04922                     {
04923                     /*%%%*/
04924                         $$ = list_append(NEW_LIST(0), $2);
04925                     /*%
04926                         $$ = dispatch1(assoc_splat, $2);
04927                     %*/
04928                     }
04929                 ;
04930 
04931                 ;
04932 
04933 operation       : tIDENTIFIER
04934                 | tCONSTANT
04935                 | tFID
04936                 ;
04937 
04938 operation2      : tIDENTIFIER
04939                 | tCONSTANT
04940                 | tFID
04941                 | op
04942                 ;
04943 
04944 operation3      : tIDENTIFIER
04945                 | tFID
04946                 | op
04947                 ;
04948 
04949 dot_or_colon    : '.'
04950                     /*%c%*/
04951                     /*%c
04952                     { $$ = $<val>1; }
04953                     %*/
04954                 | tCOLON2
04955                     /*%c%*/
04956                     /*%c
04957                     { $$ = $<val>1; }
04958                     %*/
04959                 ;
04960 
04961 opt_terms       : /* none */
04962                 | terms
04963                 ;
04964 
04965 opt_nl          : /* none */
04966                 | '\n'
04967                 ;
04968 
04969 rparen          : opt_nl ')'
04970                 ;
04971 
04972 rbracket        : opt_nl ']'
04973                 ;
04974 
04975 trailer         : /* none */
04976                 | '\n'
04977                 | ','
04978                 ;
04979 
04980 term            : ';' {yyerrok;}
04981                 | '\n'
04982                 ;
04983 
04984 terms           : term
04985                 | terms ';' {yyerrok;}
04986                 ;
04987 
04988 none            : /* none */
04989                     {
04990                     /*%%%*/
04991                         $$ = 0;
04992                     /*%
04993                         $$ = Qundef;
04994                     %*/
04995                     }
04996                 ;
04997 %%
04998 # undef parser
04999 # undef yylex
05000 # undef yylval
05001 # define yylval  (*((YYSTYPE*)(parser->parser_yylval)))
05002 
05003 static int parser_regx_options(struct parser_params*);
05004 static int parser_tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**);
05005 static void parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc);
05006 static int parser_parse_string(struct parser_params*,NODE*);
05007 static int parser_here_document(struct parser_params*,NODE*);
05008 
05009 
05010 # define nextc()                   parser_nextc(parser)
05011 # define pushback(c)               parser_pushback(parser, (c))
05012 # define newtok()                  parser_newtok(parser)
05013 # define tokspace(n)               parser_tokspace(parser, (n))
05014 # define tokadd(c)                 parser_tokadd(parser, (c))
05015 # define tok_hex(numlen)           parser_tok_hex(parser, (numlen))
05016 # define read_escape(flags,e)      parser_read_escape(parser, (flags), (e))
05017 # define tokadd_escape(e)          parser_tokadd_escape(parser, (e))
05018 # define regx_options()            parser_regx_options(parser)
05019 # define tokadd_string(f,t,p,n,e)  parser_tokadd_string(parser,(f),(t),(p),(n),(e))
05020 # define parse_string(n)           parser_parse_string(parser,(n))
05021 # define tokaddmbc(c, enc)         parser_tokaddmbc(parser, (c), (enc))
05022 # define here_document(n)          parser_here_document(parser,(n))
05023 # define heredoc_identifier()      parser_heredoc_identifier(parser)
05024 # define heredoc_restore(n)        parser_heredoc_restore(parser,(n))
05025 # define whole_match_p(e,l,i)      parser_whole_match_p(parser,(e),(l),(i))
05026 
05027 #ifndef RIPPER
05028 # define set_yylval_str(x) (yylval.node = NEW_STR(x))
05029 # define set_yylval_num(x) (yylval.num = (x))
05030 # define set_yylval_id(x)  (yylval.id = (x))
05031 # define set_yylval_name(x)  (yylval.id = (x))
05032 # define set_yylval_literal(x) (yylval.node = NEW_LIT(x))
05033 # define set_yylval_node(x) (yylval.node = (x))
05034 # define yylval_id() (yylval.id)
05035 #else
05036 static inline VALUE
05037 ripper_yylval_id(ID x)
05038 {
05039     return (VALUE)NEW_LASGN(x, ID2SYM(x));
05040 }
05041 # define set_yylval_str(x) (void)(x)
05042 # define set_yylval_num(x) (void)(x)
05043 # define set_yylval_id(x)  (void)(x)
05044 # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x))
05045 # define set_yylval_literal(x) (void)(x)
05046 # define set_yylval_node(x) (void)(x)
05047 # define yylval_id() yylval.id
05048 #endif
05049 
05050 #ifndef RIPPER
05051 #define ripper_flush(p) (void)(p)
05052 #else
05053 #define ripper_flush(p) ((p)->tokp = (p)->parser_lex_p)
05054 
05055 #define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
05056 
05057 static int
05058 ripper_has_scan_event(struct parser_params *parser)
05059 {
05060 
05061     if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp");
05062     return lex_p > parser->tokp;
05063 }
05064 
05065 static VALUE
05066 ripper_scan_event_val(struct parser_params *parser, int t)
05067 {
05068     VALUE str = STR_NEW(parser->tokp, lex_p - parser->tokp);
05069     VALUE rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
05070     ripper_flush(parser);
05071     return rval;
05072 }
05073 
05074 static void
05075 ripper_dispatch_scan_event(struct parser_params *parser, int t)
05076 {
05077     if (!ripper_has_scan_event(parser)) return;
05078     yylval_rval = ripper_scan_event_val(parser, t);
05079 }
05080 
05081 static void
05082 ripper_dispatch_ignored_scan_event(struct parser_params *parser, int t)
05083 {
05084     if (!ripper_has_scan_event(parser)) return;
05085     (void)ripper_scan_event_val(parser, t);
05086 }
05087 
05088 static void
05089 ripper_dispatch_delayed_token(struct parser_params *parser, int t)
05090 {
05091     int saved_line = ruby_sourceline;
05092     const char *saved_tokp = parser->tokp;
05093 
05094     ruby_sourceline = parser->delayed_line;
05095     parser->tokp = lex_pbeg + parser->delayed_col;
05096     yylval_rval = ripper_dispatch1(parser, ripper_token2eventid(t), parser->delayed);
05097     parser->delayed = Qnil;
05098     ruby_sourceline = saved_line;
05099     parser->tokp = saved_tokp;
05100 }
05101 #endif /* RIPPER */
05102 
05103 #include "ruby/regex.h"
05104 #include "ruby/util.h"
05105 
05106 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
05107    since ours (we hope) works properly with all combinations of
05108    machines, compilers, `char' and `unsigned char' argument types.
05109    (Per Bothner suggested the basic approach.)  */
05110 #undef SIGN_EXTEND_CHAR
05111 #if __STDC__
05112 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
05113 #else  /* not __STDC__ */
05114 /* As in Harbison and Steele.  */
05115 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
05116 #endif
05117 
05118 #define parser_encoding_name()  (current_enc->name)
05119 #define parser_mbclen()  mbclen((lex_p-1),lex_pend,current_enc)
05120 #define parser_precise_mbclen()  rb_enc_precise_mbclen((lex_p-1),lex_pend,current_enc)
05121 #define is_identchar(p,e,enc) (rb_enc_isalnum(*(p),(enc)) || (*(p)) == '_' || !ISASCII(*(p)))
05122 #define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,current_enc))
05123 
05124 #define parser_isascii() ISASCII(*(lex_p-1))
05125 
05126 #ifndef RIPPER
05127 static int
05128 token_info_get_column(struct parser_params *parser, const char *token)
05129 {
05130     int column = 1;
05131     const char *p, *pend = lex_p - strlen(token);
05132     for (p = lex_pbeg; p < pend; p++) {
05133         if (*p == '\t') {
05134             column = (((column - 1) / 8) + 1) * 8;
05135         }
05136         column++;
05137     }
05138     return column;
05139 }
05140 
05141 static int
05142 token_info_has_nonspaces(struct parser_params *parser, const char *token)
05143 {
05144     const char *p, *pend = lex_p - strlen(token);
05145     for (p = lex_pbeg; p < pend; p++) {
05146         if (*p != ' ' && *p != '\t') {
05147             return 1;
05148         }
05149     }
05150     return 0;
05151 }
05152 
05153 #undef token_info_push
05154 static void
05155 token_info_push(struct parser_params *parser, const char *token)
05156 {
05157     token_info *ptinfo;
05158 
05159     if (!parser->parser_token_info_enabled) return;
05160     ptinfo = ALLOC(token_info);
05161     ptinfo->token = token;
05162     ptinfo->linenum = ruby_sourceline;
05163     ptinfo->column = token_info_get_column(parser, token);
05164     ptinfo->nonspc = token_info_has_nonspaces(parser, token);
05165     ptinfo->next = parser->parser_token_info;
05166 
05167     parser->parser_token_info = ptinfo;
05168 }
05169 
05170 #undef token_info_pop
05171 static void
05172 token_info_pop(struct parser_params *parser, const char *token)
05173 {
05174     int linenum;
05175     token_info *ptinfo = parser->parser_token_info;
05176 
05177     if (!ptinfo) return;
05178     parser->parser_token_info = ptinfo->next;
05179     if (token_info_get_column(parser, token) == ptinfo->column) { /* OK */
05180         goto finish;
05181     }
05182     linenum = ruby_sourceline;
05183     if (linenum == ptinfo->linenum) { /* SKIP */
05184         goto finish;
05185     }
05186     if (token_info_has_nonspaces(parser, token) || ptinfo->nonspc) { /* SKIP */
05187         goto finish;
05188     }
05189     if (parser->parser_token_info_enabled) {
05190         rb_compile_warn(ruby_sourcefile, linenum,
05191                         "mismatched indentations at '%s' with '%s' at %d",
05192                         token, ptinfo->token, ptinfo->linenum);
05193     }
05194 
05195   finish:
05196     xfree(ptinfo);
05197 }
05198 #endif  /* RIPPER */
05199 
05200 static int
05201 parser_yyerror(struct parser_params *parser, const char *msg)
05202 {
05203 #ifndef RIPPER
05204     const int max_line_margin = 30;
05205     const char *p, *pe;
05206     char *buf;
05207     long len;
05208     int i;
05209 
05210     compile_error(PARSER_ARG "%s", msg);
05211     p = lex_p;
05212     while (lex_pbeg <= p) {
05213         if (*p == '\n') break;
05214         p--;
05215     }
05216     p++;
05217 
05218     pe = lex_p;
05219     while (pe < lex_pend) {
05220         if (*pe == '\n') break;
05221         pe++;
05222     }
05223 
05224     len = pe - p;
05225     if (len > 4) {
05226         char *p2;
05227         const char *pre = "", *post = "";
05228 
05229         if (len > max_line_margin * 2 + 10) {
05230             if (lex_p - p > max_line_margin) {
05231                 p = rb_enc_prev_char(p, lex_p - max_line_margin, pe, rb_enc_get(lex_lastline));
05232                 pre = "...";
05233             }
05234             if (pe - lex_p > max_line_margin) {
05235                 pe = rb_enc_prev_char(lex_p, lex_p + max_line_margin, pe, rb_enc_get(lex_lastline));
05236                 post = "...";
05237             }
05238             len = pe - p;
05239         }
05240         buf = ALLOCA_N(char, len+2);
05241         MEMCPY(buf, p, char, len);
05242         buf[len] = '\0';
05243         rb_compile_error_append("%s%s%s", pre, buf, post);
05244 
05245         i = (int)(lex_p - p);
05246         p2 = buf; pe = buf + len;
05247 
05248         while (p2 < pe) {
05249             if (*p2 != '\t') *p2 = ' ';
05250             p2++;
05251         }
05252         buf[i] = '^';
05253         buf[i+1] = '\0';
05254         rb_compile_error_append("%s%s", pre, buf);
05255     }
05256 #else
05257     dispatch1(parse_error, STR_NEW2(msg));
05258 #endif /* !RIPPER */
05259     return 0;
05260 }
05261 
05262 static void parser_prepare(struct parser_params *parser);
05263 
05264 #ifndef RIPPER
05265 static VALUE
05266 debug_lines(VALUE fname)
05267 {
05268     ID script_lines;
05269     CONST_ID(script_lines, "SCRIPT_LINES__");
05270     if (rb_const_defined_at(rb_cObject, script_lines)) {
05271         VALUE hash = rb_const_get_at(rb_cObject, script_lines);
05272         if (RB_TYPE_P(hash, T_HASH)) {
05273             VALUE lines = rb_ary_new();
05274             rb_hash_aset(hash, fname, lines);
05275             return lines;
05276         }
05277     }
05278     return 0;
05279 }
05280 
05281 static VALUE
05282 coverage(VALUE fname, int n)
05283 {
05284     VALUE coverages = rb_get_coverages();
05285     if (RTEST(coverages) && RBASIC(coverages)->klass == 0) {
05286         VALUE lines = rb_ary_new2(n);
05287         int i;
05288         RBASIC(lines)->klass = 0;
05289         for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
05290         RARRAY(lines)->as.heap.len = n;
05291         rb_hash_aset(coverages, fname, lines);
05292         return lines;
05293     }
05294     return 0;
05295 }
05296 
05297 static int
05298 e_option_supplied(struct parser_params *parser)
05299 {
05300     return strcmp(ruby_sourcefile, "-e") == 0;
05301 }
05302 
05303 static VALUE
05304 yycompile0(VALUE arg)
05305 {
05306     int n;
05307     NODE *tree;
05308     struct parser_params *parser = (struct parser_params *)arg;
05309 
05310     if (!compile_for_eval && rb_safe_level() == 0) {
05311         ruby_debug_lines = debug_lines(ruby_sourcefile_string);
05312         if (ruby_debug_lines && ruby_sourceline > 0) {
05313             VALUE str = STR_NEW0();
05314             n = ruby_sourceline;
05315             do {
05316                 rb_ary_push(ruby_debug_lines, str);
05317             } while (--n);
05318         }
05319 
05320         if (!e_option_supplied(parser)) {
05321             ruby_coverage = coverage(ruby_sourcefile_string, ruby_sourceline);
05322         }
05323     }
05324 
05325     parser_prepare(parser);
05326     deferred_nodes = 0;
05327 #ifndef RIPPER
05328     parser->parser_token_info_enabled = !compile_for_eval && RTEST(ruby_verbose);
05329 #endif
05330 #ifndef RIPPER
05331     if (RUBY_DTRACE_PARSE_BEGIN_ENABLED()) {
05332         RUBY_DTRACE_PARSE_BEGIN(parser->parser_ruby_sourcefile,
05333                                 parser->parser_ruby_sourceline);
05334     }
05335 #endif
05336     n = yyparse((void*)parser);
05337 #ifndef RIPPER
05338     if (RUBY_DTRACE_PARSE_END_ENABLED()) {
05339         RUBY_DTRACE_PARSE_END(parser->parser_ruby_sourcefile,
05340                               parser->parser_ruby_sourceline);
05341     }
05342 #endif
05343     ruby_debug_lines = 0;
05344     ruby_coverage = 0;
05345     compile_for_eval = 0;
05346 
05347     lex_strterm = 0;
05348     lex_p = lex_pbeg = lex_pend = 0;
05349     lex_lastline = lex_nextline = 0;
05350     if (parser->nerr) {
05351         return 0;
05352     }
05353     tree = ruby_eval_tree;
05354     if (!tree) {
05355         tree = NEW_NIL();
05356     }
05357     else if (ruby_eval_tree_begin) {
05358         tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body);
05359     }
05360     return (VALUE)tree;
05361 }
05362 
05363 static NODE*
05364 yycompile(struct parser_params *parser, VALUE fname, int line)
05365 {
05366     ruby_sourcefile_string = rb_str_new_frozen(fname);
05367     ruby_sourcefile = RSTRING_PTR(fname);
05368     ruby_sourceline = line - 1;
05369     return (NODE *)rb_suppress_tracing(yycompile0, (VALUE)parser);
05370 }
05371 #endif /* !RIPPER */
05372 
05373 static rb_encoding *
05374 must_be_ascii_compatible(VALUE s)
05375 {
05376     rb_encoding *enc = rb_enc_get(s);
05377     if (!rb_enc_asciicompat(enc)) {
05378         rb_raise(rb_eArgError, "invalid source encoding");
05379     }
05380     return enc;
05381 }
05382 
05383 static VALUE
05384 lex_get_str(struct parser_params *parser, VALUE s)
05385 {
05386     char *beg, *end, *pend;
05387     rb_encoding *enc = must_be_ascii_compatible(s);
05388 
05389     beg = RSTRING_PTR(s);
05390     if (lex_gets_ptr) {
05391         if (RSTRING_LEN(s) == lex_gets_ptr) return Qnil;
05392         beg += lex_gets_ptr;
05393     }
05394     pend = RSTRING_PTR(s) + RSTRING_LEN(s);
05395     end = beg;
05396     while (end < pend) {
05397         if (*end++ == '\n') break;
05398     }
05399     lex_gets_ptr = end - RSTRING_PTR(s);
05400     return rb_enc_str_new(beg, end - beg, enc);
05401 }
05402 
05403 static VALUE
05404 lex_getline(struct parser_params *parser)
05405 {
05406     VALUE line = (*parser->parser_lex_gets)(parser, parser->parser_lex_input);
05407     if (NIL_P(line)) return line;
05408     must_be_ascii_compatible(line);
05409 #ifndef RIPPER
05410     if (ruby_debug_lines) {
05411         rb_enc_associate(line, current_enc);
05412         rb_ary_push(ruby_debug_lines, line);
05413     }
05414     if (ruby_coverage) {
05415         rb_ary_push(ruby_coverage, Qnil);
05416     }
05417 #endif
05418     return line;
05419 }
05420 
05421 #ifdef RIPPER
05422 static rb_data_type_t parser_data_type;
05423 #else
05424 static const rb_data_type_t parser_data_type;
05425 
05426 static NODE*
05427 parser_compile_string(volatile VALUE vparser, VALUE fname, VALUE s, int line)
05428 {
05429     struct parser_params *parser;
05430     NODE *node;
05431 
05432     TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
05433     lex_gets = lex_get_str;
05434     lex_gets_ptr = 0;
05435     lex_input = s;
05436     lex_pbeg = lex_p = lex_pend = 0;
05437     compile_for_eval = rb_parse_in_eval();
05438 
05439     node = yycompile(parser, fname, line);
05440     RB_GC_GUARD(vparser); /* prohibit tail call optimization */
05441 
05442     return node;
05443 }
05444 
05445 NODE*
05446 rb_compile_string(const char *f, VALUE s, int line)
05447 {
05448     must_be_ascii_compatible(s);
05449     return parser_compile_string(rb_parser_new(), rb_filesystem_str_new_cstr(f), s, line);
05450 }
05451 
05452 NODE*
05453 rb_parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
05454 {
05455     return rb_parser_compile_string_path(vparser, rb_filesystem_str_new_cstr(f), s, line);
05456 }
05457 
05458 NODE*
05459 rb_parser_compile_string_path(volatile VALUE vparser, VALUE f, VALUE s, int line)
05460 {
05461     must_be_ascii_compatible(s);
05462     return parser_compile_string(vparser, f, s, line);
05463 }
05464 
05465 NODE*
05466 rb_compile_cstr(const char *f, const char *s, int len, int line)
05467 {
05468     VALUE str = rb_str_new(s, len);
05469     return parser_compile_string(rb_parser_new(), rb_filesystem_str_new_cstr(f), str, line);
05470 }
05471 
05472 NODE*
05473 rb_parser_compile_cstr(volatile VALUE vparser, const char *f, const char *s, int len, int line)
05474 {
05475     VALUE str = rb_str_new(s, len);
05476     return parser_compile_string(vparser, rb_filesystem_str_new_cstr(f), str, line);
05477 }
05478 
05479 static VALUE
05480 lex_io_gets(struct parser_params *parser, VALUE io)
05481 {
05482     return rb_io_gets(io);
05483 }
05484 
05485 NODE*
05486 rb_compile_file(const char *f, VALUE file, int start)
05487 {
05488     VALUE volatile vparser = rb_parser_new();
05489 
05490     return rb_parser_compile_file(vparser, f, file, start);
05491 }
05492 
05493 NODE*
05494 rb_parser_compile_file(volatile VALUE vparser, const char *f, VALUE file, int start)
05495 {
05496     return rb_parser_compile_file_path(vparser, rb_filesystem_str_new_cstr(f), file, start);
05497 }
05498 
05499 NODE*
05500 rb_parser_compile_file_path(volatile VALUE vparser, VALUE fname, VALUE file, int start)
05501 {
05502     struct parser_params *parser;
05503     NODE *node;
05504 
05505     TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
05506     lex_gets = lex_io_gets;
05507     lex_input = file;
05508     lex_pbeg = lex_p = lex_pend = 0;
05509     compile_for_eval = rb_parse_in_eval();
05510 
05511     node = yycompile(parser, fname, start);
05512     RB_GC_GUARD(vparser); /* prohibit tail call optimization */
05513 
05514     return node;
05515 }
05516 #endif  /* !RIPPER */
05517 
05518 #define STR_FUNC_ESCAPE 0x01
05519 #define STR_FUNC_EXPAND 0x02
05520 #define STR_FUNC_REGEXP 0x04
05521 #define STR_FUNC_QWORDS 0x08
05522 #define STR_FUNC_SYMBOL 0x10
05523 #define STR_FUNC_INDENT 0x20
05524 
05525 enum string_type {
05526     str_squote = (0),
05527     str_dquote = (STR_FUNC_EXPAND),
05528     str_xquote = (STR_FUNC_EXPAND),
05529     str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
05530     str_sword  = (STR_FUNC_QWORDS),
05531     str_dword  = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
05532     str_ssym   = (STR_FUNC_SYMBOL),
05533     str_dsym   = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND)
05534 };
05535 
05536 static VALUE
05537 parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *enc0)
05538 {
05539     VALUE str;
05540 
05541     str = rb_enc_str_new(p, n, enc);
05542     if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
05543         if (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) {
05544         }
05545         else if (enc0 == rb_usascii_encoding() && enc != rb_utf8_encoding()) {
05546             rb_enc_associate(str, rb_ascii8bit_encoding());
05547         }
05548     }
05549 
05550     return str;
05551 }
05552 
05553 #define lex_goto_eol(parser) ((parser)->parser_lex_p = (parser)->parser_lex_pend)
05554 #define lex_eol_p() (lex_p >= lex_pend)
05555 #define peek(c) peek_n((c), 0)
05556 #define peek_n(c,n) (lex_p+(n) < lex_pend && (c) == (unsigned char)lex_p[n])
05557 
05558 static inline int
05559 parser_nextc(struct parser_params *parser)
05560 {
05561     int c;
05562 
05563     if (lex_p == lex_pend) {
05564         VALUE v = lex_nextline;
05565         lex_nextline = 0;
05566         if (!v) {
05567             if (parser->eofp)
05568                 return -1;
05569 
05570             if (!lex_input || NIL_P(v = lex_getline(parser))) {
05571                 parser->eofp = Qtrue;
05572                 lex_goto_eol(parser);
05573                 return -1;
05574             }
05575         }
05576         {
05577 #ifdef RIPPER
05578             if (parser->tokp < lex_pend) {
05579                 if (NIL_P(parser->delayed)) {
05580                     parser->delayed = rb_str_buf_new(1024);
05581                     rb_enc_associate(parser->delayed, current_enc);
05582                     rb_str_buf_cat(parser->delayed,
05583                                    parser->tokp, lex_pend - parser->tokp);
05584                     parser->delayed_line = ruby_sourceline;
05585                     parser->delayed_col = (int)(parser->tokp - lex_pbeg);
05586                 }
05587                 else {
05588                     rb_str_buf_cat(parser->delayed,
05589                                    parser->tokp, lex_pend - parser->tokp);
05590                 }
05591             }
05592 #endif
05593             if (heredoc_end > 0) {
05594                 ruby_sourceline = heredoc_end;
05595                 heredoc_end = 0;
05596             }
05597             ruby_sourceline++;
05598             parser->line_count++;
05599             lex_pbeg = lex_p = RSTRING_PTR(v);
05600             lex_pend = lex_p + RSTRING_LEN(v);
05601             ripper_flush(parser);
05602             lex_lastline = v;
05603         }
05604     }
05605     c = (unsigned char)*lex_p++;
05606     if (c == '\r' && peek('\n')) {
05607         lex_p++;
05608         c = '\n';
05609     }
05610 
05611     return c;
05612 }
05613 
05614 static void
05615 parser_pushback(struct parser_params *parser, int c)
05616 {
05617     if (c == -1) return;
05618     lex_p--;
05619     if (lex_p > lex_pbeg && lex_p[0] == '\n' && lex_p[-1] == '\r') {
05620         lex_p--;
05621     }
05622 }
05623 
05624 #define was_bol() (lex_p == lex_pbeg + 1)
05625 
05626 #define tokfix() (tokenbuf[tokidx]='\0')
05627 #define tok() tokenbuf
05628 #define toklen() tokidx
05629 #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
05630 
05631 static char*
05632 parser_newtok(struct parser_params *parser)
05633 {
05634     tokidx = 0;
05635     tokline = ruby_sourceline;
05636     if (!tokenbuf) {
05637         toksiz = 60;
05638         tokenbuf = ALLOC_N(char, 60);
05639     }
05640     if (toksiz > 4096) {
05641         toksiz = 60;
05642         REALLOC_N(tokenbuf, char, 60);
05643     }
05644     return tokenbuf;
05645 }
05646 
05647 static char *
05648 parser_tokspace(struct parser_params *parser, int n)
05649 {
05650     tokidx += n;
05651 
05652     if (tokidx >= toksiz) {
05653         do {toksiz *= 2;} while (toksiz < tokidx);
05654         REALLOC_N(tokenbuf, char, toksiz);
05655     }
05656     return &tokenbuf[tokidx-n];
05657 }
05658 
05659 static void
05660 parser_tokadd(struct parser_params *parser, int c)
05661 {
05662     tokenbuf[tokidx++] = (char)c;
05663     if (tokidx >= toksiz) {
05664         toksiz *= 2;
05665         REALLOC_N(tokenbuf, char, toksiz);
05666     }
05667 }
05668 
05669 static int
05670 parser_tok_hex(struct parser_params *parser, size_t *numlen)
05671 {
05672     int c;
05673 
05674     c = scan_hex(lex_p, 2, numlen);
05675     if (!*numlen) {
05676         yyerror("invalid hex escape");
05677         return 0;
05678     }
05679     lex_p += *numlen;
05680     return c;
05681 }
05682 
05683 #define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
05684 
05685 /* return value is for ?\u3042 */
05686 static int
05687 parser_tokadd_utf8(struct parser_params *parser, rb_encoding **encp,
05688                    int string_literal, int symbol_literal, int regexp_literal)
05689 {
05690     /*
05691      * If string_literal is true, then we allow multiple codepoints
05692      * in \u{}, and add the codepoints to the current token.
05693      * Otherwise we're parsing a character literal and return a single
05694      * codepoint without adding it
05695      */
05696 
05697     int codepoint;
05698     size_t numlen;
05699 
05700     if (regexp_literal) { tokadd('\\'); tokadd('u'); }
05701 
05702     if (peek('{')) {  /* handle \u{...} form */
05703         do {
05704             if (regexp_literal) { tokadd(*lex_p); }
05705             nextc();
05706             codepoint = scan_hex(lex_p, 6, &numlen);
05707             if (numlen == 0)  {
05708                 yyerror("invalid Unicode escape");
05709                 return 0;
05710             }
05711             if (codepoint > 0x10ffff) {
05712                 yyerror("invalid Unicode codepoint (too large)");
05713                 return 0;
05714             }
05715             lex_p += numlen;
05716             if (regexp_literal) {
05717                 tokcopy((int)numlen);
05718             }
05719             else if (codepoint >= 0x80) {
05720                 *encp = rb_utf8_encoding();
05721                 if (string_literal) tokaddmbc(codepoint, *encp);
05722             }
05723             else if (string_literal) {
05724                 tokadd(codepoint);
05725             }
05726         } while (string_literal && (peek(' ') || peek('\t')));
05727 
05728         if (!peek('}')) {
05729             yyerror("unterminated Unicode escape");
05730             return 0;
05731         }
05732 
05733         if (regexp_literal) { tokadd('}'); }
05734         nextc();
05735     }
05736     else {                      /* handle \uxxxx form */
05737         codepoint = scan_hex(lex_p, 4, &numlen);
05738         if (numlen < 4) {
05739             yyerror("invalid Unicode escape");
05740             return 0;
05741         }
05742         lex_p += 4;
05743         if (regexp_literal) {
05744             tokcopy(4);
05745         }
05746         else if (codepoint >= 0x80) {
05747             *encp = rb_utf8_encoding();
05748             if (string_literal) tokaddmbc(codepoint, *encp);
05749         }
05750         else if (string_literal) {
05751             tokadd(codepoint);
05752         }
05753     }
05754 
05755     return codepoint;
05756 }
05757 
05758 #define ESCAPE_CONTROL 1
05759 #define ESCAPE_META    2
05760 
05761 static int
05762 parser_read_escape(struct parser_params *parser, int flags,
05763                    rb_encoding **encp)
05764 {
05765     int c;
05766     size_t numlen;
05767 
05768     switch (c = nextc()) {
05769       case '\\':        /* Backslash */
05770         return c;
05771 
05772       case 'n': /* newline */
05773         return '\n';
05774 
05775       case 't': /* horizontal tab */
05776         return '\t';
05777 
05778       case 'r': /* carriage-return */
05779         return '\r';
05780 
05781       case 'f': /* form-feed */
05782         return '\f';
05783 
05784       case 'v': /* vertical tab */
05785         return '\13';
05786 
05787       case 'a': /* alarm(bell) */
05788         return '\007';
05789 
05790       case 'e': /* escape */
05791         return 033;
05792 
05793       case '0': case '1': case '2': case '3': /* octal constant */
05794       case '4': case '5': case '6': case '7':
05795         pushback(c);
05796         c = scan_oct(lex_p, 3, &numlen);
05797         lex_p += numlen;
05798         return c;
05799 
05800       case 'x': /* hex constant */
05801         c = tok_hex(&numlen);
05802         if (numlen == 0) return 0;
05803         return c;
05804 
05805       case 'b': /* backspace */
05806         return '\010';
05807 
05808       case 's': /* space */
05809         return ' ';
05810 
05811       case 'M':
05812         if (flags & ESCAPE_META) goto eof;
05813         if ((c = nextc()) != '-') {
05814             pushback(c);
05815             goto eof;
05816         }
05817         if ((c = nextc()) == '\\') {
05818             if (peek('u')) goto eof;
05819             return read_escape(flags|ESCAPE_META, encp) | 0x80;
05820         }
05821         else if (c == -1 || !ISASCII(c)) goto eof;
05822         else {
05823             return ((c & 0xff) | 0x80);
05824         }
05825 
05826       case 'C':
05827         if ((c = nextc()) != '-') {
05828             pushback(c);
05829             goto eof;
05830         }
05831       case 'c':
05832         if (flags & ESCAPE_CONTROL) goto eof;
05833         if ((c = nextc())== '\\') {
05834             if (peek('u')) goto eof;
05835             c = read_escape(flags|ESCAPE_CONTROL, encp);
05836         }
05837         else if (c == '?')
05838             return 0177;
05839         else if (c == -1 || !ISASCII(c)) goto eof;
05840         return c & 0x9f;
05841 
05842       eof:
05843       case -1:
05844         yyerror("Invalid escape character syntax");
05845         return '\0';
05846 
05847       default:
05848         return c;
05849     }
05850 }
05851 
05852 static void
05853 parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc)
05854 {
05855     int len = rb_enc_codelen(c, enc);
05856     rb_enc_mbcput(c, tokspace(len), enc);
05857 }
05858 
05859 static int
05860 parser_tokadd_escape(struct parser_params *parser, rb_encoding **encp)
05861 {
05862     int c;
05863     int flags = 0;
05864     size_t numlen;
05865 
05866   first:
05867     switch (c = nextc()) {
05868       case '\n':
05869         return 0;               /* just ignore */
05870 
05871       case '0': case '1': case '2': case '3': /* octal constant */
05872       case '4': case '5': case '6': case '7':
05873         {
05874             ruby_scan_oct(--lex_p, 3, &numlen);
05875             if (numlen == 0) goto eof;
05876             lex_p += numlen;
05877             tokcopy((int)numlen + 1);
05878         }
05879         return 0;
05880 
05881       case 'x': /* hex constant */
05882         {
05883             tok_hex(&numlen);
05884             if (numlen == 0) return -1;
05885             tokcopy((int)numlen + 2);
05886         }
05887         return 0;
05888 
05889       case 'M':
05890         if (flags & ESCAPE_META) goto eof;
05891         if ((c = nextc()) != '-') {
05892             pushback(c);
05893             goto eof;
05894         }
05895         tokcopy(3);
05896         flags |= ESCAPE_META;
05897         goto escaped;
05898 
05899       case 'C':
05900         if (flags & ESCAPE_CONTROL) goto eof;
05901         if ((c = nextc()) != '-') {
05902             pushback(c);
05903             goto eof;
05904         }
05905         tokcopy(3);
05906         goto escaped;
05907 
05908       case 'c':
05909         if (flags & ESCAPE_CONTROL) goto eof;
05910         tokcopy(2);
05911         flags |= ESCAPE_CONTROL;
05912       escaped:
05913         if ((c = nextc()) == '\\') {
05914             goto first;
05915         }
05916         else if (c == -1) goto eof;
05917         tokadd(c);
05918         return 0;
05919 
05920       eof:
05921       case -1:
05922         yyerror("Invalid escape character syntax");
05923         return -1;
05924 
05925       default:
05926         tokadd('\\');
05927         tokadd(c);
05928     }
05929     return 0;
05930 }
05931 
05932 static int
05933 parser_regx_options(struct parser_params *parser)
05934 {
05935     int kcode = 0;
05936     int kopt = 0;
05937     int options = 0;
05938     int c, opt, kc;
05939 
05940     newtok();
05941     while (c = nextc(), ISALPHA(c)) {
05942         if (c == 'o') {
05943             options |= RE_OPTION_ONCE;
05944         }
05945         else if (rb_char_to_option_kcode(c, &opt, &kc)) {
05946             if (kc >= 0) {
05947                 if (kc != rb_ascii8bit_encindex()) kcode = c;
05948                 kopt = opt;
05949             }
05950             else {
05951                 options |= opt;
05952             }
05953         }
05954         else {
05955             tokadd(c);
05956         }
05957     }
05958     options |= kopt;
05959     pushback(c);
05960     if (toklen()) {
05961         tokfix();
05962         compile_error(PARSER_ARG "unknown regexp option%s - %s",
05963                       toklen() > 1 ? "s" : "", tok());
05964     }
05965     return options | RE_OPTION_ENCODING(kcode);
05966 }
05967 
05968 static void
05969 dispose_string(VALUE str)
05970 {
05971     rb_str_free(str);
05972     rb_gc_force_recycle(str);
05973 }
05974 
05975 static int
05976 parser_tokadd_mbchar(struct parser_params *parser, int c)
05977 {
05978     int len = parser_precise_mbclen();
05979     if (!MBCLEN_CHARFOUND_P(len)) {
05980         compile_error(PARSER_ARG "invalid multibyte char (%s)", parser_encoding_name());
05981         return -1;
05982     }
05983     tokadd(c);
05984     lex_p += --len;
05985     if (len > 0) tokcopy(len);
05986     return c;
05987 }
05988 
05989 #define tokadd_mbchar(c) parser_tokadd_mbchar(parser, (c))
05990 
05991 static inline int
05992 simple_re_meta(int c)
05993 {
05994     switch (c) {
05995       case '$': case '*': case '+': case '.':
05996       case '?': case '^': case '|':
05997       case ')': case ']': case '}': case '>':
05998         return TRUE;
05999       default:
06000         return FALSE;
06001     }
06002 }
06003 
06004 static int
06005 parser_tokadd_string(struct parser_params *parser,
06006                      int func, int term, int paren, long *nest,
06007                      rb_encoding **encp)
06008 {
06009     int c;
06010     int has_nonascii = 0;
06011     rb_encoding *enc = *encp;
06012     char *errbuf = 0;
06013     static const char mixed_msg[] = "%s mixed within %s source";
06014 
06015 #define mixed_error(enc1, enc2) if (!errbuf) {  \
06016         size_t len = sizeof(mixed_msg) - 4;     \
06017         len += strlen(rb_enc_name(enc1));       \
06018         len += strlen(rb_enc_name(enc2));       \
06019         errbuf = ALLOCA_N(char, len);           \
06020         snprintf(errbuf, len, mixed_msg,        \
06021                  rb_enc_name(enc1),             \
06022                  rb_enc_name(enc2));            \
06023         yyerror(errbuf);                        \
06024     }
06025 #define mixed_escape(beg, enc1, enc2) do {      \
06026         const char *pos = lex_p;                \
06027         lex_p = (beg);                          \
06028         mixed_error((enc1), (enc2));            \
06029         lex_p = pos;                            \
06030     } while (0)
06031 
06032     while ((c = nextc()) != -1) {
06033         if (paren && c == paren) {
06034             ++*nest;
06035         }
06036         else if (c == term) {
06037             if (!nest || !*nest) {
06038                 pushback(c);
06039                 break;
06040             }
06041             --*nest;
06042         }
06043         else if ((func & STR_FUNC_EXPAND) && c == '#' && lex_p < lex_pend) {
06044             int c2 = *lex_p;
06045             if (c2 == '$' || c2 == '@' || c2 == '{') {
06046                 pushback(c);
06047                 break;
06048             }
06049         }
06050         else if (c == '\\') {
06051             const char *beg = lex_p - 1;
06052             c = nextc();
06053             switch (c) {
06054               case '\n':
06055                 if (func & STR_FUNC_QWORDS) break;
06056                 if (func & STR_FUNC_EXPAND) continue;
06057                 tokadd('\\');
06058                 break;
06059 
06060               case '\\':
06061                 if (func & STR_FUNC_ESCAPE) tokadd(c);
06062                 break;
06063 
06064               case 'u':
06065                 if ((func & STR_FUNC_EXPAND) == 0) {
06066                     tokadd('\\');
06067                     break;
06068                 }
06069                 parser_tokadd_utf8(parser, &enc, 1,
06070                                    func & STR_FUNC_SYMBOL,
06071                                    func & STR_FUNC_REGEXP);
06072                 if (has_nonascii && enc != *encp) {
06073                     mixed_escape(beg, enc, *encp);
06074                 }
06075                 continue;
06076 
06077               default:
06078                 if (c == -1) return -1;
06079                 if (!ISASCII(c)) {
06080                     if ((func & STR_FUNC_EXPAND) == 0) tokadd('\\');
06081                     goto non_ascii;
06082                 }
06083                 if (func & STR_FUNC_REGEXP) {
06084                     if (c == term && !simple_re_meta(c)) {
06085                         tokadd(c);
06086                         continue;
06087                     }
06088                     pushback(c);
06089                     if ((c = tokadd_escape(&enc)) < 0)
06090                         return -1;
06091                     if (has_nonascii && enc != *encp) {
06092                         mixed_escape(beg, enc, *encp);
06093                     }
06094                     continue;
06095                 }
06096                 else if (func & STR_FUNC_EXPAND) {
06097                     pushback(c);
06098                     if (func & STR_FUNC_ESCAPE) tokadd('\\');
06099                     c = read_escape(0, &enc);
06100                 }
06101                 else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
06102                     /* ignore backslashed spaces in %w */
06103                 }
06104                 else if (c != term && !(paren && c == paren)) {
06105                     tokadd('\\');
06106                     pushback(c);
06107                     continue;
06108                 }
06109             }
06110         }
06111         else if (!parser_isascii()) {
06112           non_ascii:
06113             has_nonascii = 1;
06114             if (enc != *encp) {
06115                 mixed_error(enc, *encp);
06116                 continue;
06117             }
06118             if (tokadd_mbchar(c) == -1) return -1;
06119             continue;
06120         }
06121         else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
06122             pushback(c);
06123             break;
06124         }
06125         if (c & 0x80) {
06126             has_nonascii = 1;
06127             if (enc != *encp) {
06128                 mixed_error(enc, *encp);
06129                 continue;
06130             }
06131         }
06132         tokadd(c);
06133     }
06134     *encp = enc;
06135     return c;
06136 }
06137 
06138 #define NEW_STRTERM(func, term, paren) \
06139         rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
06140 
06141 #ifdef RIPPER
06142 static void
06143 ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc)
06144 {
06145     if (!NIL_P(parser->delayed)) {
06146         ptrdiff_t len = lex_p - parser->tokp;
06147         if (len > 0) {
06148             rb_enc_str_buf_cat(parser->delayed, parser->tokp, len, enc);
06149         }
06150         ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
06151         parser->tokp = lex_p;
06152     }
06153 }
06154 
06155 #define flush_string_content(enc) ripper_flush_string_content(parser, (enc))
06156 #else
06157 #define flush_string_content(enc) ((void)(enc))
06158 #endif
06159 
06160 RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
06161 /* this can be shared with ripper, since it's independent from struct
06162  * parser_params. */
06163 #ifndef RIPPER
06164 #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
06165 #define SPECIAL_PUNCT(idx) ( \
06166         BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
06167         BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
06168         BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
06169         BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
06170         BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
06171         BIT('0', idx))
06172 const unsigned int ruby_global_name_punct_bits[] = {
06173     SPECIAL_PUNCT(0),
06174     SPECIAL_PUNCT(1),
06175     SPECIAL_PUNCT(2),
06176 };
06177 #undef BIT
06178 #undef SPECIAL_PUNCT
06179 #endif
06180 
06181 static inline int
06182 is_global_name_punct(const char c)
06183 {
06184     if (c <= 0x20 || 0x7e < c) return 0;
06185     return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
06186 }
06187 
06188 static int
06189 parser_peek_variable_name(struct parser_params *parser)
06190 {
06191     int c;
06192     const char *p = lex_p;
06193 
06194     if (p + 1 >= lex_pend) return 0;
06195     c = *p++;
06196     switch (c) {
06197       case '$':
06198         if ((c = *p) == '-') {
06199             if (++p >= lex_pend) return 0;
06200             c = *p;
06201         }
06202         else if (is_global_name_punct(c) || ISDIGIT(c)) {
06203             return tSTRING_DVAR;
06204         }
06205         break;
06206       case '@':
06207         if ((c = *p) == '@') {
06208             if (++p >= lex_pend) return 0;
06209             c = *p;
06210         }
06211         break;
06212       case '{':
06213         lex_p = p;
06214         command_start = TRUE;
06215         return tSTRING_DBEG;
06216       default:
06217         return 0;
06218     }
06219     if (!ISASCII(c) || c == '_' || ISALPHA(c))
06220         return tSTRING_DVAR;
06221     return 0;
06222 }
06223 
06224 static int
06225 parser_parse_string(struct parser_params *parser, NODE *quote)
06226 {
06227     int func = (int)quote->nd_func;
06228     int term = nd_term(quote);
06229     int paren = nd_paren(quote);
06230     int c, space = 0;
06231     rb_encoding *enc = current_enc;
06232 
06233     if (func == -1) return tSTRING_END;
06234     c = nextc();
06235     if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
06236         do {c = nextc();} while (ISSPACE(c));
06237         space = 1;
06238     }
06239     if (c == term && !quote->nd_nest) {
06240         if (func & STR_FUNC_QWORDS) {
06241             quote->nd_func = -1;
06242             return ' ';
06243         }
06244         if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
06245         set_yylval_num(regx_options());
06246         return tREGEXP_END;
06247     }
06248     if (space) {
06249         pushback(c);
06250         return ' ';
06251     }
06252     newtok();
06253     if ((func & STR_FUNC_EXPAND) && c == '#') {
06254         int t = parser_peek_variable_name(parser);
06255         if (t) return t;
06256         tokadd('#');
06257         c = nextc();
06258     }
06259     pushback(c);
06260     if (tokadd_string(func, term, paren, &quote->nd_nest,
06261                       &enc) == -1) {
06262         ruby_sourceline = nd_line(quote);
06263         if (func & STR_FUNC_REGEXP) {
06264             if (parser->eofp)
06265                 compile_error(PARSER_ARG "unterminated regexp meets end of file");
06266             return tREGEXP_END;
06267         }
06268         else {
06269             if (parser->eofp)
06270                 compile_error(PARSER_ARG "unterminated string meets end of file");
06271             return tSTRING_END;
06272         }
06273     }
06274 
06275     tokfix();
06276     set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
06277     flush_string_content(enc);
06278 
06279     return tSTRING_CONTENT;
06280 }
06281 
06282 static int
06283 parser_heredoc_identifier(struct parser_params *parser)
06284 {
06285     int c = nextc(), term, func = 0;
06286     long len;
06287 
06288     if (c == '-') {
06289         c = nextc();
06290         func = STR_FUNC_INDENT;
06291     }
06292     switch (c) {
06293       case '\'':
06294         func |= str_squote; goto quoted;
06295       case '"':
06296         func |= str_dquote; goto quoted;
06297       case '`':
06298         func |= str_xquote;
06299       quoted:
06300         newtok();
06301         tokadd(func);
06302         term = c;
06303         while ((c = nextc()) != -1 && c != term) {
06304             if (tokadd_mbchar(c) == -1) return 0;
06305         }
06306         if (c == -1) {
06307             compile_error(PARSER_ARG "unterminated here document identifier");
06308             return 0;
06309         }
06310         break;
06311 
06312       default:
06313         if (!parser_is_identchar()) {
06314             pushback(c);
06315             if (func & STR_FUNC_INDENT) {
06316                 pushback('-');
06317             }
06318             return 0;
06319         }
06320         newtok();
06321         term = '"';
06322         tokadd(func |= str_dquote);
06323         do {
06324             if (tokadd_mbchar(c) == -1) return 0;
06325         } while ((c = nextc()) != -1 && parser_is_identchar());
06326         pushback(c);
06327         break;
06328     }
06329 
06330     tokfix();
06331 #ifdef RIPPER
06332     ripper_dispatch_scan_event(parser, tHEREDOC_BEG);
06333 #endif
06334     len = lex_p - lex_pbeg;
06335     lex_goto_eol(parser);
06336     lex_strterm = rb_node_newnode(NODE_HEREDOC,
06337                                   STR_NEW(tok(), toklen()),     /* nd_lit */
06338                                   len,                          /* nd_nth */
06339                                   lex_lastline);                /* nd_orig */
06340     nd_set_line(lex_strterm, ruby_sourceline);
06341     ripper_flush(parser);
06342     return term == '`' ? tXSTRING_BEG : tSTRING_BEG;
06343 }
06344 
06345 static void
06346 parser_heredoc_restore(struct parser_params *parser, NODE *here)
06347 {
06348     VALUE line;
06349 
06350     line = here->nd_orig;
06351     lex_lastline = line;
06352     lex_pbeg = RSTRING_PTR(line);
06353     lex_pend = lex_pbeg + RSTRING_LEN(line);
06354     lex_p = lex_pbeg + here->nd_nth;
06355     heredoc_end = ruby_sourceline;
06356     ruby_sourceline = nd_line(here);
06357     dispose_string(here->nd_lit);
06358     rb_gc_force_recycle((VALUE)here);
06359     ripper_flush(parser);
06360 }
06361 
06362 static int
06363 parser_whole_match_p(struct parser_params *parser,
06364     const char *eos, long len, int indent)
06365 {
06366     const char *p = lex_pbeg;
06367     long n;
06368 
06369     if (indent) {
06370         while (*p && ISSPACE(*p)) p++;
06371     }
06372     n = lex_pend - (p + len);
06373     if (n < 0 || (n > 0 && p[len] != '\n' && p[len] != '\r')) return FALSE;
06374     return strncmp(eos, p, len) == 0;
06375 }
06376 
06377 #ifdef RIPPER
06378 static void
06379 ripper_dispatch_heredoc_end(struct parser_params *parser)
06380 {
06381     if (!NIL_P(parser->delayed))
06382         ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
06383     lex_goto_eol(parser);
06384     ripper_dispatch_ignored_scan_event(parser, tHEREDOC_END);
06385 }
06386 
06387 #define dispatch_heredoc_end() ripper_dispatch_heredoc_end(parser)
06388 #else
06389 #define dispatch_heredoc_end() ((void)0)
06390 #endif
06391 
06392 static int
06393 parser_here_document(struct parser_params *parser, NODE *here)
06394 {
06395     int c, func, indent = 0;
06396     const char *eos, *p, *pend;
06397     long len;
06398     VALUE str = 0;
06399     rb_encoding *enc = current_enc;
06400 
06401     eos = RSTRING_PTR(here->nd_lit);
06402     len = RSTRING_LEN(here->nd_lit) - 1;
06403     indent = (func = *eos++) & STR_FUNC_INDENT;
06404 
06405     if ((c = nextc()) == -1) {
06406       error:
06407         compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
06408 #ifdef RIPPER
06409         if (NIL_P(parser->delayed)) {
06410             ripper_dispatch_scan_event(parser, tSTRING_CONTENT);
06411         }
06412         else {
06413             if (str ||
06414                 ((len = lex_p - parser->tokp) > 0 &&
06415                  (str = STR_NEW3(parser->tokp, len, enc, func), 1))) {
06416                 rb_str_append(parser->delayed, str);
06417             }
06418             ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
06419         }
06420         lex_goto_eol(parser);
06421 #endif
06422       restore:
06423         heredoc_restore(lex_strterm);
06424         lex_strterm = 0;
06425         return 0;
06426     }
06427     if (was_bol() && whole_match_p(eos, len, indent)) {
06428         dispatch_heredoc_end();
06429         heredoc_restore(lex_strterm);
06430         return tSTRING_END;
06431     }
06432 
06433     if (!(func & STR_FUNC_EXPAND)) {
06434         do {
06435             p = RSTRING_PTR(lex_lastline);
06436             pend = lex_pend;
06437             if (pend > p) {
06438                 switch (pend[-1]) {
06439                   case '\n':
06440                     if (--pend == p || pend[-1] != '\r') {
06441                         pend++;
06442                         break;
06443                     }
06444                   case '\r':
06445                     --pend;
06446                 }
06447             }
06448             if (str)
06449                 rb_str_cat(str, p, pend - p);
06450             else
06451                 str = STR_NEW(p, pend - p);
06452             if (pend < lex_pend) rb_str_cat(str, "\n", 1);
06453             lex_goto_eol(parser);
06454             if (nextc() == -1) {
06455                 if (str) dispose_string(str);
06456                 goto error;
06457             }
06458         } while (!whole_match_p(eos, len, indent));
06459     }
06460     else {
06461         /*      int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
06462         newtok();
06463         if (c == '#') {
06464             int t = parser_peek_variable_name(parser);
06465             if (t) return t;
06466             tokadd('#');
06467             c = nextc();
06468         }
06469         do {
06470             pushback(c);
06471             if ((c = tokadd_string(func, '\n', 0, NULL, &enc)) == -1) {
06472                 if (parser->eofp) goto error;
06473                 goto restore;
06474             }
06475             if (c != '\n') {
06476                 set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
06477                 flush_string_content(enc);
06478                 return tSTRING_CONTENT;
06479             }
06480             tokadd(nextc());
06481             /*      if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
06482             if ((c = nextc()) == -1) goto error;
06483         } while (!whole_match_p(eos, len, indent));
06484         str = STR_NEW3(tok(), toklen(), enc, func);
06485     }
06486     dispatch_heredoc_end();
06487     heredoc_restore(lex_strterm);
06488     lex_strterm = NEW_STRTERM(-1, 0, 0);
06489     set_yylval_str(str);
06490     return tSTRING_CONTENT;
06491 }
06492 
06493 #include "lex.c"
06494 
06495 static void
06496 arg_ambiguous_gen(struct parser_params *parser)
06497 {
06498 #ifndef RIPPER
06499     rb_warning0("ambiguous first argument; put parentheses or even spaces");
06500 #else
06501     dispatch0(arg_ambiguous);
06502 #endif
06503 }
06504 #define arg_ambiguous() (arg_ambiguous_gen(parser), 1)
06505 
06506 static ID
06507 formal_argument_gen(struct parser_params *parser, ID lhs)
06508 {
06509 #ifndef RIPPER
06510     if (!is_local_id(lhs))
06511         yyerror("formal argument must be local variable");
06512 #endif
06513     shadowing_lvar(lhs);
06514     return lhs;
06515 }
06516 
06517 static int
06518 lvar_defined_gen(struct parser_params *parser, ID id)
06519 {
06520     return (dyna_in_block() && dvar_defined_get(id)) || local_id(id);
06521 }
06522 
06523 /* emacsen -*- hack */
06524 static long
06525 parser_encode_length(struct parser_params *parser, const char *name, long len)
06526 {
06527     long nlen;
06528 
06529     if (len > 5 && name[nlen = len - 5] == '-') {
06530         if (rb_memcicmp(name + nlen + 1, "unix", 4) == 0)
06531             return nlen;
06532     }
06533     if (len > 4 && name[nlen = len - 4] == '-') {
06534         if (rb_memcicmp(name + nlen + 1, "dos", 3) == 0)
06535             return nlen;
06536         if (rb_memcicmp(name + nlen + 1, "mac", 3) == 0 &&
06537             !(len == 8 && rb_memcicmp(name, "utf8-mac", len) == 0))
06538             /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
06539             return nlen;
06540     }
06541     return len;
06542 }
06543 
06544 static void
06545 parser_set_encode(struct parser_params *parser, const char *name)
06546 {
06547     int idx = rb_enc_find_index(name);
06548     rb_encoding *enc;
06549     VALUE excargs[3];
06550 
06551     if (idx < 0) {
06552         excargs[1] = rb_sprintf("unknown encoding name: %s", name);
06553       error:
06554         excargs[0] = rb_eArgError;
06555         excargs[2] = rb_make_backtrace();
06556         rb_ary_unshift(excargs[2], rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline));
06557         rb_exc_raise(rb_make_exception(3, excargs));
06558     }
06559     enc = rb_enc_from_index(idx);
06560     if (!rb_enc_asciicompat(enc)) {
06561         excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
06562         goto error;
06563     }
06564     parser->enc = enc;
06565 #ifndef RIPPER
06566     if (ruby_debug_lines) {
06567         long i, n = RARRAY_LEN(ruby_debug_lines);
06568         const VALUE *p = RARRAY_PTR(ruby_debug_lines);
06569         for (i = 0; i < n; ++i) {
06570             rb_enc_associate_index(*p, idx);
06571         }
06572     }
06573 #endif
06574 }
06575 
06576 static int
06577 comment_at_top(struct parser_params *parser)
06578 {
06579     const char *p = lex_pbeg, *pend = lex_p - 1;
06580     if (parser->line_count != (parser->has_shebang ? 2 : 1)) return 0;
06581     while (p < pend) {
06582         if (!ISSPACE(*p)) return 0;
06583         p++;
06584     }
06585     return 1;
06586 }
06587 
06588 #ifndef RIPPER
06589 typedef long (*rb_magic_comment_length_t)(struct parser_params *parser, const char *name, long len);
06590 typedef void (*rb_magic_comment_setter_t)(struct parser_params *parser, const char *name, const char *val);
06591 
06592 static void
06593 magic_comment_encoding(struct parser_params *parser, const char *name, const char *val)
06594 {
06595     if (!comment_at_top(parser)) {
06596         return;
06597     }
06598     parser_set_encode(parser, val);
06599 }
06600 
06601 static void
06602 parser_set_token_info(struct parser_params *parser, const char *name, const char *val)
06603 {
06604     int *p = &parser->parser_token_info_enabled;
06605 
06606     switch (*val) {
06607       case 't': case 'T':
06608         if (strcasecmp(val, "true") == 0) {
06609             *p = TRUE;
06610             return;
06611         }
06612         break;
06613       case 'f': case 'F':
06614         if (strcasecmp(val, "false") == 0) {
06615             *p = FALSE;
06616             return;
06617         }
06618         break;
06619     }
06620     rb_compile_warning(ruby_sourcefile, ruby_sourceline, "invalid value for %s: %s", name, val);
06621 }
06622 
06623 struct magic_comment {
06624     const char *name;
06625     rb_magic_comment_setter_t func;
06626     rb_magic_comment_length_t length;
06627 };
06628 
06629 static const struct magic_comment magic_comments[] = {
06630     {"coding", magic_comment_encoding, parser_encode_length},
06631     {"encoding", magic_comment_encoding, parser_encode_length},
06632     {"warn_indent", parser_set_token_info},
06633 };
06634 #endif
06635 
06636 static const char *
06637 magic_comment_marker(const char *str, long len)
06638 {
06639     long i = 2;
06640 
06641     while (i < len) {
06642         switch (str[i]) {
06643           case '-':
06644             if (str[i-1] == '*' && str[i-2] == '-') {
06645                 return str + i + 1;
06646             }
06647             i += 2;
06648             break;
06649           case '*':
06650             if (i + 1 >= len) return 0;
06651             if (str[i+1] != '-') {
06652                 i += 4;
06653             }
06654             else if (str[i-1] != '-') {
06655                 i += 2;
06656             }
06657             else {
06658                 return str + i + 2;
06659             }
06660             break;
06661           default:
06662             i += 3;
06663             break;
06664         }
06665     }
06666     return 0;
06667 }
06668 
06669 static int
06670 parser_magic_comment(struct parser_params *parser, const char *str, long len)
06671 {
06672     VALUE name = 0, val = 0;
06673     const char *beg, *end, *vbeg, *vend;
06674 #define str_copy(_s, _p, _n) ((_s) \
06675         ? (void)(rb_str_resize((_s), (_n)), \
06676            MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
06677         : (void)((_s) = STR_NEW((_p), (_n))))
06678 
06679     if (len <= 7) return FALSE;
06680     if (!(beg = magic_comment_marker(str, len))) return FALSE;
06681     if (!(end = magic_comment_marker(beg, str + len - beg))) return FALSE;
06682     str = beg;
06683     len = end - beg - 3;
06684 
06685     /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
06686     while (len > 0) {
06687 #ifndef RIPPER
06688         const struct magic_comment *p = magic_comments;
06689 #endif
06690         char *s;
06691         int i;
06692         long n = 0;
06693 
06694         for (; len > 0 && *str; str++, --len) {
06695             switch (*str) {
06696               case '\'': case '"': case ':': case ';':
06697                 continue;
06698             }
06699             if (!ISSPACE(*str)) break;
06700         }
06701         for (beg = str; len > 0; str++, --len) {
06702             switch (*str) {
06703               case '\'': case '"': case ':': case ';':
06704                 break;
06705               default:
06706                 if (ISSPACE(*str)) break;
06707                 continue;
06708             }
06709             break;
06710         }
06711         for (end = str; len > 0 && ISSPACE(*str); str++, --len);
06712         if (!len) break;
06713         if (*str != ':') continue;
06714 
06715         do str++; while (--len > 0 && ISSPACE(*str));
06716         if (!len) break;
06717         if (*str == '"') {
06718             for (vbeg = ++str; --len > 0 && *str != '"'; str++) {
06719                 if (*str == '\\') {
06720                     --len;
06721                     ++str;
06722                 }
06723             }
06724             vend = str;
06725             if (len) {
06726                 --len;
06727                 ++str;
06728             }
06729         }
06730         else {
06731             for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
06732             vend = str;
06733         }
06734         while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
06735 
06736         n = end - beg;
06737         str_copy(name, beg, n);
06738         s = RSTRING_PTR(name);
06739         for (i = 0; i < n; ++i) {
06740             if (s[i] == '-') s[i] = '_';
06741         }
06742 #ifndef RIPPER
06743         do {
06744             if (STRNCASECMP(p->name, s, n) == 0) {
06745                 n = vend - vbeg;
06746                 if (p->length) {
06747                     n = (*p->length)(parser, vbeg, n);
06748                 }
06749                 str_copy(val, vbeg, n);
06750                 (*p->func)(parser, s, RSTRING_PTR(val));
06751                 break;
06752             }
06753         } while (++p < magic_comments + numberof(magic_comments));
06754 #else
06755         str_copy(val, vbeg, vend - vbeg);
06756         dispatch2(magic_comment, name, val);
06757 #endif
06758     }
06759 
06760     return TRUE;
06761 }
06762 
06763 static void
06764 set_file_encoding(struct parser_params *parser, const char *str, const char *send)
06765 {
06766     int sep = 0;
06767     const char *beg = str;
06768     VALUE s;
06769 
06770     for (;;) {
06771         if (send - str <= 6) return;
06772         switch (str[6]) {
06773           case 'C': case 'c': str += 6; continue;
06774           case 'O': case 'o': str += 5; continue;
06775           case 'D': case 'd': str += 4; continue;
06776           case 'I': case 'i': str += 3; continue;
06777           case 'N': case 'n': str += 2; continue;
06778           case 'G': case 'g': str += 1; continue;
06779           case '=': case ':':
06780             sep = 1;
06781             str += 6;
06782             break;
06783           default:
06784             str += 6;
06785             if (ISSPACE(*str)) break;
06786             continue;
06787         }
06788         if (STRNCASECMP(str-6, "coding", 6) == 0) break;
06789     }
06790     for (;;) {
06791         do {
06792             if (++str >= send) return;
06793         } while (ISSPACE(*str));
06794         if (sep) break;
06795         if (*str != '=' && *str != ':') return;
06796         sep = 1;
06797         str++;
06798     }
06799     beg = str;
06800     while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
06801     s = rb_str_new(beg, parser_encode_length(parser, beg, str - beg));
06802     parser_set_encode(parser, RSTRING_PTR(s));
06803     rb_str_resize(s, 0);
06804 }
06805 
06806 static void
06807 parser_prepare(struct parser_params *parser)
06808 {
06809     int c = nextc();
06810     switch (c) {
06811       case '#':
06812         if (peek('!')) parser->has_shebang = 1;
06813         break;
06814       case 0xef:                /* UTF-8 BOM marker */
06815         if (lex_pend - lex_p >= 2 &&
06816             (unsigned char)lex_p[0] == 0xbb &&
06817             (unsigned char)lex_p[1] == 0xbf) {
06818             parser->enc = rb_utf8_encoding();
06819             lex_p += 2;
06820             lex_pbeg = lex_p;
06821             return;
06822         }
06823         break;
06824       case EOF:
06825         return;
06826     }
06827     pushback(c);
06828     parser->enc = rb_enc_get(lex_lastline);
06829 }
06830 
06831 #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
06832 #define IS_END() IS_lex_state(EXPR_END_ANY)
06833 #define IS_BEG() IS_lex_state(EXPR_BEG_ANY)
06834 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
06835 #define IS_LABEL_POSSIBLE() ((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !cmd_state) || IS_ARG())
06836 #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
06837 #define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
06838 
06839 #ifndef RIPPER
06840 #define ambiguous_operator(op, syn) ( \
06841     rb_warning0("`"op"' after local variable is interpreted as binary operator"), \
06842     rb_warning0("even though it seems like "syn""))
06843 #else
06844 #define ambiguous_operator(op, syn) dispatch2(operator_ambiguous, ripper_intern(op), rb_str_new_cstr(syn))
06845 #endif
06846 #define warn_balanced(op, syn) ((void) \
06847     (!IS_lex_state_for(last_state, EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN|EXPR_ENDARG) && \
06848      space_seen && !ISSPACE(c) && \
06849      (ambiguous_operator(op, syn), 0)))
06850 
06851 static int
06852 parser_yylex(struct parser_params *parser)
06853 {
06854     register int c;
06855     int space_seen = 0;
06856     int cmd_state;
06857     enum lex_state_e last_state;
06858     rb_encoding *enc;
06859     int mb;
06860 #ifdef RIPPER
06861     int fallthru = FALSE;
06862 #endif
06863 
06864     if (lex_strterm) {
06865         int token;
06866         if (nd_type(lex_strterm) == NODE_HEREDOC) {
06867             token = here_document(lex_strterm);
06868             if (token == tSTRING_END) {
06869                 lex_strterm = 0;
06870                 lex_state = EXPR_END;
06871             }
06872         }
06873         else {
06874             token = parse_string(lex_strterm);
06875             if (token == tSTRING_END || token == tREGEXP_END) {
06876                 rb_gc_force_recycle((VALUE)lex_strterm);
06877                 lex_strterm = 0;
06878                 lex_state = EXPR_END;
06879             }
06880         }
06881         return token;
06882     }
06883     cmd_state = command_start;
06884     command_start = FALSE;
06885   retry:
06886     last_state = lex_state;
06887     switch (c = nextc()) {
06888       case '\0':                /* NUL */
06889       case '\004':              /* ^D */
06890       case '\032':              /* ^Z */
06891       case -1:                  /* end of script. */
06892         return 0;
06893 
06894         /* white spaces */
06895       case ' ': case '\t': case '\f': case '\r':
06896       case '\13': /* '\v' */
06897         space_seen = 1;
06898 #ifdef RIPPER
06899         while ((c = nextc())) {
06900             switch (c) {
06901               case ' ': case '\t': case '\f': case '\r':
06902               case '\13': /* '\v' */
06903                 break;
06904               default:
06905                 goto outofloop;
06906             }
06907         }
06908       outofloop:
06909         pushback(c);
06910         ripper_dispatch_scan_event(parser, tSP);
06911 #endif
06912         goto retry;
06913 
06914       case '#':         /* it's a comment */
06915         /* no magic_comment in shebang line */
06916         if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
06917             if (comment_at_top(parser)) {
06918                 set_file_encoding(parser, lex_p, lex_pend);
06919             }
06920         }
06921         lex_p = lex_pend;
06922 #ifdef RIPPER
06923         ripper_dispatch_scan_event(parser, tCOMMENT);
06924         fallthru = TRUE;
06925 #endif
06926         /* fall through */
06927       case '\n':
06928         if (IS_lex_state(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT)) {
06929 #ifdef RIPPER
06930             if (!fallthru) {
06931                 ripper_dispatch_scan_event(parser, tIGNORED_NL);
06932             }
06933             fallthru = FALSE;
06934 #endif
06935             goto retry;
06936         }
06937         while ((c = nextc())) {
06938             switch (c) {
06939               case ' ': case '\t': case '\f': case '\r':
06940               case '\13': /* '\v' */
06941                 space_seen = 1;
06942                 break;
06943               case '.': {
06944                   if ((c = nextc()) != '.') {
06945                       pushback(c);
06946                       pushback('.');
06947                       goto retry;
06948                   }
06949               }
06950               default:
06951                 --ruby_sourceline;
06952                 lex_nextline = lex_lastline;
06953               case -1:          /* EOF no decrement*/
06954                 lex_goto_eol(parser);
06955 #ifdef RIPPER
06956                 if (c != -1) {
06957                     parser->tokp = lex_p;
06958                 }
06959 #endif
06960                 goto normal_newline;
06961             }
06962         }
06963       normal_newline:
06964         command_start = TRUE;
06965         lex_state = EXPR_BEG;
06966         return '\n';
06967 
06968       case '*':
06969         if ((c = nextc()) == '*') {
06970             if ((c = nextc()) == '=') {
06971                 set_yylval_id(tPOW);
06972                 lex_state = EXPR_BEG;
06973                 return tOP_ASGN;
06974             }
06975             pushback(c);
06976             if (IS_SPCARG(c)) {
06977                 rb_warning0("`**' interpreted as argument prefix");
06978                 c = tDSTAR;
06979             }
06980             else if (IS_BEG()) {
06981                 c = tDSTAR;
06982             }
06983             else {
06984                 warn_balanced("**", "argument prefix");
06985                 c = tPOW;
06986             }
06987         }
06988         else {
06989             if (c == '=') {
06990                 set_yylval_id('*');
06991                 lex_state = EXPR_BEG;
06992                 return tOP_ASGN;
06993             }
06994             pushback(c);
06995             if (IS_SPCARG(c)) {
06996                 rb_warning0("`*' interpreted as argument prefix");
06997                 c = tSTAR;
06998             }
06999             else if (IS_BEG()) {
07000                 c = tSTAR;
07001             }
07002             else {
07003                 warn_balanced("*", "argument prefix");
07004                 c = '*';
07005             }
07006         }
07007         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07008         return c;
07009 
07010       case '!':
07011         c = nextc();
07012         if (IS_AFTER_OPERATOR()) {
07013             lex_state = EXPR_ARG;
07014             if (c == '@') {
07015                 return '!';
07016             }
07017         }
07018         else {
07019             lex_state = EXPR_BEG;
07020         }
07021         if (c == '=') {
07022             return tNEQ;
07023         }
07024         if (c == '~') {
07025             return tNMATCH;
07026         }
07027         pushback(c);
07028         return '!';
07029 
07030       case '=':
07031         if (was_bol()) {
07032             /* skip embedded rd document */
07033             if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
07034 #ifdef RIPPER
07035                 int first_p = TRUE;
07036 
07037                 lex_goto_eol(parser);
07038                 ripper_dispatch_scan_event(parser, tEMBDOC_BEG);
07039 #endif
07040                 for (;;) {
07041                     lex_goto_eol(parser);
07042 #ifdef RIPPER
07043                     if (!first_p) {
07044                         ripper_dispatch_scan_event(parser, tEMBDOC);
07045                     }
07046                     first_p = FALSE;
07047 #endif
07048                     c = nextc();
07049                     if (c == -1) {
07050                         compile_error(PARSER_ARG "embedded document meets end of file");
07051                         return 0;
07052                     }
07053                     if (c != '=') continue;
07054                     if (strncmp(lex_p, "end", 3) == 0 &&
07055                         (lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {
07056                         break;
07057                     }
07058                 }
07059                 lex_goto_eol(parser);
07060 #ifdef RIPPER
07061                 ripper_dispatch_scan_event(parser, tEMBDOC_END);
07062 #endif
07063                 goto retry;
07064             }
07065         }
07066 
07067         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07068         if ((c = nextc()) == '=') {
07069             if ((c = nextc()) == '=') {
07070                 return tEQQ;
07071             }
07072             pushback(c);
07073             return tEQ;
07074         }
07075         if (c == '~') {
07076             return tMATCH;
07077         }
07078         else if (c == '>') {
07079             return tASSOC;
07080         }
07081         pushback(c);
07082         return '=';
07083 
07084       case '<':
07085         last_state = lex_state;
07086         c = nextc();
07087         if (c == '<' &&
07088             !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
07089             !IS_END() &&
07090             (!IS_ARG() || space_seen)) {
07091             int token = heredoc_identifier();
07092             if (token) return token;
07093         }
07094         if (IS_AFTER_OPERATOR()) {
07095             lex_state = EXPR_ARG;
07096         }
07097         else {
07098             if (IS_lex_state(EXPR_CLASS))
07099                 command_start = TRUE;
07100             lex_state = EXPR_BEG;
07101         }
07102         if (c == '=') {
07103             if ((c = nextc()) == '>') {
07104                 return tCMP;
07105             }
07106             pushback(c);
07107             return tLEQ;
07108         }
07109         if (c == '<') {
07110             if ((c = nextc()) == '=') {
07111                 set_yylval_id(tLSHFT);
07112                 lex_state = EXPR_BEG;
07113                 return tOP_ASGN;
07114             }
07115             pushback(c);
07116             warn_balanced("<<", "here document");
07117             return tLSHFT;
07118         }
07119         pushback(c);
07120         return '<';
07121 
07122       case '>':
07123         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07124         if ((c = nextc()) == '=') {
07125             return tGEQ;
07126         }
07127         if (c == '>') {
07128             if ((c = nextc()) == '=') {
07129                 set_yylval_id(tRSHFT);
07130                 lex_state = EXPR_BEG;
07131                 return tOP_ASGN;
07132             }
07133             pushback(c);
07134             return tRSHFT;
07135         }
07136         pushback(c);
07137         return '>';
07138 
07139       case '"':
07140         lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
07141         return tSTRING_BEG;
07142 
07143       case '`':
07144         if (IS_lex_state(EXPR_FNAME)) {
07145             lex_state = EXPR_ENDFN;
07146             return c;
07147         }
07148         if (IS_lex_state(EXPR_DOT)) {
07149             if (cmd_state)
07150                 lex_state = EXPR_CMDARG;
07151             else
07152                 lex_state = EXPR_ARG;
07153             return c;
07154         }
07155         lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
07156         return tXSTRING_BEG;
07157 
07158       case '\'':
07159         lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
07160         return tSTRING_BEG;
07161 
07162       case '?':
07163         if (IS_END()) {
07164             lex_state = EXPR_VALUE;
07165             return '?';
07166         }
07167         c = nextc();
07168         if (c == -1) {
07169             compile_error(PARSER_ARG "incomplete character syntax");
07170             return 0;
07171         }
07172         if (rb_enc_isspace(c, current_enc)) {
07173             if (!IS_ARG()) {
07174                 int c2 = 0;
07175                 switch (c) {
07176                   case ' ':
07177                     c2 = 's';
07178                     break;
07179                   case '\n':
07180                     c2 = 'n';
07181                     break;
07182                   case '\t':
07183                     c2 = 't';
07184                     break;
07185                   case '\v':
07186                     c2 = 'v';
07187                     break;
07188                   case '\r':
07189                     c2 = 'r';
07190                     break;
07191                   case '\f':
07192                     c2 = 'f';
07193                     break;
07194                 }
07195                 if (c2) {
07196                     rb_warnI("invalid character syntax; use ?\\%c", c2);
07197                 }
07198             }
07199           ternary:
07200             pushback(c);
07201             lex_state = EXPR_VALUE;
07202             return '?';
07203         }
07204         newtok();
07205         enc = current_enc;
07206         if (!parser_isascii()) {
07207             if (tokadd_mbchar(c) == -1) return 0;
07208         }
07209         else if ((rb_enc_isalnum(c, current_enc) || c == '_') &&
07210                  lex_p < lex_pend && is_identchar(lex_p, lex_pend, current_enc)) {
07211             goto ternary;
07212         }
07213         else if (c == '\\') {
07214             if (peek('u')) {
07215                 nextc();
07216                 c = parser_tokadd_utf8(parser, &enc, 0, 0, 0);
07217                 if (0x80 <= c) {
07218                     tokaddmbc(c, enc);
07219                 }
07220                 else {
07221                     tokadd(c);
07222                 }
07223             }
07224             else if (!lex_eol_p() && !(c = *lex_p, ISASCII(c))) {
07225                 nextc();
07226                 if (tokadd_mbchar(c) == -1) return 0;
07227             }
07228             else {
07229                 c = read_escape(0, &enc);
07230                 tokadd(c);
07231             }
07232         }
07233         else {
07234             tokadd(c);
07235         }
07236         tokfix();
07237         set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0));
07238         lex_state = EXPR_END;
07239         return tCHAR;
07240 
07241       case '&':
07242         if ((c = nextc()) == '&') {
07243             lex_state = EXPR_BEG;
07244             if ((c = nextc()) == '=') {
07245                 set_yylval_id(tANDOP);
07246                 lex_state = EXPR_BEG;
07247                 return tOP_ASGN;
07248             }
07249             pushback(c);
07250             return tANDOP;
07251         }
07252         else if (c == '=') {
07253             set_yylval_id('&');
07254             lex_state = EXPR_BEG;
07255             return tOP_ASGN;
07256         }
07257         pushback(c);
07258         if (IS_SPCARG(c)) {
07259             rb_warning0("`&' interpreted as argument prefix");
07260             c = tAMPER;
07261         }
07262         else if (IS_BEG()) {
07263             c = tAMPER;
07264         }
07265         else {
07266             warn_balanced("&", "argument prefix");
07267             c = '&';
07268         }
07269         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07270         return c;
07271 
07272       case '|':
07273         if ((c = nextc()) == '|') {
07274             lex_state = EXPR_BEG;
07275             if ((c = nextc()) == '=') {
07276                 set_yylval_id(tOROP);
07277                 lex_state = EXPR_BEG;
07278                 return tOP_ASGN;
07279             }
07280             pushback(c);
07281             return tOROP;
07282         }
07283         if (c == '=') {
07284             set_yylval_id('|');
07285             lex_state = EXPR_BEG;
07286             return tOP_ASGN;
07287         }
07288         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07289         pushback(c);
07290         return '|';
07291 
07292       case '+':
07293         c = nextc();
07294         if (IS_AFTER_OPERATOR()) {
07295             lex_state = EXPR_ARG;
07296             if (c == '@') {
07297                 return tUPLUS;
07298             }
07299             pushback(c);
07300             return '+';
07301         }
07302         if (c == '=') {
07303             set_yylval_id('+');
07304             lex_state = EXPR_BEG;
07305             return tOP_ASGN;
07306         }
07307         if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
07308             lex_state = EXPR_BEG;
07309             pushback(c);
07310             if (c != -1 && ISDIGIT(c)) {
07311                 c = '+';
07312                 goto start_num;
07313             }
07314             return tUPLUS;
07315         }
07316         lex_state = EXPR_BEG;
07317         pushback(c);
07318         warn_balanced("+", "unary operator");
07319         return '+';
07320 
07321       case '-':
07322         c = nextc();
07323         if (IS_AFTER_OPERATOR()) {
07324             lex_state = EXPR_ARG;
07325             if (c == '@') {
07326                 return tUMINUS;
07327             }
07328             pushback(c);
07329             return '-';
07330         }
07331         if (c == '=') {
07332             set_yylval_id('-');
07333             lex_state = EXPR_BEG;
07334             return tOP_ASGN;
07335         }
07336         if (c == '>') {
07337             lex_state = EXPR_ENDFN;
07338             return tLAMBDA;
07339         }
07340         if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
07341             lex_state = EXPR_BEG;
07342             pushback(c);
07343             if (c != -1 && ISDIGIT(c)) {
07344                 return tUMINUS_NUM;
07345             }
07346             return tUMINUS;
07347         }
07348         lex_state = EXPR_BEG;
07349         pushback(c);
07350         warn_balanced("-", "unary operator");
07351         return '-';
07352 
07353       case '.':
07354         lex_state = EXPR_BEG;
07355         if ((c = nextc()) == '.') {
07356             if ((c = nextc()) == '.') {
07357                 return tDOT3;
07358             }
07359             pushback(c);
07360             return tDOT2;
07361         }
07362         pushback(c);
07363         if (c != -1 && ISDIGIT(c)) {
07364             yyerror("no .<digit> floating literal anymore; put 0 before dot");
07365         }
07366         lex_state = EXPR_DOT;
07367         return '.';
07368 
07369       start_num:
07370       case '0': case '1': case '2': case '3': case '4':
07371       case '5': case '6': case '7': case '8': case '9':
07372         {
07373             int is_float, seen_point, seen_e, nondigit;
07374 
07375             is_float = seen_point = seen_e = nondigit = 0;
07376             lex_state = EXPR_END;
07377             newtok();
07378             if (c == '-' || c == '+') {
07379                 tokadd(c);
07380                 c = nextc();
07381             }
07382             if (c == '0') {
07383 #define no_digits() do {yyerror("numeric literal without digits"); return 0;} while (0)
07384                 int start = toklen();
07385                 c = nextc();
07386                 if (c == 'x' || c == 'X') {
07387                     /* hexadecimal */
07388                     c = nextc();
07389                     if (c != -1 && ISXDIGIT(c)) {
07390                         do {
07391                             if (c == '_') {
07392                                 if (nondigit) break;
07393                                 nondigit = c;
07394                                 continue;
07395                             }
07396                             if (!ISXDIGIT(c)) break;
07397                             nondigit = 0;
07398                             tokadd(c);
07399                         } while ((c = nextc()) != -1);
07400                     }
07401                     pushback(c);
07402                     tokfix();
07403                     if (toklen() == start) {
07404                         no_digits();
07405                     }
07406                     else if (nondigit) goto trailing_uc;
07407                     set_yylval_literal(rb_cstr_to_inum(tok(), 16, FALSE));
07408                     return tINTEGER;
07409                 }
07410                 if (c == 'b' || c == 'B') {
07411                     /* binary */
07412                     c = nextc();
07413                     if (c == '0' || c == '1') {
07414                         do {
07415                             if (c == '_') {
07416                                 if (nondigit) break;
07417                                 nondigit = c;
07418                                 continue;
07419                             }
07420                             if (c != '0' && c != '1') break;
07421                             nondigit = 0;
07422                             tokadd(c);
07423                         } while ((c = nextc()) != -1);
07424                     }
07425                     pushback(c);
07426                     tokfix();
07427                     if (toklen() == start) {
07428                         no_digits();
07429                     }
07430                     else if (nondigit) goto trailing_uc;
07431                     set_yylval_literal(rb_cstr_to_inum(tok(), 2, FALSE));
07432                     return tINTEGER;
07433                 }
07434                 if (c == 'd' || c == 'D') {
07435                     /* decimal */
07436                     c = nextc();
07437                     if (c != -1 && ISDIGIT(c)) {
07438                         do {
07439                             if (c == '_') {
07440                                 if (nondigit) break;
07441                                 nondigit = c;
07442                                 continue;
07443                             }
07444                             if (!ISDIGIT(c)) break;
07445                             nondigit = 0;
07446                             tokadd(c);
07447                         } while ((c = nextc()) != -1);
07448                     }
07449                     pushback(c);
07450                     tokfix();
07451                     if (toklen() == start) {
07452                         no_digits();
07453                     }
07454                     else if (nondigit) goto trailing_uc;
07455                     set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
07456                     return tINTEGER;
07457                 }
07458                 if (c == '_') {
07459                     /* 0_0 */
07460                     goto octal_number;
07461                 }
07462                 if (c == 'o' || c == 'O') {
07463                     /* prefixed octal */
07464                     c = nextc();
07465                     if (c == -1 || c == '_' || !ISDIGIT(c)) {
07466                         no_digits();
07467                     }
07468                 }
07469                 if (c >= '0' && c <= '7') {
07470                     /* octal */
07471                   octal_number:
07472                     do {
07473                         if (c == '_') {
07474                             if (nondigit) break;
07475                             nondigit = c;
07476                             continue;
07477                         }
07478                         if (c < '0' || c > '9') break;
07479                         if (c > '7') goto invalid_octal;
07480                         nondigit = 0;
07481                         tokadd(c);
07482                     } while ((c = nextc()) != -1);
07483                     if (toklen() > start) {
07484                         pushback(c);
07485                         tokfix();
07486                         if (nondigit) goto trailing_uc;
07487                         set_yylval_literal(rb_cstr_to_inum(tok(), 8, FALSE));
07488                         return tINTEGER;
07489                     }
07490                     if (nondigit) {
07491                         pushback(c);
07492                         goto trailing_uc;
07493                     }
07494                 }
07495                 if (c > '7' && c <= '9') {
07496                   invalid_octal:
07497                     yyerror("Invalid octal digit");
07498                 }
07499                 else if (c == '.' || c == 'e' || c == 'E') {
07500                     tokadd('0');
07501                 }
07502                 else {
07503                     pushback(c);
07504                     set_yylval_literal(INT2FIX(0));
07505                     return tINTEGER;
07506                 }
07507             }
07508 
07509             for (;;) {
07510                 switch (c) {
07511                   case '0': case '1': case '2': case '3': case '4':
07512                   case '5': case '6': case '7': case '8': case '9':
07513                     nondigit = 0;
07514                     tokadd(c);
07515                     break;
07516 
07517                   case '.':
07518                     if (nondigit) goto trailing_uc;
07519                     if (seen_point || seen_e) {
07520                         goto decode_num;
07521                     }
07522                     else {
07523                         int c0 = nextc();
07524                         if (c0 == -1 || !ISDIGIT(c0)) {
07525                             pushback(c0);
07526                             goto decode_num;
07527                         }
07528                         c = c0;
07529                     }
07530                     tokadd('.');
07531                     tokadd(c);
07532                     is_float++;
07533                     seen_point++;
07534                     nondigit = 0;
07535                     break;
07536 
07537                   case 'e':
07538                   case 'E':
07539                     if (nondigit) {
07540                         pushback(c);
07541                         c = nondigit;
07542                         goto decode_num;
07543                     }
07544                     if (seen_e) {
07545                         goto decode_num;
07546                     }
07547                     tokadd(c);
07548                     seen_e++;
07549                     is_float++;
07550                     nondigit = c;
07551                     c = nextc();
07552                     if (c != '-' && c != '+') continue;
07553                     tokadd(c);
07554                     nondigit = c;
07555                     break;
07556 
07557                   case '_':     /* `_' in number just ignored */
07558                     if (nondigit) goto decode_num;
07559                     nondigit = c;
07560                     break;
07561 
07562                   default:
07563                     goto decode_num;
07564                 }
07565                 c = nextc();
07566             }
07567 
07568           decode_num:
07569             pushback(c);
07570             if (nondigit) {
07571                 char tmp[30];
07572               trailing_uc:
07573                 snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
07574                 yyerror(tmp);
07575             }
07576             tokfix();
07577             if (is_float) {
07578                 double d = strtod(tok(), 0);
07579                 if (errno == ERANGE) {
07580                     rb_warningS("Float %s out of range", tok());
07581                     errno = 0;
07582                 }
07583                 set_yylval_literal(DBL2NUM(d));
07584                 return tFLOAT;
07585             }
07586             set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
07587             return tINTEGER;
07588         }
07589 
07590       case ')':
07591       case ']':
07592         paren_nest--;
07593       case '}':
07594         COND_LEXPOP();
07595         CMDARG_LEXPOP();
07596         if (c == ')')
07597             lex_state = EXPR_ENDFN;
07598         else
07599             lex_state = EXPR_ENDARG;
07600         if (c == '}') {
07601             if (!brace_nest--) c = tSTRING_DEND;
07602         }
07603         return c;
07604 
07605       case ':':
07606         c = nextc();
07607         if (c == ':') {
07608             if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
07609                 lex_state = EXPR_BEG;
07610                 return tCOLON3;
07611             }
07612             lex_state = EXPR_DOT;
07613             return tCOLON2;
07614         }
07615         if (IS_END() || ISSPACE(c)) {
07616             pushback(c);
07617             warn_balanced(":", "symbol literal");
07618             lex_state = EXPR_BEG;
07619             return ':';
07620         }
07621         switch (c) {
07622           case '\'':
07623             lex_strterm = NEW_STRTERM(str_ssym, c, 0);
07624             break;
07625           case '"':
07626             lex_strterm = NEW_STRTERM(str_dsym, c, 0);
07627             break;
07628           default:
07629             pushback(c);
07630             break;
07631         }
07632         lex_state = EXPR_FNAME;
07633         return tSYMBEG;
07634 
07635       case '/':
07636         if (IS_lex_state(EXPR_BEG_ANY)) {
07637             lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
07638             return tREGEXP_BEG;
07639         }
07640         if ((c = nextc()) == '=') {
07641             set_yylval_id('/');
07642             lex_state = EXPR_BEG;
07643             return tOP_ASGN;
07644         }
07645         pushback(c);
07646         if (IS_SPCARG(c)) {
07647             (void)arg_ambiguous();
07648             lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
07649             return tREGEXP_BEG;
07650         }
07651         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07652         warn_balanced("/", "regexp literal");
07653         return '/';
07654 
07655       case '^':
07656         if ((c = nextc()) == '=') {
07657             set_yylval_id('^');
07658             lex_state = EXPR_BEG;
07659             return tOP_ASGN;
07660         }
07661         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07662         pushback(c);
07663         return '^';
07664 
07665       case ';':
07666         lex_state = EXPR_BEG;
07667         command_start = TRUE;
07668         return ';';
07669 
07670       case ',':
07671         lex_state = EXPR_BEG;
07672         return ',';
07673 
07674       case '~':
07675         if (IS_AFTER_OPERATOR()) {
07676             if ((c = nextc()) != '@') {
07677                 pushback(c);
07678             }
07679             lex_state = EXPR_ARG;
07680         }
07681         else {
07682             lex_state = EXPR_BEG;
07683         }
07684         return '~';
07685 
07686       case '(':
07687         if (IS_BEG()) {
07688             c = tLPAREN;
07689         }
07690         else if (IS_SPCARG(-1)) {
07691             c = tLPAREN_ARG;
07692         }
07693         paren_nest++;
07694         COND_PUSH(0);
07695         CMDARG_PUSH(0);
07696         lex_state = EXPR_BEG;
07697         return c;
07698 
07699       case '[':
07700         paren_nest++;
07701         if (IS_AFTER_OPERATOR()) {
07702             lex_state = EXPR_ARG;
07703             if ((c = nextc()) == ']') {
07704                 if ((c = nextc()) == '=') {
07705                     return tASET;
07706                 }
07707                 pushback(c);
07708                 return tAREF;
07709             }
07710             pushback(c);
07711             return '[';
07712         }
07713         else if (IS_BEG()) {
07714             c = tLBRACK;
07715         }
07716         else if (IS_ARG() && space_seen) {
07717             c = tLBRACK;
07718         }
07719         lex_state = EXPR_BEG;
07720         COND_PUSH(0);
07721         CMDARG_PUSH(0);
07722         return c;
07723 
07724       case '{':
07725         ++brace_nest;
07726         if (lpar_beg && lpar_beg == paren_nest) {
07727             lex_state = EXPR_BEG;
07728             lpar_beg = 0;
07729             --paren_nest;
07730             COND_PUSH(0);
07731             CMDARG_PUSH(0);
07732             return tLAMBEG;
07733         }
07734         if (IS_ARG() || IS_lex_state(EXPR_END | EXPR_ENDFN))
07735             c = '{';          /* block (primary) */
07736         else if (IS_lex_state(EXPR_ENDARG))
07737             c = tLBRACE_ARG;  /* block (expr) */
07738         else
07739             c = tLBRACE;      /* hash */
07740         COND_PUSH(0);
07741         CMDARG_PUSH(0);
07742         lex_state = EXPR_BEG;
07743         if (c != tLBRACE) command_start = TRUE;
07744         return c;
07745 
07746       case '\\':
07747         c = nextc();
07748         if (c == '\n') {
07749             space_seen = 1;
07750 #ifdef RIPPER
07751             ripper_dispatch_scan_event(parser, tSP);
07752 #endif
07753             goto retry; /* skip \\n */
07754         }
07755         pushback(c);
07756         return '\\';
07757 
07758       case '%':
07759         if (IS_lex_state(EXPR_BEG_ANY)) {
07760             int term;
07761             int paren;
07762 
07763             c = nextc();
07764           quotation:
07765             if (c == -1 || !ISALNUM(c)) {
07766                 term = c;
07767                 c = 'Q';
07768             }
07769             else {
07770                 term = nextc();
07771                 if (rb_enc_isalnum(term, current_enc) || !parser_isascii()) {
07772                     yyerror("unknown type of %string");
07773                     return 0;
07774                 }
07775             }
07776             if (c == -1 || term == -1) {
07777                 compile_error(PARSER_ARG "unterminated quoted string meets end of file");
07778                 return 0;
07779             }
07780             paren = term;
07781             if (term == '(') term = ')';
07782             else if (term == '[') term = ']';
07783             else if (term == '{') term = '}';
07784             else if (term == '<') term = '>';
07785             else paren = 0;
07786 
07787             switch (c) {
07788               case 'Q':
07789                 lex_strterm = NEW_STRTERM(str_dquote, term, paren);
07790                 return tSTRING_BEG;
07791 
07792               case 'q':
07793                 lex_strterm = NEW_STRTERM(str_squote, term, paren);
07794                 return tSTRING_BEG;
07795 
07796               case 'W':
07797                 lex_strterm = NEW_STRTERM(str_dword, term, paren);
07798                 do {c = nextc();} while (ISSPACE(c));
07799                 pushback(c);
07800                 return tWORDS_BEG;
07801 
07802               case 'w':
07803                 lex_strterm = NEW_STRTERM(str_sword, term, paren);
07804                 do {c = nextc();} while (ISSPACE(c));
07805                 pushback(c);
07806                 return tQWORDS_BEG;
07807 
07808               case 'I':
07809                 lex_strterm = NEW_STRTERM(str_dword, term, paren);
07810                 do {c = nextc();} while (ISSPACE(c));
07811                 pushback(c);
07812                 return tSYMBOLS_BEG;
07813 
07814               case 'i':
07815                 lex_strterm = NEW_STRTERM(str_sword, term, paren);
07816                 do {c = nextc();} while (ISSPACE(c));
07817                 pushback(c);
07818                 return tQSYMBOLS_BEG;
07819 
07820               case 'x':
07821                 lex_strterm = NEW_STRTERM(str_xquote, term, paren);
07822                 return tXSTRING_BEG;
07823 
07824               case 'r':
07825                 lex_strterm = NEW_STRTERM(str_regexp, term, paren);
07826                 return tREGEXP_BEG;
07827 
07828               case 's':
07829                 lex_strterm = NEW_STRTERM(str_ssym, term, paren);
07830                 lex_state = EXPR_FNAME;
07831                 return tSYMBEG;
07832 
07833               default:
07834                 yyerror("unknown type of %string");
07835                 return 0;
07836             }
07837         }
07838         if ((c = nextc()) == '=') {
07839             set_yylval_id('%');
07840             lex_state = EXPR_BEG;
07841             return tOP_ASGN;
07842         }
07843         if (IS_SPCARG(c)) {
07844             goto quotation;
07845         }
07846         lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07847         pushback(c);
07848         warn_balanced("%%", "string literal");
07849         return '%';
07850 
07851       case '$':
07852         lex_state = EXPR_END;
07853         newtok();
07854         c = nextc();
07855         switch (c) {
07856           case '_':             /* $_: last read line string */
07857             c = nextc();
07858             if (parser_is_identchar()) {
07859                 tokadd('$');
07860                 tokadd('_');
07861                 break;
07862             }
07863             pushback(c);
07864             c = '_';
07865             /* fall through */
07866           case '~':             /* $~: match-data */
07867           case '*':             /* $*: argv */
07868           case '$':             /* $$: pid */
07869           case '?':             /* $?: last status */
07870           case '!':             /* $!: error string */
07871           case '@':             /* $@: error position */
07872           case '/':             /* $/: input record separator */
07873           case '\\':            /* $\: output record separator */
07874           case ';':             /* $;: field separator */
07875           case ',':             /* $,: output field separator */
07876           case '.':             /* $.: last read line number */
07877           case '=':             /* $=: ignorecase */
07878           case ':':             /* $:: load path */
07879           case '<':             /* $<: reading filename */
07880           case '>':             /* $>: default output handle */
07881           case '\"':            /* $": already loaded files */
07882             tokadd('$');
07883             tokadd(c);
07884             tokfix();
07885             set_yylval_name(rb_intern(tok()));
07886             return tGVAR;
07887 
07888           case '-':
07889             tokadd('$');
07890             tokadd(c);
07891             c = nextc();
07892             if (parser_is_identchar()) {
07893                 if (tokadd_mbchar(c) == -1) return 0;
07894             }
07895             else {
07896                 pushback(c);
07897             }
07898           gvar:
07899             tokfix();
07900             set_yylval_name(rb_intern(tok()));
07901             return tGVAR;
07902 
07903           case '&':             /* $&: last match */
07904           case '`':             /* $`: string before last match */
07905           case '\'':            /* $': string after last match */
07906           case '+':             /* $+: string matches last paren. */
07907             if (IS_lex_state_for(last_state, EXPR_FNAME)) {
07908                 tokadd('$');
07909                 tokadd(c);
07910                 goto gvar;
07911             }
07912             set_yylval_node(NEW_BACK_REF(c));
07913             return tBACK_REF;
07914 
07915           case '1': case '2': case '3':
07916           case '4': case '5': case '6':
07917           case '7': case '8': case '9':
07918             tokadd('$');
07919             do {
07920                 tokadd(c);
07921                 c = nextc();
07922             } while (c != -1 && ISDIGIT(c));
07923             pushback(c);
07924             if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
07925             tokfix();
07926             set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
07927             return tNTH_REF;
07928 
07929           default:
07930             if (!parser_is_identchar()) {
07931                 pushback(c);
07932                 compile_error(PARSER_ARG "`$%c' is not allowed as a global variable name", c);
07933                 return 0;
07934             }
07935           case '0':
07936             tokadd('$');
07937         }
07938         break;
07939 
07940       case '@':
07941         c = nextc();
07942         newtok();
07943         tokadd('@');
07944         if (c == '@') {
07945             tokadd('@');
07946             c = nextc();
07947         }
07948         if (c != -1 && (ISDIGIT(c) || !parser_is_identchar())) {
07949             pushback(c);
07950             if (tokidx == 1) {
07951                 compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
07952             }
07953             else {
07954                 compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
07955             }
07956             return 0;
07957         }
07958         break;
07959 
07960       case '_':
07961         if (was_bol() && whole_match_p("__END__", 7, 0)) {
07962             ruby__end__seen = 1;
07963             parser->eofp = Qtrue;
07964 #ifndef RIPPER
07965             return -1;
07966 #else
07967             lex_goto_eol(parser);
07968             ripper_dispatch_scan_event(parser, k__END__);
07969             return 0;
07970 #endif
07971         }
07972         newtok();
07973         break;
07974 
07975       default:
07976         if (!parser_is_identchar()) {
07977             rb_compile_error(PARSER_ARG  "Invalid char `\\x%02X' in expression", c);
07978             goto retry;
07979         }
07980 
07981         newtok();
07982         break;
07983     }
07984 
07985     mb = ENC_CODERANGE_7BIT;
07986     do {
07987         if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
07988         if (tokadd_mbchar(c) == -1) return 0;
07989         c = nextc();
07990     } while (parser_is_identchar());
07991     switch (tok()[0]) {
07992       case '@': case '$':
07993         pushback(c);
07994         break;
07995       default:
07996         if ((c == '!' || c == '?') && !peek('=')) {
07997             tokadd(c);
07998         }
07999         else {
08000             pushback(c);
08001         }
08002     }
08003     tokfix();
08004 
08005     {
08006         int result = 0;
08007 
08008         last_state = lex_state;
08009         switch (tok()[0]) {
08010           case '$':
08011             lex_state = EXPR_END;
08012             result = tGVAR;
08013             break;
08014           case '@':
08015             lex_state = EXPR_END;
08016             if (tok()[1] == '@')
08017                 result = tCVAR;
08018             else
08019                 result = tIVAR;
08020             break;
08021 
08022           default:
08023             if (toklast() == '!' || toklast() == '?') {
08024                 result = tFID;
08025             }
08026             else {
08027                 if (IS_lex_state(EXPR_FNAME)) {
08028                     if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
08029                         (!peek('=') || (peek_n('>', 1)))) {
08030                         result = tIDENTIFIER;
08031                         tokadd(c);
08032                         tokfix();
08033                     }
08034                     else {
08035                         pushback(c);
08036                     }
08037                 }
08038                 if (result == 0 && ISUPPER(tok()[0])) {
08039                     result = tCONSTANT;
08040                 }
08041                 else {
08042                     result = tIDENTIFIER;
08043                 }
08044             }
08045 
08046             if (IS_LABEL_POSSIBLE()) {
08047                 if (IS_LABEL_SUFFIX(0)) {
08048                     lex_state = EXPR_BEG;
08049                     nextc();
08050                     set_yylval_name(TOK_INTERN(!ENC_SINGLE(mb)));
08051                     return tLABEL;
08052                 }
08053             }
08054             if (mb == ENC_CODERANGE_7BIT && !IS_lex_state(EXPR_DOT)) {
08055                 const struct kwtable *kw;
08056 
08057                 /* See if it is a reserved word.  */
08058                 kw = rb_reserved_word(tok(), toklen());
08059                 if (kw) {
08060                     enum lex_state_e state = lex_state;
08061                     lex_state = kw->state;
08062                     if (state == EXPR_FNAME) {
08063                         set_yylval_name(rb_intern(kw->name));
08064                         return kw->id[0];
08065                     }
08066                     if (lex_state == EXPR_BEG) {
08067                         command_start = TRUE;
08068                     }
08069                     if (kw->id[0] == keyword_do) {
08070                         if (lpar_beg && lpar_beg == paren_nest) {
08071                             lpar_beg = 0;
08072                             --paren_nest;
08073                             return keyword_do_LAMBDA;
08074                         }
08075                         if (COND_P()) return keyword_do_cond;
08076                         if (CMDARG_P() && state != EXPR_CMDARG)
08077                             return keyword_do_block;
08078                         if (state & (EXPR_BEG | EXPR_ENDARG))
08079                             return keyword_do_block;
08080                         return keyword_do;
08081                     }
08082                     if (state & (EXPR_BEG | EXPR_VALUE))
08083                         return kw->id[0];
08084                     else {
08085                         if (kw->id[0] != kw->id[1])
08086                             lex_state = EXPR_BEG;
08087                         return kw->id[1];
08088                     }
08089                 }
08090             }
08091 
08092             if (IS_lex_state(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT)) {
08093                 if (cmd_state) {
08094                     lex_state = EXPR_CMDARG;
08095                 }
08096                 else {
08097                     lex_state = EXPR_ARG;
08098                 }
08099             }
08100             else if (lex_state == EXPR_FNAME) {
08101                 lex_state = EXPR_ENDFN;
08102             }
08103             else {
08104                 lex_state = EXPR_END;
08105             }
08106         }
08107         {
08108             ID ident = TOK_INTERN(!ENC_SINGLE(mb));
08109 
08110             set_yylval_name(ident);
08111             if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
08112                 is_local_id(ident) && lvar_defined(ident)) {
08113                 lex_state = EXPR_END;
08114             }
08115         }
08116         return result;
08117     }
08118 }
08119 
08120 #if YYPURE
08121 static int
08122 yylex(void *lval, void *p)
08123 #else
08124 yylex(void *p)
08125 #endif
08126 {
08127     struct parser_params *parser = (struct parser_params*)p;
08128     int t;
08129 
08130 #if YYPURE
08131     parser->parser_yylval = lval;
08132     parser->parser_yylval->val = Qundef;
08133 #endif
08134     t = parser_yylex(parser);
08135 #ifdef RIPPER
08136     if (!NIL_P(parser->delayed)) {
08137         ripper_dispatch_delayed_token(parser, t);
08138         return t;
08139     }
08140     if (t != 0)
08141         ripper_dispatch_scan_event(parser, t);
08142 #endif
08143 
08144     return t;
08145 }
08146 
08147 #ifndef RIPPER
08148 static NODE*
08149 node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
08150 {
08151     NODE *n = (rb_node_newnode)(type, a0, a1, a2);
08152     nd_set_line(n, ruby_sourceline);
08153     return n;
08154 }
08155 
08156 static enum node_type
08157 nodetype(NODE *node)                    /* for debug */
08158 {
08159     return (enum node_type)nd_type(node);
08160 }
08161 
08162 static int
08163 nodeline(NODE *node)
08164 {
08165     return nd_line(node);
08166 }
08167 
08168 static NODE*
08169 newline_node(NODE *node)
08170 {
08171     if (node) {
08172         node = remove_begin(node);
08173         node->flags |= NODE_FL_NEWLINE;
08174     }
08175     return node;
08176 }
08177 
08178 static void
08179 fixpos(NODE *node, NODE *orig)
08180 {
08181     if (!node) return;
08182     if (!orig) return;
08183     if (orig == (NODE*)1) return;
08184     nd_set_line(node, nd_line(orig));
08185 }
08186 
08187 static void
08188 parser_warning(struct parser_params *parser, NODE *node, const char *mesg)
08189 {
08190     rb_compile_warning(ruby_sourcefile, nd_line(node), "%s", mesg);
08191 }
08192 #define parser_warning(node, mesg) parser_warning(parser, (node), (mesg))
08193 
08194 static void
08195 parser_warn(struct parser_params *parser, NODE *node, const char *mesg)
08196 {
08197     rb_compile_warn(ruby_sourcefile, nd_line(node), "%s", mesg);
08198 }
08199 #define parser_warn(node, mesg) parser_warn(parser, (node), (mesg))
08200 
08201 static NODE*
08202 block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
08203 {
08204     NODE *end, *h = head, *nd;
08205 
08206     if (tail == 0) return head;
08207 
08208     if (h == 0) return tail;
08209     switch (nd_type(h)) {
08210       case NODE_LIT:
08211       case NODE_STR:
08212       case NODE_SELF:
08213       case NODE_TRUE:
08214       case NODE_FALSE:
08215       case NODE_NIL:
08216         parser_warning(h, "unused literal ignored");
08217         return tail;
08218       default:
08219         h = end = NEW_BLOCK(head);
08220         end->nd_end = end;
08221         fixpos(end, head);
08222         head = end;
08223         break;
08224       case NODE_BLOCK:
08225         end = h->nd_end;
08226         break;
08227     }
08228 
08229     nd = end->nd_head;
08230     switch (nd_type(nd)) {
08231       case NODE_RETURN:
08232       case NODE_BREAK:
08233       case NODE_NEXT:
08234       case NODE_REDO:
08235       case NODE_RETRY:
08236         if (RTEST(ruby_verbose)) {
08237             parser_warning(tail, "statement not reached");
08238         }
08239         break;
08240 
08241       default:
08242         break;
08243     }
08244 
08245     if (nd_type(tail) != NODE_BLOCK) {
08246         tail = NEW_BLOCK(tail);
08247         tail->nd_end = tail;
08248     }
08249     end->nd_next = tail;
08250     h->nd_end = tail->nd_end;
08251     return head;
08252 }
08253 
08254 /* append item to the list */
08255 static NODE*
08256 list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
08257 {
08258     NODE *last;
08259 
08260     if (list == 0) return NEW_LIST(item);
08261     if (list->nd_next) {
08262         last = list->nd_next->nd_end;
08263     }
08264     else {
08265         last = list;
08266     }
08267 
08268     list->nd_alen += 1;
08269     last->nd_next = NEW_LIST(item);
08270     list->nd_next->nd_end = last->nd_next;
08271     return list;
08272 }
08273 
08274 /* concat two lists */
08275 static NODE*
08276 list_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
08277 {
08278     NODE *last;
08279 
08280     if (head->nd_next) {
08281         last = head->nd_next->nd_end;
08282     }
08283     else {
08284         last = head;
08285     }
08286 
08287     head->nd_alen += tail->nd_alen;
08288     last->nd_next = tail;
08289     if (tail->nd_next) {
08290         head->nd_next->nd_end = tail->nd_next->nd_end;
08291     }
08292     else {
08293         head->nd_next->nd_end = tail;
08294     }
08295 
08296     return head;
08297 }
08298 
08299 static int
08300 literal_concat0(struct parser_params *parser, VALUE head, VALUE tail)
08301 {
08302     if (NIL_P(tail)) return 1;
08303     if (!rb_enc_compatible(head, tail)) {
08304         compile_error(PARSER_ARG "string literal encodings differ (%s / %s)",
08305                       rb_enc_name(rb_enc_get(head)),
08306                       rb_enc_name(rb_enc_get(tail)));
08307         rb_str_resize(head, 0);
08308         rb_str_resize(tail, 0);
08309         return 0;
08310     }
08311     rb_str_buf_append(head, tail);
08312     return 1;
08313 }
08314 
08315 /* concat two string literals */
08316 static NODE *
08317 literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
08318 {
08319     enum node_type htype;
08320     NODE *headlast;
08321     VALUE lit;
08322 
08323     if (!head) return tail;
08324     if (!tail) return head;
08325 
08326     htype = nd_type(head);
08327     if (htype == NODE_EVSTR) {
08328         NODE *node = NEW_DSTR(Qnil);
08329         head = list_append(node, head);
08330         htype = NODE_DSTR;
08331     }
08332     switch (nd_type(tail)) {
08333       case NODE_STR:
08334         if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
08335             nd_type(headlast) == NODE_STR) {
08336             htype = NODE_STR;
08337             lit = headlast->nd_lit;
08338         }
08339         else {
08340             lit = head->nd_lit;
08341         }
08342         if (htype == NODE_STR) {
08343             if (!literal_concat0(parser, lit, tail->nd_lit)) {
08344               error:
08345                 rb_gc_force_recycle((VALUE)head);
08346                 rb_gc_force_recycle((VALUE)tail);
08347                 return 0;
08348             }
08349             rb_gc_force_recycle((VALUE)tail);
08350         }
08351         else {
08352             list_append(head, tail);
08353         }
08354         break;
08355 
08356       case NODE_DSTR:
08357         if (htype == NODE_STR) {
08358             if (!literal_concat0(parser, head->nd_lit, tail->nd_lit))
08359                 goto error;
08360             tail->nd_lit = head->nd_lit;
08361             rb_gc_force_recycle((VALUE)head);
08362             head = tail;
08363         }
08364         else if (NIL_P(tail->nd_lit)) {
08365           append:
08366             head->nd_alen += tail->nd_alen - 1;
08367             head->nd_next->nd_end->nd_next = tail->nd_next;
08368             head->nd_next->nd_end = tail->nd_next->nd_end;
08369             rb_gc_force_recycle((VALUE)tail);
08370         }
08371         else if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
08372                  nd_type(headlast) == NODE_STR) {
08373             lit = headlast->nd_lit;
08374             if (!literal_concat0(parser, lit, tail->nd_lit))
08375                 goto error;
08376             tail->nd_lit = Qnil;
08377             goto append;
08378         }
08379         else {
08380             nd_set_type(tail, NODE_ARRAY);
08381             tail->nd_head = NEW_STR(tail->nd_lit);
08382             list_concat(head, tail);
08383         }
08384         break;
08385 
08386       case NODE_EVSTR:
08387         if (htype == NODE_STR) {
08388             nd_set_type(head, NODE_DSTR);
08389             head->nd_alen = 1;
08390         }
08391         list_append(head, tail);
08392         break;
08393     }
08394     return head;
08395 }
08396 
08397 static NODE *
08398 evstr2dstr_gen(struct parser_params *parser, NODE *node)
08399 {
08400     if (nd_type(node) == NODE_EVSTR) {
08401         node = list_append(NEW_DSTR(Qnil), node);
08402     }
08403     return node;
08404 }
08405 
08406 static NODE *
08407 new_evstr_gen(struct parser_params *parser, NODE *node)
08408 {
08409     NODE *head = node;
08410 
08411     if (node) {
08412         switch (nd_type(node)) {
08413           case NODE_STR: case NODE_DSTR: case NODE_EVSTR:
08414             return node;
08415         }
08416     }
08417     return NEW_EVSTR(head);
08418 }
08419 
08420 static NODE *
08421 call_bin_op_gen(struct parser_params *parser, NODE *recv, ID id, NODE *arg1)
08422 {
08423     value_expr(recv);
08424     value_expr(arg1);
08425     return NEW_CALL(recv, id, NEW_LIST(arg1));
08426 }
08427 
08428 static NODE *
08429 call_uni_op_gen(struct parser_params *parser, NODE *recv, ID id)
08430 {
08431     value_expr(recv);
08432     return NEW_CALL(recv, id, 0);
08433 }
08434 
08435 static NODE*
08436 match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
08437 {
08438     value_expr(node1);
08439     value_expr(node2);
08440     if (node1) {
08441         switch (nd_type(node1)) {
08442           case NODE_DREGX:
08443           case NODE_DREGX_ONCE:
08444             return NEW_MATCH2(node1, node2);
08445 
08446           case NODE_LIT:
08447             if (RB_TYPE_P(node1->nd_lit, T_REGEXP)) {
08448                 return NEW_MATCH2(node1, node2);
08449             }
08450         }
08451     }
08452 
08453     if (node2) {
08454         switch (nd_type(node2)) {
08455           case NODE_DREGX:
08456           case NODE_DREGX_ONCE:
08457             return NEW_MATCH3(node2, node1);
08458 
08459           case NODE_LIT:
08460             if (RB_TYPE_P(node2->nd_lit, T_REGEXP)) {
08461                 return NEW_MATCH3(node2, node1);
08462             }
08463         }
08464     }
08465 
08466     return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
08467 }
08468 
08469 static NODE*
08470 gettable_gen(struct parser_params *parser, ID id)
08471 {
08472     switch (id) {
08473       case keyword_self:
08474         return NEW_SELF();
08475       case keyword_nil:
08476         return NEW_NIL();
08477       case keyword_true:
08478         return NEW_TRUE();
08479       case keyword_false:
08480         return NEW_FALSE();
08481       case keyword__FILE__:
08482         return NEW_STR(rb_str_dup(ruby_sourcefile_string));
08483       case keyword__LINE__:
08484         return NEW_LIT(INT2FIX(tokline));
08485       case keyword__ENCODING__:
08486         return NEW_LIT(rb_enc_from_encoding(current_enc));
08487     }
08488     switch (id_type(id)) {
08489       case ID_LOCAL:
08490         if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id);
08491         if (local_id(id)) return NEW_LVAR(id);
08492         /* method call without arguments */
08493         return NEW_VCALL(id);
08494       case ID_GLOBAL:
08495         return NEW_GVAR(id);
08496       case ID_INSTANCE:
08497         return NEW_IVAR(id);
08498       case ID_CONST:
08499         return NEW_CONST(id);
08500       case ID_CLASS:
08501         return NEW_CVAR(id);
08502     }
08503     compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
08504     return 0;
08505 }
08506 #else  /* !RIPPER */
08507 static int
08508 id_is_var_gen(struct parser_params *parser, ID id)
08509 {
08510     if (is_notop_id(id)) {
08511         switch (id & ID_SCOPE_MASK) {
08512           case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
08513             return 1;
08514           case ID_LOCAL:
08515             if (dyna_in_block() && dvar_defined(id)) return 1;
08516             if (local_id(id)) return 1;
08517             /* method call without arguments */
08518             return 0;
08519         }
08520     }
08521     compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
08522     return 0;
08523 }
08524 #endif /* !RIPPER */
08525 
08526 #if PARSER_DEBUG
08527 static const char *
08528 lex_state_name(enum lex_state_e state)
08529 {
08530     static const char names[][12] = {
08531         "EXPR_BEG",    "EXPR_END",    "EXPR_ENDARG", "EXPR_ENDFN",  "EXPR_ARG",
08532         "EXPR_CMDARG", "EXPR_MID",    "EXPR_FNAME",  "EXPR_DOT",    "EXPR_CLASS",
08533         "EXPR_VALUE",
08534     };
08535 
08536     if ((unsigned)state & ~(~0u << EXPR_MAX_STATE))
08537         return names[ffs(state)];
08538     return NULL;
08539 }
08540 #endif
08541 
08542 #ifdef RIPPER
08543 static VALUE
08544 assignable_gen(struct parser_params *parser, VALUE lhs)
08545 #else
08546 static NODE*
08547 assignable_gen(struct parser_params *parser, ID id, NODE *val)
08548 #endif
08549 {
08550 #ifdef RIPPER
08551     ID id = get_id(lhs);
08552 # define assignable_result(x) get_value(lhs)
08553 # define parser_yyerror(parser, x) dispatch1(assign_error, lhs)
08554 #else
08555 # define assignable_result(x) (x)
08556 #endif
08557     if (!id) return assignable_result(0);
08558     switch (id) {
08559       case keyword_self:
08560         yyerror("Can't change the value of self");
08561         goto error;
08562       case keyword_nil:
08563         yyerror("Can't assign to nil");
08564         goto error;
08565       case keyword_true:
08566         yyerror("Can't assign to true");
08567         goto error;
08568       case keyword_false:
08569         yyerror("Can't assign to false");
08570         goto error;
08571       case keyword__FILE__:
08572         yyerror("Can't assign to __FILE__");
08573         goto error;
08574       case keyword__LINE__:
08575         yyerror("Can't assign to __LINE__");
08576         goto error;
08577       case keyword__ENCODING__:
08578         yyerror("Can't assign to __ENCODING__");
08579         goto error;
08580     }
08581     switch (id_type(id)) {
08582       case ID_LOCAL:
08583         if (dyna_in_block()) {
08584             if (dvar_curr(id)) {
08585                 return assignable_result(NEW_DASGN_CURR(id, val));
08586             }
08587             else if (dvar_defined(id)) {
08588                 return assignable_result(NEW_DASGN(id, val));
08589             }
08590             else if (local_id(id)) {
08591                 return assignable_result(NEW_LASGN(id, val));
08592             }
08593             else {
08594                 dyna_var(id);
08595                 return assignable_result(NEW_DASGN_CURR(id, val));
08596             }
08597         }
08598         else {
08599             if (!local_id(id)) {
08600                 local_var(id);
08601             }
08602             return assignable_result(NEW_LASGN(id, val));
08603         }
08604         break;
08605       case ID_GLOBAL:
08606         return assignable_result(NEW_GASGN(id, val));
08607       case ID_INSTANCE:
08608         return assignable_result(NEW_IASGN(id, val));
08609       case ID_CONST:
08610         if (!in_def && !in_single)
08611             return assignable_result(NEW_CDECL(id, val, 0));
08612         yyerror("dynamic constant assignment");
08613         break;
08614       case ID_CLASS:
08615         return assignable_result(NEW_CVASGN(id, val));
08616       default:
08617         compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
08618     }
08619   error:
08620     return assignable_result(0);
08621 #undef assignable_result
08622 #undef parser_yyerror
08623 }
08624 
08625 static int
08626 is_private_local_id(ID name)
08627 {
08628     VALUE s;
08629     if (name == idUScore) return 1;
08630     if (!is_local_id(name)) return 0;
08631     s = rb_id2str(name);
08632     if (!s) return 0;
08633     return RSTRING_PTR(s)[0] == '_';
08634 }
08635 
08636 #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
08637 
08638 static ID
08639 shadowing_lvar_gen(struct parser_params *parser, ID name)
08640 {
08641     if (is_private_local_id(name)) return name;
08642     if (dyna_in_block()) {
08643         if (dvar_curr(name)) {
08644             yyerror("duplicated argument name");
08645         }
08646         else if (dvar_defined_get(name) || local_id(name)) {
08647             rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
08648             vtable_add(lvtbl->vars, name);
08649             if (lvtbl->used) {
08650                 vtable_add(lvtbl->used, (ID)ruby_sourceline | LVAR_USED);
08651             }
08652         }
08653     }
08654     else {
08655         if (local_id(name)) {
08656             yyerror("duplicated argument name");
08657         }
08658     }
08659     return name;
08660 }
08661 
08662 static void
08663 new_bv_gen(struct parser_params *parser, ID name)
08664 {
08665     if (!name) return;
08666     if (!is_local_id(name)) {
08667         compile_error(PARSER_ARG "invalid local variable - %s",
08668                       rb_id2name(name));
08669         return;
08670     }
08671     shadowing_lvar(name);
08672     dyna_var(name);
08673 }
08674 
08675 #ifndef RIPPER
08676 static NODE *
08677 aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
08678 {
08679     if (recv && nd_type(recv) == NODE_SELF)
08680         recv = (NODE *)1;
08681     return NEW_ATTRASGN(recv, tASET, idx);
08682 }
08683 
08684 static void
08685 block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
08686 {
08687     if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
08688         compile_error(PARSER_ARG "both block arg and actual block given");
08689     }
08690 }
08691 
08692 static const char id_type_names[][9] = {
08693     "LOCAL",
08694     "INSTANCE",
08695     "",                         /* INSTANCE2 */
08696     "GLOBAL",
08697     "ATTRSET",
08698     "CONST",
08699     "CLASS",
08700     "JUNK",
08701 };
08702 
08703 ID
08704 rb_id_attrset(ID id)
08705 {
08706     if (!is_notop_id(id)) {
08707         switch (id) {
08708           case tAREF: case tASET:
08709             return tASET;       /* only exception */
08710         }
08711         rb_name_error(id, "cannot make operator ID :%s attrset", rb_id2name(id));
08712     }
08713     else {
08714         int scope = (int)(id & ID_SCOPE_MASK);
08715         switch (scope) {
08716           case ID_LOCAL: case ID_INSTANCE: case ID_GLOBAL:
08717           case ID_CONST: case ID_CLASS: case ID_JUNK:
08718             break;
08719           case ID_ATTRSET:
08720             return id;
08721           default:
08722             rb_name_error(id, "cannot make %s ID %+"PRIsVALUE" attrset",
08723                           id_type_names[scope], ID2SYM(id));
08724 
08725         }
08726     }
08727     id &= ~ID_SCOPE_MASK;
08728     id |= ID_ATTRSET;
08729     return id;
08730 }
08731 
08732 static NODE *
08733 attrset_gen(struct parser_params *parser, NODE *recv, ID id)
08734 {
08735     if (recv && nd_type(recv) == NODE_SELF)
08736         recv = (NODE *)1;
08737     return NEW_ATTRASGN(recv, rb_id_attrset(id), 0);
08738 }
08739 
08740 static void
08741 rb_backref_error_gen(struct parser_params *parser, NODE *node)
08742 {
08743     switch (nd_type(node)) {
08744       case NODE_NTH_REF:
08745         compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
08746         break;
08747       case NODE_BACK_REF:
08748         compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
08749         break;
08750     }
08751 }
08752 
08753 static NODE *
08754 arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
08755 {
08756     if (!node2) return node1;
08757     switch (nd_type(node1)) {
08758       case NODE_BLOCK_PASS:
08759         if (node1->nd_head)
08760             node1->nd_head = arg_concat(node1->nd_head, node2);
08761         else
08762             node1->nd_head = NEW_LIST(node2);
08763         return node1;
08764       case NODE_ARGSPUSH:
08765         if (nd_type(node2) != NODE_ARRAY) break;
08766         node1->nd_body = list_concat(NEW_LIST(node1->nd_body), node2);
08767         nd_set_type(node1, NODE_ARGSCAT);
08768         return node1;
08769       case NODE_ARGSCAT:
08770         if (nd_type(node2) != NODE_ARRAY ||
08771             nd_type(node1->nd_body) != NODE_ARRAY) break;
08772         node1->nd_body = list_concat(node1->nd_body, node2);
08773         return node1;
08774     }
08775     return NEW_ARGSCAT(node1, node2);
08776 }
08777 
08778 static NODE *
08779 arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
08780 {
08781     if (!node1) return NEW_LIST(node2);
08782     switch (nd_type(node1))  {
08783       case NODE_ARRAY:
08784         return list_append(node1, node2);
08785       case NODE_BLOCK_PASS:
08786         node1->nd_head = arg_append(node1->nd_head, node2);
08787         return node1;
08788       case NODE_ARGSPUSH:
08789         node1->nd_body = list_append(NEW_LIST(node1->nd_body), node2);
08790         nd_set_type(node1, NODE_ARGSCAT);
08791         return node1;
08792     }
08793     return NEW_ARGSPUSH(node1, node2);
08794 }
08795 
08796 static NODE *
08797 splat_array(NODE* node)
08798 {
08799     if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
08800     if (nd_type(node) == NODE_ARRAY) return node;
08801     return 0;
08802 }
08803 
08804 static NODE *
08805 node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
08806 {
08807     if (!lhs) return 0;
08808 
08809     switch (nd_type(lhs)) {
08810       case NODE_GASGN:
08811       case NODE_IASGN:
08812       case NODE_IASGN2:
08813       case NODE_LASGN:
08814       case NODE_DASGN:
08815       case NODE_DASGN_CURR:
08816       case NODE_MASGN:
08817       case NODE_CDECL:
08818       case NODE_CVASGN:
08819         lhs->nd_value = rhs;
08820         break;
08821 
08822       case NODE_ATTRASGN:
08823       case NODE_CALL:
08824         lhs->nd_args = arg_append(lhs->nd_args, rhs);
08825         break;
08826 
08827       default:
08828         /* should not happen */
08829         break;
08830     }
08831 
08832     return lhs;
08833 }
08834 
08835 static int
08836 value_expr_gen(struct parser_params *parser, NODE *node)
08837 {
08838     int cond = 0;
08839 
08840     if (!node) {
08841         rb_warning0("empty expression");
08842     }
08843     while (node) {
08844         switch (nd_type(node)) {
08845           case NODE_DEFN:
08846           case NODE_DEFS:
08847             parser_warning(node, "void value expression");
08848             return FALSE;
08849 
08850           case NODE_RETURN:
08851           case NODE_BREAK:
08852           case NODE_NEXT:
08853           case NODE_REDO:
08854           case NODE_RETRY:
08855             if (!cond) yyerror("void value expression");
08856             /* or "control never reach"? */
08857             return FALSE;
08858 
08859           case NODE_BLOCK:
08860             while (node->nd_next) {
08861                 node = node->nd_next;
08862             }
08863             node = node->nd_head;
08864             break;
08865 
08866           case NODE_BEGIN:
08867             node = node->nd_body;
08868             break;
08869 
08870           case NODE_IF:
08871             if (!node->nd_body) {
08872                 node = node->nd_else;
08873                 break;
08874             }
08875             else if (!node->nd_else) {
08876                 node = node->nd_body;
08877                 break;
08878             }
08879             if (!value_expr(node->nd_body)) return FALSE;
08880             node = node->nd_else;
08881             break;
08882 
08883           case NODE_AND:
08884           case NODE_OR:
08885             cond = 1;
08886             node = node->nd_2nd;
08887             break;
08888 
08889           default:
08890             return TRUE;
08891         }
08892     }
08893 
08894     return TRUE;
08895 }
08896 
08897 static void
08898 void_expr_gen(struct parser_params *parser, NODE *node)
08899 {
08900     const char *useless = 0;
08901 
08902     if (!RTEST(ruby_verbose)) return;
08903 
08904     if (!node) return;
08905     switch (nd_type(node)) {
08906       case NODE_CALL:
08907         switch (node->nd_mid) {
08908           case '+':
08909           case '-':
08910           case '*':
08911           case '/':
08912           case '%':
08913           case tPOW:
08914           case tUPLUS:
08915           case tUMINUS:
08916           case '|':
08917           case '^':
08918           case '&':
08919           case tCMP:
08920           case '>':
08921           case tGEQ:
08922           case '<':
08923           case tLEQ:
08924           case tEQ:
08925           case tNEQ:
08926             useless = rb_id2name(node->nd_mid);
08927             break;
08928         }
08929         break;
08930 
08931       case NODE_LVAR:
08932       case NODE_DVAR:
08933       case NODE_GVAR:
08934       case NODE_IVAR:
08935       case NODE_CVAR:
08936       case NODE_NTH_REF:
08937       case NODE_BACK_REF:
08938         useless = "a variable";
08939         break;
08940       case NODE_CONST:
08941         useless = "a constant";
08942         break;
08943       case NODE_LIT:
08944       case NODE_STR:
08945       case NODE_DSTR:
08946       case NODE_DREGX:
08947       case NODE_DREGX_ONCE:
08948         useless = "a literal";
08949         break;
08950       case NODE_COLON2:
08951       case NODE_COLON3:
08952         useless = "::";
08953         break;
08954       case NODE_DOT2:
08955         useless = "..";
08956         break;
08957       case NODE_DOT3:
08958         useless = "...";
08959         break;
08960       case NODE_SELF:
08961         useless = "self";
08962         break;
08963       case NODE_NIL:
08964         useless = "nil";
08965         break;
08966       case NODE_TRUE:
08967         useless = "true";
08968         break;
08969       case NODE_FALSE:
08970         useless = "false";
08971         break;
08972       case NODE_DEFINED:
08973         useless = "defined?";
08974         break;
08975     }
08976 
08977     if (useless) {
08978         int line = ruby_sourceline;
08979 
08980         ruby_sourceline = nd_line(node);
08981         rb_warnS("possibly useless use of %s in void context", useless);
08982         ruby_sourceline = line;
08983     }
08984 }
08985 
08986 static void
08987 void_stmts_gen(struct parser_params *parser, NODE *node)
08988 {
08989     if (!RTEST(ruby_verbose)) return;
08990     if (!node) return;
08991     if (nd_type(node) != NODE_BLOCK) return;
08992 
08993     for (;;) {
08994         if (!node->nd_next) return;
08995         void_expr0(node->nd_head);
08996         node = node->nd_next;
08997     }
08998 }
08999 
09000 static NODE *
09001 remove_begin(NODE *node)
09002 {
09003     NODE **n = &node, *n1 = node;
09004     while (n1 && nd_type(n1) == NODE_BEGIN && n1->nd_body) {
09005         *n = n1 = n1->nd_body;
09006     }
09007     return node;
09008 }
09009 
09010 static void
09011 reduce_nodes_gen(struct parser_params *parser, NODE **body)
09012 {
09013     NODE *node = *body;
09014 
09015     if (!node) {
09016         *body = NEW_NIL();
09017         return;
09018     }
09019 #define subnodes(n1, n2) \
09020     ((!node->n1) ? (node->n2 ? (body = &node->n2, 1) : 0) : \
09021      (!node->n2) ? (body = &node->n1, 1) : \
09022      (reduce_nodes(&node->n1), body = &node->n2, 1))
09023 
09024     while (node) {
09025         int newline = (int)(node->flags & NODE_FL_NEWLINE);
09026         switch (nd_type(node)) {
09027           end:
09028           case NODE_NIL:
09029             *body = 0;
09030             return;
09031           case NODE_RETURN:
09032             *body = node = node->nd_stts;
09033             if (newline && node) node->flags |= NODE_FL_NEWLINE;
09034             continue;
09035           case NODE_BEGIN:
09036             *body = node = node->nd_body;
09037             if (newline && node) node->flags |= NODE_FL_NEWLINE;
09038             continue;
09039           case NODE_BLOCK:
09040             body = &node->nd_end->nd_head;
09041             break;
09042           case NODE_IF:
09043             if (subnodes(nd_body, nd_else)) break;
09044             return;
09045           case NODE_CASE:
09046             body = &node->nd_body;
09047             break;
09048           case NODE_WHEN:
09049             if (!subnodes(nd_body, nd_next)) goto end;
09050             break;
09051           case NODE_ENSURE:
09052             if (!subnodes(nd_head, nd_resq)) goto end;
09053             break;
09054           case NODE_RESCUE:
09055             if (node->nd_else) {
09056                 body = &node->nd_resq;
09057                 break;
09058             }
09059             if (!subnodes(nd_head, nd_resq)) goto end;
09060             break;
09061           default:
09062             return;
09063         }
09064         node = *body;
09065         if (newline && node) node->flags |= NODE_FL_NEWLINE;
09066     }
09067 
09068 #undef subnodes
09069 }
09070 
09071 static int
09072 is_static_content(NODE *node)
09073 {
09074     if (!node) return 1;
09075     switch (nd_type(node)) {
09076       case NODE_HASH:
09077         if (!(node = node->nd_head)) break;
09078       case NODE_ARRAY:
09079         do {
09080             if (!is_static_content(node->nd_head)) return 0;
09081         } while ((node = node->nd_next) != 0);
09082       case NODE_LIT:
09083       case NODE_STR:
09084       case NODE_NIL:
09085       case NODE_TRUE:
09086       case NODE_FALSE:
09087       case NODE_ZARRAY:
09088         break;
09089       default:
09090         return 0;
09091     }
09092     return 1;
09093 }
09094 
09095 static int
09096 assign_in_cond(struct parser_params *parser, NODE *node)
09097 {
09098     switch (nd_type(node)) {
09099       case NODE_MASGN:
09100         yyerror("multiple assignment in conditional");
09101         return 1;
09102 
09103       case NODE_LASGN:
09104       case NODE_DASGN:
09105       case NODE_DASGN_CURR:
09106       case NODE_GASGN:
09107       case NODE_IASGN:
09108         break;
09109 
09110       default:
09111         return 0;
09112     }
09113 
09114     if (!node->nd_value) return 1;
09115     if (is_static_content(node->nd_value)) {
09116         /* reports always */
09117         parser_warn(node->nd_value, "found = in conditional, should be ==");
09118     }
09119     return 1;
09120 }
09121 
09122 static void
09123 warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
09124 {
09125     if (!e_option_supplied(parser)) parser_warn(node, str);
09126 }
09127 
09128 static void
09129 warning_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
09130 {
09131     if (!e_option_supplied(parser)) parser_warning(node, str);
09132 }
09133 
09134 static void
09135 fixup_nodes(NODE **rootnode)
09136 {
09137     NODE *node, *next, *head;
09138 
09139     for (node = *rootnode; node; node = next) {
09140         enum node_type type;
09141         VALUE val;
09142 
09143         next = node->nd_next;
09144         head = node->nd_head;
09145         rb_gc_force_recycle((VALUE)node);
09146         *rootnode = next;
09147         switch (type = nd_type(head)) {
09148           case NODE_DOT2:
09149           case NODE_DOT3:
09150             val = rb_range_new(head->nd_beg->nd_lit, head->nd_end->nd_lit,
09151                                type == NODE_DOT3);
09152             rb_gc_force_recycle((VALUE)head->nd_beg);
09153             rb_gc_force_recycle((VALUE)head->nd_end);
09154             nd_set_type(head, NODE_LIT);
09155             head->nd_lit = val;
09156             break;
09157           default:
09158             break;
09159         }
09160     }
09161 }
09162 
09163 static NODE *cond0(struct parser_params*,NODE*);
09164 
09165 static NODE*
09166 range_op(struct parser_params *parser, NODE *node)
09167 {
09168     enum node_type type;
09169 
09170     if (node == 0) return 0;
09171 
09172     type = nd_type(node);
09173     value_expr(node);
09174     if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
09175         warn_unless_e_option(parser, node, "integer literal in conditional range");
09176         return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."))));
09177     }
09178     return cond0(parser, node);
09179 }
09180 
09181 static int
09182 literal_node(NODE *node)
09183 {
09184     if (!node) return 1;        /* same as NODE_NIL */
09185     switch (nd_type(node)) {
09186       case NODE_LIT:
09187       case NODE_STR:
09188       case NODE_DSTR:
09189       case NODE_EVSTR:
09190       case NODE_DREGX:
09191       case NODE_DREGX_ONCE:
09192       case NODE_DSYM:
09193         return 2;
09194       case NODE_TRUE:
09195       case NODE_FALSE:
09196       case NODE_NIL:
09197         return 1;
09198     }
09199     return 0;
09200 }
09201 
09202 static NODE*
09203 cond0(struct parser_params *parser, NODE *node)
09204 {
09205     if (node == 0) return 0;
09206     assign_in_cond(parser, node);
09207 
09208     switch (nd_type(node)) {
09209       case NODE_DSTR:
09210       case NODE_EVSTR:
09211       case NODE_STR:
09212         rb_warn0("string literal in condition");
09213         break;
09214 
09215       case NODE_DREGX:
09216       case NODE_DREGX_ONCE:
09217         warning_unless_e_option(parser, node, "regex literal in condition");
09218         return NEW_MATCH2(node, NEW_GVAR(rb_intern("$_")));
09219 
09220       case NODE_AND:
09221       case NODE_OR:
09222         node->nd_1st = cond0(parser, node->nd_1st);
09223         node->nd_2nd = cond0(parser, node->nd_2nd);
09224         break;
09225 
09226       case NODE_DOT2:
09227       case NODE_DOT3:
09228         node->nd_beg = range_op(parser, node->nd_beg);
09229         node->nd_end = range_op(parser, node->nd_end);
09230         if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
09231         else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
09232         if (!e_option_supplied(parser)) {
09233             int b = literal_node(node->nd_beg);
09234             int e = literal_node(node->nd_end);
09235             if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
09236                 parser_warn(node, "range literal in condition");
09237             }
09238         }
09239         break;
09240 
09241       case NODE_DSYM:
09242         parser_warning(node, "literal in condition");
09243         break;
09244 
09245       case NODE_LIT:
09246         if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
09247             warn_unless_e_option(parser, node, "regex literal in condition");
09248             nd_set_type(node, NODE_MATCH);
09249         }
09250         else {
09251             parser_warning(node, "literal in condition");
09252         }
09253       default:
09254         break;
09255     }
09256     return node;
09257 }
09258 
09259 static NODE*
09260 cond_gen(struct parser_params *parser, NODE *node)
09261 {
09262     if (node == 0) return 0;
09263     return cond0(parser, node);
09264 }
09265 
09266 static NODE*
09267 logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *right)
09268 {
09269     value_expr(left);
09270     if (left && (enum node_type)nd_type(left) == type) {
09271         NODE *node = left, *second;
09272         while ((second = node->nd_2nd) != 0 && (enum node_type)nd_type(second) == type) {
09273             node = second;
09274         }
09275         node->nd_2nd = NEW_NODE(type, second, right, 0);
09276         return left;
09277     }
09278     return NEW_NODE(type, left, right, 0);
09279 }
09280 
09281 static void
09282 no_blockarg(struct parser_params *parser, NODE *node)
09283 {
09284     if (node && nd_type(node) == NODE_BLOCK_PASS) {
09285         compile_error(PARSER_ARG "block argument should not be given");
09286     }
09287 }
09288 
09289 static NODE *
09290 ret_args_gen(struct parser_params *parser, NODE *node)
09291 {
09292     if (node) {
09293         no_blockarg(parser, node);
09294         if (nd_type(node) == NODE_ARRAY) {
09295             if (node->nd_next == 0) {
09296                 node = node->nd_head;
09297             }
09298             else {
09299                 nd_set_type(node, NODE_VALUES);
09300             }
09301         }
09302     }
09303     return node;
09304 }
09305 
09306 static NODE *
09307 new_yield_gen(struct parser_params *parser, NODE *node)
09308 {
09309     if (node) no_blockarg(parser, node);
09310 
09311     return NEW_YIELD(node);
09312 }
09313 
09314 static NODE*
09315 negate_lit(NODE *node)
09316 {
09317     switch (TYPE(node->nd_lit)) {
09318       case T_FIXNUM:
09319         node->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit));
09320         break;
09321       case T_BIGNUM:
09322         node->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0);
09323         break;
09324       case T_FLOAT:
09325 #if USE_FLONUM
09326         if (FLONUM_P(node->nd_lit)) {
09327             node->nd_lit = DBL2NUM(-RFLOAT_VALUE(node->nd_lit));
09328         }
09329         else {
09330             RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
09331         }
09332 #else
09333         RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
09334 #endif
09335         break;
09336       default:
09337         break;
09338     }
09339     return node;
09340 }
09341 
09342 static NODE *
09343 arg_blk_pass(NODE *node1, NODE *node2)
09344 {
09345     if (node2) {
09346         node2->nd_head = node1;
09347         return node2;
09348     }
09349     return node1;
09350 }
09351 
09352 
09353 static NODE*
09354 new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, NODE *tail)
09355 {
09356     int saved_line = ruby_sourceline;
09357     struct rb_args_info *args = tail->nd_ainfo;
09358 
09359     args->pre_args_num   = m ? rb_long2int(m->nd_plen) : 0;
09360     args->pre_init       = m ? m->nd_next : 0;
09361 
09362     args->post_args_num  = p ? rb_long2int(p->nd_plen) : 0;
09363     args->post_init      = p ? p->nd_next : 0;
09364     args->first_post_arg = p ? p->nd_pid : 0;
09365 
09366     args->rest_arg       = r;
09367 
09368     args->opt_args       = o;
09369 
09370     ruby_sourceline = saved_line;
09371 
09372     return tail;
09373 }
09374 
09375 static NODE*
09376 new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
09377 {
09378     int saved_line = ruby_sourceline;
09379     struct rb_args_info *args;
09380     NODE *kw_rest_arg = 0;
09381     NODE *node;
09382 
09383     args = ALLOC(struct rb_args_info);
09384     MEMZERO(args, struct rb_args_info, 1);
09385     node = NEW_NODE(NODE_ARGS, 0, 0, args);
09386 
09387     args->block_arg      = b;
09388     args->kw_args        = k;
09389     if (k && !kr) kr = internal_id();
09390     if (kr) {
09391         arg_var(kr);
09392         kw_rest_arg  = NEW_DVAR(kr);
09393     }
09394     args->kw_rest_arg    = kw_rest_arg;
09395 
09396     ruby_sourceline = saved_line;
09397     return node;
09398 }
09399 
09400 static NODE*
09401 dsym_node_gen(struct parser_params *parser, NODE *node)
09402 {
09403     VALUE lit;
09404 
09405     if (!node) {
09406         return NEW_LIT(ID2SYM(idNULL));
09407     }
09408 
09409     switch (nd_type(node)) {
09410       case NODE_DSTR:
09411         nd_set_type(node, NODE_DSYM);
09412         break;
09413       case NODE_STR:
09414         lit = node->nd_lit;
09415         node->nd_lit = ID2SYM(rb_intern_str(lit));
09416         nd_set_type(node, NODE_LIT);
09417         break;
09418       default:
09419         node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node));
09420         break;
09421     }
09422     return node;
09423 }
09424 #endif /* !RIPPER */
09425 
09426 #ifndef RIPPER
09427 static NODE *
09428 new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
09429 {
09430     NODE *asgn;
09431 
09432     if (lhs) {
09433         ID vid = lhs->nd_vid;
09434         if (op == tOROP) {
09435             lhs->nd_value = rhs;
09436             asgn = NEW_OP_ASGN_OR(gettable(vid), lhs);
09437             if (is_asgn_or_id(vid)) {
09438                 asgn->nd_aid = vid;
09439             }
09440         }
09441         else if (op == tANDOP) {
09442             lhs->nd_value = rhs;
09443             asgn = NEW_OP_ASGN_AND(gettable(vid), lhs);
09444         }
09445         else {
09446             asgn = lhs;
09447             asgn->nd_value = NEW_CALL(gettable(vid), op, NEW_LIST(rhs));
09448         }
09449     }
09450     else {
09451         asgn = NEW_BEGIN(0);
09452     }
09453     return asgn;
09454 }
09455 
09456 static NODE *
09457 new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs)
09458 {
09459     NODE *asgn;
09460 
09461     if (op == tOROP) {
09462         op = 0;
09463     }
09464     else if (op == tANDOP) {
09465         op = 1;
09466     }
09467     asgn = NEW_OP_ASGN2(lhs, attr, op, rhs);
09468     fixpos(asgn, lhs);
09469     return asgn;
09470 }
09471 
09472 static NODE *
09473 new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
09474 {
09475     NODE *asgn;
09476 
09477     if (op == tOROP) {
09478         op = 0;
09479     }
09480     else if (op == tANDOP) {
09481         op = 1;
09482     }
09483     if (lhs) {
09484         asgn = NEW_OP_CDECL(lhs, op, rhs);
09485     }
09486     else {
09487         asgn = NEW_BEGIN(0);
09488     }
09489     fixpos(asgn, lhs);
09490     return asgn;
09491 }
09492 #else
09493 static VALUE
09494 new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs)
09495 {
09496     return dispatch3(opassign, lhs, op, rhs);
09497 }
09498 
09499 static VALUE
09500 new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs)
09501 {
09502     VALUE recv = dispatch3(field, lhs, type, attr);
09503     return dispatch3(opassign, recv, op, rhs);
09504 }
09505 #endif
09506 
09507 static void
09508 warn_unused_var(struct parser_params *parser, struct local_vars *local)
09509 {
09510     int i, cnt;
09511     ID *v, *u;
09512 
09513     if (!local->used) return;
09514     v = local->vars->tbl;
09515     u = local->used->tbl;
09516     cnt = local->used->pos;
09517     if (cnt != local->vars->pos) {
09518         rb_bug("local->used->pos != local->vars->pos");
09519     }
09520     for (i = 0; i < cnt; ++i) {
09521         if (!v[i] || (u[i] & LVAR_USED)) continue;
09522         if (is_private_local_id(v[i])) continue;
09523         rb_warn4S(ruby_sourcefile, (int)u[i], "assigned but unused variable - %s", rb_id2name(v[i]));
09524     }
09525 }
09526 
09527 static void
09528 local_push_gen(struct parser_params *parser, int inherit_dvars)
09529 {
09530     struct local_vars *local;
09531 
09532     local = ALLOC(struct local_vars);
09533     local->prev = lvtbl;
09534     local->args = vtable_alloc(0);
09535     local->vars = vtable_alloc(inherit_dvars ? DVARS_INHERIT : DVARS_TOPSCOPE);
09536     local->used = !(inherit_dvars &&
09537                     (ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
09538         RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
09539     local->cmdargs = cmdarg_stack;
09540     cmdarg_stack = 0;
09541     lvtbl = local;
09542 }
09543 
09544 static void
09545 local_pop_gen(struct parser_params *parser)
09546 {
09547     struct local_vars *local = lvtbl->prev;
09548     if (lvtbl->used) {
09549         warn_unused_var(parser, lvtbl);
09550         vtable_free(lvtbl->used);
09551     }
09552     vtable_free(lvtbl->args);
09553     vtable_free(lvtbl->vars);
09554     cmdarg_stack = lvtbl->cmdargs;
09555     xfree(lvtbl);
09556     lvtbl = local;
09557 }
09558 
09559 #ifndef RIPPER
09560 static ID*
09561 vtable_tblcpy(ID *buf, const struct vtable *src)
09562 {
09563     int i, cnt = vtable_size(src);
09564 
09565     if (cnt > 0) {
09566         buf[0] = cnt;
09567         for (i = 0; i < cnt; i++) {
09568             buf[i] = src->tbl[i];
09569         }
09570         return buf;
09571     }
09572     return 0;
09573 }
09574 
09575 static ID*
09576 local_tbl_gen(struct parser_params *parser)
09577 {
09578     int cnt = vtable_size(lvtbl->args) + vtable_size(lvtbl->vars);
09579     ID *buf;
09580 
09581     if (cnt <= 0) return 0;
09582     buf = ALLOC_N(ID, cnt + 1);
09583     vtable_tblcpy(buf+1, lvtbl->args);
09584     vtable_tblcpy(buf+vtable_size(lvtbl->args)+1, lvtbl->vars);
09585     buf[0] = cnt;
09586     return buf;
09587 }
09588 #endif
09589 
09590 static int
09591 arg_var_gen(struct parser_params *parser, ID id)
09592 {
09593     vtable_add(lvtbl->args, id);
09594     return vtable_size(lvtbl->args) - 1;
09595 }
09596 
09597 static int
09598 local_var_gen(struct parser_params *parser, ID id)
09599 {
09600     vtable_add(lvtbl->vars, id);
09601     if (lvtbl->used) {
09602         vtable_add(lvtbl->used, (ID)ruby_sourceline);
09603     }
09604     return vtable_size(lvtbl->vars) - 1;
09605 }
09606 
09607 static int
09608 local_id_gen(struct parser_params *parser, ID id)
09609 {
09610     struct vtable *vars, *args, *used;
09611 
09612     vars = lvtbl->vars;
09613     args = lvtbl->args;
09614     used = lvtbl->used;
09615 
09616     while (vars && POINTER_P(vars->prev)) {
09617         vars = vars->prev;
09618         args = args->prev;
09619         if (used) used = used->prev;
09620     }
09621 
09622     if (vars && vars->prev == DVARS_INHERIT) {
09623         return rb_local_defined(id);
09624     }
09625     else if (vtable_included(args, id)) {
09626         return 1;
09627     }
09628     else {
09629         int i = vtable_included(vars, id);
09630         if (i && used) used->tbl[i-1] |= LVAR_USED;
09631         return i != 0;
09632     }
09633 }
09634 
09635 static const struct vtable *
09636 dyna_push_gen(struct parser_params *parser)
09637 {
09638     lvtbl->args = vtable_alloc(lvtbl->args);
09639     lvtbl->vars = vtable_alloc(lvtbl->vars);
09640     if (lvtbl->used) {
09641         lvtbl->used = vtable_alloc(lvtbl->used);
09642     }
09643     return lvtbl->args;
09644 }
09645 
09646 static void
09647 dyna_pop_1(struct parser_params *parser)
09648 {
09649     struct vtable *tmp;
09650 
09651     if ((tmp = lvtbl->used) != 0) {
09652         warn_unused_var(parser, lvtbl);
09653         lvtbl->used = lvtbl->used->prev;
09654         vtable_free(tmp);
09655     }
09656     tmp = lvtbl->args;
09657     lvtbl->args = lvtbl->args->prev;
09658     vtable_free(tmp);
09659     tmp = lvtbl->vars;
09660     lvtbl->vars = lvtbl->vars->prev;
09661     vtable_free(tmp);
09662 }
09663 
09664 static void
09665 dyna_pop_gen(struct parser_params *parser, const struct vtable *lvargs)
09666 {
09667     while (lvtbl->args != lvargs) {
09668         dyna_pop_1(parser);
09669         if (!lvtbl->args) {
09670             struct local_vars *local = lvtbl->prev;
09671             xfree(lvtbl);
09672             lvtbl = local;
09673         }
09674     }
09675     dyna_pop_1(parser);
09676 }
09677 
09678 static int
09679 dyna_in_block_gen(struct parser_params *parser)
09680 {
09681     return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
09682 }
09683 
09684 static int
09685 dvar_defined_gen(struct parser_params *parser, ID id, int get)
09686 {
09687     struct vtable *vars, *args, *used;
09688     int i;
09689 
09690     args = lvtbl->args;
09691     vars = lvtbl->vars;
09692     used = lvtbl->used;
09693 
09694     while (POINTER_P(vars)) {
09695         if (vtable_included(args, id)) {
09696             return 1;
09697         }
09698         if ((i = vtable_included(vars, id)) != 0) {
09699             if (used) used->tbl[i-1] |= LVAR_USED;
09700             return 1;
09701         }
09702         args = args->prev;
09703         vars = vars->prev;
09704         if (get) used = 0;
09705         if (used) used = used->prev;
09706     }
09707 
09708     if (vars == DVARS_INHERIT) {
09709         return rb_dvar_defined(id);
09710     }
09711 
09712     return 0;
09713 }
09714 
09715 static int
09716 dvar_curr_gen(struct parser_params *parser, ID id)
09717 {
09718     return (vtable_included(lvtbl->args, id) ||
09719             vtable_included(lvtbl->vars, id));
09720 }
09721 
09722 #ifndef RIPPER
09723 static void
09724 reg_fragment_setenc_gen(struct parser_params* parser, VALUE str, int options)
09725 {
09726     int c = RE_OPTION_ENCODING_IDX(options);
09727 
09728     if (c) {
09729         int opt, idx;
09730         rb_char_to_option_kcode(c, &opt, &idx);
09731         if (idx != ENCODING_GET(str) &&
09732             rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
09733             goto error;
09734         }
09735         ENCODING_SET(str, idx);
09736     }
09737     else if (RE_OPTION_ENCODING_NONE(options)) {
09738         if (!ENCODING_IS_ASCII8BIT(str) &&
09739             rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
09740             c = 'n';
09741             goto error;
09742         }
09743         rb_enc_associate(str, rb_ascii8bit_encoding());
09744     }
09745     else if (current_enc == rb_usascii_encoding()) {
09746         if (rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
09747             /* raise in re.c */
09748             rb_enc_associate(str, rb_usascii_encoding());
09749         }
09750         else {
09751             rb_enc_associate(str, rb_ascii8bit_encoding());
09752         }
09753     }
09754     return;
09755 
09756   error:
09757     compile_error(PARSER_ARG
09758         "regexp encoding option '%c' differs from source encoding '%s'",
09759         c, rb_enc_name(rb_enc_get(str)));
09760 }
09761 
09762 static int
09763 reg_fragment_check_gen(struct parser_params* parser, VALUE str, int options)
09764 {
09765     VALUE err;
09766     reg_fragment_setenc(str, options);
09767     err = rb_reg_check_preprocess(str);
09768     if (err != Qnil) {
09769         err = rb_obj_as_string(err);
09770         compile_error(PARSER_ARG "%s", RSTRING_PTR(err));
09771         RB_GC_GUARD(err);
09772         return 0;
09773     }
09774     return 1;
09775 }
09776 
09777 typedef struct {
09778     struct parser_params* parser;
09779     rb_encoding *enc;
09780     NODE *succ_block;
09781     NODE *fail_block;
09782     int num;
09783 } reg_named_capture_assign_t;
09784 
09785 static int
09786 reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
09787           int back_num, int *back_refs, OnigRegex regex, void *arg0)
09788 {
09789     reg_named_capture_assign_t *arg = (reg_named_capture_assign_t*)arg0;
09790     struct parser_params* parser = arg->parser;
09791     rb_encoding *enc = arg->enc;
09792     long len = name_end - name;
09793     const char *s = (const char *)name;
09794     ID var;
09795 
09796     arg->num++;
09797 
09798     if (arg->succ_block == 0) {
09799         arg->succ_block = NEW_BEGIN(0);
09800         arg->fail_block = NEW_BEGIN(0);
09801     }
09802 
09803     if (!len || (*name != '_' && ISASCII(*name) && !rb_enc_islower(*name, enc)) ||
09804         (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) ||
09805         !rb_enc_symname2_p(s, len, enc)) {
09806         return ST_CONTINUE;
09807     }
09808     var = rb_intern3(s, len, enc);
09809     if (dvar_defined(var) || local_id(var)) {
09810         rb_warningS("named capture conflicts a local variable - %s",
09811                     rb_id2name(var));
09812     }
09813     arg->succ_block = block_append(arg->succ_block,
09814         newline_node(node_assign(assignable(var,0),
09815             NEW_CALL(
09816               gettable(rb_intern("$~")),
09817               idAREF,
09818               NEW_LIST(NEW_LIT(ID2SYM(var))))
09819             )));
09820     arg->fail_block = block_append(arg->fail_block,
09821         newline_node(node_assign(assignable(var,0), NEW_LIT(Qnil))));
09822     return ST_CONTINUE;
09823 }
09824 
09825 static NODE *
09826 reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match)
09827 {
09828     reg_named_capture_assign_t arg;
09829 
09830     arg.parser = parser;
09831     arg.enc = rb_enc_get(regexp);
09832     arg.succ_block = 0;
09833     arg.fail_block = 0;
09834     arg.num = 0;
09835     onig_foreach_name(RREGEXP(regexp)->ptr, reg_named_capture_assign_iter, (void*)&arg);
09836 
09837     if (arg.num == 0)
09838         return match;
09839 
09840     return
09841         block_append(
09842             newline_node(match),
09843             NEW_IF(gettable(rb_intern("$~")),
09844                 block_append(
09845                     newline_node(arg.succ_block),
09846                     newline_node(
09847                         NEW_CALL(
09848                           gettable(rb_intern("$~")),
09849                           rb_intern("begin"),
09850                           NEW_LIST(NEW_LIT(INT2FIX(0)))))),
09851                 block_append(
09852                     newline_node(arg.fail_block),
09853                     newline_node(
09854                         NEW_LIT(Qnil)))));
09855 }
09856 
09857 static VALUE
09858 reg_compile_gen(struct parser_params* parser, VALUE str, int options)
09859 {
09860     VALUE re;
09861     VALUE err;
09862 
09863     reg_fragment_setenc(str, options);
09864     err = rb_errinfo();
09865     re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
09866     if (NIL_P(re)) {
09867         ID mesg = rb_intern("mesg");
09868         VALUE m = rb_attr_get(rb_errinfo(), mesg);
09869         rb_set_errinfo(err);
09870         if (!NIL_P(err)) {
09871             rb_str_append(rb_str_cat(rb_attr_get(err, mesg), "\n", 1), m);
09872         }
09873         else {
09874             compile_error(PARSER_ARG "%s", RSTRING_PTR(m));
09875         }
09876         return Qnil;
09877     }
09878     return re;
09879 }
09880 
09881 void
09882 rb_gc_mark_parser(void)
09883 {
09884 }
09885 
09886 NODE*
09887 rb_parser_append_print(VALUE vparser, NODE *node)
09888 {
09889     NODE *prelude = 0;
09890     NODE *scope = node;
09891     struct parser_params *parser;
09892 
09893     if (!node) return node;
09894 
09895     TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
09896 
09897     node = node->nd_body;
09898 
09899     if (nd_type(node) == NODE_PRELUDE) {
09900         prelude = node;
09901         node = node->nd_body;
09902     }
09903 
09904     node = block_append(node,
09905                         NEW_FCALL(rb_intern("print"),
09906                                   NEW_ARRAY(NEW_GVAR(rb_intern("$_")))));
09907     if (prelude) {
09908         prelude->nd_body = node;
09909         scope->nd_body = prelude;
09910     }
09911     else {
09912         scope->nd_body = node;
09913     }
09914 
09915     return scope;
09916 }
09917 
09918 NODE *
09919 rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
09920 {
09921     NODE *prelude = 0;
09922     NODE *scope = node;
09923     struct parser_params *parser;
09924 
09925     if (!node) return node;
09926 
09927     TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
09928 
09929     node = node->nd_body;
09930 
09931     if (nd_type(node) == NODE_PRELUDE) {
09932         prelude = node;
09933         node = node->nd_body;
09934     }
09935     if (split) {
09936         node = block_append(NEW_GASGN(rb_intern("$F"),
09937                                       NEW_CALL(NEW_GVAR(rb_intern("$_")),
09938                                                rb_intern("split"), 0)),
09939                             node);
09940     }
09941     if (chop) {
09942         node = block_append(NEW_CALL(NEW_GVAR(rb_intern("$_")),
09943                                      rb_intern("chop!"), 0), node);
09944     }
09945 
09946     node = NEW_OPT_N(node);
09947 
09948     if (prelude) {
09949         prelude->nd_body = node;
09950         scope->nd_body = prelude;
09951     }
09952     else {
09953         scope->nd_body = node;
09954     }
09955 
09956     return scope;
09957 }
09958 
09959 static const struct {
09960     ID token;
09961     const char *name;
09962 } op_tbl[] = {
09963     {tDOT2,     ".."},
09964     {tDOT3,     "..."},
09965     {tPOW,      "**"},
09966     {tDSTAR,    "**"},
09967     {tUPLUS,    "+@"},
09968     {tUMINUS,   "-@"},
09969     {tCMP,      "<=>"},
09970     {tGEQ,      ">="},
09971     {tLEQ,      "<="},
09972     {tEQ,       "=="},
09973     {tEQQ,      "==="},
09974     {tNEQ,      "!="},
09975     {tMATCH,    "=~"},
09976     {tNMATCH,   "!~"},
09977     {tAREF,     "[]"},
09978     {tASET,     "[]="},
09979     {tLSHFT,    "<<"},
09980     {tRSHFT,    ">>"},
09981     {tCOLON2,   "::"},
09982 };
09983 
09984 #define op_tbl_count numberof(op_tbl)
09985 
09986 #ifndef ENABLE_SELECTOR_NAMESPACE
09987 #define ENABLE_SELECTOR_NAMESPACE 0
09988 #endif
09989 
09990 static struct symbols {
09991     ID last_id;
09992     st_table *sym_id;
09993     st_table *id_str;
09994 #if ENABLE_SELECTOR_NAMESPACE
09995     st_table *ivar2_id;
09996     st_table *id_ivar2;
09997 #endif
09998     VALUE op_sym[tLAST_OP_ID];
09999 } global_symbols = {tLAST_TOKEN};
10000 
10001 static const struct st_hash_type symhash = {
10002     rb_str_hash_cmp,
10003     rb_str_hash,
10004 };
10005 
10006 #if ENABLE_SELECTOR_NAMESPACE
10007 struct ivar2_key {
10008     ID id;
10009     VALUE klass;
10010 };
10011 
10012 static int
10013 ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2)
10014 {
10015     if (key1->id == key2->id && key1->klass == key2->klass) {
10016         return 0;
10017     }
10018     return 1;
10019 }
10020 
10021 static int
10022 ivar2_hash(struct ivar2_key *key)
10023 {
10024     return (key->id << 8) ^ (key->klass >> 2);
10025 }
10026 
10027 static const struct st_hash_type ivar2_hash_type = {
10028     ivar2_cmp,
10029     ivar2_hash,
10030 };
10031 #endif
10032 
10033 void
10034 Init_sym(void)
10035 {
10036     global_symbols.sym_id = st_init_table_with_size(&symhash, 1000);
10037     global_symbols.id_str = st_init_numtable_with_size(1000);
10038 #if ENABLE_SELECTOR_NAMESPACE
10039     global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
10040     global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
10041 #endif
10042 
10043     (void)nodetype;
10044     (void)nodeline;
10045 #if PARSER_DEBUG
10046     (void)lex_state_name(-1);
10047 #endif
10048 
10049     Init_id();
10050 }
10051 
10052 void
10053 rb_gc_mark_symbols(void)
10054 {
10055     rb_mark_tbl(global_symbols.id_str);
10056     rb_gc_mark_locations(global_symbols.op_sym,
10057                          global_symbols.op_sym + numberof(global_symbols.op_sym));
10058 }
10059 #endif /* !RIPPER */
10060 
10061 static ID
10062 internal_id_gen(struct parser_params *parser)
10063 {
10064     ID id = (ID)vtable_size(lvtbl->args) + (ID)vtable_size(lvtbl->vars);
10065     id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1;
10066     return ID_INTERNAL | (id << ID_SCOPE_SHIFT);
10067 }
10068 
10069 #ifndef RIPPER
10070 static int
10071 is_special_global_name(const char *m, const char *e, rb_encoding *enc)
10072 {
10073     int mb = 0;
10074 
10075     if (m >= e) return 0;
10076     if (is_global_name_punct(*m)) {
10077         ++m;
10078     }
10079     else if (*m == '-') {
10080         ++m;
10081         if (m < e && is_identchar(m, e, enc)) {
10082             if (!ISASCII(*m)) mb = 1;
10083             m += rb_enc_mbclen(m, e, enc);
10084         }
10085     }
10086     else {
10087         if (!rb_enc_isdigit(*m, enc)) return 0;
10088         do {
10089             if (!ISASCII(*m)) mb = 1;
10090             ++m;
10091         } while (m < e && rb_enc_isdigit(*m, enc));
10092     }
10093     return m == e ? mb + 1 : 0;
10094 }
10095 
10096 int
10097 rb_symname_p(const char *name)
10098 {
10099     return rb_enc_symname_p(name, rb_ascii8bit_encoding());
10100 }
10101 
10102 int
10103 rb_enc_symname_p(const char *name, rb_encoding *enc)
10104 {
10105     return rb_enc_symname2_p(name, strlen(name), enc);
10106 }
10107 
10108 #define IDSET_ATTRSET_FOR_SYNTAX ((1U<<ID_LOCAL)|(1U<<ID_CONST))
10109 #define IDSET_ATTRSET_FOR_INTERN (~(~0U<<(1<<ID_SCOPE_SHIFT)) & ~(1U<<ID_ATTRSET))
10110 
10111 static int
10112 rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_atttset)
10113 {
10114     const char *m = name;
10115     const char *e = m + len;
10116     int type = ID_JUNK;
10117 
10118     if (!m || len <= 0) return -1;
10119     switch (*m) {
10120       case '\0':
10121         return -1;
10122 
10123       case '$':
10124         type = ID_GLOBAL;
10125         if (is_special_global_name(++m, e, enc)) return type;
10126         goto id;
10127 
10128       case '@':
10129         type = ID_INSTANCE;
10130         if (*++m == '@') {
10131             ++m;
10132             type = ID_CLASS;
10133         }
10134         goto id;
10135 
10136       case '<':
10137         switch (*++m) {
10138           case '<': ++m; break;
10139           case '=': if (*++m == '>') ++m; break;
10140           default: break;
10141         }
10142         break;
10143 
10144       case '>':
10145         switch (*++m) {
10146           case '>': case '=': ++m; break;
10147         }
10148         break;
10149 
10150       case '=':
10151         switch (*++m) {
10152           case '~': ++m; break;
10153           case '=': if (*++m == '=') ++m; break;
10154           default: return -1;
10155         }
10156         break;
10157 
10158       case '*':
10159         if (*++m == '*') ++m;
10160         break;
10161 
10162       case '+': case '-':
10163         if (*++m == '@') ++m;
10164         break;
10165 
10166       case '|': case '^': case '&': case '/': case '%': case '~': case '`':
10167         ++m;
10168         break;
10169 
10170       case '[':
10171         if (*++m != ']') return -1;
10172         if (*++m == '=') ++m;
10173         break;
10174 
10175       case '!':
10176         if (len == 1) return ID_JUNK;
10177         switch (*++m) {
10178           case '=': case '~': ++m; break;
10179           default: return -1;
10180         }
10181         break;
10182 
10183       default:
10184         type = rb_enc_isupper(*m, enc) ? ID_CONST : ID_LOCAL;
10185       id:
10186         if (m >= e || (*m != '_' && !rb_enc_isalpha(*m, enc) && ISASCII(*m)))
10187             return -1;
10188         while (m < e && is_identchar(m, e, enc)) m += rb_enc_mbclen(m, e, enc);
10189         if (m >= e) break;
10190         switch (*m) {
10191           case '!': case '?':
10192             if (type == ID_GLOBAL || type == ID_CLASS || type == ID_INSTANCE) return -1;
10193             type = ID_JUNK;
10194             ++m;
10195             if (m + 1 < e || *m != '=') break;
10196             /* fall through */
10197           case '=':
10198             if (!(allowed_atttset & (1U << type))) return -1;
10199             type = ID_ATTRSET;
10200             ++m;
10201             break;
10202         }
10203         break;
10204     }
10205     return m == e ? type : -1;
10206 }
10207 
10208 int
10209 rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
10210 {
10211     return rb_enc_symname_type(name, len, enc, IDSET_ATTRSET_FOR_SYNTAX) != -1;
10212 }
10213 
10214 static int
10215 rb_str_symname_type(VALUE name, unsigned int allowed_atttset)
10216 {
10217     const char *ptr = StringValuePtr(name);
10218     long len = RSTRING_LEN(name);
10219     int type = rb_enc_symname_type(ptr, len, rb_enc_get(name), allowed_atttset);
10220     RB_GC_GUARD(name);
10221     return type;
10222 }
10223 
10224 static ID
10225 register_symid(ID id, const char *name, long len, rb_encoding *enc)
10226 {
10227     VALUE str = rb_enc_str_new(name, len, enc);
10228     return register_symid_str(id, str);
10229 }
10230 
10231 static ID
10232 register_symid_str(ID id, VALUE str)
10233 {
10234     OBJ_FREEZE(str);
10235     st_add_direct(global_symbols.sym_id, (st_data_t)str, id);
10236     st_add_direct(global_symbols.id_str, id, (st_data_t)str);
10237     return id;
10238 }
10239 
10240 static int
10241 sym_check_asciionly(VALUE str)
10242 {
10243     if (!rb_enc_asciicompat(rb_enc_get(str))) return FALSE;
10244     switch (rb_enc_str_coderange(str)) {
10245       case ENC_CODERANGE_BROKEN:
10246         rb_raise(rb_eEncodingError, "invalid encoding symbol");
10247       case ENC_CODERANGE_7BIT:
10248         return TRUE;
10249     }
10250     return FALSE;
10251 }
10252 
10253 /*
10254  * _str_ itself will be registered at the global symbol table.  _str_
10255  * can be modified before the registration, since the encoding will be
10256  * set to ASCII-8BIT if it is a special global name.
10257  */
10258 static ID intern_str(VALUE str);
10259 
10260 ID
10261 rb_intern3(const char *name, long len, rb_encoding *enc)
10262 {
10263     VALUE str;
10264     st_data_t data;
10265     struct RString fake_str;
10266     fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10267     fake_str.basic.klass = rb_cString;
10268     fake_str.as.heap.len = len;
10269     fake_str.as.heap.ptr = (char *)name;
10270     fake_str.as.heap.aux.capa = len;
10271     str = (VALUE)&fake_str;
10272     rb_enc_associate(str, enc);
10273     OBJ_FREEZE(str);
10274 
10275     if (st_lookup(global_symbols.sym_id, str, &data))
10276         return (ID)data;
10277 
10278     str = rb_enc_str_new(name, len, enc); /* make true string */
10279     return intern_str(str);
10280 }
10281 
10282 static ID
10283 intern_str(VALUE str)
10284 {
10285     const char *name, *m, *e;
10286     long len, last;
10287     rb_encoding *enc, *symenc;
10288     unsigned char c;
10289     ID id;
10290     int mb;
10291 
10292     RSTRING_GETMEM(str, name, len);
10293     m = name;
10294     e = m + len;
10295     enc = rb_enc_get(str);
10296     symenc = enc;
10297 
10298     if (!len || (rb_cString && !rb_enc_asciicompat(enc))) {
10299       junk:
10300         id = ID_JUNK;
10301         goto new_id;
10302     }
10303     last = len-1;
10304     id = 0;
10305     switch (*m) {
10306       case '$':
10307         if (len < 2) goto junk;
10308         id |= ID_GLOBAL;
10309         if ((mb = is_special_global_name(++m, e, enc)) != 0) {
10310             if (!--mb) symenc = rb_usascii_encoding();
10311             goto new_id;
10312         }
10313         break;
10314       case '@':
10315         if (m[1] == '@') {
10316             if (len < 3) goto junk;
10317             m++;
10318             id |= ID_CLASS;
10319         }
10320         else {
10321             if (len < 2) goto junk;
10322             id |= ID_INSTANCE;
10323         }
10324         m++;
10325         break;
10326       default:
10327         c = m[0];
10328         if (c != '_' && rb_enc_isascii(c, enc) && rb_enc_ispunct(c, enc)) {
10329             /* operators */
10330             int i;
10331 
10332             if (len == 1) {
10333                 id = c;
10334                 goto id_register;
10335             }
10336             for (i = 0; i < op_tbl_count; i++) {
10337                 if (*op_tbl[i].name == *m &&
10338                     strcmp(op_tbl[i].name, m) == 0) {
10339                     id = op_tbl[i].token;
10340                     goto id_register;
10341                 }
10342             }
10343         }
10344         break;
10345     }
10346     if (name[last] == '=') {
10347         /* attribute assignment */
10348         if (last > 1 && name[last-1] == '=')
10349             goto junk;
10350         id = rb_intern3(name, last, enc);
10351         if (id > tLAST_OP_ID && !is_attrset_id(id)) {
10352             enc = rb_enc_get(rb_id2str(id));
10353             id = rb_id_attrset(id);
10354             goto id_register;
10355         }
10356         id = ID_ATTRSET;
10357     }
10358     else if (id == 0) {
10359         if (rb_enc_isupper(m[0], enc)) {
10360             id = ID_CONST;
10361         }
10362         else {
10363             id = ID_LOCAL;
10364         }
10365     }
10366     if (!rb_enc_isdigit(*m, enc)) {
10367         while (m <= name + last && is_identchar(m, e, enc)) {
10368             if (ISASCII(*m)) {
10369                 m++;
10370             }
10371             else {
10372                 m += rb_enc_mbclen(m, e, enc);
10373             }
10374         }
10375     }
10376     if (id != ID_ATTRSET && m - name < len) id = ID_JUNK;
10377     if (sym_check_asciionly(str)) symenc = rb_usascii_encoding();
10378   new_id:
10379     if (symenc != enc) rb_enc_associate(str, symenc);
10380     if (global_symbols.last_id >= ~(ID)0 >> (ID_SCOPE_SHIFT+RUBY_SPECIAL_SHIFT)) {
10381         if (len > 20) {
10382             rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.20s...)",
10383                      name);
10384         }
10385         else {
10386             rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.*s)",
10387                      (int)len, name);
10388         }
10389     }
10390     id |= ++global_symbols.last_id << ID_SCOPE_SHIFT;
10391   id_register:
10392     return register_symid_str(id, str);
10393 }
10394 
10395 ID
10396 rb_intern2(const char *name, long len)
10397 {
10398     return rb_intern3(name, len, rb_usascii_encoding());
10399 }
10400 
10401 #undef rb_intern
10402 ID
10403 rb_intern(const char *name)
10404 {
10405     return rb_intern2(name, strlen(name));
10406 }
10407 
10408 ID
10409 rb_intern_str(VALUE str)
10410 {
10411     st_data_t id;
10412 
10413     if (st_lookup(global_symbols.sym_id, str, &id))
10414         return (ID)id;
10415     return intern_str(rb_str_dup(str));
10416 }
10417 
10418 VALUE
10419 rb_id2str(ID id)
10420 {
10421     st_data_t data;
10422 
10423     if (id < tLAST_TOKEN) {
10424         int i = 0;
10425 
10426         if (id < INT_MAX && rb_ispunct((int)id)) {
10427             VALUE str = global_symbols.op_sym[i = (int)id];
10428             if (!str) {
10429                 char name[2];
10430                 name[0] = (char)id;
10431                 name[1] = 0;
10432                 str = rb_usascii_str_new(name, 1);
10433                 OBJ_FREEZE(str);
10434                 global_symbols.op_sym[i] = str;
10435             }
10436             return str;
10437         }
10438         for (i = 0; i < op_tbl_count; i++) {
10439             if (op_tbl[i].token == id) {
10440                 VALUE str = global_symbols.op_sym[i];
10441                 if (!str) {
10442                     str = rb_usascii_str_new2(op_tbl[i].name);
10443                     OBJ_FREEZE(str);
10444                     global_symbols.op_sym[i] = str;
10445                 }
10446                 return str;
10447             }
10448         }
10449     }
10450 
10451     if (st_lookup(global_symbols.id_str, id, &data)) {
10452         VALUE str = (VALUE)data;
10453         if (RBASIC(str)->klass == 0)
10454             RBASIC(str)->klass = rb_cString;
10455         return str;
10456     }
10457 
10458     if (is_attrset_id(id)) {
10459         ID id_stem = (id & ~ID_SCOPE_MASK);
10460         VALUE str;
10461 
10462         do {
10463             if (!!(str = rb_id2str(id_stem | ID_LOCAL))) break;
10464             if (!!(str = rb_id2str(id_stem | ID_CONST))) break;
10465             if (!!(str = rb_id2str(id_stem | ID_INSTANCE))) break;
10466             if (!!(str = rb_id2str(id_stem | ID_GLOBAL))) break;
10467             if (!!(str = rb_id2str(id_stem | ID_CLASS))) break;
10468             if (!!(str = rb_id2str(id_stem | ID_JUNK))) break;
10469             return 0;
10470         } while (0);
10471         str = rb_str_dup(str);
10472         rb_str_cat(str, "=", 1);
10473         register_symid_str(id, str);
10474         if (st_lookup(global_symbols.id_str, id, &data)) {
10475             VALUE str = (VALUE)data;
10476             if (RBASIC(str)->klass == 0)
10477                 RBASIC(str)->klass = rb_cString;
10478             return str;
10479         }
10480     }
10481     return 0;
10482 }
10483 
10484 const char *
10485 rb_id2name(ID id)
10486 {
10487     VALUE str = rb_id2str(id);
10488 
10489     if (!str) return 0;
10490     return RSTRING_PTR(str);
10491 }
10492 
10493 static int
10494 symbols_i(VALUE sym, ID value, VALUE ary)
10495 {
10496     rb_ary_push(ary, ID2SYM(value));
10497     return ST_CONTINUE;
10498 }
10499 
10500 /*
10501  *  call-seq:
10502  *     Symbol.all_symbols    => array
10503  *
10504  *  Returns an array of all the symbols currently in Ruby's symbol
10505  *  table.
10506  *
10507  *     Symbol.all_symbols.size    #=> 903
10508  *     Symbol.all_symbols[1,20]   #=> [:floor, :ARGV, :Binding, :symlink,
10509  *                                     :chown, :EOFError, :$;, :String,
10510  *                                     :LOCK_SH, :"setuid?", :$<,
10511  *                                     :default_proc, :compact, :extend,
10512  *                                     :Tms, :getwd, :$=, :ThreadGroup,
10513  *                                     :wait2, :$>]
10514  */
10515 
10516 VALUE
10517 rb_sym_all_symbols(void)
10518 {
10519     VALUE ary = rb_ary_new2(global_symbols.sym_id->num_entries);
10520 
10521     st_foreach(global_symbols.sym_id, symbols_i, ary);
10522     return ary;
10523 }
10524 
10525 int
10526 rb_is_const_id(ID id)
10527 {
10528     return is_const_id(id);
10529 }
10530 
10531 int
10532 rb_is_class_id(ID id)
10533 {
10534     return is_class_id(id);
10535 }
10536 
10537 int
10538 rb_is_global_id(ID id)
10539 {
10540     return is_global_id(id);
10541 }
10542 
10543 int
10544 rb_is_instance_id(ID id)
10545 {
10546     return is_instance_id(id);
10547 }
10548 
10549 int
10550 rb_is_attrset_id(ID id)
10551 {
10552     return is_attrset_id(id);
10553 }
10554 
10555 int
10556 rb_is_local_id(ID id)
10557 {
10558     return is_local_id(id);
10559 }
10560 
10561 int
10562 rb_is_junk_id(ID id)
10563 {
10564     return is_junk_id(id);
10565 }
10566 
10578 ID
10579 rb_check_id(volatile VALUE *namep)
10580 {
10581     st_data_t id;
10582     VALUE tmp;
10583     VALUE name = *namep;
10584 
10585     if (SYMBOL_P(name)) {
10586         return SYM2ID(name);
10587     }
10588     else if (!RB_TYPE_P(name, T_STRING)) {
10589         tmp = rb_check_string_type(name);
10590         if (NIL_P(tmp)) {
10591             tmp = rb_inspect(name);
10592             rb_raise(rb_eTypeError, "%s is not a symbol",
10593                      RSTRING_PTR(tmp));
10594         }
10595         name = tmp;
10596         *namep = name;
10597     }
10598 
10599     sym_check_asciionly(name);
10600 
10601     if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10602         return (ID)id;
10603 
10604     if (rb_is_attrset_name(name)) {
10605         struct RString fake_str;
10606         const VALUE localname = (VALUE)&fake_str;
10607         /* make local name by chopping '=' */
10608         fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10609         fake_str.basic.klass = rb_cString;
10610         fake_str.as.heap.len = RSTRING_LEN(name) - 1;
10611         fake_str.as.heap.ptr = RSTRING_PTR(name);
10612         fake_str.as.heap.aux.capa = fake_str.as.heap.len;
10613         rb_enc_copy(localname, name);
10614         OBJ_FREEZE(localname);
10615 
10616         if (st_lookup(global_symbols.sym_id, (st_data_t)localname, &id)) {
10617             return rb_id_attrset((ID)id);
10618         }
10619         RB_GC_GUARD(name);
10620     }
10621 
10622     return (ID)0;
10623 }
10624 
10625 ID
10626 rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
10627 {
10628     st_data_t id;
10629     struct RString fake_str;
10630     const VALUE name = (VALUE)&fake_str;
10631     fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10632     fake_str.basic.klass = rb_cString;
10633     fake_str.as.heap.len = len;
10634     fake_str.as.heap.ptr = (char *)ptr;
10635     fake_str.as.heap.aux.capa = len;
10636     rb_enc_associate(name, enc);
10637 
10638     sym_check_asciionly(name);
10639 
10640     if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10641         return (ID)id;
10642 
10643     if (rb_is_attrset_name(name)) {
10644         fake_str.as.heap.len = len - 1;
10645         if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id)) {
10646             return rb_id_attrset((ID)id);
10647         }
10648     }
10649 
10650     return (ID)0;
10651 }
10652 
10653 int
10654 rb_is_const_name(VALUE name)
10655 {
10656     return rb_str_symname_type(name, 0) == ID_CONST;
10657 }
10658 
10659 int
10660 rb_is_class_name(VALUE name)
10661 {
10662     return rb_str_symname_type(name, 0) == ID_CLASS;
10663 }
10664 
10665 int
10666 rb_is_global_name(VALUE name)
10667 {
10668     return rb_str_symname_type(name, 0) == ID_GLOBAL;
10669 }
10670 
10671 int
10672 rb_is_instance_name(VALUE name)
10673 {
10674     return rb_str_symname_type(name, 0) == ID_INSTANCE;
10675 }
10676 
10677 int
10678 rb_is_attrset_name(VALUE name)
10679 {
10680     return rb_str_symname_type(name, IDSET_ATTRSET_FOR_INTERN) == ID_ATTRSET;
10681 }
10682 
10683 int
10684 rb_is_local_name(VALUE name)
10685 {
10686     return rb_str_symname_type(name, 0) == ID_LOCAL;
10687 }
10688 
10689 int
10690 rb_is_method_name(VALUE name)
10691 {
10692     switch (rb_str_symname_type(name, 0)) {
10693       case ID_LOCAL: case ID_ATTRSET: case ID_JUNK:
10694         return TRUE;
10695     }
10696     return FALSE;
10697 }
10698 
10699 int
10700 rb_is_junk_name(VALUE name)
10701 {
10702     return rb_str_symname_type(name, IDSET_ATTRSET_FOR_SYNTAX) == -1;
10703 }
10704 
10705 #endif /* !RIPPER */
10706 
10707 static void
10708 parser_initialize(struct parser_params *parser)
10709 {
10710     parser->eofp = Qfalse;
10711 
10712     parser->parser_lex_strterm = 0;
10713     parser->parser_cond_stack = 0;
10714     parser->parser_cmdarg_stack = 0;
10715     parser->parser_class_nest = 0;
10716     parser->parser_paren_nest = 0;
10717     parser->parser_lpar_beg = 0;
10718     parser->parser_brace_nest = 0;
10719     parser->parser_in_single = 0;
10720     parser->parser_in_def = 0;
10721     parser->parser_in_defined = 0;
10722     parser->parser_compile_for_eval = 0;
10723     parser->parser_cur_mid = 0;
10724     parser->parser_tokenbuf = NULL;
10725     parser->parser_tokidx = 0;
10726     parser->parser_toksiz = 0;
10727     parser->parser_heredoc_end = 0;
10728     parser->parser_command_start = TRUE;
10729     parser->parser_deferred_nodes = 0;
10730     parser->parser_lex_pbeg = 0;
10731     parser->parser_lex_p = 0;
10732     parser->parser_lex_pend = 0;
10733     parser->parser_lvtbl = 0;
10734     parser->parser_ruby__end__seen = 0;
10735     parser->parser_ruby_sourcefile = 0;
10736     parser->parser_ruby_sourcefile_string = Qnil;
10737 #ifndef RIPPER
10738     parser->is_ripper = 0;
10739     parser->parser_eval_tree_begin = 0;
10740     parser->parser_eval_tree = 0;
10741 #else
10742     parser->is_ripper = 1;
10743     parser->delayed = Qnil;
10744 
10745     parser->result = Qnil;
10746     parser->parsing_thread = Qnil;
10747     parser->toplevel_p = TRUE;
10748 #endif
10749 #ifdef YYMALLOC
10750     parser->heap = NULL;
10751 #endif
10752     parser->enc = rb_utf8_encoding();
10753 }
10754 
10755 #ifdef RIPPER
10756 #define parser_mark ripper_parser_mark
10757 #define parser_free ripper_parser_free
10758 #endif
10759 
10760 static void
10761 parser_mark(void *ptr)
10762 {
10763     struct parser_params *p = (struct parser_params*)ptr;
10764 
10765     rb_gc_mark((VALUE)p->parser_lex_strterm);
10766     rb_gc_mark((VALUE)p->parser_deferred_nodes);
10767     rb_gc_mark(p->parser_lex_input);
10768     rb_gc_mark(p->parser_lex_lastline);
10769     rb_gc_mark(p->parser_lex_nextline);
10770     rb_gc_mark(p->parser_ruby_sourcefile_string);
10771 #ifndef RIPPER
10772     rb_gc_mark((VALUE)p->parser_eval_tree_begin) ;
10773     rb_gc_mark((VALUE)p->parser_eval_tree) ;
10774     rb_gc_mark(p->debug_lines);
10775 #else
10776     rb_gc_mark(p->delayed);
10777     rb_gc_mark(p->value);
10778     rb_gc_mark(p->result);
10779     rb_gc_mark(p->parsing_thread);
10780 #endif
10781 #ifdef YYMALLOC
10782     rb_gc_mark((VALUE)p->heap);
10783 #endif
10784 }
10785 
10786 static void
10787 parser_free(void *ptr)
10788 {
10789     struct parser_params *p = (struct parser_params*)ptr;
10790     struct local_vars *local, *prev;
10791 
10792     if (p->parser_tokenbuf) {
10793         xfree(p->parser_tokenbuf);
10794     }
10795     for (local = p->parser_lvtbl; local; local = prev) {
10796         if (local->vars) xfree(local->vars);
10797         prev = local->prev;
10798         xfree(local);
10799     }
10800     xfree(p);
10801 }
10802 
10803 static size_t
10804 parser_memsize(const void *ptr)
10805 {
10806     struct parser_params *p = (struct parser_params*)ptr;
10807     struct local_vars *local;
10808     size_t size = sizeof(*p);
10809 
10810     if (!ptr) return 0;
10811     size += p->parser_toksiz;
10812     for (local = p->parser_lvtbl; local; local = local->prev) {
10813         size += sizeof(*local);
10814         if (local->vars) size += local->vars->capa * sizeof(ID);
10815     }
10816     return size;
10817 }
10818 
10819 static
10820 #ifndef RIPPER
10821 const
10822 #endif
10823 rb_data_type_t parser_data_type = {
10824     "parser",
10825     {
10826         parser_mark,
10827         parser_free,
10828         parser_memsize,
10829     },
10830 };
10831 
10832 #ifndef RIPPER
10833 #undef rb_reserved_word
10834 
10835 const struct kwtable *
10836 rb_reserved_word(const char *str, unsigned int len)
10837 {
10838     return reserved_word(str, len);
10839 }
10840 
10841 static struct parser_params *
10842 parser_new(void)
10843 {
10844     struct parser_params *p;
10845 
10846     p = ALLOC_N(struct parser_params, 1);
10847     MEMZERO(p, struct parser_params, 1);
10848     parser_initialize(p);
10849     return p;
10850 }
10851 
10852 VALUE
10853 rb_parser_new(void)
10854 {
10855     struct parser_params *p = parser_new();
10856 
10857     return TypedData_Wrap_Struct(0, &parser_data_type, p);
10858 }
10859 
10860 /*
10861  *  call-seq:
10862  *    ripper#end_seen?   -> Boolean
10863  *
10864  *  Return true if parsed source ended by +\_\_END\_\_+.
10865  */
10866 VALUE
10867 rb_parser_end_seen_p(VALUE vparser)
10868 {
10869     struct parser_params *parser;
10870 
10871     TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10872     return ruby__end__seen ? Qtrue : Qfalse;
10873 }
10874 
10875 /*
10876  *  call-seq:
10877  *    ripper#encoding   -> encoding
10878  *
10879  *  Return encoding of the source.
10880  */
10881 VALUE
10882 rb_parser_encoding(VALUE vparser)
10883 {
10884     struct parser_params *parser;
10885 
10886     TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10887     return rb_enc_from_encoding(current_enc);
10888 }
10889 
10890 /*
10891  *  call-seq:
10892  *    ripper.yydebug   -> true or false
10893  *
10894  *  Get yydebug.
10895  */
10896 VALUE
10897 rb_parser_get_yydebug(VALUE self)
10898 {
10899     struct parser_params *parser;
10900 
10901     TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10902     return yydebug ? Qtrue : Qfalse;
10903 }
10904 
10905 /*
10906  *  call-seq:
10907  *    ripper.yydebug = flag
10908  *
10909  *  Set yydebug.
10910  */
10911 VALUE
10912 rb_parser_set_yydebug(VALUE self, VALUE flag)
10913 {
10914     struct parser_params *parser;
10915 
10916     TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10917     yydebug = RTEST(flag);
10918     return flag;
10919 }
10920 
10921 #ifdef YYMALLOC
10922 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
10923 #define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
10924 #define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
10925                            (n)->u3.cnt = (c), (p))
10926 
10927 void *
10928 rb_parser_malloc(struct parser_params *parser, size_t size)
10929 {
10930     size_t cnt = HEAPCNT(1, size);
10931     NODE *n = NEWHEAP();
10932     void *ptr = xmalloc(size);
10933 
10934     return ADD2HEAP(n, cnt, ptr);
10935 }
10936 
10937 void *
10938 rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
10939 {
10940     size_t cnt = HEAPCNT(nelem, size);
10941     NODE *n = NEWHEAP();
10942     void *ptr = xcalloc(nelem, size);
10943 
10944     return ADD2HEAP(n, cnt, ptr);
10945 }
10946 
10947 void *
10948 rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
10949 {
10950     NODE *n;
10951     size_t cnt = HEAPCNT(1, size);
10952 
10953     if (ptr && (n = parser->heap) != NULL) {
10954         do {
10955             if (n->u1.node == ptr) {
10956                 n->u1.node = ptr = xrealloc(ptr, size);
10957                 if (n->u3.cnt) n->u3.cnt = cnt;
10958                 return ptr;
10959             }
10960         } while ((n = n->u2.node) != NULL);
10961     }
10962     n = NEWHEAP();
10963     ptr = xrealloc(ptr, size);
10964     return ADD2HEAP(n, cnt, ptr);
10965 }
10966 
10967 void
10968 rb_parser_free(struct parser_params *parser, void *ptr)
10969 {
10970     NODE **prev = &parser->heap, *n;
10971 
10972     while ((n = *prev) != NULL) {
10973         if (n->u1.node == ptr) {
10974             *prev = n->u2.node;
10975             rb_gc_force_recycle((VALUE)n);
10976             break;
10977         }
10978         prev = &n->u2.node;
10979     }
10980     xfree(ptr);
10981 }
10982 #endif
10983 #endif
10984 
10985 #ifdef RIPPER
10986 #ifdef RIPPER_DEBUG
10987 extern int rb_is_pointer_to_heap(VALUE);
10988 
10989 /* :nodoc: */
10990 static VALUE
10991 ripper_validate_object(VALUE self, VALUE x)
10992 {
10993     if (x == Qfalse) return x;
10994     if (x == Qtrue) return x;
10995     if (x == Qnil) return x;
10996     if (x == Qundef)
10997         rb_raise(rb_eArgError, "Qundef given");
10998     if (FIXNUM_P(x)) return x;
10999     if (SYMBOL_P(x)) return x;
11000     if (!rb_is_pointer_to_heap(x))
11001         rb_raise(rb_eArgError, "invalid pointer: %p", x);
11002     switch (TYPE(x)) {
11003       case T_STRING:
11004       case T_OBJECT:
11005       case T_ARRAY:
11006       case T_BIGNUM:
11007       case T_FLOAT:
11008         return x;
11009       case T_NODE:
11010         if (nd_type(x) != NODE_LASGN) {
11011             rb_raise(rb_eArgError, "NODE given: %p", x);
11012         }
11013         return ((NODE *)x)->nd_rval;
11014       default:
11015         rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
11016                  x, rb_obj_classname(x));
11017     }
11018     return x;
11019 }
11020 #endif
11021 
11022 #define validate(x) ((x) = get_value(x))
11023 
11024 static VALUE
11025 ripper_dispatch0(struct parser_params *parser, ID mid)
11026 {
11027     return rb_funcall(parser->value, mid, 0);
11028 }
11029 
11030 static VALUE
11031 ripper_dispatch1(struct parser_params *parser, ID mid, VALUE a)
11032 {
11033     validate(a);
11034     return rb_funcall(parser->value, mid, 1, a);
11035 }
11036 
11037 static VALUE
11038 ripper_dispatch2(struct parser_params *parser, ID mid, VALUE a, VALUE b)
11039 {
11040     validate(a);
11041     validate(b);
11042     return rb_funcall(parser->value, mid, 2, a, b);
11043 }
11044 
11045 static VALUE
11046 ripper_dispatch3(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c)
11047 {
11048     validate(a);
11049     validate(b);
11050     validate(c);
11051     return rb_funcall(parser->value, mid, 3, a, b, c);
11052 }
11053 
11054 static VALUE
11055 ripper_dispatch4(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d)
11056 {
11057     validate(a);
11058     validate(b);
11059     validate(c);
11060     validate(d);
11061     return rb_funcall(parser->value, mid, 4, a, b, c, d);
11062 }
11063 
11064 static VALUE
11065 ripper_dispatch5(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e)
11066 {
11067     validate(a);
11068     validate(b);
11069     validate(c);
11070     validate(d);
11071     validate(e);
11072     return rb_funcall(parser->value, mid, 5, a, b, c, d, e);
11073 }
11074 
11075 static VALUE
11076 ripper_dispatch7(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g)
11077 {
11078     validate(a);
11079     validate(b);
11080     validate(c);
11081     validate(d);
11082     validate(e);
11083     validate(f);
11084     validate(g);
11085     return rb_funcall(parser->value, mid, 7, a, b, c, d, e, f, g);
11086 }
11087 
11088 static const struct kw_assoc {
11089     ID id;
11090     const char *name;
11091 } keyword_to_name[] = {
11092     {keyword_class,     "class"},
11093     {keyword_module,    "module"},
11094     {keyword_def,       "def"},
11095     {keyword_undef,     "undef"},
11096     {keyword_begin,     "begin"},
11097     {keyword_rescue,    "rescue"},
11098     {keyword_ensure,    "ensure"},
11099     {keyword_end,       "end"},
11100     {keyword_if,        "if"},
11101     {keyword_unless,    "unless"},
11102     {keyword_then,      "then"},
11103     {keyword_elsif,     "elsif"},
11104     {keyword_else,      "else"},
11105     {keyword_case,      "case"},
11106     {keyword_when,      "when"},
11107     {keyword_while,     "while"},
11108     {keyword_until,     "until"},
11109     {keyword_for,       "for"},
11110     {keyword_break,     "break"},
11111     {keyword_next,      "next"},
11112     {keyword_redo,      "redo"},
11113     {keyword_retry,     "retry"},
11114     {keyword_in,        "in"},
11115     {keyword_do,        "do"},
11116     {keyword_do_cond,   "do"},
11117     {keyword_do_block,  "do"},
11118     {keyword_return,    "return"},
11119     {keyword_yield,     "yield"},
11120     {keyword_super,     "super"},
11121     {keyword_self,      "self"},
11122     {keyword_nil,       "nil"},
11123     {keyword_true,      "true"},
11124     {keyword_false,     "false"},
11125     {keyword_and,       "and"},
11126     {keyword_or,        "or"},
11127     {keyword_not,       "not"},
11128     {modifier_if,       "if"},
11129     {modifier_unless,   "unless"},
11130     {modifier_while,    "while"},
11131     {modifier_until,    "until"},
11132     {modifier_rescue,   "rescue"},
11133     {keyword_alias,     "alias"},
11134     {keyword_defined,   "defined?"},
11135     {keyword_BEGIN,     "BEGIN"},
11136     {keyword_END,       "END"},
11137     {keyword__LINE__,   "__LINE__"},
11138     {keyword__FILE__,   "__FILE__"},
11139     {keyword__ENCODING__, "__ENCODING__"},
11140     {0, NULL}
11141 };
11142 
11143 static const char*
11144 keyword_id_to_str(ID id)
11145 {
11146     const struct kw_assoc *a;
11147 
11148     for (a = keyword_to_name; a->id; a++) {
11149         if (a->id == id)
11150             return a->name;
11151     }
11152     return NULL;
11153 }
11154 
11155 #undef ripper_id2sym
11156 static VALUE
11157 ripper_id2sym(ID id)
11158 {
11159     const char *name;
11160     char buf[8];
11161 
11162     if (id <= 256) {
11163         buf[0] = (char)id;
11164         buf[1] = '\0';
11165         return ID2SYM(rb_intern2(buf, 1));
11166     }
11167     if ((name = keyword_id_to_str(id))) {
11168         return ID2SYM(rb_intern(name));
11169     }
11170     switch (id) {
11171       case tOROP:
11172         name = "||";
11173         break;
11174       case tANDOP:
11175         name = "&&";
11176         break;
11177       default:
11178         name = rb_id2name(id);
11179         if (!name) {
11180             rb_bug("cannot convert ID to string: %ld", (unsigned long)id);
11181         }
11182         return ID2SYM(id);
11183     }
11184     return ID2SYM(rb_intern(name));
11185 }
11186 
11187 static ID
11188 ripper_get_id(VALUE v)
11189 {
11190     NODE *nd;
11191     if (!RB_TYPE_P(v, T_NODE)) return 0;
11192     nd = (NODE *)v;
11193     if (nd_type(nd) != NODE_LASGN) return 0;
11194     return nd->nd_vid;
11195 }
11196 
11197 static VALUE
11198 ripper_get_value(VALUE v)
11199 {
11200     NODE *nd;
11201     if (v == Qundef) return Qnil;
11202     if (!RB_TYPE_P(v, T_NODE)) return v;
11203     nd = (NODE *)v;
11204     if (nd_type(nd) != NODE_LASGN) return Qnil;
11205     return nd->nd_rval;
11206 }
11207 
11208 static void
11209 ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
11210 {
11211     VALUE str;
11212     va_list args;
11213 
11214     va_start(args, fmt);
11215     str = rb_vsprintf(fmt, args);
11216     va_end(args);
11217     rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
11218 }
11219 
11220 static void
11221 ripper_warn0(struct parser_params *parser, const char *fmt)
11222 {
11223     rb_funcall(parser->value, rb_intern("warn"), 1, STR_NEW2(fmt));
11224 }
11225 
11226 static void
11227 ripper_warnI(struct parser_params *parser, const char *fmt, int a)
11228 {
11229     rb_funcall(parser->value, rb_intern("warn"), 2,
11230                STR_NEW2(fmt), INT2NUM(a));
11231 }
11232 
11233 static void
11234 ripper_warnS(struct parser_params *parser, const char *fmt, const char *str)
11235 {
11236     rb_funcall(parser->value, rb_intern("warn"), 2,
11237                STR_NEW2(fmt), STR_NEW2(str));
11238 }
11239 
11240 static void
11241 ripper_warning0(struct parser_params *parser, const char *fmt)
11242 {
11243     rb_funcall(parser->value, rb_intern("warning"), 1, STR_NEW2(fmt));
11244 }
11245 
11246 static void
11247 ripper_warningS(struct parser_params *parser, const char *fmt, const char *str)
11248 {
11249     rb_funcall(parser->value, rb_intern("warning"), 2,
11250                STR_NEW2(fmt), STR_NEW2(str));
11251 }
11252 
11253 static VALUE
11254 ripper_lex_get_generic(struct parser_params *parser, VALUE src)
11255 {
11256     return rb_io_gets(src);
11257 }
11258 
11259 static VALUE
11260 ripper_s_allocate(VALUE klass)
11261 {
11262     struct parser_params *p;
11263     VALUE self;
11264 
11265     p = ALLOC_N(struct parser_params, 1);
11266     MEMZERO(p, struct parser_params, 1);
11267     self = TypedData_Wrap_Struct(klass, &parser_data_type, p);
11268     p->value = self;
11269     return self;
11270 }
11271 
11272 #define ripper_initialized_p(r) ((r)->parser_lex_input != 0)
11273 
11274 /*
11275  *  call-seq:
11276  *    Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
11277  *
11278  *  Create a new Ripper object.
11279  *  _src_ must be a String, an IO, or an Object which has #gets method.
11280  *
11281  *  This method does not starts parsing.
11282  *  See also Ripper#parse and Ripper.parse.
11283  */
11284 static VALUE
11285 ripper_initialize(int argc, VALUE *argv, VALUE self)
11286 {
11287     struct parser_params *parser;
11288     VALUE src, fname, lineno;
11289 
11290     TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11291     rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
11292     if (RB_TYPE_P(src, T_FILE)) {
11293         parser->parser_lex_gets = ripper_lex_get_generic;
11294     }
11295     else {
11296         StringValue(src);
11297         parser->parser_lex_gets = lex_get_str;
11298     }
11299     parser->parser_lex_input = src;
11300     parser->eofp = Qfalse;
11301     if (NIL_P(fname)) {
11302         fname = STR_NEW2("(ripper)");
11303     }
11304     else {
11305         StringValue(fname);
11306     }
11307     parser_initialize(parser);
11308 
11309     parser->parser_ruby_sourcefile_string = fname;
11310     parser->parser_ruby_sourcefile = RSTRING_PTR(fname);
11311     parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
11312 
11313     return Qnil;
11314 }
11315 
11316 struct ripper_args {
11317     struct parser_params *parser;
11318     int argc;
11319     VALUE *argv;
11320 };
11321 
11322 static VALUE
11323 ripper_parse0(VALUE parser_v)
11324 {
11325     struct parser_params *parser;
11326 
11327     TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11328     parser_prepare(parser);
11329     ripper_yyparse((void*)parser);
11330     return parser->result;
11331 }
11332 
11333 static VALUE
11334 ripper_ensure(VALUE parser_v)
11335 {
11336     struct parser_params *parser;
11337 
11338     TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11339     parser->parsing_thread = Qnil;
11340     return Qnil;
11341 }
11342 
11343 /*
11344  *  call-seq:
11345  *    ripper#parse
11346  *
11347  *  Start parsing and returns the value of the root action.
11348  */
11349 static VALUE
11350 ripper_parse(VALUE self)
11351 {
11352     struct parser_params *parser;
11353 
11354     TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11355     if (!ripper_initialized_p(parser)) {
11356         rb_raise(rb_eArgError, "method called for uninitialized object");
11357     }
11358     if (!NIL_P(parser->parsing_thread)) {
11359         if (parser->parsing_thread == rb_thread_current())
11360             rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
11361         else
11362             rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
11363     }
11364     parser->parsing_thread = rb_thread_current();
11365     rb_ensure(ripper_parse0, self, ripper_ensure, self);
11366 
11367     return parser->result;
11368 }
11369 
11370 /*
11371  *  call-seq:
11372  *    ripper#column   -> Integer
11373  *
11374  *  Return column number of current parsing line.
11375  *  This number starts from 0.
11376  */
11377 static VALUE
11378 ripper_column(VALUE self)
11379 {
11380     struct parser_params *parser;
11381     long col;
11382 
11383     TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11384     if (!ripper_initialized_p(parser)) {
11385         rb_raise(rb_eArgError, "method called for uninitialized object");
11386     }
11387     if (NIL_P(parser->parsing_thread)) return Qnil;
11388     col = parser->tokp - parser->parser_lex_pbeg;
11389     return LONG2NUM(col);
11390 }
11391 
11392 /*
11393  *  call-seq:
11394  *    ripper#filename   -> String
11395  *
11396  *  Return current parsing filename.
11397  */
11398 static VALUE
11399 ripper_filename(VALUE self)
11400 {
11401     struct parser_params *parser;
11402 
11403     TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11404     if (!ripper_initialized_p(parser)) {
11405         rb_raise(rb_eArgError, "method called for uninitialized object");
11406     }
11407     return parser->parser_ruby_sourcefile_string;
11408 }
11409 
11410 /*
11411  *  call-seq:
11412  *    ripper#lineno   -> Integer
11413  *
11414  *  Return line number of current parsing line.
11415  *  This number starts from 1.
11416  */
11417 static VALUE
11418 ripper_lineno(VALUE self)
11419 {
11420     struct parser_params *parser;
11421 
11422     TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11423     if (!ripper_initialized_p(parser)) {
11424         rb_raise(rb_eArgError, "method called for uninitialized object");
11425     }
11426     if (NIL_P(parser->parsing_thread)) return Qnil;
11427     return INT2NUM(parser->parser_ruby_sourceline);
11428 }
11429 
11430 #ifdef RIPPER_DEBUG
11431 /* :nodoc: */
11432 static VALUE
11433 ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
11434 {
11435     StringValue(msg);
11436     if (obj == Qundef) {
11437         rb_raise(rb_eArgError, "%s", RSTRING_PTR(msg));
11438     }
11439     return Qnil;
11440 }
11441 
11442 /* :nodoc: */
11443 static VALUE
11444 ripper_value(VALUE self, VALUE obj)
11445 {
11446     return ULONG2NUM(obj);
11447 }
11448 #endif
11449 
11450 
11451 void
11452 Init_ripper(void)
11453 {
11454     parser_data_type.parent = RTYPEDDATA_TYPE(rb_parser_new());
11455 
11456     ripper_init_eventids1();
11457     ripper_init_eventids2();
11458     /* ensure existing in symbol table */
11459     (void)rb_intern("||");
11460     (void)rb_intern("&&");
11461 
11462     InitVM(ripper);
11463 }
11464 
11465 void
11466 InitVM_ripper(void)
11467 {
11468     VALUE Ripper;
11469 
11470     Ripper = rb_define_class("Ripper", rb_cObject);
11471     rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
11472     rb_define_alloc_func(Ripper, ripper_s_allocate);
11473     rb_define_method(Ripper, "initialize", ripper_initialize, -1);
11474     rb_define_method(Ripper, "parse", ripper_parse, 0);
11475     rb_define_method(Ripper, "column", ripper_column, 0);
11476     rb_define_method(Ripper, "filename", ripper_filename, 0);
11477     rb_define_method(Ripper, "lineno", ripper_lineno, 0);
11478     rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
11479     rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
11480     rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
11481     rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
11482 #ifdef RIPPER_DEBUG
11483     rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
11484     rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
11485     rb_define_method(rb_mKernel, "validate_object", ripper_validate_object, 1);
11486 #endif
11487 
11488     ripper_init_eventids1_table(Ripper);
11489     ripper_init_eventids2_table(Ripper);
11490 
11491 # if 0
11492     /* Hack to let RDoc document SCRIPT_LINES__ */
11493 
11494     /*
11495      * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
11496      * after the assignment will be added as an Array of lines with the file
11497      * name as the key.
11498      */
11499     rb_define_global_const("SCRIPT_LINES__", Qnil);
11500 #endif
11501 
11502 }
11503 #endif /* RIPPER */
11504