1 /**********************************************************************
6 created at: Fri May 28 18:02:42 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
10 **********************************************************************/
15 #define YYERROR_VERBOSE 1
16 #define YYSTACK_USE_ALLOCA 0
18 #include "ruby/ruby.h"
19 #include "ruby/intern.h"
20 #include "ruby/node.h"
22 #include "ruby/encoding.h"
29 #define YYMALLOC(size) rb_parser_malloc(parser, size)
30 #define YYREALLOC(ptr, size) rb_parser_realloc(parser, ptr, size)
31 #define YYCALLOC(nelem, size) rb_parser_calloc(parser, nelem, size)
32 #define YYFREE(ptr) rb_parser_free(parser, ptr)
33 #define malloc YYMALLOC
34 #define realloc YYREALLOC
35 #define calloc YYCALLOC
38 #define ID_SCOPE_SHIFT 3
39 #define ID_SCOPE_MASK 0x07
41 #define ID_INSTANCE 0x01
42 #define ID_GLOBAL 0x03
43 #define ID_ATTRSET 0x04
47 #define ID_INTERNAL ID_JUNK
49 #define is_notop_id(id) ((id)>tLAST_TOKEN)
50 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
51 #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
52 #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
53 #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
54 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
55 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
56 #define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
58 #define is_asgn_or_id(id) ((is_notop_id(id)) && \
59 (((id
)&ID_SCOPE_MASK
) == ID_GLOBAL || \
60 ((id
)&ID_SCOPE_MASK
) == ID_INSTANCE || \
61 ((id
)&ID_SCOPE_MASK
) == ID_CLASS
))
64 EXPR_BEG
, /* ignore newline, +/- is a sign. */
65 EXPR_END
, /* newline significant, +/- is a operator. */
66 EXPR_ENDARG
, /* ditto, and unbound braces. */
67 EXPR_ARG
, /* newline significant, +/- is a operator. */
68 EXPR_CMDARG
, /* newline significant, +/- is a operator. */
69 EXPR_MID
, /* newline significant, +/- is a operator. */
70 EXPR_FNAME
, /* ignore newline, no reserved words. */
71 EXPR_DOT
, /* right after `.' or `::', no reserved words. */
72 EXPR_CLASS
, /* immediate after `class', no here document. */
73 EXPR_VALUE
/* alike EXPR_BEG but label is disallowed. */
76 # ifdef HAVE_LONG_LONG
77 typedef
unsigned LONG_LONG stack_type
;
79 typedef
unsigned long stack_type
;
82 # define BITSTACK_PUSH(stack, n) (stack = (stack<<1)|((n)&1))
83 # define BITSTACK_POP(stack) (stack = stack >> 1)
84 # define BITSTACK_LEXPOP(stack) (stack = (stack >> 1) | (stack & 1))
85 # define BITSTACK_SET_P(stack) (stack&1)
87 #define COND_PUSH(n) BITSTACK_PUSH(cond_stack, n)
88 #define COND_POP() BITSTACK_POP(cond_stack)
89 #define COND_LEXPOP() BITSTACK_LEXPOP(cond_stack)
90 #define COND_P() BITSTACK_SET_P(cond_stack)
92 #define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, n)
93 #define CMDARG_POP() BITSTACK_POP(cmdarg_stack)
94 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
95 #define CMDARG_P() BITSTACK_SET_P(cmdarg_stack)
97 /* must sync with real YYSTYPE */
103 struct RVarmap
*vars
;
116 struct local_vars
*prev
;
119 #define DVARS_INHERIT ((void*)1)
120 #define DVARS_TOPSCOPE NULL
121 #define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
122 #define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
126 vtable_size
(const struct vtable
*tbl
)
128 if
(POINTER_P
(tbl
)) {
138 static struct vtable
*
139 vtable_alloc
(struct vtable
*prev
)
141 struct vtable
*tbl
= ALLOC
(struct vtable
);
144 tbl
->tbl
= ALLOC_N
(ID
, tbl
->capa
);
146 if
(VTBL_DEBUG
) printf
("vtable_alloc: %p\n", tbl
);
151 vtable_free
(struct vtable
*tbl
)
153 if
(VTBL_DEBUG
)printf
("vtable_free: %p\n", tbl
);
154 if
(POINTER_P
(tbl
)) {
163 vtable_add
(struct vtable
*tbl
, ID id
)
165 if
(!POINTER_P
(tbl
)) {
166 rb_bug
("vtable_add: vtable is not allocated (%p)", tbl
);
168 if
(VTBL_DEBUG
) printf
("vtable_add: %p, %s\n", tbl
, rb_id2name
(id
));
170 if
(tbl
->pos
== tbl
->capa
) {
171 tbl
->capa
= tbl
->capa
* 2;
172 REALLOC_N
(tbl
->tbl
, ID
, tbl
->capa
);
174 tbl
->tbl
[tbl
->pos
++] = id
;
178 vtable_included
(const struct vtable
* tbl
, ID id
)
182 if
(POINTER_P
(tbl
)) {
183 for
(i
= 0; i
< tbl
->pos
; i
++) {
184 if
(tbl
->tbl
[i
] == id
) {
194 Structure of Lexer Buffer:
196 lex_pbeg tokp lex_p lex_pend
198 |-----------+--------------+------------|
202 struct parser_params
{
206 union tmpyystype
*parser_yylval
; /* YYSTYPE not defined yet */
209 NODE
*parser_lex_strterm
;
210 enum lex_state_e parser_lex_state
;
211 stack_type parser_cond_stack
;
212 stack_type parser_cmdarg_stack
;
213 int parser_class_nest
;
214 int parser_paren_nest
;
216 int parser_in_single
;
218 int parser_compile_for_eval
;
219 VALUE parser_cur_mid
;
220 int parser_in_defined
;
221 char *parser_tokenbuf
;
224 VALUE parser_lex_input
;
225 VALUE parser_lex_lastline
;
226 VALUE parser_lex_nextline
;
227 const char *parser_lex_pbeg
;
228 const char *parser_lex_p
;
229 const char *parser_lex_pend
;
230 int parser_heredoc_end
;
231 int parser_command_start
;
232 NODE
*parser_deferred_nodes
;
233 int parser_lex_gets_ptr
;
234 VALUE
(*parser_lex_gets
)(struct parser_params
*,VALUE
);
235 struct local_vars
*parser_lvtbl
;
236 int parser_ruby__end__seen
;
239 char *parser_ruby_sourcefile
; /* current source file */
240 int parser_ruby_sourceline
; /* current line no. */
248 NODE
*parser_eval_tree_begin
;
249 NODE
*parser_eval_tree
;
255 VALUE parser_ruby_sourcefile_string
;
263 VALUE parsing_thread
;
268 #define UTF8_ENC() (parser->utf8 ? parser->utf8 : \
269 (parser
->utf8
= rb_utf8_encoding
()))
270 #define STR_NEW(p,n) rb_enc_str_new((p),(n),parser->enc)
271 #define STR_NEW0() rb_usascii_str_new(0,0)
272 #define STR_NEW2(p) rb_enc_str_new((p),strlen(p),parser->enc)
273 #define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),parser->enc)
274 #define STR_ENC(m) ((m)?parser->enc:rb_usascii_encoding())
275 #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT)
276 #define TOK_INTERN(mb) rb_intern3(tok(), toklen(), STR_ENC(mb))
279 void *rb_parser_malloc
(struct parser_params
*, size_t);
280 void *rb_parser_realloc
(struct parser_params
*, void *, size_t);
281 void *rb_parser_calloc
(struct parser_params
*, size_t, size_t);
282 void rb_parser_free
(struct parser_params
*, void *);
285 static int parser_yyerror
(struct parser_params
*, const char*);
286 #define yyerror(msg) parser_yyerror(parser, msg)
288 #define YYLEX_PARAM parser
290 #define lex_strterm (parser->parser_lex_strterm)
291 #define lex_state (parser->parser_lex_state)
292 #define cond_stack (parser->parser_cond_stack)
293 #define cmdarg_stack (parser->parser_cmdarg_stack)
294 #define class_nest (parser->parser_class_nest)
295 #define paren_nest (parser->parser_paren_nest)
296 #define lpar_beg (parser->parser_lpar_beg)
297 #define in_single (parser->parser_in_single)
298 #define in_def (parser->parser_in_def)
299 #define compile_for_eval (parser->parser_compile_for_eval)
300 #define cur_mid (parser->parser_cur_mid)
301 #define in_defined (parser->parser_in_defined)
302 #define tokenbuf (parser->parser_tokenbuf)
303 #define tokidx (parser->parser_tokidx)
304 #define toksiz (parser->parser_toksiz)
305 #define lex_input (parser->parser_lex_input)
306 #define lex_lastline (parser->parser_lex_lastline)
307 #define lex_nextline (parser->parser_lex_nextline)
308 #define lex_pbeg (parser->parser_lex_pbeg)
309 #define lex_p (parser->parser_lex_p)
310 #define lex_pend (parser->parser_lex_pend)
311 #define heredoc_end (parser->parser_heredoc_end)
312 #define command_start (parser->parser_command_start)
313 #define deferred_nodes (parser->parser_deferred_nodes)
314 #define lex_gets_ptr (parser->parser_lex_gets_ptr)
315 #define lex_gets (parser->parser_lex_gets)
316 #define lvtbl (parser->parser_lvtbl)
317 #define ruby__end__seen (parser->parser_ruby__end__seen)
318 #define ruby_sourceline (parser->parser_ruby_sourceline)
319 #define ruby_sourcefile (parser->parser_ruby_sourcefile)
320 #define yydebug (parser->parser_yydebug)
323 #define ruby_eval_tree (parser->parser_eval_tree)
324 #define ruby_eval_tree_begin (parser->parser_eval_tree_begin)
325 #define ruby_debug_lines (parser->debug_lines)
326 #define ruby_coverage (parser->coverage)
329 static int yylex(void*, void*);
332 #define yyparse ruby_yyparse
334 static NODE
* node_newnode
(struct parser_params
*, enum node_type
, VALUE
, VALUE
, VALUE
);
335 #define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, type, a1, a2, a3)
337 static NODE
*cond_gen
(struct parser_params
*,NODE
*);
338 #define cond(node) cond_gen(parser, node)
339 static NODE
*logop_gen
(struct parser_params
*,enum node_type
,NODE
*,NODE
*);
340 #define logop(type,node1,node2) logop_gen(parser, type, node1, node2)
342 static NODE
*newline_node
(NODE
*);
343 static void fixpos
(NODE
*,NODE
*);
345 static int value_expr_gen
(struct parser_params
*,NODE
*);
346 static void void_expr_gen
(struct parser_params
*,NODE
*);
347 static NODE
*remove_begin
(NODE
*);
348 #define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
349 #define void_expr0(node) void_expr_gen(parser, (node))
350 #define void_expr(node) void_expr0((node) = remove_begin(node))
351 static void void_stmts_gen
(struct parser_params
*,NODE
*);
352 #define void_stmts(node) void_stmts_gen(parser, node)
353 static void reduce_nodes_gen
(struct parser_params
*,NODE
**);
354 #define reduce_nodes(n) reduce_nodes_gen(parser,n)
355 static void block_dup_check_gen
(struct parser_params
*,NODE
*,NODE
*);
356 #define block_dup_check(n1,n2) block_dup_check_gen(parser,n1,n2)
358 static NODE
*block_append_gen
(struct parser_params
*,NODE
*,NODE
*);
359 #define block_append(h,t) block_append_gen(parser,h,t)
360 static NODE
*list_append_gen
(struct parser_params
*,NODE
*,NODE
*);
361 #define list_append(l,i) list_append_gen(parser,l,i)
362 static NODE
*list_concat_gen
(struct parser_params
*,NODE
*,NODE
*);
363 #define list_concat(h,t) list_concat_gen(parser,h,t)
364 static NODE
*arg_append_gen
(struct parser_params
*,NODE
*,NODE
*);
365 #define arg_append(h,t) arg_append_gen(parser,h,t)
366 static NODE
*arg_concat_gen
(struct parser_params
*,NODE
*,NODE
*);
367 #define arg_concat(h,t) arg_concat_gen(parser,h,t)
368 static NODE
*literal_concat_gen
(struct parser_params
*,NODE
*,NODE
*);
369 #define literal_concat(h,t) literal_concat_gen(parser,h,t)
370 static NODE
*new_evstr_gen
(struct parser_params
*,NODE
*);
371 #define new_evstr(n) new_evstr_gen(parser,n)
372 static NODE
*evstr2dstr_gen
(struct parser_params
*,NODE
*);
373 #define evstr2dstr(n) evstr2dstr_gen(parser,n)
374 static NODE
*splat_array
(NODE
*);
376 static NODE
*call_bin_op_gen
(struct parser_params
*,NODE
*,ID
,NODE
*);
377 #define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, recv,id,arg1)
378 static NODE
*call_uni_op_gen
(struct parser_params
*,NODE
*,ID
);
379 #define call_uni_op(recv,id) call_uni_op_gen(parser, recv,id)
381 static NODE
*new_args_gen
(struct parser_params
*,NODE
*,NODE
*,ID
,NODE
*,ID
);
382 #define new_args(f,o,r,p,b) new_args_gen(parser, f,o,r,p,b)
383 static void shadowing_lvar_gen
(struct parser_params
*,ID
);
384 #define shadowing_lvar(name) shadowing_lvar_gen(parser, name)
386 static NODE
*negate_lit
(NODE
*);
387 static NODE
*ret_args_gen
(struct parser_params
*,NODE
*);
388 #define ret_args(node) ret_args_gen(parser, node)
389 static NODE
*arg_blk_pass
(NODE
*,NODE
*);
390 static NODE
*new_yield_gen
(struct parser_params
*,NODE
*);
391 #define new_yield(node) new_yield_gen(parser, node)
393 static NODE
*gettable_gen
(struct parser_params
*,ID
);
394 #define gettable(id) gettable_gen(parser,id)
395 static NODE
*assignable_gen
(struct parser_params
*,ID
,NODE
*);
396 #define assignable(id,node) assignable_gen(parser, id, node)
397 static void new_bv_gen
(struct parser_params
*,ID
);
398 #define new_bv(id) new_bv_gen(parser, id)
399 static NODE
*aryset_gen
(struct parser_params
*,NODE
*,NODE
*);
400 #define aryset(node1,node2) aryset_gen(parser, node1, node2)
401 static NODE
*attrset_gen
(struct parser_params
*,NODE
*,ID
);
402 #define attrset(node,id) attrset_gen(parser, node, id)
404 static void rb_backref_error_gen
(struct parser_params
*,NODE
*);
405 #define rb_backref_error(n) rb_backref_error_gen(parser,n)
406 static NODE
*node_assign_gen
(struct parser_params
*,NODE
*,NODE
*);
407 #define node_assign(node1, node2) node_assign_gen(parser, node1, node2)
409 static NODE
*match_op_gen
(struct parser_params
*,NODE
*,NODE
*);
410 #define match_op(node1,node2) match_op_gen(parser, node1, node2)
412 static void local_push_gen
(struct parser_params
*,int);
413 #define local_push(top) local_push_gen(parser,top)
414 static void local_pop_gen
(struct parser_params
*);
415 #define local_pop() local_pop_gen(parser)
416 static int local_var_gen
(struct parser_params
*, ID
);
417 #define local_var(id) local_var_gen(parser, id);
418 static int arg_var_gen
(struct parser_params
*, ID
);
419 #define arg_var(id) arg_var_gen(parser, id)
420 static int local_id_gen
(struct parser_params
*, ID
);
421 #define local_id(id) local_id_gen(parser, id)
422 static ID
*local_tbl_gen
(struct parser_params
*);
423 #define local_tbl() local_tbl_gen(parser)
424 static ID internal_id_gen
(struct parser_params
*);
425 #define internal_id() internal_id_gen(parser)
427 static void dyna_push_gen
(struct parser_params
*);
428 #define dyna_push() dyna_push_gen(parser)
429 static void dyna_pop_gen
(struct parser_params
*);
430 #define dyna_pop() dyna_pop_gen(parser)
431 static int dyna_in_block_gen
(struct parser_params
*);
432 #define dyna_in_block() dyna_in_block_gen(parser)
433 #define dyna_var(id) local_var(id)
434 static int dvar_defined_gen
(struct parser_params
*,ID
);
435 #define dvar_defined(id) dvar_defined_gen(parser, id)
436 static int dvar_curr_gen
(struct parser_params
*,ID
);
437 #define dvar_curr(id) dvar_curr_gen(parser, id)
439 static void fixup_nodes
(NODE
**);
441 extern
int rb_dvar_defined
(ID
);
442 extern
int rb_local_defined
(ID
);
443 extern
int rb_parse_in_eval
(void);
445 static VALUE reg_compile_gen
(struct parser_params
*, VALUE
, int);
446 #define reg_compile(str,options) reg_compile_gen(parser, str, options)
447 static void reg_fragment_setenc_gen
(struct parser_params
*, VALUE
, int);
448 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, str, options)
449 static void reg_fragment_check_gen
(struct parser_params
*, VALUE
, int);
450 #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, str, options)
451 static NODE
*reg_named_capture_assign_gen
(struct parser_params
* parser
, VALUE regexp
, NODE
*match
);
452 #define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,regexp,match)
453 int rb_enc_symname2_p
(const char *, int, rb_encoding
*);
455 #define remove_begin(node) (node)
457 static int lvar_defined_gen
(struct parser_params
*, ID
);
458 #define lvar_defined(id) lvar_defined_gen(parser, id)
460 #define RE_OPTION_ONCE (1<<16)
461 #define RE_OPTION_ENCODING_SHIFT 8
462 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
463 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
464 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
465 #define RE_OPTION_MASK 0xff
466 #define RE_OPTION_ARG_ENCODING_NONE 32
468 #define NODE_STRTERM NODE_ZARRAY /* nothing to gc */
469 #define NODE_HEREDOC NODE_ARRAY /* 1, 3 to gc */
470 #define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
471 #define nd_func u1.id
472 #if SIZEOF_SHORT == 2
473 #define nd_term(node) ((signed short)(node)->u2.id)
475 #define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
477 #define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
478 #define nd_nest u3.cnt
480 /****** Ripper *******/
483 #define RIPPER_VERSION "0.1.0"
485 #include "eventids1.c"
486 #include "eventids2.c"
487 static ID ripper_id_gets
;
489 static VALUE ripper_dispatch0
(struct parser_params
*,ID
);
490 static VALUE ripper_dispatch1
(struct parser_params
*,ID
,VALUE
);
491 static VALUE ripper_dispatch2
(struct parser_params
*,ID
,VALUE
,VALUE
);
492 static VALUE ripper_dispatch3
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
);
493 static VALUE ripper_dispatch4
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
);
494 static VALUE ripper_dispatch5
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
);
496 #define dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
497 #define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), a)
498 #define dispatch2(n,a,b) ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), a, b)
499 #define dispatch3(n,a,b,c) ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), a, b, c)
500 #define dispatch4(n,a,b,c,d) ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), a, b, c, d)
501 #define dispatch5(n,a,b,c,d,e) ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), a, b, c, d, e)
503 #define yyparse ripper_yyparse
505 static VALUE ripper_intern
(const char*);
506 static VALUE ripper_id2sym
(ID
);
508 #define arg_new() dispatch0(args_new)
509 #define arg_add(l,a) dispatch2(args_add, l, a)
510 #define arg_prepend(l,a) dispatch2(args_prepend, l, a)
511 #define arg_add_star(l,a) dispatch2(args_add_star, l, a)
512 #define arg_add_block(l,b) dispatch2(args_add_block, l, b)
513 #define arg_add_optblock(l,b) ((b)==Qundef? l : dispatch2(args_add_block, l, b))
514 #define bare_assoc(v) dispatch1(bare_assoc_hash, v)
515 #define arg_add_assocs(l,b) arg_add(l, bare_assoc(b))
517 #define args2mrhs(a) dispatch1(mrhs_new_from_args, a)
518 #define mrhs_new() dispatch0(mrhs_new)
519 #define mrhs_add(l,a) dispatch2(mrhs_add, l, a)
520 #define mrhs_add_star(l,a) dispatch2(mrhs_add_star, l, a)
522 #define mlhs_new() dispatch0(mlhs_new)
523 #define mlhs_add(l,a) dispatch2(mlhs_add, l, a)
524 #define mlhs_add_star(l,a) dispatch2(mlhs_add_star, l, a)
526 #define params_new(pars, opts, rest, pars2, blk) \
527 dispatch5
(params
, pars
, opts
, rest
, pars2
, blk
)
529 #define blockvar_new(p,v) dispatch2(block_var, p, v)
530 #define blockvar_add_star(l,a) dispatch2(block_var_add_star, l, a)
531 #define blockvar_add_block(l,a) dispatch2(block_var_add_block, l, a)
533 #define method_optarg(m,a) ((a)==Qundef ? m : dispatch2(method_add_arg,m,a))
534 #define method_arg(m,a) dispatch2(method_add_arg,m,a)
535 #define method_add_block(m,b) dispatch2(method_add_block, m, b)
537 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
544 # define ifndef_ripper(x) x
546 # define ifndef_ripper(x)
550 # define rb_warn0(fmt) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt)
551 # define rb_warnI(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt, a)
552 # define rb_warnS(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt, a)
553 # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, fmt)
554 # define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, fmt, a)
556 # define rb_warn0(fmt) ripper_warn0(parser, fmt)
557 # define rb_warnI(fmt,a) ripper_warnI(parser, fmt, a)
558 # define rb_warnS(fmt,a) ripper_warnS(parser, fmt, a)
559 # define rb_warning0(fmt) ripper_warning0(parser, fmt)
560 # define rb_warningS(fmt,a) ripper_warningS(parser, fmt, a)
561 static void ripper_warn0
(struct parser_params
*, const char*);
562 static void ripper_warnI
(struct parser_params
*, const char*, int);
564 static void ripper_warnS
(struct parser_params
*, const char*, const char*);
566 static void ripper_warning0
(struct parser_params
*, const char*);
567 static void ripper_warningS
(struct parser_params
*, const char*, const char*);
571 static void ripper_compile_error
(struct parser_params
*, const char *fmt
, ...
);
572 # define rb_compile_error ripper_compile_error
573 # define compile_error ripper_compile_error
574 # define PARSER_ARG parser,
576 # define compile_error parser->nerr++,rb_compile_error
577 # define PARSER_ARG ruby_sourcefile, ruby_sourceline,
580 /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
581 for instance). This is too low for Ruby to parse some files, such as
582 date/format.rb, therefore bump the value up to at least Bison's default. */
585 #define YYMAXDEPTH 10000
592 %parse
-param
{struct parser_params
*parser
}
599 struct RVarmap
*vars
;
657 %token
<id
> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
658 %token
<node
> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
659 %token
<node
> tNTH_REF tBACK_REF
660 %token
<num
> tREGEXP_END
662 %type
<node
> singleton strings
string string1 xstring regexp
663 %type
<node
> string_contents xstring_contents string_content
664 %type
<node
> words qwords word_list qword_list word
665 %type
<node
> literal numeric dsym cpath
666 %type
<node
> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
667 %type
<node
> expr_value arg_value primary_value
668 %type
<node
> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
669 %type
<node
> args call_args opt_call_args
670 %type
<node
> paren_args opt_paren_args
671 %type
<node
> command_args aref_args opt_block_arg block_arg var_ref var_lhs
672 %type
<node
> mrhs superclass block_call block_command
673 %type
<node
> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
674 %type
<node
> assoc_list assocs assoc undef_list backref string_dvar for_var
675 %type
<node
> block_param opt_block_param block_param_def f_opt
676 %type
<node
> bv_decls opt_bv_decl bvar
677 %type
<node
> lambda f_larglist lambda_body
678 %type
<node
> brace_block cmd_brace_block do_block lhs none fitem
679 %type
<node
> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
680 %type
<id
> fsym variable sym symbol operation operation2 operation3
681 %type
<id
> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
684 %type <val> program reswords then do dot_or_colon
686 %token tUPLUS
/* unary+ */
687 %token tUMINUS
/* unary- */
689 %token tCMP
/* <=> */
691 %token tEQQ
/* === */
695 %token tANDOP tOROP
/* && and || */
696 %token tMATCH tNMATCH
/* =~ and !~ */
697 %token tDOT2 tDOT3
/* .. and ... */
698 %token tAREF tASET
/* [] and []= */
699 %token tLSHFT tRSHFT
/* << and >> */
700 %token tCOLON2
/* :: */
701 %token tCOLON3
/* :: at EXPR_BEG */
702 %token
<id
> tOP_ASGN
/* +=, -= etc. */
703 %token tASSOC
/* => */
704 %token tLPAREN
/* ( */
705 %token tLPAREN_ARG
/* ( */
706 %token tRPAREN
/* ) */
707 %token tLBRACK
/* [ */
708 %token tLBRACE
/* { */
709 %token tLBRACE_ARG
/* { */
711 %token tAMPER
/* & */
712 %token tLAMBDA
/* -> */
713 %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
714 %token tSTRING_DBEG tSTRING_DVAR tSTRING_END tLAMBEG
721 %nonassoc tLBRACE_ARG
723 %nonassoc modifier_if modifier_unless modifier_while modifier_until
724 %left keyword_or keyword_and
726 %nonassoc keyword_defined
728 %left modifier_rescue
730 %nonassoc tDOT2 tDOT3
733 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
734 %left
'>' tGEQ
'<' tLEQ
740 %right tUMINUS_NUM tUMINUS
742 %right
'!' '~' tUPLUS
748 lex_state
= EXPR_BEG
;
750 local_push
(compile_for_eval
);
757 if
($2 && !compile_for_eval
) {
758 /* last expression should not be void */
759 if
(nd_type
($2) != NODE_BLOCK
) void_expr
($2);
762 while
(node
->nd_next
) {
763 node
= node
->nd_next
;
765 void_expr
(node
->nd_head
);
768 ruby_eval_tree
= NEW_SCOPE
(0, block_append
(ruby_eval_tree
, $2));
772 parser->result = dispatch1(program, $$);
785 $$
= NEW_RESCUE
($1, $2, $3);
788 rb_warn0
("else without rescue is useless");
789 $$
= block_append
($$
, $3);
793 $$
= NEW_ENSURE
($$
, $4);
796 $$
= block_append
($4, NEW_NIL
());
801 $$ = dispatch4(body_stmt,
810 compstmt
: stmts opt_terms
814 fixup_nodes
(&deferred_nodes
);
826 $$ = dispatch2(stmts_add, dispatch0(stmts_new),
827 dispatch0(void_stmt));
833 $$
= newline_node
($1);
835 $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
841 $$
= block_append
($1, newline_node
($3));
843 $$ = dispatch2(stmts_add, $1, $3);
848 $$
= remove_begin
($2);
852 stmt
: keyword_alias fitem
{lex_state
= EXPR_FNAME
;} fitem
855 $$
= NEW_ALIAS
($2, $4);
857 $$ = dispatch2(alias, $2, $4);
860 | keyword_alias tGVAR tGVAR
863 $$
= NEW_VALIAS
($2, $3);
865 $$ = dispatch2(var_alias, $2, $3);
868 | keyword_alias tGVAR tBACK_REF
873 sprintf
(buf
, "$%c", (char)$3->nd_nth
);
874 $$
= NEW_VALIAS
($2, rb_intern
(buf
));
876 $$ = dispatch2(var_alias, $2, $3);
879 | keyword_alias tGVAR tNTH_REF
882 yyerror("can't make alias for the number variables");
885 $$ = dispatch2(var_alias, $2, $3);
886 $$ = dispatch1(alias_error, $$);
889 | keyword_undef undef_list
894 $$ = dispatch1(undef, $2);
897 | stmt modifier_if expr_value
900 $$
= NEW_IF
(cond
($3), remove_begin
($1), 0);
903 $$ = dispatch2(if_mod, $3, $1);
906 | stmt modifier_unless expr_value
909 $$
= NEW_UNLESS
(cond
($3), remove_begin
($1), 0);
912 $$ = dispatch2(unless_mod, $3, $1);
915 | stmt modifier_while expr_value
918 if
($1 && nd_type
($1) == NODE_BEGIN
) {
919 $$
= NEW_WHILE
(cond
($3), $1->nd_body
, 0);
922 $$
= NEW_WHILE
(cond
($3), $1, 1);
925 $$ = dispatch2(while_mod, $3, $1);
928 | stmt modifier_until expr_value
931 if
($1 && nd_type
($1) == NODE_BEGIN
) {
932 $$
= NEW_UNTIL
(cond
($3), $1->nd_body
, 0);
935 $$
= NEW_UNTIL
(cond
($3), $1, 1);
938 $$ = dispatch2(until_mod, $3, $1);
941 | stmt modifier_rescue stmt
944 NODE
*resq
= NEW_RESBODY
(0, remove_begin
($3), 0);
945 $$
= NEW_RESCUE
(remove_begin
($1), resq
, 0);
947 $$ = dispatch2(rescue_mod, $3, $1);
952 if
(in_def || in_single
) {
953 yyerror("BEGIN in method");
963 ruby_eval_tree_begin
= block_append
(ruby_eval_tree_begin
,
965 /* NEW_PREEXE($4)); */
969 $$ = dispatch1(BEGIN, $4);
972 | keyword_END
'{' compstmt
'}'
974 if
(in_def || in_single
) {
975 rb_warn0
("END in method; use at_exit");
978 $$
= NEW_POSTEXE
(NEW_NODE
(
979 NODE_SCOPE
, 0 /* tbl */, $3 /* body */, 0 /* args */));
981 $$ = dispatch1(END, $3);
984 | lhs
'=' command_call
988 $$
= node_assign
($1, $3);
990 $$ = dispatch2(assign, $1, $3);
993 | mlhs
'=' command_call
1000 $$ = dispatch2(massign, $1, $3);
1003 | var_lhs tOP_ASGN command_call
1008 ID vid
= $1->nd_vid
;
1011 $$
= NEW_OP_ASGN_OR
(gettable
(vid
), $1);
1012 if
(is_asgn_or_id
(vid
)) {
1016 else if
($2 == tANDOP
) {
1018 $$
= NEW_OP_ASGN_AND
(gettable
(vid
), $1);
1022 $$
->nd_value
= NEW_CALL
(gettable
(vid
), $2, NEW_LIST
($3));
1029 $$ = dispatch3(opassign, $1, $2, $3);
1032 | primary_value
'[' opt_call_args rbracket tOP_ASGN command_call
1038 if
(!$3) $3 = NEW_ZARRAY
();
1039 args
= arg_concat
($6, $3);
1043 else if
($5 == tANDOP
) {
1046 $$
= NEW_OP_ASGN1
($1, $5, args
);
1049 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1050 $$ = dispatch3(opassign, $$, $5, $6);
1053 | primary_value
'.' tIDENTIFIER tOP_ASGN command_call
1060 else if
($4 == tANDOP
) {
1063 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1066 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1067 $$ = dispatch3(opassign, $$, $4, $5);
1070 | primary_value
'.' tCONSTANT tOP_ASGN command_call
1077 else if
($4 == tANDOP
) {
1080 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1083 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1084 $$ = dispatch3(opassign, $$, $4, $5);
1087 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
1094 else if
($4 == tANDOP
) {
1097 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1100 $$ = dispatch3(field, $1, ripper_intern("::"), $3);
1101 $$ = dispatch3(opassign, $$, $4, $5);
1104 | backref tOP_ASGN command_call
1107 rb_backref_error
($1);
1110 $$ = dispatch2(assign, dispatch1(var_field, $1), $3);
1111 $$ = dispatch1(assign_error, $$);
1118 $$
= node_assign
($1, $3);
1120 $$ = dispatch2(assign, $1, $3);
1123 | mlhs
'=' arg_value
1129 dispatch2(massign, $1, $3);
1138 $$ = dispatch2(massign, $1, $3);
1145 | expr keyword_and expr
1148 $$
= logop
(NODE_AND
, $1, $3);
1150 $$ = dispatch3(binary, $1, ripper_intern("and"), $3);
1153 | expr keyword_or expr
1156 $$
= logop
(NODE_OR
, $1, $3);
1158 $$ = dispatch3(binary, $1, ripper_intern("or"), $3);
1164 $$
= call_uni_op
(cond
($2), '!');
1166 $$ = dispatch2(unary, ripper_intern("not"), $2);
1172 $$
= call_uni_op
(cond
($2), '!');
1174 $$ = dispatch2(unary, ripper_id2sym('!'), $2);
1185 if
(!$$
) $$
= NEW_NIL
();
1192 command_call
: command
1194 | keyword_return call_args
1197 $$
= NEW_RETURN
(ret_args
($2));
1199 $$ = dispatch1(return, $2);
1202 | keyword_break call_args
1205 $$
= NEW_BREAK
(ret_args
($2));
1207 $$ = dispatch1(break, $2);
1210 | keyword_next call_args
1213 $$
= NEW_NEXT
(ret_args
($2));
1215 $$ = dispatch1(next, $2);
1220 block_command
: block_call
1221 | block_call
'.' operation2 command_args
1224 $$
= NEW_CALL
($1, $3, $4);
1226 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
1227 $$ = method_arg($$, $4);
1230 | block_call tCOLON2 operation2 command_args
1233 $$
= NEW_CALL
($1, $3, $4);
1235 $$ = dispatch3(call, $1, ripper_intern("::"), $3);
1236 $$ = method_arg($$, $4);
1241 cmd_brace_block
: tLBRACE_ARG
1245 $
<num
>$
= ruby_sourceline
;
1254 $$
= NEW_ITER
($3,$4);
1255 nd_set_line
($$
, $
<num
>2);
1258 $$ = dispatch2(brace_block, escape_Qundef($3), $4);
1263 command
: operation command_args %prec tLOWEST
1266 $$
= NEW_FCALL
($1, $2);
1269 $$ = dispatch2(command, $1, $2);
1272 | operation command_args cmd_brace_block
1275 block_dup_check
($2,$3);
1276 $3->nd_iter
= NEW_FCALL
($1, $2);
1280 $$ = dispatch2(command, $1, $2);
1281 $$ = method_add_block($$, $3);
1284 | primary_value
'.' operation2 command_args %prec tLOWEST
1287 $$
= NEW_CALL
($1, $3, $4);
1290 $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1293 | primary_value
'.' operation2 command_args cmd_brace_block
1296 block_dup_check
($4,$5);
1297 $5->nd_iter
= NEW_CALL
($1, $3, $4);
1301 $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1302 $$ = method_add_block($$, $5);
1305 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1308 $$
= NEW_CALL
($1, $3, $4);
1311 $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1314 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1317 block_dup_check
($4,$5);
1318 $5->nd_iter
= NEW_CALL
($1, $3, $4);
1322 $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1323 $$ = method_add_block($$, $5);
1326 | keyword_super command_args
1332 $$ = dispatch1(super, $2);
1335 | keyword_yield command_args
1341 $$ = dispatch1(yield, $2);
1347 | tLPAREN mlhs_inner rparen
1352 $$ = dispatch1(mlhs_paren, $2);
1357 mlhs_inner
: mlhs_basic
1358 | tLPAREN mlhs_inner rparen
1361 $$
= NEW_MASGN
(NEW_LIST
($2), 0);
1363 $$ = dispatch1(mlhs_paren, $2);
1368 mlhs_basic
: mlhs_head
1371 $$
= NEW_MASGN
($1, 0);
1376 | mlhs_head mlhs_item
1379 $$
= NEW_MASGN
(list_append
($1,$2), 0);
1381 $$ = mlhs_add($1, $2);
1384 | mlhs_head tSTAR mlhs_node
1387 $$
= NEW_MASGN
($1, $3);
1389 $$ = mlhs_add_star($1, $3);
1392 | mlhs_head tSTAR mlhs_node
',' mlhs_post
1395 $$
= NEW_MASGN
($1, NEW_POSTARG
($3,$5));
1397 $$ = mlhs_add_star($1, $3);
1403 $$
= NEW_MASGN
($1, -1);
1405 $$ = mlhs_add_star($1, Qnil);
1408 | mlhs_head tSTAR
',' mlhs_post
1411 $$
= NEW_MASGN
($1, NEW_POSTARG
(-1, $4));
1413 $$ = mlhs_add_star($1, Qnil);
1419 $$
= NEW_MASGN
(0, $2);
1421 $$ = mlhs_add_star(mlhs_new(), $2);
1424 | tSTAR mlhs_node
',' mlhs_post
1427 $$
= NEW_MASGN
(0, NEW_POSTARG
($2,$4));
1429 $$ = mlhs_add_star(mlhs_new(), $2);
1435 $$
= NEW_MASGN
(0, -1);
1437 $$ = mlhs_add_star(mlhs_new(), Qnil);
1440 | tSTAR
',' mlhs_post
1443 $$
= NEW_MASGN
(0, NEW_POSTARG
(-1, $3));
1445 $$ = mlhs_add_star(mlhs_new(), Qnil);
1450 mlhs_item
: mlhs_node
1451 | tLPAREN mlhs_inner rparen
1456 $$ = dispatch1(mlhs_paren, $2);
1461 mlhs_head
: mlhs_item
','
1466 $$ = mlhs_add(mlhs_new(), $1);
1469 | mlhs_head mlhs_item
','
1472 $$
= list_append
($1, $2);
1474 $$ = mlhs_add($1, $2);
1479 mlhs_post
: mlhs_item
1484 $$ = mlhs_add(mlhs_new(), $1);
1487 | mlhs_post
',' mlhs_item
1490 $$
= list_append
($1, $3);
1492 $$ = mlhs_add($1, $3);
1497 mlhs_node
: variable
1500 $$
= assignable
($1, 0);
1505 | primary_value
'[' opt_call_args rbracket
1508 $$
= aryset
($1, $3);
1510 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1513 | primary_value
'.' tIDENTIFIER
1516 $$
= attrset
($1, $3);
1518 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1521 | primary_value tCOLON2 tIDENTIFIER
1524 $$
= attrset
($1, $3);
1526 $$ = dispatch2(const_path_field, $1, $3);
1529 | primary_value
'.' tCONSTANT
1532 $$
= attrset
($1, $3);
1534 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1537 | primary_value tCOLON2 tCONSTANT
1540 if
(in_def || in_single
)
1541 yyerror("dynamic constant assignment");
1542 $$
= NEW_CDECL
(0, 0, NEW_COLON2
($1, $3));
1544 if (in_def || in_single)
1545 yyerror("dynamic constant assignment");
1546 $$ = dispatch2(const_path_field, $1, $3);
1552 if
(in_def || in_single
)
1553 yyerror("dynamic constant assignment");
1554 $$
= NEW_CDECL
(0, 0, NEW_COLON3
($2));
1556 $$ = dispatch1(top_const_field, $2);
1562 rb_backref_error
($1);
1565 $$ = dispatch1(var_field, $1);
1566 $$ = dispatch1(assign_error, $$);
1574 if
(!($$
= assignable
($1, 0))) $$
= NEW_BEGIN
(0);
1576 $$ = dispatch1(var_field, $1);
1579 | primary_value
'[' opt_call_args rbracket
1582 $$
= aryset
($1, $3);
1584 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1587 | primary_value
'.' tIDENTIFIER
1590 $$
= attrset
($1, $3);
1592 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1595 | primary_value tCOLON2 tIDENTIFIER
1598 $$
= attrset
($1, $3);
1600 $$ = dispatch3(field, $1, ripper_intern("::"), $3);
1603 | primary_value
'.' tCONSTANT
1606 $$
= attrset
($1, $3);
1608 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1611 | primary_value tCOLON2 tCONSTANT
1614 if
(in_def || in_single
)
1615 yyerror("dynamic constant assignment");
1616 $$
= NEW_CDECL
(0, 0, NEW_COLON2
($1, $3));
1618 $$ = dispatch2(const_path_field, $1, $3);
1619 if (in_def || in_single) {
1620 $$ = dispatch1(assign_error, $$);
1627 if
(in_def || in_single
)
1628 yyerror("dynamic constant assignment");
1629 $$
= NEW_CDECL
(0, 0, NEW_COLON3
($2));
1631 $$ = dispatch1(top_const_field, $2);
1632 if (in_def || in_single) {
1633 $$ = dispatch1(assign_error, $$);
1640 rb_backref_error
($1);
1643 $$ = dispatch1(assign_error, $1);
1651 yyerror("class/module name must be CONSTANT");
1653 $$ = dispatch1(class_name_error, $1);
1659 cpath
: tCOLON3 cname
1662 $$
= NEW_COLON3
($2);
1664 $$ = dispatch1(top_const_ref, $2);
1670 $$
= NEW_COLON2
(0, $$
);
1672 $$ = dispatch1(const_ref, $1);
1675 | primary_value tCOLON2 cname
1678 $$
= NEW_COLON2
($1, $3);
1680 $$ = dispatch2(const_path_ref, $1, $3);
1691 lex_state
= EXPR_END
;
1694 lex_state = EXPR_END;
1701 lex_state
= EXPR_END
;
1704 lex_state = EXPR_END;
1717 $$
= NEW_LIT
(ID2SYM
($1));
1719 $$ = dispatch1(symbol_literal, $1);
1730 $$ = rb_ary_new3(1, $1);
1733 | undef_list
',' {lex_state
= EXPR_FNAME
;} fitem
1736 $$
= block_append
($1, NEW_UNDEF
($4));
1738 rb_ary_push($1, $4);
1743 op
: '|' { ifndef_ripper
($$
= '|'); }
1744 |
'^' { ifndef_ripper
($$
= '^'); }
1745 |
'&' { ifndef_ripper
($$
= '&'); }
1746 | tCMP
{ ifndef_ripper
($$
= tCMP
); }
1747 | tEQ
{ ifndef_ripper
($$
= tEQ
); }
1748 | tEQQ
{ ifndef_ripper
($$
= tEQQ
); }
1749 | tMATCH
{ ifndef_ripper
($$
= tMATCH
); }
1750 | tNMATCH
{ ifndef_ripper
($$
= tNMATCH
); }
1751 |
'>' { ifndef_ripper
($$
= '>'); }
1752 | tGEQ
{ ifndef_ripper
($$
= tGEQ
); }
1753 |
'<' { ifndef_ripper
($$
= '<'); }
1754 | tLEQ
{ ifndef_ripper
($$
= tLEQ
); }
1755 | tNEQ
{ ifndef_ripper
($$
= tNEQ
); }
1756 | tLSHFT
{ ifndef_ripper
($$
= tLSHFT
); }
1757 | tRSHFT
{ ifndef_ripper
($$
= tRSHFT
); }
1758 |
'+' { ifndef_ripper
($$
= '+'); }
1759 |
'-' { ifndef_ripper
($$
= '-'); }
1760 |
'*' { ifndef_ripper
($$
= '*'); }
1761 | tSTAR
{ ifndef_ripper
($$
= '*'); }
1762 |
'/' { ifndef_ripper
($$
= '/'); }
1763 |
'%' { ifndef_ripper
($$
= '%'); }
1764 | tPOW
{ ifndef_ripper
($$
= tPOW
); }
1765 |
'!' { ifndef_ripper
($$
= '!'); }
1766 |
'~' { ifndef_ripper
($$
= '~'); }
1767 | tUPLUS
{ ifndef_ripper
($$
= tUPLUS
); }
1768 | tUMINUS
{ ifndef_ripper
($$
= tUMINUS
); }
1769 | tAREF
{ ifndef_ripper
($$
= tAREF
); }
1770 | tASET
{ ifndef_ripper
($$
= tASET
); }
1771 |
'`' { ifndef_ripper
($$
= '`'); }
1774 reswords
: keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
1775 | keyword_BEGIN | keyword_END
1776 | keyword_alias | keyword_and | keyword_begin
1777 | keyword_break | keyword_case | keyword_class | keyword_def
1778 | keyword_defined | keyword_do | keyword_else | keyword_elsif
1779 | keyword_end | keyword_ensure | keyword_false
1780 | keyword_for | keyword_in | keyword_module | keyword_next
1781 | keyword_nil | keyword_not | keyword_or | keyword_redo
1782 | keyword_rescue | keyword_retry | keyword_return | keyword_self
1783 | keyword_super | keyword_then | keyword_true | keyword_undef
1784 | keyword_when | keyword_yield | keyword_if | keyword_unless
1785 | keyword_while | keyword_until
1792 $$
= node_assign
($1, $3);
1794 $$ = dispatch2(assign, $1, $3);
1797 | lhs
'=' arg modifier_rescue arg
1801 $3 = NEW_RESCUE
($3, NEW_RESBODY
(0,$5,0), 0);
1802 $$
= node_assign
($1, $3);
1804 $$ = dispatch2(assign, $1, dispatch2(rescue_mod, $3, $5));
1807 | var_lhs tOP_ASGN arg
1812 ID vid
= $1->nd_vid
;
1815 $$
= NEW_OP_ASGN_OR
(gettable
(vid
), $1);
1816 if
(is_asgn_or_id
(vid
)) {
1820 else if
($2 == tANDOP
) {
1822 $$
= NEW_OP_ASGN_AND
(gettable
(vid
), $1);
1826 $$
->nd_value
= NEW_CALL
(gettable
(vid
), $2, NEW_LIST
($3));
1833 $$ = dispatch3(opassign, $1, $2, $3);
1836 | var_lhs tOP_ASGN arg modifier_rescue arg
1840 $3 = NEW_RESCUE
($3, NEW_RESBODY
(0,$5,0), 0);
1842 ID vid
= $1->nd_vid
;
1845 $$
= NEW_OP_ASGN_OR
(gettable
(vid
), $1);
1846 if
(is_asgn_or_id
(vid
)) {
1850 else if
($2 == tANDOP
) {
1852 $$
= NEW_OP_ASGN_AND
(gettable
(vid
), $1);
1856 $$
->nd_value
= NEW_CALL
(gettable
(vid
), $2, NEW_LIST
($3));
1863 $3 = dispatch2(rescue_mod, $3, $5);
1864 $$ = dispatch3(opassign, $1, $2, $3);
1867 | primary_value
'[' opt_call_args rbracket tOP_ASGN arg
1873 if
(!$3) $3 = NEW_ZARRAY
();
1874 args
= arg_concat
($6, $3);
1878 else if
($5 == tANDOP
) {
1881 $$
= NEW_OP_ASGN1
($1, $5, args
);
1884 $1 = dispatch2(aref_field, $1, escape_Qundef($3));
1885 $$ = dispatch3(opassign, $1, $5, $6);
1888 | primary_value
'.' tIDENTIFIER tOP_ASGN arg
1895 else if
($4 == tANDOP
) {
1898 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1901 $1 = dispatch3(field, $1, ripper_id2sym('.'), $3);
1902 $$ = dispatch3(opassign, $1, $4, $5);
1905 | primary_value
'.' tCONSTANT tOP_ASGN arg
1912 else if
($4 == tANDOP
) {
1915 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1918 $1 = dispatch3(field, $1, ripper_id2sym('.'), $3);
1919 $$ = dispatch3(opassign, $1, $4, $5);
1922 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
1929 else if
($4 == tANDOP
) {
1932 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1935 $1 = dispatch3(field, $1, ripper_intern("::"), $3);
1936 $$ = dispatch3(opassign, $1, $4, $5);
1939 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
1942 yyerror("constant re-assignment");
1945 $$ = dispatch2(const_path_field, $1, $3);
1946 $$ = dispatch3(opassign, $$, $4, $5);
1947 $$ = dispatch1(assign_error, $$);
1950 | tCOLON3 tCONSTANT tOP_ASGN arg
1953 yyerror("constant re-assignment");
1956 $$ = dispatch1(top_const_field, $2);
1957 $$ = dispatch3(opassign, $$, $3, $4);
1958 $$ = dispatch1(assign_error, $$);
1961 | backref tOP_ASGN arg
1964 rb_backref_error
($1);
1967 $$ = dispatch1(var_field, $1);
1968 $$ = dispatch3(opassign, $$, $2, $3);
1969 $$ = dispatch1(assign_error, $$);
1977 $$
= NEW_DOT2
($1, $3);
1978 if
(nd_type
($1) == NODE_LIT
&& FIXNUM_P
($1->nd_lit
) &&
1979 nd_type
($3) == NODE_LIT
&& FIXNUM_P
($3->nd_lit
)) {
1980 deferred_nodes
= list_append
(deferred_nodes
, $$
);
1983 $$ = dispatch2(dot2, $1, $3);
1991 $$
= NEW_DOT3
($1, $3);
1992 if
(nd_type
($1) == NODE_LIT
&& FIXNUM_P
($1->nd_lit
) &&
1993 nd_type
($3) == NODE_LIT
&& FIXNUM_P
($3->nd_lit
)) {
1994 deferred_nodes
= list_append
(deferred_nodes
, $$
);
1997 $$ = dispatch2(dot3, $1, $3);
2003 $$
= call_bin_op
($1, '+', $3);
2005 $$ = dispatch3(binary, $1, ID2SYM('+'), $3);
2011 $$
= call_bin_op
($1, '-', $3);
2013 $$ = dispatch3(binary, $1, ID2SYM('-'), $3);
2019 $$
= call_bin_op
($1, '*', $3);
2021 $$ = dispatch3(binary, $1, ID2SYM('*'), $3);
2027 $$
= call_bin_op
($1, '/', $3);
2029 $$ = dispatch3(binary, $1, ID2SYM('/'), $3);
2035 $$
= call_bin_op
($1, '%', $3);
2037 $$ = dispatch3(binary, $1, ID2SYM('%'), $3);
2043 $$
= call_bin_op
($1, tPOW
, $3);
2045 $$ = dispatch3(binary, $1, ripper_intern("**"), $3);
2048 | tUMINUS_NUM tINTEGER tPOW arg
2051 $$
= NEW_CALL
(call_bin_op
($2, tPOW
, $4), tUMINUS
, 0);
2053 $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2054 $$ = dispatch2(unary, ripper_intern("-@"), $$);
2057 | tUMINUS_NUM tFLOAT tPOW arg
2060 $$
= NEW_CALL
(call_bin_op
($2, tPOW
, $4), tUMINUS
, 0);
2062 $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2063 $$ = dispatch2(unary, ripper_intern("-@"), $$);
2069 $$
= call_uni_op
($2, tUPLUS
);
2071 $$ = dispatch2(unary, ripper_intern("+@"), $2);
2077 $$
= call_uni_op
($2, tUMINUS
);
2079 $$ = dispatch2(unary, ripper_intern("-@"), $2);
2085 $$
= call_bin_op
($1, '|', $3);
2087 $$ = dispatch3(binary, $1, ID2SYM('|'), $3);
2093 $$
= call_bin_op
($1, '^', $3);
2095 $$ = dispatch3(binary, $1, ID2SYM('^'), $3);
2101 $$
= call_bin_op
($1, '&', $3);
2103 $$ = dispatch3(binary, $1, ID2SYM('&'), $3);
2109 $$
= call_bin_op
($1, tCMP
, $3);
2111 $$ = dispatch3(binary, $1, ripper_intern("<=>"), $3);
2117 $$
= call_bin_op
($1, '>', $3);
2119 $$ = dispatch3(binary, $1, ID2SYM('>'), $3);
2125 $$
= call_bin_op
($1, tGEQ
, $3);
2127 $$ = dispatch3(binary, $1, ripper_intern(">="), $3);
2133 $$
= call_bin_op
($1, '<', $3);
2135 $$ = dispatch3(binary, $1, ID2SYM('<'), $3);
2141 $$
= call_bin_op
($1, tLEQ
, $3);
2143 $$ = dispatch3(binary, $1, ripper_intern("<="), $3);
2149 $$
= call_bin_op
($1, tEQ
, $3);
2151 $$ = dispatch3(binary, $1, ripper_intern("=="), $3);
2157 $$
= call_bin_op
($1, tEQQ
, $3);
2159 $$ = dispatch3(binary, $1, ripper_intern("==="), $3);
2165 $$
= call_bin_op
($1, tNEQ
, $3);
2167 $$ = dispatch3(binary, $1, ripper_intern("!="), $3);
2173 $$
= match_op
($1, $3);
2174 if
(nd_type
($1) == NODE_LIT
&& TYPE
($1->nd_lit
) == T_REGEXP
) {
2175 $$
= reg_named_capture_assign
($1->nd_lit
, $$
);
2178 $$ = dispatch3(binary, $1, ripper_intern("=~"), $3);
2184 $$
= call_bin_op
($1, tNMATCH
, $3);
2186 $$ = dispatch3(binary, $1, ripper_intern("!~"), $3);
2192 $$
= call_uni_op
(cond
($2), '!');
2194 $$ = dispatch2(unary, ID2SYM('!'), $2);
2200 $$
= call_uni_op
($2, '~');
2202 $$ = dispatch2(unary, ID2SYM('~'), $2);
2208 $$
= call_bin_op
($1, tLSHFT
, $3);
2210 $$ = dispatch3(binary, $1, ripper_intern("<<"), $3);
2216 $$
= call_bin_op
($1, tRSHFT
, $3);
2218 $$ = dispatch3(binary, $1, ripper_intern(">>"), $3);
2224 $$
= logop
(NODE_AND
, $1, $3);
2226 $$ = dispatch3(binary, $1, ripper_intern("&&"), $3);
2232 $$
= logop
(NODE_OR
, $1, $3);
2234 $$ = dispatch3(binary, $1, ripper_intern("||"), $3);
2237 | keyword_defined opt_nl
{in_defined
= 1;} arg
2241 $$
= NEW_DEFINED
($4);
2244 $$ = dispatch1(defined, $4);
2247 | arg
'?' arg opt_nl
':' arg
2251 $$
= NEW_IF
(cond
($1), $3, $6);
2254 $$ = dispatch3(ifop, $1, $3, $6);
2268 if
(!$$
) $$
= NEW_NIL
();
2280 | args
',' assocs trailer
2283 $$
= arg_append
($1, NEW_HASH
($3));
2285 $$ = arg_add_assocs($1, $3);
2291 $$
= NEW_LIST
(NEW_HASH
($1));
2293 $$ = arg_add_assocs(arg_new(), $1);
2298 paren_args
: '(' opt_call_args rparen
2303 $$ = dispatch1(arg_paren, escape_Qundef($2));
2308 opt_paren_args
: none
2312 opt_call_args
: none
2321 $$ = arg_add(arg_new(), $1);
2324 | args opt_block_arg
2327 $$
= arg_blk_pass
($1, $2);
2329 $$ = arg_add_optblock($1, $2);
2332 | assocs opt_block_arg
2335 $$
= NEW_LIST
(NEW_HASH
($1));
2336 $$
= arg_blk_pass
($$
, $2);
2338 $$ = arg_add_assocs(arg_new(), $1);
2339 $$ = arg_add_optblock($$, $2);
2342 | args
',' assocs opt_block_arg
2345 $$
= arg_append
($1, NEW_HASH
($3));
2346 $$
= arg_blk_pass
($$
, $4);
2348 $$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
2355 $$ = arg_add_block(arg_new(), $1);
2361 $
<num
>$
= cmdarg_stack
;
2367 cmdarg_stack
= $
<num
>1;
2372 block_arg
: tAMPER arg_value
2375 $$
= NEW_BLOCK_PASS
($2);
2382 opt_block_arg
: ',' block_arg
2397 $$ = arg_add(arg_new(), $1);
2405 $$ = arg_add_star(arg_new(), $2);
2408 | args
',' arg_value
2412 if
((n1
= splat_array
($1)) != 0) {
2413 $$
= list_append
(n1
, $3);
2416 $$
= arg_append
($1, $3);
2419 $$ = arg_add($1, $3);
2422 | args
',' tSTAR arg_value
2426 if
(nd_type
($4) == NODE_ARRAY
&&
2427 (n1
= splat_array
($1)) != 0) {
2428 $$
= list_concat
(n1
, $4);
2431 $$
= arg_concat
($1, $4);
2434 $$ = arg_add_star($1, $4);
2439 mrhs
: args
',' arg_value
2443 if
((n1
= splat_array
($1)) != 0) {
2444 $$
= list_append
(n1
, $3);
2447 $$
= arg_append
($1, $3);
2450 $$ = mrhs_add(args2mrhs($1), $3);
2453 | args
',' tSTAR arg_value
2457 if
(nd_type
($4) == NODE_ARRAY
&&
2458 (n1
= splat_array
($1)) != 0) {
2459 $$
= list_concat
(n1
, $4);
2462 $$
= arg_concat
($1, $4);
2465 $$ = mrhs_add_star(args2mrhs($1), $4);
2473 $$ = mrhs_add_star(mrhs_new(), $2);
2489 $$
= NEW_FCALL
($1, 0);
2491 $$ = method_arg(dispatch1(fcall, $1), arg_new());
2497 $
<num
>$
= ruby_sourceline
;
2509 if
(nd_type
($3) == NODE_RESCUE ||
2510 nd_type
($3) == NODE_ENSURE
)
2511 nd_set_line
($3, $
<num
>2);
2514 nd_set_line
($$
, $
<num
>2);
2516 $$ = dispatch1(begin, $3);
2519 | tLPAREN_ARG expr
{lex_state
= EXPR_ENDARG
;} rparen
2521 rb_warning0
("(...) interpreted as grouped expression");
2525 $$ = dispatch1(paren, $2);
2528 | tLPAREN compstmt
')'
2533 $$ = dispatch1(paren, $2);
2536 | primary_value tCOLON2 tCONSTANT
2539 $$
= NEW_COLON2
($1, $3);
2541 $$ = dispatch2(const_path_ref, $1, $3);
2547 $$
= NEW_COLON3
($2);
2549 $$ = dispatch1(top_const_ref, $2);
2552 | tLBRACK aref_args
']'
2556 $$
= NEW_ZARRAY
(); /* zero length array*/
2562 $$ = dispatch1(array, escape_Qundef($2));
2565 | tLBRACE assoc_list
'}'
2570 $$ = dispatch1(hash, escape_Qundef($2));
2578 $$ = dispatch0(return0);
2581 | keyword_yield
'(' call_args rparen
2586 $$ = dispatch1(yield, dispatch1(paren, $3));
2589 | keyword_yield
'(' rparen
2592 $$
= NEW_YIELD
(0, Qfalse
);
2594 $$ = dispatch1(yield, dispatch1(paren, arg_new()));
2600 $$
= NEW_YIELD
(0, Qfalse
);
2602 $$ = dispatch0(yield0);
2605 | keyword_defined opt_nl
'(' {in_defined
= 1;} expr rparen
2609 $$
= NEW_DEFINED
($5);
2612 $$ = dispatch1(defined, $5);
2615 | keyword_not
'(' expr rparen
2618 $$
= call_uni_op
(cond
($3), '!');
2620 $$ = dispatch2(unary, ripper_intern("not"), $3);
2623 | keyword_not
'(' rparen
2626 $$
= call_uni_op
(cond
(NEW_NIL
()), '!');
2628 $$ = dispatch2(unary, ripper_intern("not"), Qnil);
2631 | operation brace_block
2634 $2->nd_iter
= NEW_FCALL
($1, 0);
2636 fixpos
($2->nd_iter
, $2);
2638 $$ = method_arg(dispatch1(fcall, $1), arg_new());
2639 $$ = method_add_block($$, $2);
2643 | method_call brace_block
2646 block_dup_check
($1->nd_args
, $2);
2651 $$ = method_add_block($1, $2);
2658 | keyword_if expr_value then
2664 $$
= NEW_IF
(cond
($2), $4, $5);
2667 $$ = dispatch3(if, $2, $4, escape_Qundef($5));
2670 | keyword_unless expr_value then
2676 $$
= NEW_UNLESS
(cond
($2), $4, $5);
2679 $$ = dispatch3(unless, $2, $4, escape_Qundef($5));
2682 | keyword_while
{COND_PUSH
(1);} expr_value do
{COND_POP
();}
2687 $$
= NEW_WHILE
(cond
($3), $6, 1);
2690 $$ = dispatch2(while, $3, $6);
2693 | keyword_until
{COND_PUSH
(1);} expr_value do
{COND_POP
();}
2698 $$
= NEW_UNTIL
(cond
($3), $6, 1);
2701 $$ = dispatch2(until, $3, $6);
2704 | keyword_case expr_value opt_terms
2709 $$
= NEW_CASE
($2, $4);
2712 $$ = dispatch2(case, $2, $4);
2715 | keyword_case opt_terms case_body keyword_end
2718 $$
= NEW_CASE
(0, $3);
2720 $$ = dispatch2(case, Qnil, $3);
2723 | keyword_for for_var keyword_in
2734 * e.each{|*x| a, b, c = x
2738 * e.each{|x| a, = x}
2740 ID id
= internal_id
();
2741 ID
*tbl
= ALLOC_N
(ID
, 2);
2742 NODE
*m
= NEW_ARGS_AUX
(0, 0);
2745 if
(nd_type
($2) == NODE_MASGN
) {
2746 /* if args.length == 1 && args[0].kind_of?(Array)
2750 NODE
*one
= NEW_LIST
(NEW_LIT
(INT2FIX
(1)));
2751 NODE
*zero
= NEW_LIST
(NEW_LIT
(INT2FIX
(0)));
2752 m
->nd_next
= block_append
(
2755 NEW_CALL
(NEW_CALL
(NEW_DVAR
(id
), rb_intern
("length"), 0),
2756 rb_intern
("=="), one
),
2757 NEW_CALL
(NEW_CALL
(NEW_DVAR
(id
), rb_intern
("[]"), zero
),
2758 rb_intern
("kind_of?"), NEW_LIST
(NEW_LIT
(rb_cArray
))),
2761 NEW_CALL
(NEW_DVAR
(id
), rb_intern
("[]"), zero
)),
2763 node_assign
($2, NEW_DVAR
(id
)));
2766 m
->nd_next
= node_assign
(NEW_MASGN
(NEW_LIST
($2), 0), NEW_DVAR
(id
));
2769 args
= new_args
(m
, 0, id
, 0, 0);
2770 scope
= NEW_NODE
(NODE_SCOPE
, tbl
, $8, args
);
2771 tbl
[0] = 1; tbl
[1] = id
;
2772 $$
= NEW_FOR
(0, $5, scope
);
2775 $$ = dispatch3(for, $2, $5, $8);
2778 | keyword_class cpath superclass
2780 if
(in_def || in_single
)
2781 yyerror("class definition in method body");
2784 $
<num
>$
= ruby_sourceline
;
2792 $$
= NEW_CLASS
($2, $5, $3);
2793 nd_set_line
($$
, $
<num
>4);
2796 $$ = dispatch3(class, $2, $3, $5);
2799 | keyword_class tLSHFT expr
2811 $
<num
>$
= in_single
;
2823 $$
= NEW_SCLASS
($3, $7);
2827 in_single
= $
<num
>6;
2829 $$ = dispatch2(sclass, $3, $7);
2831 in_single = $<val>6;
2834 | keyword_module cpath
2836 if
(in_def || in_single
)
2837 yyerror("module definition in method body");
2840 $
<num
>$
= ruby_sourceline
;
2848 $$
= NEW_MODULE
($2, $4);
2849 nd_set_line
($$
, $
<num
>3);
2852 $$ = dispatch2(module, $2, $4);
2870 NODE
*body
= remove_begin
($5);
2871 reduce_nodes
(&body
);
2872 $$
= NEW_DEFN
($2, $4, body
, NOEX_PRIVATE
);
2878 $$ = dispatch3(def, $2, $4, $5);
2883 | keyword_def singleton dot_or_colon
{lex_state
= EXPR_FNAME
;} fname
2886 lex_state
= EXPR_END
; /* force for args */
2897 NODE
*body
= remove_begin
($8);
2898 reduce_nodes
(&body
);
2899 $$
= NEW_DEFS
($2, $5, $7, body
);
2904 $$ = dispatch5(defs, $2, $3, $5, $7, $8);
2913 $$ = dispatch1(break, arg_new());
2921 $$ = dispatch1(next, arg_new());
2929 $$ = dispatch0(redo);
2937 $$ = dispatch0(retry);
2942 primary_value
: primary
2947 if
(!$$
) $$
= NEW_NIL
();
2976 | keyword_elsif expr_value then
2981 $$
= NEW_IF
(cond
($2), $4, $5);
2984 $$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
2990 | keyword_else compstmt
2995 $$ = dispatch1(else, $2);
3007 $$
= assignable
($1, 0);
3009 $$ = dispatch1(mlhs_paren, $1);
3012 | tLPAREN f_margs rparen
3017 $$ = dispatch1(mlhs_paren, $2);
3022 f_marg_list
: f_marg
3027 $$ = mlhs_add(mlhs_new(), $1);
3030 | f_marg_list
',' f_marg
3033 $$
= list_append
($1, $3);
3035 $$ = mlhs_add($1, $3);
3040 f_margs
: f_marg_list
3043 $$
= NEW_MASGN
($1, 0);
3048 | f_marg_list
',' tSTAR f_norm_arg
3051 $$
= NEW_MASGN
($1, assignable
($4, 0));
3053 $$ = mlhs_add_star($1, $4);
3056 | f_marg_list
',' tSTAR f_norm_arg
',' f_marg_list
3059 $$
= NEW_MASGN
($1, NEW_POSTARG
(assignable
($4, 0), $6));
3061 $$ = mlhs_add_star($1, $4);
3064 | f_marg_list
',' tSTAR
3067 $$
= NEW_MASGN
($1, -1);
3069 $$ = mlhs_add_star($1, Qnil);
3072 | f_marg_list
',' tSTAR
',' f_marg_list
3075 $$
= NEW_MASGN
($1, NEW_POSTARG
(-1, $5));
3077 $$ = mlhs_add_star($1, $5);
3083 $$
= NEW_MASGN
(0, assignable
($2, 0));
3085 $$ = mlhs_add_star(mlhs_new(), $2);
3088 | tSTAR f_norm_arg
',' f_marg_list
3091 $$
= NEW_MASGN
(0, NEW_POSTARG
(assignable
($2, 0), $4));
3096 $$ = mlhs_add_star($2, $4);
3102 $$
= NEW_MASGN
(0, -1);
3104 $$ = mlhs_add_star(mlhs_new(), Qnil);
3107 | tSTAR
',' f_marg_list
3110 $$
= NEW_MASGN
(0, NEW_POSTARG
(-1, $3));
3112 $$ = mlhs_add_star(mlhs_new(), Qnil);
3117 block_param
: f_arg
',' f_rest_arg opt_f_block_arg
3120 $$
= new_args
($1, 0, $3, 0, $4);
3122 $$ = params_new($1, Qnil, $3, Qnil, escape_Qundef($4));
3128 $$
= new_args
($1, 0, 1, 0, 0);
3130 $$ = params_new($1, Qnil, Qnil, Qnil, Qnil);
3131 dispatch1(excessed_comma, $$);
3134 | f_arg
',' f_rest_arg
',' f_arg opt_f_block_arg
3137 $$
= new_args
($1, 0, $3, $5, $6);
3139 $$ = params_new($1, Qnil, $3, $5, escape_Qundef($6));
3142 | f_arg opt_f_block_arg
3145 $$
= new_args
($1, 0, 0, 0, $2);
3147 $$ = params_new($1, Qnil,Qnil, Qnil, escape_Qundef($2));
3150 | f_rest_arg opt_f_block_arg
3153 $$
= new_args
(0, 0, $1, 0, $2);
3155 $$ = params_new(Qnil, Qnil, $1, Qnil, escape_Qundef($2));
3158 | f_rest_arg
',' f_arg opt_f_block_arg
3161 $$
= new_args
(0, 0, $1, $3, $4);
3163 $$ = params_new(Qnil, Qnil, $1, $3, escape_Qundef($4));
3169 $$
= new_args
(0, 0, 0, 0, $1);
3171 $$ = params_new(Qnil, Qnil, Qnil, Qnil, $1);
3176 opt_block_param
: none
3179 command_start
= Qtrue
;
3183 block_param_def
: '|' opt_bv_decl
'|'
3188 $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil),
3197 $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil),
3201 |
'|' block_param opt_bv_decl
'|'
3206 $$ = blockvar_new(escape_Qundef($2), escape_Qundef($3));
3227 $$ = rb_ary_new2($1);
3234 rb_ary_push($$, $3);
3257 lpar_beg
= ++paren_nest
;
3266 $$
->nd_body
= NEW_SCOPE
($2->nd_head
, $3);
3270 $$ = dispatch2(lambda, $2, $3);
3275 f_larglist
: '(' f_args opt_bv_decl rparen
3278 $$
= NEW_LAMBDA
($2);
3280 $$ = dispatch1(paren, $2);
3283 | f_args opt_bv_decl
3286 $$
= NEW_LAMBDA
($1);
3293 lambda_body
: tLAMBEG compstmt
'}'
3297 | keyword_do_LAMBDA compstmt keyword_end
3303 do_block
: keyword_do_block
3307 $
<num
>$
= ruby_sourceline
;
3315 $$
= NEW_ITER
($3,$4);
3316 nd_set_line
($$
, $
<num
>2);
3319 $$ = dispatch2(do_block, escape_Qundef($3), $4);
3324 block_call
: command do_block
3327 block_dup_check
($1->nd_args
, $2);
3332 $$ = method_add_block($1, $2);
3335 | block_call
'.' operation2 opt_paren_args
3338 $$
= NEW_CALL
($1, $3, $4);
3340 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3341 $$ = method_optarg($$, $4);
3344 | block_call tCOLON2 operation2 opt_paren_args
3347 $$
= NEW_CALL
($1, $3, $4);
3349 $$ = dispatch3(call, $1, ripper_intern("::"), $3);
3350 $$ = method_optarg($$, $4);
3355 method_call
: operation paren_args
3358 $$
= NEW_FCALL
($1, $2);
3361 $$ = method_arg(dispatch1(fcall, $1), $2);
3364 | primary_value
'.' operation2 opt_paren_args
3367 $$
= NEW_CALL
($1, $3, $4);
3370 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3371 $$ = method_optarg($$, $4);
3374 | primary_value tCOLON2 operation2 paren_args
3377 $$
= NEW_CALL
($1, $3, $4);
3380 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3381 $$ = method_optarg($$, $4);
3384 | primary_value tCOLON2 operation3
3387 $$
= NEW_CALL
($1, $3, 0);
3389 $$ = dispatch3(call, $1, ripper_intern("::"), $3);
3392 | primary_value
'.' paren_args
3395 $$
= NEW_CALL
($1, rb_intern
("call"), $3);
3398 $$ = dispatch3(call, dispatch1(paren, $1),
3399 ripper_id2sym('.'), rb_intern("call"));
3400 $$ = method_optarg($$, $3);
3403 | primary_value tCOLON2 paren_args
3406 $$
= NEW_CALL
($1, rb_intern
("call"), $3);
3409 $$ = dispatch3(call, dispatch1(paren, $1),
3410 ripper_id2sym('.'), rb_intern("call"));
3411 $$ = method_optarg($$, $3);
3414 | keyword_super paren_args
3419 $$ = dispatch1(super, $2);
3427 $$ = dispatch0(zsuper);
3430 | primary_value
'[' opt_call_args rbracket
3433 if
($1 && nd_type
($1) == NODE_SELF
)
3434 $$
= NEW_FCALL
(tAREF
, $3);
3436 $$
= NEW_CALL
($1, tAREF
, $3);
3439 $$ = dispatch2(aref, $1, escape_Qundef($3));
3448 $
<num
>$
= ruby_sourceline
;
3456 $$
= NEW_ITER
($3,$4);
3457 nd_set_line
($$
, $
<num
>2);
3460 $$ = dispatch2(brace_block, escape_Qundef($3), $4);
3467 $
<num
>$
= ruby_sourceline
;
3472 compstmt keyword_end
3475 $$
= NEW_ITER
($3,$4);
3476 nd_set_line
($$
, $
<num
>2);
3479 $$ = dispatch2(do_block, escape_Qundef($3), $4);
3484 case_body
: keyword_when args then
3489 $$
= NEW_WHEN
($2, $4, $5);
3491 $$ = dispatch3(when, $2, $4, escape_Qundef($5));
3500 opt_rescue
: keyword_rescue exc_list exc_var then
3506 $3 = node_assign
($3, NEW_ERRINFO
());
3507 $5 = block_append
($3, $5);
3509 $$
= NEW_RESBODY
($2, $5, $6);
3510 fixpos
($$
, $2?
$2:$5);
3512 $$ = dispatch4(rescue,
3522 exc_list
: arg_value
3527 $$ = rb_ary_new3(1, $1);
3533 if
(!($$
= splat_array
($1))) $$
= $1;
3541 exc_var
: tASSOC lhs
3548 opt_ensure
: keyword_ensure compstmt
3553 $$ = dispatch1(ensure, $2);
3563 $$
= NEW_LIT
(ID2SYM
($1));
3565 $$ = dispatch1(symbol_literal, $1);
3576 node
= NEW_STR
(STR_NEW0
());
3579 node
= evstr2dstr
(node
);
3593 $$
= literal_concat
($1, $2);
3595 $$ = dispatch2(string_concat, $1, $2);
3600 string1
: tSTRING_BEG string_contents tSTRING_END
3605 $$ = dispatch1(string_literal, $2);
3610 xstring
: tXSTRING_BEG xstring_contents tSTRING_END
3615 node
= NEW_XSTR
(STR_NEW0
());
3618 switch
(nd_type
(node
)) {
3620 nd_set_type
(node
, NODE_XSTR
);
3623 nd_set_type
(node
, NODE_DXSTR
);
3626 node
= NEW_NODE
(NODE_DXSTR
, STR_NEW0
(), 1, NEW_LIST
(node
));
3632 $$ = dispatch1(xstring_literal, $2);
3637 regexp
: tREGEXP_BEG xstring_contents tREGEXP_END
3644 node
= NEW_LIT
(reg_compile
(STR_NEW0
(), options
));
3646 else switch
(nd_type
(node
)) {
3649 VALUE src
= node
->nd_lit
;
3650 nd_set_type
(node
, NODE_LIT
);
3651 node
->nd_lit
= reg_compile
(src
, options
);
3655 node
= NEW_NODE
(NODE_DSTR
, STR_NEW0
(), 1, NEW_LIST
(node
));
3657 if
(options
& RE_OPTION_ONCE
) {
3658 nd_set_type
(node
, NODE_DREGX_ONCE
);
3661 nd_set_type
(node
, NODE_DREGX
);
3663 node
->nd_cflag
= options
& RE_OPTION_MASK
;
3664 reg_fragment_check
(node
->nd_lit
, options
);
3665 for
(list
= node
->nd_next
; list
; list
= list
->nd_next
) {
3666 if
(nd_type
(list
->nd_head
) == NODE_STR
) {
3667 reg_fragment_check
(list
->nd_head
->nd_lit
, options
);
3674 $$ = dispatch2(regexp_literal, $2, $3);
3679 words
: tWORDS_BEG
' ' tSTRING_END
3684 $$ = dispatch0(words_new);
3687 | tWORDS_BEG word_list tSTRING_END
3693 word_list
: /* none */
3698 $$ = dispatch0(words_new);
3701 | word_list word
' '
3704 $$
= list_append
($1, evstr2dstr
($2));
3706 $$ = dispatch2(words_add, $1, $2);
3711 word
: string_content
3715 $$ = dispatch0(word_new);
3716 $$ = dispatch2(word_add, $$, $1);
3719 | word string_content
3722 $$
= literal_concat
($1, $2);
3724 $$ = dispatch2(word_add, $1, $2);
3729 qwords
: tQWORDS_BEG
' ' tSTRING_END
3734 $$ = dispatch0(qwords_new);
3737 | tQWORDS_BEG qword_list tSTRING_END
3743 qword_list
: /* none */
3748 $$ = dispatch0(qwords_new);
3751 | qword_list tSTRING_CONTENT
' '
3754 $$
= list_append
($1, $2);
3756 $$ = dispatch2(qwords_add, $1, $2);
3761 string_contents
: /* none */
3766 $$ = dispatch0(string_content);
3769 | string_contents string_content
3772 $$
= literal_concat
($1, $2);
3774 $$ = dispatch2(string_add, $1, $2);
3779 xstring_contents: /* none */
3784 $$ = dispatch0(xstring_new);
3787 | xstring_contents string_content
3790 $$
= literal_concat
($1, $2);
3792 $$ = dispatch2(xstring_add, $1, $2);
3797 string_content
: tSTRING_CONTENT
3800 $
<node
>$
= lex_strterm
;
3802 lex_state
= EXPR_BEG
;
3807 lex_strterm
= $
<node
>2;
3810 lex_strterm = $<node>2;
3811 $$ = dispatch1(string_dvar, $3);
3816 $
<node
>$
= lex_strterm
;
3818 lex_state
= EXPR_BEG
;
3824 lex_strterm
= $
<node
>2;
3828 if
($3) $3->flags
&= ~NODE_FL_NEWLINE
;
3831 $$ = dispatch1(string_embexpr, $3);
3841 $$ = dispatch1(var_ref, $1);
3849 $$ = dispatch1(var_ref, $1);
3857 $$ = dispatch1(var_ref, $1);
3863 symbol
: tSYMBEG sym
3866 lex_state
= EXPR_ENDARG
;
3869 lex_state = EXPR_ENDARG;
3870 $$ = dispatch1(symbol, $2);
3881 dsym
: tSYMBEG xstring_contents tSTRING_END
3884 lex_state
= EXPR_ENDARG
;
3886 $$
= NEW_LIT
(ID2SYM
(rb_intern
("")));
3891 switch
(nd_type
($$
)) {
3893 nd_set_type
($$
, NODE_DSYM
);
3897 $$
->nd_lit
= ID2SYM
(rb_intern_str
(lit
));
3898 nd_set_type
($$
, NODE_LIT
);
3901 $$
= NEW_NODE
(NODE_DSYM
, STR_NEW0
(), 1, NEW_LIST
($$
));
3906 lex_state = EXPR_ENDARG;
3907 $$ = dispatch1(dyna_symbol, $2);
3914 | tUMINUS_NUM tINTEGER %prec tLOWEST
3917 $$
= negate_lit
($2);
3919 $$ = dispatch2(unary, ripper_intern("-@"), $2);
3922 | tUMINUS_NUM tFLOAT %prec tLOWEST
3925 $$
= negate_lit
($2);
3927 $$ = dispatch2(unary, ripper_intern("-@"), $2);
3932 variable
: tIDENTIFIER
3937 | keyword_nil
{ifndef_ripper
($$
= keyword_nil
);}
3938 | keyword_self
{ifndef_ripper
($$
= keyword_self
);}
3939 | keyword_true
{ifndef_ripper
($$
= keyword_true
);}
3940 | keyword_false
{ifndef_ripper
($$
= keyword_false
);}
3941 | keyword__FILE__
{ifndef_ripper
($$
= keyword__FILE__
);}
3942 | keyword__LINE__
{ifndef_ripper
($$
= keyword__LINE__
);}
3943 | keyword__ENCODING__
{ifndef_ripper
($$
= keyword__ENCODING__
);}
3949 if
(!($$
= gettable
($1))) $$
= NEW_BEGIN
(0);
3951 $$ = dispatch1(var_ref, $1);
3959 $$
= assignable
($1, 0);
3961 $$ = dispatch1(var_field, $1);
3980 lex_state
= EXPR_BEG
;
3998 f_arglist
: '(' f_args rparen
4002 lex_state
= EXPR_BEG
;
4003 command_start
= Qtrue
;
4005 $$ = dispatch1(paren, $2);
4006 lex_state = EXPR_BEG;
4007 command_start = Qtrue;
4016 f_args
: f_arg
',' f_optarg
',' f_rest_arg opt_f_block_arg
4019 $$
= new_args
($1, $3, $5, 0, $6);
4021 $$ = params_new($1, $3, $5, Qnil, escape_Qundef($6));
4024 | f_arg
',' f_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
4027 $$
= new_args
($1, $3, $5, $7, $8);
4029 $$ = params_new($1, $3, $5, $7, escape_Qundef($8));
4032 | f_arg
',' f_optarg opt_f_block_arg
4035 $$
= new_args
($1, $3, 0, 0, $4);
4037 $$ = params_new($1, $3, Qnil, Qnil, escape_Qundef($4));
4040 | f_arg
',' f_optarg
',' f_arg opt_f_block_arg
4043 $$
= new_args
($1, $3, 0, $5, $6);
4045 $$ = params_new($1, $3, Qnil, $5, escape_Qundef($6));
4048 | f_arg
',' f_rest_arg opt_f_block_arg
4051 $$
= new_args
($1, 0, $3, 0, $4);
4053 $$ = params_new($1, Qnil, $3, Qnil, escape_Qundef($4));
4056 | f_arg
',' f_rest_arg
',' f_arg opt_f_block_arg
4059 $$
= new_args
($1, 0, $3, $5, $6);
4061 $$ = params_new($1, Qnil, $3, $5, escape_Qundef($6));
4064 | f_arg opt_f_block_arg
4067 $$
= new_args
($1, 0, 0, 0, $2);
4069 $$ = params_new($1, Qnil, Qnil, Qnil,escape_Qundef($2));
4072 | f_optarg
',' f_rest_arg opt_f_block_arg
4075 $$
= new_args
(0, $1, $3, 0, $4);
4077 $$ = params_new(Qnil, $1, $3, Qnil, escape_Qundef($4));
4080 | f_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
4083 $$
= new_args
(0, $1, $3, $5, $6);
4085 $$ = params_new(Qnil, $1, $3, $5, escape_Qundef($6));
4088 | f_optarg opt_f_block_arg
4091 $$
= new_args
(0, $1, 0, 0, $2);
4093 $$ = params_new(Qnil, $1, Qnil, Qnil,escape_Qundef($2));
4096 | f_optarg
',' f_arg opt_f_block_arg
4099 $$
= new_args
(0, $1, 0, $3, $4);
4101 $$ = params_new(Qnil, $1, Qnil, $3, escape_Qundef($4));
4104 | f_rest_arg opt_f_block_arg
4107 $$
= new_args
(0, 0, $1, 0, $2);
4109 $$ = params_new(Qnil, Qnil, $1, Qnil,escape_Qundef($2));
4112 | f_rest_arg
',' f_arg opt_f_block_arg
4115 $$
= new_args
(0, 0, $1, $3, $4);
4117 $$ = params_new(Qnil, Qnil, $1, $3, escape_Qundef($4));
4123 $$
= new_args
(0, 0, 0, 0, $1);
4125 $$ = params_new(Qnil, Qnil, Qnil, Qnil, $1);
4131 $$
= new_args
(0, 0, 0, 0, 0);
4133 $$ = params_new(Qnil, Qnil, Qnil, Qnil, Qnil);
4138 f_bad_arg
: tCONSTANT
4141 yyerror("formal argument cannot be a constant");
4144 $$ = dispatch1(param_error, $1);
4150 yyerror("formal argument cannot be an instance variable");
4153 $$ = dispatch1(param_error, $1);
4159 yyerror("formal argument cannot be a global variable");
4162 $$ = dispatch1(param_error, $1);
4168 yyerror("formal argument cannot be a class variable");
4171 $$ = dispatch1(param_error, $1);
4176 f_norm_arg
: f_bad_arg
4180 if
(!is_local_id
($1))
4181 yyerror("formal argument must be local variable");
4189 f_arg_item
: f_norm_arg
4193 $$
= NEW_ARGS_AUX
($1, 1);
4197 | tLPAREN f_margs rparen
4200 ID tid
= internal_id
();
4202 if
(dyna_in_block
()) {
4203 $2->nd_value
= NEW_DVAR
(tid
);
4206 $2->nd_value
= NEW_LVAR
(tid
);
4208 $$
= NEW_ARGS_AUX
(tid
, 1);
4211 $$ = dispatch1(mlhs_paren, $2);
4220 $$ = rb_ary_new3(1, $1);
4223 | f_arg
',' f_arg_item
4228 $$
->nd_next
= block_append
($$
->nd_next
, $3->nd_next
);
4229 rb_gc_force_recycle
((VALUE
)$3);
4231 $$ = rb_ary_push($1, $3);
4236 f_opt
: tIDENTIFIER
'=' arg_value
4239 if
(!is_local_id
($1))
4240 yyerror("formal argument must be local variable");
4243 $$
= NEW_OPT_ARG
(0, assignable
($1, $3));
4245 $$ = rb_assoc_new($1, $3);
4255 $$ = rb_ary_new3(1, $1);
4258 | f_optarg
',' f_opt
4263 while
(opts
->nd_next
) {
4264 opts
= opts
->nd_next
;
4269 $$ = rb_ary_push($1, $3);
4278 f_rest_arg
: restarg_mark tIDENTIFIER
4281 if
(!is_local_id
($2))
4282 yyerror("rest argument must be local variable");
4287 $$ = dispatch1(rest_param, $2);
4296 $$ = dispatch1(rest_param, Qnil);
4305 f_block_arg
: blkarg_mark tIDENTIFIER
4308 if
(!is_local_id
($2))
4309 yyerror("block argument must be local variable");
4310 else if
(!dyna_in_block
() && local_id
($2))
4311 yyerror("duplicated block argument name");
4316 $$ = dispatch1(blockarg, $2);
4321 opt_f_block_arg
: ',' f_block_arg
4340 if
(!$$
) $$
= NEW_NIL
();
4345 |
'(' {lex_state
= EXPR_BEG
;} expr rparen
4349 yyerror("can't define singleton method for ().");
4352 switch
(nd_type
($3)) {
4361 yyerror("can't define singleton method for literals");
4369 $$ = dispatch1(paren, $3);
4380 $$ = dispatch1(assoclist_from_args, $1);
4389 $$ = rb_ary_new3(1, $1);
4395 $$
= list_concat
($1, $3);
4397 $$ = rb_ary_push($1, $3);
4402 assoc
: arg_value tASSOC arg_value
4405 $$
= list_append
(NEW_LIST
($1), $3);
4407 $$ = dispatch2(assoc_new, $1, $3);
4413 $$
= list_append
(NEW_LIST
(NEW_LIT
(ID2SYM
($1))), $2);
4415 $$ = dispatch2(assoc_new, $1, $2);
4420 operation
: tIDENTIFIER
4425 operation2
: tIDENTIFIER
4431 operation3
: tIDENTIFIER
4448 opt_terms
: /* none */
4459 rbracket
: opt_nl
']'
4462 trailer
: /* none */
4467 term
: ';' {yyerrok;}
4472 | terms
';' {yyerrok;}
4488 # define yylval (*((YYSTYPE*)(parser->parser_yylval)))
4490 static int parser_regx_options
(struct parser_params
*);
4491 static int parser_tokadd_string
(struct parser_params
*,int,int,int,long*,rb_encoding
**);
4492 static void parser_tokaddmbc
(struct parser_params
*parser
, int c
, rb_encoding
*enc
);
4493 static int parser_parse_string
(struct parser_params
*,NODE
*);
4494 static int parser_here_document
(struct parser_params
*,NODE
*);
4497 # define nextc() parser_nextc(parser)
4498 # define pushback(c) parser_pushback(parser, c)
4499 # define newtok() parser_newtok(parser)
4500 # define tokspace(n) parser_tokspace(parser, n)
4501 # define tokadd(c) parser_tokadd(parser, c)
4502 # define tok_hex(numlen) parser_tok_hex(parser, numlen)
4503 # define read_escape(flags,e) parser_read_escape(parser, flags, e)
4504 # define tokadd_escape(e) parser_tokadd_escape(parser, e)
4505 # define regx_options() parser_regx_options(parser)
4506 # define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser,f,t,p,n,e)
4507 # define parse_string(n) parser_parse_string(parser,n)
4508 # define tokaddmbc(c, enc) parser_tokaddmbc(parser, c, enc)
4509 # define here_document(n) parser_here_document(parser,n)
4510 # define heredoc_identifier() parser_heredoc_identifier(parser)
4511 # define heredoc_restore(n) parser_heredoc_restore(parser,n)
4512 # define whole_match_p(e,l,i) parser_whole_match_p(parser,e,l,i)
4516 # define local_id(x) 1
4517 # define dyna_in_block() 1
4521 # define set_yylval_str(x) yylval.node = NEW_STR(x)
4522 # define set_yylval_num(x) yylval.num = x
4523 # define set_yylval_id(x) yylval.id = x
4524 # define set_yylval_literal(x) yylval.node = NEW_LIT(x)
4525 # define set_yylval_node(x) yylval.node = x
4526 # define yylval_id() yylval.id
4528 # define set_yylval_str(x) (void)(x)
4529 # define set_yylval_num(x) (void)(x)
4530 # define set_yylval_id(x) (void)(x)
4531 # define set_yylval_literal(x) (void)(x)
4532 # define set_yylval_node(x) (void)(x)
4533 # define yylval_id() SYM2ID(yylval.val)
4537 #define ripper_flush(p) (p->tokp = p->parser_lex_p)
4540 ripper_dispatch_scan_event
(struct parser_params
*parser
, int t
)
4544 if
(lex_p
< parser
->tokp
) rb_raise
(rb_eRuntimeError
, "lex_p < tokp");
4545 if
(lex_p
== parser
->tokp
) return
;
4546 str
= STR_NEW
(parser
->tokp
, lex_p
- parser
->tokp
);
4547 yylval.val
= ripper_dispatch1
(parser
, ripper_token2eventid
(t
), str
);
4548 ripper_flush
(parser
);
4552 ripper_dispatch_delayed_token
(struct parser_params
*parser
, int t
)
4554 int saved_line
= ruby_sourceline
;
4555 const char *saved_tokp
= parser
->tokp
;
4557 ruby_sourceline
= parser
->delayed_line
;
4558 parser
->tokp
= lex_pbeg
+ parser
->delayed_col
;
4559 yylval.val
= ripper_dispatch1
(parser
, ripper_token2eventid
(t
), parser
->delayed
);
4560 parser
->delayed
= Qnil
;
4561 ruby_sourceline
= saved_line
;
4562 parser
->tokp
= saved_tokp
;
4566 #include "ruby/regex.h"
4567 #include "ruby/util.h"
4569 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
4570 since ours (we hope) works properly with all combinations of
4571 machines, compilers, `char' and `unsigned char' argument types.
4572 (Per Bothner suggested the basic approach.) */
4573 #undef SIGN_EXTEND_CHAR
4575 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
4576 #else /* not __STDC__ */
4577 /* As in Harbison and Steele. */
4578 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
4581 #define parser_mbclen() mbclen((lex_p-1),lex_pend,parser->enc)
4582 #define parser_precise_mbclen() rb_enc_precise_mbclen((lex_p-1),lex_pend,parser->enc)
4583 #define is_identchar(p,e,enc) (rb_enc_isalnum(*p,enc) || (*p) == '_' || !ISASCII(*p))
4584 #define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,parser->enc))
4586 #define parser_isascii() ISASCII(*(lex_p-1))
4589 parser_yyerror
(struct parser_params
*parser
, const char *msg
)
4592 const int max_line_margin
= 30;
4597 compile_error
(PARSER_ARG
"%s", msg
);
4599 while
(lex_pbeg
<= p
) {
4600 if
(*p
== '\n') break
;
4606 while
(pe
< lex_pend
) {
4607 if
(*pe
== '\n') break
;
4614 const char *pre
= "", *post
= "";
4616 if
(len
> max_line_margin
* 2 + 10) {
4617 if
(lex_p
- p
> max_line_margin
) {
4618 p
= rb_enc_prev_char
(p
, lex_p
- max_line_margin
, rb_enc_get
(lex_lastline
));
4621 if
(pe
- lex_p
> max_line_margin
) {
4622 pe
= rb_enc_prev_char
(lex_p
, lex_p
+ max_line_margin
, rb_enc_get
(lex_lastline
));
4627 buf
= ALLOCA_N
(char, len
+2);
4628 MEMCPY
(buf
, p
, char, len
);
4630 rb_compile_error_append
("%s%s%s", pre
, buf
, post
);
4633 p2
= buf
; pe
= buf
+ len
;
4636 if
(*p2
!= '\t') *p2
= ' ';
4641 rb_compile_error_append
("%s%s", pre
, buf
);
4644 dispatch1
(parse_error
, STR_NEW2
(msg
));
4645 #endif /* !RIPPER */
4649 static void parser_prepare
(struct parser_params
*parser
);
4652 VALUE ruby_suppress_tracing
(VALUE
(*func
)(VALUE
, int), VALUE arg
, int always
);
4655 debug_lines
(const char *f
)
4657 if
(rb_const_defined_at
(rb_cObject
, rb_intern
("SCRIPT_LINES__"))) {
4658 VALUE hash
= rb_const_get_at
(rb_cObject
, rb_intern
("SCRIPT_LINES__"));
4659 if
(TYPE
(hash
) == T_HASH
) {
4660 VALUE fname
= rb_str_new2
(f
);
4661 VALUE lines
= rb_ary_new
();
4662 rb_hash_aset
(hash
, fname
, lines
);
4670 coverage
(const char *f
, int n
)
4672 extern VALUE rb_get_coverages
(void);
4673 VALUE coverages
= rb_get_coverages
();
4674 if
(RTEST
(coverages
) && RBASIC
(coverages
)->klass
== 0) {
4675 VALUE fname
= rb_str_new2
(f
);
4676 VALUE lines
= rb_ary_new2
(n
);
4678 RBASIC
(lines
)->klass
= 0;
4679 for
(i
= 0; i
< n
; i
++) RARRAY_PTR
(lines
)[i
] = Qnil
;
4680 RARRAY
(lines
)->len
= n
;
4681 rb_hash_aset
(coverages
, fname
, lines
);
4688 e_option_supplied
(struct parser_params
*parser
)
4690 if
(strcmp
(ruby_sourcefile
, "-e") == 0)
4696 yycompile0
(VALUE arg
, int tracing
)
4700 struct parser_params
*parser
= (struct parser_params
*)arg
;
4702 if
(!compile_for_eval
&& rb_safe_level
() == 0) {
4703 ruby_debug_lines
= debug_lines
(ruby_sourcefile
);
4704 if
(ruby_debug_lines
&& ruby_sourceline
> 0) {
4705 VALUE str
= STR_NEW0
();
4706 n
= ruby_sourceline
;
4708 rb_ary_push
(ruby_debug_lines
, str
);
4712 if
(!e_option_supplied
(parser
)) {
4713 ruby_coverage
= coverage
(ruby_sourcefile
, ruby_sourceline
);
4717 parser_prepare
(parser
);
4719 n
= yyparse((void*)parser
);
4720 ruby_debug_lines
= 0;
4722 compile_for_eval
= 0;
4725 lex_p
= lex_pbeg
= lex_pend
= 0;
4726 lex_lastline
= lex_nextline
= 0;
4730 tree
= ruby_eval_tree
;
4734 if
(ruby_eval_tree_begin
) {
4735 NODE
*scope
= ruby_eval_tree
;
4738 scope
->nd_body
= NEW_PRELUDE
(ruby_eval_tree_begin
, scope
->nd_body
);
4743 tree
= ruby_eval_tree
;
4749 yycompile
(struct parser_params
*parser
, const char *f
, int line
)
4751 ruby_sourcefile
= ruby_strdup
(f
);
4752 ruby_sourceline
= line
- 1;
4753 return
(NODE
*)ruby_suppress_tracing
(yycompile0
, (VALUE
)parser
, Qtrue
);
4755 #endif /* !RIPPER */
4758 lex_get_str
(struct parser_params
*parser
, VALUE s
)
4760 char *beg
, *end
, *pend
;
4762 beg
= RSTRING_PTR
(s
);
4764 if
(RSTRING_LEN
(s
) == lex_gets_ptr
) return Qnil
;
4765 beg
+= lex_gets_ptr
;
4767 pend
= RSTRING_PTR
(s
) + RSTRING_LEN
(s
);
4769 while
(end
< pend
) {
4770 if
(*end
++ == '\n') break
;
4772 lex_gets_ptr
= end
- RSTRING_PTR
(s
);
4773 return rb_enc_str_new
(beg
, end
- beg
, rb_enc_get
(s
));
4777 lex_getline
(struct parser_params
*parser
)
4779 VALUE line
= (*parser
->parser_lex_gets
)(parser
, parser
->parser_lex_input
);
4781 if
(ruby_debug_lines
&& !NIL_P
(line
)) {
4782 rb_ary_push
(ruby_debug_lines
, line
);
4784 if
(ruby_coverage
&& !NIL_P
(line
)) {
4785 rb_ary_push
(ruby_coverage
, Qnil
);
4793 rb_compile_string
(const char *f
, VALUE s
, int line
)
4795 VALUE volatile vparser
= rb_parser_new
();
4797 return rb_parser_compile_string
(vparser
, f
, s
, line
);
4801 rb_parser_compile_string
(volatile VALUE vparser
, const char *f
, VALUE s
, int line
)
4803 struct parser_params
*parser
;
4807 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
4808 lex_gets
= lex_get_str
;
4811 lex_pbeg
= lex_p
= lex_pend
= 0;
4812 compile_for_eval
= rb_parse_in_eval
();
4814 node
= yycompile
(parser
, f
, line
);
4815 tmp
= vparser
; /* prohibit tail call optimization */
4821 rb_compile_cstr
(const char *f
, const char *s
, int len
, int line
)
4823 return rb_compile_string
(f
, rb_str_new
(s
, len
), line
);
4827 rb_parser_compile_cstr
(volatile VALUE vparser
, const char *f
, const char *s
, int len
, int line
)
4829 return rb_parser_compile_string
(vparser
, f
, rb_str_new
(s
, len
), line
);
4833 lex_io_gets
(struct parser_params
*parser
, VALUE io
)
4835 return rb_io_gets
(io
);
4839 rb_compile_file
(const char *f
, VALUE file
, int start
)
4841 VALUE volatile vparser
= rb_parser_new
();
4843 return rb_parser_compile_file
(vparser
, f
, file
, start
);
4847 rb_parser_compile_file
(volatile VALUE vparser
, const char *f
, VALUE file
, int start
)
4849 struct parser_params
*parser
;
4853 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
4854 lex_gets
= lex_io_gets
;
4856 lex_pbeg
= lex_p
= lex_pend
= 0;
4858 node
= yycompile
(parser
, f
, start
);
4859 tmp
= vparser
; /* prohibit tail call optimization */
4863 #endif /* !RIPPER */
4865 #define STR_FUNC_ESCAPE 0x01
4866 #define STR_FUNC_EXPAND 0x02
4867 #define STR_FUNC_REGEXP 0x04
4868 #define STR_FUNC_QWORDS 0x08
4869 #define STR_FUNC_SYMBOL 0x10
4870 #define STR_FUNC_INDENT 0x20
4874 str_dquote
= (STR_FUNC_EXPAND
),
4875 str_xquote
= (STR_FUNC_EXPAND
),
4876 str_regexp
= (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND
),
4877 str_sword
= (STR_FUNC_QWORDS
),
4878 str_dword
= (STR_FUNC_QWORDS|STR_FUNC_EXPAND
),
4879 str_ssym
= (STR_FUNC_SYMBOL
),
4880 str_dsym
= (STR_FUNC_SYMBOL|STR_FUNC_EXPAND
)
4884 parser_str_new
(const char *p
, long n
, rb_encoding
*enc
, int func
, rb_encoding
*enc0
)
4888 str
= rb_enc_str_new
(p
, n
, enc
);
4889 if
(!(func
& STR_FUNC_REGEXP
) && rb_enc_asciicompat
(enc
)) {
4890 if
(rb_enc_str_coderange
(str
) == ENC_CODERANGE_7BIT
) {
4891 rb_enc_associate
(str
, rb_usascii_encoding
());
4893 else if
(enc0
== rb_usascii_encoding
() && enc
!= rb_utf8_encoding
()) {
4894 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
4901 #define lex_goto_eol(parser) (parser->parser_lex_p = parser->parser_lex_pend)
4904 parser_nextc
(struct parser_params
*parser
)
4908 if
(lex_p
== lex_pend
) {
4909 VALUE v
= lex_nextline
;
4915 if
(!lex_input || NIL_P
(v
= lex_getline
(parser
))) {
4916 parser
->eofp
= Qtrue
;
4917 lex_goto_eol
(parser
);
4923 if
(parser
->tokp
< lex_pend
) {
4924 if
(NIL_P
(parser
->delayed
)) {
4925 parser
->delayed
= rb_str_buf_new
(1024);
4926 rb_str_buf_cat
(parser
->delayed
,
4927 parser
->tokp
, lex_pend
- parser
->tokp
);
4928 parser
->delayed_line
= ruby_sourceline
;
4929 parser
->delayed_col
= parser
->tokp
- lex_pbeg
;
4932 rb_str_buf_cat
(parser
->delayed
,
4933 parser
->tokp
, lex_pend
- parser
->tokp
);
4937 if
(heredoc_end
> 0) {
4938 ruby_sourceline
= heredoc_end
;
4942 parser
->line_count
++;
4943 lex_pbeg
= lex_p
= RSTRING_PTR
(v
);
4944 lex_pend
= lex_p
+ RSTRING_LEN
(v
);
4946 ripper_flush
(parser
);
4951 c
= (unsigned char)*lex_p
++;
4952 if
(c
== '\r' && lex_p
< lex_pend
&& *lex_p
== '\n') {
4961 parser_pushback
(struct parser_params
*parser
, int c
)
4963 if
(c
== -1) return
;
4965 if
(lex_p
> lex_pbeg
&& lex_p
[0] == '\n' && lex_p
[-1] == '\r') {
4970 #define was_bol() (lex_p == lex_pbeg + 1)
4971 #define peek(c) (lex_p != lex_pend && (c) == *lex_p)
4973 #define tokfix() (tokenbuf[tokidx]='\0')
4974 #define tok() tokenbuf
4975 #define toklen() tokidx
4976 #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
4979 parser_newtok
(struct parser_params
*parser
)
4984 tokenbuf
= ALLOC_N
(char, 60);
4986 if
(toksiz
> 4096) {
4988 REALLOC_N
(tokenbuf
, char, 60);
4994 parser_tokspace
(struct parser_params
*parser
, int n
)
4998 if
(tokidx
>= toksiz
) {
4999 do
{toksiz
*= 2;} while
(toksiz
< tokidx
);
5000 REALLOC_N
(tokenbuf
, char, toksiz
);
5002 return
&tokenbuf
[tokidx
-n
];
5006 parser_tokadd
(struct parser_params
*parser
, int c
)
5008 tokenbuf
[tokidx
++] = (char)c
;
5009 if
(tokidx
>= toksiz
) {
5011 REALLOC_N
(tokenbuf
, char, toksiz
);
5016 parser_tok_hex
(struct parser_params
*parser
, int *numlen
)
5020 c
= scan_hex
(lex_p
, 2, numlen
);
5022 yyerror("invalid hex escape");
5029 #define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
5032 parser_tokadd_utf8
(struct parser_params
*parser
, rb_encoding
**encp
,
5033 int string_literal
, int symbol_literal
, int regexp_literal
)
5036 * If string_literal is true, then we allow multiple codepoints
5037 * in \u{}, and add the codepoints to the current token.
5038 * Otherwise we're parsing a character literal and return a single
5039 * codepoint without adding it
5045 if
(regexp_literal
) { tokadd
('\\'); tokadd
('u'); }
5047 if
(peek
('{')) { /* handle \u{...} form */
5049 if
(regexp_literal
) { tokadd
(*lex_p
); }
5051 codepoint
= scan_hex
(lex_p
, 6, &numlen
);
5053 yyerror("invalid Unicode escape");
5056 if
(codepoint
> 0x10ffff) {
5057 yyerror("invalid Unicode codepoint (too large)");
5061 if
(regexp_literal
) {
5064 else if
(codepoint
>= 0x80) {
5066 if
(string_literal
) tokaddmbc
(codepoint
, *encp
);
5068 else if
(string_literal
) {
5069 if
(codepoint
== 0 && symbol_literal
) {
5070 yyerror("symbol cannot contain '\\u{0}'");
5076 } while
(string_literal
&& (peek
(' ') || peek
('\t')));
5079 yyerror("unterminated Unicode escape");
5083 if
(regexp_literal
) { tokadd
('}'); }
5086 else
{ /* handle \uxxxx form */
5087 codepoint
= scan_hex
(lex_p
, 4, &numlen
);
5089 yyerror("invalid Unicode escape");
5093 if
(regexp_literal
) {
5096 else if
(codepoint
>= 0x80) {
5098 if
(string_literal
) tokaddmbc
(codepoint
, *encp
);
5100 else if
(string_literal
) {
5101 if
(codepoint
== 0 && symbol_literal
) {
5102 yyerror("symbol cannot contain '\\u0000'");
5113 #define ESCAPE_CONTROL 1
5114 #define ESCAPE_META 2
5117 parser_read_escape
(struct parser_params
*parser
, int flags
,
5123 switch
(c
= nextc
()) {
5124 case
'\\': /* Backslash */
5127 case
'n': /* newline */
5130 case
't': /* horizontal tab */
5133 case
'r': /* carriage-return */
5136 case
'f': /* form-feed */
5139 case
'v': /* vertical tab */
5142 case
'a': /* alarm(bell) */
5145 case
'e': /* escape */
5148 case
'0': case
'1': case
'2': case
'3': /* octal constant */
5149 case
'4': case
'5': case
'6': case
'7':
5150 if
(flags
& (ESCAPE_CONTROL|ESCAPE_META
)) goto eof
;
5155 c
= scan_oct
(lex_p
, 3, &numlen
);
5160 case
'x': /* hex constant */
5161 if
(flags
& (ESCAPE_CONTROL|ESCAPE_META
)) goto eof
;
5162 c
= tok_hex
(&numlen
);
5163 if
(numlen
== 0) return
0;
5166 case
'b': /* backspace */
5169 case
's': /* space */
5173 if
(flags
& ESCAPE_META
) goto eof
;
5174 if
((c
= nextc
()) != '-') {
5178 if
((c
= nextc
()) == '\\') {
5179 return read_escape
(flags|ESCAPE_META
, encp
) |
0x80;
5181 else if
(c
== -1 ||
!ISASCII
(c
)) goto eof
;
5183 return
((c
& 0xff) |
0x80);
5187 if
((c
= nextc
()) != '-') {
5192 if
(flags
& ESCAPE_CONTROL
) goto eof
;
5193 if
((c
= nextc
())== '\\') {
5194 c
= read_escape
(flags|ESCAPE_CONTROL
, encp
);
5198 else if
(c
== -1 ||
!ISASCII
(c
)) goto eof
;
5203 yyerror("Invalid escape character syntax");
5212 parser_tokaddmbc
(struct parser_params
*parser
, int c
, rb_encoding
*enc
)
5214 int len
= rb_enc_codelen
(c
, enc
);
5215 rb_enc_mbcput
(c
, tokspace
(len
), enc
);
5219 parser_tokadd_escape
(struct parser_params
*parser
, rb_encoding
**encp
)
5225 switch
(c
= nextc
()) {
5227 return
0; /* just ignore */
5229 case
'0': case
'1': case
'2': case
'3': /* octal constant */
5230 case
'4': case
'5': case
'6': case
'7':
5231 if
(flags
& (ESCAPE_CONTROL|ESCAPE_META
)) goto eof
;
5236 oct
= scan_oct
(--lex_p
, 3, &numlen
);
5237 if
(numlen
== 0) goto eof
;
5239 tokcopy
(numlen
+ 1);
5243 case
'x': /* hex constant */
5244 if
(flags
& (ESCAPE_CONTROL|ESCAPE_META
)) goto eof
;
5249 hex
= tok_hex
(&numlen
);
5250 if
(numlen
== 0) goto eof
;
5251 tokcopy
(numlen
+ 2);
5256 if
(flags
& ESCAPE_META
) goto eof
;
5257 if
((c
= nextc
()) != '-') {
5262 flags |
= ESCAPE_META
;
5266 if
(flags
& ESCAPE_CONTROL
) goto eof
;
5267 if
((c
= nextc
()) != '-') {
5275 if
(flags
& ESCAPE_CONTROL
) goto eof
;
5277 flags |
= ESCAPE_CONTROL
;
5279 if
((c
= nextc
()) == '\\') {
5282 else if
(c
== -1) goto eof
;
5288 yyerror("Invalid escape character syntax");
5298 extern
int rb_char_to_option_kcode
(int c
, int *option
, int *kcode
);
5301 parser_regx_options
(struct parser_params
*parser
)
5308 while
(c
= nextc
(), ISALPHA
(c
)) {
5310 options |
= RE_OPTION_ONCE
;
5312 else if
(rb_char_to_option_kcode
(c
, &opt
, &kc
)) {
5314 if
(kc
>= 0) kcode
= c
;
5323 compile_error
(PARSER_ARG
"unknown regexp option%s - %s",
5324 toklen
() > 1 ?
"s" : "", tok
());
5326 return options | RE_OPTION_ENCODING
(kcode
);
5330 dispose_string
(VALUE str
)
5332 /* TODO: should use another API? */
5333 if
(RBASIC
(str
)->flags
& RSTRING_NOEMBED
)
5334 xfree
(RSTRING_PTR
(str
));
5335 rb_gc_force_recycle
(str
);
5339 parser_tokadd_mbchar
(struct parser_params
*parser
, int c
)
5341 int len
= parser_precise_mbclen
();
5342 if
(!MBCLEN_CHARFOUND_P
(len
)) {
5343 compile_error
(PARSER_ARG
"invalid multibyte char");
5348 if
(len
> 0) tokcopy
(len
);
5352 #define tokadd_mbchar(c) parser_tokadd_mbchar(parser, c)
5355 parser_tokadd_string
(struct parser_params
*parser
,
5356 int func
, int term
, int paren
, long *nest
,
5360 int has_nonascii
= 0;
5361 rb_encoding
*enc
= *encp
;
5363 static const char mixed_msg
[] = "%s mixed within %s source";
5365 #define mixed_error(enc1, enc2) if (!errbuf) { \
5366 int len
= sizeof
(mixed_msg
) - 4; \
5367 len
+= strlen
(rb_enc_name
(enc1
)); \
5368 len
+= strlen
(rb_enc_name
(enc2
)); \
5369 errbuf
= ALLOCA_N
(char, len
); \
5370 snprintf
(errbuf
, len
, mixed_msg
, \
5371 rb_enc_name
(enc1
), \
5372 rb_enc_name
(enc2
)); \
5375 #define mixed_escape(beg, enc1, enc2) do { \
5376 const char *pos
= lex_p
; \
5378 mixed_error
(enc1
, enc2
); \
5382 while
((c
= nextc
()) != -1) {
5383 if
(paren
&& c
== paren
) {
5386 else if
(c
== term
) {
5387 if
(!nest ||
!*nest
) {
5393 else if
((func
& STR_FUNC_EXPAND
) && c
== '#' && lex_p
< lex_pend
) {
5395 if
(c2
== '$' || c2
== '@' || c2
== '{') {
5400 else if
(c
== '\\') {
5401 const char *beg
= lex_p
- 1;
5405 if
(func
& STR_FUNC_QWORDS
) break
;
5406 if
(func
& STR_FUNC_EXPAND
) continue
;
5411 if
(func
& STR_FUNC_ESCAPE
) tokadd
(c
);
5415 if
((func
& STR_FUNC_EXPAND
) == 0) {
5419 parser_tokadd_utf8
(parser
, &enc
, 1,
5420 func
& STR_FUNC_SYMBOL
,
5421 func
& STR_FUNC_REGEXP
);
5422 if
(has_nonascii
&& enc
!= *encp
) {
5423 mixed_escape
(beg
, enc
, *encp
);
5428 if
(func
& STR_FUNC_REGEXP
) {
5430 if
((c
= tokadd_escape
(&enc
)) < 0)
5432 if
(has_nonascii
&& enc
!= *encp
) {
5433 mixed_escape
(beg
, enc
, *encp
);
5437 else if
(func
& STR_FUNC_EXPAND
) {
5439 if
(func
& STR_FUNC_ESCAPE
) tokadd
('\\');
5440 c
= read_escape
(0, &enc
);
5442 else if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
5443 /* ignore backslashed spaces in %w */
5445 else if
(c
!= term
&& !(paren
&& c
== paren
)) {
5450 else if
(!parser_isascii
()) {
5453 mixed_error
(enc
, *encp
);
5456 if
(tokadd_mbchar
(c
) == -1) return
-1;
5459 else if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
5463 if
(!c
&& (func
& STR_FUNC_SYMBOL
)) {
5464 func
&= ~STR_FUNC_SYMBOL
;
5465 compile_error
(PARSER_ARG
"symbol cannot contain '\\0'");
5471 mixed_error
(enc
, *encp
);
5481 #define NEW_STRTERM(func, term, paren) \
5482 rb_node_newnode
(NODE_STRTERM
, (func
), (term
) |
((paren
) << (CHAR_BIT
* 2)), 0)
5485 parser_parse_string
(struct parser_params
*parser
, NODE
*quote
)
5487 int func
= quote
->nd_func
;
5488 int term
= nd_term
(quote
);
5489 int paren
= nd_paren
(quote
);
5491 rb_encoding
*enc
= parser
->enc
;
5493 if
(func
== -1) return tSTRING_END
;
5495 if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
5496 do
{c
= nextc
();} while
(ISSPACE
(c
));
5499 if
(c
== term
&& !quote
->nd_nest
) {
5500 if
(func
& STR_FUNC_QWORDS
) {
5501 quote
->nd_func
= -1;
5504 if
(!(func
& STR_FUNC_REGEXP
)) return tSTRING_END
;
5505 set_yylval_num
(regx_options
());
5513 if
((func
& STR_FUNC_EXPAND
) && c
== '#') {
5514 switch
(c
= nextc
()) {
5518 return tSTRING_DVAR
;
5520 return tSTRING_DBEG
;
5525 if
(tokadd_string
(func
, term
, paren
, "e
->nd_nest
,
5527 ruby_sourceline
= nd_line
(quote
);
5528 if
(func
& STR_FUNC_REGEXP
) {
5530 compile_error
(PARSER_ARG
"unterminated regexp meets end of file");
5535 compile_error
(PARSER_ARG
"unterminated string meets end of file");
5541 set_yylval_str
(STR_NEW3
(tok
(), toklen
(), enc
, func
));
5542 return tSTRING_CONTENT
;
5546 parser_heredoc_identifier
(struct parser_params
*parser
)
5548 int c
= nextc
(), term
, func
= 0, len
;
5552 func
= STR_FUNC_INDENT
;
5556 func |
= str_squote
; goto quoted
;
5558 func |
= str_dquote
; goto quoted
;
5565 while
((c
= nextc
()) != -1 && c
!= term
) {
5566 if
(tokadd_mbchar
(c
) == -1) return
0;
5569 compile_error
(PARSER_ARG
"unterminated here document identifier");
5575 if
(!parser_is_identchar
()) {
5577 if
(func
& STR_FUNC_INDENT
) {
5584 tokadd
(func |
= str_dquote
);
5586 if
(tokadd_mbchar
(c
) == -1) return
0;
5587 } while
((c
= nextc
()) != -1 && parser_is_identchar
());
5594 ripper_dispatch_scan_event
(parser
, tHEREDOC_BEG
);
5596 len
= lex_p
- lex_pbeg
;
5597 lex_goto_eol
(parser
);
5598 lex_strterm
= rb_node_newnode
(NODE_HEREDOC
,
5599 STR_NEW
(tok
(), toklen
()), /* nd_lit */
5601 lex_lastline
); /* nd_orig */
5602 nd_set_line
(lex_strterm
, ruby_sourceline
);
5604 ripper_flush
(parser
);
5606 return term
== '`' ? tXSTRING_BEG
: tSTRING_BEG
;
5610 parser_heredoc_restore
(struct parser_params
*parser
, NODE
*here
)
5615 if
(!NIL_P
(parser
->delayed
))
5616 ripper_dispatch_delayed_token
(parser
, tSTRING_CONTENT
);
5617 lex_goto_eol
(parser
);
5618 ripper_dispatch_scan_event
(parser
, tHEREDOC_END
);
5620 line
= here
->nd_orig
;
5621 lex_lastline
= line
;
5622 lex_pbeg
= RSTRING_PTR
(line
);
5623 lex_pend
= lex_pbeg
+ RSTRING_LEN
(line
);
5624 lex_p
= lex_pbeg
+ here
->nd_nth
;
5625 heredoc_end
= ruby_sourceline
;
5626 ruby_sourceline
= nd_line
(here
);
5627 dispose_string
(here
->nd_lit
);
5628 rb_gc_force_recycle
((VALUE
)here
);
5630 ripper_flush
(parser
);
5635 parser_whole_match_p
(struct parser_params
*parser
,
5636 const char *eos
, int len
, int indent
)
5638 const char *p
= lex_pbeg
;
5642 while
(*p
&& ISSPACE
(*p
)) p
++;
5644 n
= lex_pend
- (p
+ len
);
5645 if
(n
< 0 ||
(n
> 0 && p
[len
] != '\n' && p
[len
] != '\r')) return Qfalse
;
5646 if
(strncmp
(eos
, p
, len
) == 0) return Qtrue
;
5651 parser_here_document
(struct parser_params
*parser
, NODE
*here
)
5653 int c
, func
, indent
= 0;
5654 const char *eos
, *p
, *pend
;
5658 eos
= RSTRING_PTR
(here
->nd_lit
);
5659 len
= RSTRING_LEN
(here
->nd_lit
) - 1;
5660 indent
= (func
= *eos
++) & STR_FUNC_INDENT
;
5662 if
((c
= nextc
()) == -1) {
5664 compile_error
(PARSER_ARG
"can't find string \"%s\" anywhere before EOF", eos
);
5666 heredoc_restore
(lex_strterm
);
5670 if
(was_bol
() && whole_match_p
(eos
, len
, indent
)) {
5671 heredoc_restore
(lex_strterm
);
5675 if
(!(func
& STR_FUNC_EXPAND
)) {
5677 p
= RSTRING_PTR
(lex_lastline
);
5682 if
(--pend
== p || pend
[-1] != '\r') {
5691 rb_str_cat
(str
, p
, pend
- p
);
5693 str
= STR_NEW
(p
, pend
- p
);
5694 if
(pend
< lex_pend
) rb_str_cat
(str
, "\n", 1);
5695 lex_goto_eol
(parser
);
5696 if
(nextc
() == -1) {
5697 if
(str
) dispose_string
(str
);
5700 } while
(!whole_match_p
(eos
, len
, indent
));
5703 /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
5704 rb_encoding
*enc
= parser
->enc
;
5707 switch
(c
= nextc
()) {
5711 return tSTRING_DVAR
;
5713 return tSTRING_DBEG
;
5719 if
((c
= tokadd_string
(func
, '\n', 0, NULL
, &enc
)) == -1) {
5720 if
(parser
->eofp
) goto
error;
5724 set_yylval_str
(STR_NEW3
(tok
(), toklen
(), enc
, func
));
5725 return tSTRING_CONTENT
;
5728 /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
5729 if
((c
= nextc
()) == -1) goto
error;
5730 } while
(!whole_match_p
(eos
, len
, indent
));
5731 str
= STR_NEW3
(tok
(), toklen
(), enc
, func
);
5733 heredoc_restore
(lex_strterm
);
5734 lex_strterm
= NEW_STRTERM
(-1, 0, 0);
5735 set_yylval_str
(str
);
5736 return tSTRING_CONTENT
;
5743 arg_ambiguous_gen
(struct parser_params
*parser
)
5745 rb_warning0
("ambiguous first argument; put parentheses or even spaces");
5749 arg_ambiguous_gen
(struct parser_params
*parser
)
5751 dispatch0
(arg_ambiguous
);
5754 #define arg_ambiguous() arg_ambiguous_gen(parser)
5757 lvar_defined_gen
(struct parser_params
*parser
, ID id
)
5760 return
(dyna_in_block
() && dvar_defined
(id
)) || local_id
(id
);
5766 /* emacsen -*- hack */
5768 parser_encode_length
(struct parser_params
*parser
, const char *name
, int len
)
5772 if
(len
> 5 && name
[nlen
= len
- 5] == '-') {
5773 if
(rb_memcicmp
(name
+ nlen
+ 1, "unix", 4) == 0)
5776 if
(len
> 4 && name
[nlen
= len
- 5] == '-') {
5777 if
(rb_memcicmp
(name
+ nlen
+ 1, "dos", 3) == 0)
5779 if
(rb_memcicmp
(name
+ nlen
+ 1, "mac", 3) == 0)
5786 parser_set_encode
(struct parser_params
*parser
, const char *name
)
5788 int idx
= rb_enc_find_index
(name
);
5792 rb_raise
(rb_eArgError
, "unknown encoding name: %s", name
);
5794 enc
= rb_enc_from_index
(idx
);
5795 if
(!rb_enc_asciicompat
(enc
)) {
5796 rb_raise
(rb_eArgError
, "%s is not ASCII compatible", rb_enc_name
(enc
));
5802 typedef
int (*rb_magic_comment_length_t
)(struct parser_params
*parser
, const char *name
, int len
);
5803 typedef
void (*rb_magic_comment_setter_t
)(struct parser_params
*parser
, const char *name
, const char *val
);
5806 magic_comment_encoding
(struct parser_params
*parser
, const char *name
, const char *val
)
5808 if
(parser
->line_count
!= (parser
->has_shebang ?
2 : 1))
5810 parser_set_encode
(parser
, val
);
5813 struct magic_comment
{
5815 rb_magic_comment_setter_t func
;
5816 rb_magic_comment_length_t length
;
5819 static const struct magic_comment magic_comments
[] = {
5820 {"coding", magic_comment_encoding
, parser_encode_length
},
5821 {"encoding", magic_comment_encoding
, parser_encode_length
},
5826 magic_comment_marker
(const char *str
, int len
)
5833 if
(str
[i
-1] == '*' && str
[i
-2] == '-') {
5839 if
(i
+ 1 >= len
) return
0;
5840 if
(str
[i
+1] != '-') {
5843 else if
(str
[i
-1] != '-') {
5859 parser_magic_comment
(struct parser_params
*parser
, const char *str
, int len
)
5861 VALUE name
= 0, val
= 0;
5862 const char *beg
, *end
, *vbeg
, *vend
;
5863 #define str_copy(_s, _p, _n) ((_s) \
5864 ?
(rb_str_resize
((_s
), (_n
)), \
5865 MEMCPY
(RSTRING_PTR
(_s
), (_p
), char, (_n
)), (_s
)) \
5866 : ((_s
) = STR_NEW
((_p
), (_n
))))
5868 if
(len
<= 7) return Qfalse
;
5869 if
(!(beg
= magic_comment_marker
(str
, len
))) return Qfalse
;
5870 if
(!(end
= magic_comment_marker
(beg
, str
+ len
- beg
))) return Qfalse
;
5872 len
= end
- beg
- 3;
5874 /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
5877 const struct magic_comment
*p
= magic_comments
;
5881 for
(; len
> 0 && *str
; str
++, --len
) {
5883 case
'\'': case
'"': case
':': case
';':
5886 if
(!ISSPACE
(*str
)) break
;
5888 for
(beg
= str
; len
> 0; str
++, --len
) {
5890 case
'\'': case
'"': case
':': case
';':
5893 if
(ISSPACE
(*str
)) break
;
5898 for
(end
= str
; len
> 0 && ISSPACE
(*str
); str
++, --len
);
5900 if
(*str
!= ':') continue
;
5902 do str
++; while
(--len
> 0 && ISSPACE
(*str
));
5905 for
(vbeg
= ++str
; --len
> 0 && *str
!= '"'; str
++) {
5918 for
(vbeg
= str
; len
> 0 && *str
!= '"' && *str
!= ';' && !ISSPACE
(*str
); --len
, str
++);
5921 while
(len
> 0 && (*str
== ';' || ISSPACE
(*str
))) --len
, str
++;
5924 str_copy
(name
, beg
, n
);
5927 if
(STRNCASECMP
(p
->name
, RSTRING_PTR
(name
), n
) == 0) {
5930 n
= (*p
->length
)(parser
, vbeg
, n
);
5932 str_copy
(val
, vbeg
, n
);
5933 (*p
->func
)(parser
, RSTRING_PTR
(name
), RSTRING_PTR
(val
));
5936 } while
(++p
< magic_comments
+ sizeof
(magic_comments
) / sizeof
(*p
));
5938 dispatch2
(magic_comment
, name
, val
);
5946 set_file_encoding
(struct parser_params
*parser
, const char *str
, const char *send
)
5949 const char *beg
= str
;
5953 if
(send
- str
<= 6) return
;
5955 case
'C': case
'c': str
+= 6; continue
;
5956 case
'O': case
'o': str
+= 5; continue
;
5957 case
'D': case
'd': str
+= 4; continue
;
5958 case
'I': case
'i': str
+= 3; continue
;
5959 case
'N': case
'n': str
+= 2; continue
;
5960 case
'G': case
'g': str
+= 1; continue
;
5967 if
(ISSPACE
(*str
)) break
;
5970 if
(STRNCASECMP
(str
-6, "coding", 6) == 0) break
;
5974 if
(++str
>= send
) return
;
5975 } while
(ISSPACE
(*str
));
5977 if
(*str
!= '=' && *str
!= ':') return
;
5982 while
((*str
== '-' ||
*str
== '_' || ISALNUM
(*str
)) && ++str
< send
);
5983 s
= rb_str_new
(beg
, parser_encode_length
(parser
, beg
, str
- beg
));
5984 parser_set_encode
(parser
, RSTRING_PTR
(s
));
5985 rb_str_resize
(s
, 0);
5989 parser_prepare
(struct parser_params
*parser
)
5994 if
(peek
('!')) parser
->has_shebang
= 1;
5996 case
0xef: /* UTF-8 BOM marker */
5997 if
(lex_pend
- lex_p
>= 2 &&
5998 (unsigned char)lex_p
[0] == 0xbb &&
5999 (unsigned char)lex_p
[1] == 0xbf) {
6000 parser_set_encode
(parser
, "UTF-8");
6010 parser
->enc
= rb_enc_get
(lex_lastline
);
6013 #define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG)
6014 #define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_VALUE || lex_state == EXPR_CLASS)
6017 parser_yylex
(struct parser_params
*parser
)
6022 enum lex_state_e last_state
;
6026 int fallthru
= Qfalse
;
6031 if
(nd_type
(lex_strterm
) == NODE_HEREDOC
) {
6032 token
= here_document
(lex_strterm
);
6033 if
(token
== tSTRING_END
) {
6035 lex_state
= EXPR_ENDARG
;
6039 token
= parse_string
(lex_strterm
);
6040 if
(token
== tSTRING_END || token
== tREGEXP_END
) {
6041 rb_gc_force_recycle
((VALUE
)lex_strterm
);
6043 lex_state
= EXPR_ENDARG
;
6048 cmd_state
= command_start
;
6049 command_start
= Qfalse
;
6051 switch
(c
= nextc
()) {
6052 case
'\0': /* NUL */
6053 case
'\004': /* ^D */
6054 case
'\032': /* ^Z */
6055 case
-1: /* end of script. */
6059 case
' ': case
'\t': case
'\f': case
'\r':
6060 case
'\13': /* '\v' */
6063 while
((c
= nextc
())) {
6065 case
' ': case
'\t': case
'\f': case
'\r':
6066 case
'\13': /* '\v' */
6074 ripper_dispatch_scan_event
(parser
, tSP
);
6078 case
'#': /* it's a comment */
6079 /* no magic_comment in shebang line */
6080 if
(parser
->line_count
== (parser
->has_shebang ?
2 : 1)
6081 && (lex_p
- lex_pbeg
) == 1) {
6082 if
(!parser_magic_comment
(parser
, lex_p
, lex_pend
- lex_p
)) {
6083 set_file_encoding
(parser
, lex_p
, lex_pend
);
6088 ripper_dispatch_scan_event
(parser
, tCOMMENT
);
6093 switch
(lex_state
) {
6101 ripper_dispatch_scan_event
(parser
, tIGNORED_NL
);
6109 while
((c
= nextc
())) {
6111 case
' ': case
'\t': case
'\f': case
'\r':
6112 case
'\13': /* '\v' */
6116 if
((c
= nextc
()) != '.') {
6124 lex_nextline
= lex_lastline
;
6125 case
-1: /* EOF no decrement*/
6126 lex_goto_eol
(parser
);
6129 parser
->tokp
= lex_p
;
6132 goto normal_newline
;
6136 command_start
= Qtrue
;
6137 lex_state
= EXPR_BEG
;
6141 if
((c
= nextc
()) == '*') {
6142 if
((c
= nextc
()) == '=') {
6143 set_yylval_id
(tPOW
);
6144 lex_state
= EXPR_BEG
;
6153 lex_state
= EXPR_BEG
;
6157 if
(IS_ARG
() && space_seen
&& !ISSPACE
(c
)) {
6158 rb_warning0
("`*' interpreted as argument prefix");
6161 else if
(IS_BEG
()) {
6168 switch
(lex_state
) {
6169 case EXPR_FNAME
: case EXPR_DOT
:
6170 lex_state
= EXPR_ARG
; break
;
6172 lex_state
= EXPR_BEG
; break
;
6178 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6179 lex_state
= EXPR_ARG
;
6185 lex_state
= EXPR_BEG
;
6198 /* skip embedded rd document */
6199 if
(strncmp
(lex_p
, "begin", 5) == 0 && ISSPACE
(lex_p
[5])) {
6201 int first_p
= Qtrue
;
6203 lex_goto_eol
(parser
);
6204 ripper_dispatch_scan_event
(parser
, tEMBDOC_BEG
);
6207 lex_goto_eol
(parser
);
6210 ripper_dispatch_scan_event
(parser
, tEMBDOC
);
6216 compile_error
(PARSER_ARG
"embedded document meets end of file");
6219 if
(c
!= '=') continue
;
6220 if
(strncmp
(lex_p
, "end", 3) == 0 &&
6221 (lex_p
+ 3 == lex_pend || ISSPACE
(lex_p
[3]))) {
6225 lex_goto_eol
(parser
);
6227 ripper_dispatch_scan_event
(parser
, tEMBDOC_END
);
6233 switch
(lex_state
) {
6234 case EXPR_FNAME
: case EXPR_DOT
:
6235 lex_state
= EXPR_ARG
; break
;
6237 lex_state
= EXPR_BEG
; break
;
6239 if
((c
= nextc
()) == '=') {
6240 if
((c
= nextc
()) == '=') {
6249 else if
(c
== '>') {
6258 lex_state
!= EXPR_END
&&
6259 lex_state
!= EXPR_DOT
&&
6260 lex_state
!= EXPR_ENDARG
&&
6261 lex_state
!= EXPR_CLASS
&&
6262 (!IS_ARG
() || space_seen
)) {
6263 int token
= heredoc_identifier
();
6264 if
(token
) return token
;
6266 switch
(lex_state
) {
6267 case EXPR_FNAME
: case EXPR_DOT
:
6268 lex_state
= EXPR_ARG
; break
;
6270 lex_state
= EXPR_BEG
; break
;
6273 if
((c
= nextc
()) == '>') {
6280 if
((c
= nextc
()) == '=') {
6281 set_yylval_id
(tLSHFT
);
6282 lex_state
= EXPR_BEG
;
6292 switch
(lex_state
) {
6293 case EXPR_FNAME
: case EXPR_DOT
:
6294 lex_state
= EXPR_ARG
; break
;
6296 lex_state
= EXPR_BEG
; break
;
6298 if
((c
= nextc
()) == '=') {
6302 if
((c
= nextc
()) == '=') {
6303 set_yylval_id
(tRSHFT
);
6304 lex_state
= EXPR_BEG
;
6314 lex_strterm
= NEW_STRTERM
(str_dquote
, '"', 0);
6318 if
(lex_state
== EXPR_FNAME
) {
6319 lex_state
= EXPR_END
;
6322 if
(lex_state
== EXPR_DOT
) {
6324 lex_state
= EXPR_CMDARG
;
6326 lex_state
= EXPR_ARG
;
6329 lex_strterm
= NEW_STRTERM
(str_xquote
, '`', 0);
6330 return tXSTRING_BEG
;
6333 lex_strterm
= NEW_STRTERM
(str_squote
, '\'', 0);
6337 if
(lex_state
== EXPR_END ||
6338 lex_state
== EXPR_ENDARG
) {
6339 lex_state
= EXPR_VALUE
;
6344 compile_error
(PARSER_ARG
"incomplete character syntax");
6347 if
(rb_enc_isspace
(c
, parser
->enc
)) {
6371 rb_warnI
("invalid character syntax; use ?\\%c", c2
);
6376 lex_state
= EXPR_VALUE
;
6381 if
(!parser_isascii
()) {
6382 if
(tokadd_mbchar
(c
) == -1) return
0;
6384 else if
((rb_enc_isalnum
(c
, parser
->enc
) || c
== '_') &&
6385 lex_p
< lex_pend
&& is_identchar
(lex_p
, lex_pend
, parser
->enc
)) {
6388 else if
(c
== '\\') {
6391 c
= parser_tokadd_utf8
(parser
, &enc
, 0, 0, 0);
6400 c
= read_escape
(0, &enc
);
6408 set_yylval_str
(STR_NEW3
(tok
(), toklen
(), enc
, 0));
6409 lex_state
= EXPR_ENDARG
;
6413 if
((c
= nextc
()) == '&') {
6414 lex_state
= EXPR_BEG
;
6415 if
((c
= nextc
()) == '=') {
6416 set_yylval_id
(tANDOP
);
6417 lex_state
= EXPR_BEG
;
6423 else if
(c
== '=') {
6425 lex_state
= EXPR_BEG
;
6429 if
(IS_ARG
() && space_seen
&& !ISSPACE
(c
)) {
6430 rb_warning0
("`&' interpreted as argument prefix");
6433 else if
(IS_BEG
()) {
6439 switch
(lex_state
) {
6440 case EXPR_FNAME
: case EXPR_DOT
:
6441 lex_state
= EXPR_ARG
; break
;
6443 lex_state
= EXPR_BEG
;
6448 if
((c
= nextc
()) == '|') {
6449 lex_state
= EXPR_BEG
;
6450 if
((c
= nextc
()) == '=') {
6451 set_yylval_id
(tOROP
);
6452 lex_state
= EXPR_BEG
;
6460 lex_state
= EXPR_BEG
;
6463 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6464 lex_state
= EXPR_ARG
;
6467 lex_state
= EXPR_BEG
;
6474 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6475 lex_state
= EXPR_ARG
;
6484 lex_state
= EXPR_BEG
;
6488 (IS_ARG
() && space_seen
&& !ISSPACE
(c
))) {
6489 if
(IS_ARG
()) arg_ambiguous
();
6490 lex_state
= EXPR_BEG
;
6498 lex_state
= EXPR_BEG
;
6504 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6505 lex_state
= EXPR_ARG
;
6514 lex_state
= EXPR_BEG
;
6518 lex_state
= EXPR_ARG
;
6522 (IS_ARG
() && space_seen
&& !ISSPACE
(c
))) {
6523 if
(IS_ARG
()) arg_ambiguous
();
6524 lex_state
= EXPR_BEG
;
6531 lex_state
= EXPR_BEG
;
6536 lex_state
= EXPR_BEG
;
6537 if
((c
= nextc
()) == '.') {
6538 if
((c
= nextc
()) == '.') {
6546 yyerror("no .<digit> floating literal anymore; put 0 before dot");
6548 lex_state
= EXPR_DOT
;
6552 case
'0': case
'1': case
'2': case
'3': case
'4':
6553 case
'5': case
'6': case
'7': case
'8': case
'9':
6555 int is_float
, seen_point
, seen_e
, nondigit
;
6557 is_float
= seen_point
= seen_e
= nondigit
= 0;
6558 lex_state
= EXPR_ENDARG
;
6560 if
(c
== '-' || c
== '+') {
6565 int start
= toklen
();
6567 if
(c
== 'x' || c
== 'X') {
6573 if
(nondigit
) break
;
6577 if
(!ISXDIGIT
(c
)) break
;
6580 } while
((c
= nextc
()) != -1);
6584 if
(toklen
() == start
) {
6585 yyerror("numeric literal without digits");
6587 else if
(nondigit
) goto trailing_uc
;
6588 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 16, Qfalse
));
6591 if
(c
== 'b' || c
== 'B') {
6594 if
(c
== '0' || c
== '1') {
6597 if
(nondigit
) break
;
6601 if
(c
!= '0' && c
!= '1') break
;
6604 } while
((c
= nextc
()) != -1);
6608 if
(toklen
() == start
) {
6609 yyerror("numeric literal without digits");
6611 else if
(nondigit
) goto trailing_uc
;
6612 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 2, Qfalse
));
6615 if
(c
== 'd' || c
== 'D') {
6621 if
(nondigit
) break
;
6625 if
(!ISDIGIT
(c
)) break
;
6628 } while
((c
= nextc
()) != -1);
6632 if
(toklen
() == start
) {
6633 yyerror("numeric literal without digits");
6635 else if
(nondigit
) goto trailing_uc
;
6636 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 10, Qfalse
));
6643 if
(c
== 'o' || c
== 'O') {
6644 /* prefixed octal */
6646 if
(c
== '_' ||
!ISDIGIT
(c
)) {
6647 yyerror("numeric literal without digits");
6650 if
(c
>= '0' && c
<= '7') {
6655 if
(nondigit
) break
;
6659 if
(c
< '0' || c
> '9') break
;
6660 if
(c
> '7') goto invalid_octal
;
6663 } while
((c
= nextc
()) != -1);
6664 if
(toklen
() > start
) {
6667 if
(nondigit
) goto trailing_uc
;
6668 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 8, Qfalse
));
6676 if
(c
> '7' && c
<= '9') {
6678 yyerror("Invalid octal digit");
6680 else if
(c
== '.' || c
== 'e' || c
== 'E') {
6685 set_yylval_literal
(INT2FIX
(0));
6692 case
'0': case
'1': case
'2': case
'3': case
'4':
6693 case
'5': case
'6': case
'7': case
'8': case
'9':
6699 if
(nondigit
) goto trailing_uc
;
6700 if
(seen_point || seen_e
) {
6733 if
(c
!= '-' && c
!= '+') continue
;
6738 case
'_': /* `_' in number just ignored */
6739 if
(nondigit
) goto decode_num
;
6755 sprintf
(tmp
, "trailing `%c' in number", nondigit
);
6759 double d
= strtod
(tok
(), 0);
6760 if
(errno
== ERANGE
) {
6761 rb_warningS
("Float %s out of range", tok
());
6764 set_yylval_literal
(DOUBLE2NUM
(d
));
6767 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 10, Qfalse
));
6778 lex_state
= EXPR_END
;
6780 lex_state
= EXPR_ENDARG
;
6787 lex_state
== EXPR_CLASS ||
(IS_ARG
() && space_seen
)) {
6788 lex_state
= EXPR_BEG
;
6791 lex_state
= EXPR_DOT
;
6794 if
(lex_state
== EXPR_END ||
6795 lex_state
== EXPR_ENDARG || ISSPACE
(c
)) {
6797 lex_state
= EXPR_BEG
;
6802 lex_strterm
= NEW_STRTERM
(str_ssym
, c
, 0);
6805 lex_strterm
= NEW_STRTERM
(str_dsym
, c
, 0);
6811 lex_state
= EXPR_FNAME
;
6816 lex_strterm
= NEW_STRTERM
(str_regexp
, '/', 0);
6819 if
((c
= nextc
()) == '=') {
6821 lex_state
= EXPR_BEG
;
6825 if
(IS_ARG
() && space_seen
) {
6828 lex_strterm
= NEW_STRTERM
(str_regexp
, '/', 0);
6832 switch
(lex_state
) {
6833 case EXPR_FNAME
: case EXPR_DOT
:
6834 lex_state
= EXPR_ARG
; break
;
6836 lex_state
= EXPR_BEG
; break
;
6841 if
((c
= nextc
()) == '=') {
6843 lex_state
= EXPR_BEG
;
6846 switch
(lex_state
) {
6847 case EXPR_FNAME
: case EXPR_DOT
:
6848 lex_state
= EXPR_ARG
; break
;
6850 lex_state
= EXPR_BEG
; break
;
6856 lex_state
= EXPR_BEG
;
6857 command_start
= Qtrue
;
6861 lex_state
= EXPR_BEG
;
6865 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6866 if
((c
= nextc
()) != '@') {
6869 lex_state
= EXPR_ARG
;
6872 lex_state
= EXPR_BEG
;
6880 else if
(space_seen
) {
6888 lex_state
= EXPR_BEG
;
6893 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6894 lex_state
= EXPR_ARG
;
6895 if
((c
= nextc
()) == ']') {
6896 if
((c
= nextc
()) == '=') {
6905 else if
(IS_BEG
()) {
6908 else if
(IS_ARG
() && space_seen
) {
6911 lex_state
= EXPR_BEG
;
6917 if
(lpar_beg
&& lpar_beg
== paren_nest
) {
6918 lex_state
= EXPR_BEG
;
6923 if
(IS_ARG
() || lex_state
== EXPR_END
)
6924 c
= '{'; /* block (primary) */
6925 else if
(lex_state
== EXPR_ENDARG
)
6926 c
= tLBRACE_ARG
; /* block (expr) */
6928 c
= tLBRACE
; /* hash */
6931 lex_state
= EXPR_BEG
;
6932 if
(c
!= tLBRACE
) command_start
= Qtrue
;
6940 ripper_dispatch_scan_event
(parser
, tSP
);
6942 goto retry
; /* skip \\n */
6960 if
(rb_enc_isalnum
(term
, parser
->enc
) ||
!parser_isascii
()) {
6961 yyerror("unknown type of %string");
6965 if
(c
== -1 || term
== -1) {
6966 compile_error
(PARSER_ARG
"unterminated quoted string meets end of file");
6970 if
(term
== '(') term
= ')';
6971 else if
(term
== '[') term
= ']';
6972 else if
(term
== '{') term
= '}';
6973 else if
(term
== '<') term
= '>';
6978 lex_strterm
= NEW_STRTERM
(str_dquote
, term
, paren
);
6982 lex_strterm
= NEW_STRTERM
(str_squote
, term
, paren
);
6986 lex_strterm
= NEW_STRTERM
(str_dword
, term
, paren
);
6987 do
{c
= nextc
();} while
(ISSPACE
(c
));
6992 lex_strterm
= NEW_STRTERM
(str_sword
, term
, paren
);
6993 do
{c
= nextc
();} while
(ISSPACE
(c
));
6998 lex_strterm
= NEW_STRTERM
(str_xquote
, term
, paren
);
6999 return tXSTRING_BEG
;
7002 lex_strterm
= NEW_STRTERM
(str_regexp
, term
, paren
);
7006 lex_strterm
= NEW_STRTERM
(str_ssym
, term
, paren
);
7007 lex_state
= EXPR_FNAME
;
7011 yyerror("unknown type of %string");
7015 if
((c
= nextc
()) == '=') {
7017 lex_state
= EXPR_BEG
;
7020 if
(IS_ARG
() && space_seen
&& !ISSPACE
(c
)) {
7023 switch
(lex_state
) {
7024 case EXPR_FNAME
: case EXPR_DOT
:
7025 lex_state
= EXPR_ARG
; break
;
7027 lex_state
= EXPR_BEG
; break
;
7033 last_state
= lex_state
;
7034 lex_state
= EXPR_ENDARG
;
7038 case
'_': /* $_: last read line string */
7040 if
(parser_is_identchar
()) {
7048 case
'~': /* $~: match-data */
7049 case
'*': /* $*: argv */
7050 case
'$': /* $$: pid */
7051 case
'?': /* $?: last status */
7052 case
'!': /* $!: error string */
7053 case
'@': /* $@: error position */
7054 case
'/': /* $/: input record separator */
7055 case
'\\': /* $\: output record separator */
7056 case
';': /* $;: field separator */
7057 case
',': /* $,: output field separator */
7058 case
'.': /* $.: last read line number */
7059 case
'=': /* $=: ignorecase */
7060 case
':': /* $:: load path */
7061 case
'<': /* $<: reading filename */
7062 case
'>': /* $>: default output handle */
7063 case
'\"': /* $": already loaded files */
7067 set_yylval_id
(rb_intern
(tok
()));
7074 if
(parser_is_identchar
()) {
7075 if
(tokadd_mbchar
(c
) == -1) return
0;
7082 set_yylval_id
(rb_intern
(tok
()));
7085 case
'&': /* $&: last match */
7086 case
'`': /* $`: string before last match */
7087 case
'\'': /* $': string after last match */
7088 case
'+': /* $+: string matches last paren. */
7089 if
(last_state
== EXPR_FNAME
) {
7094 set_yylval_node
(NEW_BACK_REF
(c
));
7097 case
'1': case
'2': case
'3':
7098 case
'4': case
'5': case
'6':
7099 case
'7': case
'8': case
'9':
7104 } while
(ISDIGIT
(c
));
7106 if
(last_state
== EXPR_FNAME
) goto gvar
;
7108 set_yylval_node
(NEW_NTH_REF
(atoi
(tok
()+1)));
7112 if
(!parser_is_identchar
()) {
7131 compile_error
(PARSER_ARG
"`@%c' is not allowed as an instance variable name", c
);
7134 compile_error
(PARSER_ARG
"`@@%c' is not allowed as a class variable name", c
);
7138 if
(!parser_is_identchar
()) {
7145 if
(was_bol
() && whole_match_p
("__END__", 7, 0)) {
7146 ruby__end__seen
= 1;
7147 parser
->eofp
= Qtrue
;
7151 lex_goto_eol
(parser
);
7152 ripper_dispatch_scan_event
(parser
, k__END__
);
7160 if
(!parser_is_identchar
()) {
7161 rb_compile_error
(PARSER_ARG
"Invalid char `\\x%02X' in expression", c
);
7169 mb
= ENC_CODERANGE_7BIT
;
7171 if
(!ISASCII
(c
)) mb
= ENC_CODERANGE_UNKNOWN
;
7172 if
(tokadd_mbchar
(c
) == -1) return
0;
7174 } while
(parser_is_identchar
());
7180 if
((c
== '!' || c
== '?') && !peek
('=')) {
7192 last_state
= lex_state
;
7195 lex_state
= EXPR_ENDARG
;
7199 lex_state
= EXPR_ENDARG
;
7200 if
(tok
()[1] == '@')
7207 if
(toklast
() == '!' || toklast
() == '?') {
7211 if
(lex_state
== EXPR_FNAME
) {
7212 if
((c
= nextc
()) == '=' && !peek
('~') && !peek
('>') &&
7213 (!peek
('=') ||
(lex_p
+ 1 < lex_pend
&& lex_p
[1] == '>'))) {
7214 result
= tIDENTIFIER
;
7222 if
(result
== 0 && ISUPPER
(tok
()[0])) {
7226 result
= tIDENTIFIER
;
7230 if
(mb
== ENC_CODERANGE_7BIT
&& lex_state
!= EXPR_DOT
) {
7231 const struct kwtable
*kw
;
7233 /* See if it is a reserved word. */
7234 kw
= rb_reserved_word
(tok
(), toklen
());
7236 enum lex_state_e state
= lex_state
;
7237 lex_state
= kw
->state
;
7238 if
(state
== EXPR_FNAME
) {
7239 set_yylval_id
(rb_intern
(kw
->name
));
7242 if
(kw
->id
[0] == keyword_do
) {
7243 command_start
= Qtrue
;
7244 if
(lpar_beg
&& lpar_beg
== paren_nest
) {
7247 return keyword_do_LAMBDA
;
7249 if
(COND_P
()) return keyword_do_cond
;
7250 if
(CMDARG_P
() && state
!= EXPR_CMDARG
)
7251 return keyword_do_block
;
7252 if
(state
== EXPR_ENDARG || state
== EXPR_BEG
)
7253 return keyword_do_block
;
7256 if
(state
== EXPR_BEG || state
== EXPR_VALUE
)
7259 if
(kw
->id
[0] != kw
->id
[1])
7260 lex_state
= EXPR_BEG
;
7266 if
((lex_state
== EXPR_BEG
&& !cmd_state
) ||
7267 lex_state
== EXPR_ARG ||
7268 lex_state
== EXPR_CMDARG
) {
7269 if
(peek
(':') && !(lex_p
+ 1 < lex_pend
&& lex_p
[1] == ':')) {
7270 lex_state
= EXPR_BEG
;
7272 set_yylval_id
(TOK_INTERN
(!ENC_SINGLE
(mb
)));
7277 lex_state
== EXPR_DOT ||
7280 lex_state
= EXPR_CMDARG
;
7283 lex_state
= EXPR_ARG
;
7287 lex_state
= EXPR_END
;
7291 ID ident
= TOK_INTERN
(!ENC_SINGLE
(mb
));
7293 set_yylval_id
(ident
);
7294 if
(last_state
!= EXPR_DOT
&& is_local_id
(ident
) && lvar_defined
(ident
)) {
7295 lex_state
= EXPR_END
;
7304 yylex(void *lval
, void *p
)
7309 struct parser_params
*parser
= (struct parser_params
*)p
;
7313 parser
->parser_yylval
= (union tmpyystype
*)lval
;
7314 parser
->parser_yylval
->val
= Qundef
;
7316 t
= parser_yylex
(parser
);
7318 if
(!NIL_P
(parser
->delayed
)) {
7319 ripper_dispatch_delayed_token
(parser
, t
);
7323 ripper_dispatch_scan_event
(parser
, t
);
7331 node_newnode
(struct parser_params
*parser
, enum node_type type
, VALUE a0
, VALUE a1
, VALUE a2
)
7333 NODE
*n
= (rb_node_newnode
)(type
, a0
, a1
, a2
);
7334 nd_set_line
(n
, ruby_sourceline
);
7339 nodetype
(NODE
*node
) /* for debug */
7341 return
(enum node_type
)nd_type
(node
);
7345 nodeline
(NODE
*node
)
7347 return nd_line
(node
);
7351 newline_node
(NODE
*node
)
7354 node
= remove_begin
(node
);
7355 node
->flags |
= NODE_FL_NEWLINE
;
7361 fixpos
(NODE
*node
, NODE
*orig
)
7365 if
(orig
== (NODE
*)1) return
;
7366 nd_set_line
(node
, nd_line
(orig
));
7370 parser_warning
(struct parser_params
*parser
, NODE
*node
, const char *mesg
)
7372 rb_compile_warning
(ruby_sourcefile
, nd_line
(node
), "%s", mesg
);
7374 #define parser_warning(node, mesg) parser_warning(parser, node, mesg)
7377 parser_warn
(struct parser_params
*parser
, NODE
*node
, const char *mesg
)
7379 rb_compile_warn
(ruby_sourcefile
, nd_line
(node
), "%s", mesg
);
7381 #define parser_warn(node, mesg) parser_warn(parser, node, mesg)
7384 block_append_gen
(struct parser_params
*parser
, NODE
*head
, NODE
*tail
)
7386 NODE
*end
, *h
= head
, *nd
;
7388 if
(tail
== 0) return head
;
7390 if
(h
== 0) return tail
;
7391 switch
(nd_type
(h
)) {
7398 parser_warning
(h
, "unused literal ignored");
7401 h
= end
= NEW_BLOCK
(head
);
7412 switch
(nd_type
(nd
)) {
7418 if
(RTEST
(ruby_verbose
)) {
7419 parser_warning
(nd
, "statement not reached");
7427 if
(nd_type
(tail
) != NODE_BLOCK
) {
7428 tail
= NEW_BLOCK
(tail
);
7429 tail
->nd_end
= tail
;
7431 end
->nd_next
= tail
;
7432 h
->nd_end
= tail
->nd_end
;
7436 /* append item to the list */
7438 list_append_gen
(struct parser_params
*parser
, NODE
*list
, NODE
*item
)
7442 if
(list
== 0) return NEW_LIST
(item
);
7443 if
(list
->nd_next
) {
7444 last
= list
->nd_next
->nd_end
;
7451 last
->nd_next
= NEW_LIST
(item
);
7452 list
->nd_next
->nd_end
= last
->nd_next
;
7456 /* concat two lists */
7458 list_concat_gen
(struct parser_params
*parser
, NODE
*head
, NODE
*tail
)
7462 if
(head
->nd_next
) {
7463 last
= head
->nd_next
->nd_end
;
7469 head
->nd_alen
+= tail
->nd_alen
;
7470 last
->nd_next
= tail
;
7471 if
(tail
->nd_next
) {
7472 head
->nd_next
->nd_end
= tail
->nd_next
->nd_end
;
7475 head
->nd_next
->nd_end
= tail
;
7482 literal_concat0
(struct parser_params
*parser
, VALUE head
, VALUE tail
)
7484 if
(!rb_enc_compatible
(head
, tail
)) {
7485 compile_error
(PARSER_ARG
"string literal encodings differ (%s / %s)",
7486 rb_enc_name
(rb_enc_get
(head
)),
7487 rb_enc_name
(rb_enc_get
(tail
)));
7488 rb_str_resize
(head
, 0);
7489 rb_str_resize
(tail
, 0);
7492 rb_str_buf_append
(head
, tail
);
7496 /* concat two string literals */
7498 literal_concat_gen
(struct parser_params
*parser
, NODE
*head
, NODE
*tail
)
7500 enum node_type htype
;
7502 if
(!head
) return tail
;
7503 if
(!tail
) return head
;
7505 htype
= nd_type
(head
);
7506 if
(htype
== NODE_EVSTR
) {
7507 NODE
*node
= NEW_DSTR
(STR_NEW0
());
7508 head
= list_append
(node
, head
);
7510 switch
(nd_type
(tail
)) {
7512 if
(htype
== NODE_STR
) {
7513 if
(!literal_concat0
(parser
, head
->nd_lit
, tail
->nd_lit
)) {
7515 rb_gc_force_recycle
((VALUE
)head
);
7516 rb_gc_force_recycle
((VALUE
)tail
);
7519 rb_gc_force_recycle
((VALUE
)tail
);
7522 list_append
(head
, tail
);
7527 if
(htype
== NODE_STR
) {
7528 if
(!literal_concat0
(parser
, head
->nd_lit
, tail
->nd_lit
))
7530 tail
->nd_lit
= head
->nd_lit
;
7531 rb_gc_force_recycle
((VALUE
)head
);
7535 nd_set_type
(tail
, NODE_ARRAY
);
7536 tail
->nd_head
= NEW_STR
(tail
->nd_lit
);
7537 list_concat
(head
, tail
);
7542 if
(htype
== NODE_STR
) {
7543 nd_set_type
(head
, NODE_DSTR
);
7546 list_append
(head
, tail
);
7553 evstr2dstr_gen
(struct parser_params
*parser
, NODE
*node
)
7555 if
(nd_type
(node
) == NODE_EVSTR
) {
7556 node
= list_append
(NEW_DSTR
(STR_NEW0
()), node
);
7562 new_evstr_gen
(struct parser_params
*parser
, NODE
*node
)
7567 switch
(nd_type
(node
)) {
7568 case NODE_STR
: case NODE_DSTR
: case NODE_EVSTR
:
7572 return NEW_EVSTR
(head
);
7576 call_bin_op_gen
(struct parser_params
*parser
, NODE
*recv
, ID id
, NODE
*arg1
)
7580 return NEW_CALL
(recv
, id
, NEW_LIST
(arg1
));
7584 call_uni_op_gen
(struct parser_params
*parser
, NODE
*recv
, ID id
)
7587 return NEW_CALL
(recv
, id
, 0);
7591 match_op_gen
(struct parser_params
*parser
, NODE
*node1
, NODE
*node2
)
7596 switch
(nd_type
(node1
)) {
7598 case NODE_DREGX_ONCE
:
7599 return NEW_MATCH2
(node1
, node2
);
7602 if
(TYPE
(node1
->nd_lit
) == T_REGEXP
) {
7603 return NEW_MATCH2
(node1
, node2
);
7609 switch
(nd_type
(node2
)) {
7611 case NODE_DREGX_ONCE
:
7612 return NEW_MATCH3
(node2
, node1
);
7615 if
(TYPE
(node2
->nd_lit
) == T_REGEXP
) {
7616 return NEW_MATCH3
(node2
, node1
);
7621 return NEW_CALL
(node1
, tMATCH
, NEW_LIST
(node2
));
7625 gettable_gen
(struct parser_params
*parser
, ID id
)
7627 if
(id
== keyword_self
) {
7630 else if
(id
== keyword_nil
) {
7633 else if
(id
== keyword_true
) {
7636 else if
(id
== keyword_false
) {
7639 else if
(id
== keyword__FILE__
) {
7640 return NEW_STR
(STR_NEW2
(ruby_sourcefile
));
7642 else if
(id
== keyword__LINE__
) {
7643 return NEW_LIT
(INT2FIX
(ruby_sourceline
));
7645 else if
(id
== keyword__ENCODING__
) {
7646 return NEW_LIT
(rb_enc_from_encoding
(parser
->enc
));
7648 else if
(is_local_id
(id
)) {
7649 if
(dyna_in_block
() && dvar_defined
(id
)) return NEW_DVAR
(id
);
7650 if
(local_id
(id
)) return NEW_LVAR
(id
);
7651 /* method call without arguments */
7652 return NEW_VCALL
(id
);
7654 else if
(is_global_id
(id
)) {
7655 return NEW_GVAR
(id
);
7657 else if
(is_instance_id
(id
)) {
7658 return NEW_IVAR
(id
);
7660 else if
(is_const_id
(id
)) {
7661 return NEW_CONST
(id
);
7663 else if
(is_class_id
(id
)) {
7664 return NEW_CVAR
(id
);
7666 compile_error
(PARSER_ARG
"identifier %s is not valid to get", rb_id2name
(id
));
7671 assignable_gen
(struct parser_params
*parser
, ID id
, NODE
*val
)
7674 if
(id
== keyword_self
) {
7675 yyerror("Can't change the value of self");
7677 else if
(id
== keyword_nil
) {
7678 yyerror("Can't assign to nil");
7680 else if
(id
== keyword_true
) {
7681 yyerror("Can't assign to true");
7683 else if
(id
== keyword_false
) {
7684 yyerror("Can't assign to false");
7686 else if
(id
== keyword__FILE__
) {
7687 yyerror("Can't assign to __FILE__");
7689 else if
(id
== keyword__LINE__
) {
7690 yyerror("Can't assign to __LINE__");
7692 else if
(id
== keyword__ENCODING__
) {
7693 yyerror("Can't assign to __ENCODING__");
7695 else if
(is_local_id
(id
)) {
7696 if
(dyna_in_block
()) {
7697 if
(dvar_curr
(id
)) {
7698 return NEW_DASGN_CURR
(id
, val
);
7700 else if
(dvar_defined
(id
)) {
7701 return NEW_DASGN
(id
, val
);
7703 else if
(local_id
(id
)) {
7704 return NEW_LASGN
(id
, val
);
7708 return NEW_DASGN_CURR
(id
, val
);
7712 if
(!local_id
(id
)) {
7715 return NEW_LASGN
(id
, val
);
7718 else if
(is_global_id
(id
)) {
7719 return NEW_GASGN
(id
, val
);
7721 else if
(is_instance_id
(id
)) {
7722 return NEW_IASGN
(id
, val
);
7724 else if
(is_const_id
(id
)) {
7725 if
(in_def || in_single
)
7726 yyerror("dynamic constant assignment");
7727 return NEW_CDECL
(id
, val
, 0);
7729 else if
(is_class_id
(id
)) {
7730 return NEW_CVASGN
(id
, val
);
7733 compile_error
(PARSER_ARG
"identifier %s is not valid to set", rb_id2name
(id
));
7739 shadowing_lvar_gen
(struct parser_params
*parser
, ID name
)
7743 CONST_ID
(uscore
, "_");
7744 if
(uscore
== name
) return
;
7745 if
(dyna_in_block
()) {
7746 if
(dvar_curr
(name
)) {
7747 yyerror("duplicated argument name");
7749 else if
(dvar_defined
(name
) || local_id
(name
)) {
7750 rb_warningS
("shadowing outer local variable - %s", rb_id2name
(name
));
7751 vtable_add
(lvtbl
->vars
, name
);
7755 if
(local_id
(name
)) {
7756 yyerror("duplicated argument name");
7762 new_bv_gen
(struct parser_params
*parser
, ID name
)
7765 if
(!is_local_id
(name
)) {
7766 compile_error
(PARSER_ARG
"invalid local variable - %s",
7770 shadowing_lvar
(name
);
7775 aryset_gen
(struct parser_params
*parser
, NODE
*recv
, NODE
*idx
)
7777 if
(recv
&& nd_type
(recv
) == NODE_SELF
)
7779 return NEW_ATTRASGN
(recv
, tASET
, idx
);
7783 block_dup_check_gen
(struct parser_params
*parser
, NODE
*node1
, NODE
*node2
)
7785 if
(node2
&& node1
&& nd_type
(node1
) == NODE_BLOCK_PASS
) {
7786 compile_error
(PARSER_ARG
"both block arg and actual block given");
7791 rb_id_attrset
(ID id
)
7793 id
&= ~ID_SCOPE_MASK
;
7799 attrset_gen
(struct parser_params
*parser
, NODE
*recv
, ID id
)
7801 if
(recv
&& nd_type
(recv
) == NODE_SELF
)
7803 return NEW_ATTRASGN
(recv
, rb_id_attrset
(id
), 0);
7807 rb_backref_error_gen
(struct parser_params
*parser
, NODE
*node
)
7809 switch
(nd_type
(node
)) {
7811 compile_error
(PARSER_ARG
"Can't set variable $%ld", node
->nd_nth
);
7814 compile_error
(PARSER_ARG
"Can't set variable $%c", (int)node
->nd_nth
);
7820 arg_concat_gen
(struct parser_params
*parser
, NODE
*node1
, NODE
*node2
)
7822 if
(!node2
) return node1
;
7823 switch
(nd_type
(node1
)) {
7824 case NODE_BLOCK_PASS
:
7825 node1
->nd_iter
= arg_concat
(node1
->nd_iter
, node2
);
7828 if
(nd_type
(node2
) != NODE_ARRAY
) break
;
7829 node1
->nd_body
= list_concat
(NEW_LIST
(node1
->nd_body
), node2
);
7830 nd_set_type
(node1
, NODE_ARGSCAT
);
7833 if
(nd_type
(node2
) != NODE_ARRAY
) break
;
7834 node1
->nd_body
= list_concat
(node1
->nd_body
, node2
);
7837 return NEW_ARGSCAT
(node1
, node2
);
7841 arg_append_gen
(struct parser_params
*parser
, NODE
*node1
, NODE
*node2
)
7843 if
(!node1
) return NEW_LIST
(node2
);
7844 switch
(nd_type
(node1
)) {
7846 return list_append
(node1
, node2
);
7847 case NODE_BLOCK_PASS
:
7848 node1
->nd_head
= arg_append
(node1
->nd_head
, node2
);
7851 node1
->nd_body
= list_append
(NEW_LIST
(node1
->nd_body
), node2
);
7852 nd_set_type
(node1
, NODE_ARGSCAT
);
7855 return NEW_ARGSPUSH
(node1
, node2
);
7859 splat_array
(NODE
* node
)
7861 if
(nd_type
(node
) == NODE_SPLAT
) node
= node
->nd_head
;
7862 if
(nd_type
(node
) == NODE_ARRAY
) return node
;
7867 node_assign_gen
(struct parser_params
*parser
, NODE
*lhs
, NODE
*rhs
)
7871 switch
(nd_type
(lhs
)) {
7877 case NODE_DASGN_CURR
:
7881 lhs
->nd_value
= rhs
;
7886 lhs
->nd_args
= arg_append
(lhs
->nd_args
, rhs
);
7890 /* should not happen */
7898 value_expr_gen
(struct parser_params
*parser
, NODE
*node
)
7903 rb_warning0
("empty expression");
7906 switch
(nd_type
(node
)) {
7909 parser_warning
(node
, "void value expression");
7917 if
(!cond
) yyerror("void value expression");
7918 /* or "control never reach"? */
7922 while
(node
->nd_next
) {
7923 node
= node
->nd_next
;
7925 node
= node
->nd_head
;
7929 node
= node
->nd_body
;
7933 if
(!node
->nd_body
) {
7934 node
= node
->nd_else
;
7937 else if
(!node
->nd_else
) {
7938 node
= node
->nd_body
;
7941 if
(!value_expr
(node
->nd_body
)) return Qfalse
;
7942 node
= node
->nd_else
;
7948 node
= node
->nd_2nd
;
7960 void_expr_gen
(struct parser_params
*parser
, NODE
*node
)
7962 const char *useless
= 0;
7964 if
(!RTEST
(ruby_verbose
)) return
;
7967 switch
(nd_type
(node
)) {
7969 switch
(node
->nd_mid
) {
7988 useless
= rb_id2name
(node
->nd_mid
);
8000 useless
= "a variable";
8003 useless
= "a constant";
8009 case NODE_DREGX_ONCE
:
8010 useless
= "a literal";
8035 useless
= "defined?";
8040 int line
= ruby_sourceline
;
8042 ruby_sourceline
= nd_line
(node
);
8043 rb_warnS
("useless use of %s in void context", useless
);
8044 ruby_sourceline
= line
;
8049 void_stmts_gen
(struct parser_params
*parser
, NODE
*node
)
8051 if
(!RTEST
(ruby_verbose
)) return
;
8053 if
(nd_type
(node
) != NODE_BLOCK
) return
;
8056 if
(!node
->nd_next
) return
;
8057 void_expr0
(node
->nd_head
);
8058 node
= node
->nd_next
;
8063 remove_begin
(NODE
*node
)
8065 NODE
**n
= &node
, *n1
= node
;
8066 while
(n1
&& nd_type
(n1
) == NODE_BEGIN
&& n1
->nd_body
) {
8067 *n
= n1
= n1
->nd_body
;
8073 reduce_nodes_gen
(struct parser_params
*parser
, NODE
**body
)
8081 #define subnodes(n1, n2) \
8082 ((!node
->n1
) ?
(node
->n2 ?
(body
= &node
->n2
, 1) : 0) : \
8083 (!node
->n2
) ?
(body
= &node
->n1
, 1) : \
8084 (reduce_nodes
(&node
->n1
), body
= &node
->n2
, 1))
8087 switch
(nd_type
(node
)) {
8093 *body
= node
= node
->nd_stts
;
8096 *body
= node
= node
->nd_body
;
8099 body
= &node
->nd_end
->nd_head
;
8102 if
(subnodes
(nd_body
, nd_else
)) break
;
8105 body
= &node
->nd_body
;
8108 if
(!subnodes
(nd_body
, nd_next
)) goto end
;
8111 if
(!subnodes
(nd_head
, nd_resq
)) goto end
;
8114 if
(!subnodes
(nd_head
, nd_resq
)) goto end
;
8126 assign_in_cond
(struct parser_params
*parser
, NODE
*node
)
8128 switch
(nd_type
(node
)) {
8130 yyerror("multiple assignment in conditional");
8143 switch
(nd_type
(node
->nd_value
)) {
8149 /* reports always */
8150 parser_warn
(node
->nd_value
, "found = in conditional, should be ==");
8165 warn_unless_e_option
(struct parser_params
*parser
, NODE
*node
, const char *str
)
8167 if
(!e_option_supplied
(parser
)) parser_warn
(node
, str
);
8171 warning_unless_e_option
(struct parser_params
*parser
, NODE
*node
, const char *str
)
8173 if
(!e_option_supplied
(parser
)) parser_warning
(node
, str
);
8177 fixup_nodes
(NODE
**rootnode
)
8179 NODE
*node
, *next
, *head
;
8181 for
(node
= *rootnode
; node
; node
= next
) {
8182 enum node_type type
;
8185 next
= node
->nd_next
;
8186 head
= node
->nd_head
;
8187 rb_gc_force_recycle
((VALUE
)node
);
8189 switch
(type
= nd_type
(head
)) {
8192 val
= rb_range_new
(head
->nd_beg
->nd_lit
, head
->nd_end
->nd_lit
,
8193 type
== NODE_DOT3 ? Qtrue
: Qfalse
);
8194 rb_gc_force_recycle
((VALUE
)head
->nd_beg
);
8195 rb_gc_force_recycle
((VALUE
)head
->nd_end
);
8196 nd_set_type
(head
, NODE_LIT
);
8205 static NODE
*cond0
(struct parser_params
*,NODE
*);
8208 range_op
(struct parser_params
*parser
, NODE
*node
)
8210 enum node_type type
;
8212 if
(node
== 0) return
0;
8214 type
= nd_type
(node
);
8216 if
(type
== NODE_LIT
&& FIXNUM_P
(node
->nd_lit
)) {
8217 warn_unless_e_option
(parser
, node
, "integer literal in conditional range");
8218 return NEW_CALL
(node
, tEQ
, NEW_LIST
(NEW_GVAR
(rb_intern
("$."))));
8220 return cond0
(parser
, node
);
8224 literal_node
(NODE
*node
)
8226 if
(!node
) return
1; /* same as NODE_NIL */
8227 switch
(nd_type
(node
)) {
8233 case NODE_DREGX_ONCE
:
8245 cond0
(struct parser_params
*parser
, NODE
*node
)
8247 if
(node
== 0) return
0;
8248 assign_in_cond
(parser
, node
);
8250 switch
(nd_type
(node
)) {
8254 rb_warn0
("string literal in condition");
8258 case NODE_DREGX_ONCE
:
8259 warning_unless_e_option
(parser
, node
, "regex literal in condition");
8260 return NEW_MATCH2
(node
, NEW_GVAR
(rb_intern
("$_")));
8264 node
->nd_1st
= cond0
(parser
, node
->nd_1st
);
8265 node
->nd_2nd
= cond0
(parser
, node
->nd_2nd
);
8270 node
->nd_beg
= range_op
(parser
, node
->nd_beg
);
8271 node
->nd_end
= range_op
(parser
, node
->nd_end
);
8272 if
(nd_type
(node
) == NODE_DOT2
) nd_set_type
(node
,NODE_FLIP2
);
8273 else if
(nd_type
(node
) == NODE_DOT3
) nd_set_type
(node
, NODE_FLIP3
);
8274 if
(!e_option_supplied
(parser
)) {
8275 int b
= literal_node
(node
->nd_beg
);
8276 int e
= literal_node
(node
->nd_end
);
8277 if
((b
== 1 && e
== 1) ||
(b
+ e
>= 2 && RTEST
(ruby_verbose
))) {
8278 parser_warn
(node
, "range literal in condition");
8284 parser_warning
(node
, "literal in condition");
8288 if
(TYPE
(node
->nd_lit
) == T_REGEXP
) {
8289 warn_unless_e_option
(parser
, node
, "regex literal in condition");
8290 nd_set_type
(node
, NODE_MATCH
);
8293 parser_warning
(node
, "literal in condition");
8302 cond_gen
(struct parser_params
*parser
, NODE
*node
)
8304 if
(node
== 0) return
0;
8305 return cond0
(parser
, node
);
8309 logop_gen
(struct parser_params
*parser
, enum node_type type
, NODE
*left
, NODE
*right
)
8312 if
(left
&& nd_type
(left
) == type
) {
8313 NODE
*node
= left
, *second
;
8314 while
((second
= node
->nd_2nd
) != 0 && nd_type
(second
) == type
) {
8317 node
->nd_2nd
= NEW_NODE
(type
, second
, right
, 0);
8320 return NEW_NODE
(type
, left
, right
, 0);
8324 no_blockarg
(struct parser_params
*parser
, NODE
*node
)
8326 if
(node
&& nd_type
(node
) == NODE_BLOCK_PASS
) {
8327 compile_error
(PARSER_ARG
"block argument should not be given");
8332 ret_args_gen
(struct parser_params
*parser
, NODE
*node
)
8335 no_blockarg
(parser
, node
);
8336 if
(nd_type
(node
) == NODE_ARRAY
) {
8337 if
(node
->nd_next
== 0) {
8338 node
= node
->nd_head
;
8341 nd_set_type
(node
, NODE_VALUES
);
8349 new_yield_gen
(struct parser_params
*parser
, NODE
*node
)
8354 no_blockarg
(parser
, node
);
8355 if
(node
&& nd_type
(node
) == NODE_SPLAT
) {
8362 return NEW_YIELD
(node
, state
);
8366 negate_lit
(NODE
*node
)
8368 switch
(TYPE
(node
->nd_lit
)) {
8370 node
->nd_lit
= LONG2FIX
(-FIX2LONG
(node
->nd_lit
));
8373 node
->nd_lit
= rb_funcall
(node
->nd_lit
,tUMINUS
,0,0);
8376 RFLOAT
(node
->nd_lit
)->float_value
= -RFLOAT_VALUE
(node
->nd_lit
);
8385 arg_blk_pass
(NODE
*node1
, NODE
*node2
)
8388 node2
->nd_head
= node1
;
8395 new_args_gen
(struct parser_params
*parser
, NODE
*m
, NODE
*o
, ID r
, NODE
*p
, ID b
)
8397 int saved_line
= ruby_sourceline
;
8401 node
= NEW_ARGS
(m ? m
->nd_plen
: 0, o
);
8402 i1
= m ? m
->nd_next
: 0;
8403 node
->nd_next
= NEW_ARGS_AUX
(r
, b
);
8407 node
->nd_next
->nd_next
= NEW_ARGS_AUX
(p
->nd_pid
, p
->nd_plen
);
8410 node
->nd_next
->nd_next
= NEW_ARGS_AUX
(0, 0);
8413 node
->nd_next
->nd_next
->nd_next
= NEW_NODE
(NODE_AND
, i1
, i2
, 0);
8415 ruby_sourceline
= saved_line
;
8420 local_push_gen
(struct parser_params
*parser
, int inherit_dvars
)
8422 struct local_vars
*local
;
8424 local
= ALLOC
(struct local_vars
);
8425 local
->prev
= lvtbl
;
8426 local
->args
= vtable_alloc
(0);
8427 local
->vars
= vtable_alloc
(inherit_dvars ? DVARS_INHERIT
: DVARS_TOPSCOPE
);
8432 local_pop_gen
(struct parser_params
*parser
)
8434 struct local_vars
*local
= lvtbl
->prev
;
8435 vtable_free
(lvtbl
->args
);
8436 vtable_free
(lvtbl
->vars
);
8442 vtable_tblcpy
(ID
*buf
, const struct vtable
*src
)
8444 int i
, cnt
= vtable_size
(src
);
8448 for
(i
= 0; i
< cnt
; i
++) {
8449 buf
[i
] = src
->tbl
[i
];
8457 local_tbl_gen
(struct parser_params
*parser
)
8459 int cnt
= vtable_size
(lvtbl
->args
) + vtable_size
(lvtbl
->vars
);
8462 if
(cnt
<= 0) return
0;
8463 buf
= ALLOC_N
(ID
, cnt
+ 1);
8464 vtable_tblcpy
(buf
+1, lvtbl
->args
);
8465 vtable_tblcpy
(buf
+vtable_size
(lvtbl
->args
)+1, lvtbl
->vars
);
8472 arg_var_gen
(struct parser_params
*parser
, ID id
)
8474 vtable_add
(lvtbl
->args
, id
);
8475 return vtable_size
(lvtbl
->args
) - 1;
8479 local_var_gen
(struct parser_params
*parser
, ID id
)
8481 vtable_add
(lvtbl
->vars
, id
);
8482 return vtable_size
(lvtbl
->vars
) - 1;
8486 local_id_gen
(struct parser_params
*parser
, ID id
)
8488 struct vtable
*vars
, *args
;
8493 while
(vars
&& POINTER_P
(vars
->prev
)) {
8498 if
(vars
&& vars
->prev
== DVARS_INHERIT
) {
8499 return rb_local_defined
(id
);
8502 return
(vtable_included
(args
, id
) ||
8503 vtable_included
(vars
, id
));
8508 dyna_push_gen
(struct parser_params
*parser
)
8510 lvtbl
->args
= vtable_alloc
(lvtbl
->args
);
8511 lvtbl
->vars
= vtable_alloc
(lvtbl
->vars
);
8515 dyna_pop_gen
(struct parser_params
*parser
)
8520 lvtbl
->args
= lvtbl
->args
->prev
;
8523 lvtbl
->vars
= lvtbl
->vars
->prev
;
8528 dyna_in_block_gen
(struct parser_params
*parser
)
8530 return POINTER_P
(lvtbl
->vars
) && lvtbl
->vars
->prev
!= DVARS_TOPSCOPE
;
8534 dvar_defined_gen
(struct parser_params
*parser
, ID id
)
8536 struct vtable
*vars
, *args
;
8541 while
(POINTER_P
(vars
)) {
8542 if
(vtable_included
(args
, id
)) {
8545 if
(vtable_included
(vars
, id
)) {
8552 if
(vars
== DVARS_INHERIT
) {
8553 return rb_dvar_defined
(id
);
8560 dvar_curr_gen
(struct parser_params
*parser
, ID id
)
8562 return
(vtable_included
(lvtbl
->args
, id
) ||
8563 vtable_included
(lvtbl
->vars
, id
));
8566 VALUE rb_reg_compile
(VALUE str
, int options
);
8567 VALUE rb_reg_check_preprocess
(VALUE
);
8570 reg_fragment_setenc_gen
(struct parser_params
* parser
, VALUE str
, int options
)
8572 int c
= RE_OPTION_ENCODING_IDX
(options
);
8576 rb_char_to_option_kcode
(c
, &opt
, &idx
);
8577 if
(idx
!= ENCODING_GET
(str
) &&
8578 rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
8581 ENCODING_SET
(str
, idx
);
8583 else if
(RE_OPTION_ENCODING_NONE
(options
)) {
8584 if
(!ENCODING_IS_ASCII8BIT
(str
) &&
8585 rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
8589 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
8591 else if
(parser
->enc
== rb_usascii_encoding
()) {
8592 if
(rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
8594 rb_enc_associate
(str
, rb_usascii_encoding
());
8597 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
8603 compile_error
(PARSER_ARG
8604 "regexp encoding option '%c' differs from source encoding '%s'",
8605 c
, rb_enc_name
(rb_enc_get
(str
)));
8609 reg_fragment_check_gen
(struct parser_params
* parser
, VALUE str
, int options
)
8612 reg_fragment_setenc_gen
(parser
, str
, options
);
8613 err
= rb_reg_check_preprocess
(str
);
8615 err
= rb_obj_as_string
(err
);
8616 compile_error
(PARSER_ARG
"%s", RSTRING_PTR
(err
));
8622 struct parser_params
* parser
;
8627 } reg_named_capture_assign_t
;
8630 reg_named_capture_assign_iter
(const OnigUChar
*name
, const OnigUChar
*name_end
,
8631 int back_num
, int *back_refs
, OnigRegex regex
, void *arg0
)
8633 reg_named_capture_assign_t
*arg
= (reg_named_capture_assign_t
*)arg0
;
8634 struct parser_params
* parser
= arg
->parser
;
8635 rb_encoding
*enc
= arg
->enc
;
8636 int len
= name_end
- name
;
8637 const char *s
= (const char *)name
;
8642 if
(arg
->succ_block
== 0) {
8643 arg
->succ_block
= NEW_BEGIN
(0);
8644 arg
->fail_block
= NEW_BEGIN
(0);
8647 if
(!len ||
(*name
!= '_' && ISASCII
(*name
) && !rb_enc_islower
(*name
, enc
)) ||
8648 rb_reserved_word
(s
, len
) ||
!rb_enc_symname2_p
(s
, len
, enc
)) {
8651 var
= rb_intern3
(s
, len
, enc
);
8652 if
(dvar_defined
(var
) || local_id
(var
)) {
8653 rb_warningS
("named capture conflicts a local variable - %s",
8656 arg
->succ_block
= block_append
(arg
->succ_block
,
8657 newline_node
(node_assign
(assignable
(var
,0),
8659 gettable
(rb_intern
("$~")),
8661 NEW_LIST
(NEW_LIT
(ID2SYM
(var
))))
8663 arg
->fail_block
= block_append
(arg
->fail_block
,
8664 newline_node
(node_assign
(assignable
(var
,0), NEW_LIT
(Qnil
))));
8669 reg_named_capture_assign_gen
(struct parser_params
* parser
, VALUE regexp
, NODE
*match
)
8671 reg_named_capture_assign_t arg
;
8673 arg.parser
= parser
;
8674 arg.enc
= rb_enc_get
(regexp
);
8678 onig_foreach_name
(RREGEXP
(regexp
)->ptr
, reg_named_capture_assign_iter
, (void*)&arg
);
8685 newline_node
(match
),
8686 NEW_IF
(gettable
(rb_intern
("$~")),
8688 newline_node
(arg.succ_block
),
8691 gettable
(rb_intern
("$~")),
8693 NEW_LIST
(NEW_LIT
(INT2FIX
(0)))))),
8695 newline_node
(arg.fail_block
),
8701 reg_compile_gen
(struct parser_params
* parser
, VALUE str
, int options
)
8706 reg_fragment_setenc
(str
, options
);
8708 re
= rb_reg_compile
(str
, options
& RE_OPTION_MASK
);
8710 ID mesg
= rb_intern
("mesg");
8711 VALUE m
= rb_attr_get
(rb_errinfo
(), mesg
);
8712 rb_set_errinfo
(err
);
8714 rb_str_append
(rb_str_cat
(rb_attr_get
(err
, mesg
), "\n", 1), m
);
8717 compile_error
(PARSER_ARG
"%s", RSTRING_PTR
(m
));
8725 rb_gc_mark_parser
(void)
8730 rb_parser_append_print
(VALUE vparser
, NODE
*node
)
8734 struct parser_params
*parser
;
8736 if
(!node
) return node
;
8738 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
8740 node
= node
->nd_body
;
8742 if
(nd_type
(node
) == NODE_PRELUDE
) {
8744 node
= node
->nd_body
;
8747 node
= block_append
(node
,
8748 NEW_FCALL
(rb_intern
("print"),
8749 NEW_ARRAY
(NEW_GVAR
(rb_intern
("$_")))));
8751 prelude
->nd_body
= node
;
8752 scope
->nd_body
= prelude
;
8755 scope
->nd_body
= node
;
8762 rb_parser_while_loop
(VALUE vparser
, NODE
*node
, int chop
, int split
)
8766 struct parser_params
*parser
;
8768 if
(!node
) return node
;
8770 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
8772 node
= node
->nd_body
;
8774 if
(nd_type
(node
) == NODE_PRELUDE
) {
8776 node
= node
->nd_body
;
8779 node
= block_append
(NEW_GASGN
(rb_intern
("$F"),
8780 NEW_CALL
(NEW_GVAR
(rb_intern
("$_")),
8781 rb_intern
("split"), 0)),
8785 node
= block_append
(NEW_CALL
(NEW_GVAR
(rb_intern
("$_")),
8786 rb_intern
("chop!"), 0), node
);
8789 node
= NEW_OPT_N
(node
);
8792 prelude
->nd_body
= node
;
8793 scope
->nd_body
= prelude
;
8796 scope
->nd_body
= node
;
8802 static const struct {
8843 static struct symbols
{
8849 VALUE op_sym
[tLAST_TOKEN
];
8850 } global_symbols
= {tLAST_TOKEN
>> ID_SCOPE_SHIFT
};
8852 static const struct st_hash_type symhash
= {
8863 ivar2_cmp
(struct ivar2_key
*key1
, struct ivar2_key
*key2
)
8865 if
(key1
->id
== key2
->id
&& key1
->klass
== key2
->klass
) {
8872 ivar2_hash
(struct ivar2_key
*key
)
8874 return
(key
->id
<< 8) ^
(key
->klass
>> 2);
8877 static const struct st_hash_type ivar2_hash_type
= {
8885 global_symbols.sym_id
= st_init_table_with_size
(&symhash
, 1000);
8886 global_symbols.id_str
= st_init_numtable_with_size
(1000);
8887 global_symbols.ivar2_id
= st_init_table_with_size
(&ivar2_hash_type
, 1000);
8888 global_symbols.id_ivar2
= st_init_numtable_with_size
(1000);
8893 rb_gc_mark_symbols
(void)
8895 rb_mark_tbl
(global_symbols.id_str
);
8896 rb_gc_mark_locations
(global_symbols.op_sym
,
8897 global_symbols.op_sym
+ tLAST_TOKEN
);
8901 internal_id_gen
(struct parser_params
*parser
)
8903 ID id
= (ID
)vtable_size
(lvtbl
->args
) + (ID
)vtable_size
(lvtbl
->vars
);
8904 id
+= ((tLAST_TOKEN
- ID_INTERNAL
) >> ID_SCOPE_SHIFT
) + 1;
8905 return ID_INTERNAL |
(id
<< ID_SCOPE_SHIFT
);
8909 is_special_global_name
(const char *m
, const char *e
, rb_encoding
*enc
)
8913 if
(m
>= e
) return
0;
8915 case
'~': case
'*': case
'$': case
'?': case
'!': case
'@':
8916 case
'/': case
'\\': case
';': case
',': case
'.': case
'=':
8917 case
':': case
'<': case
'>': case
'\"':
8918 case
'&': case
'`': case
'\'': case
'+':
8924 if
(m
< e
&& is_identchar
(m
, e
, enc
)) {
8925 if
(!ISASCII
(*m
)) mb
= 1;
8926 m
+= rb_enc_mbclen
(m
, e
, enc
);
8930 if
(!rb_enc_isdigit
(*m
, enc
)) return
0;
8932 if
(!ISASCII
(*m
)) mb
= 1;
8934 } while
(rb_enc_isdigit
(*m
, enc
));
8936 return m
== e ? mb
+ 1 : 0;
8940 rb_symname_p
(const char *name
)
8942 return rb_enc_symname_p
(name
, rb_ascii8bit_encoding
());
8946 rb_enc_symname_p
(const char *name
, rb_encoding
*enc
)
8948 return rb_enc_symname2_p
(name
, strlen
(name
), enc
);
8952 rb_enc_symname2_p
(const char *name
, int len
, rb_encoding
*enc
)
8954 const char *m
= name
;
8955 const char *e
= m
+ len
;
8956 int localid
= Qfalse
;
8958 if
(!m
) return Qfalse
;
8964 if
(is_special_global_name
(++m
, e
, enc
)) return Qtrue
;
8968 if
(*++m
== '@') ++m
;
8973 case
'<': ++m
; break
;
8974 case
'=': if
(*++m
== '>') ++m
; break
;
8981 case
'>': case
'=': ++m
; break
;
8987 case
'~': ++m
; break
;
8988 case
'=': if
(*++m
== '=') ++m
; break
;
8989 default
: return Qfalse
;
8994 if
(*++m
== '*') ++m
;
8998 if
(*++m
== '@') ++m
;
9001 case
'|': case
'^': case
'&': case
'/': case
'%': case
'~': case
'`':
9006 if
(*++m
!= ']') return Qfalse
;
9007 if
(*++m
== '=') ++m
;
9012 case
'\0': return Qtrue
;
9013 case
'=': case
'~': ++m
; break
;
9014 default
: return Qfalse
;
9019 localid
= !rb_enc_isupper
(*m
, enc
);
9021 if
(m
>= e ||
(*m
!= '_' && !rb_enc_isalpha
(*m
, enc
) && ISASCII
(*m
)))
9023 while
(m
< e
&& is_identchar
(m
, e
, enc
)) m
+= rb_enc_mbclen
(m
, e
, enc
);
9026 case
'!': case
'?': case
'=': ++m
;
9031 return
*m ? Qfalse
: Qtrue
;
9035 rb_intern3
(const char *name
, long len
, rb_encoding
*enc
)
9037 const char *m
= name
;
9038 const char *e
= m
+ len
;
9043 struct RString fake_str
;
9044 fake_str.basic.flags
= T_STRING|RSTRING_NOEMBED|FL_FREEZE
;
9045 fake_str.basic.klass
= rb_cString
;
9046 fake_str.as.heap.len
= len
;
9047 fake_str.as.heap.ptr
= (char *)name
;
9048 fake_str.as.heap.aux.capa
= len
;
9049 str
= (VALUE
)&fake_str
;
9050 rb_enc_associate
(str
, enc
);
9052 if
(st_lookup
(global_symbols.sym_id
, str
, (st_data_t
*)&id
))
9055 if
(rb_cString
&& !rb_enc_asciicompat
(enc
)) {
9064 if
((mb
= is_special_global_name
(++m
, e
, enc
)) != 0) {
9065 if
(!--mb
) enc
= rb_ascii8bit_encoding
();
9080 if
(m
[0] != '_' && rb_enc_isascii
((unsigned char)m
[0], enc
)
9081 && !rb_enc_isalnum
(m
[0], enc
)) {
9085 for
(i
=0; op_tbl
[i
].token
; i
++) {
9086 if
(*op_tbl
[i
].name
== *m
&&
9087 strcmp
(op_tbl
[i
].name
, m
) == 0) {
9088 id
= op_tbl
[i
].token
;
9094 if
(m
[last
] == '=') {
9095 /* attribute assignment */
9096 id
= rb_intern3
(name
, last
, enc
);
9097 if
(id
> tLAST_TOKEN
&& !is_attrset_id
(id
)) {
9098 enc
= rb_enc_get
(rb_id2str
(id
));
9099 id
= rb_id_attrset
(id
);
9104 else if
(rb_enc_isupper
(m
[0], enc
)) {
9113 if
(!rb_enc_isdigit
(*m
, enc
)) {
9114 while
(m
<= name
+ last
&& is_identchar
(m
, e
, enc
)) {
9120 m
+= rb_enc_mbclen
(m
, e
, enc
);
9124 if
(m
- name
< len
) id
= ID_JUNK
;
9125 if
(enc
!= rb_usascii_encoding
()) {
9127 * this clause makes sense only when called from other than
9128 * rb_intern_str() taking care of code-range.
9131 for
(; m
<= name
+ len
; ++m
) {
9132 if
(!ISASCII
(*m
)) goto mbstr
;
9134 enc
= rb_usascii_encoding
();
9139 id |
= ++global_symbols.last_id
<< ID_SCOPE_SHIFT
;
9141 str
= rb_enc_str_new
(name
, len
, enc
);
9143 st_add_direct
(global_symbols.sym_id
, (st_data_t
)str
, id
);
9144 st_add_direct
(global_symbols.id_str
, id
, (st_data_t
)str
);
9149 rb_intern2
(const char *name
, long len
)
9151 return rb_intern3
(name
, len
, rb_usascii_encoding
());
9156 rb_intern
(const char *name
)
9158 return rb_intern2
(name
, strlen
(name
));
9162 rb_intern_str
(VALUE str
)
9167 if
(rb_enc_str_coderange
(str
) == ENC_CODERANGE_7BIT
) {
9168 enc
= rb_usascii_encoding
();
9171 enc
= rb_enc_get
(str
);
9173 id
= rb_intern3
(RSTRING_PTR
(str
), RSTRING_LEN
(str
), enc
);
9183 if
(id
< tLAST_TOKEN
) {
9186 for
(i
=0; op_tbl
[i
].token
; i
++) {
9187 if
(op_tbl
[i
].token
== id
) {
9188 VALUE str
= global_symbols.op_sym
[i
];
9190 str
= rb_usascii_str_new2
(op_tbl
[i
].name
);
9192 global_symbols.op_sym
[i
] = str
;
9199 if
(st_lookup
(global_symbols.id_str
, id
, &data
)) {
9200 VALUE str
= (VALUE
)data
;
9201 if
(RBASIC
(str
)->klass
== 0)
9202 RBASIC
(str
)->klass
= rb_cString
;
9206 if
(is_attrset_id
(id
)) {
9207 ID id2
= (id
& ~ID_SCOPE_MASK
) | ID_LOCAL
;
9210 while
(!(str
= rb_id2str
(id2
))) {
9211 if
(!is_local_id
(id2
)) return
0;
9212 id2
= (id
& ~ID_SCOPE_MASK
) | ID_CONST
;
9214 str
= rb_str_dup
(str
);
9215 rb_str_cat
(str
, "=", 1);
9217 if
(st_lookup
(global_symbols.id_str
, id
, &data
)) {
9218 VALUE str
= (VALUE
)data
;
9219 if
(RBASIC
(str
)->klass
== 0)
9220 RBASIC
(str
)->klass
= rb_cString
;
9230 VALUE str
= rb_id2str
(id
);
9233 return RSTRING_PTR
(str
);
9237 symbols_i
(VALUE sym
, ID value
, VALUE ary
)
9239 rb_ary_push
(ary
, ID2SYM
(value
));
9245 * Symbol.all_symbols => array
9247 * Returns an array of all the symbols currently in Ruby's symbol
9250 * Symbol.all_symbols.size #=> 903
9251 * Symbol.all_symbols[1,20] #=> [:floor, :ARGV, :Binding, :symlink,
9252 * :chown, :EOFError, :$;, :String,
9253 * :LOCK_SH, :"setuid?", :$<,
9254 * :default_proc, :compact, :extend,
9255 * :Tms, :getwd, :$=, :ThreadGroup,
9260 rb_sym_all_symbols
(void)
9262 VALUE ary
= rb_ary_new2
(global_symbols.sym_id
->num_entries
);
9264 st_foreach
(global_symbols.sym_id
, symbols_i
, ary
);
9269 rb_is_const_id
(ID id
)
9271 if
(is_const_id
(id
)) return Qtrue
;
9276 rb_is_class_id
(ID id
)
9278 if
(is_class_id
(id
)) return Qtrue
;
9283 rb_is_instance_id
(ID id
)
9285 if
(is_instance_id
(id
)) return Qtrue
;
9290 rb_is_local_id
(ID id
)
9292 if
(is_local_id
(id
)) return Qtrue
;
9297 rb_is_junk_id
(ID id
)
9299 if
(is_junk_id
(id
)) return Qtrue
;
9303 #endif /* !RIPPER */
9306 parser_initialize
(struct parser_params
*parser
)
9308 parser
->eofp
= Qfalse
;
9310 parser
->parser_lex_strterm
= 0;
9311 parser
->parser_cond_stack
= 0;
9312 parser
->parser_cmdarg_stack
= 0;
9313 parser
->parser_class_nest
= 0;
9314 parser
->parser_paren_nest
= 0;
9315 parser
->parser_lpar_beg
= 0;
9316 parser
->parser_in_single
= 0;
9317 parser
->parser_in_def
= 0;
9318 parser
->parser_in_defined
= 0;
9319 parser
->parser_compile_for_eval
= 0;
9320 parser
->parser_cur_mid
= 0;
9321 parser
->parser_tokenbuf
= NULL
;
9322 parser
->parser_tokidx
= 0;
9323 parser
->parser_toksiz
= 0;
9324 parser
->parser_heredoc_end
= 0;
9325 parser
->parser_command_start
= Qtrue
;
9326 parser
->parser_deferred_nodes
= 0;
9327 parser
->parser_lex_pbeg
= 0;
9328 parser
->parser_lex_p
= 0;
9329 parser
->parser_lex_pend
= 0;
9330 parser
->parser_lvtbl
= 0;
9331 parser
->parser_ruby__end__seen
= 0;
9332 parser
->parser_ruby_sourcefile
= 0;
9334 parser
->is_ripper
= 0;
9335 parser
->parser_eval_tree_begin
= 0;
9336 parser
->parser_eval_tree
= 0;
9338 parser
->is_ripper
= 1;
9339 parser
->parser_ruby_sourcefile_string
= Qnil
;
9340 parser
->delayed
= Qnil
;
9342 parser
->result
= Qnil
;
9343 parser
->parsing_thread
= Qnil
;
9344 parser
->toplevel_p
= Qtrue
;
9347 parser
->heap
= NULL
;
9349 parser
->enc
= rb_usascii_encoding
();
9353 #define parser_mark ripper_parser_mark
9354 #define parser_free ripper_parser_free
9358 parser_mark
(void *ptr
)
9360 struct parser_params
*p
= (struct parser_params
*)ptr
;
9362 rb_gc_mark
((VALUE
)p
->parser_lex_strterm
);
9363 rb_gc_mark
((VALUE
)p
->parser_deferred_nodes
);
9364 rb_gc_mark
(p
->parser_lex_input
);
9365 rb_gc_mark
(p
->parser_lex_lastline
);
9366 rb_gc_mark
(p
->parser_lex_nextline
);
9368 rb_gc_mark
((VALUE
)p
->parser_eval_tree_begin
) ;
9369 rb_gc_mark
((VALUE
)p
->parser_eval_tree
) ;
9370 rb_gc_mark
(p
->debug_lines
);
9372 rb_gc_mark
(p
->parser_ruby_sourcefile_string
);
9373 rb_gc_mark
(p
->delayed
);
9374 rb_gc_mark
(p
->value
);
9375 rb_gc_mark
(p
->result
);
9376 rb_gc_mark
(p
->parsing_thread
);
9379 rb_gc_mark
((VALUE
)p
->heap
);
9384 parser_free
(void *ptr
)
9386 struct parser_params
*p
= (struct parser_params
*)ptr
;
9387 struct local_vars
*local
, *prev
;
9389 if
(p
->parser_tokenbuf
) {
9390 xfree
(p
->parser_tokenbuf
);
9392 for
(local
= p
->parser_lvtbl
; local
; local
= prev
) {
9393 if
(local
->vars
) xfree
(local
->vars
);
9398 xfree
(p
->parser_ruby_sourcefile
);
9403 VALUE rb_parser_get_yydebug
(VALUE
);
9404 VALUE rb_parser_set_yydebug
(VALUE
, VALUE
);
9407 static struct parser_params
*
9410 struct parser_params
*p
;
9412 p
= ALLOC_N
(struct parser_params
, 1);
9413 MEMZERO
(p
, struct parser_params
, 1);
9414 parser_initialize
(p
);
9421 struct parser_params
*p
= parser_new
();
9423 return Data_Wrap_Struct
(0, parser_mark
, parser_free
, p
);
9428 * ripper#end_seen? -> Boolean
9430 * Return if parsed source ended by +\_\_END\_\_+.
9431 * This number starts from 1.
9434 rb_parser_end_seen_p
(VALUE vparser
)
9436 struct parser_params
*parser
;
9438 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
9439 return ruby__end__seen ? Qtrue
: Qfalse
;
9444 * ripper#encoding -> encoding
9446 * Return encoding of the source.
9449 rb_parser_encoding
(VALUE vparser
)
9451 struct parser_params
*parser
;
9453 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
9454 return rb_enc_from_encoding
(parser
->enc
);
9459 * ripper.yydebug -> true or false
9464 rb_parser_get_yydebug
(VALUE self
)
9466 struct parser_params
*parser
;
9468 Data_Get_Struct
(self
, struct parser_params
, parser
);
9469 return
yydebug ? Qtrue
: Qfalse
;
9474 * ripper.yydebug = flag
9479 rb_parser_set_yydebug
(VALUE self
, VALUE flag
)
9481 struct parser_params
*parser
;
9483 Data_Get_Struct
(self
, struct parser_params
, parser
);
9484 yydebug = RTEST
(flag
);
9489 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
9490 #define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
9491 #define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
9492 (n
)->u3.cnt
= (c
), (p
))
9495 rb_parser_malloc
(struct parser_params
*parser
, size_t size
)
9497 size_t cnt
= HEAPCNT
(1, size
);
9498 NODE
*n
= NEWHEAP
();
9499 void *ptr
= xmalloc
(size
);
9501 return ADD2HEAP
(n
, cnt
, ptr
);
9505 rb_parser_calloc
(struct parser_params
*parser
, size_t nelem
, size_t size
)
9507 size_t cnt
= HEAPCNT
(nelem
, size
);
9508 NODE
*n
= NEWHEAP
();
9509 void *ptr
= xcalloc
(nelem
, size
);
9511 return ADD2HEAP
(n
, cnt
, ptr
);
9515 rb_parser_realloc
(struct parser_params
*parser
, void *ptr
, size_t size
)
9518 size_t cnt
= HEAPCNT
(1, size
);
9520 if
(ptr
&& (n
= parser
->heap
) != NULL
) {
9522 if
(n
->u1.node
== ptr
) {
9523 n
->u1.node
= ptr
= xrealloc
(ptr
, size
);
9524 if
(n
->u3.cnt
) n
->u3.cnt
= cnt
;
9527 } while
((n
= n
->u2.node
) != NULL
);
9530 ptr
= xrealloc
(ptr
, size
);
9531 return ADD2HEAP
(n
, cnt
, ptr
);
9535 rb_parser_free
(struct parser_params
*parser
, void *ptr
)
9537 NODE
**prev
= &parser
->heap
, *n
;
9539 while
((n
= *prev
) != NULL
) {
9540 if
(n
->u1.node
== ptr
) {
9542 rb_gc_force_recycle
((VALUE
)n
);
9554 extern
int rb_is_pointer_to_heap
(VALUE
);
9558 ripper_validate_object
(VALUE self
, VALUE x
)
9560 if
(x
== Qfalse
) return x
;
9561 if
(x
== Qtrue
) return x
;
9562 if
(x
== Qnil
) return x
;
9564 rb_raise
(rb_eArgError
, "Qundef given");
9565 if
(FIXNUM_P
(x
)) return x
;
9566 if
(SYMBOL_P
(x
)) return x
;
9567 if
(!rb_is_pointer_to_heap
(x
))
9568 rb_raise
(rb_eArgError
, "invalid pointer: %p", x
);
9577 rb_raise
(rb_eArgError
, "NODE given: %p", x
);
9579 rb_raise
(rb_eArgError
, "wrong type of ruby object: %p (%s)",
9580 x
, rb_obj_classname
(x
));
9589 ripper_dispatch0
(struct parser_params
*parser
, ID mid
)
9591 return rb_funcall
(parser
->value
, mid
, 0);
9595 ripper_dispatch1
(struct parser_params
*parser
, ID mid
, VALUE a
)
9598 return rb_funcall
(parser
->value
, mid
, 1, a
);
9602 ripper_dispatch2
(struct parser_params
*parser
, ID mid
, VALUE a
, VALUE b
)
9606 return rb_funcall
(parser
->value
, mid
, 2, a
, b
);
9610 ripper_dispatch3
(struct parser_params
*parser
, ID mid
, VALUE a
, VALUE b
, VALUE c
)
9615 return rb_funcall
(parser
->value
, mid
, 3, a
, b
, c
);
9619 ripper_dispatch4
(struct parser_params
*parser
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
)
9625 return rb_funcall
(parser
->value
, mid
, 4, a
, b
, c
, d
);
9629 ripper_dispatch5
(struct parser_params
*parser
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
, VALUE e
)
9636 return rb_funcall
(parser
->value
, mid
, 5, a
, b
, c
, d
, e
);
9639 static const struct kw_assoc
{
9642 } keyword_to_name
[] = {
9643 {keyword_class
, "class"},
9644 {keyword_module
, "module"},
9645 {keyword_def
, "def"},
9646 {keyword_undef
, "undef"},
9647 {keyword_begin
, "begin"},
9648 {keyword_rescue
, "rescue"},
9649 {keyword_ensure
, "ensure"},
9650 {keyword_end
, "end"},
9652 {keyword_unless
, "unless"},
9653 {keyword_then
, "then"},
9654 {keyword_elsif
, "elsif"},
9655 {keyword_else
, "else"},
9656 {keyword_case
, "case"},
9657 {keyword_when
, "when"},
9658 {keyword_while
, "while"},
9659 {keyword_until
, "until"},
9660 {keyword_for
, "for"},
9661 {keyword_break
, "break"},
9662 {keyword_next
, "next"},
9663 {keyword_redo
, "redo"},
9664 {keyword_retry
, "retry"},
9667 {keyword_do_cond
, "do"},
9668 {keyword_do_block
, "do"},
9669 {keyword_return
, "return"},
9670 {keyword_yield
, "yield"},
9671 {keyword_super
, "super"},
9672 {keyword_self
, "self"},
9673 {keyword_nil
, "nil"},
9674 {keyword_true
, "true"},
9675 {keyword_false
, "false"},
9676 {keyword_and
, "and"},
9678 {keyword_not
, "not"},
9679 {modifier_if
, "if"},
9680 {modifier_unless
, "unless"},
9681 {modifier_while
, "while"},
9682 {modifier_until
, "until"},
9683 {modifier_rescue
, "rescue"},
9684 {keyword_alias
, "alias"},
9685 {keyword_defined
, "defined?"},
9686 {keyword_BEGIN
, "BEGIN"},
9687 {keyword_END
, "END"},
9688 {keyword__LINE__
, "__LINE__"},
9689 {keyword__FILE__
, "__FILE__"},
9690 {keyword__ENCODING__
, "__ENCODING__"},
9695 keyword_id_to_str
(ID id
)
9697 const struct kw_assoc
*a
;
9699 for
(a
= keyword_to_name
; a
->id
; a
++) {
9707 ripper_id2sym
(ID id
)
9715 return ID2SYM
(rb_intern
(buf
));
9717 if
((name
= keyword_id_to_str
(id
))) {
9718 return ID2SYM
(rb_intern
(name
));
9728 name
= rb_id2name
(id
);
9730 rb_bug
("cannot convert ID to string: %ld", (unsigned long)id
);
9734 return ID2SYM
(rb_intern
(name
));
9738 ripper_intern
(const char *s
)
9740 return ID2SYM
(rb_intern
(s
));
9744 ripper_compile_error
(struct parser_params
*parser
, const char *fmt
, ...
)
9749 va_start
(args
, fmt
);
9750 str
= rb_vsprintf
(fmt
, args
);
9752 rb_funcall
(parser
->value
, rb_intern
("compile_error"), 1, str
);
9756 ripper_warn0
(struct parser_params
*parser
, const char *fmt
)
9758 rb_funcall
(parser
->value
, rb_intern
("warn"), 1, STR_NEW2
(fmt
));
9762 ripper_warnI
(struct parser_params
*parser
, const char *fmt
, int a
)
9764 rb_funcall
(parser
->value
, rb_intern
("warn"), 2,
9765 STR_NEW2
(fmt
), INT2NUM
(a
));
9770 ripper_warnS
(struct parser_params
*parser
, const char *fmt
, const char *str
)
9772 rb_funcall
(parser
->value
, rb_intern
("warn"), 2,
9773 STR_NEW2
(fmt
), STR_NEW2
(str
));
9778 ripper_warning0
(struct parser_params
*parser
, const char *fmt
)
9780 rb_funcall
(parser
->value
, rb_intern
("warning"), 1, STR_NEW2
(fmt
));
9784 ripper_warningS
(struct parser_params
*parser
, const char *fmt
, const char *str
)
9786 rb_funcall
(parser
->value
, rb_intern
("warning"), 2,
9787 STR_NEW2
(fmt
), STR_NEW2
(str
));
9791 ripper_lex_get_generic
(struct parser_params
*parser
, VALUE src
)
9793 return rb_funcall
(src
, ripper_id_gets
, 0);
9797 ripper_s_allocate
(VALUE klass
)
9799 struct parser_params
*p
;
9802 p
= ALLOC_N
(struct parser_params
, 1);
9803 MEMZERO
(p
, struct parser_params
, 1);
9804 self
= Data_Wrap_Struct
(klass
, parser_mark
, parser_free
, p
);
9809 #define ripper_initialized_p(r) ((r)->parser_lex_input != 0)
9813 * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
9815 * Create a new Ripper object.
9816 * _src_ must be a String, a IO, or an Object which has #gets method.
9818 * This method does not starts parsing.
9819 * See also Ripper#parse and Ripper.parse.
9822 ripper_initialize
(int argc
, VALUE
*argv
, VALUE self
)
9824 struct parser_params
*parser
;
9825 VALUE src
, fname
, lineno
;
9827 Data_Get_Struct
(self
, struct parser_params
, parser
);
9828 rb_scan_args
(argc
, argv
, "12", &src
, &fname
, &lineno
);
9829 if
(rb_obj_respond_to
(src
, ripper_id_gets
, 0)) {
9830 parser
->parser_lex_gets
= ripper_lex_get_generic
;
9834 parser
->parser_lex_gets
= lex_get_str
;
9836 parser
->parser_lex_input
= src
;
9837 parser
->eofp
= Qfalse
;
9839 fname
= STR_NEW2
("(ripper)");
9844 parser_initialize
(parser
);
9846 parser
->parser_ruby_sourcefile_string
= fname
;
9847 parser
->parser_ruby_sourcefile
= RSTRING_PTR
(fname
);
9848 parser
->parser_ruby_sourceline
= NIL_P
(lineno
) ?
0 : NUM2INT
(lineno
) - 1;
9853 extern VALUE rb_thread_pass
(void);
9855 struct ripper_args
{
9856 struct parser_params
*parser
;
9862 ripper_parse0
(VALUE parser_v
)
9864 struct parser_params
*parser
;
9866 Data_Get_Struct
(parser_v
, struct parser_params
, parser
);
9867 parser_prepare
(parser
);
9868 ripper_yyparse
((void*)parser
);
9869 return parser
->result
;
9873 ripper_ensure
(VALUE parser_v
)
9875 struct parser_params
*parser
;
9877 Data_Get_Struct
(parser_v
, struct parser_params
, parser
);
9878 parser
->parsing_thread
= Qnil
;
9886 * Start parsing and returns the value of the root action.
9889 ripper_parse
(VALUE self
)
9891 struct parser_params
*parser
;
9893 Data_Get_Struct
(self
, struct parser_params
, parser
);
9894 if
(!ripper_initialized_p
(parser
)) {
9895 rb_raise
(rb_eArgError
, "method called for uninitialized object");
9897 if
(!NIL_P
(parser
->parsing_thread
)) {
9898 if
(parser
->parsing_thread
== rb_thread_current
())
9899 rb_raise
(rb_eArgError
, "Ripper#parse is not reentrant");
9901 rb_raise
(rb_eArgError
, "Ripper#parse is not multithread-safe");
9903 parser
->parsing_thread
= rb_thread_current
();
9904 rb_ensure
(ripper_parse0
, self
, ripper_ensure
, self
);
9906 return parser
->result
;
9911 * ripper#column -> Integer
9913 * Return column number of current parsing line.
9914 * This number starts from 0.
9917 ripper_column
(VALUE self
)
9919 struct parser_params
*parser
;
9922 Data_Get_Struct
(self
, struct parser_params
, parser
);
9923 if
(!ripper_initialized_p
(parser
)) {
9924 rb_raise
(rb_eArgError
, "method called for uninitialized object");
9926 if
(NIL_P
(parser
->parsing_thread
)) return Qnil
;
9927 col
= parser
->tokp
- parser
->parser_lex_pbeg
;
9928 return LONG2NUM
(col
);
9933 * ripper#lineno -> Integer
9935 * Return line number of current parsing line.
9936 * This number starts from 1.
9939 ripper_lineno
(VALUE self
)
9941 struct parser_params
*parser
;
9943 Data_Get_Struct
(self
, struct parser_params
, parser
);
9944 if
(!ripper_initialized_p
(parser
)) {
9945 rb_raise
(rb_eArgError
, "method called for uninitialized object");
9947 if
(NIL_P
(parser
->parsing_thread
)) return Qnil
;
9948 return INT2NUM
(parser
->parser_ruby_sourceline
);
9954 ripper_assert_Qundef
(VALUE self
, VALUE obj
, VALUE msg
)
9957 if
(obj
== Qundef
) {
9958 rb_raise
(rb_eArgError
, "%s", RSTRING_PTR
(msg
));
9965 ripper_value
(VALUE self
, VALUE obj
)
9967 return ULONG2NUM
(obj
);
9976 Ripper
= rb_define_class
("Ripper", rb_cObject
);
9977 rb_define_const
(Ripper
, "Version", rb_usascii_str_new2
(RIPPER_VERSION
));
9978 rb_define_alloc_func
(Ripper
, ripper_s_allocate
);
9979 rb_define_method
(Ripper
, "initialize", ripper_initialize
, -1);
9980 rb_define_method
(Ripper
, "parse", ripper_parse
, 0);
9981 rb_define_method
(Ripper
, "column", ripper_column
, 0);
9982 rb_define_method
(Ripper
, "lineno", ripper_lineno
, 0);
9983 rb_define_method
(Ripper
, "end_seen?", rb_parser_end_seen_p
, 0);
9984 rb_define_method
(Ripper
, "encoding", rb_parser_encoding
, 0);
9985 rb_define_method
(Ripper
, "yydebug", rb_parser_get_yydebug
, 0);
9986 rb_define_method
(Ripper
, "yydebug=", rb_parser_set_yydebug
, 1);
9988 rb_define_method
(rb_mKernel
, "assert_Qundef", ripper_assert_Qundef
, 2);
9989 rb_define_method
(rb_mKernel
, "rawVALUE", ripper_value
, 1);
9990 rb_define_method
(rb_mKernel
, "validate_object", ripper_validate_object
, 1);
9993 ripper_id_gets
= rb_intern
("gets");
9994 ripper_init_eventids1
(Ripper
);
9995 ripper_init_eventids2
(Ripper
);
9996 /* ensure existing in symbol table */
10000 #endif /* RIPPER */