Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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