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
39 static ID register_symid
(ID
, const char *, long, rb_encoding
*);
40 #define REGISTER_SYMID(id, name) register_symid(id, name, strlen(name), enc)
44 #define is_notop_id(id) ((id)>tLAST_TOKEN)
45 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
46 #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
47 #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
48 #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
49 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
50 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
51 #define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
53 #define is_asgn_or_id(id) ((is_notop_id(id)) && \
54 (((id
)&ID_SCOPE_MASK
) == ID_GLOBAL || \
55 ((id
)&ID_SCOPE_MASK
) == ID_INSTANCE || \
56 ((id
)&ID_SCOPE_MASK
) == ID_CLASS
))
59 EXPR_BEG
, /* ignore newline, +/- is a sign. */
60 EXPR_END
, /* newline significant, +/- is a operator. */
61 EXPR_ENDARG
, /* ditto, and unbound braces. */
62 EXPR_ARG
, /* newline significant, +/- is a operator. */
63 EXPR_CMDARG
, /* newline significant, +/- is a operator. */
64 EXPR_MID
, /* newline significant, +/- is a operator. */
65 EXPR_FNAME
, /* ignore newline, no reserved words. */
66 EXPR_DOT
, /* right after `.' or `::', no reserved words. */
67 EXPR_CLASS
, /* immediate after `class', no here document. */
68 EXPR_VALUE
/* alike EXPR_BEG but label is disallowed. */
71 # ifdef HAVE_LONG_LONG
72 typedef
unsigned LONG_LONG stack_type
;
74 typedef
unsigned long stack_type
;
77 # define BITSTACK_PUSH(stack, n) (stack = (stack<<1)|((n)&1))
78 # define BITSTACK_POP(stack) (stack = stack >> 1)
79 # define BITSTACK_LEXPOP(stack) (stack = (stack >> 1) | (stack & 1))
80 # define BITSTACK_SET_P(stack) (stack&1)
82 #define COND_PUSH(n) BITSTACK_PUSH(cond_stack, n)
83 #define COND_POP() BITSTACK_POP(cond_stack)
84 #define COND_LEXPOP() BITSTACK_LEXPOP(cond_stack)
85 #define COND_P() BITSTACK_SET_P(cond_stack)
87 #define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, n)
88 #define CMDARG_POP() BITSTACK_POP(cmdarg_stack)
89 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
90 #define CMDARG_P() BITSTACK_SET_P(cmdarg_stack)
102 struct local_vars
*prev
;
105 #define DVARS_INHERIT ((void*)1)
106 #define DVARS_TOPSCOPE NULL
107 #define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
108 #define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
112 vtable_size
(const struct vtable
*tbl
)
114 if
(POINTER_P
(tbl
)) {
124 static struct vtable
*
125 vtable_alloc
(struct vtable
*prev
)
127 struct vtable
*tbl
= ALLOC
(struct vtable
);
130 tbl
->tbl
= ALLOC_N
(ID
, tbl
->capa
);
132 if
(VTBL_DEBUG
) printf
("vtable_alloc: %p\n", tbl
);
137 vtable_free
(struct vtable
*tbl
)
139 if
(VTBL_DEBUG
)printf
("vtable_free: %p\n", tbl
);
140 if
(POINTER_P
(tbl
)) {
149 vtable_add
(struct vtable
*tbl
, ID id
)
151 if
(!POINTER_P
(tbl
)) {
152 rb_bug
("vtable_add: vtable is not allocated (%p)", tbl
);
154 if
(VTBL_DEBUG
) printf
("vtable_add: %p, %s\n", tbl
, rb_id2name
(id
));
156 if
(tbl
->pos
== tbl
->capa
) {
157 tbl
->capa
= tbl
->capa
* 2;
158 REALLOC_N
(tbl
->tbl
, ID
, tbl
->capa
);
160 tbl
->tbl
[tbl
->pos
++] = id
;
164 vtable_included
(const struct vtable
* tbl
, ID id
)
168 if
(POINTER_P
(tbl
)) {
169 for
(i
= 0; i
< tbl
->pos
; i
++) {
170 if
(tbl
->tbl
[i
] == id
) {
180 Structure of Lexer Buffer:
182 lex_pbeg tokp lex_p lex_pend
184 |-----------+--------------+------------|
188 struct parser_params
{
192 YYSTYPE *parser_yylval
;
195 NODE
*parser_lex_strterm
;
196 enum lex_state_e parser_lex_state
;
197 stack_type parser_cond_stack
;
198 stack_type parser_cmdarg_stack
;
199 int parser_class_nest
;
200 int parser_paren_nest
;
202 int parser_in_single
;
204 int parser_compile_for_eval
;
205 VALUE parser_cur_mid
;
206 int parser_in_defined
;
207 char *parser_tokenbuf
;
210 VALUE parser_lex_input
;
211 VALUE parser_lex_lastline
;
212 VALUE parser_lex_nextline
;
213 const char *parser_lex_pbeg
;
214 const char *parser_lex_p
;
215 const char *parser_lex_pend
;
216 int parser_heredoc_end
;
217 int parser_command_start
;
218 NODE
*parser_deferred_nodes
;
219 int parser_lex_gets_ptr
;
220 VALUE
(*parser_lex_gets
)(struct parser_params
*,VALUE
);
221 struct local_vars
*parser_lvtbl
;
222 int parser_ruby__end__seen
;
225 char *parser_ruby_sourcefile
; /* current source file */
226 int parser_ruby_sourceline
; /* current line no. */
234 NODE
*parser_eval_tree_begin
;
235 NODE
*parser_eval_tree
;
241 VALUE parser_ruby_sourcefile_string
;
249 VALUE parsing_thread
;
254 #define UTF8_ENC() (parser->utf8 ? parser->utf8 : \
255 (parser
->utf8
= rb_utf8_encoding
()))
256 #define STR_NEW(p,n) rb_enc_str_new((p),(n),parser->enc)
257 #define STR_NEW0() rb_usascii_str_new(0,0)
258 #define STR_NEW2(p) rb_enc_str_new((p),strlen(p),parser->enc)
259 #define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),parser->enc)
260 #define STR_ENC(m) ((m)?parser->enc:rb_usascii_encoding())
261 #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT)
262 #define TOK_INTERN(mb) rb_intern3(tok(), toklen(), STR_ENC(mb))
265 void *rb_parser_malloc
(struct parser_params
*, size_t);
266 void *rb_parser_realloc
(struct parser_params
*, void *, size_t);
267 void *rb_parser_calloc
(struct parser_params
*, size_t, size_t);
268 void rb_parser_free
(struct parser_params
*, void *);
271 static int parser_yyerror
(struct parser_params
*, const char*);
272 #define yyerror(msg) parser_yyerror(parser, msg)
274 #define YYLEX_PARAM parser
276 #define lex_strterm (parser->parser_lex_strterm)
277 #define lex_state (parser->parser_lex_state)
278 #define cond_stack (parser->parser_cond_stack)
279 #define cmdarg_stack (parser->parser_cmdarg_stack)
280 #define class_nest (parser->parser_class_nest)
281 #define paren_nest (parser->parser_paren_nest)
282 #define lpar_beg (parser->parser_lpar_beg)
283 #define in_single (parser->parser_in_single)
284 #define in_def (parser->parser_in_def)
285 #define compile_for_eval (parser->parser_compile_for_eval)
286 #define cur_mid (parser->parser_cur_mid)
287 #define in_defined (parser->parser_in_defined)
288 #define tokenbuf (parser->parser_tokenbuf)
289 #define tokidx (parser->parser_tokidx)
290 #define toksiz (parser->parser_toksiz)
291 #define lex_input (parser->parser_lex_input)
292 #define lex_lastline (parser->parser_lex_lastline)
293 #define lex_nextline (parser->parser_lex_nextline)
294 #define lex_pbeg (parser->parser_lex_pbeg)
295 #define lex_p (parser->parser_lex_p)
296 #define lex_pend (parser->parser_lex_pend)
297 #define heredoc_end (parser->parser_heredoc_end)
298 #define command_start (parser->parser_command_start)
299 #define deferred_nodes (parser->parser_deferred_nodes)
300 #define lex_gets_ptr (parser->parser_lex_gets_ptr)
301 #define lex_gets (parser->parser_lex_gets)
302 #define lvtbl (parser->parser_lvtbl)
303 #define ruby__end__seen (parser->parser_ruby__end__seen)
304 #define ruby_sourceline (parser->parser_ruby_sourceline)
305 #define ruby_sourcefile (parser->parser_ruby_sourcefile)
306 #define yydebug (parser->parser_yydebug)
309 #define ruby_eval_tree (parser->parser_eval_tree)
310 #define ruby_eval_tree_begin (parser->parser_eval_tree_begin)
311 #define ruby_debug_lines (parser->debug_lines)
312 #define ruby_coverage (parser->coverage)
315 static int yylex(void*, void*);
318 #define yyparse ruby_yyparse
320 static NODE
* node_newnode
(struct parser_params
*, enum node_type
, VALUE
, VALUE
, VALUE
);
321 #define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, type, a1, a2, a3)
323 static NODE
*cond_gen
(struct parser_params
*,NODE
*);
324 #define cond(node) cond_gen(parser, node)
325 static NODE
*logop_gen
(struct parser_params
*,enum node_type
,NODE
*,NODE
*);
326 #define logop(type,node1,node2) logop_gen(parser, type, node1, node2)
328 static NODE
*newline_node
(NODE
*);
329 static void fixpos
(NODE
*,NODE
*);
331 static int value_expr_gen
(struct parser_params
*,NODE
*);
332 static void void_expr_gen
(struct parser_params
*,NODE
*);
333 static NODE
*remove_begin
(NODE
*);
334 #define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
335 #define void_expr0(node) void_expr_gen(parser, (node))
336 #define void_expr(node) void_expr0((node) = remove_begin(node))
337 static void void_stmts_gen
(struct parser_params
*,NODE
*);
338 #define void_stmts(node) void_stmts_gen(parser, node)
339 static void reduce_nodes_gen
(struct parser_params
*,NODE
**);
340 #define reduce_nodes(n) reduce_nodes_gen(parser,n)
341 static void block_dup_check_gen
(struct parser_params
*,NODE
*,NODE
*);
342 #define block_dup_check(n1,n2) block_dup_check_gen(parser,n1,n2)
344 static NODE
*block_append_gen
(struct parser_params
*,NODE
*,NODE
*);
345 #define block_append(h,t) block_append_gen(parser,h,t)
346 static NODE
*list_append_gen
(struct parser_params
*,NODE
*,NODE
*);
347 #define list_append(l,i) list_append_gen(parser,l,i)
348 static NODE
*list_concat_gen
(struct parser_params
*,NODE
*,NODE
*);
349 #define list_concat(h,t) list_concat_gen(parser,h,t)
350 static NODE
*arg_append_gen
(struct parser_params
*,NODE
*,NODE
*);
351 #define arg_append(h,t) arg_append_gen(parser,h,t)
352 static NODE
*arg_concat_gen
(struct parser_params
*,NODE
*,NODE
*);
353 #define arg_concat(h,t) arg_concat_gen(parser,h,t)
354 static NODE
*literal_concat_gen
(struct parser_params
*,NODE
*,NODE
*);
355 #define literal_concat(h,t) literal_concat_gen(parser,h,t)
356 static NODE
*new_evstr_gen
(struct parser_params
*,NODE
*);
357 #define new_evstr(n) new_evstr_gen(parser,n)
358 static NODE
*evstr2dstr_gen
(struct parser_params
*,NODE
*);
359 #define evstr2dstr(n) evstr2dstr_gen(parser,n)
360 static NODE
*splat_array
(NODE
*);
362 static NODE
*call_bin_op_gen
(struct parser_params
*,NODE
*,ID
,NODE
*);
363 #define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, recv,id,arg1)
364 static NODE
*call_uni_op_gen
(struct parser_params
*,NODE
*,ID
);
365 #define call_uni_op(recv,id) call_uni_op_gen(parser, recv,id)
367 static NODE
*new_args_gen
(struct parser_params
*,NODE
*,NODE
*,ID
,NODE
*,ID
);
368 #define new_args(f,o,r,p,b) new_args_gen(parser, f,o,r,p,b)
369 static void shadowing_lvar_gen
(struct parser_params
*,ID
);
370 #define shadowing_lvar(name) shadowing_lvar_gen(parser, name)
372 static NODE
*negate_lit
(NODE
*);
373 static NODE
*ret_args_gen
(struct parser_params
*,NODE
*);
374 #define ret_args(node) ret_args_gen(parser, node)
375 static NODE
*arg_blk_pass
(NODE
*,NODE
*);
376 static NODE
*new_yield_gen
(struct parser_params
*,NODE
*);
377 #define new_yield(node) new_yield_gen(parser, node)
379 static NODE
*gettable_gen
(struct parser_params
*,ID
);
380 #define gettable(id) gettable_gen(parser,id)
381 static NODE
*assignable_gen
(struct parser_params
*,ID
,NODE
*);
382 #define assignable(id,node) assignable_gen(parser, id, node)
383 static void new_bv_gen
(struct parser_params
*,ID
);
384 #define new_bv(id) new_bv_gen(parser, id)
385 static NODE
*aryset_gen
(struct parser_params
*,NODE
*,NODE
*);
386 #define aryset(node1,node2) aryset_gen(parser, node1, node2)
387 static NODE
*attrset_gen
(struct parser_params
*,NODE
*,ID
);
388 #define attrset(node,id) attrset_gen(parser, node, id)
390 static void rb_backref_error_gen
(struct parser_params
*,NODE
*);
391 #define rb_backref_error(n) rb_backref_error_gen(parser,n)
392 static NODE
*node_assign_gen
(struct parser_params
*,NODE
*,NODE
*);
393 #define node_assign(node1, node2) node_assign_gen(parser, node1, node2)
395 static NODE
*match_op_gen
(struct parser_params
*,NODE
*,NODE
*);
396 #define match_op(node1,node2) match_op_gen(parser, node1, node2)
398 static void local_push_gen
(struct parser_params
*,int);
399 #define local_push(top) local_push_gen(parser,top)
400 static void local_pop_gen
(struct parser_params
*);
401 #define local_pop() local_pop_gen(parser)
402 static int local_var_gen
(struct parser_params
*, ID
);
403 #define local_var(id) local_var_gen(parser, id);
404 static int arg_var_gen
(struct parser_params
*, ID
);
405 #define arg_var(id) arg_var_gen(parser, id)
406 static int local_id_gen
(struct parser_params
*, ID
);
407 #define local_id(id) local_id_gen(parser, id)
408 static ID
*local_tbl_gen
(struct parser_params
*);
409 #define local_tbl() local_tbl_gen(parser)
410 static ID internal_id_gen
(struct parser_params
*);
411 #define internal_id() internal_id_gen(parser)
413 static void dyna_push_gen
(struct parser_params
*);
414 #define dyna_push() dyna_push_gen(parser)
415 static void dyna_pop_gen
(struct parser_params
*);
416 #define dyna_pop() dyna_pop_gen(parser)
417 static int dyna_in_block_gen
(struct parser_params
*);
418 #define dyna_in_block() dyna_in_block_gen(parser)
419 #define dyna_var(id) local_var(id)
420 static int dvar_defined_gen
(struct parser_params
*,ID
);
421 #define dvar_defined(id) dvar_defined_gen(parser, id)
422 static int dvar_curr_gen
(struct parser_params
*,ID
);
423 #define dvar_curr(id) dvar_curr_gen(parser, id)
425 static void fixup_nodes
(NODE
**);
427 extern
int rb_dvar_defined
(ID
);
428 extern
int rb_local_defined
(ID
);
429 extern
int rb_parse_in_eval
(void);
431 static VALUE reg_compile_gen
(struct parser_params
*, VALUE
, int);
432 #define reg_compile(str,options) reg_compile_gen(parser, str, options)
433 static void reg_fragment_setenc_gen
(struct parser_params
*, VALUE
, int);
434 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, str, options)
435 static void reg_fragment_check_gen
(struct parser_params
*, VALUE
, int);
436 #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, str, options)
437 static NODE
*reg_named_capture_assign_gen
(struct parser_params
* parser
, VALUE regexp
, NODE
*match
);
438 #define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,regexp,match)
439 int rb_enc_symname2_p
(const char *, int, rb_encoding
*);
441 #define remove_begin(node) (node)
443 static int lvar_defined_gen
(struct parser_params
*, ID
);
444 #define lvar_defined(id) lvar_defined_gen(parser, id)
446 #define RE_OPTION_ONCE (1<<16)
447 #define RE_OPTION_ENCODING_SHIFT 8
448 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
449 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
450 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
451 #define RE_OPTION_MASK 0xff
452 #define RE_OPTION_ARG_ENCODING_NONE 32
454 #define NODE_STRTERM NODE_ZARRAY /* nothing to gc */
455 #define NODE_HEREDOC NODE_ARRAY /* 1, 3 to gc */
456 #define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
457 #define nd_func u1.id
458 #if SIZEOF_SHORT == 2
459 #define nd_term(node) ((signed short)(node)->u2.id)
461 #define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
463 #define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
464 #define nd_nest u3.cnt
466 /****** Ripper *******/
469 #define RIPPER_VERSION "0.1.0"
471 #include "eventids1.c"
472 #include "eventids2.c"
473 static ID ripper_id_gets
;
475 static VALUE ripper_dispatch0
(struct parser_params
*,ID
);
476 static VALUE ripper_dispatch1
(struct parser_params
*,ID
,VALUE
);
477 static VALUE ripper_dispatch2
(struct parser_params
*,ID
,VALUE
,VALUE
);
478 static VALUE ripper_dispatch3
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
);
479 static VALUE ripper_dispatch4
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
);
480 static VALUE ripper_dispatch5
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
);
482 #define dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
483 #define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), a)
484 #define dispatch2(n,a,b) ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), a, b)
485 #define dispatch3(n,a,b,c) ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), a, b, c)
486 #define dispatch4(n,a,b,c,d) ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), a, b, c, d)
487 #define dispatch5(n,a,b,c,d,e) ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), a, b, c, d, e)
489 #define yyparse ripper_yyparse
491 static VALUE ripper_intern
(const char*);
492 static VALUE ripper_id2sym
(ID
);
494 #define ripper_id2sym(id) ((id) < 256 && rb_ispunct(id) ? \
495 ID2SYM
(id
) : ripper_id2sym
(id
))
498 #define arg_new() dispatch0(args_new)
499 #define arg_add(l,a) dispatch2(args_add, l, a)
500 #define arg_prepend(l,a) dispatch2(args_prepend, l, a)
501 #define arg_add_star(l,a) dispatch2(args_add_star, l, a)
502 #define arg_add_block(l,b) dispatch2(args_add_block, l, b)
503 #define arg_add_optblock(l,b) ((b)==Qundef? l : dispatch2(args_add_block, l, b))
504 #define bare_assoc(v) dispatch1(bare_assoc_hash, v)
505 #define arg_add_assocs(l,b) arg_add(l, bare_assoc(b))
507 #define args2mrhs(a) dispatch1(mrhs_new_from_args, a)
508 #define mrhs_new() dispatch0(mrhs_new)
509 #define mrhs_add(l,a) dispatch2(mrhs_add, l, a)
510 #define mrhs_add_star(l,a) dispatch2(mrhs_add_star, l, a)
512 #define mlhs_new() dispatch0(mlhs_new)
513 #define mlhs_add(l,a) dispatch2(mlhs_add, l, a)
514 #define mlhs_add_star(l,a) dispatch2(mlhs_add_star, l, a)
516 #define params_new(pars, opts, rest, pars2, blk) \
517 dispatch5
(params
, pars
, opts
, rest
, pars2
, blk
)
519 #define blockvar_new(p,v) dispatch2(block_var, p, v)
520 #define blockvar_add_star(l,a) dispatch2(block_var_add_star, l, a)
521 #define blockvar_add_block(l,a) dispatch2(block_var_add_block, l, a)
523 #define method_optarg(m,a) ((a)==Qundef ? m : dispatch2(method_add_arg,m,a))
524 #define method_arg(m,a) dispatch2(method_add_arg,m,a)
525 #define method_add_block(m,b) dispatch2(method_add_block, m, b)
527 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
534 # define ifndef_ripper(x) x
536 # define ifndef_ripper(x)
540 # define rb_warn0(fmt) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt)
541 # define rb_warnI(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt, a)
542 # define rb_warnS(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, fmt, a)
543 # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, fmt)
544 # define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, fmt, a)
546 # define rb_warn0(fmt) ripper_warn0(parser, fmt)
547 # define rb_warnI(fmt,a) ripper_warnI(parser, fmt, a)
548 # define rb_warnS(fmt,a) ripper_warnS(parser, fmt, a)
549 # define rb_warning0(fmt) ripper_warning0(parser, fmt)
550 # define rb_warningS(fmt,a) ripper_warningS(parser, fmt, a)
551 static void ripper_warn0
(struct parser_params
*, const char*);
552 static void ripper_warnI
(struct parser_params
*, const char*, int);
554 static void ripper_warnS
(struct parser_params
*, const char*, const char*);
556 static void ripper_warning0
(struct parser_params
*, const char*);
557 static void ripper_warningS
(struct parser_params
*, const char*, const char*);
561 static void ripper_compile_error
(struct parser_params
*, const char *fmt
, ...
);
562 # define rb_compile_error ripper_compile_error
563 # define compile_error ripper_compile_error
564 # define PARSER_ARG parser,
566 # define compile_error parser->nerr++,rb_compile_error
567 # define PARSER_ARG ruby_sourcefile, ruby_sourceline,
570 /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
571 for instance). This is too low for Ruby to parse some files, such as
572 date/format.rb, therefore bump the value up to at least Bison's default. */
575 #define YYMAXDEPTH 10000
582 %parse
-param
{struct parser_params
*parser
}
589 struct RVarmap
*vars
;
647 %token
<id
> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
648 %token
<node
> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
649 %token
<node
> tNTH_REF tBACK_REF
650 %token
<num
> tREGEXP_END
652 %type
<node
> singleton strings
string string1 xstring regexp
653 %type
<node
> string_contents xstring_contents string_content
654 %type
<node
> words qwords word_list qword_list word
655 %type
<node
> literal numeric dsym cpath
656 %type
<node
> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
657 %type
<node
> expr_value arg_value primary_value
658 %type
<node
> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
659 %type
<node
> args call_args opt_call_args
660 %type
<node
> paren_args opt_paren_args
661 %type
<node
> command_args aref_args opt_block_arg block_arg var_ref var_lhs
662 %type
<node
> mrhs superclass block_call block_command
663 %type
<node
> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
664 %type
<node
> assoc_list assocs assoc undef_list backref string_dvar for_var
665 %type
<node
> block_param opt_block_param block_param_def f_opt
666 %type
<node
> bv_decls opt_bv_decl bvar
667 %type
<node
> lambda f_larglist lambda_body
668 %type
<node
> brace_block cmd_brace_block do_block lhs none fitem
669 %type
<node
> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
670 %type
<id
> fsym variable sym symbol operation operation2 operation3
671 %type
<id
> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
674 %type <val> program reswords then do dot_or_colon
676 %token tUPLUS
/* unary+ */
677 %token tUMINUS
/* unary- */
679 %token tCMP
/* <=> */
681 %token tEQQ
/* === */
685 %token tANDOP tOROP
/* && and || */
686 %token tMATCH tNMATCH
/* =~ and !~ */
687 %token tDOT2 tDOT3
/* .. and ... */
688 %token tAREF tASET
/* [] and []= */
689 %token tLSHFT tRSHFT
/* << and >> */
690 %token tCOLON2
/* :: */
691 %token tCOLON3
/* :: at EXPR_BEG */
692 %token
<id
> tOP_ASGN
/* +=, -= etc. */
693 %token tASSOC
/* => */
694 %token tLPAREN
/* ( */
695 %token tLPAREN_ARG
/* ( */
696 %token tRPAREN
/* ) */
697 %token tLBRACK
/* [ */
698 %token tLBRACE
/* { */
699 %token tLBRACE_ARG
/* { */
701 %token tAMPER
/* & */
702 %token tLAMBDA
/* -> */
703 %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
704 %token tSTRING_DBEG tSTRING_DVAR tSTRING_END tLAMBEG
711 %nonassoc tLBRACE_ARG
713 %nonassoc modifier_if modifier_unless modifier_while modifier_until
714 %left keyword_or keyword_and
716 %nonassoc keyword_defined
718 %left modifier_rescue
720 %nonassoc tDOT2 tDOT3
723 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
724 %left
'>' tGEQ
'<' tLEQ
730 %right tUMINUS_NUM tUMINUS
732 %right
'!' '~' tUPLUS
735 %nonassoc idRespond_to
738 %nonassoc idThrowState
739 %nonassoc id_core_set_method_alias
740 %nonassoc id_core_set_variable_alias
741 %nonassoc id_core_undef_method
742 %nonassoc id_core_define_method
743 %nonassoc id_core_define_singleton_method
744 %nonassoc id_core_set_postexe
750 lex_state
= EXPR_BEG
;
752 local_push
(compile_for_eval
);
759 if
($2 && !compile_for_eval
) {
760 /* last expression should not be void */
761 if
(nd_type
($2) != NODE_BLOCK
) void_expr
($2);
764 while
(node
->nd_next
) {
765 node
= node
->nd_next
;
767 void_expr
(node
->nd_head
);
770 ruby_eval_tree
= NEW_SCOPE
(0, block_append
(ruby_eval_tree
, $2));
774 parser->result = dispatch1(program, $$);
787 $$
= NEW_RESCUE
($1, $2, $3);
790 rb_warn0
("else without rescue is useless");
791 $$
= block_append
($$
, $3);
795 $$
= NEW_ENSURE
($$
, $4);
798 $$
= block_append
($4, NEW_NIL
());
803 $$ = dispatch4(body_stmt,
812 compstmt
: stmts opt_terms
816 fixup_nodes
(&deferred_nodes
);
828 $$ = dispatch2(stmts_add, dispatch0(stmts_new),
829 dispatch0(void_stmt));
835 $$
= newline_node
($1);
837 $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
843 $$
= block_append
($1, newline_node
($3));
845 $$ = dispatch2(stmts_add, $1, $3);
850 $$
= remove_begin
($2);
854 stmt
: keyword_alias fitem
{lex_state
= EXPR_FNAME
;} fitem
857 $$
= NEW_ALIAS
($2, $4);
859 $$ = dispatch2(alias, $2, $4);
862 | keyword_alias tGVAR tGVAR
865 $$
= NEW_VALIAS
($2, $3);
867 $$ = dispatch2(var_alias, $2, $3);
870 | keyword_alias tGVAR tBACK_REF
875 sprintf
(buf
, "$%c", (char)$3->nd_nth
);
876 $$
= NEW_VALIAS
($2, rb_intern
(buf
));
878 $$ = dispatch2(var_alias, $2, $3);
881 | keyword_alias tGVAR tNTH_REF
884 yyerror("can't make alias for the number variables");
887 $$ = dispatch2(var_alias, $2, $3);
888 $$ = dispatch1(alias_error, $$);
891 | keyword_undef undef_list
896 $$ = dispatch1(undef, $2);
899 | stmt modifier_if expr_value
902 $$
= NEW_IF
(cond
($3), remove_begin
($1), 0);
905 $$ = dispatch2(if_mod, $3, $1);
908 | stmt modifier_unless expr_value
911 $$
= NEW_UNLESS
(cond
($3), remove_begin
($1), 0);
914 $$ = dispatch2(unless_mod, $3, $1);
917 | stmt modifier_while expr_value
920 if
($1 && nd_type
($1) == NODE_BEGIN
) {
921 $$
= NEW_WHILE
(cond
($3), $1->nd_body
, 0);
924 $$
= NEW_WHILE
(cond
($3), $1, 1);
927 $$ = dispatch2(while_mod, $3, $1);
930 | stmt modifier_until expr_value
933 if
($1 && nd_type
($1) == NODE_BEGIN
) {
934 $$
= NEW_UNTIL
(cond
($3), $1->nd_body
, 0);
937 $$
= NEW_UNTIL
(cond
($3), $1, 1);
940 $$ = dispatch2(until_mod, $3, $1);
943 | stmt modifier_rescue stmt
946 NODE
*resq
= NEW_RESBODY
(0, remove_begin
($3), 0);
947 $$
= NEW_RESCUE
(remove_begin
($1), resq
, 0);
949 $$ = dispatch2(rescue_mod, $3, $1);
954 if
(in_def || in_single
) {
955 yyerror("BEGIN in method");
965 ruby_eval_tree_begin
= block_append
(ruby_eval_tree_begin
,
967 /* NEW_PREEXE($4)); */
971 $$ = dispatch1(BEGIN, $4);
974 | keyword_END
'{' compstmt
'}'
976 if
(in_def || in_single
) {
977 rb_warn0
("END in method; use at_exit");
980 $$
= NEW_POSTEXE
(NEW_NODE
(
981 NODE_SCOPE
, 0 /* tbl */, $3 /* body */, 0 /* args */));
983 $$ = dispatch1(END, $3);
986 | lhs
'=' command_call
990 $$
= node_assign
($1, $3);
992 $$ = dispatch2(assign, $1, $3);
995 | mlhs
'=' command_call
1002 $$ = dispatch2(massign, $1, $3);
1005 | var_lhs tOP_ASGN command_call
1010 ID vid
= $1->nd_vid
;
1013 $$
= NEW_OP_ASGN_OR
(gettable
(vid
), $1);
1014 if
(is_asgn_or_id
(vid
)) {
1018 else if
($2 == tANDOP
) {
1020 $$
= NEW_OP_ASGN_AND
(gettable
(vid
), $1);
1024 $$
->nd_value
= NEW_CALL
(gettable
(vid
), $2, NEW_LIST
($3));
1031 $$ = dispatch3(opassign, $1, $2, $3);
1034 | primary_value
'[' opt_call_args rbracket tOP_ASGN command_call
1040 if
(!$3) $3 = NEW_ZARRAY
();
1041 args
= arg_concat
($6, $3);
1045 else if
($5 == tANDOP
) {
1048 $$
= NEW_OP_ASGN1
($1, $5, args
);
1051 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1052 $$ = dispatch3(opassign, $$, $5, $6);
1055 | primary_value
'.' tIDENTIFIER tOP_ASGN command_call
1062 else if
($4 == tANDOP
) {
1065 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1068 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1069 $$ = dispatch3(opassign, $$, $4, $5);
1072 | primary_value
'.' tCONSTANT tOP_ASGN command_call
1079 else if
($4 == tANDOP
) {
1082 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1085 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1086 $$ = dispatch3(opassign, $$, $4, $5);
1089 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
1096 else if
($4 == tANDOP
) {
1099 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1102 $$ = dispatch3(field, $1, ripper_intern("::"), $3);
1103 $$ = dispatch3(opassign, $$, $4, $5);
1106 | backref tOP_ASGN command_call
1109 rb_backref_error
($1);
1112 $$ = dispatch2(assign, dispatch1(var_field, $1), $3);
1113 $$ = dispatch1(assign_error, $$);
1120 $$
= node_assign
($1, $3);
1122 $$ = dispatch2(assign, $1, $3);
1125 | mlhs
'=' arg_value
1131 dispatch2(massign, $1, $3);
1140 $$ = dispatch2(massign, $1, $3);
1147 | expr keyword_and expr
1150 $$
= logop
(NODE_AND
, $1, $3);
1152 $$ = dispatch3(binary, $1, ripper_intern("and"), $3);
1155 | expr keyword_or expr
1158 $$
= logop
(NODE_OR
, $1, $3);
1160 $$ = dispatch3(binary, $1, ripper_intern("or"), $3);
1166 $$
= call_uni_op
(cond
($2), '!');
1168 $$ = dispatch2(unary, ripper_intern("not"), $2);
1174 $$
= call_uni_op
(cond
($2), '!');
1176 $$ = dispatch2(unary, ripper_id2sym('!'), $2);
1187 if
(!$$
) $$
= NEW_NIL
();
1194 command_call
: command
1196 | keyword_return call_args
1199 $$
= NEW_RETURN
(ret_args
($2));
1201 $$ = dispatch1(return, $2);
1204 | keyword_break call_args
1207 $$
= NEW_BREAK
(ret_args
($2));
1209 $$ = dispatch1(break, $2);
1212 | keyword_next call_args
1215 $$
= NEW_NEXT
(ret_args
($2));
1217 $$ = dispatch1(next, $2);
1222 block_command
: block_call
1223 | block_call
'.' operation2 command_args
1226 $$
= NEW_CALL
($1, $3, $4);
1228 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
1229 $$ = method_arg($$, $4);
1232 | block_call tCOLON2 operation2 command_args
1235 $$
= NEW_CALL
($1, $3, $4);
1237 $$ = dispatch3(call, $1, ripper_intern("::"), $3);
1238 $$ = method_arg($$, $4);
1243 cmd_brace_block
: tLBRACE_ARG
1247 $
<num
>$
= ruby_sourceline
;
1256 $$
= NEW_ITER
($3,$4);
1257 nd_set_line
($$
, $
<num
>2);
1260 $$ = dispatch2(brace_block, escape_Qundef($3), $4);
1265 command
: operation command_args %prec tLOWEST
1268 $$
= NEW_FCALL
($1, $2);
1271 $$ = dispatch2(command, $1, $2);
1274 | operation command_args cmd_brace_block
1277 block_dup_check
($2,$3);
1278 $3->nd_iter
= NEW_FCALL
($1, $2);
1282 $$ = dispatch2(command, $1, $2);
1283 $$ = method_add_block($$, $3);
1286 | primary_value
'.' operation2 command_args %prec tLOWEST
1289 $$
= NEW_CALL
($1, $3, $4);
1292 $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1295 | primary_value
'.' operation2 command_args cmd_brace_block
1298 block_dup_check
($4,$5);
1299 $5->nd_iter
= NEW_CALL
($1, $3, $4);
1303 $$ = dispatch4(command_call, $1, ripper_id2sym('.'), $3, $4);
1304 $$ = method_add_block($$, $5);
1307 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1310 $$
= NEW_CALL
($1, $3, $4);
1313 $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1316 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1319 block_dup_check
($4,$5);
1320 $5->nd_iter
= NEW_CALL
($1, $3, $4);
1324 $$ = dispatch4(command_call, $1, ripper_intern("::"), $3, $4);
1325 $$ = method_add_block($$, $5);
1328 | keyword_super command_args
1334 $$ = dispatch1(super, $2);
1337 | keyword_yield command_args
1343 $$ = dispatch1(yield, $2);
1349 | tLPAREN mlhs_inner rparen
1354 $$ = dispatch1(mlhs_paren, $2);
1359 mlhs_inner
: mlhs_basic
1360 | tLPAREN mlhs_inner rparen
1363 $$
= NEW_MASGN
(NEW_LIST
($2), 0);
1365 $$ = dispatch1(mlhs_paren, $2);
1370 mlhs_basic
: mlhs_head
1373 $$
= NEW_MASGN
($1, 0);
1378 | mlhs_head mlhs_item
1381 $$
= NEW_MASGN
(list_append
($1,$2), 0);
1383 $$ = mlhs_add($1, $2);
1386 | mlhs_head tSTAR mlhs_node
1389 $$
= NEW_MASGN
($1, $3);
1391 $$ = mlhs_add_star($1, $3);
1394 | mlhs_head tSTAR mlhs_node
',' mlhs_post
1397 $$
= NEW_MASGN
($1, NEW_POSTARG
($3,$5));
1399 $$ = mlhs_add_star($1, $3);
1405 $$
= NEW_MASGN
($1, -1);
1407 $$ = mlhs_add_star($1, Qnil);
1410 | mlhs_head tSTAR
',' mlhs_post
1413 $$
= NEW_MASGN
($1, NEW_POSTARG
(-1, $4));
1415 $$ = mlhs_add_star($1, Qnil);
1421 $$
= NEW_MASGN
(0, $2);
1423 $$ = mlhs_add_star(mlhs_new(), $2);
1426 | tSTAR mlhs_node
',' mlhs_post
1429 $$
= NEW_MASGN
(0, NEW_POSTARG
($2,$4));
1431 $$ = mlhs_add_star(mlhs_new(), $2);
1437 $$
= NEW_MASGN
(0, -1);
1439 $$ = mlhs_add_star(mlhs_new(), Qnil);
1442 | tSTAR
',' mlhs_post
1445 $$
= NEW_MASGN
(0, NEW_POSTARG
(-1, $3));
1447 $$ = mlhs_add_star(mlhs_new(), Qnil);
1452 mlhs_item
: mlhs_node
1453 | tLPAREN mlhs_inner rparen
1458 $$ = dispatch1(mlhs_paren, $2);
1463 mlhs_head
: mlhs_item
','
1468 $$ = mlhs_add(mlhs_new(), $1);
1471 | mlhs_head mlhs_item
','
1474 $$
= list_append
($1, $2);
1476 $$ = mlhs_add($1, $2);
1481 mlhs_post
: mlhs_item
1486 $$ = mlhs_add(mlhs_new(), $1);
1489 | mlhs_post
',' mlhs_item
1492 $$
= list_append
($1, $3);
1494 $$ = mlhs_add($1, $3);
1499 mlhs_node
: variable
1502 $$
= assignable
($1, 0);
1507 | primary_value
'[' opt_call_args rbracket
1510 $$
= aryset
($1, $3);
1512 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1515 | primary_value
'.' tIDENTIFIER
1518 $$
= attrset
($1, $3);
1520 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1523 | primary_value tCOLON2 tIDENTIFIER
1526 $$
= attrset
($1, $3);
1528 $$ = dispatch2(const_path_field, $1, $3);
1531 | primary_value
'.' tCONSTANT
1534 $$
= attrset
($1, $3);
1536 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1539 | primary_value tCOLON2 tCONSTANT
1542 if
(in_def || in_single
)
1543 yyerror("dynamic constant assignment");
1544 $$
= NEW_CDECL
(0, 0, NEW_COLON2
($1, $3));
1546 if (in_def || in_single)
1547 yyerror("dynamic constant assignment");
1548 $$ = dispatch2(const_path_field, $1, $3);
1554 if
(in_def || in_single
)
1555 yyerror("dynamic constant assignment");
1556 $$
= NEW_CDECL
(0, 0, NEW_COLON3
($2));
1558 $$ = dispatch1(top_const_field, $2);
1564 rb_backref_error
($1);
1567 $$ = dispatch1(var_field, $1);
1568 $$ = dispatch1(assign_error, $$);
1576 if
(!($$
= assignable
($1, 0))) $$
= NEW_BEGIN
(0);
1578 $$ = dispatch1(var_field, $1);
1581 | primary_value
'[' opt_call_args rbracket
1584 $$
= aryset
($1, $3);
1586 $$ = dispatch2(aref_field, $1, escape_Qundef($3));
1589 | primary_value
'.' tIDENTIFIER
1592 $$
= attrset
($1, $3);
1594 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1597 | primary_value tCOLON2 tIDENTIFIER
1600 $$
= attrset
($1, $3);
1602 $$ = dispatch3(field, $1, ripper_intern("::"), $3);
1605 | primary_value
'.' tCONSTANT
1608 $$
= attrset
($1, $3);
1610 $$ = dispatch3(field, $1, ripper_id2sym('.'), $3);
1613 | primary_value tCOLON2 tCONSTANT
1616 if
(in_def || in_single
)
1617 yyerror("dynamic constant assignment");
1618 $$
= NEW_CDECL
(0, 0, NEW_COLON2
($1, $3));
1620 $$ = dispatch2(const_path_field, $1, $3);
1621 if (in_def || in_single) {
1622 $$ = dispatch1(assign_error, $$);
1629 if
(in_def || in_single
)
1630 yyerror("dynamic constant assignment");
1631 $$
= NEW_CDECL
(0, 0, NEW_COLON3
($2));
1633 $$ = dispatch1(top_const_field, $2);
1634 if (in_def || in_single) {
1635 $$ = dispatch1(assign_error, $$);
1642 rb_backref_error
($1);
1645 $$ = dispatch1(assign_error, $1);
1653 yyerror("class/module name must be CONSTANT");
1655 $$ = dispatch1(class_name_error, $1);
1661 cpath
: tCOLON3 cname
1664 $$
= NEW_COLON3
($2);
1666 $$ = dispatch1(top_const_ref, $2);
1672 $$
= NEW_COLON2
(0, $$
);
1674 $$ = dispatch1(const_ref, $1);
1677 | primary_value tCOLON2 cname
1680 $$
= NEW_COLON2
($1, $3);
1682 $$ = dispatch2(const_path_ref, $1, $3);
1693 lex_state
= EXPR_END
;
1696 lex_state = EXPR_END;
1703 lex_state
= EXPR_END
;
1706 lex_state = EXPR_END;
1719 $$
= NEW_LIT
(ID2SYM
($1));
1721 $$ = dispatch1(symbol_literal, $1);
1732 $$ = rb_ary_new3(1, $1);
1735 | undef_list
',' {lex_state
= EXPR_FNAME
;} fitem
1738 $$
= block_append
($1, NEW_UNDEF
($4));
1740 rb_ary_push($1, $4);
1745 op
: '|' { ifndef_ripper
($$
= '|'); }
1746 |
'^' { ifndef_ripper
($$
= '^'); }
1747 |
'&' { ifndef_ripper
($$
= '&'); }
1748 | tCMP
{ ifndef_ripper
($$
= tCMP
); }
1749 | tEQ
{ ifndef_ripper
($$
= tEQ
); }
1750 | tEQQ
{ ifndef_ripper
($$
= tEQQ
); }
1751 | tMATCH
{ ifndef_ripper
($$
= tMATCH
); }
1752 | tNMATCH
{ ifndef_ripper
($$
= tNMATCH
); }
1753 |
'>' { ifndef_ripper
($$
= '>'); }
1754 | tGEQ
{ ifndef_ripper
($$
= tGEQ
); }
1755 |
'<' { ifndef_ripper
($$
= '<'); }
1756 | tLEQ
{ ifndef_ripper
($$
= tLEQ
); }
1757 | tNEQ
{ ifndef_ripper
($$
= tNEQ
); }
1758 | tLSHFT
{ ifndef_ripper
($$
= tLSHFT
); }
1759 | tRSHFT
{ ifndef_ripper
($$
= tRSHFT
); }
1760 |
'+' { ifndef_ripper
($$
= '+'); }
1761 |
'-' { ifndef_ripper
($$
= '-'); }
1762 |
'*' { ifndef_ripper
($$
= '*'); }
1763 | tSTAR
{ ifndef_ripper
($$
= '*'); }
1764 |
'/' { ifndef_ripper
($$
= '/'); }
1765 |
'%' { ifndef_ripper
($$
= '%'); }
1766 | tPOW
{ ifndef_ripper
($$
= tPOW
); }
1767 |
'!' { ifndef_ripper
($$
= '!'); }
1768 |
'~' { ifndef_ripper
($$
= '~'); }
1769 | tUPLUS
{ ifndef_ripper
($$
= tUPLUS
); }
1770 | tUMINUS
{ ifndef_ripper
($$
= tUMINUS
); }
1771 | tAREF
{ ifndef_ripper
($$
= tAREF
); }
1772 | tASET
{ ifndef_ripper
($$
= tASET
); }
1773 |
'`' { ifndef_ripper
($$
= '`'); }
1776 reswords
: keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
1777 | keyword_BEGIN | keyword_END
1778 | keyword_alias | keyword_and | keyword_begin
1779 | keyword_break | keyword_case | keyword_class | keyword_def
1780 | keyword_defined | keyword_do | keyword_else | keyword_elsif
1781 | keyword_end | keyword_ensure | keyword_false
1782 | keyword_for | keyword_in | keyword_module | keyword_next
1783 | keyword_nil | keyword_not | keyword_or | keyword_redo
1784 | keyword_rescue | keyword_retry | keyword_return | keyword_self
1785 | keyword_super | keyword_then | keyword_true | keyword_undef
1786 | keyword_when | keyword_yield | keyword_if | keyword_unless
1787 | keyword_while | keyword_until
1794 $$
= node_assign
($1, $3);
1796 $$ = dispatch2(assign, $1, $3);
1799 | lhs
'=' arg modifier_rescue arg
1803 $3 = NEW_RESCUE
($3, NEW_RESBODY
(0,$5,0), 0);
1804 $$
= node_assign
($1, $3);
1806 $$ = dispatch2(assign, $1, dispatch2(rescue_mod, $3, $5));
1809 | var_lhs tOP_ASGN arg
1814 ID vid
= $1->nd_vid
;
1817 $$
= NEW_OP_ASGN_OR
(gettable
(vid
), $1);
1818 if
(is_asgn_or_id
(vid
)) {
1822 else if
($2 == tANDOP
) {
1824 $$
= NEW_OP_ASGN_AND
(gettable
(vid
), $1);
1828 $$
->nd_value
= NEW_CALL
(gettable
(vid
), $2, NEW_LIST
($3));
1835 $$ = dispatch3(opassign, $1, $2, $3);
1838 | var_lhs tOP_ASGN arg modifier_rescue arg
1842 $3 = NEW_RESCUE
($3, NEW_RESBODY
(0,$5,0), 0);
1844 ID vid
= $1->nd_vid
;
1847 $$
= NEW_OP_ASGN_OR
(gettable
(vid
), $1);
1848 if
(is_asgn_or_id
(vid
)) {
1852 else if
($2 == tANDOP
) {
1854 $$
= NEW_OP_ASGN_AND
(gettable
(vid
), $1);
1858 $$
->nd_value
= NEW_CALL
(gettable
(vid
), $2, NEW_LIST
($3));
1865 $3 = dispatch2(rescue_mod, $3, $5);
1866 $$ = dispatch3(opassign, $1, $2, $3);
1869 | primary_value
'[' opt_call_args rbracket tOP_ASGN arg
1875 if
(!$3) $3 = NEW_ZARRAY
();
1876 args
= arg_concat
($6, $3);
1880 else if
($5 == tANDOP
) {
1883 $$
= NEW_OP_ASGN1
($1, $5, args
);
1886 $1 = dispatch2(aref_field, $1, escape_Qundef($3));
1887 $$ = dispatch3(opassign, $1, $5, $6);
1890 | primary_value
'.' tIDENTIFIER tOP_ASGN arg
1897 else if
($4 == tANDOP
) {
1900 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1903 $1 = dispatch3(field, $1, ripper_id2sym('.'), $3);
1904 $$ = dispatch3(opassign, $1, $4, $5);
1907 | primary_value
'.' tCONSTANT tOP_ASGN arg
1914 else if
($4 == tANDOP
) {
1917 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1920 $1 = dispatch3(field, $1, ripper_id2sym('.'), $3);
1921 $$ = dispatch3(opassign, $1, $4, $5);
1924 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
1931 else if
($4 == tANDOP
) {
1934 $$
= NEW_OP_ASGN2
($1, $3, $4, $5);
1937 $1 = dispatch3(field, $1, ripper_intern("::"), $3);
1938 $$ = dispatch3(opassign, $1, $4, $5);
1941 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
1944 yyerror("constant re-assignment");
1947 $$ = dispatch2(const_path_field, $1, $3);
1948 $$ = dispatch3(opassign, $$, $4, $5);
1949 $$ = dispatch1(assign_error, $$);
1952 | tCOLON3 tCONSTANT tOP_ASGN arg
1955 yyerror("constant re-assignment");
1958 $$ = dispatch1(top_const_field, $2);
1959 $$ = dispatch3(opassign, $$, $3, $4);
1960 $$ = dispatch1(assign_error, $$);
1963 | backref tOP_ASGN arg
1966 rb_backref_error
($1);
1969 $$ = dispatch1(var_field, $1);
1970 $$ = dispatch3(opassign, $$, $2, $3);
1971 $$ = dispatch1(assign_error, $$);
1979 $$
= NEW_DOT2
($1, $3);
1980 if
(nd_type
($1) == NODE_LIT
&& FIXNUM_P
($1->nd_lit
) &&
1981 nd_type
($3) == NODE_LIT
&& FIXNUM_P
($3->nd_lit
)) {
1982 deferred_nodes
= list_append
(deferred_nodes
, $$
);
1985 $$ = dispatch2(dot2, $1, $3);
1993 $$
= NEW_DOT3
($1, $3);
1994 if
(nd_type
($1) == NODE_LIT
&& FIXNUM_P
($1->nd_lit
) &&
1995 nd_type
($3) == NODE_LIT
&& FIXNUM_P
($3->nd_lit
)) {
1996 deferred_nodes
= list_append
(deferred_nodes
, $$
);
1999 $$ = dispatch2(dot3, $1, $3);
2005 $$
= call_bin_op
($1, '+', $3);
2007 $$ = dispatch3(binary, $1, ID2SYM('+'), $3);
2013 $$
= call_bin_op
($1, '-', $3);
2015 $$ = dispatch3(binary, $1, ID2SYM('-'), $3);
2021 $$
= call_bin_op
($1, '*', $3);
2023 $$ = dispatch3(binary, $1, ID2SYM('*'), $3);
2029 $$
= call_bin_op
($1, '/', $3);
2031 $$ = dispatch3(binary, $1, ID2SYM('/'), $3);
2037 $$
= call_bin_op
($1, '%', $3);
2039 $$ = dispatch3(binary, $1, ID2SYM('%'), $3);
2045 $$
= call_bin_op
($1, tPOW
, $3);
2047 $$ = dispatch3(binary, $1, ripper_intern("**"), $3);
2050 | tUMINUS_NUM tINTEGER tPOW arg
2053 $$
= NEW_CALL
(call_bin_op
($2, tPOW
, $4), tUMINUS
, 0);
2055 $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2056 $$ = dispatch2(unary, ripper_intern("-@"), $$);
2059 | tUMINUS_NUM tFLOAT tPOW arg
2062 $$
= NEW_CALL
(call_bin_op
($2, tPOW
, $4), tUMINUS
, 0);
2064 $$ = dispatch3(binary, $2, ripper_intern("**"), $4);
2065 $$ = dispatch2(unary, ripper_intern("-@"), $$);
2071 $$
= call_uni_op
($2, tUPLUS
);
2073 $$ = dispatch2(unary, ripper_intern("+@"), $2);
2079 $$
= call_uni_op
($2, tUMINUS
);
2081 $$ = dispatch2(unary, ripper_intern("-@"), $2);
2087 $$
= call_bin_op
($1, '|', $3);
2089 $$ = dispatch3(binary, $1, ID2SYM('|'), $3);
2095 $$
= call_bin_op
($1, '^', $3);
2097 $$ = dispatch3(binary, $1, ID2SYM('^'), $3);
2103 $$
= call_bin_op
($1, '&', $3);
2105 $$ = dispatch3(binary, $1, ID2SYM('&'), $3);
2111 $$
= call_bin_op
($1, tCMP
, $3);
2113 $$ = dispatch3(binary, $1, ripper_intern("<=>"), $3);
2119 $$
= call_bin_op
($1, '>', $3);
2121 $$ = dispatch3(binary, $1, ID2SYM('>'), $3);
2127 $$
= call_bin_op
($1, tGEQ
, $3);
2129 $$ = dispatch3(binary, $1, ripper_intern(">="), $3);
2135 $$
= call_bin_op
($1, '<', $3);
2137 $$ = dispatch3(binary, $1, ID2SYM('<'), $3);
2143 $$
= call_bin_op
($1, tLEQ
, $3);
2145 $$ = dispatch3(binary, $1, ripper_intern("<="), $3);
2151 $$
= call_bin_op
($1, tEQ
, $3);
2153 $$ = dispatch3(binary, $1, ripper_intern("=="), $3);
2159 $$
= call_bin_op
($1, tEQQ
, $3);
2161 $$ = dispatch3(binary, $1, ripper_intern("==="), $3);
2167 $$
= call_bin_op
($1, tNEQ
, $3);
2169 $$ = dispatch3(binary, $1, ripper_intern("!="), $3);
2175 $$
= match_op
($1, $3);
2176 if
(nd_type
($1) == NODE_LIT
&& TYPE
($1->nd_lit
) == T_REGEXP
) {
2177 $$
= reg_named_capture_assign
($1->nd_lit
, $$
);
2180 $$ = dispatch3(binary, $1, ripper_intern("=~"), $3);
2186 $$
= call_bin_op
($1, tNMATCH
, $3);
2188 $$ = dispatch3(binary, $1, ripper_intern("!~"), $3);
2194 $$
= call_uni_op
(cond
($2), '!');
2196 $$ = dispatch2(unary, ID2SYM('!'), $2);
2202 $$
= call_uni_op
($2, '~');
2204 $$ = dispatch2(unary, ID2SYM('~'), $2);
2210 $$
= call_bin_op
($1, tLSHFT
, $3);
2212 $$ = dispatch3(binary, $1, ripper_intern("<<"), $3);
2218 $$
= call_bin_op
($1, tRSHFT
, $3);
2220 $$ = dispatch3(binary, $1, ripper_intern(">>"), $3);
2226 $$
= logop
(NODE_AND
, $1, $3);
2228 $$ = dispatch3(binary, $1, ripper_intern("&&"), $3);
2234 $$
= logop
(NODE_OR
, $1, $3);
2236 $$ = dispatch3(binary, $1, ripper_intern("||"), $3);
2239 | keyword_defined opt_nl
{in_defined
= 1;} arg
2243 $$
= NEW_DEFINED
($4);
2246 $$ = dispatch1(defined, $4);
2249 | arg
'?' arg opt_nl
':' arg
2253 $$
= NEW_IF
(cond
($1), $3, $6);
2256 $$ = dispatch3(ifop, $1, $3, $6);
2270 if
(!$$
) $$
= NEW_NIL
();
2282 | args
',' assocs trailer
2285 $$
= arg_append
($1, NEW_HASH
($3));
2287 $$ = arg_add_assocs($1, $3);
2293 $$
= NEW_LIST
(NEW_HASH
($1));
2295 $$ = arg_add_assocs(arg_new(), $1);
2300 paren_args
: '(' opt_call_args rparen
2305 $$ = dispatch1(arg_paren, escape_Qundef($2));
2310 opt_paren_args
: none
2314 opt_call_args
: none
2323 $$ = arg_add(arg_new(), $1);
2326 | args opt_block_arg
2329 $$
= arg_blk_pass
($1, $2);
2331 $$ = arg_add_optblock($1, $2);
2334 | assocs opt_block_arg
2337 $$
= NEW_LIST
(NEW_HASH
($1));
2338 $$
= arg_blk_pass
($$
, $2);
2340 $$ = arg_add_assocs(arg_new(), $1);
2341 $$ = arg_add_optblock($$, $2);
2344 | args
',' assocs opt_block_arg
2347 $$
= arg_append
($1, NEW_HASH
($3));
2348 $$
= arg_blk_pass
($$
, $4);
2350 $$ = arg_add_optblock(arg_add_assocs($1, $3), $4);
2357 $$ = arg_add_block(arg_new(), $1);
2363 $
<num
>$
= cmdarg_stack
;
2369 cmdarg_stack
= $
<num
>1;
2374 block_arg
: tAMPER arg_value
2377 $$
= NEW_BLOCK_PASS
($2);
2384 opt_block_arg
: ',' block_arg
2399 $$ = arg_add(arg_new(), $1);
2407 $$ = arg_add_star(arg_new(), $2);
2410 | args
',' arg_value
2414 if
((n1
= splat_array
($1)) != 0) {
2415 $$
= list_append
(n1
, $3);
2418 $$
= arg_append
($1, $3);
2421 $$ = arg_add($1, $3);
2424 | args
',' tSTAR arg_value
2428 if
(nd_type
($4) == NODE_ARRAY
&&
2429 (n1
= splat_array
($1)) != 0) {
2430 $$
= list_concat
(n1
, $4);
2433 $$
= arg_concat
($1, $4);
2436 $$ = arg_add_star($1, $4);
2441 mrhs
: args
',' arg_value
2445 if
((n1
= splat_array
($1)) != 0) {
2446 $$
= list_append
(n1
, $3);
2449 $$
= arg_append
($1, $3);
2452 $$ = mrhs_add(args2mrhs($1), $3);
2455 | args
',' tSTAR arg_value
2459 if
(nd_type
($4) == NODE_ARRAY
&&
2460 (n1
= splat_array
($1)) != 0) {
2461 $$
= list_concat
(n1
, $4);
2464 $$
= arg_concat
($1, $4);
2467 $$ = mrhs_add_star(args2mrhs($1), $4);
2475 $$ = mrhs_add_star(mrhs_new(), $2);
2491 $$
= NEW_FCALL
($1, 0);
2493 $$ = method_arg(dispatch1(fcall, $1), arg_new());
2499 $
<num
>$
= ruby_sourceline
;
2511 if
(nd_type
($3) == NODE_RESCUE ||
2512 nd_type
($3) == NODE_ENSURE
)
2513 nd_set_line
($3, $
<num
>2);
2516 nd_set_line
($$
, $
<num
>2);
2518 $$ = dispatch1(begin, $3);
2521 | tLPAREN_ARG expr
{lex_state
= EXPR_ENDARG
;} rparen
2523 rb_warning0
("(...) interpreted as grouped expression");
2527 $$ = dispatch1(paren, $2);
2530 | tLPAREN compstmt
')'
2535 $$ = dispatch1(paren, $2);
2538 | primary_value tCOLON2 tCONSTANT
2541 $$
= NEW_COLON2
($1, $3);
2543 $$ = dispatch2(const_path_ref, $1, $3);
2549 $$
= NEW_COLON3
($2);
2551 $$ = dispatch1(top_const_ref, $2);
2554 | tLBRACK aref_args
']'
2558 $$
= NEW_ZARRAY
(); /* zero length array*/
2564 $$ = dispatch1(array, escape_Qundef($2));
2567 | tLBRACE assoc_list
'}'
2572 $$ = dispatch1(hash, escape_Qundef($2));
2580 $$ = dispatch0(return0);
2583 | keyword_yield
'(' call_args rparen
2588 $$ = dispatch1(yield, dispatch1(paren, $3));
2591 | keyword_yield
'(' rparen
2594 $$
= NEW_YIELD
(0, Qfalse
);
2596 $$ = dispatch1(yield, dispatch1(paren, arg_new()));
2602 $$
= NEW_YIELD
(0, Qfalse
);
2604 $$ = dispatch0(yield0);
2607 | keyword_defined opt_nl
'(' {in_defined
= 1;} expr rparen
2611 $$
= NEW_DEFINED
($5);
2614 $$ = dispatch1(defined, $5);
2617 | keyword_not
'(' expr rparen
2620 $$
= call_uni_op
(cond
($3), '!');
2622 $$ = dispatch2(unary, ripper_intern("not"), $3);
2625 | keyword_not
'(' rparen
2628 $$
= call_uni_op
(cond
(NEW_NIL
()), '!');
2630 $$ = dispatch2(unary, ripper_intern("not"), Qnil);
2633 | operation brace_block
2636 $2->nd_iter
= NEW_FCALL
($1, 0);
2638 fixpos
($2->nd_iter
, $2);
2640 $$ = method_arg(dispatch1(fcall, $1), arg_new());
2641 $$ = method_add_block($$, $2);
2645 | method_call brace_block
2648 block_dup_check
($1->nd_args
, $2);
2653 $$ = method_add_block($1, $2);
2660 | keyword_if expr_value then
2666 $$
= NEW_IF
(cond
($2), $4, $5);
2669 $$ = dispatch3(if, $2, $4, escape_Qundef($5));
2672 | keyword_unless expr_value then
2678 $$
= NEW_UNLESS
(cond
($2), $4, $5);
2681 $$ = dispatch3(unless, $2, $4, escape_Qundef($5));
2684 | keyword_while
{COND_PUSH
(1);} expr_value do
{COND_POP
();}
2689 $$
= NEW_WHILE
(cond
($3), $6, 1);
2692 $$ = dispatch2(while, $3, $6);
2695 | keyword_until
{COND_PUSH
(1);} expr_value do
{COND_POP
();}
2700 $$
= NEW_UNTIL
(cond
($3), $6, 1);
2703 $$ = dispatch2(until, $3, $6);
2706 | keyword_case expr_value opt_terms
2711 $$
= NEW_CASE
($2, $4);
2714 $$ = dispatch2(case, $2, $4);
2717 | keyword_case opt_terms case_body keyword_end
2720 $$
= NEW_CASE
(0, $3);
2722 $$ = dispatch2(case, Qnil, $3);
2725 | keyword_for for_var keyword_in
2736 * e.each{|*x| a, b, c = x
2740 * e.each{|x| a, = x}
2742 ID id
= internal_id
();
2743 ID
*tbl
= ALLOC_N
(ID
, 2);
2744 NODE
*m
= NEW_ARGS_AUX
(0, 0);
2747 if
(nd_type
($2) == NODE_MASGN
) {
2748 /* if args.length == 1 && args[0].kind_of?(Array)
2752 NODE
*one
= NEW_LIST
(NEW_LIT
(INT2FIX
(1)));
2753 NODE
*zero
= NEW_LIST
(NEW_LIT
(INT2FIX
(0)));
2754 m
->nd_next
= block_append
(
2757 NEW_CALL
(NEW_CALL
(NEW_DVAR
(id
), rb_intern
("length"), 0),
2758 rb_intern
("=="), one
),
2759 NEW_CALL
(NEW_CALL
(NEW_DVAR
(id
), rb_intern
("[]"), zero
),
2760 rb_intern
("kind_of?"), NEW_LIST
(NEW_LIT
(rb_cArray
))),
2763 NEW_CALL
(NEW_DVAR
(id
), rb_intern
("[]"), zero
)),
2765 node_assign
($2, NEW_DVAR
(id
)));
2768 m
->nd_next
= node_assign
(NEW_MASGN
(NEW_LIST
($2), 0), NEW_DVAR
(id
));
2771 args
= new_args
(m
, 0, id
, 0, 0);
2772 scope
= NEW_NODE
(NODE_SCOPE
, tbl
, $8, args
);
2773 tbl
[0] = 1; tbl
[1] = id
;
2774 $$
= NEW_FOR
(0, $5, scope
);
2777 $$ = dispatch3(for, $2, $5, $8);
2780 | keyword_class cpath superclass
2782 if
(in_def || in_single
)
2783 yyerror("class definition in method body");
2786 $
<num
>$
= ruby_sourceline
;
2794 $$
= NEW_CLASS
($2, $5, $3);
2795 nd_set_line
($$
, $
<num
>4);
2798 $$ = dispatch3(class, $2, $3, $5);
2801 | keyword_class tLSHFT expr
2813 $
<num
>$
= in_single
;
2825 $$
= NEW_SCLASS
($3, $7);
2829 in_single
= $
<num
>6;
2831 $$ = dispatch2(sclass, $3, $7);
2833 in_single = $<val>6;
2836 | keyword_module cpath
2838 if
(in_def || in_single
)
2839 yyerror("module definition in method body");
2842 $
<num
>$
= ruby_sourceline
;
2850 $$
= NEW_MODULE
($2, $4);
2851 nd_set_line
($$
, $
<num
>3);
2854 $$ = dispatch2(module, $2, $4);
2872 NODE
*body
= remove_begin
($5);
2873 reduce_nodes
(&body
);
2874 $$
= NEW_DEFN
($2, $4, body
, NOEX_PRIVATE
);
2880 $$ = dispatch3(def, $2, $4, $5);
2885 | keyword_def singleton dot_or_colon
{lex_state
= EXPR_FNAME
;} fname
2888 lex_state
= EXPR_END
; /* force for args */
2899 NODE
*body
= remove_begin
($8);
2900 reduce_nodes
(&body
);
2901 $$
= NEW_DEFS
($2, $5, $7, body
);
2906 $$ = dispatch5(defs, $2, $3, $5, $7, $8);
2915 $$ = dispatch1(break, arg_new());
2923 $$ = dispatch1(next, arg_new());
2931 $$ = dispatch0(redo);
2939 $$ = dispatch0(retry);
2944 primary_value
: primary
2949 if
(!$$
) $$
= NEW_NIL
();
2978 | keyword_elsif expr_value then
2983 $$
= NEW_IF
(cond
($2), $4, $5);
2986 $$ = dispatch3(elsif, $2, $4, escape_Qundef($5));
2992 | keyword_else compstmt
2997 $$ = dispatch1(else, $2);
3009 $$
= assignable
($1, 0);
3011 $$ = dispatch1(mlhs_paren, $1);
3014 | tLPAREN f_margs rparen
3019 $$ = dispatch1(mlhs_paren, $2);
3024 f_marg_list
: f_marg
3029 $$ = mlhs_add(mlhs_new(), $1);
3032 | f_marg_list
',' f_marg
3035 $$
= list_append
($1, $3);
3037 $$ = mlhs_add($1, $3);
3042 f_margs
: f_marg_list
3045 $$
= NEW_MASGN
($1, 0);
3050 | f_marg_list
',' tSTAR f_norm_arg
3053 $$
= NEW_MASGN
($1, assignable
($4, 0));
3055 $$ = mlhs_add_star($1, $4);
3058 | f_marg_list
',' tSTAR f_norm_arg
',' f_marg_list
3061 $$
= NEW_MASGN
($1, NEW_POSTARG
(assignable
($4, 0), $6));
3063 $$ = mlhs_add_star($1, $4);
3066 | f_marg_list
',' tSTAR
3069 $$
= NEW_MASGN
($1, -1);
3071 $$ = mlhs_add_star($1, Qnil);
3074 | f_marg_list
',' tSTAR
',' f_marg_list
3077 $$
= NEW_MASGN
($1, NEW_POSTARG
(-1, $5));
3079 $$ = mlhs_add_star($1, $5);
3085 $$
= NEW_MASGN
(0, assignable
($2, 0));
3087 $$ = mlhs_add_star(mlhs_new(), $2);
3090 | tSTAR f_norm_arg
',' f_marg_list
3093 $$
= NEW_MASGN
(0, NEW_POSTARG
(assignable
($2, 0), $4));
3098 $$ = mlhs_add_star($2, $4);
3104 $$
= NEW_MASGN
(0, -1);
3106 $$ = mlhs_add_star(mlhs_new(), Qnil);
3109 | tSTAR
',' f_marg_list
3112 $$
= NEW_MASGN
(0, NEW_POSTARG
(-1, $3));
3114 $$ = mlhs_add_star(mlhs_new(), Qnil);
3119 block_param
: f_arg
',' f_rest_arg opt_f_block_arg
3122 $$
= new_args
($1, 0, $3, 0, $4);
3124 $$ = params_new($1, Qnil, $3, Qnil, escape_Qundef($4));
3130 $$
= new_args
($1, 0, 1, 0, 0);
3132 $$ = params_new($1, Qnil, Qnil, Qnil, Qnil);
3133 dispatch1(excessed_comma, $$);
3136 | f_arg
',' f_rest_arg
',' f_arg opt_f_block_arg
3139 $$
= new_args
($1, 0, $3, $5, $6);
3141 $$ = params_new($1, Qnil, $3, $5, escape_Qundef($6));
3144 | f_arg opt_f_block_arg
3147 $$
= new_args
($1, 0, 0, 0, $2);
3149 $$ = params_new($1, Qnil,Qnil, Qnil, escape_Qundef($2));
3152 | f_rest_arg opt_f_block_arg
3155 $$
= new_args
(0, 0, $1, 0, $2);
3157 $$ = params_new(Qnil, Qnil, $1, Qnil, escape_Qundef($2));
3160 | f_rest_arg
',' f_arg opt_f_block_arg
3163 $$
= new_args
(0, 0, $1, $3, $4);
3165 $$ = params_new(Qnil, Qnil, $1, $3, escape_Qundef($4));
3171 $$
= new_args
(0, 0, 0, 0, $1);
3173 $$ = params_new(Qnil, Qnil, Qnil, Qnil, $1);
3178 opt_block_param
: none
3181 command_start
= Qtrue
;
3185 block_param_def
: '|' opt_bv_decl
'|'
3190 $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil),
3199 $$ = blockvar_new(params_new(Qnil,Qnil,Qnil,Qnil,Qnil),
3203 |
'|' block_param opt_bv_decl
'|'
3208 $$ = blockvar_new(escape_Qundef($2), escape_Qundef($3));
3229 $$ = rb_ary_new2($1);
3236 rb_ary_push($$, $3);
3259 lpar_beg
= ++paren_nest
;
3268 $$
->nd_body
= NEW_SCOPE
($2->nd_head
, $3);
3272 $$ = dispatch2(lambda, $2, $3);
3277 f_larglist
: '(' f_args opt_bv_decl rparen
3280 $$
= NEW_LAMBDA
($2);
3282 $$ = dispatch1(paren, $2);
3285 | f_args opt_bv_decl
3288 $$
= NEW_LAMBDA
($1);
3295 lambda_body
: tLAMBEG compstmt
'}'
3299 | keyword_do_LAMBDA compstmt keyword_end
3305 do_block
: keyword_do_block
3309 $
<num
>$
= ruby_sourceline
;
3317 $$
= NEW_ITER
($3,$4);
3318 nd_set_line
($$
, $
<num
>2);
3321 $$ = dispatch2(do_block, escape_Qundef($3), $4);
3326 block_call
: command do_block
3329 block_dup_check
($1->nd_args
, $2);
3334 $$ = method_add_block($1, $2);
3337 | block_call
'.' operation2 opt_paren_args
3340 $$
= NEW_CALL
($1, $3, $4);
3342 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3343 $$ = method_optarg($$, $4);
3346 | block_call tCOLON2 operation2 opt_paren_args
3349 $$
= NEW_CALL
($1, $3, $4);
3351 $$ = dispatch3(call, $1, ripper_intern("::"), $3);
3352 $$ = method_optarg($$, $4);
3357 method_call
: operation paren_args
3360 $$
= NEW_FCALL
($1, $2);
3363 $$ = method_arg(dispatch1(fcall, $1), $2);
3366 | primary_value
'.' operation2 opt_paren_args
3369 $$
= NEW_CALL
($1, $3, $4);
3372 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3373 $$ = method_optarg($$, $4);
3376 | primary_value tCOLON2 operation2 paren_args
3379 $$
= NEW_CALL
($1, $3, $4);
3382 $$ = dispatch3(call, $1, ripper_id2sym('.'), $3);
3383 $$ = method_optarg($$, $4);
3386 | primary_value tCOLON2 operation3
3389 $$
= NEW_CALL
($1, $3, 0);
3391 $$ = dispatch3(call, $1, ripper_intern("::"), $3);
3394 | primary_value
'.' paren_args
3397 $$
= NEW_CALL
($1, rb_intern
("call"), $3);
3400 $$ = dispatch3(call, dispatch1(paren, $1),
3401 ripper_id2sym('.'), rb_intern("call"));
3402 $$ = method_optarg($$, $3);
3405 | primary_value tCOLON2 paren_args
3408 $$
= NEW_CALL
($1, rb_intern
("call"), $3);
3411 $$ = dispatch3(call, dispatch1(paren, $1),
3412 ripper_id2sym('.'), rb_intern("call"));
3413 $$ = method_optarg($$, $3);
3416 | keyword_super paren_args
3421 $$ = dispatch1(super, $2);
3429 $$ = dispatch0(zsuper);
3432 | primary_value
'[' opt_call_args rbracket
3435 if
($1 && nd_type
($1) == NODE_SELF
)
3436 $$
= NEW_FCALL
(tAREF
, $3);
3438 $$
= NEW_CALL
($1, tAREF
, $3);
3441 $$ = dispatch2(aref, $1, escape_Qundef($3));
3450 $
<num
>$
= ruby_sourceline
;
3458 $$
= NEW_ITER
($3,$4);
3459 nd_set_line
($$
, $
<num
>2);
3462 $$ = dispatch2(brace_block, escape_Qundef($3), $4);
3469 $
<num
>$
= ruby_sourceline
;
3474 compstmt keyword_end
3477 $$
= NEW_ITER
($3,$4);
3478 nd_set_line
($$
, $
<num
>2);
3481 $$ = dispatch2(do_block, escape_Qundef($3), $4);
3486 case_body
: keyword_when args then
3491 $$
= NEW_WHEN
($2, $4, $5);
3493 $$ = dispatch3(when, $2, $4, escape_Qundef($5));
3502 opt_rescue
: keyword_rescue exc_list exc_var then
3508 $3 = node_assign
($3, NEW_ERRINFO
());
3509 $5 = block_append
($3, $5);
3511 $$
= NEW_RESBODY
($2, $5, $6);
3512 fixpos
($$
, $2?
$2:$5);
3514 $$ = dispatch4(rescue,
3524 exc_list
: arg_value
3529 $$ = rb_ary_new3(1, $1);
3535 if
(!($$
= splat_array
($1))) $$
= $1;
3543 exc_var
: tASSOC lhs
3550 opt_ensure
: keyword_ensure compstmt
3555 $$ = dispatch1(ensure, $2);
3565 $$
= NEW_LIT
(ID2SYM
($1));
3567 $$ = dispatch1(symbol_literal, $1);
3578 node
= NEW_STR
(STR_NEW0
());
3581 node
= evstr2dstr
(node
);
3595 $$
= literal_concat
($1, $2);
3597 $$ = dispatch2(string_concat, $1, $2);
3602 string1
: tSTRING_BEG string_contents tSTRING_END
3607 $$ = dispatch1(string_literal, $2);
3612 xstring
: tXSTRING_BEG xstring_contents tSTRING_END
3617 node
= NEW_XSTR
(STR_NEW0
());
3620 switch
(nd_type
(node
)) {
3622 nd_set_type
(node
, NODE_XSTR
);
3625 nd_set_type
(node
, NODE_DXSTR
);
3628 node
= NEW_NODE
(NODE_DXSTR
, STR_NEW0
(), 1, NEW_LIST
(node
));
3634 $$ = dispatch1(xstring_literal, $2);
3639 regexp
: tREGEXP_BEG xstring_contents tREGEXP_END
3646 node
= NEW_LIT
(reg_compile
(STR_NEW0
(), options
));
3648 else switch
(nd_type
(node
)) {
3651 VALUE src
= node
->nd_lit
;
3652 nd_set_type
(node
, NODE_LIT
);
3653 node
->nd_lit
= reg_compile
(src
, options
);
3657 node
= NEW_NODE
(NODE_DSTR
, STR_NEW0
(), 1, NEW_LIST
(node
));
3659 if
(options
& RE_OPTION_ONCE
) {
3660 nd_set_type
(node
, NODE_DREGX_ONCE
);
3663 nd_set_type
(node
, NODE_DREGX
);
3665 node
->nd_cflag
= options
& RE_OPTION_MASK
;
3666 reg_fragment_check
(node
->nd_lit
, options
);
3667 for
(list
= node
->nd_next
; list
; list
= list
->nd_next
) {
3668 if
(nd_type
(list
->nd_head
) == NODE_STR
) {
3669 reg_fragment_check
(list
->nd_head
->nd_lit
, options
);
3676 $$ = dispatch2(regexp_literal, $2, $3);
3681 words
: tWORDS_BEG
' ' tSTRING_END
3686 $$ = dispatch0(words_new);
3689 | tWORDS_BEG word_list tSTRING_END
3695 word_list
: /* none */
3700 $$ = dispatch0(words_new);
3703 | word_list word
' '
3706 $$
= list_append
($1, evstr2dstr
($2));
3708 $$ = dispatch2(words_add, $1, $2);
3713 word
: string_content
3717 $$ = dispatch0(word_new);
3718 $$ = dispatch2(word_add, $$, $1);
3721 | word string_content
3724 $$
= literal_concat
($1, $2);
3726 $$ = dispatch2(word_add, $1, $2);
3731 qwords
: tQWORDS_BEG
' ' tSTRING_END
3736 $$ = dispatch0(qwords_new);
3739 | tQWORDS_BEG qword_list tSTRING_END
3745 qword_list
: /* none */
3750 $$ = dispatch0(qwords_new);
3753 | qword_list tSTRING_CONTENT
' '
3756 $$
= list_append
($1, $2);
3758 $$ = dispatch2(qwords_add, $1, $2);
3763 string_contents
: /* none */
3768 $$ = dispatch0(string_content);
3771 | string_contents string_content
3774 $$
= literal_concat
($1, $2);
3776 $$ = dispatch2(string_add, $1, $2);
3781 xstring_contents: /* none */
3786 $$ = dispatch0(xstring_new);
3789 | xstring_contents string_content
3792 $$
= literal_concat
($1, $2);
3794 $$ = dispatch2(xstring_add, $1, $2);
3799 string_content
: tSTRING_CONTENT
3802 $
<node
>$
= lex_strterm
;
3804 lex_state
= EXPR_BEG
;
3809 lex_strterm
= $
<node
>2;
3812 lex_strterm = $<node>2;
3813 $$ = dispatch1(string_dvar, $3);
3818 $
<node
>$
= lex_strterm
;
3820 lex_state
= EXPR_BEG
;
3826 lex_strterm
= $
<node
>2;
3830 if
($3) $3->flags
&= ~NODE_FL_NEWLINE
;
3833 $$ = dispatch1(string_embexpr, $3);
3843 $$ = dispatch1(var_ref, $1);
3851 $$ = dispatch1(var_ref, $1);
3859 $$ = dispatch1(var_ref, $1);
3865 symbol
: tSYMBEG sym
3868 lex_state
= EXPR_ENDARG
;
3871 lex_state = EXPR_ENDARG;
3872 $$ = dispatch1(symbol, $2);
3883 dsym
: tSYMBEG xstring_contents tSTRING_END
3886 lex_state
= EXPR_ENDARG
;
3888 $$
= NEW_LIT
(ID2SYM
(rb_intern
("")));
3893 switch
(nd_type
($$
)) {
3895 nd_set_type
($$
, NODE_DSYM
);
3899 $$
->nd_lit
= ID2SYM
(rb_intern_str
(lit
));
3900 nd_set_type
($$
, NODE_LIT
);
3903 $$
= NEW_NODE
(NODE_DSYM
, STR_NEW0
(), 1, NEW_LIST
($$
));
3908 lex_state = EXPR_ENDARG;
3909 $$ = dispatch1(dyna_symbol, $2);
3916 | tUMINUS_NUM tINTEGER %prec tLOWEST
3919 $$
= negate_lit
($2);
3921 $$ = dispatch2(unary, ripper_intern("-@"), $2);
3924 | tUMINUS_NUM tFLOAT %prec tLOWEST
3927 $$
= negate_lit
($2);
3929 $$ = dispatch2(unary, ripper_intern("-@"), $2);
3934 variable
: tIDENTIFIER
3939 | keyword_nil
{ifndef_ripper
($$
= keyword_nil
);}
3940 | keyword_self
{ifndef_ripper
($$
= keyword_self
);}
3941 | keyword_true
{ifndef_ripper
($$
= keyword_true
);}
3942 | keyword_false
{ifndef_ripper
($$
= keyword_false
);}
3943 | keyword__FILE__
{ifndef_ripper
($$
= keyword__FILE__
);}
3944 | keyword__LINE__
{ifndef_ripper
($$
= keyword__LINE__
);}
3945 | keyword__ENCODING__
{ifndef_ripper
($$
= keyword__ENCODING__
);}
3951 if
(!($$
= gettable
($1))) $$
= NEW_BEGIN
(0);
3953 $$ = dispatch1(var_ref, $1);
3961 $$
= assignable
($1, 0);
3963 $$ = dispatch1(var_field, $1);
3982 lex_state
= EXPR_BEG
;
4000 f_arglist
: '(' f_args rparen
4004 lex_state
= EXPR_BEG
;
4005 command_start
= Qtrue
;
4007 $$ = dispatch1(paren, $2);
4008 lex_state = EXPR_BEG;
4009 command_start = Qtrue;
4018 f_args
: f_arg
',' f_optarg
',' f_rest_arg opt_f_block_arg
4021 $$
= new_args
($1, $3, $5, 0, $6);
4023 $$ = params_new($1, $3, $5, Qnil, escape_Qundef($6));
4026 | f_arg
',' f_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
4029 $$
= new_args
($1, $3, $5, $7, $8);
4031 $$ = params_new($1, $3, $5, $7, escape_Qundef($8));
4034 | f_arg
',' f_optarg opt_f_block_arg
4037 $$
= new_args
($1, $3, 0, 0, $4);
4039 $$ = params_new($1, $3, Qnil, Qnil, escape_Qundef($4));
4042 | f_arg
',' f_optarg
',' f_arg opt_f_block_arg
4045 $$
= new_args
($1, $3, 0, $5, $6);
4047 $$ = params_new($1, $3, Qnil, $5, escape_Qundef($6));
4050 | f_arg
',' f_rest_arg opt_f_block_arg
4053 $$
= new_args
($1, 0, $3, 0, $4);
4055 $$ = params_new($1, Qnil, $3, Qnil, escape_Qundef($4));
4058 | f_arg
',' f_rest_arg
',' f_arg opt_f_block_arg
4061 $$
= new_args
($1, 0, $3, $5, $6);
4063 $$ = params_new($1, Qnil, $3, $5, escape_Qundef($6));
4066 | f_arg opt_f_block_arg
4069 $$
= new_args
($1, 0, 0, 0, $2);
4071 $$ = params_new($1, Qnil, Qnil, Qnil,escape_Qundef($2));
4074 | f_optarg
',' f_rest_arg opt_f_block_arg
4077 $$
= new_args
(0, $1, $3, 0, $4);
4079 $$ = params_new(Qnil, $1, $3, Qnil, escape_Qundef($4));
4082 | f_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
4085 $$
= new_args
(0, $1, $3, $5, $6);
4087 $$ = params_new(Qnil, $1, $3, $5, escape_Qundef($6));
4090 | f_optarg opt_f_block_arg
4093 $$
= new_args
(0, $1, 0, 0, $2);
4095 $$ = params_new(Qnil, $1, Qnil, Qnil,escape_Qundef($2));
4098 | f_optarg
',' f_arg opt_f_block_arg
4101 $$
= new_args
(0, $1, 0, $3, $4);
4103 $$ = params_new(Qnil, $1, Qnil, $3, escape_Qundef($4));
4106 | f_rest_arg opt_f_block_arg
4109 $$
= new_args
(0, 0, $1, 0, $2);
4111 $$ = params_new(Qnil, Qnil, $1, Qnil,escape_Qundef($2));
4114 | f_rest_arg
',' f_arg opt_f_block_arg
4117 $$
= new_args
(0, 0, $1, $3, $4);
4119 $$ = params_new(Qnil, Qnil, $1, $3, escape_Qundef($4));
4125 $$
= new_args
(0, 0, 0, 0, $1);
4127 $$ = params_new(Qnil, Qnil, Qnil, Qnil, $1);
4133 $$
= new_args
(0, 0, 0, 0, 0);
4135 $$ = params_new(Qnil, Qnil, Qnil, Qnil, Qnil);
4140 f_bad_arg
: tCONSTANT
4143 yyerror("formal argument cannot be a constant");
4146 $$ = dispatch1(param_error, $1);
4152 yyerror("formal argument cannot be an instance variable");
4155 $$ = dispatch1(param_error, $1);
4161 yyerror("formal argument cannot be a global variable");
4164 $$ = dispatch1(param_error, $1);
4170 yyerror("formal argument cannot be a class variable");
4173 $$ = dispatch1(param_error, $1);
4178 f_norm_arg
: f_bad_arg
4182 if
(!is_local_id
($1))
4183 yyerror("formal argument must be local variable");
4191 f_arg_item
: f_norm_arg
4195 $$
= NEW_ARGS_AUX
($1, 1);
4199 | tLPAREN f_margs rparen
4202 ID tid
= internal_id
();
4204 if
(dyna_in_block
()) {
4205 $2->nd_value
= NEW_DVAR
(tid
);
4208 $2->nd_value
= NEW_LVAR
(tid
);
4210 $$
= NEW_ARGS_AUX
(tid
, 1);
4213 $$ = dispatch1(mlhs_paren, $2);
4222 $$ = rb_ary_new3(1, $1);
4225 | f_arg
',' f_arg_item
4230 $$
->nd_next
= block_append
($$
->nd_next
, $3->nd_next
);
4231 rb_gc_force_recycle
((VALUE
)$3);
4233 $$ = rb_ary_push($1, $3);
4238 f_opt
: tIDENTIFIER
'=' arg_value
4241 if
(!is_local_id
($1))
4242 yyerror("formal argument must be local variable");
4245 $$
= NEW_OPT_ARG
(0, assignable
($1, $3));
4247 $$ = rb_assoc_new($1, $3);
4257 $$ = rb_ary_new3(1, $1);
4260 | f_optarg
',' f_opt
4265 while
(opts
->nd_next
) {
4266 opts
= opts
->nd_next
;
4271 $$ = rb_ary_push($1, $3);
4280 f_rest_arg
: restarg_mark tIDENTIFIER
4283 if
(!is_local_id
($2))
4284 yyerror("rest argument must be local variable");
4289 $$ = dispatch1(rest_param, $2);
4298 $$ = dispatch1(rest_param, Qnil);
4307 f_block_arg
: blkarg_mark tIDENTIFIER
4310 if
(!is_local_id
($2))
4311 yyerror("block argument must be local variable");
4312 else if
(!dyna_in_block
() && local_id
($2))
4313 yyerror("duplicated block argument name");
4318 $$ = dispatch1(blockarg, $2);
4323 opt_f_block_arg
: ',' f_block_arg
4342 if
(!$$
) $$
= NEW_NIL
();
4347 |
'(' {lex_state
= EXPR_BEG
;} expr rparen
4351 yyerror("can't define singleton method for ().");
4354 switch
(nd_type
($3)) {
4363 yyerror("can't define singleton method for literals");
4371 $$ = dispatch1(paren, $3);
4382 $$ = dispatch1(assoclist_from_args, $1);
4391 $$ = rb_ary_new3(1, $1);
4397 $$
= list_concat
($1, $3);
4399 $$ = rb_ary_push($1, $3);
4404 assoc
: arg_value tASSOC arg_value
4407 $$
= list_append
(NEW_LIST
($1), $3);
4409 $$ = dispatch2(assoc_new, $1, $3);
4415 $$
= list_append
(NEW_LIST
(NEW_LIT
(ID2SYM
($1))), $2);
4417 $$ = dispatch2(assoc_new, $1, $2);
4422 operation
: tIDENTIFIER
4427 operation2
: tIDENTIFIER
4433 operation3
: tIDENTIFIER
4450 opt_terms
: /* none */
4461 rbracket
: opt_nl
']'
4464 trailer
: /* none */
4469 term
: ';' {yyerrok;}
4474 | terms
';' {yyerrok;}
4490 # define yylval (*((YYSTYPE*)(parser->parser_yylval)))
4492 static int parser_regx_options
(struct parser_params
*);
4493 static int parser_tokadd_string
(struct parser_params
*,int,int,int,long*,rb_encoding
**);
4494 static void parser_tokaddmbc
(struct parser_params
*parser
, int c
, rb_encoding
*enc
);
4495 static int parser_parse_string
(struct parser_params
*,NODE
*);
4496 static int parser_here_document
(struct parser_params
*,NODE
*);
4499 # define nextc() parser_nextc(parser)
4500 # define pushback(c) parser_pushback(parser, c)
4501 # define newtok() parser_newtok(parser)
4502 # define tokspace(n) parser_tokspace(parser, n)
4503 # define tokadd(c) parser_tokadd(parser, c)
4504 # define tok_hex(numlen) parser_tok_hex(parser, numlen)
4505 # define read_escape(flags,e) parser_read_escape(parser, flags, e)
4506 # define tokadd_escape(e) parser_tokadd_escape(parser, e)
4507 # define regx_options() parser_regx_options(parser)
4508 # define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser,f,t,p,n,e)
4509 # define parse_string(n) parser_parse_string(parser,n)
4510 # define tokaddmbc(c, enc) parser_tokaddmbc(parser, c, enc)
4511 # define here_document(n) parser_here_document(parser,n)
4512 # define heredoc_identifier() parser_heredoc_identifier(parser)
4513 # define heredoc_restore(n) parser_heredoc_restore(parser,n)
4514 # define whole_match_p(e,l,i) parser_whole_match_p(parser,e,l,i)
4518 # define local_id(x) 1
4519 # define dyna_in_block() 1
4523 # define set_yylval_str(x) yylval.node = NEW_STR(x)
4524 # define set_yylval_num(x) yylval.num = x
4525 # define set_yylval_id(x) yylval.id = x
4526 # define set_yylval_literal(x) yylval.node = NEW_LIT(x)
4527 # define set_yylval_node(x) yylval.node = x
4528 # define yylval_id() yylval.id
4530 # define set_yylval_str(x) (void)(x)
4531 # define set_yylval_num(x) (void)(x)
4532 # define set_yylval_id(x) (void)(x)
4533 # define set_yylval_literal(x) (void)(x)
4534 # define set_yylval_node(x) (void)(x)
4535 # define yylval_id() SYM2ID(yylval.val)
4539 #define ripper_flush(p) (p->tokp = p->parser_lex_p)
4542 ripper_dispatch_scan_event
(struct parser_params
*parser
, int t
)
4546 if
(lex_p
< parser
->tokp
) rb_raise
(rb_eRuntimeError
, "lex_p < tokp");
4547 if
(lex_p
== parser
->tokp
) return
;
4548 str
= STR_NEW
(parser
->tokp
, lex_p
- parser
->tokp
);
4549 yylval.val
= ripper_dispatch1
(parser
, ripper_token2eventid
(t
), str
);
4550 ripper_flush
(parser
);
4554 ripper_dispatch_delayed_token
(struct parser_params
*parser
, int t
)
4556 int saved_line
= ruby_sourceline
;
4557 const char *saved_tokp
= parser
->tokp
;
4559 ruby_sourceline
= parser
->delayed_line
;
4560 parser
->tokp
= lex_pbeg
+ parser
->delayed_col
;
4561 yylval.val
= ripper_dispatch1
(parser
, ripper_token2eventid
(t
), parser
->delayed
);
4562 parser
->delayed
= Qnil
;
4563 ruby_sourceline
= saved_line
;
4564 parser
->tokp
= saved_tokp
;
4568 #include "ruby/regex.h"
4569 #include "ruby/util.h"
4571 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
4572 since ours (we hope) works properly with all combinations of
4573 machines, compilers, `char' and `unsigned char' argument types.
4574 (Per Bothner suggested the basic approach.) */
4575 #undef SIGN_EXTEND_CHAR
4577 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
4578 #else /* not __STDC__ */
4579 /* As in Harbison and Steele. */
4580 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
4583 #define parser_mbclen() mbclen((lex_p-1),lex_pend,parser->enc)
4584 #define parser_precise_mbclen() rb_enc_precise_mbclen((lex_p-1),lex_pend,parser->enc)
4585 #define is_identchar(p,e,enc) (rb_enc_isalnum(*p,enc) || (*p) == '_' || !ISASCII(*p))
4586 #define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,parser->enc))
4588 #define parser_isascii() ISASCII(*(lex_p-1))
4591 parser_yyerror
(struct parser_params
*parser
, const char *msg
)
4594 const int max_line_margin
= 30;
4599 compile_error
(PARSER_ARG
"%s", msg
);
4601 while
(lex_pbeg
<= p
) {
4602 if
(*p
== '\n') break
;
4608 while
(pe
< lex_pend
) {
4609 if
(*pe
== '\n') break
;
4616 const char *pre
= "", *post
= "";
4618 if
(len
> max_line_margin
* 2 + 10) {
4619 if
(lex_p
- p
> max_line_margin
) {
4620 p
= rb_enc_prev_char
(p
, lex_p
- max_line_margin
, rb_enc_get
(lex_lastline
));
4623 if
(pe
- lex_p
> max_line_margin
) {
4624 pe
= rb_enc_prev_char
(lex_p
, lex_p
+ max_line_margin
, rb_enc_get
(lex_lastline
));
4629 buf
= ALLOCA_N
(char, len
+2);
4630 MEMCPY
(buf
, p
, char, len
);
4632 rb_compile_error_append
("%s%s%s", pre
, buf
, post
);
4635 p2
= buf
; pe
= buf
+ len
;
4638 if
(*p2
!= '\t') *p2
= ' ';
4643 rb_compile_error_append
("%s%s", pre
, buf
);
4646 dispatch1
(parse_error
, STR_NEW2
(msg
));
4647 #endif /* !RIPPER */
4651 static void parser_prepare
(struct parser_params
*parser
);
4654 VALUE ruby_suppress_tracing
(VALUE
(*func
)(VALUE
, int), VALUE arg
, int always
);
4657 debug_lines
(const char *f
)
4659 if
(rb_const_defined_at
(rb_cObject
, rb_intern
("SCRIPT_LINES__"))) {
4660 VALUE hash
= rb_const_get_at
(rb_cObject
, rb_intern
("SCRIPT_LINES__"));
4661 if
(TYPE
(hash
) == T_HASH
) {
4662 VALUE fname
= rb_str_new2
(f
);
4663 VALUE lines
= rb_ary_new
();
4664 rb_hash_aset
(hash
, fname
, lines
);
4672 coverage
(const char *f
, int n
)
4674 extern VALUE rb_get_coverages
(void);
4675 VALUE coverages
= rb_get_coverages
();
4676 if
(RTEST
(coverages
) && RBASIC
(coverages
)->klass
== 0) {
4677 VALUE fname
= rb_str_new2
(f
);
4678 VALUE lines
= rb_ary_new2
(n
);
4680 RBASIC
(lines
)->klass
= 0;
4681 for
(i
= 0; i
< n
; i
++) RARRAY_PTR
(lines
)[i
] = Qnil
;
4682 RARRAY
(lines
)->len
= n
;
4683 rb_hash_aset
(coverages
, fname
, lines
);
4690 e_option_supplied
(struct parser_params
*parser
)
4692 if
(strcmp
(ruby_sourcefile
, "-e") == 0)
4698 yycompile0
(VALUE arg
, int tracing
)
4702 struct parser_params
*parser
= (struct parser_params
*)arg
;
4704 if
(!compile_for_eval
&& rb_safe_level
() == 0) {
4705 ruby_debug_lines
= debug_lines
(ruby_sourcefile
);
4706 if
(ruby_debug_lines
&& ruby_sourceline
> 0) {
4707 VALUE str
= STR_NEW0
();
4708 n
= ruby_sourceline
;
4710 rb_ary_push
(ruby_debug_lines
, str
);
4714 if
(!e_option_supplied
(parser
)) {
4715 ruby_coverage
= coverage
(ruby_sourcefile
, ruby_sourceline
);
4719 parser_prepare
(parser
);
4721 n
= yyparse((void*)parser
);
4722 ruby_debug_lines
= 0;
4724 compile_for_eval
= 0;
4727 lex_p
= lex_pbeg
= lex_pend
= 0;
4728 lex_lastline
= lex_nextline
= 0;
4732 tree
= ruby_eval_tree
;
4736 if
(ruby_eval_tree_begin
) {
4737 NODE
*scope
= ruby_eval_tree
;
4740 scope
->nd_body
= NEW_PRELUDE
(ruby_eval_tree_begin
, scope
->nd_body
);
4745 tree
= ruby_eval_tree
;
4751 yycompile
(struct parser_params
*parser
, const char *f
, int line
)
4753 ruby_sourcefile
= ruby_strdup
(f
);
4754 ruby_sourceline
= line
- 1;
4755 return
(NODE
*)ruby_suppress_tracing
(yycompile0
, (VALUE
)parser
, Qtrue
);
4757 #endif /* !RIPPER */
4760 lex_get_str
(struct parser_params
*parser
, VALUE s
)
4762 char *beg
, *end
, *pend
;
4764 beg
= RSTRING_PTR
(s
);
4766 if
(RSTRING_LEN
(s
) == lex_gets_ptr
) return Qnil
;
4767 beg
+= lex_gets_ptr
;
4769 pend
= RSTRING_PTR
(s
) + RSTRING_LEN
(s
);
4771 while
(end
< pend
) {
4772 if
(*end
++ == '\n') break
;
4774 lex_gets_ptr
= end
- RSTRING_PTR
(s
);
4775 return rb_enc_str_new
(beg
, end
- beg
, rb_enc_get
(s
));
4779 lex_getline
(struct parser_params
*parser
)
4781 VALUE line
= (*parser
->parser_lex_gets
)(parser
, parser
->parser_lex_input
);
4783 if
(ruby_debug_lines
&& !NIL_P
(line
)) {
4784 rb_ary_push
(ruby_debug_lines
, line
);
4786 if
(ruby_coverage
&& !NIL_P
(line
)) {
4787 rb_ary_push
(ruby_coverage
, Qnil
);
4795 rb_compile_string
(const char *f
, VALUE s
, int line
)
4797 VALUE volatile vparser
= rb_parser_new
();
4799 return rb_parser_compile_string
(vparser
, f
, s
, line
);
4803 rb_parser_compile_string
(volatile VALUE vparser
, const char *f
, VALUE s
, int line
)
4805 struct parser_params
*parser
;
4809 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
4810 lex_gets
= lex_get_str
;
4813 lex_pbeg
= lex_p
= lex_pend
= 0;
4814 compile_for_eval
= rb_parse_in_eval
();
4816 node
= yycompile
(parser
, f
, line
);
4817 tmp
= vparser
; /* prohibit tail call optimization */
4823 rb_compile_cstr
(const char *f
, const char *s
, int len
, int line
)
4825 return rb_compile_string
(f
, rb_str_new
(s
, len
), line
);
4829 rb_parser_compile_cstr
(volatile VALUE vparser
, const char *f
, const char *s
, int len
, int line
)
4831 return rb_parser_compile_string
(vparser
, f
, rb_str_new
(s
, len
), line
);
4835 lex_io_gets
(struct parser_params
*parser
, VALUE io
)
4837 return rb_io_gets
(io
);
4841 rb_compile_file
(const char *f
, VALUE file
, int start
)
4843 VALUE volatile vparser
= rb_parser_new
();
4845 return rb_parser_compile_file
(vparser
, f
, file
, start
);
4849 rb_parser_compile_file
(volatile VALUE vparser
, const char *f
, VALUE file
, int start
)
4851 struct parser_params
*parser
;
4855 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
4856 lex_gets
= lex_io_gets
;
4858 lex_pbeg
= lex_p
= lex_pend
= 0;
4860 node
= yycompile
(parser
, f
, start
);
4861 tmp
= vparser
; /* prohibit tail call optimization */
4865 #endif /* !RIPPER */
4867 #define STR_FUNC_ESCAPE 0x01
4868 #define STR_FUNC_EXPAND 0x02
4869 #define STR_FUNC_REGEXP 0x04
4870 #define STR_FUNC_QWORDS 0x08
4871 #define STR_FUNC_SYMBOL 0x10
4872 #define STR_FUNC_INDENT 0x20
4876 str_dquote
= (STR_FUNC_EXPAND
),
4877 str_xquote
= (STR_FUNC_EXPAND
),
4878 str_regexp
= (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND
),
4879 str_sword
= (STR_FUNC_QWORDS
),
4880 str_dword
= (STR_FUNC_QWORDS|STR_FUNC_EXPAND
),
4881 str_ssym
= (STR_FUNC_SYMBOL
),
4882 str_dsym
= (STR_FUNC_SYMBOL|STR_FUNC_EXPAND
)
4886 parser_str_new
(const char *p
, long n
, rb_encoding
*enc
, int func
, rb_encoding
*enc0
)
4890 str
= rb_enc_str_new
(p
, n
, enc
);
4891 if
(!(func
& STR_FUNC_REGEXP
) && rb_enc_asciicompat
(enc
)) {
4892 if
(rb_enc_str_coderange
(str
) == ENC_CODERANGE_7BIT
) {
4893 rb_enc_associate
(str
, rb_usascii_encoding
());
4895 else if
(enc0
== rb_usascii_encoding
() && enc
!= rb_utf8_encoding
()) {
4896 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
4903 #define lex_goto_eol(parser) (parser->parser_lex_p = parser->parser_lex_pend)
4906 parser_nextc
(struct parser_params
*parser
)
4910 if
(lex_p
== lex_pend
) {
4911 VALUE v
= lex_nextline
;
4917 if
(!lex_input || NIL_P
(v
= lex_getline
(parser
))) {
4918 parser
->eofp
= Qtrue
;
4919 lex_goto_eol
(parser
);
4925 if
(parser
->tokp
< lex_pend
) {
4926 if
(NIL_P
(parser
->delayed
)) {
4927 parser
->delayed
= rb_str_buf_new
(1024);
4928 rb_str_buf_cat
(parser
->delayed
,
4929 parser
->tokp
, lex_pend
- parser
->tokp
);
4930 parser
->delayed_line
= ruby_sourceline
;
4931 parser
->delayed_col
= parser
->tokp
- lex_pbeg
;
4934 rb_str_buf_cat
(parser
->delayed
,
4935 parser
->tokp
, lex_pend
- parser
->tokp
);
4939 if
(heredoc_end
> 0) {
4940 ruby_sourceline
= heredoc_end
;
4944 parser
->line_count
++;
4945 lex_pbeg
= lex_p
= RSTRING_PTR
(v
);
4946 lex_pend
= lex_p
+ RSTRING_LEN
(v
);
4948 ripper_flush
(parser
);
4953 c
= (unsigned char)*lex_p
++;
4954 if
(c
== '\r' && lex_p
< lex_pend
&& *lex_p
== '\n') {
4963 parser_pushback
(struct parser_params
*parser
, int c
)
4965 if
(c
== -1) return
;
4967 if
(lex_p
> lex_pbeg
&& lex_p
[0] == '\n' && lex_p
[-1] == '\r') {
4972 #define was_bol() (lex_p == lex_pbeg + 1)
4973 #define peek(c) (lex_p != lex_pend && (c) == *lex_p)
4975 #define tokfix() (tokenbuf[tokidx]='\0')
4976 #define tok() tokenbuf
4977 #define toklen() tokidx
4978 #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
4981 parser_newtok
(struct parser_params
*parser
)
4986 tokenbuf
= ALLOC_N
(char, 60);
4988 if
(toksiz
> 4096) {
4990 REALLOC_N
(tokenbuf
, char, 60);
4996 parser_tokspace
(struct parser_params
*parser
, int n
)
5000 if
(tokidx
>= toksiz
) {
5001 do
{toksiz
*= 2;} while
(toksiz
< tokidx
);
5002 REALLOC_N
(tokenbuf
, char, toksiz
);
5004 return
&tokenbuf
[tokidx
-n
];
5008 parser_tokadd
(struct parser_params
*parser
, int c
)
5010 tokenbuf
[tokidx
++] = (char)c
;
5011 if
(tokidx
>= toksiz
) {
5013 REALLOC_N
(tokenbuf
, char, toksiz
);
5018 parser_tok_hex
(struct parser_params
*parser
, int *numlen
)
5022 c
= scan_hex
(lex_p
, 2, numlen
);
5024 yyerror("invalid hex escape");
5031 #define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
5034 parser_tokadd_utf8
(struct parser_params
*parser
, rb_encoding
**encp
,
5035 int string_literal
, int symbol_literal
, int regexp_literal
)
5038 * If string_literal is true, then we allow multiple codepoints
5039 * in \u{}, and add the codepoints to the current token.
5040 * Otherwise we're parsing a character literal and return a single
5041 * codepoint without adding it
5047 if
(regexp_literal
) { tokadd
('\\'); tokadd
('u'); }
5049 if
(peek
('{')) { /* handle \u{...} form */
5051 if
(regexp_literal
) { tokadd
(*lex_p
); }
5053 codepoint
= scan_hex
(lex_p
, 6, &numlen
);
5055 yyerror("invalid Unicode escape");
5058 if
(codepoint
> 0x10ffff) {
5059 yyerror("invalid Unicode codepoint (too large)");
5063 if
(regexp_literal
) {
5066 else if
(codepoint
>= 0x80) {
5068 if
(string_literal
) tokaddmbc
(codepoint
, *encp
);
5070 else if
(string_literal
) {
5071 if
(codepoint
== 0 && symbol_literal
) {
5072 yyerror("symbol cannot contain '\\u{0}'");
5078 } while
(string_literal
&& (peek
(' ') || peek
('\t')));
5081 yyerror("unterminated Unicode escape");
5085 if
(regexp_literal
) { tokadd
('}'); }
5088 else
{ /* handle \uxxxx form */
5089 codepoint
= scan_hex
(lex_p
, 4, &numlen
);
5091 yyerror("invalid Unicode escape");
5095 if
(regexp_literal
) {
5098 else if
(codepoint
>= 0x80) {
5100 if
(string_literal
) tokaddmbc
(codepoint
, *encp
);
5102 else if
(string_literal
) {
5103 if
(codepoint
== 0 && symbol_literal
) {
5104 yyerror("symbol cannot contain '\\u0000'");
5115 #define ESCAPE_CONTROL 1
5116 #define ESCAPE_META 2
5119 parser_read_escape
(struct parser_params
*parser
, int flags
,
5125 switch
(c
= nextc
()) {
5126 case
'\\': /* Backslash */
5129 case
'n': /* newline */
5132 case
't': /* horizontal tab */
5135 case
'r': /* carriage-return */
5138 case
'f': /* form-feed */
5141 case
'v': /* vertical tab */
5144 case
'a': /* alarm(bell) */
5147 case
'e': /* escape */
5150 case
'0': case
'1': case
'2': case
'3': /* octal constant */
5151 case
'4': case
'5': case
'6': case
'7':
5152 if
(flags
& (ESCAPE_CONTROL|ESCAPE_META
)) goto eof
;
5157 c
= scan_oct
(lex_p
, 3, &numlen
);
5162 case
'x': /* hex constant */
5163 if
(flags
& (ESCAPE_CONTROL|ESCAPE_META
)) goto eof
;
5164 c
= tok_hex
(&numlen
);
5165 if
(numlen
== 0) return
0;
5168 case
'b': /* backspace */
5171 case
's': /* space */
5175 if
(flags
& ESCAPE_META
) goto eof
;
5176 if
((c
= nextc
()) != '-') {
5180 if
((c
= nextc
()) == '\\') {
5181 return read_escape
(flags|ESCAPE_META
, encp
) |
0x80;
5183 else if
(c
== -1 ||
!ISASCII
(c
)) goto eof
;
5185 return
((c
& 0xff) |
0x80);
5189 if
((c
= nextc
()) != '-') {
5194 if
(flags
& ESCAPE_CONTROL
) goto eof
;
5195 if
((c
= nextc
())== '\\') {
5196 c
= read_escape
(flags|ESCAPE_CONTROL
, encp
);
5200 else if
(c
== -1 ||
!ISASCII
(c
)) goto eof
;
5205 yyerror("Invalid escape character syntax");
5214 parser_tokaddmbc
(struct parser_params
*parser
, int c
, rb_encoding
*enc
)
5216 int len
= rb_enc_codelen
(c
, enc
);
5217 rb_enc_mbcput
(c
, tokspace
(len
), enc
);
5221 parser_tokadd_escape
(struct parser_params
*parser
, rb_encoding
**encp
)
5227 switch
(c
= nextc
()) {
5229 return
0; /* just ignore */
5231 case
'0': case
'1': case
'2': case
'3': /* octal constant */
5232 case
'4': case
'5': case
'6': case
'7':
5233 if
(flags
& (ESCAPE_CONTROL|ESCAPE_META
)) goto eof
;
5238 oct
= scan_oct
(--lex_p
, 3, &numlen
);
5239 if
(numlen
== 0) goto eof
;
5241 tokcopy
(numlen
+ 1);
5245 case
'x': /* hex constant */
5246 if
(flags
& (ESCAPE_CONTROL|ESCAPE_META
)) goto eof
;
5251 hex
= tok_hex
(&numlen
);
5252 if
(numlen
== 0) goto eof
;
5253 tokcopy
(numlen
+ 2);
5258 if
(flags
& ESCAPE_META
) goto eof
;
5259 if
((c
= nextc
()) != '-') {
5264 flags |
= ESCAPE_META
;
5268 if
(flags
& ESCAPE_CONTROL
) goto eof
;
5269 if
((c
= nextc
()) != '-') {
5277 if
(flags
& ESCAPE_CONTROL
) goto eof
;
5279 flags |
= ESCAPE_CONTROL
;
5281 if
((c
= nextc
()) == '\\') {
5284 else if
(c
== -1) goto eof
;
5290 yyerror("Invalid escape character syntax");
5300 extern
int rb_char_to_option_kcode
(int c
, int *option
, int *kcode
);
5303 parser_regx_options
(struct parser_params
*parser
)
5310 while
(c
= nextc
(), ISALPHA
(c
)) {
5312 options |
= RE_OPTION_ONCE
;
5314 else if
(rb_char_to_option_kcode
(c
, &opt
, &kc
)) {
5316 if
(kc
>= 0) kcode
= c
;
5325 compile_error
(PARSER_ARG
"unknown regexp option%s - %s",
5326 toklen
() > 1 ?
"s" : "", tok
());
5328 return options | RE_OPTION_ENCODING
(kcode
);
5332 dispose_string
(VALUE str
)
5334 /* TODO: should use another API? */
5335 if
(RBASIC
(str
)->flags
& RSTRING_NOEMBED
)
5336 xfree
(RSTRING_PTR
(str
));
5337 rb_gc_force_recycle
(str
);
5341 parser_tokadd_mbchar
(struct parser_params
*parser
, int c
)
5343 int len
= parser_precise_mbclen
();
5344 if
(!MBCLEN_CHARFOUND_P
(len
)) {
5345 compile_error
(PARSER_ARG
"invalid multibyte char");
5350 if
(len
> 0) tokcopy
(len
);
5354 #define tokadd_mbchar(c) parser_tokadd_mbchar(parser, c)
5357 parser_tokadd_string
(struct parser_params
*parser
,
5358 int func
, int term
, int paren
, long *nest
,
5362 int has_nonascii
= 0;
5363 rb_encoding
*enc
= *encp
;
5365 static const char mixed_msg
[] = "%s mixed within %s source";
5367 #define mixed_error(enc1, enc2) if (!errbuf) { \
5368 int len
= sizeof
(mixed_msg
) - 4; \
5369 len
+= strlen
(rb_enc_name
(enc1
)); \
5370 len
+= strlen
(rb_enc_name
(enc2
)); \
5371 errbuf
= ALLOCA_N
(char, len
); \
5372 snprintf
(errbuf
, len
, mixed_msg
, \
5373 rb_enc_name
(enc1
), \
5374 rb_enc_name
(enc2
)); \
5377 #define mixed_escape(beg, enc1, enc2) do { \
5378 const char *pos
= lex_p
; \
5380 mixed_error
(enc1
, enc2
); \
5384 while
((c
= nextc
()) != -1) {
5385 if
(paren
&& c
== paren
) {
5388 else if
(c
== term
) {
5389 if
(!nest ||
!*nest
) {
5395 else if
((func
& STR_FUNC_EXPAND
) && c
== '#' && lex_p
< lex_pend
) {
5397 if
(c2
== '$' || c2
== '@' || c2
== '{') {
5402 else if
(c
== '\\') {
5403 const char *beg
= lex_p
- 1;
5407 if
(func
& STR_FUNC_QWORDS
) break
;
5408 if
(func
& STR_FUNC_EXPAND
) continue
;
5413 if
(func
& STR_FUNC_ESCAPE
) tokadd
(c
);
5417 if
((func
& STR_FUNC_EXPAND
) == 0) {
5421 parser_tokadd_utf8
(parser
, &enc
, 1,
5422 func
& STR_FUNC_SYMBOL
,
5423 func
& STR_FUNC_REGEXP
);
5424 if
(has_nonascii
&& enc
!= *encp
) {
5425 mixed_escape
(beg
, enc
, *encp
);
5430 if
(func
& STR_FUNC_REGEXP
) {
5432 if
((c
= tokadd_escape
(&enc
)) < 0)
5434 if
(has_nonascii
&& enc
!= *encp
) {
5435 mixed_escape
(beg
, enc
, *encp
);
5439 else if
(func
& STR_FUNC_EXPAND
) {
5441 if
(func
& STR_FUNC_ESCAPE
) tokadd
('\\');
5442 c
= read_escape
(0, &enc
);
5444 else if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
5445 /* ignore backslashed spaces in %w */
5447 else if
(c
!= term
&& !(paren
&& c
== paren
)) {
5452 else if
(!parser_isascii
()) {
5455 mixed_error
(enc
, *encp
);
5458 if
(tokadd_mbchar
(c
) == -1) return
-1;
5461 else if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
5465 if
(!c
&& (func
& STR_FUNC_SYMBOL
)) {
5466 func
&= ~STR_FUNC_SYMBOL
;
5467 compile_error
(PARSER_ARG
"symbol cannot contain '\\0'");
5473 mixed_error
(enc
, *encp
);
5483 #define NEW_STRTERM(func, term, paren) \
5484 rb_node_newnode
(NODE_STRTERM
, (func
), (term
) |
((paren
) << (CHAR_BIT
* 2)), 0)
5487 parser_parse_string
(struct parser_params
*parser
, NODE
*quote
)
5489 int func
= quote
->nd_func
;
5490 int term
= nd_term
(quote
);
5491 int paren
= nd_paren
(quote
);
5493 rb_encoding
*enc
= parser
->enc
;
5495 if
(func
== -1) return tSTRING_END
;
5497 if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
5498 do
{c
= nextc
();} while
(ISSPACE
(c
));
5501 if
(c
== term
&& !quote
->nd_nest
) {
5502 if
(func
& STR_FUNC_QWORDS
) {
5503 quote
->nd_func
= -1;
5506 if
(!(func
& STR_FUNC_REGEXP
)) return tSTRING_END
;
5507 set_yylval_num
(regx_options
());
5515 if
((func
& STR_FUNC_EXPAND
) && c
== '#') {
5516 switch
(c
= nextc
()) {
5520 return tSTRING_DVAR
;
5522 return tSTRING_DBEG
;
5527 if
(tokadd_string
(func
, term
, paren
, "e
->nd_nest
,
5529 ruby_sourceline
= nd_line
(quote
);
5530 if
(func
& STR_FUNC_REGEXP
) {
5532 compile_error
(PARSER_ARG
"unterminated regexp meets end of file");
5537 compile_error
(PARSER_ARG
"unterminated string meets end of file");
5543 set_yylval_str
(STR_NEW3
(tok
(), toklen
(), enc
, func
));
5544 return tSTRING_CONTENT
;
5548 parser_heredoc_identifier
(struct parser_params
*parser
)
5550 int c
= nextc
(), term
, func
= 0, len
;
5554 func
= STR_FUNC_INDENT
;
5558 func |
= str_squote
; goto quoted
;
5560 func |
= str_dquote
; goto quoted
;
5567 while
((c
= nextc
()) != -1 && c
!= term
) {
5568 if
(tokadd_mbchar
(c
) == -1) return
0;
5571 compile_error
(PARSER_ARG
"unterminated here document identifier");
5577 if
(!parser_is_identchar
()) {
5579 if
(func
& STR_FUNC_INDENT
) {
5586 tokadd
(func |
= str_dquote
);
5588 if
(tokadd_mbchar
(c
) == -1) return
0;
5589 } while
((c
= nextc
()) != -1 && parser_is_identchar
());
5596 ripper_dispatch_scan_event
(parser
, tHEREDOC_BEG
);
5598 len
= lex_p
- lex_pbeg
;
5599 lex_goto_eol
(parser
);
5600 lex_strterm
= rb_node_newnode
(NODE_HEREDOC
,
5601 STR_NEW
(tok
(), toklen
()), /* nd_lit */
5603 lex_lastline
); /* nd_orig */
5604 nd_set_line
(lex_strterm
, ruby_sourceline
);
5606 ripper_flush
(parser
);
5608 return term
== '`' ? tXSTRING_BEG
: tSTRING_BEG
;
5612 parser_heredoc_restore
(struct parser_params
*parser
, NODE
*here
)
5617 if
(!NIL_P
(parser
->delayed
))
5618 ripper_dispatch_delayed_token
(parser
, tSTRING_CONTENT
);
5619 lex_goto_eol
(parser
);
5620 ripper_dispatch_scan_event
(parser
, tHEREDOC_END
);
5622 line
= here
->nd_orig
;
5623 lex_lastline
= line
;
5624 lex_pbeg
= RSTRING_PTR
(line
);
5625 lex_pend
= lex_pbeg
+ RSTRING_LEN
(line
);
5626 lex_p
= lex_pbeg
+ here
->nd_nth
;
5627 heredoc_end
= ruby_sourceline
;
5628 ruby_sourceline
= nd_line
(here
);
5629 dispose_string
(here
->nd_lit
);
5630 rb_gc_force_recycle
((VALUE
)here
);
5632 ripper_flush
(parser
);
5637 parser_whole_match_p
(struct parser_params
*parser
,
5638 const char *eos
, int len
, int indent
)
5640 const char *p
= lex_pbeg
;
5644 while
(*p
&& ISSPACE
(*p
)) p
++;
5646 n
= lex_pend
- (p
+ len
);
5647 if
(n
< 0 ||
(n
> 0 && p
[len
] != '\n' && p
[len
] != '\r')) return Qfalse
;
5648 if
(strncmp
(eos
, p
, len
) == 0) return Qtrue
;
5653 parser_here_document
(struct parser_params
*parser
, NODE
*here
)
5655 int c
, func
, indent
= 0;
5656 const char *eos
, *p
, *pend
;
5660 eos
= RSTRING_PTR
(here
->nd_lit
);
5661 len
= RSTRING_LEN
(here
->nd_lit
) - 1;
5662 indent
= (func
= *eos
++) & STR_FUNC_INDENT
;
5664 if
((c
= nextc
()) == -1) {
5666 compile_error
(PARSER_ARG
"can't find string \"%s\" anywhere before EOF", eos
);
5668 heredoc_restore
(lex_strterm
);
5672 if
(was_bol
() && whole_match_p
(eos
, len
, indent
)) {
5673 heredoc_restore
(lex_strterm
);
5677 if
(!(func
& STR_FUNC_EXPAND
)) {
5679 p
= RSTRING_PTR
(lex_lastline
);
5684 if
(--pend
== p || pend
[-1] != '\r') {
5693 rb_str_cat
(str
, p
, pend
- p
);
5695 str
= STR_NEW
(p
, pend
- p
);
5696 if
(pend
< lex_pend
) rb_str_cat
(str
, "\n", 1);
5697 lex_goto_eol
(parser
);
5698 if
(nextc
() == -1) {
5699 if
(str
) dispose_string
(str
);
5702 } while
(!whole_match_p
(eos
, len
, indent
));
5705 /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
5706 rb_encoding
*enc
= parser
->enc
;
5709 switch
(c
= nextc
()) {
5713 return tSTRING_DVAR
;
5715 return tSTRING_DBEG
;
5721 if
((c
= tokadd_string
(func
, '\n', 0, NULL
, &enc
)) == -1) {
5722 if
(parser
->eofp
) goto
error;
5726 set_yylval_str
(STR_NEW3
(tok
(), toklen
(), enc
, func
));
5727 return tSTRING_CONTENT
;
5730 /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
5731 if
((c
= nextc
()) == -1) goto
error;
5732 } while
(!whole_match_p
(eos
, len
, indent
));
5733 str
= STR_NEW3
(tok
(), toklen
(), enc
, func
);
5735 heredoc_restore
(lex_strterm
);
5736 lex_strterm
= NEW_STRTERM
(-1, 0, 0);
5737 set_yylval_str
(str
);
5738 return tSTRING_CONTENT
;
5745 arg_ambiguous_gen
(struct parser_params
*parser
)
5747 rb_warning0
("ambiguous first argument; put parentheses or even spaces");
5751 arg_ambiguous_gen
(struct parser_params
*parser
)
5753 dispatch0
(arg_ambiguous
);
5756 #define arg_ambiguous() arg_ambiguous_gen(parser)
5759 lvar_defined_gen
(struct parser_params
*parser
, ID id
)
5762 return
(dyna_in_block
() && dvar_defined
(id
)) || local_id
(id
);
5768 /* emacsen -*- hack */
5770 parser_encode_length
(struct parser_params
*parser
, const char *name
, int len
)
5774 if
(len
> 5 && name
[nlen
= len
- 5] == '-') {
5775 if
(rb_memcicmp
(name
+ nlen
+ 1, "unix", 4) == 0)
5778 if
(len
> 4 && name
[nlen
= len
- 5] == '-') {
5779 if
(rb_memcicmp
(name
+ nlen
+ 1, "dos", 3) == 0)
5781 if
(rb_memcicmp
(name
+ nlen
+ 1, "mac", 3) == 0)
5788 parser_set_encode
(struct parser_params
*parser
, const char *name
)
5790 int idx
= rb_enc_find_index
(name
);
5794 rb_raise
(rb_eArgError
, "unknown encoding name: %s", name
);
5796 enc
= rb_enc_from_index
(idx
);
5797 if
(!rb_enc_asciicompat
(enc
)) {
5798 rb_raise
(rb_eArgError
, "%s is not ASCII compatible", rb_enc_name
(enc
));
5804 typedef
int (*rb_magic_comment_length_t
)(struct parser_params
*parser
, const char *name
, int len
);
5805 typedef
void (*rb_magic_comment_setter_t
)(struct parser_params
*parser
, const char *name
, const char *val
);
5808 magic_comment_encoding
(struct parser_params
*parser
, const char *name
, const char *val
)
5810 if
(parser
->line_count
!= (parser
->has_shebang ?
2 : 1))
5812 parser_set_encode
(parser
, val
);
5815 struct magic_comment
{
5817 rb_magic_comment_setter_t func
;
5818 rb_magic_comment_length_t length
;
5821 static const struct magic_comment magic_comments
[] = {
5822 {"coding", magic_comment_encoding
, parser_encode_length
},
5823 {"encoding", magic_comment_encoding
, parser_encode_length
},
5828 magic_comment_marker
(const char *str
, int len
)
5835 if
(str
[i
-1] == '*' && str
[i
-2] == '-') {
5841 if
(i
+ 1 >= len
) return
0;
5842 if
(str
[i
+1] != '-') {
5845 else if
(str
[i
-1] != '-') {
5861 parser_magic_comment
(struct parser_params
*parser
, const char *str
, int len
)
5863 VALUE name
= 0, val
= 0;
5864 const char *beg
, *end
, *vbeg
, *vend
;
5865 #define str_copy(_s, _p, _n) ((_s) \
5866 ?
(rb_str_resize
((_s
), (_n
)), \
5867 MEMCPY
(RSTRING_PTR
(_s
), (_p
), char, (_n
)), (_s
)) \
5868 : ((_s
) = STR_NEW
((_p
), (_n
))))
5870 if
(len
<= 7) return Qfalse
;
5871 if
(!(beg
= magic_comment_marker
(str
, len
))) return Qfalse
;
5872 if
(!(end
= magic_comment_marker
(beg
, str
+ len
- beg
))) return Qfalse
;
5874 len
= end
- beg
- 3;
5876 /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
5879 const struct magic_comment
*p
= magic_comments
;
5883 for
(; len
> 0 && *str
; str
++, --len
) {
5885 case
'\'': case
'"': case
':': case
';':
5888 if
(!ISSPACE
(*str
)) break
;
5890 for
(beg
= str
; len
> 0; str
++, --len
) {
5892 case
'\'': case
'"': case
':': case
';':
5895 if
(ISSPACE
(*str
)) break
;
5900 for
(end
= str
; len
> 0 && ISSPACE
(*str
); str
++, --len
);
5902 if
(*str
!= ':') continue
;
5904 do str
++; while
(--len
> 0 && ISSPACE
(*str
));
5907 for
(vbeg
= ++str
; --len
> 0 && *str
!= '"'; str
++) {
5920 for
(vbeg
= str
; len
> 0 && *str
!= '"' && *str
!= ';' && !ISSPACE
(*str
); --len
, str
++);
5923 while
(len
> 0 && (*str
== ';' || ISSPACE
(*str
))) --len
, str
++;
5926 str_copy
(name
, beg
, n
);
5929 if
(STRNCASECMP
(p
->name
, RSTRING_PTR
(name
), n
) == 0) {
5932 n
= (*p
->length
)(parser
, vbeg
, n
);
5934 str_copy
(val
, vbeg
, n
);
5935 (*p
->func
)(parser
, RSTRING_PTR
(name
), RSTRING_PTR
(val
));
5938 } while
(++p
< magic_comments
+ sizeof
(magic_comments
) / sizeof
(*p
));
5940 dispatch2
(magic_comment
, name
, val
);
5948 set_file_encoding
(struct parser_params
*parser
, const char *str
, const char *send
)
5951 const char *beg
= str
;
5955 if
(send
- str
<= 6) return
;
5957 case
'C': case
'c': str
+= 6; continue
;
5958 case
'O': case
'o': str
+= 5; continue
;
5959 case
'D': case
'd': str
+= 4; continue
;
5960 case
'I': case
'i': str
+= 3; continue
;
5961 case
'N': case
'n': str
+= 2; continue
;
5962 case
'G': case
'g': str
+= 1; continue
;
5969 if
(ISSPACE
(*str
)) break
;
5972 if
(STRNCASECMP
(str
-6, "coding", 6) == 0) break
;
5976 if
(++str
>= send
) return
;
5977 } while
(ISSPACE
(*str
));
5979 if
(*str
!= '=' && *str
!= ':') return
;
5984 while
((*str
== '-' ||
*str
== '_' || ISALNUM
(*str
)) && ++str
< send
);
5985 s
= rb_str_new
(beg
, parser_encode_length
(parser
, beg
, str
- beg
));
5986 parser_set_encode
(parser
, RSTRING_PTR
(s
));
5987 rb_str_resize
(s
, 0);
5991 parser_prepare
(struct parser_params
*parser
)
5996 if
(peek
('!')) parser
->has_shebang
= 1;
5998 case
0xef: /* UTF-8 BOM marker */
5999 if
(lex_pend
- lex_p
>= 2 &&
6000 (unsigned char)lex_p
[0] == 0xbb &&
6001 (unsigned char)lex_p
[1] == 0xbf) {
6002 parser_set_encode
(parser
, "UTF-8");
6012 parser
->enc
= rb_enc_get
(lex_lastline
);
6015 #define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG)
6016 #define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_VALUE || lex_state == EXPR_CLASS)
6019 parser_yylex
(struct parser_params
*parser
)
6024 enum lex_state_e last_state
;
6028 int fallthru
= Qfalse
;
6033 if
(nd_type
(lex_strterm
) == NODE_HEREDOC
) {
6034 token
= here_document
(lex_strterm
);
6035 if
(token
== tSTRING_END
) {
6037 lex_state
= EXPR_ENDARG
;
6041 token
= parse_string
(lex_strterm
);
6042 if
(token
== tSTRING_END || token
== tREGEXP_END
) {
6043 rb_gc_force_recycle
((VALUE
)lex_strterm
);
6045 lex_state
= EXPR_ENDARG
;
6050 cmd_state
= command_start
;
6051 command_start
= Qfalse
;
6053 switch
(c
= nextc
()) {
6054 case
'\0': /* NUL */
6055 case
'\004': /* ^D */
6056 case
'\032': /* ^Z */
6057 case
-1: /* end of script. */
6061 case
' ': case
'\t': case
'\f': case
'\r':
6062 case
'\13': /* '\v' */
6065 while
((c
= nextc
())) {
6067 case
' ': case
'\t': case
'\f': case
'\r':
6068 case
'\13': /* '\v' */
6076 ripper_dispatch_scan_event
(parser
, tSP
);
6080 case
'#': /* it's a comment */
6081 /* no magic_comment in shebang line */
6082 if
(parser
->line_count
== (parser
->has_shebang ?
2 : 1)
6083 && (lex_p
- lex_pbeg
) == 1) {
6084 if
(!parser_magic_comment
(parser
, lex_p
, lex_pend
- lex_p
)) {
6085 set_file_encoding
(parser
, lex_p
, lex_pend
);
6090 ripper_dispatch_scan_event
(parser
, tCOMMENT
);
6095 switch
(lex_state
) {
6103 ripper_dispatch_scan_event
(parser
, tIGNORED_NL
);
6111 while
((c
= nextc
())) {
6113 case
' ': case
'\t': case
'\f': case
'\r':
6114 case
'\13': /* '\v' */
6118 if
((c
= nextc
()) != '.') {
6126 lex_nextline
= lex_lastline
;
6127 case
-1: /* EOF no decrement*/
6128 lex_goto_eol
(parser
);
6131 parser
->tokp
= lex_p
;
6134 goto normal_newline
;
6138 command_start
= Qtrue
;
6139 lex_state
= EXPR_BEG
;
6143 if
((c
= nextc
()) == '*') {
6144 if
((c
= nextc
()) == '=') {
6145 set_yylval_id
(tPOW
);
6146 lex_state
= EXPR_BEG
;
6155 lex_state
= EXPR_BEG
;
6159 if
(IS_ARG
() && space_seen
&& !ISSPACE
(c
)) {
6160 rb_warning0
("`*' interpreted as argument prefix");
6163 else if
(IS_BEG
()) {
6170 switch
(lex_state
) {
6171 case EXPR_FNAME
: case EXPR_DOT
:
6172 lex_state
= EXPR_ARG
; break
;
6174 lex_state
= EXPR_BEG
; break
;
6180 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6181 lex_state
= EXPR_ARG
;
6187 lex_state
= EXPR_BEG
;
6200 /* skip embedded rd document */
6201 if
(strncmp
(lex_p
, "begin", 5) == 0 && ISSPACE
(lex_p
[5])) {
6203 int first_p
= Qtrue
;
6205 lex_goto_eol
(parser
);
6206 ripper_dispatch_scan_event
(parser
, tEMBDOC_BEG
);
6209 lex_goto_eol
(parser
);
6212 ripper_dispatch_scan_event
(parser
, tEMBDOC
);
6218 compile_error
(PARSER_ARG
"embedded document meets end of file");
6221 if
(c
!= '=') continue
;
6222 if
(strncmp
(lex_p
, "end", 3) == 0 &&
6223 (lex_p
+ 3 == lex_pend || ISSPACE
(lex_p
[3]))) {
6227 lex_goto_eol
(parser
);
6229 ripper_dispatch_scan_event
(parser
, tEMBDOC_END
);
6235 switch
(lex_state
) {
6236 case EXPR_FNAME
: case EXPR_DOT
:
6237 lex_state
= EXPR_ARG
; break
;
6239 lex_state
= EXPR_BEG
; break
;
6241 if
((c
= nextc
()) == '=') {
6242 if
((c
= nextc
()) == '=') {
6251 else if
(c
== '>') {
6260 lex_state
!= EXPR_END
&&
6261 lex_state
!= EXPR_DOT
&&
6262 lex_state
!= EXPR_ENDARG
&&
6263 lex_state
!= EXPR_CLASS
&&
6264 (!IS_ARG
() || space_seen
)) {
6265 int token
= heredoc_identifier
();
6266 if
(token
) return token
;
6268 switch
(lex_state
) {
6269 case EXPR_FNAME
: case EXPR_DOT
:
6270 lex_state
= EXPR_ARG
; break
;
6272 lex_state
= EXPR_BEG
; break
;
6275 if
((c
= nextc
()) == '>') {
6282 if
((c
= nextc
()) == '=') {
6283 set_yylval_id
(tLSHFT
);
6284 lex_state
= EXPR_BEG
;
6294 switch
(lex_state
) {
6295 case EXPR_FNAME
: case EXPR_DOT
:
6296 lex_state
= EXPR_ARG
; break
;
6298 lex_state
= EXPR_BEG
; break
;
6300 if
((c
= nextc
()) == '=') {
6304 if
((c
= nextc
()) == '=') {
6305 set_yylval_id
(tRSHFT
);
6306 lex_state
= EXPR_BEG
;
6316 lex_strterm
= NEW_STRTERM
(str_dquote
, '"', 0);
6320 if
(lex_state
== EXPR_FNAME
) {
6321 lex_state
= EXPR_END
;
6324 if
(lex_state
== EXPR_DOT
) {
6326 lex_state
= EXPR_CMDARG
;
6328 lex_state
= EXPR_ARG
;
6331 lex_strterm
= NEW_STRTERM
(str_xquote
, '`', 0);
6332 return tXSTRING_BEG
;
6335 lex_strterm
= NEW_STRTERM
(str_squote
, '\'', 0);
6339 if
(lex_state
== EXPR_END ||
6340 lex_state
== EXPR_ENDARG
) {
6341 lex_state
= EXPR_VALUE
;
6346 compile_error
(PARSER_ARG
"incomplete character syntax");
6349 if
(rb_enc_isspace
(c
, parser
->enc
)) {
6373 rb_warnI
("invalid character syntax; use ?\\%c", c2
);
6378 lex_state
= EXPR_VALUE
;
6383 if
(!parser_isascii
()) {
6384 if
(tokadd_mbchar
(c
) == -1) return
0;
6386 else if
((rb_enc_isalnum
(c
, parser
->enc
) || c
== '_') &&
6387 lex_p
< lex_pend
&& is_identchar
(lex_p
, lex_pend
, parser
->enc
)) {
6390 else if
(c
== '\\') {
6393 c
= parser_tokadd_utf8
(parser
, &enc
, 0, 0, 0);
6402 c
= read_escape
(0, &enc
);
6410 set_yylval_str
(STR_NEW3
(tok
(), toklen
(), enc
, 0));
6411 lex_state
= EXPR_ENDARG
;
6415 if
((c
= nextc
()) == '&') {
6416 lex_state
= EXPR_BEG
;
6417 if
((c
= nextc
()) == '=') {
6418 set_yylval_id
(tANDOP
);
6419 lex_state
= EXPR_BEG
;
6425 else if
(c
== '=') {
6427 lex_state
= EXPR_BEG
;
6431 if
(IS_ARG
() && space_seen
&& !ISSPACE
(c
)) {
6432 rb_warning0
("`&' interpreted as argument prefix");
6435 else if
(IS_BEG
()) {
6441 switch
(lex_state
) {
6442 case EXPR_FNAME
: case EXPR_DOT
:
6443 lex_state
= EXPR_ARG
; break
;
6445 lex_state
= EXPR_BEG
;
6450 if
((c
= nextc
()) == '|') {
6451 lex_state
= EXPR_BEG
;
6452 if
((c
= nextc
()) == '=') {
6453 set_yylval_id
(tOROP
);
6454 lex_state
= EXPR_BEG
;
6462 lex_state
= EXPR_BEG
;
6465 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6466 lex_state
= EXPR_ARG
;
6469 lex_state
= EXPR_BEG
;
6476 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6477 lex_state
= EXPR_ARG
;
6486 lex_state
= EXPR_BEG
;
6490 (IS_ARG
() && space_seen
&& !ISSPACE
(c
))) {
6491 if
(IS_ARG
()) arg_ambiguous
();
6492 lex_state
= EXPR_BEG
;
6500 lex_state
= EXPR_BEG
;
6506 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6507 lex_state
= EXPR_ARG
;
6516 lex_state
= EXPR_BEG
;
6520 lex_state
= EXPR_ARG
;
6524 (IS_ARG
() && space_seen
&& !ISSPACE
(c
))) {
6525 if
(IS_ARG
()) arg_ambiguous
();
6526 lex_state
= EXPR_BEG
;
6533 lex_state
= EXPR_BEG
;
6538 lex_state
= EXPR_BEG
;
6539 if
((c
= nextc
()) == '.') {
6540 if
((c
= nextc
()) == '.') {
6548 yyerror("no .<digit> floating literal anymore; put 0 before dot");
6550 lex_state
= EXPR_DOT
;
6554 case
'0': case
'1': case
'2': case
'3': case
'4':
6555 case
'5': case
'6': case
'7': case
'8': case
'9':
6557 int is_float
, seen_point
, seen_e
, nondigit
;
6559 is_float
= seen_point
= seen_e
= nondigit
= 0;
6560 lex_state
= EXPR_ENDARG
;
6562 if
(c
== '-' || c
== '+') {
6567 int start
= toklen
();
6569 if
(c
== 'x' || c
== 'X') {
6575 if
(nondigit
) break
;
6579 if
(!ISXDIGIT
(c
)) break
;
6582 } while
((c
= nextc
()) != -1);
6586 if
(toklen
() == start
) {
6587 yyerror("numeric literal without digits");
6589 else if
(nondigit
) goto trailing_uc
;
6590 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 16, Qfalse
));
6593 if
(c
== 'b' || c
== 'B') {
6596 if
(c
== '0' || c
== '1') {
6599 if
(nondigit
) break
;
6603 if
(c
!= '0' && c
!= '1') break
;
6606 } while
((c
= nextc
()) != -1);
6610 if
(toklen
() == start
) {
6611 yyerror("numeric literal without digits");
6613 else if
(nondigit
) goto trailing_uc
;
6614 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 2, Qfalse
));
6617 if
(c
== 'd' || c
== 'D') {
6623 if
(nondigit
) break
;
6627 if
(!ISDIGIT
(c
)) break
;
6630 } while
((c
= nextc
()) != -1);
6634 if
(toklen
() == start
) {
6635 yyerror("numeric literal without digits");
6637 else if
(nondigit
) goto trailing_uc
;
6638 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 10, Qfalse
));
6645 if
(c
== 'o' || c
== 'O') {
6646 /* prefixed octal */
6648 if
(c
== '_' ||
!ISDIGIT
(c
)) {
6649 yyerror("numeric literal without digits");
6652 if
(c
>= '0' && c
<= '7') {
6657 if
(nondigit
) break
;
6661 if
(c
< '0' || c
> '9') break
;
6662 if
(c
> '7') goto invalid_octal
;
6665 } while
((c
= nextc
()) != -1);
6666 if
(toklen
() > start
) {
6669 if
(nondigit
) goto trailing_uc
;
6670 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 8, Qfalse
));
6678 if
(c
> '7' && c
<= '9') {
6680 yyerror("Invalid octal digit");
6682 else if
(c
== '.' || c
== 'e' || c
== 'E') {
6687 set_yylval_literal
(INT2FIX
(0));
6694 case
'0': case
'1': case
'2': case
'3': case
'4':
6695 case
'5': case
'6': case
'7': case
'8': case
'9':
6701 if
(nondigit
) goto trailing_uc
;
6702 if
(seen_point || seen_e
) {
6735 if
(c
!= '-' && c
!= '+') continue
;
6740 case
'_': /* `_' in number just ignored */
6741 if
(nondigit
) goto decode_num
;
6757 sprintf
(tmp
, "trailing `%c' in number", nondigit
);
6761 double d
= strtod
(tok
(), 0);
6762 if
(errno
== ERANGE
) {
6763 rb_warningS
("Float %s out of range", tok
());
6766 set_yylval_literal
(DOUBLE2NUM
(d
));
6769 set_yylval_literal
(rb_cstr_to_inum
(tok
(), 10, Qfalse
));
6780 lex_state
= EXPR_END
;
6782 lex_state
= EXPR_ENDARG
;
6789 lex_state
== EXPR_CLASS ||
(IS_ARG
() && space_seen
)) {
6790 lex_state
= EXPR_BEG
;
6793 lex_state
= EXPR_DOT
;
6796 if
(lex_state
== EXPR_END ||
6797 lex_state
== EXPR_ENDARG || ISSPACE
(c
)) {
6799 lex_state
= EXPR_BEG
;
6804 lex_strterm
= NEW_STRTERM
(str_ssym
, c
, 0);
6807 lex_strterm
= NEW_STRTERM
(str_dsym
, c
, 0);
6813 lex_state
= EXPR_FNAME
;
6818 lex_strterm
= NEW_STRTERM
(str_regexp
, '/', 0);
6821 if
((c
= nextc
()) == '=') {
6823 lex_state
= EXPR_BEG
;
6827 if
(IS_ARG
() && space_seen
) {
6830 lex_strterm
= NEW_STRTERM
(str_regexp
, '/', 0);
6834 switch
(lex_state
) {
6835 case EXPR_FNAME
: case EXPR_DOT
:
6836 lex_state
= EXPR_ARG
; break
;
6838 lex_state
= EXPR_BEG
; break
;
6843 if
((c
= nextc
()) == '=') {
6845 lex_state
= EXPR_BEG
;
6848 switch
(lex_state
) {
6849 case EXPR_FNAME
: case EXPR_DOT
:
6850 lex_state
= EXPR_ARG
; break
;
6852 lex_state
= EXPR_BEG
; break
;
6858 lex_state
= EXPR_BEG
;
6859 command_start
= Qtrue
;
6863 lex_state
= EXPR_BEG
;
6867 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6868 if
((c
= nextc
()) != '@') {
6871 lex_state
= EXPR_ARG
;
6874 lex_state
= EXPR_BEG
;
6882 else if
(space_seen
) {
6890 lex_state
= EXPR_BEG
;
6895 if
(lex_state
== EXPR_FNAME || lex_state
== EXPR_DOT
) {
6896 lex_state
= EXPR_ARG
;
6897 if
((c
= nextc
()) == ']') {
6898 if
((c
= nextc
()) == '=') {
6907 else if
(IS_BEG
()) {
6910 else if
(IS_ARG
() && space_seen
) {
6913 lex_state
= EXPR_BEG
;
6919 if
(lpar_beg
&& lpar_beg
== paren_nest
) {
6920 lex_state
= EXPR_BEG
;
6925 if
(IS_ARG
() || lex_state
== EXPR_END
)
6926 c
= '{'; /* block (primary) */
6927 else if
(lex_state
== EXPR_ENDARG
)
6928 c
= tLBRACE_ARG
; /* block (expr) */
6930 c
= tLBRACE
; /* hash */
6933 lex_state
= EXPR_BEG
;
6934 if
(c
!= tLBRACE
) command_start
= Qtrue
;
6942 ripper_dispatch_scan_event
(parser
, tSP
);
6944 goto retry
; /* skip \\n */
6962 if
(rb_enc_isalnum
(term
, parser
->enc
) ||
!parser_isascii
()) {
6963 yyerror("unknown type of %string");
6967 if
(c
== -1 || term
== -1) {
6968 compile_error
(PARSER_ARG
"unterminated quoted string meets end of file");
6972 if
(term
== '(') term
= ')';
6973 else if
(term
== '[') term
= ']';
6974 else if
(term
== '{') term
= '}';
6975 else if
(term
== '<') term
= '>';
6980 lex_strterm
= NEW_STRTERM
(str_dquote
, term
, paren
);
6984 lex_strterm
= NEW_STRTERM
(str_squote
, term
, paren
);
6988 lex_strterm
= NEW_STRTERM
(str_dword
, term
, paren
);
6989 do
{c
= nextc
();} while
(ISSPACE
(c
));
6994 lex_strterm
= NEW_STRTERM
(str_sword
, term
, paren
);
6995 do
{c
= nextc
();} while
(ISSPACE
(c
));
7000 lex_strterm
= NEW_STRTERM
(str_xquote
, term
, paren
);
7001 return tXSTRING_BEG
;
7004 lex_strterm
= NEW_STRTERM
(str_regexp
, term
, paren
);
7008 lex_strterm
= NEW_STRTERM
(str_ssym
, term
, paren
);
7009 lex_state
= EXPR_FNAME
;
7013 yyerror("unknown type of %string");
7017 if
((c
= nextc
()) == '=') {
7019 lex_state
= EXPR_BEG
;
7022 if
(IS_ARG
() && space_seen
&& !ISSPACE
(c
)) {
7025 switch
(lex_state
) {
7026 case EXPR_FNAME
: case EXPR_DOT
:
7027 lex_state
= EXPR_ARG
; break
;
7029 lex_state
= EXPR_BEG
; break
;
7035 last_state
= lex_state
;
7036 lex_state
= EXPR_ENDARG
;
7040 case
'_': /* $_: last read line string */
7042 if
(parser_is_identchar
()) {
7050 case
'~': /* $~: match-data */
7051 case
'*': /* $*: argv */
7052 case
'$': /* $$: pid */
7053 case
'?': /* $?: last status */
7054 case
'!': /* $!: error string */
7055 case
'@': /* $@: error position */
7056 case
'/': /* $/: input record separator */
7057 case
'\\': /* $\: output record separator */
7058 case
';': /* $;: field separator */
7059 case
',': /* $,: output field separator */
7060 case
'.': /* $.: last read line number */
7061 case
'=': /* $=: ignorecase */
7062 case
':': /* $:: load path */
7063 case
'<': /* $<: reading filename */
7064 case
'>': /* $>: default output handle */
7065 case
'\"': /* $": already loaded files */
7069 set_yylval_id
(rb_intern
(tok
()));
7076 if
(parser_is_identchar
()) {
7077 if
(tokadd_mbchar
(c
) == -1) return
0;
7084 set_yylval_id
(rb_intern
(tok
()));
7087 case
'&': /* $&: last match */
7088 case
'`': /* $`: string before last match */
7089 case
'\'': /* $': string after last match */
7090 case
'+': /* $+: string matches last paren. */
7091 if
(last_state
== EXPR_FNAME
) {
7096 set_yylval_node
(NEW_BACK_REF
(c
));
7099 case
'1': case
'2': case
'3':
7100 case
'4': case
'5': case
'6':
7101 case
'7': case
'8': case
'9':
7106 } while
(ISDIGIT
(c
));
7108 if
(last_state
== EXPR_FNAME
) goto gvar
;
7110 set_yylval_node
(NEW_NTH_REF
(atoi
(tok
()+1)));
7114 if
(!parser_is_identchar
()) {
7133 compile_error
(PARSER_ARG
"`@%c' is not allowed as an instance variable name", c
);
7136 compile_error
(PARSER_ARG
"`@@%c' is not allowed as a class variable name", c
);
7140 if
(!parser_is_identchar
()) {
7147 if
(was_bol
() && whole_match_p
("__END__", 7, 0)) {
7148 ruby__end__seen
= 1;
7149 parser
->eofp
= Qtrue
;
7153 lex_goto_eol
(parser
);
7154 ripper_dispatch_scan_event
(parser
, k__END__
);
7162 if
(!parser_is_identchar
()) {
7163 rb_compile_error
(PARSER_ARG
"Invalid char `\\x%02X' in expression", c
);
7171 mb
= ENC_CODERANGE_7BIT
;
7173 if
(!ISASCII
(c
)) mb
= ENC_CODERANGE_UNKNOWN
;
7174 if
(tokadd_mbchar
(c
) == -1) return
0;
7176 } while
(parser_is_identchar
());
7182 if
((c
== '!' || c
== '?') && !peek
('=')) {
7194 last_state
= lex_state
;
7197 lex_state
= EXPR_ENDARG
;
7201 lex_state
= EXPR_ENDARG
;
7202 if
(tok
()[1] == '@')
7209 if
(toklast
() == '!' || toklast
() == '?') {
7213 if
(lex_state
== EXPR_FNAME
) {
7214 if
((c
= nextc
()) == '=' && !peek
('~') && !peek
('>') &&
7215 (!peek
('=') ||
(lex_p
+ 1 < lex_pend
&& lex_p
[1] == '>'))) {
7216 result
= tIDENTIFIER
;
7224 if
(result
== 0 && ISUPPER
(tok
()[0])) {
7228 result
= tIDENTIFIER
;
7232 if
(mb
== ENC_CODERANGE_7BIT
&& lex_state
!= EXPR_DOT
) {
7233 const struct kwtable
*kw
;
7235 /* See if it is a reserved word. */
7236 kw
= rb_reserved_word
(tok
(), toklen
());
7238 enum lex_state_e state
= lex_state
;
7239 lex_state
= kw
->state
;
7240 if
(state
== EXPR_FNAME
) {
7241 set_yylval_id
(rb_intern
(kw
->name
));
7244 if
(kw
->id
[0] == keyword_do
) {
7245 command_start
= Qtrue
;
7246 if
(lpar_beg
&& lpar_beg
== paren_nest
) {
7249 return keyword_do_LAMBDA
;
7251 if
(COND_P
()) return keyword_do_cond
;
7252 if
(CMDARG_P
() && state
!= EXPR_CMDARG
)
7253 return keyword_do_block
;
7254 if
(state
== EXPR_ENDARG || state
== EXPR_BEG
)
7255 return keyword_do_block
;
7258 if
(state
== EXPR_BEG || state
== EXPR_VALUE
)
7261 if
(kw
->id
[0] != kw
->id
[1])
7262 lex_state
= EXPR_BEG
;
7268 if
((lex_state
== EXPR_BEG
&& !cmd_state
) ||
7269 lex_state
== EXPR_ARG ||
7270 lex_state
== EXPR_CMDARG
) {
7271 if
(peek
(':') && !(lex_p
+ 1 < lex_pend
&& lex_p
[1] == ':')) {
7272 lex_state
= EXPR_BEG
;
7274 set_yylval_id
(TOK_INTERN
(!ENC_SINGLE
(mb
)));
7279 lex_state
== EXPR_DOT ||
7282 lex_state
= EXPR_CMDARG
;
7285 lex_state
= EXPR_ARG
;
7289 lex_state
= EXPR_END
;
7293 ID ident
= TOK_INTERN
(!ENC_SINGLE
(mb
));
7295 set_yylval_id
(ident
);
7296 if
(last_state
!= EXPR_DOT
&& is_local_id
(ident
) && lvar_defined
(ident
)) {
7297 lex_state
= EXPR_END
;
7306 yylex(void *lval
, void *p
)
7311 struct parser_params
*parser
= (struct parser_params
*)p
;
7315 parser
->parser_yylval
= lval
;
7316 parser
->parser_yylval
->val
= Qundef
;
7318 t
= parser_yylex
(parser
);
7320 if
(!NIL_P
(parser
->delayed
)) {
7321 ripper_dispatch_delayed_token
(parser
, t
);
7325 ripper_dispatch_scan_event
(parser
, t
);
7333 node_newnode
(struct parser_params
*parser
, enum node_type type
, VALUE a0
, VALUE a1
, VALUE a2
)
7335 NODE
*n
= (rb_node_newnode
)(type
, a0
, a1
, a2
);
7336 nd_set_line
(n
, ruby_sourceline
);
7341 nodetype
(NODE
*node
) /* for debug */
7343 return
(enum node_type
)nd_type
(node
);
7347 nodeline
(NODE
*node
)
7349 return nd_line
(node
);
7353 newline_node
(NODE
*node
)
7356 node
= remove_begin
(node
);
7357 node
->flags |
= NODE_FL_NEWLINE
;
7363 fixpos
(NODE
*node
, NODE
*orig
)
7367 if
(orig
== (NODE
*)1) return
;
7368 nd_set_line
(node
, nd_line
(orig
));
7372 parser_warning
(struct parser_params
*parser
, NODE
*node
, const char *mesg
)
7374 rb_compile_warning
(ruby_sourcefile
, nd_line
(node
), "%s", mesg
);
7376 #define parser_warning(node, mesg) parser_warning(parser, node, mesg)
7379 parser_warn
(struct parser_params
*parser
, NODE
*node
, const char *mesg
)
7381 rb_compile_warn
(ruby_sourcefile
, nd_line
(node
), "%s", mesg
);
7383 #define parser_warn(node, mesg) parser_warn(parser, node, mesg)
7386 block_append_gen
(struct parser_params
*parser
, NODE
*head
, NODE
*tail
)
7388 NODE
*end
, *h
= head
, *nd
;
7390 if
(tail
== 0) return head
;
7392 if
(h
== 0) return tail
;
7393 switch
(nd_type
(h
)) {
7400 parser_warning
(h
, "unused literal ignored");
7403 h
= end
= NEW_BLOCK
(head
);
7414 switch
(nd_type
(nd
)) {
7420 if
(RTEST
(ruby_verbose
)) {
7421 parser_warning
(nd
, "statement not reached");
7429 if
(nd_type
(tail
) != NODE_BLOCK
) {
7430 tail
= NEW_BLOCK
(tail
);
7431 tail
->nd_end
= tail
;
7433 end
->nd_next
= tail
;
7434 h
->nd_end
= tail
->nd_end
;
7438 /* append item to the list */
7440 list_append_gen
(struct parser_params
*parser
, NODE
*list
, NODE
*item
)
7444 if
(list
== 0) return NEW_LIST
(item
);
7445 if
(list
->nd_next
) {
7446 last
= list
->nd_next
->nd_end
;
7453 last
->nd_next
= NEW_LIST
(item
);
7454 list
->nd_next
->nd_end
= last
->nd_next
;
7458 /* concat two lists */
7460 list_concat_gen
(struct parser_params
*parser
, NODE
*head
, NODE
*tail
)
7464 if
(head
->nd_next
) {
7465 last
= head
->nd_next
->nd_end
;
7471 head
->nd_alen
+= tail
->nd_alen
;
7472 last
->nd_next
= tail
;
7473 if
(tail
->nd_next
) {
7474 head
->nd_next
->nd_end
= tail
->nd_next
->nd_end
;
7477 head
->nd_next
->nd_end
= tail
;
7484 literal_concat0
(struct parser_params
*parser
, VALUE head
, VALUE tail
)
7486 if
(!rb_enc_compatible
(head
, tail
)) {
7487 compile_error
(PARSER_ARG
"string literal encodings differ (%s / %s)",
7488 rb_enc_name
(rb_enc_get
(head
)),
7489 rb_enc_name
(rb_enc_get
(tail
)));
7490 rb_str_resize
(head
, 0);
7491 rb_str_resize
(tail
, 0);
7494 rb_str_buf_append
(head
, tail
);
7498 /* concat two string literals */
7500 literal_concat_gen
(struct parser_params
*parser
, NODE
*head
, NODE
*tail
)
7502 enum node_type htype
;
7504 if
(!head
) return tail
;
7505 if
(!tail
) return head
;
7507 htype
= nd_type
(head
);
7508 if
(htype
== NODE_EVSTR
) {
7509 NODE
*node
= NEW_DSTR
(STR_NEW0
());
7510 head
= list_append
(node
, head
);
7512 switch
(nd_type
(tail
)) {
7514 if
(htype
== NODE_STR
) {
7515 if
(!literal_concat0
(parser
, head
->nd_lit
, tail
->nd_lit
)) {
7517 rb_gc_force_recycle
((VALUE
)head
);
7518 rb_gc_force_recycle
((VALUE
)tail
);
7521 rb_gc_force_recycle
((VALUE
)tail
);
7524 list_append
(head
, tail
);
7529 if
(htype
== NODE_STR
) {
7530 if
(!literal_concat0
(parser
, head
->nd_lit
, tail
->nd_lit
))
7532 tail
->nd_lit
= head
->nd_lit
;
7533 rb_gc_force_recycle
((VALUE
)head
);
7537 nd_set_type
(tail
, NODE_ARRAY
);
7538 tail
->nd_head
= NEW_STR
(tail
->nd_lit
);
7539 list_concat
(head
, tail
);
7544 if
(htype
== NODE_STR
) {
7545 nd_set_type
(head
, NODE_DSTR
);
7548 list_append
(head
, tail
);
7555 evstr2dstr_gen
(struct parser_params
*parser
, NODE
*node
)
7557 if
(nd_type
(node
) == NODE_EVSTR
) {
7558 node
= list_append
(NEW_DSTR
(STR_NEW0
()), node
);
7564 new_evstr_gen
(struct parser_params
*parser
, NODE
*node
)
7569 switch
(nd_type
(node
)) {
7570 case NODE_STR
: case NODE_DSTR
: case NODE_EVSTR
:
7574 return NEW_EVSTR
(head
);
7578 call_bin_op_gen
(struct parser_params
*parser
, NODE
*recv
, ID id
, NODE
*arg1
)
7582 return NEW_CALL
(recv
, id
, NEW_LIST
(arg1
));
7586 call_uni_op_gen
(struct parser_params
*parser
, NODE
*recv
, ID id
)
7589 return NEW_CALL
(recv
, id
, 0);
7593 match_op_gen
(struct parser_params
*parser
, NODE
*node1
, NODE
*node2
)
7598 switch
(nd_type
(node1
)) {
7600 case NODE_DREGX_ONCE
:
7601 return NEW_MATCH2
(node1
, node2
);
7604 if
(TYPE
(node1
->nd_lit
) == T_REGEXP
) {
7605 return NEW_MATCH2
(node1
, node2
);
7611 switch
(nd_type
(node2
)) {
7613 case NODE_DREGX_ONCE
:
7614 return NEW_MATCH3
(node2
, node1
);
7617 if
(TYPE
(node2
->nd_lit
) == T_REGEXP
) {
7618 return NEW_MATCH3
(node2
, node1
);
7623 return NEW_CALL
(node1
, tMATCH
, NEW_LIST
(node2
));
7627 gettable_gen
(struct parser_params
*parser
, ID id
)
7629 if
(id
== keyword_self
) {
7632 else if
(id
== keyword_nil
) {
7635 else if
(id
== keyword_true
) {
7638 else if
(id
== keyword_false
) {
7641 else if
(id
== keyword__FILE__
) {
7642 return NEW_STR
(STR_NEW2
(ruby_sourcefile
));
7644 else if
(id
== keyword__LINE__
) {
7645 return NEW_LIT
(INT2FIX
(ruby_sourceline
));
7647 else if
(id
== keyword__ENCODING__
) {
7648 return NEW_LIT
(rb_enc_from_encoding
(parser
->enc
));
7650 else if
(is_local_id
(id
)) {
7651 if
(dyna_in_block
() && dvar_defined
(id
)) return NEW_DVAR
(id
);
7652 if
(local_id
(id
)) return NEW_LVAR
(id
);
7653 /* method call without arguments */
7654 return NEW_VCALL
(id
);
7656 else if
(is_global_id
(id
)) {
7657 return NEW_GVAR
(id
);
7659 else if
(is_instance_id
(id
)) {
7660 return NEW_IVAR
(id
);
7662 else if
(is_const_id
(id
)) {
7663 return NEW_CONST
(id
);
7665 else if
(is_class_id
(id
)) {
7666 return NEW_CVAR
(id
);
7668 compile_error
(PARSER_ARG
"identifier %s is not valid to get", rb_id2name
(id
));
7673 assignable_gen
(struct parser_params
*parser
, ID id
, NODE
*val
)
7676 if
(id
== keyword_self
) {
7677 yyerror("Can't change the value of self");
7679 else if
(id
== keyword_nil
) {
7680 yyerror("Can't assign to nil");
7682 else if
(id
== keyword_true
) {
7683 yyerror("Can't assign to true");
7685 else if
(id
== keyword_false
) {
7686 yyerror("Can't assign to false");
7688 else if
(id
== keyword__FILE__
) {
7689 yyerror("Can't assign to __FILE__");
7691 else if
(id
== keyword__LINE__
) {
7692 yyerror("Can't assign to __LINE__");
7694 else if
(id
== keyword__ENCODING__
) {
7695 yyerror("Can't assign to __ENCODING__");
7697 else if
(is_local_id
(id
)) {
7698 if
(dyna_in_block
()) {
7699 if
(dvar_curr
(id
)) {
7700 return NEW_DASGN_CURR
(id
, val
);
7702 else if
(dvar_defined
(id
)) {
7703 return NEW_DASGN
(id
, val
);
7705 else if
(local_id
(id
)) {
7706 return NEW_LASGN
(id
, val
);
7710 return NEW_DASGN_CURR
(id
, val
);
7714 if
(!local_id
(id
)) {
7717 return NEW_LASGN
(id
, val
);
7720 else if
(is_global_id
(id
)) {
7721 return NEW_GASGN
(id
, val
);
7723 else if
(is_instance_id
(id
)) {
7724 return NEW_IASGN
(id
, val
);
7726 else if
(is_const_id
(id
)) {
7727 if
(in_def || in_single
)
7728 yyerror("dynamic constant assignment");
7729 return NEW_CDECL
(id
, val
, 0);
7731 else if
(is_class_id
(id
)) {
7732 return NEW_CVASGN
(id
, val
);
7735 compile_error
(PARSER_ARG
"identifier %s is not valid to set", rb_id2name
(id
));
7741 shadowing_lvar_gen
(struct parser_params
*parser
, ID name
)
7745 CONST_ID
(uscore
, "_");
7746 if
(uscore
== name
) return
;
7747 if
(dyna_in_block
()) {
7748 if
(dvar_curr
(name
)) {
7749 yyerror("duplicated argument name");
7751 else if
(dvar_defined
(name
) || local_id
(name
)) {
7752 rb_warningS
("shadowing outer local variable - %s", rb_id2name
(name
));
7753 vtable_add
(lvtbl
->vars
, name
);
7757 if
(local_id
(name
)) {
7758 yyerror("duplicated argument name");
7764 new_bv_gen
(struct parser_params
*parser
, ID name
)
7767 if
(!is_local_id
(name
)) {
7768 compile_error
(PARSER_ARG
"invalid local variable - %s",
7772 shadowing_lvar
(name
);
7777 aryset_gen
(struct parser_params
*parser
, NODE
*recv
, NODE
*idx
)
7779 if
(recv
&& nd_type
(recv
) == NODE_SELF
)
7781 return NEW_ATTRASGN
(recv
, tASET
, idx
);
7785 block_dup_check_gen
(struct parser_params
*parser
, NODE
*node1
, NODE
*node2
)
7787 if
(node2
&& node1
&& nd_type
(node1
) == NODE_BLOCK_PASS
) {
7788 compile_error
(PARSER_ARG
"both block arg and actual block given");
7793 rb_id_attrset
(ID id
)
7795 id
&= ~ID_SCOPE_MASK
;
7801 attrset_gen
(struct parser_params
*parser
, NODE
*recv
, ID id
)
7803 if
(recv
&& nd_type
(recv
) == NODE_SELF
)
7805 return NEW_ATTRASGN
(recv
, rb_id_attrset
(id
), 0);
7809 rb_backref_error_gen
(struct parser_params
*parser
, NODE
*node
)
7811 switch
(nd_type
(node
)) {
7813 compile_error
(PARSER_ARG
"Can't set variable $%ld", node
->nd_nth
);
7816 compile_error
(PARSER_ARG
"Can't set variable $%c", (int)node
->nd_nth
);
7822 arg_concat_gen
(struct parser_params
*parser
, NODE
*node1
, NODE
*node2
)
7824 if
(!node2
) return node1
;
7825 switch
(nd_type
(node1
)) {
7826 case NODE_BLOCK_PASS
:
7827 node1
->nd_iter
= arg_concat
(node1
->nd_iter
, node2
);
7830 if
(nd_type
(node2
) != NODE_ARRAY
) break
;
7831 node1
->nd_body
= list_concat
(NEW_LIST
(node1
->nd_body
), node2
);
7832 nd_set_type
(node1
, NODE_ARGSCAT
);
7835 if
(nd_type
(node2
) != NODE_ARRAY
) break
;
7836 node1
->nd_body
= list_concat
(node1
->nd_body
, node2
);
7839 return NEW_ARGSCAT
(node1
, node2
);
7843 arg_append_gen
(struct parser_params
*parser
, NODE
*node1
, NODE
*node2
)
7845 if
(!node1
) return NEW_LIST
(node2
);
7846 switch
(nd_type
(node1
)) {
7848 return list_append
(node1
, node2
);
7849 case NODE_BLOCK_PASS
:
7850 node1
->nd_head
= arg_append
(node1
->nd_head
, node2
);
7853 node1
->nd_body
= list_append
(NEW_LIST
(node1
->nd_body
), node2
);
7854 nd_set_type
(node1
, NODE_ARGSCAT
);
7857 return NEW_ARGSPUSH
(node1
, node2
);
7861 splat_array
(NODE
* node
)
7863 if
(nd_type
(node
) == NODE_SPLAT
) node
= node
->nd_head
;
7864 if
(nd_type
(node
) == NODE_ARRAY
) return node
;
7869 node_assign_gen
(struct parser_params
*parser
, NODE
*lhs
, NODE
*rhs
)
7873 switch
(nd_type
(lhs
)) {
7879 case NODE_DASGN_CURR
:
7883 lhs
->nd_value
= rhs
;
7888 lhs
->nd_args
= arg_append
(lhs
->nd_args
, rhs
);
7892 /* should not happen */
7900 value_expr_gen
(struct parser_params
*parser
, NODE
*node
)
7905 rb_warning0
("empty expression");
7908 switch
(nd_type
(node
)) {
7911 parser_warning
(node
, "void value expression");
7919 if
(!cond
) yyerror("void value expression");
7920 /* or "control never reach"? */
7924 while
(node
->nd_next
) {
7925 node
= node
->nd_next
;
7927 node
= node
->nd_head
;
7931 node
= node
->nd_body
;
7935 if
(!node
->nd_body
) {
7936 node
= node
->nd_else
;
7939 else if
(!node
->nd_else
) {
7940 node
= node
->nd_body
;
7943 if
(!value_expr
(node
->nd_body
)) return Qfalse
;
7944 node
= node
->nd_else
;
7950 node
= node
->nd_2nd
;
7962 void_expr_gen
(struct parser_params
*parser
, NODE
*node
)
7964 const char *useless
= 0;
7966 if
(!RTEST
(ruby_verbose
)) return
;
7969 switch
(nd_type
(node
)) {
7971 switch
(node
->nd_mid
) {
7990 useless
= rb_id2name
(node
->nd_mid
);
8002 useless
= "a variable";
8005 useless
= "a constant";
8011 case NODE_DREGX_ONCE
:
8012 useless
= "a literal";
8037 useless
= "defined?";
8042 int line
= ruby_sourceline
;
8044 ruby_sourceline
= nd_line
(node
);
8045 rb_warnS
("useless use of %s in void context", useless
);
8046 ruby_sourceline
= line
;
8051 void_stmts_gen
(struct parser_params
*parser
, NODE
*node
)
8053 if
(!RTEST
(ruby_verbose
)) return
;
8055 if
(nd_type
(node
) != NODE_BLOCK
) return
;
8058 if
(!node
->nd_next
) return
;
8059 void_expr0
(node
->nd_head
);
8060 node
= node
->nd_next
;
8065 remove_begin
(NODE
*node
)
8067 NODE
**n
= &node
, *n1
= node
;
8068 while
(n1
&& nd_type
(n1
) == NODE_BEGIN
&& n1
->nd_body
) {
8069 *n
= n1
= n1
->nd_body
;
8075 reduce_nodes_gen
(struct parser_params
*parser
, NODE
**body
)
8083 #define subnodes(n1, n2) \
8084 ((!node
->n1
) ?
(node
->n2 ?
(body
= &node
->n2
, 1) : 0) : \
8085 (!node
->n2
) ?
(body
= &node
->n1
, 1) : \
8086 (reduce_nodes
(&node
->n1
), body
= &node
->n2
, 1))
8089 switch
(nd_type
(node
)) {
8095 *body
= node
= node
->nd_stts
;
8098 *body
= node
= node
->nd_body
;
8101 body
= &node
->nd_end
->nd_head
;
8104 if
(subnodes
(nd_body
, nd_else
)) break
;
8107 body
= &node
->nd_body
;
8110 if
(!subnodes
(nd_body
, nd_next
)) goto end
;
8113 if
(!subnodes
(nd_head
, nd_resq
)) goto end
;
8116 if
(!subnodes
(nd_head
, nd_resq
)) goto end
;
8128 assign_in_cond
(struct parser_params
*parser
, NODE
*node
)
8130 switch
(nd_type
(node
)) {
8132 yyerror("multiple assignment in conditional");
8145 switch
(nd_type
(node
->nd_value
)) {
8151 /* reports always */
8152 parser_warn
(node
->nd_value
, "found = in conditional, should be ==");
8167 warn_unless_e_option
(struct parser_params
*parser
, NODE
*node
, const char *str
)
8169 if
(!e_option_supplied
(parser
)) parser_warn
(node
, str
);
8173 warning_unless_e_option
(struct parser_params
*parser
, NODE
*node
, const char *str
)
8175 if
(!e_option_supplied
(parser
)) parser_warning
(node
, str
);
8179 fixup_nodes
(NODE
**rootnode
)
8181 NODE
*node
, *next
, *head
;
8183 for
(node
= *rootnode
; node
; node
= next
) {
8184 enum node_type type
;
8187 next
= node
->nd_next
;
8188 head
= node
->nd_head
;
8189 rb_gc_force_recycle
((VALUE
)node
);
8191 switch
(type
= nd_type
(head
)) {
8194 val
= rb_range_new
(head
->nd_beg
->nd_lit
, head
->nd_end
->nd_lit
,
8195 type
== NODE_DOT3 ? Qtrue
: Qfalse
);
8196 rb_gc_force_recycle
((VALUE
)head
->nd_beg
);
8197 rb_gc_force_recycle
((VALUE
)head
->nd_end
);
8198 nd_set_type
(head
, NODE_LIT
);
8207 static NODE
*cond0
(struct parser_params
*,NODE
*);
8210 range_op
(struct parser_params
*parser
, NODE
*node
)
8212 enum node_type type
;
8214 if
(node
== 0) return
0;
8216 type
= nd_type
(node
);
8218 if
(type
== NODE_LIT
&& FIXNUM_P
(node
->nd_lit
)) {
8219 warn_unless_e_option
(parser
, node
, "integer literal in conditional range");
8220 return NEW_CALL
(node
, tEQ
, NEW_LIST
(NEW_GVAR
(rb_intern
("$."))));
8222 return cond0
(parser
, node
);
8226 literal_node
(NODE
*node
)
8228 if
(!node
) return
1; /* same as NODE_NIL */
8229 switch
(nd_type
(node
)) {
8235 case NODE_DREGX_ONCE
:
8247 cond0
(struct parser_params
*parser
, NODE
*node
)
8249 if
(node
== 0) return
0;
8250 assign_in_cond
(parser
, node
);
8252 switch
(nd_type
(node
)) {
8256 rb_warn0
("string literal in condition");
8260 case NODE_DREGX_ONCE
:
8261 warning_unless_e_option
(parser
, node
, "regex literal in condition");
8262 return NEW_MATCH2
(node
, NEW_GVAR
(rb_intern
("$_")));
8266 node
->nd_1st
= cond0
(parser
, node
->nd_1st
);
8267 node
->nd_2nd
= cond0
(parser
, node
->nd_2nd
);
8272 node
->nd_beg
= range_op
(parser
, node
->nd_beg
);
8273 node
->nd_end
= range_op
(parser
, node
->nd_end
);
8274 if
(nd_type
(node
) == NODE_DOT2
) nd_set_type
(node
,NODE_FLIP2
);
8275 else if
(nd_type
(node
) == NODE_DOT3
) nd_set_type
(node
, NODE_FLIP3
);
8276 if
(!e_option_supplied
(parser
)) {
8277 int b
= literal_node
(node
->nd_beg
);
8278 int e
= literal_node
(node
->nd_end
);
8279 if
((b
== 1 && e
== 1) ||
(b
+ e
>= 2 && RTEST
(ruby_verbose
))) {
8280 parser_warn
(node
, "range literal in condition");
8286 parser_warning
(node
, "literal in condition");
8290 if
(TYPE
(node
->nd_lit
) == T_REGEXP
) {
8291 warn_unless_e_option
(parser
, node
, "regex literal in condition");
8292 nd_set_type
(node
, NODE_MATCH
);
8295 parser_warning
(node
, "literal in condition");
8304 cond_gen
(struct parser_params
*parser
, NODE
*node
)
8306 if
(node
== 0) return
0;
8307 return cond0
(parser
, node
);
8311 logop_gen
(struct parser_params
*parser
, enum node_type type
, NODE
*left
, NODE
*right
)
8314 if
(left
&& nd_type
(left
) == type
) {
8315 NODE
*node
= left
, *second
;
8316 while
((second
= node
->nd_2nd
) != 0 && nd_type
(second
) == type
) {
8319 node
->nd_2nd
= NEW_NODE
(type
, second
, right
, 0);
8322 return NEW_NODE
(type
, left
, right
, 0);
8326 no_blockarg
(struct parser_params
*parser
, NODE
*node
)
8328 if
(node
&& nd_type
(node
) == NODE_BLOCK_PASS
) {
8329 compile_error
(PARSER_ARG
"block argument should not be given");
8334 ret_args_gen
(struct parser_params
*parser
, NODE
*node
)
8337 no_blockarg
(parser
, node
);
8338 if
(nd_type
(node
) == NODE_ARRAY
) {
8339 if
(node
->nd_next
== 0) {
8340 node
= node
->nd_head
;
8343 nd_set_type
(node
, NODE_VALUES
);
8351 new_yield_gen
(struct parser_params
*parser
, NODE
*node
)
8356 no_blockarg
(parser
, node
);
8357 if
(node
&& nd_type
(node
) == NODE_SPLAT
) {
8364 return NEW_YIELD
(node
, state
);
8368 negate_lit
(NODE
*node
)
8370 switch
(TYPE
(node
->nd_lit
)) {
8372 node
->nd_lit
= LONG2FIX
(-FIX2LONG
(node
->nd_lit
));
8375 node
->nd_lit
= rb_funcall
(node
->nd_lit
,tUMINUS
,0,0);
8378 RFLOAT
(node
->nd_lit
)->float_value
= -RFLOAT_VALUE
(node
->nd_lit
);
8387 arg_blk_pass
(NODE
*node1
, NODE
*node2
)
8390 node2
->nd_head
= node1
;
8397 new_args_gen
(struct parser_params
*parser
, NODE
*m
, NODE
*o
, ID r
, NODE
*p
, ID b
)
8399 int saved_line
= ruby_sourceline
;
8403 node
= NEW_ARGS
(m ? m
->nd_plen
: 0, o
);
8404 i1
= m ? m
->nd_next
: 0;
8405 node
->nd_next
= NEW_ARGS_AUX
(r
, b
);
8409 node
->nd_next
->nd_next
= NEW_ARGS_AUX
(p
->nd_pid
, p
->nd_plen
);
8412 node
->nd_next
->nd_next
= NEW_ARGS_AUX
(0, 0);
8415 node
->nd_next
->nd_next
->nd_next
= NEW_NODE
(NODE_AND
, i1
, i2
, 0);
8417 ruby_sourceline
= saved_line
;
8422 local_push_gen
(struct parser_params
*parser
, int inherit_dvars
)
8424 struct local_vars
*local
;
8426 local
= ALLOC
(struct local_vars
);
8427 local
->prev
= lvtbl
;
8428 local
->args
= vtable_alloc
(0);
8429 local
->vars
= vtable_alloc
(inherit_dvars ? DVARS_INHERIT
: DVARS_TOPSCOPE
);
8434 local_pop_gen
(struct parser_params
*parser
)
8436 struct local_vars
*local
= lvtbl
->prev
;
8437 vtable_free
(lvtbl
->args
);
8438 vtable_free
(lvtbl
->vars
);
8444 vtable_tblcpy
(ID
*buf
, const struct vtable
*src
)
8446 int i
, cnt
= vtable_size
(src
);
8450 for
(i
= 0; i
< cnt
; i
++) {
8451 buf
[i
] = src
->tbl
[i
];
8459 local_tbl_gen
(struct parser_params
*parser
)
8461 int cnt
= vtable_size
(lvtbl
->args
) + vtable_size
(lvtbl
->vars
);
8464 if
(cnt
<= 0) return
0;
8465 buf
= ALLOC_N
(ID
, cnt
+ 1);
8466 vtable_tblcpy
(buf
+1, lvtbl
->args
);
8467 vtable_tblcpy
(buf
+vtable_size
(lvtbl
->args
)+1, lvtbl
->vars
);
8474 arg_var_gen
(struct parser_params
*parser
, ID id
)
8476 vtable_add
(lvtbl
->args
, id
);
8477 return vtable_size
(lvtbl
->args
) - 1;
8481 local_var_gen
(struct parser_params
*parser
, ID id
)
8483 vtable_add
(lvtbl
->vars
, id
);
8484 return vtable_size
(lvtbl
->vars
) - 1;
8488 local_id_gen
(struct parser_params
*parser
, ID id
)
8490 struct vtable
*vars
, *args
;
8495 while
(vars
&& POINTER_P
(vars
->prev
)) {
8500 if
(vars
&& vars
->prev
== DVARS_INHERIT
) {
8501 return rb_local_defined
(id
);
8504 return
(vtable_included
(args
, id
) ||
8505 vtable_included
(vars
, id
));
8510 dyna_push_gen
(struct parser_params
*parser
)
8512 lvtbl
->args
= vtable_alloc
(lvtbl
->args
);
8513 lvtbl
->vars
= vtable_alloc
(lvtbl
->vars
);
8517 dyna_pop_gen
(struct parser_params
*parser
)
8522 lvtbl
->args
= lvtbl
->args
->prev
;
8525 lvtbl
->vars
= lvtbl
->vars
->prev
;
8530 dyna_in_block_gen
(struct parser_params
*parser
)
8532 return POINTER_P
(lvtbl
->vars
) && lvtbl
->vars
->prev
!= DVARS_TOPSCOPE
;
8536 dvar_defined_gen
(struct parser_params
*parser
, ID id
)
8538 struct vtable
*vars
, *args
;
8543 while
(POINTER_P
(vars
)) {
8544 if
(vtable_included
(args
, id
)) {
8547 if
(vtable_included
(vars
, id
)) {
8554 if
(vars
== DVARS_INHERIT
) {
8555 return rb_dvar_defined
(id
);
8562 dvar_curr_gen
(struct parser_params
*parser
, ID id
)
8564 return
(vtable_included
(lvtbl
->args
, id
) ||
8565 vtable_included
(lvtbl
->vars
, id
));
8568 VALUE rb_reg_compile
(VALUE str
, int options
);
8569 VALUE rb_reg_check_preprocess
(VALUE
);
8572 reg_fragment_setenc_gen
(struct parser_params
* parser
, VALUE str
, int options
)
8574 int c
= RE_OPTION_ENCODING_IDX
(options
);
8578 rb_char_to_option_kcode
(c
, &opt
, &idx
);
8579 if
(idx
!= ENCODING_GET
(str
) &&
8580 rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
8583 ENCODING_SET
(str
, idx
);
8585 else if
(RE_OPTION_ENCODING_NONE
(options
)) {
8586 if
(!ENCODING_IS_ASCII8BIT
(str
) &&
8587 rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
8591 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
8593 else if
(parser
->enc
== rb_usascii_encoding
()) {
8594 if
(rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
8596 rb_enc_associate
(str
, rb_usascii_encoding
());
8599 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
8605 compile_error
(PARSER_ARG
8606 "regexp encoding option '%c' differs from source encoding '%s'",
8607 c
, rb_enc_name
(rb_enc_get
(str
)));
8611 reg_fragment_check_gen
(struct parser_params
* parser
, VALUE str
, int options
)
8614 reg_fragment_setenc_gen
(parser
, str
, options
);
8615 err
= rb_reg_check_preprocess
(str
);
8617 err
= rb_obj_as_string
(err
);
8618 compile_error
(PARSER_ARG
"%s", RSTRING_PTR
(err
));
8624 struct parser_params
* parser
;
8629 } reg_named_capture_assign_t
;
8632 reg_named_capture_assign_iter
(const OnigUChar
*name
, const OnigUChar
*name_end
,
8633 int back_num
, int *back_refs
, OnigRegex regex
, void *arg0
)
8635 reg_named_capture_assign_t
*arg
= (reg_named_capture_assign_t
*)arg0
;
8636 struct parser_params
* parser
= arg
->parser
;
8637 rb_encoding
*enc
= arg
->enc
;
8638 int len
= name_end
- name
;
8639 const char *s
= (const char *)name
;
8644 if
(arg
->succ_block
== 0) {
8645 arg
->succ_block
= NEW_BEGIN
(0);
8646 arg
->fail_block
= NEW_BEGIN
(0);
8649 if
(!len ||
(*name
!= '_' && ISASCII
(*name
) && !rb_enc_islower
(*name
, enc
)) ||
8650 rb_reserved_word
(s
, len
) ||
!rb_enc_symname2_p
(s
, len
, enc
)) {
8653 var
= rb_intern3
(s
, len
, enc
);
8654 if
(dvar_defined
(var
) || local_id
(var
)) {
8655 rb_warningS
("named capture conflicts a local variable - %s",
8658 arg
->succ_block
= block_append
(arg
->succ_block
,
8659 newline_node
(node_assign
(assignable
(var
,0),
8661 gettable
(rb_intern
("$~")),
8663 NEW_LIST
(NEW_LIT
(ID2SYM
(var
))))
8665 arg
->fail_block
= block_append
(arg
->fail_block
,
8666 newline_node
(node_assign
(assignable
(var
,0), NEW_LIT
(Qnil
))));
8671 reg_named_capture_assign_gen
(struct parser_params
* parser
, VALUE regexp
, NODE
*match
)
8673 reg_named_capture_assign_t arg
;
8675 arg.parser
= parser
;
8676 arg.enc
= rb_enc_get
(regexp
);
8680 onig_foreach_name
(RREGEXP
(regexp
)->ptr
, reg_named_capture_assign_iter
, (void*)&arg
);
8687 newline_node
(match
),
8688 NEW_IF
(gettable
(rb_intern
("$~")),
8690 newline_node
(arg.succ_block
),
8693 gettable
(rb_intern
("$~")),
8695 NEW_LIST
(NEW_LIT
(INT2FIX
(0)))))),
8697 newline_node
(arg.fail_block
),
8703 reg_compile_gen
(struct parser_params
* parser
, VALUE str
, int options
)
8708 reg_fragment_setenc
(str
, options
);
8710 re
= rb_reg_compile
(str
, options
& RE_OPTION_MASK
);
8712 ID mesg
= rb_intern
("mesg");
8713 VALUE m
= rb_attr_get
(rb_errinfo
(), mesg
);
8714 rb_set_errinfo
(err
);
8716 rb_str_append
(rb_str_cat
(rb_attr_get
(err
, mesg
), "\n", 1), m
);
8719 compile_error
(PARSER_ARG
"%s", RSTRING_PTR
(m
));
8727 rb_gc_mark_parser
(void)
8732 rb_parser_append_print
(VALUE vparser
, NODE
*node
)
8736 struct parser_params
*parser
;
8738 if
(!node
) return node
;
8740 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
8742 node
= node
->nd_body
;
8744 if
(nd_type
(node
) == NODE_PRELUDE
) {
8746 node
= node
->nd_body
;
8749 node
= block_append
(node
,
8750 NEW_FCALL
(rb_intern
("print"),
8751 NEW_ARRAY
(NEW_GVAR
(rb_intern
("$_")))));
8753 prelude
->nd_body
= node
;
8754 scope
->nd_body
= prelude
;
8757 scope
->nd_body
= node
;
8764 rb_parser_while_loop
(VALUE vparser
, NODE
*node
, int chop
, int split
)
8768 struct parser_params
*parser
;
8770 if
(!node
) return node
;
8772 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
8774 node
= node
->nd_body
;
8776 if
(nd_type
(node
) == NODE_PRELUDE
) {
8778 node
= node
->nd_body
;
8781 node
= block_append
(NEW_GASGN
(rb_intern
("$F"),
8782 NEW_CALL
(NEW_GVAR
(rb_intern
("$_")),
8783 rb_intern
("split"), 0)),
8787 node
= block_append
(NEW_CALL
(NEW_GVAR
(rb_intern
("$_")),
8788 rb_intern
("chop!"), 0), node
);
8791 node
= NEW_OPT_N
(node
);
8794 prelude
->nd_body
= node
;
8795 scope
->nd_body
= prelude
;
8798 scope
->nd_body
= node
;
8804 static const struct {
8830 #define op_tbl_count (sizeof(op_tbl) / sizeof(op_tbl[0]))
8832 static struct symbols
{
8838 VALUE op_sym
[tLAST_TOKEN
];
8839 } global_symbols
= {tLAST_ID
};
8841 static const struct st_hash_type symhash
= {
8852 ivar2_cmp
(struct ivar2_key
*key1
, struct ivar2_key
*key2
)
8854 if
(key1
->id
== key2
->id
&& key1
->klass
== key2
->klass
) {
8861 ivar2_hash
(struct ivar2_key
*key
)
8863 return
(key
->id
<< 8) ^
(key
->klass
>> 2);
8866 static const struct st_hash_type ivar2_hash_type
= {
8874 global_symbols.sym_id
= st_init_table_with_size
(&symhash
, 1000);
8875 global_symbols.id_str
= st_init_numtable_with_size
(1000);
8876 global_symbols.ivar2_id
= st_init_table_with_size
(&ivar2_hash_type
, 1000);
8877 global_symbols.id_ivar2
= st_init_numtable_with_size
(1000);
8883 rb_gc_mark_symbols
(void)
8885 rb_mark_tbl
(global_symbols.id_str
);
8886 rb_gc_mark_locations
(global_symbols.op_sym
,
8887 global_symbols.op_sym
+ tLAST_TOKEN
);
8891 internal_id_gen
(struct parser_params
*parser
)
8893 ID id
= (ID
)vtable_size
(lvtbl
->args
) + (ID
)vtable_size
(lvtbl
->vars
);
8894 id
+= ((tLAST_TOKEN
- ID_INTERNAL
) >> ID_SCOPE_SHIFT
) + 1;
8895 return ID_INTERNAL |
(id
<< ID_SCOPE_SHIFT
);
8899 is_special_global_name
(const char *m
, const char *e
, rb_encoding
*enc
)
8903 if
(m
>= e
) return
0;
8905 case
'~': case
'*': case
'$': case
'?': case
'!': case
'@':
8906 case
'/': case
'\\': case
';': case
',': case
'.': case
'=':
8907 case
':': case
'<': case
'>': case
'\"':
8908 case
'&': case
'`': case
'\'': case
'+':
8914 if
(m
< e
&& is_identchar
(m
, e
, enc
)) {
8915 if
(!ISASCII
(*m
)) mb
= 1;
8916 m
+= rb_enc_mbclen
(m
, e
, enc
);
8920 if
(!rb_enc_isdigit
(*m
, enc
)) return
0;
8922 if
(!ISASCII
(*m
)) mb
= 1;
8924 } while
(rb_enc_isdigit
(*m
, enc
));
8926 return m
== e ? mb
+ 1 : 0;
8930 rb_symname_p
(const char *name
)
8932 return rb_enc_symname_p
(name
, rb_ascii8bit_encoding
());
8936 rb_enc_symname_p
(const char *name
, rb_encoding
*enc
)
8938 return rb_enc_symname2_p
(name
, strlen
(name
), enc
);
8942 rb_enc_symname2_p
(const char *name
, int len
, rb_encoding
*enc
)
8944 const char *m
= name
;
8945 const char *e
= m
+ len
;
8946 int localid
= Qfalse
;
8948 if
(!m
) return Qfalse
;
8954 if
(is_special_global_name
(++m
, e
, enc
)) return Qtrue
;
8958 if
(*++m
== '@') ++m
;
8963 case
'<': ++m
; break
;
8964 case
'=': if
(*++m
== '>') ++m
; break
;
8971 case
'>': case
'=': ++m
; break
;
8977 case
'~': ++m
; break
;
8978 case
'=': if
(*++m
== '=') ++m
; break
;
8979 default
: return Qfalse
;
8984 if
(*++m
== '*') ++m
;
8988 if
(*++m
== '@') ++m
;
8991 case
'|': case
'^': case
'&': case
'/': case
'%': case
'~': case
'`':
8996 if
(*++m
!= ']') return Qfalse
;
8997 if
(*++m
== '=') ++m
;
9002 case
'\0': return Qtrue
;
9003 case
'=': case
'~': ++m
; break
;
9004 default
: return Qfalse
;
9009 localid
= !rb_enc_isupper
(*m
, enc
);
9011 if
(m
>= e ||
(*m
!= '_' && !rb_enc_isalpha
(*m
, enc
) && ISASCII
(*m
)))
9013 while
(m
< e
&& is_identchar
(m
, e
, enc
)) m
+= rb_enc_mbclen
(m
, e
, enc
);
9016 case
'!': case
'?': case
'=': ++m
;
9021 return
*m ? Qfalse
: Qtrue
;
9025 register_symid
(ID id
, const char *name
, long len
, rb_encoding
*enc
)
9027 VALUE str
= rb_enc_str_new
(name
, len
, enc
);
9029 st_add_direct
(global_symbols.sym_id
, (st_data_t
)str
, id
);
9030 st_add_direct
(global_symbols.id_str
, id
, (st_data_t
)str
);
9035 rb_intern3
(const char *name
, long len
, rb_encoding
*enc
)
9037 const char *m
= name
;
9038 const char *e
= m
+ len
;
9044 struct RString fake_str
;
9045 fake_str.basic.flags
= T_STRING|RSTRING_NOEMBED|FL_FREEZE
;
9046 fake_str.basic.klass
= rb_cString
;
9047 fake_str.as.heap.len
= len
;
9048 fake_str.as.heap.ptr
= (char *)name
;
9049 fake_str.as.heap.aux.capa
= len
;
9050 str
= (VALUE
)&fake_str
;
9051 rb_enc_associate
(str
, enc
);
9053 if
(st_lookup
(global_symbols.sym_id
, str
, (st_data_t
*)&id
))
9056 if
(rb_cString
&& !rb_enc_asciicompat
(enc
)) {
9065 if
((mb
= is_special_global_name
(++m
, e
, enc
)) != 0) {
9066 if
(!--mb
) enc
= rb_ascii8bit_encoding
();
9082 if
(c
!= '_' && rb_enc_isascii
(c
, enc
) && rb_enc_ispunct
(c
, enc
)) {
9090 for
(i
= 0; i
< op_tbl_count
; i
++) {
9091 if
(*op_tbl
[i
].name
== *m
&&
9092 strcmp
(op_tbl
[i
].name
, m
) == 0) {
9093 id
= op_tbl
[i
].token
;
9099 if
(m
[last
] == '=') {
9100 /* attribute assignment */
9101 id
= rb_intern3
(name
, last
, enc
);
9102 if
(id
> tLAST_TOKEN
&& !is_attrset_id
(id
)) {
9103 enc
= rb_enc_get
(rb_id2str
(id
));
9104 id
= rb_id_attrset
(id
);
9109 else if
(rb_enc_isupper
(m
[0], enc
)) {
9118 if
(!rb_enc_isdigit
(*m
, enc
)) {
9119 while
(m
<= name
+ last
&& is_identchar
(m
, e
, enc
)) {
9125 m
+= rb_enc_mbclen
(m
, e
, enc
);
9129 if
(m
- name
< len
) id
= ID_JUNK
;
9130 if
(enc
!= rb_usascii_encoding
()) {
9132 * this clause makes sense only when called from other than
9133 * rb_intern_str() taking care of code-range.
9136 for
(; m
<= name
+ len
; ++m
) {
9137 if
(!ISASCII
(*m
)) goto mbstr
;
9139 enc
= rb_usascii_encoding
();
9144 id |
= ++global_symbols.last_id
<< ID_SCOPE_SHIFT
;
9146 return register_symid
(id
, name
, len
, enc
);
9150 rb_intern2
(const char *name
, long len
)
9152 return rb_intern3
(name
, len
, rb_usascii_encoding
());
9157 rb_intern
(const char *name
)
9159 return rb_intern2
(name
, strlen
(name
));
9163 rb_intern_str
(VALUE str
)
9168 if
(rb_enc_str_coderange
(str
) == ENC_CODERANGE_7BIT
) {
9169 enc
= rb_usascii_encoding
();
9172 enc
= rb_enc_get
(str
);
9174 id
= rb_intern3
(RSTRING_PTR
(str
), RSTRING_LEN
(str
), enc
);
9184 if
(id
< tLAST_TOKEN
) {
9187 if
(rb_ispunct
(id
)) {
9188 VALUE str
= global_symbols.op_sym
[i
= (int)id
];
9193 str
= rb_usascii_str_new
(name
, 1);
9195 global_symbols.op_sym
[i
] = str
;
9199 for
(i
= 0; i
< op_tbl_count
; i
++) {
9200 if
(op_tbl
[i
].token
== id
) {
9201 VALUE str
= global_symbols.op_sym
[i
];
9203 str
= rb_usascii_str_new2
(op_tbl
[i
].name
);
9205 global_symbols.op_sym
[i
] = str
;
9212 if
(st_lookup
(global_symbols.id_str
, id
, &data
)) {
9213 VALUE str
= (VALUE
)data
;
9214 if
(RBASIC
(str
)->klass
== 0)
9215 RBASIC
(str
)->klass
= rb_cString
;
9219 if
(is_attrset_id
(id
)) {
9220 ID id2
= (id
& ~ID_SCOPE_MASK
) | ID_LOCAL
;
9223 while
(!(str
= rb_id2str
(id2
))) {
9224 if
(!is_local_id
(id2
)) return
0;
9225 id2
= (id
& ~ID_SCOPE_MASK
) | ID_CONST
;
9227 str
= rb_str_dup
(str
);
9228 rb_str_cat
(str
, "=", 1);
9230 if
(st_lookup
(global_symbols.id_str
, id
, &data
)) {
9231 VALUE str
= (VALUE
)data
;
9232 if
(RBASIC
(str
)->klass
== 0)
9233 RBASIC
(str
)->klass
= rb_cString
;
9243 VALUE str
= rb_id2str
(id
);
9246 return RSTRING_PTR
(str
);
9250 symbols_i
(VALUE sym
, ID value
, VALUE ary
)
9252 rb_ary_push
(ary
, ID2SYM
(value
));
9258 * Symbol.all_symbols => array
9260 * Returns an array of all the symbols currently in Ruby's symbol
9263 * Symbol.all_symbols.size #=> 903
9264 * Symbol.all_symbols[1,20] #=> [:floor, :ARGV, :Binding, :symlink,
9265 * :chown, :EOFError, :$;, :String,
9266 * :LOCK_SH, :"setuid?", :$<,
9267 * :default_proc, :compact, :extend,
9268 * :Tms, :getwd, :$=, :ThreadGroup,
9273 rb_sym_all_symbols
(void)
9275 VALUE ary
= rb_ary_new2
(global_symbols.sym_id
->num_entries
);
9277 st_foreach
(global_symbols.sym_id
, symbols_i
, ary
);
9282 rb_is_const_id
(ID id
)
9284 if
(is_const_id
(id
)) return Qtrue
;
9289 rb_is_class_id
(ID id
)
9291 if
(is_class_id
(id
)) return Qtrue
;
9296 rb_is_instance_id
(ID id
)
9298 if
(is_instance_id
(id
)) return Qtrue
;
9303 rb_is_local_id
(ID id
)
9305 if
(is_local_id
(id
)) return Qtrue
;
9310 rb_is_junk_id
(ID id
)
9312 if
(is_junk_id
(id
)) return Qtrue
;
9316 #endif /* !RIPPER */
9319 parser_initialize
(struct parser_params
*parser
)
9321 parser
->eofp
= Qfalse
;
9323 parser
->parser_lex_strterm
= 0;
9324 parser
->parser_cond_stack
= 0;
9325 parser
->parser_cmdarg_stack
= 0;
9326 parser
->parser_class_nest
= 0;
9327 parser
->parser_paren_nest
= 0;
9328 parser
->parser_lpar_beg
= 0;
9329 parser
->parser_in_single
= 0;
9330 parser
->parser_in_def
= 0;
9331 parser
->parser_in_defined
= 0;
9332 parser
->parser_compile_for_eval
= 0;
9333 parser
->parser_cur_mid
= 0;
9334 parser
->parser_tokenbuf
= NULL
;
9335 parser
->parser_tokidx
= 0;
9336 parser
->parser_toksiz
= 0;
9337 parser
->parser_heredoc_end
= 0;
9338 parser
->parser_command_start
= Qtrue
;
9339 parser
->parser_deferred_nodes
= 0;
9340 parser
->parser_lex_pbeg
= 0;
9341 parser
->parser_lex_p
= 0;
9342 parser
->parser_lex_pend
= 0;
9343 parser
->parser_lvtbl
= 0;
9344 parser
->parser_ruby__end__seen
= 0;
9345 parser
->parser_ruby_sourcefile
= 0;
9347 parser
->is_ripper
= 0;
9348 parser
->parser_eval_tree_begin
= 0;
9349 parser
->parser_eval_tree
= 0;
9351 parser
->is_ripper
= 1;
9352 parser
->parser_ruby_sourcefile_string
= Qnil
;
9353 parser
->delayed
= Qnil
;
9355 parser
->result
= Qnil
;
9356 parser
->parsing_thread
= Qnil
;
9357 parser
->toplevel_p
= Qtrue
;
9360 parser
->heap
= NULL
;
9362 parser
->enc
= rb_usascii_encoding
();
9366 #define parser_mark ripper_parser_mark
9367 #define parser_free ripper_parser_free
9371 parser_mark
(void *ptr
)
9373 struct parser_params
*p
= (struct parser_params
*)ptr
;
9375 rb_gc_mark
((VALUE
)p
->parser_lex_strterm
);
9376 rb_gc_mark
((VALUE
)p
->parser_deferred_nodes
);
9377 rb_gc_mark
(p
->parser_lex_input
);
9378 rb_gc_mark
(p
->parser_lex_lastline
);
9379 rb_gc_mark
(p
->parser_lex_nextline
);
9381 rb_gc_mark
((VALUE
)p
->parser_eval_tree_begin
) ;
9382 rb_gc_mark
((VALUE
)p
->parser_eval_tree
) ;
9383 rb_gc_mark
(p
->debug_lines
);
9385 rb_gc_mark
(p
->parser_ruby_sourcefile_string
);
9386 rb_gc_mark
(p
->delayed
);
9387 rb_gc_mark
(p
->value
);
9388 rb_gc_mark
(p
->result
);
9389 rb_gc_mark
(p
->parsing_thread
);
9392 rb_gc_mark
((VALUE
)p
->heap
);
9397 parser_free
(void *ptr
)
9399 struct parser_params
*p
= (struct parser_params
*)ptr
;
9400 struct local_vars
*local
, *prev
;
9402 if
(p
->parser_tokenbuf
) {
9403 xfree
(p
->parser_tokenbuf
);
9405 for
(local
= p
->parser_lvtbl
; local
; local
= prev
) {
9406 if
(local
->vars
) xfree
(local
->vars
);
9411 xfree
(p
->parser_ruby_sourcefile
);
9416 VALUE rb_parser_get_yydebug
(VALUE
);
9417 VALUE rb_parser_set_yydebug
(VALUE
, VALUE
);
9420 static struct parser_params
*
9423 struct parser_params
*p
;
9425 p
= ALLOC_N
(struct parser_params
, 1);
9426 MEMZERO
(p
, struct parser_params
, 1);
9427 parser_initialize
(p
);
9434 struct parser_params
*p
= parser_new
();
9436 return Data_Wrap_Struct
(0, parser_mark
, parser_free
, p
);
9441 * ripper#end_seen? -> Boolean
9443 * Return if parsed source ended by +\_\_END\_\_+.
9444 * This number starts from 1.
9447 rb_parser_end_seen_p
(VALUE vparser
)
9449 struct parser_params
*parser
;
9451 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
9452 return ruby__end__seen ? Qtrue
: Qfalse
;
9457 * ripper#encoding -> encoding
9459 * Return encoding of the source.
9462 rb_parser_encoding
(VALUE vparser
)
9464 struct parser_params
*parser
;
9466 Data_Get_Struct
(vparser
, struct parser_params
, parser
);
9467 return rb_enc_from_encoding
(parser
->enc
);
9472 * ripper.yydebug -> true or false
9477 rb_parser_get_yydebug
(VALUE self
)
9479 struct parser_params
*parser
;
9481 Data_Get_Struct
(self
, struct parser_params
, parser
);
9482 return
yydebug ? Qtrue
: Qfalse
;
9487 * ripper.yydebug = flag
9492 rb_parser_set_yydebug
(VALUE self
, VALUE flag
)
9494 struct parser_params
*parser
;
9496 Data_Get_Struct
(self
, struct parser_params
, parser
);
9497 yydebug = RTEST
(flag
);
9502 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
9503 #define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
9504 #define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
9505 (n
)->u3.cnt
= (c
), (p
))
9508 rb_parser_malloc
(struct parser_params
*parser
, size_t size
)
9510 size_t cnt
= HEAPCNT
(1, size
);
9511 NODE
*n
= NEWHEAP
();
9512 void *ptr
= xmalloc
(size
);
9514 return ADD2HEAP
(n
, cnt
, ptr
);
9518 rb_parser_calloc
(struct parser_params
*parser
, size_t nelem
, size_t size
)
9520 size_t cnt
= HEAPCNT
(nelem
, size
);
9521 NODE
*n
= NEWHEAP
();
9522 void *ptr
= xcalloc
(nelem
, size
);
9524 return ADD2HEAP
(n
, cnt
, ptr
);
9528 rb_parser_realloc
(struct parser_params
*parser
, void *ptr
, size_t size
)
9531 size_t cnt
= HEAPCNT
(1, size
);
9533 if
(ptr
&& (n
= parser
->heap
) != NULL
) {
9535 if
(n
->u1.node
== ptr
) {
9536 n
->u1.node
= ptr
= xrealloc
(ptr
, size
);
9537 if
(n
->u3.cnt
) n
->u3.cnt
= cnt
;
9540 } while
((n
= n
->u2.node
) != NULL
);
9543 ptr
= xrealloc
(ptr
, size
);
9544 return ADD2HEAP
(n
, cnt
, ptr
);
9548 rb_parser_free
(struct parser_params
*parser
, void *ptr
)
9550 NODE
**prev
= &parser
->heap
, *n
;
9552 while
((n
= *prev
) != NULL
) {
9553 if
(n
->u1.node
== ptr
) {
9555 rb_gc_force_recycle
((VALUE
)n
);
9567 extern
int rb_is_pointer_to_heap
(VALUE
);
9571 ripper_validate_object
(VALUE self
, VALUE x
)
9573 if
(x
== Qfalse
) return x
;
9574 if
(x
== Qtrue
) return x
;
9575 if
(x
== Qnil
) return x
;
9577 rb_raise
(rb_eArgError
, "Qundef given");
9578 if
(FIXNUM_P
(x
)) return x
;
9579 if
(SYMBOL_P
(x
)) return x
;
9580 if
(!rb_is_pointer_to_heap
(x
))
9581 rb_raise
(rb_eArgError
, "invalid pointer: %p", x
);
9590 rb_raise
(rb_eArgError
, "NODE given: %p", x
);
9592 rb_raise
(rb_eArgError
, "wrong type of ruby object: %p (%s)",
9593 x
, rb_obj_classname
(x
));
9602 ripper_dispatch0
(struct parser_params
*parser
, ID mid
)
9604 return rb_funcall
(parser
->value
, mid
, 0);
9608 ripper_dispatch1
(struct parser_params
*parser
, ID mid
, VALUE a
)
9611 return rb_funcall
(parser
->value
, mid
, 1, a
);
9615 ripper_dispatch2
(struct parser_params
*parser
, ID mid
, VALUE a
, VALUE b
)
9619 return rb_funcall
(parser
->value
, mid
, 2, a
, b
);
9623 ripper_dispatch3
(struct parser_params
*parser
, ID mid
, VALUE a
, VALUE b
, VALUE c
)
9628 return rb_funcall
(parser
->value
, mid
, 3, a
, b
, c
);
9632 ripper_dispatch4
(struct parser_params
*parser
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
)
9638 return rb_funcall
(parser
->value
, mid
, 4, a
, b
, c
, d
);
9642 ripper_dispatch5
(struct parser_params
*parser
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
, VALUE e
)
9649 return rb_funcall
(parser
->value
, mid
, 5, a
, b
, c
, d
, e
);
9652 static const struct kw_assoc
{
9655 } keyword_to_name
[] = {
9656 {keyword_class
, "class"},
9657 {keyword_module
, "module"},
9658 {keyword_def
, "def"},
9659 {keyword_undef
, "undef"},
9660 {keyword_begin
, "begin"},
9661 {keyword_rescue
, "rescue"},
9662 {keyword_ensure
, "ensure"},
9663 {keyword_end
, "end"},
9665 {keyword_unless
, "unless"},
9666 {keyword_then
, "then"},
9667 {keyword_elsif
, "elsif"},
9668 {keyword_else
, "else"},
9669 {keyword_case
, "case"},
9670 {keyword_when
, "when"},
9671 {keyword_while
, "while"},
9672 {keyword_until
, "until"},
9673 {keyword_for
, "for"},
9674 {keyword_break
, "break"},
9675 {keyword_next
, "next"},
9676 {keyword_redo
, "redo"},
9677 {keyword_retry
, "retry"},
9680 {keyword_do_cond
, "do"},
9681 {keyword_do_block
, "do"},
9682 {keyword_return
, "return"},
9683 {keyword_yield
, "yield"},
9684 {keyword_super
, "super"},
9685 {keyword_self
, "self"},
9686 {keyword_nil
, "nil"},
9687 {keyword_true
, "true"},
9688 {keyword_false
, "false"},
9689 {keyword_and
, "and"},
9691 {keyword_not
, "not"},
9692 {modifier_if
, "if"},
9693 {modifier_unless
, "unless"},
9694 {modifier_while
, "while"},
9695 {modifier_until
, "until"},
9696 {modifier_rescue
, "rescue"},
9697 {keyword_alias
, "alias"},
9698 {keyword_defined
, "defined?"},
9699 {keyword_BEGIN
, "BEGIN"},
9700 {keyword_END
, "END"},
9701 {keyword__LINE__
, "__LINE__"},
9702 {keyword__FILE__
, "__FILE__"},
9703 {keyword__ENCODING__
, "__ENCODING__"},
9708 keyword_id_to_str
(ID id
)
9710 const struct kw_assoc
*a
;
9712 for
(a
= keyword_to_name
; a
->id
; a
++) {
9719 #undef ripper_id2sym
9721 ripper_id2sym
(ID id
)
9729 return ID2SYM
(rb_intern
(buf
));
9731 if
((name
= keyword_id_to_str
(id
))) {
9732 return ID2SYM
(rb_intern
(name
));
9742 name
= rb_id2name
(id
);
9744 rb_bug
("cannot convert ID to string: %ld", (unsigned long)id
);
9748 return ID2SYM
(rb_intern
(name
));
9752 ripper_intern
(const char *s
)
9754 return ID2SYM
(rb_intern
(s
));
9758 ripper_compile_error
(struct parser_params
*parser
, const char *fmt
, ...
)
9763 va_start
(args
, fmt
);
9764 str
= rb_vsprintf
(fmt
, args
);
9766 rb_funcall
(parser
->value
, rb_intern
("compile_error"), 1, str
);
9770 ripper_warn0
(struct parser_params
*parser
, const char *fmt
)
9772 rb_funcall
(parser
->value
, rb_intern
("warn"), 1, STR_NEW2
(fmt
));
9776 ripper_warnI
(struct parser_params
*parser
, const char *fmt
, int a
)
9778 rb_funcall
(parser
->value
, rb_intern
("warn"), 2,
9779 STR_NEW2
(fmt
), INT2NUM
(a
));
9784 ripper_warnS
(struct parser_params
*parser
, const char *fmt
, const char *str
)
9786 rb_funcall
(parser
->value
, rb_intern
("warn"), 2,
9787 STR_NEW2
(fmt
), STR_NEW2
(str
));
9792 ripper_warning0
(struct parser_params
*parser
, const char *fmt
)
9794 rb_funcall
(parser
->value
, rb_intern
("warning"), 1, STR_NEW2
(fmt
));
9798 ripper_warningS
(struct parser_params
*parser
, const char *fmt
, const char *str
)
9800 rb_funcall
(parser
->value
, rb_intern
("warning"), 2,
9801 STR_NEW2
(fmt
), STR_NEW2
(str
));
9805 ripper_lex_get_generic
(struct parser_params
*parser
, VALUE src
)
9807 return rb_funcall
(src
, ripper_id_gets
, 0);
9811 ripper_s_allocate
(VALUE klass
)
9813 struct parser_params
*p
;
9816 p
= ALLOC_N
(struct parser_params
, 1);
9817 MEMZERO
(p
, struct parser_params
, 1);
9818 self
= Data_Wrap_Struct
(klass
, parser_mark
, parser_free
, p
);
9823 #define ripper_initialized_p(r) ((r)->parser_lex_input != 0)
9827 * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
9829 * Create a new Ripper object.
9830 * _src_ must be a String, a IO, or an Object which has #gets method.
9832 * This method does not starts parsing.
9833 * See also Ripper#parse and Ripper.parse.
9836 ripper_initialize
(int argc
, VALUE
*argv
, VALUE self
)
9838 struct parser_params
*parser
;
9839 VALUE src
, fname
, lineno
;
9841 Data_Get_Struct
(self
, struct parser_params
, parser
);
9842 rb_scan_args
(argc
, argv
, "12", &src
, &fname
, &lineno
);
9843 if
(rb_obj_respond_to
(src
, ripper_id_gets
, 0)) {
9844 parser
->parser_lex_gets
= ripper_lex_get_generic
;
9848 parser
->parser_lex_gets
= lex_get_str
;
9850 parser
->parser_lex_input
= src
;
9851 parser
->eofp
= Qfalse
;
9853 fname
= STR_NEW2
("(ripper)");
9858 parser_initialize
(parser
);
9860 parser
->parser_ruby_sourcefile_string
= fname
;
9861 parser
->parser_ruby_sourcefile
= RSTRING_PTR
(fname
);
9862 parser
->parser_ruby_sourceline
= NIL_P
(lineno
) ?
0 : NUM2INT
(lineno
) - 1;
9867 extern VALUE rb_thread_pass
(void);
9869 struct ripper_args
{
9870 struct parser_params
*parser
;
9876 ripper_parse0
(VALUE parser_v
)
9878 struct parser_params
*parser
;
9880 Data_Get_Struct
(parser_v
, struct parser_params
, parser
);
9881 parser_prepare
(parser
);
9882 ripper_yyparse
((void*)parser
);
9883 return parser
->result
;
9887 ripper_ensure
(VALUE parser_v
)
9889 struct parser_params
*parser
;
9891 Data_Get_Struct
(parser_v
, struct parser_params
, parser
);
9892 parser
->parsing_thread
= Qnil
;
9900 * Start parsing and returns the value of the root action.
9903 ripper_parse
(VALUE self
)
9905 struct parser_params
*parser
;
9907 Data_Get_Struct
(self
, struct parser_params
, parser
);
9908 if
(!ripper_initialized_p
(parser
)) {
9909 rb_raise
(rb_eArgError
, "method called for uninitialized object");
9911 if
(!NIL_P
(parser
->parsing_thread
)) {
9912 if
(parser
->parsing_thread
== rb_thread_current
())
9913 rb_raise
(rb_eArgError
, "Ripper#parse is not reentrant");
9915 rb_raise
(rb_eArgError
, "Ripper#parse is not multithread-safe");
9917 parser
->parsing_thread
= rb_thread_current
();
9918 rb_ensure
(ripper_parse0
, self
, ripper_ensure
, self
);
9920 return parser
->result
;
9925 * ripper#column -> Integer
9927 * Return column number of current parsing line.
9928 * This number starts from 0.
9931 ripper_column
(VALUE self
)
9933 struct parser_params
*parser
;
9936 Data_Get_Struct
(self
, struct parser_params
, parser
);
9937 if
(!ripper_initialized_p
(parser
)) {
9938 rb_raise
(rb_eArgError
, "method called for uninitialized object");
9940 if
(NIL_P
(parser
->parsing_thread
)) return Qnil
;
9941 col
= parser
->tokp
- parser
->parser_lex_pbeg
;
9942 return LONG2NUM
(col
);
9947 * ripper#lineno -> Integer
9949 * Return line number of current parsing line.
9950 * This number starts from 1.
9953 ripper_lineno
(VALUE self
)
9955 struct parser_params
*parser
;
9957 Data_Get_Struct
(self
, struct parser_params
, parser
);
9958 if
(!ripper_initialized_p
(parser
)) {
9959 rb_raise
(rb_eArgError
, "method called for uninitialized object");
9961 if
(NIL_P
(parser
->parsing_thread
)) return Qnil
;
9962 return INT2NUM
(parser
->parser_ruby_sourceline
);
9968 ripper_assert_Qundef
(VALUE self
, VALUE obj
, VALUE msg
)
9971 if
(obj
== Qundef
) {
9972 rb_raise
(rb_eArgError
, "%s", RSTRING_PTR
(msg
));
9979 ripper_value
(VALUE self
, VALUE obj
)
9981 return ULONG2NUM
(obj
);
9990 Ripper
= rb_define_class
("Ripper", rb_cObject
);
9991 rb_define_const
(Ripper
, "Version", rb_usascii_str_new2
(RIPPER_VERSION
));
9992 rb_define_alloc_func
(Ripper
, ripper_s_allocate
);
9993 rb_define_method
(Ripper
, "initialize", ripper_initialize
, -1);
9994 rb_define_method
(Ripper
, "parse", ripper_parse
, 0);
9995 rb_define_method
(Ripper
, "column", ripper_column
, 0);
9996 rb_define_method
(Ripper
, "lineno", ripper_lineno
, 0);
9997 rb_define_method
(Ripper
, "end_seen?", rb_parser_end_seen_p
, 0);
9998 rb_define_method
(Ripper
, "encoding", rb_parser_encoding
, 0);
9999 rb_define_method
(Ripper
, "yydebug", rb_parser_get_yydebug
, 0);
10000 rb_define_method
(Ripper
, "yydebug=", rb_parser_set_yydebug
, 1);
10001 #ifdef RIPPER_DEBUG
10002 rb_define_method
(rb_mKernel
, "assert_Qundef", ripper_assert_Qundef
, 2);
10003 rb_define_method
(rb_mKernel
, "rawVALUE", ripper_value
, 1);
10004 rb_define_method
(rb_mKernel
, "validate_object", ripper_validate_object
, 1);
10007 ripper_id_gets
= rb_intern
("gets");
10008 ripper_init_eventids1
(Ripper
);
10009 ripper_init_eventids2
(Ripper
);
10010 /* ensure existing in symbol table */
10014 #endif /* RIPPER */