1 /**********************************************************************
6 created at: Fri May 28 18:02:42 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
10 **********************************************************************/
15 # error needs pure parser
18 #define YYERROR_VERBOSE 1
19 #define YYSTACK_USE_ALLOCA 0
20 #define YYLTYPE rb_code_location_t
21 #define YYLTYPE_IS_DECLARED 1
23 #include "ruby/internal/config.h"
32 #include "internal/compile.h"
33 #include "internal/compilers.h"
34 #include "internal/complex.h"
35 #include "internal/error.h"
36 #include "internal/hash.h"
37 #include "internal/imemo.h"
38 #include "internal/io.h"
39 #include "internal/numeric.h"
40 #include "internal/parse.h"
41 #include "internal/rational.h"
42 #include "internal/re.h"
43 #include "internal/symbol.h"
44 #include "internal/thread.h"
45 #include "internal/variable.h"
49 #include "ruby/encoding.h"
50 #include "ruby/regex.h"
51 #include "ruby/ruby.h"
53 #include "ruby/util.h"
54 #include "ruby/ractor.h"
65 unsigned int in_defined
: 1;
66 unsigned int in_kwarg
: 1;
67 unsigned int in_argdef
: 1;
68 unsigned int in_def
: 1;
69 unsigned int in_class
: 1;
70 BITFIELD
(enum shareability
, shareable_constant_value
, 2);
75 #define NO_LEX_CTXT (struct lex_context){0}
77 #define AREF(ary, i) RARRAY_AREF(ary, i)
79 #ifndef WARN_PAST_SCOPE
80 # define WARN_PAST_SCOPE 0
85 #define yydebug (p->debug) /* disable the global variable definition */
87 #define YYMALLOC(size) rb_parser_malloc(p, (size))
88 #define YYREALLOC(ptr, size) rb_parser_realloc(p, (ptr), (size))
89 #define YYCALLOC(nelem, size) rb_parser_calloc(p, (nelem), (size))
90 #define YYFREE(ptr) rb_parser_free(p, (ptr))
91 #define YYFPRINTF rb_parser_printf
92 #define YY_LOCATION_PRINT(File, loc) \
93 rb_parser_printf
(p
, "%d.%d-%d.%d", \
94 (loc
).beg_pos.lineno
, (loc
).beg_pos.column
,\
95 (loc
).end_pos.lineno
, (loc
).end_pos.column
)
96 #define YYLLOC_DEFAULT(Current, Rhs, N) \
100 (Current
).beg_pos
= YYRHSLOC
(Rhs
, 1).beg_pos
; \
101 (Current
).end_pos
= YYRHSLOC
(Rhs
, N
).end_pos
; \
105 (Current
).beg_pos
= YYRHSLOC
(Rhs
, 0).end_pos
; \
106 (Current
).end_pos
= YYRHSLOC
(Rhs
, 0).end_pos
; \
110 (((Msgid
)[0] == 'm') && (strcmp
((Msgid
), "memory exhausted") == 0) ? \
111 "nesting too deep" : (Msgid
))
113 #define RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC(Current) \
114 rb_parser_set_location_from_strterm_heredoc
(p
, &p
->lex.strterm
->u.heredoc
, &(Current
))
115 #define RUBY_SET_YYLLOC_OF_NONE(Current) \
116 rb_parser_set_location_of_none
(p
, &(Current
))
117 #define RUBY_SET_YYLLOC(Current) \
118 rb_parser_set_location
(p
, &(Current
))
119 #define RUBY_INIT_YYLLOC() \
121 {p
->ruby_sourceline
, (int)(p
->lex.ptok
- p
->lex.pbeg
)}, \
122 {p
->ruby_sourceline
, (int)(p
->lex.pcur
- p
->lex.pbeg
)}, \
125 enum lex_state_bits
{
126 EXPR_BEG_bit
, /* ignore newline, +/- is a sign. */
127 EXPR_END_bit
, /* newline significant, +/- is an operator. */
128 EXPR_ENDARG_bit
, /* ditto, and unbound braces. */
129 EXPR_ENDFN_bit
, /* ditto, and unbound braces. */
130 EXPR_ARG_bit
, /* newline significant, +/- is an operator. */
131 EXPR_CMDARG_bit
, /* newline significant, +/- is an operator. */
132 EXPR_MID_bit
, /* newline significant, +/- is an operator. */
133 EXPR_FNAME_bit
, /* ignore newline, no reserved words. */
134 EXPR_DOT_bit
, /* right after `.' or `::', no reserved words. */
135 EXPR_CLASS_bit
, /* immediate after `class', no here document. */
136 EXPR_LABEL_bit
, /* flag bit, label is allowed. */
137 EXPR_LABELED_bit
, /* flag bit, just after a label. */
138 EXPR_FITEM_bit
, /* symbol literal as FNAME. */
141 /* examine combinations */
143 #define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
157 EXPR_VALUE
= EXPR_BEG
,
158 EXPR_BEG_ANY
= (EXPR_BEG | EXPR_MID | EXPR_CLASS
),
159 EXPR_ARG_ANY
= (EXPR_ARG | EXPR_CMDARG
),
160 EXPR_END_ANY
= (EXPR_END | EXPR_ENDARG | EXPR_ENDFN
),
163 #define IS_lex_state_for(x, ls) ((x) & (ls))
164 #define IS_lex_state_all_for(x, ls) (((x) & (ls)) == (ls))
165 #define IS_lex_state(ls) IS_lex_state_for(p->lex.state, (ls))
166 #define IS_lex_state_all(ls) IS_lex_state_all_for(p->lex.state, (ls))
168 # define SET_LEX_STATE(ls) \
169 parser_set_lex_state
(p
, ls
, __LINE__
)
170 static inline
enum lex_state_e parser_set_lex_state
(struct parser_params
*p
, enum lex_state_e ls
, int line
);
172 typedef VALUE stack_type
;
174 static const rb_code_location_t NULL_LOC
= { {0, -1}, {0, -1} };
176 # define SHOW_BITSTACK(stack, name) (p->debug ? rb_parser_show_bitstack(p, stack, name, __LINE__) : (void)0)
177 # define BITSTACK_PUSH(stack, n) (((p->stack) = ((p->stack)<<1)|((n)&1)), SHOW_BITSTACK(p->stack, #stack"(push)"))
178 # define BITSTACK_POP(stack) (((p->stack) = (p->stack) >> 1), SHOW_BITSTACK(p->stack, #stack"(pop)"))
179 # define BITSTACK_SET_P(stack) (SHOW_BITSTACK(p->stack, #stack), (p->stack)&1)
180 # define BITSTACK_SET(stack, n) ((p->stack)=(n), SHOW_BITSTACK(p->stack, #stack"(set)"))
182 /* A flag to identify keyword_do_cond, "do" keyword after condition expression.
183 Examples: `while ... do`, `until ... do`, and `for ... in ... do` */
184 #define COND_PUSH(n) BITSTACK_PUSH(cond_stack, (n))
185 #define COND_POP() BITSTACK_POP(cond_stack)
186 #define COND_P() BITSTACK_SET_P(cond_stack)
187 #define COND_SET(n) BITSTACK_SET(cond_stack, (n))
189 /* A flag to identify keyword_do_block; "do" keyword after command_call.
190 Example: `foo 1, 2 do`. */
191 #define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, (n))
192 #define CMDARG_POP() BITSTACK_POP(cmdarg_stack)
193 #define CMDARG_P() BITSTACK_SET_P(cmdarg_stack)
194 #define CMDARG_SET(n) BITSTACK_SET(cmdarg_stack, (n))
210 struct local_vars
*prev
;
213 NODE
*outer
, *inner
, *current
;
224 #define NUMPARAM_ID_P(id) numparam_id_p(id)
225 #define NUMPARAM_ID_TO_IDX(id) (unsigned int)(((id) >> ID_SCOPE_SHIFT) - tNUMPARAM_1 + 1)
226 #define NUMPARAM_IDX_TO_ID(idx) TOKEN2LOCALID((tNUMPARAM_1 + (idx) - 1))
230 if
(!is_local_id
(id
)) return
0;
231 unsigned int idx
= NUMPARAM_ID_TO_IDX
(id
);
232 return idx
> 0 && idx
<= NUMPARAM_MAX
;
234 static void numparam_name
(struct parser_params
*p
, ID id
);
236 #define DVARS_INHERIT ((void*)1)
237 #define DVARS_TOPSCOPE NULL
238 #define DVARS_TERMINAL_P(tbl) ((tbl) == DVARS_INHERIT || (tbl) == DVARS_TOPSCOPE)
240 typedef
struct token_info
{
242 rb_code_position_t beg
;
245 struct token_info
*next
;
248 typedef
struct rb_strterm_struct rb_strterm_t
;
251 Structure of Lexer Buffer:
253 lex.pbeg lex.ptok lex.pcur lex.pend
255 |------------+------------+------------|
259 struct parser_params
{
260 rb_imemo_tmpbuf_t
*heap
;
265 rb_strterm_t
*strterm
;
266 VALUE
(*gets
)(struct parser_params
*,VALUE
);
277 VALUE
(*call
)(VALUE
, int);
279 enum lex_state_e state
;
280 /* track the nest level of any parens "()[]{}" */
282 /* keep p->lex.paren_nest at the beginning of lambda "->" to detect tLAMBEG and keyword_do_LAMBDA */
284 /* track the nest level of only braces "{}" */
287 stack_type cond_stack
;
288 stack_type cmdarg_stack
;
294 int heredoc_line_indent
;
296 struct local_vars
*lvtbl
;
300 int ruby_sourceline
; /* current line no. */
301 const char *ruby_sourcefile
; /* current source file */
302 VALUE ruby_sourcefile_string
;
304 token_info
*token_info
;
306 VALUE compile_option
;
318 struct lex_context ctxt
;
320 unsigned int command_start
:1;
321 unsigned int eofp
: 1;
322 unsigned int ruby__end__seen
: 1;
323 unsigned int debug
: 1;
324 unsigned int has_shebang
: 1;
325 unsigned int token_seen
: 1;
326 unsigned int token_info_enabled
: 1;
328 unsigned int past_scope_enabled
: 1;
330 unsigned int error_p
: 1;
331 unsigned int cr_seen
: 1;
336 unsigned int do_print
: 1;
337 unsigned int do_loop
: 1;
338 unsigned int do_chomp
: 1;
339 unsigned int do_split
: 1;
340 unsigned int keep_script_lines
: 1;
342 NODE
*eval_tree_begin
;
346 const struct rb_iseq_struct
*parent_iseq
;
358 VALUE parsing_thread
;
362 #define intern_cstr(n,l,en) rb_intern3(n,l,en)
364 #define STR_NEW(ptr,len) rb_enc_str_new((ptr),(len),p->enc)
365 #define STR_NEW0() rb_enc_str_new(0,0,p->enc)
366 #define STR_NEW2(ptr) rb_enc_str_new((ptr),strlen(ptr),p->enc)
367 #define STR_NEW3(ptr,len,e,func) parser_str_new((ptr),(len),(e),(func),p->enc)
368 #define TOK_INTERN() intern_cstr(tok(p), toklen(p), p->enc)
371 push_pvtbl
(struct parser_params
*p
)
373 st_table
*tbl
= p
->pvtbl
;
374 p
->pvtbl
= st_init_numtable
();
379 pop_pvtbl
(struct parser_params
*p
, st_table
*tbl
)
381 st_free_table
(p
->pvtbl
);
386 push_pktbl
(struct parser_params
*p
)
388 st_table
*tbl
= p
->pktbl
;
394 pop_pktbl
(struct parser_params
*p
, st_table
*tbl
)
396 if
(p
->pktbl
) st_free_table
(p
->pktbl
);
400 RBIMPL_ATTR_NONNULL
((1, 2, 3))
401 static int parser_yyerror
(struct parser_params
*, const YYLTYPE *yylloc, const char*);
402 RBIMPL_ATTR_NONNULL
((1, 2))
403 static int parser_yyerror0
(struct parser_params
*, const char*);
404 #define yyerror0(msg) parser_yyerror0(p, (msg))
405 #define yyerror1(loc, msg) parser_yyerror(p, (loc), (msg))
406 #define yyerror(yylloc, p, msg) parser_yyerror(p, yylloc, msg)
407 #define token_flush(ptr) ((ptr)->lex.ptok = (ptr)->lex.pcur)
409 static void token_info_setup
(token_info
*ptinfo
, const char *ptr
, const rb_code_location_t
*loc
);
410 static void token_info_push
(struct parser_params
*, const char *token
, const rb_code_location_t
*loc
);
411 static void token_info_pop
(struct parser_params
*, const char *token
, const rb_code_location_t
*loc
);
412 static void token_info_warn
(struct parser_params
*p
, const char *token
, token_info
*ptinfo_beg
, int same
, const rb_code_location_t
*loc
);
413 static void token_info_drop
(struct parser_params
*p
, const char *token
, rb_code_position_t beg_pos
);
416 #define compile_for_eval (0)
418 #define compile_for_eval (p->parent_iseq != 0)
421 #define token_column ((int)(p->lex.ptok - p->lex.pbeg))
423 #define CALL_Q_P(q) ((q) == TOKEN2VAL(tANDDOT))
424 #define NODE_CALL_Q(q) (CALL_Q_P(q) ? NODE_QCALL : NODE_CALL)
425 #define NEW_QCALL(q,r,m,a,loc) NEW_NODE(NODE_CALL_Q(q),r,m,a,loc)
427 #define lambda_beginning_p() (p->lex.lpar_beg == p->lex.paren_nest)
429 #define ANON_BLOCK_ID '&'
431 static enum yytokentype
yylex(YYSTYPE*, YYLTYPE*, struct parser_params
*);
435 rb_discard_node
(struct parser_params
*p
, NODE
*n
)
437 rb_ast_delete_node
(p
->ast
, n
);
443 add_mark_object
(struct parser_params
*p
, VALUE obj
)
445 if
(!SPECIAL_CONST_P
(obj
)
446 && !RB_TYPE_P
(obj
, T_NODE
) /* Ripper jumbles NODE objects and other objects... */
448 rb_ast_add_mark_object
(p
->ast
, obj
);
453 static NODE
* node_newnode_with_locals
(struct parser_params
*, enum node_type
, VALUE
, VALUE
, const rb_code_location_t
*);
456 static NODE
* node_newnode
(struct parser_params
*, enum node_type
, VALUE
, VALUE
, VALUE
, const rb_code_location_t
*);
457 #define rb_node_newnode(type, a1, a2, a3, loc) node_newnode(p, (type), (a1), (a2), (a3), (loc))
459 static NODE
*nd_set_loc
(NODE
*nd
, const YYLTYPE *loc
);
462 parser_get_node_id
(struct parser_params
*p
)
464 int node_id
= p
->node_id
;
471 set_line_body
(NODE
*body
, int line
)
474 switch
(nd_type
(body
)) {
477 nd_set_line
(body
, line
);
481 #define yyparse ruby_yyparse
483 static NODE
* cond
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
);
484 static NODE
* method_cond
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
);
485 #define new_nil(loc) NEW_NIL(loc)
486 static NODE
*new_nil_at
(struct parser_params
*p
, const rb_code_position_t
*pos
);
487 static NODE
*new_if
(struct parser_params
*,NODE
*,NODE
*,NODE
*,const YYLTYPE*);
488 static NODE
*new_unless
(struct parser_params
*,NODE
*,NODE
*,NODE
*,const YYLTYPE*);
489 static NODE
*logop
(struct parser_params
*,ID
,NODE
*,NODE
*,const YYLTYPE*,const YYLTYPE*);
491 static NODE
*newline_node
(NODE
*);
492 static void fixpos
(NODE
*,NODE
*);
494 static int value_expr_gen
(struct parser_params
*,NODE
*);
495 static void void_expr
(struct parser_params
*,NODE
*);
496 static NODE
*remove_begin
(NODE
*);
497 static NODE
*remove_begin_all
(NODE
*);
498 #define value_expr(node) value_expr_gen(p, (node))
499 static NODE
*void_stmts
(struct parser_params
*,NODE
*);
500 static void reduce_nodes
(struct parser_params
*,NODE
**);
501 static void block_dup_check
(struct parser_params
*,NODE
*,NODE
*);
503 static NODE
*block_append
(struct parser_params
*,NODE
*,NODE
*);
504 static NODE
*list_append
(struct parser_params
*,NODE
*,NODE
*);
505 static NODE
*list_concat
(NODE
*,NODE
*);
506 static NODE
*arg_append
(struct parser_params
*,NODE
*,NODE
*,const YYLTYPE*);
507 static NODE
*last_arg_append
(struct parser_params
*p
, NODE
*args
, NODE
*last_arg
, const YYLTYPE *loc
);
508 static NODE
*rest_arg_append
(struct parser_params
*p
, NODE
*args
, NODE
*rest_arg
, const YYLTYPE *loc
);
509 static NODE
*literal_concat
(struct parser_params
*,NODE
*,NODE
*,const YYLTYPE*);
510 static NODE
*new_evstr
(struct parser_params
*,NODE
*,const YYLTYPE*);
511 static NODE
*new_dstr
(struct parser_params
*,NODE
*,const YYLTYPE*);
512 static NODE
*evstr2dstr
(struct parser_params
*,NODE
*);
513 static NODE
*splat_array
(NODE
*);
514 static void mark_lvar_used
(struct parser_params
*p
, NODE
*rhs
);
516 static NODE
*call_bin_op
(struct parser_params
*,NODE
*,ID
,NODE
*,const YYLTYPE*,const YYLTYPE*);
517 static NODE
*call_uni_op
(struct parser_params
*,NODE
*,ID
,const YYLTYPE*,const YYLTYPE*);
518 static NODE
*new_qcall
(struct parser_params
* p
, ID atype
, NODE
*recv
, ID mid
, NODE
*args
, const YYLTYPE *op_loc
, const YYLTYPE *loc
);
519 static NODE
*new_command_qcall
(struct parser_params
* p
, ID atype
, NODE
*recv
, ID mid
, NODE
*args
, NODE
*block
, const YYLTYPE *op_loc
, const YYLTYPE *loc
);
520 static NODE
*method_add_block
(struct parser_params
*p
, NODE
*m
, NODE
*b
, const YYLTYPE *loc
) {b
->nd_iter
= m
; b
->nd_loc
= *loc
; return b
;}
522 static bool args_info_empty_p
(struct rb_args_info
*args
);
523 static NODE
*new_args
(struct parser_params
*,NODE
*,NODE
*,ID
,NODE
*,NODE
*,const YYLTYPE*);
524 static NODE
*new_args_tail
(struct parser_params
*,NODE
*,ID
,ID
,const YYLTYPE*);
525 static NODE
*new_array_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*pre_arg
, NODE
*aryptn
, const YYLTYPE *loc
);
526 static NODE
*new_array_pattern_tail
(struct parser_params
*p
, NODE
*pre_args
, int has_rest
, ID rest_arg
, NODE
*post_args
, const YYLTYPE *loc
);
527 static NODE
*new_find_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*fndptn
, const YYLTYPE *loc
);
528 static NODE
*new_find_pattern_tail
(struct parser_params
*p
, ID pre_rest_arg
, NODE
*args
, ID post_rest_arg
, const YYLTYPE *loc
);
529 static NODE
*new_hash_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*hshptn
, const YYLTYPE *loc
);
530 static NODE
*new_hash_pattern_tail
(struct parser_params
*p
, NODE
*kw_args
, ID kw_rest_arg
, const YYLTYPE *loc
);
532 static NODE
*new_kw_arg
(struct parser_params
*p
, NODE
*k
, const YYLTYPE *loc
);
533 static NODE
*args_with_numbered
(struct parser_params
*,NODE
*,int);
535 static VALUE negate_lit
(struct parser_params
*, VALUE
);
536 static NODE
*ret_args
(struct parser_params
*,NODE
*);
537 static NODE
*arg_blk_pass
(NODE
*,NODE
*);
538 static NODE
*new_yield
(struct parser_params
*,NODE
*,const YYLTYPE*);
539 static NODE
*dsym_node
(struct parser_params
*,NODE
*,const YYLTYPE*);
541 static NODE
*gettable
(struct parser_params
*,ID
,const YYLTYPE*);
542 static NODE
*assignable
(struct parser_params
*,ID
,NODE
*,const YYLTYPE*);
544 static NODE
*aryset
(struct parser_params
*,NODE
*,NODE
*,const YYLTYPE*);
545 static NODE
*attrset
(struct parser_params
*,NODE
*,ID
,ID
,const YYLTYPE*);
547 static void rb_backref_error
(struct parser_params
*,NODE
*);
548 static NODE
*node_assign
(struct parser_params
*,NODE
*,NODE
*,struct lex_context
,const YYLTYPE*);
550 static NODE
*new_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID op
, NODE
*rhs
, struct lex_context
, const YYLTYPE *loc
);
551 static NODE
*new_ary_op_assign
(struct parser_params
*p
, NODE
*ary
, NODE
*args
, ID op
, NODE
*rhs
, const YYLTYPE *args_loc
, const YYLTYPE *loc
);
552 static NODE
*new_attr_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID atype
, ID attr
, ID op
, NODE
*rhs
, const YYLTYPE *loc
);
553 static NODE
*new_const_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID op
, NODE
*rhs
, struct lex_context
, const YYLTYPE *loc
);
554 static NODE
*new_bodystmt
(struct parser_params
*p
, NODE
*head
, NODE
*rescue
, NODE
*rescue_else
, NODE
*ensure
, const YYLTYPE *loc
);
556 static NODE
*const_decl
(struct parser_params
*p
, NODE
* path
, const YYLTYPE *loc
);
558 static NODE
*opt_arg_append
(NODE
*, NODE
*);
559 static NODE
*kwd_append
(NODE
*, NODE
*);
561 static NODE
*new_hash
(struct parser_params
*p
, NODE
*hash
, const YYLTYPE *loc
);
562 static NODE
*new_unique_key_hash
(struct parser_params
*p
, NODE
*hash
, const YYLTYPE *loc
);
564 static NODE
*new_defined
(struct parser_params
*p
, NODE
*expr
, const YYLTYPE *loc
);
566 static NODE
*new_regexp
(struct parser_params
*, NODE
*, int, const YYLTYPE *);
568 #define make_list(list, loc) ((list) ? (nd_set_loc(list, loc), list) : NEW_ZLIST(loc))
570 static NODE
*new_xstring
(struct parser_params
*, NODE
*, const YYLTYPE *loc
);
572 static NODE
*symbol_append
(struct parser_params
*p
, NODE
*symbols
, NODE
*symbol
);
574 static NODE
*match_op
(struct parser_params
*,NODE
*,NODE
*,const YYLTYPE*,const YYLTYPE*);
576 static rb_ast_id_table_t
*local_tbl
(struct parser_params
*);
578 static VALUE reg_compile
(struct parser_params
*, VALUE
, int);
579 static void reg_fragment_setenc
(struct parser_params
*, VALUE
, int);
580 static int reg_fragment_check
(struct parser_params
*, VALUE
, int);
581 static NODE
*reg_named_capture_assign
(struct parser_params
* p
, VALUE regexp
, const YYLTYPE *loc
);
583 static int literal_concat0
(struct parser_params
*p
, VALUE head
, VALUE tail
);
584 static NODE
*heredoc_dedent
(struct parser_params
*,NODE
*);
586 static void check_literal_when
(struct parser_params
*p
, NODE
*args
, const YYLTYPE *loc
);
588 #define get_id(id) (id)
589 #define get_value(val) (val)
590 #define get_num(num) (num)
592 #define NODE_RIPPER NODE_CDECL
593 #define NEW_RIPPER(a,b,c,loc) (VALUE)NEW_CDECL(a,b,c,loc)
595 static inline
int ripper_is_node_yylval
(VALUE n
);
598 ripper_new_yylval
(struct parser_params
*p
, ID a
, VALUE b
, VALUE c
)
600 if
(ripper_is_node_yylval
(c
)) c
= RNODE
(c
)->nd_cval
;
601 add_mark_object
(p
, b
);
602 add_mark_object
(p
, c
);
603 return NEW_RIPPER
(a
, b
, c
, &NULL_LOC
);
607 ripper_is_node_yylval
(VALUE n
)
609 return RB_TYPE_P
(n
, T_NODE
) && nd_type_p
(RNODE
(n
), NODE_RIPPER
);
612 #define value_expr(node) ((void)(node))
613 #define remove_begin(node) (node)
614 #define void_stmts(p,x) (x)
615 #define rb_dvar_defined(id, base) 0
616 #define rb_local_defined(id, base) 0
617 static ID ripper_get_id
(VALUE
);
618 #define get_id(id) ripper_get_id(id)
619 static VALUE ripper_get_value
(VALUE
);
620 #define get_value(val) ripper_get_value(val)
621 #define get_num(num) (int)get_id(num)
622 static VALUE assignable
(struct parser_params
*,VALUE
);
623 static int id_is_var
(struct parser_params
*p
, ID id
);
625 #define method_cond(p,node,loc) (node)
626 #define call_bin_op(p, recv,id,arg1,op_loc,loc) dispatch3(binary, (recv), STATIC_ID2SYM(id), (arg1))
627 #define match_op(p,node1,node2,op_loc,loc) call_bin_op(0, (node1), idEqTilde, (node2), op_loc, loc)
628 #define call_uni_op(p, recv,id,op_loc,loc) dispatch2(unary, STATIC_ID2SYM(id), (recv))
629 #define logop(p,id,node1,node2,op_loc,loc) call_bin_op(0, (node1), (id), (node2), op_loc, loc)
631 #define new_nil(loc) Qnil
633 static VALUE new_regexp
(struct parser_params
*, VALUE
, VALUE
, const YYLTYPE *);
635 static VALUE const_decl
(struct parser_params
*p
, VALUE path
);
637 static VALUE var_field
(struct parser_params
*p
, VALUE a
);
638 static VALUE assign_error
(struct parser_params
*p
, const char *mesg
, VALUE a
);
640 static VALUE parser_reg_compile
(struct parser_params
*, VALUE
, int, VALUE
*);
642 static VALUE backref_error
(struct parser_params
*, NODE
*, VALUE
);
645 /* forward declaration */
646 typedef
struct rb_strterm_heredoc_struct rb_strterm_heredoc_t
;
648 RUBY_SYMBOL_EXPORT_BEGIN
649 VALUE rb_parser_reg_compile
(struct parser_params
* p
, VALUE str
, int options
);
650 int rb_reg_fragment_setenc
(struct parser_params
*, VALUE
, int);
651 enum lex_state_e rb_parser_trace_lex_state
(struct parser_params
*, enum lex_state_e
, enum lex_state_e
, int);
652 VALUE rb_parser_lex_state_name
(enum lex_state_e state
);
653 void rb_parser_show_bitstack
(struct parser_params
*, stack_type
, const char *, int);
654 PRINTF_ARGS
(void rb_parser_fatal
(struct parser_params
*p
, const char *fmt
, ...
), 2, 3);
655 YYLTYPE *rb_parser_set_location_from_strterm_heredoc
(struct parser_params
*p
, rb_strterm_heredoc_t
*here
, YYLTYPE *yylloc);
656 YYLTYPE *rb_parser_set_location_of_none
(struct parser_params
*p
, YYLTYPE *yylloc);
657 YYLTYPE *rb_parser_set_location
(struct parser_params
*p
, YYLTYPE *yylloc);
658 RUBY_SYMBOL_EXPORT_END
660 static void error_duplicate_pattern_variable
(struct parser_params
*p
, ID id
, const YYLTYPE *loc
);
661 static void error_duplicate_pattern_key
(struct parser_params
*p
, ID id
, const YYLTYPE *loc
);
663 static ID formal_argument
(struct parser_params
*, ID
);
665 static ID formal_argument
(struct parser_params
*, VALUE
);
667 static ID shadowing_lvar
(struct parser_params
*,ID
);
668 static void new_bv
(struct parser_params
*,ID
);
670 static void local_push
(struct parser_params
*,int);
671 static void local_pop
(struct parser_params
*);
672 static void local_var
(struct parser_params
*, ID
);
673 static void arg_var
(struct parser_params
*, ID
);
674 static int local_id
(struct parser_params
*p
, ID id
);
675 static int local_id_ref
(struct parser_params
*, ID
, ID
**);
677 static ID internal_id
(struct parser_params
*);
678 static NODE
*new_args_forward_call
(struct parser_params
*, NODE
*, const YYLTYPE*, const YYLTYPE*);
680 static int check_forwarding_args
(struct parser_params
*);
681 static void add_forwarding_args
(struct parser_params
*p
);
683 static const struct vtable
*dyna_push
(struct parser_params
*);
684 static void dyna_pop
(struct parser_params
*, const struct vtable
*);
685 static int dyna_in_block
(struct parser_params
*);
686 #define dyna_var(p, id) local_var(p, id)
687 static int dvar_defined
(struct parser_params
*, ID
);
688 static int dvar_defined_ref
(struct parser_params
*, ID
, ID
**);
689 static int dvar_curr
(struct parser_params
*,ID
);
691 static int lvar_defined
(struct parser_params
*, ID
);
693 static NODE
*numparam_push
(struct parser_params
*p
);
694 static void numparam_pop
(struct parser_params
*p
, NODE
*prev_inner
);
697 # define METHOD_NOT idNOT
699 # define METHOD_NOT '!'
702 #define idFWD_REST '*'
703 #ifdef RUBY3_KEYWORDS
704 #define idFWD_KWREST idPow /* Use simple "**", as tDSTAR is "**arg" */
706 #define idFWD_KWREST 0
708 #define idFWD_BLOCK '&'
710 #define RE_OPTION_ONCE (1<<16)
711 #define RE_OPTION_ENCODING_SHIFT 8
712 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
713 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
714 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
715 #define RE_OPTION_MASK 0xff
716 #define RE_OPTION_ARG_ENCODING_NONE 32
718 /* structs for managing terminator of string literal and heredocment */
719 typedef
struct rb_strterm_literal_struct
{
726 long func
; /* STR_FUNC_* (e.g., STR_FUNC_ESCAPE and STR_FUNC_EXPAND) */
730 long paren
; /* '(' of `%q(...)` */
734 long term
; /* ')' of `%q(...)` */
736 } rb_strterm_literal_t
;
738 #define HERETERM_LENGTH_BITS ((SIZEOF_VALUE - 1) * CHAR_BIT - 1)
740 struct rb_strterm_heredoc_struct
{
741 VALUE lastline
; /* the string of line that contains `<<"END"` */
742 long offset
; /* the column of END in `<<"END"` */
743 int sourceline
; /* lineno of the line that contains `<<"END"` */
744 unsigned length
/* the length of END in `<<"END"` */
745 #if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
746 : HERETERM_LENGTH_BITS
747 # define HERETERM_LENGTH_MAX ((1U << HERETERM_LENGTH_BITS) - 1)
749 # define HERETERM_LENGTH_MAX UINT_MAX
752 #if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
760 STATIC_ASSERT
(rb_strterm_heredoc_t
, sizeof
(rb_strterm_heredoc_t
) <= 4 * SIZEOF_VALUE
);
762 #define STRTERM_HEREDOC IMEMO_FL_USER0
764 struct rb_strterm_struct
{
767 rb_strterm_literal_t literal
;
768 rb_strterm_heredoc_t heredoc
;
774 rb_strterm_mark
(VALUE obj
)
776 rb_strterm_t
*strterm
= (rb_strterm_t
*)obj
;
777 if
(RBASIC
(obj
)->flags
& STRTERM_HEREDOC
) {
778 rb_strterm_heredoc_t
*heredoc
= &strterm
->u.heredoc
;
779 rb_gc_mark
(heredoc
->lastline
);
784 #define yytnamerr(yyres, yystr) (YYSIZE_T)rb_yytnamerr(p, yyres, yystr)
785 size_t rb_yytnamerr
(struct parser_params
*p
, char *yyres
, const char *yystr
);
787 #define TOKEN2ID(tok) ( \
788 tTOKEN_LOCAL_BEGIN
<(tok
)&&(tok
)<tTOKEN_LOCAL_END ? TOKEN2LOCALID
(tok
) : \
789 tTOKEN_INSTANCE_BEGIN
<(tok
)&&(tok
)<tTOKEN_INSTANCE_END ? TOKEN2INSTANCEID
(tok
) : \
790 tTOKEN_GLOBAL_BEGIN
<(tok
)&&(tok
)<tTOKEN_GLOBAL_END ? TOKEN2GLOBALID
(tok
) : \
791 tTOKEN_CONST_BEGIN
<(tok
)&&(tok
)<tTOKEN_CONST_END ? TOKEN2CONSTID
(tok
) : \
792 tTOKEN_CLASS_BEGIN
<(tok
)&&(tok
)<tTOKEN_CLASS_END ? TOKEN2CLASSID
(tok
) : \
793 tTOKEN_ATTRSET_BEGIN
<(tok
)&&(tok
)<tTOKEN_ATTRSET_END ? TOKEN2ATTRSETID
(tok
) : \
794 ((tok
) / ((tok
)<tPRESERVED_ID_END
&& ((tok
)>=128 || rb_ispunct
(tok
)))))
796 /****** Ripper *******/
799 #define RIPPER_VERSION "0.1.0"
801 static inline VALUE intern_sym
(const char *name
);
803 #include "eventids1.c"
804 #include "eventids2.c"
806 static VALUE ripper_dispatch0
(struct parser_params
*,ID
);
807 static VALUE ripper_dispatch1
(struct parser_params
*,ID
,VALUE
);
808 static VALUE ripper_dispatch2
(struct parser_params
*,ID
,VALUE
,VALUE
);
809 static VALUE ripper_dispatch3
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
);
810 static VALUE ripper_dispatch4
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
);
811 static VALUE ripper_dispatch5
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
);
812 static VALUE ripper_dispatch7
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
);
813 static void ripper_error
(struct parser_params
*p
);
815 #define dispatch0(n) ripper_dispatch0(p, TOKEN_PASTE(ripper_id_, n))
816 #define dispatch1(n,a) ripper_dispatch1(p, TOKEN_PASTE(ripper_id_, n), (a))
817 #define dispatch2(n,a,b) ripper_dispatch2(p, TOKEN_PASTE(ripper_id_, n), (a), (b))
818 #define dispatch3(n,a,b,c) ripper_dispatch3(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
819 #define dispatch4(n,a,b,c,d) ripper_dispatch4(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
820 #define dispatch5(n,a,b,c,d,e) ripper_dispatch5(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
821 #define dispatch7(n,a,b,c,d,e,f,g) ripper_dispatch7(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e), (f), (g))
823 #define yyparse ripper_yyparse
825 #define ID2VAL(id) STATIC_ID2SYM(id)
826 #define TOKEN2VAL(t) ID2VAL(TOKEN2ID(t))
827 #define KWD2EID(t, v) ripper_new_yylval(p, keyword_##t, get_value(v), 0)
829 #define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
830 dispatch7
(params
, (pars
), (opts
), (rest
), (pars2
), (kws
), (kwrest
), (blk
))
832 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
835 new_args
(struct parser_params
*p
, VALUE pre_args
, VALUE opt_args
, VALUE rest_arg
, VALUE post_args
, VALUE tail
, YYLTYPE *loc
)
837 NODE
*t
= (NODE
*)tail
;
838 VALUE kw_args
= t
->u1.value
, kw_rest_arg
= t
->u2.value
, block
= t
->u3.value
;
839 return params_new
(pre_args
, opt_args
, rest_arg
, post_args
, kw_args
, kw_rest_arg
, escape_Qundef
(block
));
843 new_args_tail
(struct parser_params
*p
, VALUE kw_args
, VALUE kw_rest_arg
, VALUE block
, YYLTYPE *loc
)
845 NODE
*t
= rb_node_newnode
(NODE_ARGS_AUX
, kw_args
, kw_rest_arg
, block
, &NULL_LOC
);
846 add_mark_object
(p
, kw_args
);
847 add_mark_object
(p
, kw_rest_arg
);
848 add_mark_object
(p
, block
);
853 args_with_numbered
(struct parser_params
*p
, VALUE args
, int max_numparam
)
859 new_array_pattern
(struct parser_params
*p
, VALUE constant
, VALUE pre_arg
, VALUE aryptn
, const YYLTYPE *loc
)
861 NODE
*t
= (NODE
*)aryptn
;
862 VALUE pre_args
= t
->u1.value
, rest_arg
= t
->u2.value
, post_args
= t
->u3.value
;
864 if
(!NIL_P
(pre_arg
)) {
865 if
(!NIL_P
(pre_args
)) {
866 rb_ary_unshift
(pre_args
, pre_arg
);
869 pre_args
= rb_ary_new_from_args
(1, pre_arg
);
872 return dispatch4
(aryptn
, constant
, pre_args
, rest_arg
, post_args
);
876 new_array_pattern_tail
(struct parser_params
*p
, VALUE pre_args
, VALUE has_rest
, VALUE rest_arg
, VALUE post_args
, const YYLTYPE *loc
)
881 rest_arg
= dispatch1
(var_field
, rest_arg ? rest_arg
: Qnil
);
887 t
= rb_node_newnode
(NODE_ARYPTN
, pre_args
, rest_arg
, post_args
, &NULL_LOC
);
888 add_mark_object
(p
, pre_args
);
889 add_mark_object
(p
, rest_arg
);
890 add_mark_object
(p
, post_args
);
895 new_find_pattern
(struct parser_params
*p
, VALUE constant
, VALUE fndptn
, const YYLTYPE *loc
)
897 NODE
*t
= (NODE
*)fndptn
;
898 VALUE pre_rest_arg
= t
->u1.value
, args
= t
->u2.value
, post_rest_arg
= t
->u3.value
;
900 return dispatch4
(fndptn
, constant
, pre_rest_arg
, args
, post_rest_arg
);
904 new_find_pattern_tail
(struct parser_params
*p
, VALUE pre_rest_arg
, VALUE args
, VALUE post_rest_arg
, const YYLTYPE *loc
)
908 pre_rest_arg
= dispatch1
(var_field
, pre_rest_arg ? pre_rest_arg
: Qnil
);
909 post_rest_arg
= dispatch1
(var_field
, post_rest_arg ? post_rest_arg
: Qnil
);
911 t
= rb_node_newnode
(NODE_FNDPTN
, pre_rest_arg
, args
, post_rest_arg
, &NULL_LOC
);
912 add_mark_object
(p
, pre_rest_arg
);
913 add_mark_object
(p
, args
);
914 add_mark_object
(p
, post_rest_arg
);
918 #define new_hash(p,h,l) rb_ary_new_from_args(0)
921 new_unique_key_hash
(struct parser_params
*p
, VALUE ary
, const YYLTYPE *loc
)
927 new_hash_pattern
(struct parser_params
*p
, VALUE constant
, VALUE hshptn
, const YYLTYPE *loc
)
929 NODE
*t
= (NODE
*)hshptn
;
930 VALUE kw_args
= t
->u1.value
, kw_rest_arg
= t
->u2.value
;
931 return dispatch3
(hshptn
, constant
, kw_args
, kw_rest_arg
);
935 new_hash_pattern_tail
(struct parser_params
*p
, VALUE kw_args
, VALUE kw_rest_arg
, const YYLTYPE *loc
)
939 kw_rest_arg
= dispatch1
(var_field
, kw_rest_arg
);
944 t
= rb_node_newnode
(NODE_HSHPTN
, kw_args
, kw_rest_arg
, 0, &NULL_LOC
);
946 add_mark_object
(p
, kw_args
);
947 add_mark_object
(p
, kw_rest_arg
);
951 #define new_defined(p,expr,loc) dispatch1(defined, (expr))
953 static VALUE heredoc_dedent
(struct parser_params
*,VALUE
);
956 #define ID2VAL(id) (id)
957 #define TOKEN2VAL(t) ID2VAL(t)
958 #define KWD2EID(t, v) keyword_##t
961 set_defun_body
(struct parser_params
*p
, NODE
*n
, NODE
*args
, NODE
*body
, const YYLTYPE *loc
)
963 body
= remove_begin
(body
);
964 reduce_nodes
(p
, &body
);
965 n
->nd_defn
= NEW_SCOPE
(args
, body
, loc
);
967 nd_set_line
(n
->nd_defn
, loc
->end_pos.lineno
);
968 set_line_body
(body
, loc
->beg_pos.lineno
);
973 rescued_expr
(struct parser_params
*p
, NODE
*arg
, NODE
*rescue
,
974 const YYLTYPE *arg_loc
, const YYLTYPE *mod_loc
, const YYLTYPE *res_loc
)
976 YYLTYPE loc
= code_loc_gen
(mod_loc
, res_loc
);
977 rescue
= NEW_RESBODY
(0, remove_begin
(rescue
), 0, &loc
);
978 loc.beg_pos
= arg_loc
->beg_pos
;
979 return NEW_RESCUE
(arg
, rescue
, 0, &loc
);
985 restore_defun
(struct parser_params
*p
, NODE
*name
)
987 YYSTYPE c
= {.val
= name
->nd_cval
};
988 p
->cur_arg
= name
->nd_vid
;
989 p
->ctxt.in_def
= c.ctxt.in_def
;
990 p
->ctxt.shareable_constant_value
= c.ctxt.shareable_constant_value
;
994 endless_method_name
(struct parser_params
*p
, NODE
*defn
, const YYLTYPE *loc
)
997 defn
= defn
->nd_defn
;
999 ID mid
= defn
->nd_mid
;
1000 if
(is_attrset_id
(mid
)) {
1001 yyerror1
(loc
, "setter method cannot be defined in an endless method definition");
1003 token_info_drop
(p
, "def", loc
->beg_pos
);
1009 # define ifndef_ripper(x) (x)
1012 # define Qnull Qundef
1013 # define ifndef_ripper(x)
1016 # define rb_warn0(fmt) WARN_CALL(WARN_ARGS(fmt, 1))
1017 # define rb_warn1(fmt,a) WARN_CALL(WARN_ARGS(fmt, 2), (a))
1018 # define rb_warn2(fmt,a,b) WARN_CALL(WARN_ARGS(fmt, 3), (a), (b))
1019 # define rb_warn3(fmt,a,b,c) WARN_CALL(WARN_ARGS(fmt, 4), (a), (b), (c))
1020 # define rb_warn4(fmt,a,b,c,d) WARN_CALL(WARN_ARGS(fmt, 5), (a), (b), (c), (d))
1021 # define rb_warning0(fmt) WARNING_CALL(WARNING_ARGS(fmt, 1))
1022 # define rb_warning1(fmt,a) WARNING_CALL(WARNING_ARGS(fmt, 2), (a))
1023 # define rb_warning2(fmt,a,b) WARNING_CALL(WARNING_ARGS(fmt, 3), (a), (b))
1024 # define rb_warning3(fmt,a,b,c) WARNING_CALL(WARNING_ARGS(fmt, 4), (a), (b), (c))
1025 # define rb_warning4(fmt,a,b,c,d) WARNING_CALL(WARNING_ARGS(fmt, 5), (a), (b), (c), (d))
1026 # define rb_warn0L(l,fmt) WARN_CALL(WARN_ARGS_L(l, fmt, 1))
1027 # define rb_warn1L(l,fmt,a) WARN_CALL(WARN_ARGS_L(l, fmt, 2), (a))
1028 # define rb_warn2L(l,fmt,a,b) WARN_CALL(WARN_ARGS_L(l, fmt, 3), (a), (b))
1029 # define rb_warn3L(l,fmt,a,b,c) WARN_CALL(WARN_ARGS_L(l, fmt, 4), (a), (b), (c))
1030 # define rb_warn4L(l,fmt,a,b,c,d) WARN_CALL(WARN_ARGS_L(l, fmt, 5), (a), (b), (c), (d))
1031 # define rb_warning0L(l,fmt) WARNING_CALL(WARNING_ARGS_L(l, fmt, 1))
1032 # define rb_warning1L(l,fmt,a) WARNING_CALL(WARNING_ARGS_L(l, fmt, 2), (a))
1033 # define rb_warning2L(l,fmt,a,b) WARNING_CALL(WARNING_ARGS_L(l, fmt, 3), (a), (b))
1034 # define rb_warning3L(l,fmt,a,b,c) WARNING_CALL(WARNING_ARGS_L(l, fmt, 4), (a), (b), (c))
1035 # define rb_warning4L(l,fmt,a,b,c,d) WARNING_CALL(WARNING_ARGS_L(l, fmt, 5), (a), (b), (c), (d))
1037 static ID id_warn
, id_warning
, id_gets
, id_assoc
;
1038 # define ERR_MESG() STR_NEW2(mesg) /* to bypass Ripper DSL */
1039 # define WARN_S_L(s,l) STR_NEW(s,l)
1040 # define WARN_S(s) STR_NEW2(s)
1041 # define WARN_I(i) INT2NUM(i)
1042 # define WARN_ID(i) rb_id2str(i)
1043 # define WARN_IVAL(i) i
1044 # define PRIsWARN "s"
1045 # define rb_warn0L_experimental(l,fmt) WARN_CALL(WARN_ARGS_L(l, fmt, 1))
1046 # define WARN_ARGS(fmt,n) p->value, id_warn, n, rb_usascii_str_new_lit(fmt)
1047 # define WARN_ARGS_L(l,fmt,n) WARN_ARGS(fmt,n)
1048 # ifdef HAVE_VA_ARGS_MACRO
1049 # define WARN_CALL(...) rb_funcall(__VA_ARGS__)
1051 # define WARN_CALL rb_funcall
1053 # define WARNING_ARGS(fmt,n) p->value, id_warning, n, rb_usascii_str_new_lit(fmt)
1054 # define WARNING_ARGS_L(l, fmt,n) WARNING_ARGS(fmt,n)
1055 # ifdef HAVE_VA_ARGS_MACRO
1056 # define WARNING_CALL(...) rb_funcall(__VA_ARGS__)
1058 # define WARNING_CALL rb_funcall
1060 PRINTF_ARGS
(static void ripper_compile_error
(struct parser_params
*, const char *fmt
, ...
), 2, 3);
1061 # define compile_error ripper_compile_error
1063 # define WARN_S_L(s,l) s
1064 # define WARN_S(s) s
1065 # define WARN_I(i) i
1066 # define WARN_ID(i) rb_id2name(i)
1067 # define WARN_IVAL(i) NUM2INT(i)
1068 # define PRIsWARN PRIsVALUE
1069 # define WARN_ARGS(fmt,n) WARN_ARGS_L(p->ruby_sourceline,fmt,n)
1070 # define WARN_ARGS_L(l,fmt,n) p->ruby_sourcefile, (l), (fmt)
1071 # define WARN_CALL rb_compile_warn
1072 # define rb_warn0L_experimental(l,fmt) rb_category_compile_warn(RB_WARN_CATEGORY_EXPERIMENTAL, WARN_ARGS_L(l, fmt, 1))
1073 # define WARNING_ARGS(fmt,n) WARN_ARGS(fmt,n)
1074 # define WARNING_ARGS_L(l,fmt,n) WARN_ARGS_L(l,fmt,n)
1075 # define WARNING_CALL rb_compile_warning
1076 PRINTF_ARGS
(static void parser_compile_error
(struct parser_params
*, const char *fmt
, ...
), 2, 3);
1077 # define compile_error parser_compile_error
1080 #define WARN_EOL(tok) \
1081 (looking_at_eol_p
(p
) ? \
1082 (void)rb_warning0
("`" tok
"' at the end of line without an expression") : \
1084 static int looking_at_eol_p
(struct parser_params
*p
);
1089 %define parse.
error verbose
1092 rb_parser_printf
(p
, "%"PRIsVALUE
, rb_id2str
($$
));
1094 rb_parser_printf
(p
, "%"PRIsVALUE
, RNODE
($$
)->nd_rval
);
1096 } tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL tOP_ASGN
1099 rb_parser_printf
(p
, "%+"PRIsVALUE
, $$
->nd_lit
);
1101 rb_parser_printf
(p
, "%+"PRIsVALUE
, get_value
($$
));
1103 } tINTEGER tFLOAT tRATIONAL tIMAGINARY tSTRING_CONTENT tCHAR
1106 rb_parser_printf
(p
, "$%ld", $$
->nd_nth
);
1108 rb_parser_printf
(p
, "%"PRIsVALUE
, $$
);
1113 rb_parser_printf
(p
, "$%c", (int)$$
->nd_nth
);
1115 rb_parser_printf
(p
, "%"PRIsVALUE
, $$
);
1119 %lex
-param
{struct parser_params
*p
}
1120 %parse
-param
{struct parser_params
*p
}
1123 RUBY_SET_YYLLOC_OF_NONE
(@$
);
1132 const struct vtable
*vars
;
1133 struct rb_strterm_struct
*strterm
;
1134 struct lex_context ctxt
;
1138 keyword_class
"`class'"
1139 keyword_module
"`module'"
1141 keyword_undef
"`undef'"
1142 keyword_begin
"`begin'"
1143 keyword_rescue
"`rescue'"
1144 keyword_ensure
"`ensure'"
1147 keyword_unless
"`unless'"
1148 keyword_then
"`then'"
1149 keyword_elsif
"`elsif'"
1150 keyword_else
"`else'"
1151 keyword_case
"`case'"
1152 keyword_when
"`when'"
1153 keyword_while
"`while'"
1154 keyword_until
"`until'"
1156 keyword_break
"`break'"
1157 keyword_next
"`next'"
1158 keyword_redo
"`redo'"
1159 keyword_retry
"`retry'"
1162 keyword_do_cond
"`do' for condition"
1163 keyword_do_block
"`do' for block"
1164 keyword_do_LAMBDA
"`do' for lambda"
1165 keyword_return
"`return'"
1166 keyword_yield
"`yield'"
1167 keyword_super
"`super'"
1168 keyword_self
"`self'"
1170 keyword_true
"`true'"
1171 keyword_false
"`false'"
1175 modifier_if
"`if' modifier"
1176 modifier_unless
"`unless' modifier"
1177 modifier_while
"`while' modifier"
1178 modifier_until
"`until' modifier"
1179 modifier_rescue
"`rescue' modifier"
1180 keyword_alias
"`alias'"
1181 keyword_defined
"`defined?'"
1182 keyword_BEGIN
"`BEGIN'"
1184 keyword__LINE__
"`__LINE__'"
1185 keyword__FILE__
"`__FILE__'"
1186 keyword__ENCODING__
"`__ENCODING__'"
1188 %token
<id
> tIDENTIFIER
"local variable or method"
1189 %token
<id
> tFID
"method"
1190 %token
<id
> tGVAR
"global variable"
1191 %token
<id
> tIVAR
"instance variable"
1192 %token
<id
> tCONSTANT
"constant"
1193 %token
<id
> tCVAR
"class variable"
1194 %token
<id
> tLABEL
"label"
1195 %token
<node
> tINTEGER
"integer literal"
1196 %token
<node
> tFLOAT
"float literal"
1197 %token
<node
> tRATIONAL
"rational literal"
1198 %token
<node
> tIMAGINARY
"imaginary literal"
1199 %token
<node
> tCHAR
"char literal"
1200 %token
<node
> tNTH_REF
"numbered reference"
1201 %token
<node
> tBACK_REF
"back reference"
1202 %token
<node
> tSTRING_CONTENT
"literal content"
1203 %token
<num
> tREGEXP_END
1205 %type
<node
> singleton strings
string string1 xstring regexp
1206 %type
<node
> string_contents xstring_contents regexp_contents string_content
1207 %type
<node
> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
1208 %type
<node
> literal numeric simple_numeric ssym dsym symbol cpath def_name defn_head defs_head
1209 %type
<node
> top_compstmt top_stmts top_stmt begin_block
1210 %type
<node
> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
1211 %type
<node
> expr_value expr_value_do arg_value primary_value fcall rel_expr
1212 %type
<node
> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
1213 %type
<node
> args call_args opt_call_args
1214 %type
<node
> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
1215 %type
<node
> command_args aref_args opt_block_arg block_arg var_ref var_lhs
1216 %type
<node
> command_rhs arg_rhs
1217 %type
<node
> command_asgn mrhs mrhs_arg superclass block_call block_command
1218 %type
<node
> f_block_optarg f_block_opt
1219 %type
<node
> f_arglist f_opt_paren_args f_paren_args f_args f_arg f_arg_item
1220 %type
<node
> f_optarg f_marg f_marg_list f_margs f_rest_marg
1221 %type
<node
> assoc_list assocs assoc undef_list backref string_dvar for_var
1222 %type
<node
> block_param opt_block_param block_param_def f_opt
1223 %type
<node
> f_kwarg f_kw f_block_kwarg f_block_kw
1224 %type
<node
> bv_decls opt_bv_decl bvar
1225 %type
<node
> lambda f_larglist lambda_body brace_body do_body
1226 %type
<node
> brace_block cmd_brace_block do_block lhs none fitem
1227 %type
<node
> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
1228 %type
<node
> p_case_body p_cases p_top_expr p_top_expr_body
1229 %type
<node
> p_expr p_as p_alt p_expr_basic p_find
1230 %type
<node
> p_args p_args_head p_args_tail p_args_post p_arg
1231 %type
<node
> p_value p_primitive p_variable p_var_ref p_expr_ref p_const
1232 %type
<node
> p_kwargs p_kwarg p_kw
1233 %type
<id
> keyword_variable user_variable sym operation operation2 operation3
1234 %type
<id
> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
1235 %type
<id
> f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon
1236 %type
<id
> p_rest p_kwrest p_kwnorest p_any_kwrest p_kw_label
1237 %type
<id
> f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var
1238 %type
<ctxt
> lex_ctxt
/* keep <ctxt> in ripper */
1239 %token END_OF_INPUT
0 "end-of-input"
1241 /* escaped chars, should be ignored otherwise */
1242 %token
<id
> '\\' "backslash"
1243 %token tSP
"escaped space"
1244 %token
<id
> '\t' "escaped horizontal tab"
1245 %token
<id
> '\f' "escaped form feed"
1246 %token
<id
> '\r' "escaped carriage return"
1247 %token
<id
> '\13' "escaped vertical tab"
1248 %token tUPLUS RUBY_TOKEN
(UPLUS
) "unary+"
1249 %token tUMINUS RUBY_TOKEN
(UMINUS
) "unary-"
1250 %token tPOW RUBY_TOKEN
(POW
) "**"
1251 %token tCMP RUBY_TOKEN
(CMP
) "<=>"
1252 %token tEQ RUBY_TOKEN
(EQ
) "=="
1253 %token tEQQ RUBY_TOKEN
(EQQ
) "==="
1254 %token tNEQ RUBY_TOKEN
(NEQ
) "!="
1255 %token tGEQ RUBY_TOKEN
(GEQ
) ">="
1256 %token tLEQ RUBY_TOKEN
(LEQ
) "<="
1257 %token tANDOP RUBY_TOKEN
(ANDOP
) "&&"
1258 %token tOROP RUBY_TOKEN
(OROP
) "||"
1259 %token tMATCH RUBY_TOKEN
(MATCH
) "=~"
1260 %token tNMATCH RUBY_TOKEN
(NMATCH
) "!~"
1261 %token tDOT2 RUBY_TOKEN
(DOT2
) ".."
1262 %token tDOT3 RUBY_TOKEN
(DOT3
) "..."
1263 %token tBDOT2 RUBY_TOKEN
(BDOT2
) "(.."
1264 %token tBDOT3 RUBY_TOKEN
(BDOT3
) "(..."
1265 %token tAREF RUBY_TOKEN
(AREF
) "[]"
1266 %token tASET RUBY_TOKEN
(ASET
) "[]="
1267 %token tLSHFT RUBY_TOKEN
(LSHFT
) "<<"
1268 %token tRSHFT RUBY_TOKEN
(RSHFT
) ">>"
1269 %token
<id
> tANDDOT RUBY_TOKEN
(ANDDOT
) "&."
1270 %token
<id
> tCOLON2 RUBY_TOKEN
(COLON2
) "::"
1271 %token tCOLON3
":: at EXPR_BEG"
1272 %token
<id
> tOP_ASGN
"operator-assignment" /* +=, -= etc. */
1275 %token tLPAREN_ARG
"( arg"
1279 %token tLBRACE_ARG
"{ arg"
1281 %token tDSTAR
"**arg"
1284 %token tSYMBEG
"symbol literal"
1285 %token tSTRING_BEG
"string literal"
1286 %token tXSTRING_BEG
"backtick literal"
1287 %token tREGEXP_BEG
"regexp literal"
1288 %token tWORDS_BEG
"word list"
1289 %token tQWORDS_BEG
"verbatim word list"
1290 %token tSYMBOLS_BEG
"symbol list"
1291 %token tQSYMBOLS_BEG
"verbatim symbol list"
1292 %token tSTRING_END
"terminator"
1293 %token tSTRING_DEND
"'}'"
1294 %token tSTRING_DBEG tSTRING_DVAR tLAMBEG tLABEL_END
1301 %nonassoc tLBRACE_ARG
1303 %nonassoc modifier_if modifier_unless modifier_while modifier_until keyword_in
1304 %left keyword_or keyword_and
1306 %nonassoc keyword_defined
1308 %left modifier_rescue
1310 %nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
1313 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
1314 %left
'>' tGEQ
'<' tLEQ
1320 %right tUMINUS_NUM tUMINUS
1322 %right
'!' '~' tUPLUS
1328 SET_LEX_STATE
(EXPR_BEG
);
1329 local_push
(p
, ifndef_ripper
(1)+0);
1334 if
($2 && !compile_for_eval
) {
1336 /* last expression should not be void */
1337 if
(nd_type_p
(node
, NODE_BLOCK
)) {
1338 while
(node
->nd_next
) {
1339 node
= node
->nd_next
;
1341 node
= node
->nd_head
;
1343 node
= remove_begin
(node
);
1346 p
->eval_tree
= NEW_SCOPE
(0, block_append
(p
, p
->eval_tree
, $2), &@$
);
1348 /*% ripper[final]: program!($2) %*/
1353 top_compstmt
: top_stmts opt_terms
1355 $$
= void_stmts
(p
, $1);
1362 $$
= NEW_BEGIN
(0, &@$
);
1364 /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
1369 $$
= newline_node
($1);
1371 /*% ripper: stmts_add!(stmts_new!, $1) %*/
1373 | top_stmts terms top_stmt
1376 $$
= block_append
(p
, $1, newline_node
($3));
1378 /*% ripper: stmts_add!($1, $3) %*/
1382 $$
= remove_begin
($2);
1387 | keyword_BEGIN begin_block
1393 begin_block
: '{' top_compstmt
'}'
1396 p
->eval_tree_begin
= block_append
(p
, p
->eval_tree_begin
,
1397 NEW_BEGIN
($2, &@$
));
1398 $$
= NEW_BEGIN
(0, &@$
);
1400 /*% ripper: BEGIN!($2) %*/
1406 k_else
{if
(!$2) {yyerror1
(&@
3, "else without rescue is useless");}}
1411 $$
= new_bodystmt
(p
, $1, $2, $5, $6, &@$
);
1413 /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), escape_Qundef($5), escape_Qundef($6)) %*/
1420 $$
= new_bodystmt
(p
, $1, $2, 0, $3, &@$
);
1422 /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), Qnil, escape_Qundef($3)) %*/
1426 compstmt
: stmts opt_terms
1428 $$
= void_stmts
(p
, $1);
1435 $$
= NEW_BEGIN
(0, &@$
);
1437 /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
1442 $$
= newline_node
($1);
1444 /*% ripper: stmts_add!(stmts_new!, $1) %*/
1446 | stmts terms stmt_or_begin
1449 $$
= block_append
(p
, $1, newline_node
($3));
1451 /*% ripper: stmts_add!($1, $3) %*/
1455 $$
= remove_begin
($2);
1459 stmt_or_begin
: stmt
1465 yyerror1
(&@
1, "BEGIN is permitted only at toplevel");
1473 stmt
: keyword_alias fitem
{SET_LEX_STATE
(EXPR_FNAME|EXPR_FITEM
);} fitem
1476 $$
= NEW_ALIAS
($2, $4, &@$
);
1478 /*% ripper: alias!($2, $4) %*/
1480 | keyword_alias tGVAR tGVAR
1483 $$
= NEW_VALIAS
($2, $3, &@$
);
1485 /*% ripper: var_alias!($2, $3) %*/
1487 | keyword_alias tGVAR tBACK_REF
1492 buf
[1] = (char)$3->nd_nth
;
1493 $$
= NEW_VALIAS
($2, rb_intern2
(buf
, 2), &@$
);
1495 /*% ripper: var_alias!($2, $3) %*/
1497 | keyword_alias tGVAR tNTH_REF
1499 static const char mesg
[] = "can't make alias for the number variables";
1501 yyerror1
(&@
3, mesg
);
1502 $$
= NEW_BEGIN
(0, &@$
);
1504 /*% ripper[error]: alias_error!(ERR_MESG(), $3) %*/
1506 | keyword_undef undef_list
1511 /*% ripper: undef!($2) %*/
1513 | stmt modifier_if expr_value
1516 $$
= new_if
(p
, $3, remove_begin
($1), 0, &@$
);
1519 /*% ripper: if_mod!($3, $1) %*/
1521 | stmt modifier_unless expr_value
1524 $$
= new_unless
(p
, $3, remove_begin
($1), 0, &@$
);
1527 /*% ripper: unless_mod!($3, $1) %*/
1529 | stmt modifier_while expr_value
1532 if
($1 && nd_type_p
($1, NODE_BEGIN
)) {
1533 $$
= NEW_WHILE
(cond
(p
, $3, &@
3), $1->nd_body
, 0, &@$
);
1536 $$
= NEW_WHILE
(cond
(p
, $3, &@
3), $1, 1, &@$
);
1539 /*% ripper: while_mod!($3, $1) %*/
1541 | stmt modifier_until expr_value
1544 if
($1 && nd_type_p
($1, NODE_BEGIN
)) {
1545 $$
= NEW_UNTIL
(cond
(p
, $3, &@
3), $1->nd_body
, 0, &@$
);
1548 $$
= NEW_UNTIL
(cond
(p
, $3, &@
3), $1, 1, &@$
);
1551 /*% ripper: until_mod!($3, $1) %*/
1553 | stmt modifier_rescue stmt
1557 YYLTYPE loc
= code_loc_gen
(&@
2, &@
3);
1558 resq
= NEW_RESBODY
(0, remove_begin
($3), 0, &loc
);
1559 $$
= NEW_RESCUE
(remove_begin
($1), resq
, 0, &@$
);
1561 /*% ripper: rescue_mod!($1, $3) %*/
1563 | keyword_END
'{' compstmt
'}'
1565 if
(p
->ctxt.in_def
) {
1566 rb_warn0
("END in method; use at_exit");
1570 NODE
*scope
= NEW_NODE
(
1571 NODE_SCOPE
, 0 /* tbl */, $3 /* body */, 0 /* args */, &@$
);
1572 $$
= NEW_POSTEXE
(scope
, &@$
);
1575 /*% ripper: END!($3) %*/
1578 | mlhs
'=' lex_ctxt command_call
1582 $$
= node_assign
(p
, $1, $4, $3, &@$
);
1584 /*% ripper: massign!($1, $4) %*/
1586 | lhs
'=' lex_ctxt mrhs
1589 $$
= node_assign
(p
, $1, $4, $3, &@$
);
1591 /*% ripper: assign!($1, $4) %*/
1593 | mlhs
'=' lex_ctxt mrhs_arg modifier_rescue stmt
1596 YYLTYPE loc
= code_loc_gen
(&@
5, &@
6);
1597 $$
= node_assign
(p
, $1, NEW_RESCUE
($4, NEW_RESBODY
(0, remove_begin
($6), 0, &loc
), 0, &@$
), $3, &@$
);
1599 /*% ripper: massign!($1, rescue_mod!($4, $6)) %*/
1601 | mlhs
'=' lex_ctxt mrhs_arg
1604 $$
= node_assign
(p
, $1, $4, $3, &@$
);
1606 /*% ripper: massign!($1, $4) %*/
1611 command_asgn
: lhs
'=' lex_ctxt command_rhs
1614 $$
= node_assign
(p
, $1, $4, $3, &@$
);
1616 /*% ripper: assign!($1, $4) %*/
1618 | var_lhs tOP_ASGN lex_ctxt command_rhs
1621 $$
= new_op_assign
(p
, $1, $2, $4, $3, &@$
);
1623 /*% ripper: opassign!($1, $2, $4) %*/
1625 | primary_value
'[' opt_call_args rbracket tOP_ASGN lex_ctxt command_rhs
1628 $$
= new_ary_op_assign
(p
, $1, $3, $5, $7, &@
3, &@$
);
1630 /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/
1633 | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
1636 $$
= new_attr_op_assign
(p
, $1, $2, $3, $4, $6, &@$
);
1638 /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
1640 | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt command_rhs
1643 $$
= new_attr_op_assign
(p
, $1, $2, $3, $4, $6, &@$
);
1645 /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
1647 | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt command_rhs
1650 YYLTYPE loc
= code_loc_gen
(&@
1, &@
3);
1651 $$
= new_const_op_assign
(p
, NEW_COLON2
($1, $3, &loc
), $4, $6, $5, &@$
);
1653 /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
1655 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
1658 $$
= new_attr_op_assign
(p
, $1, ID2VAL
(idCOLON2
), $3, $4, $6, &@$
);
1660 /*% ripper: opassign!(field!($1, ID2VAL(idCOLON2), $3), $4, $6) %*/
1662 | defn_head f_opt_paren_args
'=' command
1664 endless_method_name
(p
, $
<node
>1, &@
1);
1665 restore_defun
(p
, $
<node
>1->nd_defn
);
1667 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
1669 /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
1670 /*% ripper: def!(get_value($1), $2, $4) %*/
1673 | defn_head f_opt_paren_args
'=' command modifier_rescue arg
1675 endless_method_name
(p
, $
<node
>1, &@
1);
1676 restore_defun
(p
, $
<node
>1->nd_defn
);
1678 $4 = rescued_expr
(p
, $4, $6, &@
4, &@
5, &@
6);
1679 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
1681 /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
1682 /*% ripper: def!(get_value($1), $2, $4) %*/
1685 | defs_head f_opt_paren_args
'=' command
1687 endless_method_name
(p
, $
<node
>1, &@
1);
1688 restore_defun
(p
, $
<node
>1->nd_defn
);
1690 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
1694 /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
1695 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
1698 | defs_head f_opt_paren_args
'=' command modifier_rescue arg
1700 endless_method_name
(p
, $
<node
>1, &@
1);
1701 restore_defun
(p
, $
<node
>1->nd_defn
);
1703 $4 = rescued_expr
(p
, $4, $6, &@
4, &@
5, &@
6);
1704 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
1708 /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
1709 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
1712 | backref tOP_ASGN lex_ctxt command_rhs
1715 rb_backref_error
(p
, $1);
1716 $$
= NEW_BEGIN
(0, &@$
);
1718 /*% ripper[error]: backref_error(p, RNODE($1), assign!(var_field(p, $1), $4)) %*/
1722 command_rhs
: command_call %prec tOP_ASGN
1727 | command_call modifier_rescue stmt
1730 YYLTYPE loc
= code_loc_gen
(&@
2, &@
3);
1732 $$
= NEW_RESCUE
($1, NEW_RESBODY
(0, remove_begin
($3), 0, &loc
), 0, &@$
);
1734 /*% ripper: rescue_mod!($1, $3) %*/
1740 | expr keyword_and expr
1742 $$
= logop
(p
, idAND
, $1, $3, &@
2, &@$
);
1744 | expr keyword_or expr
1746 $$
= logop
(p
, idOR
, $1, $3, &@
2, &@$
);
1748 | keyword_not opt_nl expr
1750 $$
= call_uni_op
(p
, method_cond
(p
, $3, &@
3), METHOD_NOT
, &@
1, &@$
);
1754 $$
= call_uni_op
(p
, method_cond
(p
, $2, &@
2), '!', &@
1, &@$
);
1759 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
1760 p
->command_start
= FALSE
;
1762 p
->ctxt.in_kwarg
= 1;
1763 $
<tbl
>$
= push_pvtbl
(p
);
1767 pop_pvtbl
(p
, $
<tbl
>3);
1768 p
->ctxt.in_kwarg
= $
<ctxt
>2.in_kwarg
;
1770 $$
= NEW_CASE3
($1, NEW_IN
($4, 0, 0, &@
4), &@$
);
1772 /*% ripper: case!($1, in!($4, Qnil, Qnil)) %*/
1777 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
1778 p
->command_start
= FALSE
;
1780 p
->ctxt.in_kwarg
= 1;
1781 $
<tbl
>$
= push_pvtbl
(p
);
1785 pop_pvtbl
(p
, $
<tbl
>3);
1786 p
->ctxt.in_kwarg
= $
<ctxt
>1.in_kwarg
;
1788 $$
= NEW_CASE3
($1, NEW_IN
($4, NEW_TRUE
(&@
4), NEW_FALSE
(&@
4), &@
4), &@$
);
1790 /*% ripper: case!($1, in!($4, Qnil, Qnil)) %*/
1792 | arg %prec tLBRACE_ARG
1797 ID fname
= get_id
($1);
1798 ID cur_arg
= p
->cur_arg
;
1799 YYSTYPE c
= {.ctxt
= p
->ctxt
};
1800 numparam_name
(p
, fname
);
1804 $
<node
>$
= NEW_NODE
(NODE_SELF
, /*vid*/cur_arg
, /*mid*/fname
, /*cval*/c.val
, &@$
);
1807 $$ = NEW_RIPPER(fname, get_value($1), $$, &NULL_LOC);
1812 defn_head
: k_def def_name
1816 $$
= NEW_NODE
(NODE_DEFN
, 0, $$
->nd_mid
, $$
, &@$
);
1821 defs_head
: k_def singleton dot_or_colon
1823 SET_LEX_STATE
(EXPR_FNAME
);
1824 p
->ctxt.in_argdef
= 1;
1828 SET_LEX_STATE
(EXPR_ENDFN|EXPR_LABEL
); /* force for args */
1831 $$
= NEW_NODE
(NODE_DEFS
, $2, $$
->nd_mid
, $$
, &@$
);
1833 VALUE ary = rb_ary_new_from_args(3, $2, $3, get_value($$));
1834 add_mark_object(p, ary);
1835 $<node>$->nd_rval = ary;
1847 expr_value_do
: {COND_PUSH
(1);} expr_value do
{COND_POP
();}
1853 command_call
: command
1857 block_command
: block_call
1858 | block_call call_op2 operation2 command_args
1861 $$
= new_qcall
(p
, $2, $1, $3, $4, &@
3, &@$
);
1863 /*% ripper: method_add_arg!(call!($1, $2, $3), $4) %*/
1867 cmd_brace_block
: tLBRACE_ARG brace_body
'}'
1871 $$
->nd_body
->nd_loc
= code_loc_gen
(&@
1, &@
3);
1872 nd_set_line
($$
, @
1.end_pos.lineno
);
1880 $$
= NEW_FCALL
($1, 0, &@$
);
1881 nd_set_line
($$
, p
->tokline
);
1887 command
: fcall command_args %prec tLOWEST
1891 nd_set_last_loc
($1, @
2.end_pos
);
1894 /*% ripper: command!($1, $2) %*/
1896 | fcall command_args cmd_brace_block
1899 block_dup_check
(p
, $2, $3);
1901 $$
= method_add_block
(p
, $1, $3, &@$
);
1903 nd_set_last_loc
($1, @
2.end_pos
);
1905 /*% ripper: method_add_block!(command!($1, $2), $3) %*/
1907 | primary_value call_op operation2 command_args %prec tLOWEST
1910 $$
= new_command_qcall
(p
, $2, $1, $3, $4, Qnull
, &@
3, &@$
);
1912 /*% ripper: command_call!($1, $2, $3, $4) %*/
1914 | primary_value call_op operation2 command_args cmd_brace_block
1917 $$
= new_command_qcall
(p
, $2, $1, $3, $4, $5, &@
3, &@$
);
1919 /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
1921 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1924 $$
= new_command_qcall
(p
, ID2VAL
(idCOLON2
), $1, $3, $4, Qnull
, &@
3, &@$
);
1926 /*% ripper: command_call!($1, ID2VAL(idCOLON2), $3, $4) %*/
1928 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1931 $$
= new_command_qcall
(p
, ID2VAL
(idCOLON2
), $1, $3, $4, $5, &@
3, &@$
);
1933 /*% ripper: method_add_block!(command_call!($1, ID2VAL(idCOLON2), $3, $4), $5) %*/
1935 | keyword_super command_args
1938 $$
= NEW_SUPER
($2, &@$
);
1941 /*% ripper: super!($2) %*/
1943 | keyword_yield command_args
1946 $$
= new_yield
(p
, $2, &@$
);
1949 /*% ripper: yield!($2) %*/
1951 | k_return call_args
1954 $$
= NEW_RETURN
(ret_args
(p
, $2), &@$
);
1956 /*% ripper: return!($2) %*/
1958 | keyword_break call_args
1961 $$
= NEW_BREAK
(ret_args
(p
, $2), &@$
);
1963 /*% ripper: break!($2) %*/
1965 | keyword_next call_args
1968 $$
= NEW_NEXT
(ret_args
(p
, $2), &@$
);
1970 /*% ripper: next!($2) %*/
1975 | tLPAREN mlhs_inner rparen
1980 /*% ripper: mlhs_paren!($2) %*/
1984 mlhs_inner
: mlhs_basic
1985 | tLPAREN mlhs_inner rparen
1988 $$
= NEW_MASGN
(NEW_LIST
($2, &@$
), 0, &@$
);
1990 /*% ripper: mlhs_paren!($2) %*/
1994 mlhs_basic
: mlhs_head
1997 $$
= NEW_MASGN
($1, 0, &@$
);
2001 | mlhs_head mlhs_item
2004 $$
= NEW_MASGN
(list_append
(p
, $1,$2), 0, &@$
);
2006 /*% ripper: mlhs_add!($1, $2) %*/
2008 | mlhs_head tSTAR mlhs_node
2011 $$
= NEW_MASGN
($1, $3, &@$
);
2013 /*% ripper: mlhs_add_star!($1, $3) %*/
2015 | mlhs_head tSTAR mlhs_node
',' mlhs_post
2018 $$
= NEW_MASGN
($1, NEW_POSTARG
($3,$5,&@$
), &@$
);
2020 /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
2025 $$
= NEW_MASGN
($1, NODE_SPECIAL_NO_NAME_REST
, &@$
);
2027 /*% ripper: mlhs_add_star!($1, Qnil) %*/
2029 | mlhs_head tSTAR
',' mlhs_post
2032 $$
= NEW_MASGN
($1, NEW_POSTARG
(NODE_SPECIAL_NO_NAME_REST
, $4, &@$
), &@$
);
2034 /*% ripper: mlhs_add_post!(mlhs_add_star!($1, Qnil), $4) %*/
2039 $$
= NEW_MASGN
(0, $2, &@$
);
2041 /*% ripper: mlhs_add_star!(mlhs_new!, $2) %*/
2043 | tSTAR mlhs_node
',' mlhs_post
2046 $$
= NEW_MASGN
(0, NEW_POSTARG
($2,$4,&@$
), &@$
);
2048 /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $2), $4) %*/
2053 $$
= NEW_MASGN
(0, NODE_SPECIAL_NO_NAME_REST
, &@$
);
2055 /*% ripper: mlhs_add_star!(mlhs_new!, Qnil) %*/
2057 | tSTAR
',' mlhs_post
2060 $$
= NEW_MASGN
(0, NEW_POSTARG
(NODE_SPECIAL_NO_NAME_REST
, $3, &@$
), &@$
);
2062 /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, Qnil), $3) %*/
2066 mlhs_item
: mlhs_node
2067 | tLPAREN mlhs_inner rparen
2072 /*% ripper: mlhs_paren!($2) %*/
2076 mlhs_head
: mlhs_item
','
2079 $$
= NEW_LIST
($1, &@
1);
2081 /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
2083 | mlhs_head mlhs_item
','
2086 $$
= list_append
(p
, $1, $2);
2088 /*% ripper: mlhs_add!($1, $2) %*/
2092 mlhs_post
: mlhs_item
2095 $$
= NEW_LIST
($1, &@$
);
2097 /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
2099 | mlhs_post
',' mlhs_item
2102 $$
= list_append
(p
, $1, $3);
2104 /*% ripper: mlhs_add!($1, $3) %*/
2108 mlhs_node
: user_variable
2111 $$
= assignable
(p
, $1, 0, &@$
);
2113 /*% ripper: assignable(p, var_field(p, $1)) %*/
2118 $$
= assignable
(p
, $1, 0, &@$
);
2120 /*% ripper: assignable(p, var_field(p, $1)) %*/
2122 | primary_value
'[' opt_call_args rbracket
2125 $$
= aryset
(p
, $1, $3, &@$
);
2127 /*% ripper: aref_field!($1, escape_Qundef($3)) %*/
2129 | primary_value call_op tIDENTIFIER
2131 if
($2 == tANDDOT
) {
2132 yyerror1
(&@
2, "&. inside multiple assignment destination");
2135 $$
= attrset
(p
, $1, $2, $3, &@$
);
2137 /*% ripper: field!($1, $2, $3) %*/
2139 | primary_value tCOLON2 tIDENTIFIER
2142 $$
= attrset
(p
, $1, idCOLON2
, $3, &@$
);
2144 /*% ripper: const_path_field!($1, $3) %*/
2146 | primary_value call_op tCONSTANT
2148 if
($2 == tANDDOT
) {
2149 yyerror1
(&@
2, "&. inside multiple assignment destination");
2152 $$
= attrset
(p
, $1, $2, $3, &@$
);
2154 /*% ripper: field!($1, $2, $3) %*/
2156 | primary_value tCOLON2 tCONSTANT
2159 $$
= const_decl
(p
, NEW_COLON2
($1, $3, &@$
), &@$
);
2161 /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
2166 $$
= const_decl
(p
, NEW_COLON3
($2, &@$
), &@$
);
2168 /*% ripper: const_decl(p, top_const_field!($2)) %*/
2173 rb_backref_error
(p
, $1);
2174 $$
= NEW_BEGIN
(0, &@$
);
2176 /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
2183 $$
= assignable
(p
, $1, 0, &@$
);
2185 /*% ripper: assignable(p, var_field(p, $1)) %*/
2190 $$
= assignable
(p
, $1, 0, &@$
);
2192 /*% ripper: assignable(p, var_field(p, $1)) %*/
2194 | primary_value
'[' opt_call_args rbracket
2197 $$
= aryset
(p
, $1, $3, &@$
);
2199 /*% ripper: aref_field!($1, escape_Qundef($3)) %*/
2201 | primary_value call_op tIDENTIFIER
2204 $$
= attrset
(p
, $1, $2, $3, &@$
);
2206 /*% ripper: field!($1, $2, $3) %*/
2208 | primary_value tCOLON2 tIDENTIFIER
2211 $$
= attrset
(p
, $1, idCOLON2
, $3, &@$
);
2213 /*% ripper: field!($1, ID2VAL(idCOLON2), $3) %*/
2215 | primary_value call_op tCONSTANT
2218 $$
= attrset
(p
, $1, $2, $3, &@$
);
2220 /*% ripper: field!($1, $2, $3) %*/
2222 | primary_value tCOLON2 tCONSTANT
2225 $$
= const_decl
(p
, NEW_COLON2
($1, $3, &@$
), &@$
);
2227 /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
2232 $$
= const_decl
(p
, NEW_COLON3
($2, &@$
), &@$
);
2234 /*% ripper: const_decl(p, top_const_field!($2)) %*/
2239 rb_backref_error
(p
, $1);
2240 $$
= NEW_BEGIN
(0, &@$
);
2242 /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
2248 static const char mesg
[] = "class/module name must be CONSTANT";
2250 yyerror1
(&@
1, mesg
);
2252 /*% ripper[error]: class_name_error!(ERR_MESG(), $1) %*/
2257 cpath
: tCOLON3 cname
2260 $$
= NEW_COLON3
($2, &@$
);
2262 /*% ripper: top_const_ref!($2) %*/
2267 $$
= NEW_COLON2
(0, $$
, &@$
);
2269 /*% ripper: const_ref!($1) %*/
2271 | primary_value tCOLON2 cname
2274 $$
= NEW_COLON2
($1, $3, &@$
);
2276 /*% ripper: const_path_ref!($1, $3) %*/
2285 SET_LEX_STATE
(EXPR_ENDFN
);
2294 $$
= NEW_LIT
(ID2SYM
($1), &@$
);
2296 /*% ripper: symbol_literal!($1) %*/
2304 $$
= NEW_UNDEF
($1, &@$
);
2306 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
2308 | undef_list
',' {SET_LEX_STATE
(EXPR_FNAME|EXPR_FITEM
);} fitem
2311 NODE
*undef
= NEW_UNDEF
($4, &@
4);
2312 $$
= block_append
(p
, $1, undef
);
2314 /*% ripper: rb_ary_push($1, get_value($4)) %*/
2318 op
: '|' { ifndef_ripper
($$
= '|'); }
2319 |
'^' { ifndef_ripper
($$
= '^'); }
2320 |
'&' { ifndef_ripper
($$
= '&'); }
2321 | tCMP
{ ifndef_ripper
($$
= tCMP
); }
2322 | tEQ
{ ifndef_ripper
($$
= tEQ
); }
2323 | tEQQ
{ ifndef_ripper
($$
= tEQQ
); }
2324 | tMATCH
{ ifndef_ripper
($$
= tMATCH
); }
2325 | tNMATCH
{ ifndef_ripper
($$
= tNMATCH
); }
2326 |
'>' { ifndef_ripper
($$
= '>'); }
2327 | tGEQ
{ ifndef_ripper
($$
= tGEQ
); }
2328 |
'<' { ifndef_ripper
($$
= '<'); }
2329 | tLEQ
{ ifndef_ripper
($$
= tLEQ
); }
2330 | tNEQ
{ ifndef_ripper
($$
= tNEQ
); }
2331 | tLSHFT
{ ifndef_ripper
($$
= tLSHFT
); }
2332 | tRSHFT
{ ifndef_ripper
($$
= tRSHFT
); }
2333 |
'+' { ifndef_ripper
($$
= '+'); }
2334 |
'-' { ifndef_ripper
($$
= '-'); }
2335 |
'*' { ifndef_ripper
($$
= '*'); }
2336 | tSTAR
{ ifndef_ripper
($$
= '*'); }
2337 |
'/' { ifndef_ripper
($$
= '/'); }
2338 |
'%' { ifndef_ripper
($$
= '%'); }
2339 | tPOW
{ ifndef_ripper
($$
= tPOW
); }
2340 | tDSTAR
{ ifndef_ripper
($$
= tDSTAR
); }
2341 |
'!' { ifndef_ripper
($$
= '!'); }
2342 |
'~' { ifndef_ripper
($$
= '~'); }
2343 | tUPLUS
{ ifndef_ripper
($$
= tUPLUS
); }
2344 | tUMINUS
{ ifndef_ripper
($$
= tUMINUS
); }
2345 | tAREF
{ ifndef_ripper
($$
= tAREF
); }
2346 | tASET
{ ifndef_ripper
($$
= tASET
); }
2347 |
'`' { ifndef_ripper
($$
= '`'); }
2350 reswords
: keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
2351 | keyword_BEGIN | keyword_END
2352 | keyword_alias | keyword_and | keyword_begin
2353 | keyword_break | keyword_case | keyword_class | keyword_def
2354 | keyword_defined | keyword_do | keyword_else | keyword_elsif
2355 | keyword_end | keyword_ensure | keyword_false
2356 | keyword_for | keyword_in | keyword_module | keyword_next
2357 | keyword_nil | keyword_not | keyword_or | keyword_redo
2358 | keyword_rescue | keyword_retry | keyword_return | keyword_self
2359 | keyword_super | keyword_then | keyword_true | keyword_undef
2360 | keyword_when | keyword_yield | keyword_if | keyword_unless
2361 | keyword_while | keyword_until
2364 arg
: lhs
'=' lex_ctxt arg_rhs
2367 $$
= node_assign
(p
, $1, $4, $3, &@$
);
2369 /*% ripper: assign!($1, $4) %*/
2371 | var_lhs tOP_ASGN lex_ctxt arg_rhs
2374 $$
= new_op_assign
(p
, $1, $2, $4, $3, &@$
);
2376 /*% ripper: opassign!($1, $2, $4) %*/
2378 | primary_value
'[' opt_call_args rbracket tOP_ASGN lex_ctxt arg_rhs
2381 $$
= new_ary_op_assign
(p
, $1, $3, $5, $7, &@
3, &@$
);
2383 /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/
2385 | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
2388 $$
= new_attr_op_assign
(p
, $1, $2, $3, $4, $6, &@$
);
2390 /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
2392 | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt arg_rhs
2395 $$
= new_attr_op_assign
(p
, $1, $2, $3, $4, $6, &@$
);
2397 /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
2399 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
2402 $$
= new_attr_op_assign
(p
, $1, ID2VAL
(idCOLON2
), $3, $4, $6, &@$
);
2404 /*% ripper: opassign!(field!($1, ID2VAL(idCOLON2), $3), $4, $6) %*/
2406 | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
2409 YYLTYPE loc
= code_loc_gen
(&@
1, &@
3);
2410 $$
= new_const_op_assign
(p
, NEW_COLON2
($1, $3, &loc
), $4, $6, $5, &@$
);
2412 /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
2414 | tCOLON3 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
2417 YYLTYPE loc
= code_loc_gen
(&@
1, &@
2);
2418 $$
= new_const_op_assign
(p
, NEW_COLON3
($2, &loc
), $3, $5, $4, &@$
);
2420 /*% ripper: opassign!(top_const_field!($2), $3, $5) %*/
2422 | backref tOP_ASGN lex_ctxt arg_rhs
2425 rb_backref_error
(p
, $1);
2426 $$
= NEW_BEGIN
(0, &@$
);
2428 /*% ripper[error]: backref_error(p, RNODE($1), opassign!(var_field(p, $1), $2, $4)) %*/
2435 $$
= NEW_DOT2
($1, $3, &@$
);
2437 /*% ripper: dot2!($1, $3) %*/
2444 $$
= NEW_DOT3
($1, $3, &@$
);
2446 /*% ripper: dot3!($1, $3) %*/
2452 $$
= NEW_DOT2
($1, new_nil_at
(p
, &@
2.end_pos
), &@$
);
2454 /*% ripper: dot2!($1, Qnil) %*/
2460 $$
= NEW_DOT3
($1, new_nil_at
(p
, &@
2.end_pos
), &@$
);
2462 /*% ripper: dot3!($1, Qnil) %*/
2468 $$
= NEW_DOT2
(new_nil_at
(p
, &@
1.beg_pos
), $2, &@$
);
2470 /*% ripper: dot2!(Qnil, $2) %*/
2476 $$
= NEW_DOT3
(new_nil_at
(p
, &@
1.beg_pos
), $2, &@$
);
2478 /*% ripper: dot3!(Qnil, $2) %*/
2482 $$
= call_bin_op
(p
, $1, '+', $3, &@
2, &@$
);
2486 $$
= call_bin_op
(p
, $1, '-', $3, &@
2, &@$
);
2490 $$
= call_bin_op
(p
, $1, '*', $3, &@
2, &@$
);
2494 $$
= call_bin_op
(p
, $1, '/', $3, &@
2, &@$
);
2498 $$
= call_bin_op
(p
, $1, '%', $3, &@
2, &@$
);
2502 $$
= call_bin_op
(p
, $1, idPow
, $3, &@
2, &@$
);
2504 | tUMINUS_NUM simple_numeric tPOW arg
2506 $$
= call_uni_op
(p
, call_bin_op
(p
, $2, idPow
, $4, &@
2, &@$
), idUMinus
, &@
1, &@$
);
2510 $$
= call_uni_op
(p
, $2, idUPlus
, &@
1, &@$
);
2514 $$
= call_uni_op
(p
, $2, idUMinus
, &@
1, &@$
);
2518 $$
= call_bin_op
(p
, $1, '|', $3, &@
2, &@$
);
2522 $$
= call_bin_op
(p
, $1, '^', $3, &@
2, &@$
);
2526 $$
= call_bin_op
(p
, $1, '&', $3, &@
2, &@$
);
2530 $$
= call_bin_op
(p
, $1, idCmp
, $3, &@
2, &@$
);
2532 | rel_expr %prec tCMP
2535 $$
= call_bin_op
(p
, $1, idEq
, $3, &@
2, &@$
);
2539 $$
= call_bin_op
(p
, $1, idEqq
, $3, &@
2, &@$
);
2543 $$
= call_bin_op
(p
, $1, idNeq
, $3, &@
2, &@$
);
2547 $$
= match_op
(p
, $1, $3, &@
2, &@$
);
2551 $$
= call_bin_op
(p
, $1, idNeqTilde
, $3, &@
2, &@$
);
2555 $$
= call_uni_op
(p
, method_cond
(p
, $2, &@
2), '!', &@
1, &@$
);
2559 $$
= call_uni_op
(p
, $2, '~', &@
1, &@$
);
2563 $$
= call_bin_op
(p
, $1, idLTLT
, $3, &@
2, &@$
);
2567 $$
= call_bin_op
(p
, $1, idGTGT
, $3, &@
2, &@$
);
2571 $$
= logop
(p
, idANDOP
, $1, $3, &@
2, &@$
);
2575 $$
= logop
(p
, idOROP
, $1, $3, &@
2, &@$
);
2577 | keyword_defined opt_nl
{p
->ctxt.in_defined
= 1;} arg
2579 p
->ctxt.in_defined
= 0;
2580 $$
= new_defined
(p
, $4, &@$
);
2582 | arg
'?' arg opt_nl
':' arg
2586 $$
= new_if
(p
, $1, $3, $6, &@$
);
2589 /*% ripper: ifop!($1, $3, $6) %*/
2591 | defn_head f_opt_paren_args
'=' arg
2593 endless_method_name
(p
, $
<node
>1, &@
1);
2594 restore_defun
(p
, $
<node
>1->nd_defn
);
2596 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
2598 /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
2599 /*% ripper: def!(get_value($1), $2, $4) %*/
2602 | defn_head f_opt_paren_args
'=' arg modifier_rescue arg
2604 endless_method_name
(p
, $
<node
>1, &@
1);
2605 restore_defun
(p
, $
<node
>1->nd_defn
);
2607 $4 = rescued_expr
(p
, $4, $6, &@
4, &@
5, &@
6);
2608 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
2610 /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
2611 /*% ripper: def!(get_value($1), $2, $4) %*/
2614 | defs_head f_opt_paren_args
'=' arg
2616 endless_method_name
(p
, $
<node
>1, &@
1);
2617 restore_defun
(p
, $
<node
>1->nd_defn
);
2619 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
2623 /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
2624 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
2627 | defs_head f_opt_paren_args
'=' arg modifier_rescue arg
2629 endless_method_name
(p
, $
<node
>1, &@
1);
2630 restore_defun
(p
, $
<node
>1->nd_defn
);
2632 $4 = rescued_expr
(p
, $4, $6, &@
4, &@
5, &@
6);
2633 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
2637 /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
2638 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
2647 relop
: '>' {$$
= '>';}
2653 rel_expr
: arg relop arg %prec
'>'
2655 $$
= call_bin_op
(p
, $1, $2, $3, &@
2, &@$
);
2657 | rel_expr relop arg %prec
'>'
2659 rb_warning1
("comparison '%s' after comparison", WARN_ID
($2));
2660 $$
= call_bin_op
(p
, $1, $2, $3, &@
2, &@$
);
2686 | args
',' assocs trailer
2689 $$
= $3 ? arg_append
(p
, $1, new_hash
(p
, $3, &@
3), &@$
) : $1;
2691 /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
2696 $$
= $1 ? NEW_LIST
(new_hash
(p
, $1, &@
1), &@$
) : 0;
2698 /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
2702 arg_rhs
: arg %prec tOP_ASGN
2707 | arg modifier_rescue arg
2711 $$
= rescued_expr
(p
, $1, $3, &@
1, &@
2, &@
3);
2713 /*% ripper: rescue_mod!($1, $3) %*/
2717 paren_args
: '(' opt_call_args rparen
2722 /*% ripper: arg_paren!(escape_Qundef($2)) %*/
2724 |
'(' args
',' args_forward rparen
2726 if
(!check_forwarding_args
(p
)) {
2731 $$
= new_args_forward_call
(p
, $2, &@
4, &@$
);
2733 /*% ripper: arg_paren!(args_add!($2, $4)) %*/
2736 |
'(' args_forward rparen
2738 if
(!check_forwarding_args
(p
)) {
2743 $$
= new_args_forward_call
(p
, 0, &@
2, &@$
);
2745 /*% ripper: arg_paren!($2) %*/
2750 opt_paren_args
: none
2754 opt_call_args
: none
2760 | args
',' assocs
','
2763 $$
= $3 ? arg_append
(p
, $1, new_hash
(p
, $3, &@
3), &@$
) : $1;
2765 /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
2770 $$
= $1 ? NEW_LIST
(new_hash
(p
, $1, &@
1), &@
1) : 0;
2772 /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
2780 $$
= NEW_LIST
($1, &@$
);
2782 /*% ripper: args_add!(args_new!, $1) %*/
2784 | args opt_block_arg
2787 $$
= arg_blk_pass
($1, $2);
2789 /*% ripper: args_add_block!($1, $2) %*/
2791 | assocs opt_block_arg
2794 $$
= $1 ? NEW_LIST
(new_hash
(p
, $1, &@
1), &@
1) : 0;
2795 $$
= arg_blk_pass
($$
, $2);
2797 /*% ripper: args_add_block!(args_add!(args_new!, bare_assoc_hash!($1)), $2) %*/
2799 | args
',' assocs opt_block_arg
2802 $$
= $3 ? arg_append
(p
, $1, new_hash
(p
, $3, &@
3), &@$
) : $1;
2803 $$
= arg_blk_pass
($$
, $4);
2805 /*% ripper: args_add_block!(args_add!($1, bare_assoc_hash!($3)), $4) %*/
2808 /*% ripper[brace]: args_add_block!(args_new!, $1) %*/
2812 /* If call_args starts with a open paren '(' or '[',
2813 * look-ahead reading of the letters calls CMDARG_PUSH(0),
2814 * but the push must be done after CMDARG_PUSH(1).
2815 * So this code makes them consistent by first cancelling
2816 * the premature CMDARG_PUSH(0), doing CMDARG_PUSH(1),
2817 * and finally redoing CMDARG_PUSH(0).
2821 case
'(': case tLPAREN
: case tLPAREN_ARG
: case
'[': case tLBRACK
:
2824 if
(lookahead
) CMDARG_POP
();
2826 if
(lookahead
) CMDARG_PUSH
(0);
2830 /* call_args can be followed by tLBRACE_ARG (that does CMDARG_PUSH(0) in the lexer)
2831 * but the push must be done after CMDARG_POP() in the parser.
2832 * So this code does CMDARG_POP() to pop 0 pushed by tLBRACE_ARG,
2833 * CMDARG_POP() to pop 1 pushed by command_args,
2834 * and CMDARG_PUSH(0) to restore back the flag set by tLBRACE_ARG.
2841 if
(lookahead
) CMDARG_POP
();
2843 if
(lookahead
) CMDARG_PUSH
(0);
2848 block_arg
: tAMPER arg_value
2851 $$
= NEW_BLOCK_PASS
($2, &@$
);
2858 if
(!local_id
(p
, ANON_BLOCK_ID
)) {
2859 compile_error
(p
, "no anonymous block parameter");
2861 $$
= NEW_BLOCK_PASS
(NEW_LVAR
(ANON_BLOCK_ID
, &@
1), &@$
);
2868 opt_block_arg
: ',' block_arg
2882 $$
= NEW_LIST
($1, &@$
);
2884 /*% ripper: args_add!(args_new!, $1) %*/
2889 $$
= NEW_SPLAT
($2, &@$
);
2891 /*% ripper: args_add_star!(args_new!, $2) %*/
2893 | args
',' arg_value
2896 $$
= last_arg_append
(p
, $1, $3, &@$
);
2898 /*% ripper: args_add!($1, $3) %*/
2900 | args
',' tSTAR arg_value
2903 $$
= rest_arg_append
(p
, $1, $4, &@$
);
2905 /*% ripper: args_add_star!($1, $4) %*/
2915 mrhs
: args
',' arg_value
2918 $$
= last_arg_append
(p
, $1, $3, &@$
);
2920 /*% ripper: mrhs_add!(mrhs_new_from_args!($1), $3) %*/
2922 | args
',' tSTAR arg_value
2925 $$
= rest_arg_append
(p
, $1, $4, &@$
);
2927 /*% ripper: mrhs_add_star!(mrhs_new_from_args!($1), $4) %*/
2932 $$
= NEW_SPLAT
($2, &@$
);
2934 /*% ripper: mrhs_add_star!(mrhs_new!, $2) %*/
2951 $$
= NEW_FCALL
($1, 0, &@$
);
2953 /*% ripper: method_add_arg!(fcall!($1), args_new!) %*/
2964 set_line_body
($3, @
1.end_pos.lineno
);
2965 $$
= NEW_BEGIN
($3, &@$
);
2966 nd_set_line
($$
, @
1.end_pos.lineno
);
2968 /*% ripper: begin!($3) %*/
2970 | tLPAREN_ARG
{SET_LEX_STATE
(EXPR_ENDARG
);} rparen
2973 $$
= NEW_BEGIN
(0, &@$
);
2975 /*% ripper: paren!(0) %*/
2977 | tLPAREN_ARG stmt
{SET_LEX_STATE
(EXPR_ENDARG
);} rparen
2980 if
(nd_type_p
($2, NODE_SELF
)) $2->nd_state
= 0;
2983 /*% ripper: paren!($2) %*/
2985 | tLPAREN compstmt
')'
2988 if
(nd_type_p
($2, NODE_SELF
)) $2->nd_state
= 0;
2991 /*% ripper: paren!($2) %*/
2993 | primary_value tCOLON2 tCONSTANT
2996 $$
= NEW_COLON2
($1, $3, &@$
);
2998 /*% ripper: const_path_ref!($1, $3) %*/
3003 $$
= NEW_COLON3
($2, &@$
);
3005 /*% ripper: top_const_ref!($2) %*/
3007 | tLBRACK aref_args
']'
3010 $$
= make_list
($2, &@$
);
3012 /*% ripper: array!(escape_Qundef($2)) %*/
3014 | tLBRACE assoc_list
'}'
3017 $$
= new_hash
(p
, $2, &@$
);
3018 $$
->nd_brace
= TRUE
;
3020 /*% ripper: hash!(escape_Qundef($2)) %*/
3025 $$
= NEW_RETURN
(0, &@$
);
3027 /*% ripper: return0! %*/
3029 | keyword_yield
'(' call_args rparen
3032 $$
= new_yield
(p
, $3, &@$
);
3034 /*% ripper: yield!(paren!($3)) %*/
3036 | keyword_yield
'(' rparen
3039 $$
= NEW_YIELD
(0, &@$
);
3041 /*% ripper: yield!(paren!(args_new!)) %*/
3046 $$
= NEW_YIELD
(0, &@$
);
3048 /*% ripper: yield0! %*/
3050 | keyword_defined opt_nl
'(' {p
->ctxt.in_defined
= 1;} expr rparen
3052 p
->ctxt.in_defined
= 0;
3053 $$
= new_defined
(p
, $5, &@$
);
3055 | keyword_not
'(' expr rparen
3057 $$
= call_uni_op
(p
, method_cond
(p
, $3, &@
3), METHOD_NOT
, &@
1, &@$
);
3059 | keyword_not
'(' rparen
3061 $$
= call_uni_op
(p
, method_cond
(p
, new_nil
(&@
2), &@
2), METHOD_NOT
, &@
1, &@$
);
3066 $$
= method_add_block
(p
, $1, $2, &@$
);
3068 /*% ripper: method_add_block!(method_add_arg!(fcall!($1), args_new!), $2) %*/
3071 | method_call brace_block
3074 block_dup_check
(p
, $1->nd_args
, $2);
3075 $$
= method_add_block
(p
, $1, $2, &@$
);
3077 /*% ripper: method_add_block!($1, $2) %*/
3080 | k_if expr_value then
3086 $$
= new_if
(p
, $2, $4, $5, &@$
);
3089 /*% ripper: if!($2, $4, escape_Qundef($5)) %*/
3091 | k_unless expr_value then
3097 $$
= new_unless
(p
, $2, $4, $5, &@$
);
3100 /*% ripper: unless!($2, $4, escape_Qundef($5)) %*/
3102 | k_while expr_value_do
3107 $$
= NEW_WHILE
(cond
(p
, $2, &@
2), $3, 1, &@$
);
3110 /*% ripper: while!($2, $3) %*/
3112 | k_until expr_value_do
3117 $$
= NEW_UNTIL
(cond
(p
, $2, &@
2), $3, 1, &@$
);
3120 /*% ripper: until!($2, $3) %*/
3122 | k_case expr_value opt_terms
3124 $
<val
>$
= p
->case_labels
;
3125 p
->case_labels
= Qnil
;
3130 if
(RTEST
(p
->case_labels
)) rb_hash_clear
(p
->case_labels
);
3131 p
->case_labels
= $
<val
>4;
3133 $$
= NEW_CASE
($2, $5, &@$
);
3136 /*% ripper: case!($2, $5) %*/
3140 $
<val
>$
= p
->case_labels
;
3146 if
(RTEST
(p
->case_labels
)) rb_hash_clear
(p
->case_labels
);
3147 p
->case_labels
= $
<val
>3;
3149 $$
= NEW_CASE2
($4, &@$
);
3151 /*% ripper: case!(Qnil, $4) %*/
3153 | k_case expr_value opt_terms
3158 $$
= NEW_CASE3
($2, $4, &@$
);
3160 /*% ripper: case!($2, $4) %*/
3162 | k_for for_var keyword_in expr_value_do
3170 * e.each{|*x| a, b, c = x}
3174 * e.each{|x| a, = x}
3176 ID id
= internal_id
(p
);
3177 NODE
*m
= NEW_ARGS_AUX
(0, 0, &NULL_LOC
);
3178 NODE
*args
, *scope
, *internal_var
= NEW_DVAR
(id
, &@
2);
3179 rb_ast_id_table_t
*tbl
= rb_ast_new_local_table
(p
->ast
, 1);
3180 tbl
->ids
[0] = id
; /* internal id */
3182 switch
(nd_type
($2)) {
3184 case NODE_DASGN
: /* e.each {|internal_var| a = internal_var; ... } */
3185 $2->nd_value
= internal_var
;
3190 case NODE_MASGN
: /* e.each {|*internal_var| a, b, c = (internal_var.length == 1 && Array === (tmp = internal_var[0]) ? tmp : internal_var); ... } */
3191 m
->nd_next
= node_assign
(p
, $2, NEW_FOR_MASGN
(internal_var
, &@
2), NO_LEX_CTXT
, &@
2);
3193 default
: /* e.each {|*internal_var| @a, B, c[1], d.attr = internal_val; ... } */
3194 m
->nd_next
= node_assign
(p
, NEW_MASGN
(NEW_LIST
($2, &@
2), 0, &@
2), internal_var
, NO_LEX_CTXT
, &@
2);
3196 /* {|*internal_id| <m> = internal_id; ... } */
3197 args
= new_args
(p
, m
, 0, id
, 0, new_args_tail
(p
, 0, 0, 0, &@
2), &@
2);
3198 scope
= NEW_NODE
(NODE_SCOPE
, tbl
, $5, args
, &@$
);
3199 $$
= NEW_FOR
($4, scope
, &@$
);
3202 /*% ripper: for!($2, $4, $5) %*/
3204 | k_class cpath superclass
3206 if
(p
->ctxt.in_def
) {
3207 YYLTYPE loc
= code_loc_gen
(&@
1, &@
2);
3208 yyerror1
(&loc
, "class definition in method body");
3210 p
->ctxt.in_class
= 1;
3217 $$
= NEW_CLASS
($2, $5, $3, &@$
);
3218 nd_set_line
($$
->nd_body
, @
6.end_pos.lineno
);
3219 set_line_body
($5, @
3.end_pos.lineno
);
3220 nd_set_line
($$
, @
3.end_pos.lineno
);
3222 /*% ripper: class!($2, $3, $5) %*/
3224 p
->ctxt.in_class
= $
<ctxt
>1.in_class
;
3225 p
->ctxt.shareable_constant_value
= $
<ctxt
>1.shareable_constant_value
;
3227 | k_class tLSHFT expr
3230 p
->ctxt.in_class
= 0;
3238 $$
= NEW_SCLASS
($3, $6, &@$
);
3239 nd_set_line
($$
->nd_body
, @
7.end_pos.lineno
);
3240 set_line_body
($6, nd_line
($3));
3243 /*% ripper: sclass!($3, $6) %*/
3245 p
->ctxt.in_def
= $
<ctxt
>1.in_def
;
3246 p
->ctxt.in_class
= $
<ctxt
>1.in_class
;
3247 p
->ctxt.shareable_constant_value
= $
<ctxt
>1.shareable_constant_value
;
3251 if
(p
->ctxt.in_def
) {
3252 YYLTYPE loc
= code_loc_gen
(&@
1, &@
2);
3253 yyerror1
(&loc
, "module definition in method body");
3255 p
->ctxt.in_class
= 1;
3262 $$
= NEW_MODULE
($2, $4, &@$
);
3263 nd_set_line
($$
->nd_body
, @
5.end_pos.lineno
);
3264 set_line_body
($4, @
2.end_pos.lineno
);
3265 nd_set_line
($$
, @
2.end_pos.lineno
);
3267 /*% ripper: module!($2, $4) %*/
3269 p
->ctxt.in_class
= $
<ctxt
>1.in_class
;
3270 p
->ctxt.shareable_constant_value
= $
<ctxt
>1.shareable_constant_value
;
3277 restore_defun
(p
, $
<node
>1->nd_defn
);
3279 $$
= set_defun_body
(p
, $1, $2, $3, &@$
);
3281 /*% ripper: def!(get_value($1), $2, $3) %*/
3289 restore_defun
(p
, $
<node
>1->nd_defn
);
3291 $$
= set_defun_body
(p
, $1, $2, $3, &@$
);
3295 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $3) %*/
3301 $$
= NEW_BREAK
(0, &@$
);
3303 /*% ripper: break!(args_new!) %*/
3308 $$
= NEW_NEXT
(0, &@$
);
3310 /*% ripper: next!(args_new!) %*/
3317 /*% ripper: redo! %*/
3322 $$
= NEW_RETRY
(&@$
);
3324 /*% ripper: retry! %*/
3328 primary_value
: primary
3335 k_begin
: keyword_begin
3337 token_info_push
(p
, "begin", &@$
);
3344 token_info_push
(p
, "if", &@$
);
3345 if
(p
->token_info
&& p
->token_info
->nonspc
&&
3346 p
->token_info
->next
&& !strcmp
(p
->token_info
->next
->token
, "else")) {
3347 const char *tok
= p
->lex.ptok
;
3348 const char *beg
= p
->lex.pbeg
+ p
->token_info
->next
->beg.column
;
3349 beg
+= rb_strlen_lit
("else");
3350 while
(beg
< tok
&& ISSPACE
(*beg
)) beg
++;
3352 p
->token_info
->nonspc
= 0;
3358 k_unless
: keyword_unless
3360 token_info_push
(p
, "unless", &@$
);
3364 k_while
: keyword_while
3366 token_info_push
(p
, "while", &@$
);
3370 k_until
: keyword_until
3372 token_info_push
(p
, "until", &@$
);
3376 k_case
: keyword_case
3378 token_info_push
(p
, "case", &@$
);
3384 token_info_push
(p
, "for", &@$
);
3388 k_class
: keyword_class
3390 token_info_push
(p
, "class", &@$
);
3395 k_module
: keyword_module
3397 token_info_push
(p
, "module", &@$
);
3404 token_info_push
(p
, "def", &@$
);
3405 p
->ctxt.in_argdef
= 1;
3411 token_info_push
(p
, "do", &@$
);
3415 k_do_block
: keyword_do_block
3417 token_info_push
(p
, "do", &@$
);
3421 k_rescue
: keyword_rescue
3423 token_info_warn
(p
, "rescue", p
->token_info
, 1, &@$
);
3427 k_ensure
: keyword_ensure
3429 token_info_warn
(p
, "ensure", p
->token_info
, 1, &@$
);
3433 k_when
: keyword_when
3435 token_info_warn
(p
, "when", p
->token_info
, 0, &@$
);
3439 k_else
: keyword_else
3441 token_info
*ptinfo_beg
= p
->token_info
;
3442 int same
= ptinfo_beg
&& strcmp
(ptinfo_beg
->token
, "case") != 0;
3443 token_info_warn
(p
, "else", p
->token_info
, same
, &@$
);
3446 e.next
= ptinfo_beg
->next
;
3448 token_info_setup
(&e
, p
->lex.pbeg
, &@$
);
3449 if
(!e.nonspc
) *ptinfo_beg
= e
;
3454 k_elsif
: keyword_elsif
3457 token_info_warn
(p
, "elsif", p
->token_info
, 1, &@$
);
3463 token_info_pop
(p
, "end", &@$
);
3467 k_return
: keyword_return
3469 if
(p
->ctxt.in_class
&& !p
->ctxt.in_def
&& !dyna_in_block
(p
))
3470 yyerror1
(&@
1, "Invalid return in class/module body");
3484 | k_elsif expr_value then
3489 $$
= new_if
(p
, $2, $4, $5, &@$
);
3492 /*% ripper: elsif!($2, $4, escape_Qundef($5)) %*/
3502 /*% ripper: else!($2) %*/
3513 $$
= assignable
(p
, $1, 0, &@$
);
3514 mark_lvar_used
(p
, $$
);
3516 /*% ripper: assignable(p, $1) %*/
3518 | tLPAREN f_margs rparen
3523 /*% ripper: mlhs_paren!($2) %*/
3527 f_marg_list
: f_marg
3530 $$
= NEW_LIST
($1, &@$
);
3532 /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
3534 | f_marg_list
',' f_marg
3537 $$
= list_append
(p
, $1, $3);
3539 /*% ripper: mlhs_add!($1, $3) %*/
3543 f_margs
: f_marg_list
3546 $$
= NEW_MASGN
($1, 0, &@$
);
3550 | f_marg_list
',' f_rest_marg
3553 $$
= NEW_MASGN
($1, $3, &@$
);
3555 /*% ripper: mlhs_add_star!($1, $3) %*/
3557 | f_marg_list
',' f_rest_marg
',' f_marg_list
3560 $$
= NEW_MASGN
($1, NEW_POSTARG
($3, $5, &@$
), &@$
);
3562 /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
3567 $$
= NEW_MASGN
(0, $1, &@$
);
3569 /*% ripper: mlhs_add_star!(mlhs_new!, $1) %*/
3571 | f_rest_marg
',' f_marg_list
3574 $$
= NEW_MASGN
(0, NEW_POSTARG
($1, $3, &@$
), &@$
);
3576 /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $1), $3) %*/
3580 f_rest_marg
: tSTAR f_norm_arg
3583 $$
= assignable
(p
, $2, 0, &@$
);
3584 mark_lvar_used
(p
, $$
);
3586 /*% ripper: assignable(p, $2) %*/
3591 $$
= NODE_SPECIAL_NO_NAME_REST
;
3593 /*% ripper: Qnil %*/
3597 f_any_kwrest
: f_kwrest
3598 | f_no_kwarg
{$$
= ID2VAL
(idNil
);}
3601 f_eq
: {p
->ctxt.in_argdef
= 0;} '=';
3603 block_args_tail
: f_block_kwarg
',' f_kwrest opt_f_block_arg
3605 $$
= new_args_tail
(p
, $1, $3, $4, &@
3);
3607 | f_block_kwarg opt_f_block_arg
3609 $$
= new_args_tail
(p
, $1, Qnone
, $2, &@
1);
3611 | f_any_kwrest opt_f_block_arg
3613 $$
= new_args_tail
(p
, Qnone
, $1, $2, &@
1);
3617 $$
= new_args_tail
(p
, Qnone
, Qnone
, $1, &@
1);
3621 opt_block_args_tail
: ',' block_args_tail
3627 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
0);
3631 excessed_comma
: ','
3633 /* magic number for rest_id in iseq_set_arguments() */
3635 $$
= NODE_SPECIAL_EXCESSIVE_COMMA
;
3637 /*% ripper: excessed_comma! %*/
3641 block_param
: f_arg
',' f_block_optarg
',' f_rest_arg opt_block_args_tail
3643 $$
= new_args
(p
, $1, $3, $5, Qnone
, $6, &@$
);
3645 | f_arg
',' f_block_optarg
',' f_rest_arg
',' f_arg opt_block_args_tail
3647 $$
= new_args
(p
, $1, $3, $5, $7, $8, &@$
);
3649 | f_arg
',' f_block_optarg opt_block_args_tail
3651 $$
= new_args
(p
, $1, $3, Qnone
, Qnone
, $4, &@$
);
3653 | f_arg
',' f_block_optarg
',' f_arg opt_block_args_tail
3655 $$
= new_args
(p
, $1, $3, Qnone
, $5, $6, &@$
);
3657 | f_arg
',' f_rest_arg opt_block_args_tail
3659 $$
= new_args
(p
, $1, Qnone
, $3, Qnone
, $4, &@$
);
3661 | f_arg excessed_comma
3663 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
2);
3664 $$
= new_args
(p
, $1, Qnone
, $2, Qnone
, $$
, &@$
);
3666 | f_arg
',' f_rest_arg
',' f_arg opt_block_args_tail
3668 $$
= new_args
(p
, $1, Qnone
, $3, $5, $6, &@$
);
3670 | f_arg opt_block_args_tail
3672 $$
= new_args
(p
, $1, Qnone
, Qnone
, Qnone
, $2, &@$
);
3674 | f_block_optarg
',' f_rest_arg opt_block_args_tail
3676 $$
= new_args
(p
, Qnone
, $1, $3, Qnone
, $4, &@$
);
3678 | f_block_optarg
',' f_rest_arg
',' f_arg opt_block_args_tail
3680 $$
= new_args
(p
, Qnone
, $1, $3, $5, $6, &@$
);
3682 | f_block_optarg opt_block_args_tail
3684 $$
= new_args
(p
, Qnone
, $1, Qnone
, Qnone
, $2, &@$
);
3686 | f_block_optarg
',' f_arg opt_block_args_tail
3688 $$
= new_args
(p
, Qnone
, $1, Qnone
, $3, $4, &@$
);
3690 | f_rest_arg opt_block_args_tail
3692 $$
= new_args
(p
, Qnone
, Qnone
, $1, Qnone
, $2, &@$
);
3694 | f_rest_arg
',' f_arg opt_block_args_tail
3696 $$
= new_args
(p
, Qnone
, Qnone
, $1, $3, $4, &@$
);
3700 $$
= new_args
(p
, Qnone
, Qnone
, Qnone
, Qnone
, $1, &@$
);
3704 opt_block_param
: none
3707 p
->command_start
= TRUE
;
3711 block_param_def
: '|' opt_bv_decl
'|'
3714 p
->max_numparam
= ORDINAL_PARAM
;
3715 p
->ctxt.in_argdef
= 0;
3719 /*% ripper: block_var!(params!(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil), escape_Qundef($2)) %*/
3721 |
'|' block_param opt_bv_decl
'|'
3724 p
->max_numparam
= ORDINAL_PARAM
;
3725 p
->ctxt.in_argdef
= 0;
3729 /*% ripper: block_var!(escape_Qundef($2), escape_Qundef($3)) %*/
3734 opt_bv_decl
: opt_nl
3738 | opt_nl
';' bv_decls opt_nl
3748 /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
3750 /*% ripper[brace]: rb_ary_push($1, get_value($3)) %*/
3755 new_bv
(p
, get_id
($1));
3756 /*% ripper: get_value($1) %*/
3766 token_info_push
(p
, "->", &@
1);
3767 $
<vars
>1 = dyna_push
(p
);
3768 $
<num
>$
= p
->lex.lpar_beg
;
3769 p
->lex.lpar_beg
= p
->lex.paren_nest
;
3772 $
<num
>$
= p
->max_numparam
;
3773 p
->max_numparam
= 0;
3776 $
<node
>$
= numparam_push
(p
);
3784 int max_numparam
= p
->max_numparam
;
3785 p
->lex.lpar_beg
= $
<num
>2;
3786 p
->max_numparam
= $
<num
>3;
3788 $5 = args_with_numbered
(p
, $5, max_numparam
);
3791 YYLTYPE loc
= code_loc_gen
(&@
5, &@
7);
3792 $$
= NEW_LAMBDA
($5, $7, &loc
);
3793 nd_set_line
($$
->nd_body
, @
7.end_pos.lineno
);
3794 nd_set_line
($$
, @
5.end_pos.lineno
);
3795 nd_set_first_loc
($$
, @
1.beg_pos
);
3798 /*% ripper: lambda!($5, $7) %*/
3799 numparam_pop
(p
, $
<node
>4);
3800 dyna_pop
(p
, $
<vars
>1);
3804 f_larglist
: '(' f_args opt_bv_decl
')'
3806 p
->ctxt.in_argdef
= 0;
3809 p
->max_numparam
= ORDINAL_PARAM
;
3811 /*% ripper: paren!($2) %*/
3815 p
->ctxt.in_argdef
= 0;
3817 if
(!args_info_empty_p
($1->nd_ainfo
))
3818 p
->max_numparam
= ORDINAL_PARAM
;
3824 lambda_body
: tLAMBEG compstmt
'}'
3826 token_info_pop
(p
, "}", &@
3);
3829 | keyword_do_LAMBDA bodystmt k_end
3835 do_block
: k_do_block do_body k_end
3839 $$
->nd_body
->nd_loc
= code_loc_gen
(&@
1, &@
3);
3840 nd_set_line
($$
, @
1.end_pos.lineno
);
3845 block_call
: command do_block
3848 if
(nd_type_p
($1, NODE_YIELD
)) {
3849 compile_error
(p
, "block given to yield");
3852 block_dup_check
(p
, $1->nd_args
, $2);
3854 $$
= method_add_block
(p
, $1, $2, &@$
);
3857 /*% ripper: method_add_block!($1, $2) %*/
3859 | block_call call_op2 operation2 opt_paren_args
3862 $$
= new_qcall
(p
, $2, $1, $3, $4, &@
3, &@$
);
3864 /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
3866 | block_call call_op2 operation2 opt_paren_args brace_block
3869 $$
= new_command_qcall
(p
, $2, $1, $3, $4, $5, &@
3, &@$
);
3871 /*% ripper: opt_event(:method_add_block!, command_call!($1, $2, $3, $4), $5) %*/
3873 | block_call call_op2 operation2 command_args do_block
3876 $$
= new_command_qcall
(p
, $2, $1, $3, $4, $5, &@
3, &@$
);
3878 /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
3882 method_call
: fcall paren_args
3887 nd_set_last_loc
($1, @
2.end_pos
);
3889 /*% ripper: method_add_arg!(fcall!($1), $2) %*/
3891 | primary_value call_op operation2 opt_paren_args
3894 $$
= new_qcall
(p
, $2, $1, $3, $4, &@
3, &@$
);
3895 nd_set_line
($$
, @
3.end_pos.lineno
);
3897 /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
3899 | primary_value tCOLON2 operation2 paren_args
3902 $$
= new_qcall
(p
, ID2VAL
(idCOLON2
), $1, $3, $4, &@
3, &@$
);
3903 nd_set_line
($$
, @
3.end_pos.lineno
);
3905 /*% ripper: method_add_arg!(call!($1, ID2VAL(idCOLON2), $3), $4) %*/
3907 | primary_value tCOLON2 operation3
3910 $$
= new_qcall
(p
, ID2VAL
(idCOLON2
), $1, $3, Qnull
, &@
3, &@$
);
3912 /*% ripper: call!($1, ID2VAL(idCOLON2), $3) %*/
3914 | primary_value call_op paren_args
3917 $$
= new_qcall
(p
, $2, $1, ID2VAL
(idCall
), $3, &@
2, &@$
);
3918 nd_set_line
($$
, @
2.end_pos.lineno
);
3920 /*% ripper: method_add_arg!(call!($1, $2, ID2VAL(idCall)), $3) %*/
3922 | primary_value tCOLON2 paren_args
3925 $$
= new_qcall
(p
, ID2VAL
(idCOLON2
), $1, ID2VAL
(idCall
), $3, &@
2, &@$
);
3926 nd_set_line
($$
, @
2.end_pos.lineno
);
3928 /*% ripper: method_add_arg!(call!($1, ID2VAL(idCOLON2), ID2VAL(idCall)), $3) %*/
3930 | keyword_super paren_args
3933 $$
= NEW_SUPER
($2, &@$
);
3935 /*% ripper: super!($2) %*/
3940 $$
= NEW_ZSUPER
(&@$
);
3942 /*% ripper: zsuper! %*/
3944 | primary_value
'[' opt_call_args rbracket
3947 if
($1 && nd_type_p
($1, NODE_SELF
))
3948 $$
= NEW_FCALL
(tAREF
, $3, &@$
);
3950 $$
= NEW_CALL
($1, tAREF
, $3, &@$
);
3953 /*% ripper: aref!($1, escape_Qundef($3)) %*/
3957 brace_block
: '{' brace_body
'}'
3961 $$
->nd_body
->nd_loc
= code_loc_gen
(&@
1, &@
3);
3962 nd_set_line
($$
, @
1.end_pos.lineno
);
3965 | k_do do_body k_end
3969 $$
->nd_body
->nd_loc
= code_loc_gen
(&@
1, &@
3);
3970 nd_set_line
($$
, @
1.end_pos.lineno
);
3975 brace_body
: {$
<vars
>$
= dyna_push
(p
);}
3977 $
<num
>$
= p
->max_numparam
;
3978 p
->max_numparam
= 0;
3981 $
<node
>$
= numparam_push
(p
);
3983 opt_block_param compstmt
3985 int max_numparam
= p
->max_numparam
;
3986 p
->max_numparam
= $
<num
>2;
3987 $4 = args_with_numbered
(p
, $4, max_numparam
);
3989 $$
= NEW_ITER
($4, $5, &@$
);
3991 /*% ripper: brace_block!(escape_Qundef($4), $5) %*/
3992 numparam_pop
(p
, $
<node
>3);
3993 dyna_pop
(p
, $
<vars
>1);
3997 do_body
: {$
<vars
>$
= dyna_push
(p
);}
3999 $
<num
>$
= p
->max_numparam
;
4000 p
->max_numparam
= 0;
4003 $
<node
>$
= numparam_push
(p
);
4006 opt_block_param bodystmt
4008 int max_numparam
= p
->max_numparam
;
4009 p
->max_numparam
= $
<num
>2;
4010 $4 = args_with_numbered
(p
, $4, max_numparam
);
4012 $$
= NEW_ITER
($4, $5, &@$
);
4014 /*% ripper: do_block!(escape_Qundef($4), $5) %*/
4016 numparam_pop
(p
, $
<node
>3);
4017 dyna_pop
(p
, $
<vars
>1);
4021 case_args
: arg_value
4024 check_literal_when
(p
, $1, &@
1);
4025 $$
= NEW_LIST
($1, &@$
);
4027 /*% ripper: args_add!(args_new!, $1) %*/
4032 $$
= NEW_SPLAT
($2, &@$
);
4034 /*% ripper: args_add_star!(args_new!, $2) %*/
4036 | case_args
',' arg_value
4039 check_literal_when
(p
, $3, &@
3);
4040 $$
= last_arg_append
(p
, $1, $3, &@$
);
4042 /*% ripper: args_add!($1, $3) %*/
4044 | case_args
',' tSTAR arg_value
4047 $$
= rest_arg_append
(p
, $1, $4, &@$
);
4049 /*% ripper: args_add_star!($1, $4) %*/
4053 case_body
: k_when case_args then
4058 $$
= NEW_WHEN
($2, $4, $5, &@$
);
4061 /*% ripper: when!($2, $4, escape_Qundef($5)) %*/
4069 p_case_body
: keyword_in
4071 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
4072 p
->command_start
= FALSE
;
4074 p
->ctxt.in_kwarg
= 1;
4075 $
<tbl
>$
= push_pvtbl
(p
);
4078 $
<tbl
>$
= push_pktbl
(p
);
4082 pop_pktbl
(p
, $
<tbl
>3);
4083 pop_pvtbl
(p
, $
<tbl
>2);
4084 p
->ctxt.in_kwarg
= $
<ctxt
>1.in_kwarg
;
4090 $$
= NEW_IN
($4, $7, $8, &@$
);
4092 /*% ripper: in!($4, $7, escape_Qundef($8)) %*/
4100 p_top_expr
: p_top_expr_body
4101 | p_top_expr_body modifier_if expr_value
4104 $$
= new_if
(p
, $3, $1, 0, &@$
);
4107 /*% ripper: if_mod!($3, $1) %*/
4109 | p_top_expr_body modifier_unless expr_value
4112 $$
= new_unless
(p
, $3, $1, 0, &@$
);
4115 /*% ripper: unless_mod!($3, $1) %*/
4119 p_top_expr_body
: p_expr
4122 $$
= new_array_pattern_tail
(p
, Qnone
, 1, 0, Qnone
, &@$
);
4123 $$
= new_array_pattern
(p
, Qnone
, get_value
($1), $$
, &@$
);
4127 $$
= new_array_pattern
(p
, Qnone
, get_value
($1), $3, &@$
);
4129 nd_set_first_loc
($$
, @
1.beg_pos
);
4135 $$
= new_find_pattern
(p
, Qnone
, $1, &@$
);
4139 $$
= new_array_pattern
(p
, Qnone
, Qnone
, $1, &@$
);
4143 $$
= new_hash_pattern
(p
, Qnone
, $1, &@$
);
4150 p_as
: p_expr tASSOC p_variable
4153 NODE
*n
= NEW_LIST
($1, &@$
);
4154 n
= list_append
(p
, n
, $3);
4155 $$
= new_hash
(p
, n
, &@$
);
4157 /*% ripper: binary!($1, STATIC_ID2SYM((id_assoc)), $3) %*/
4162 p_alt
: p_alt
'|' p_expr_basic
4165 $$
= NEW_NODE
(NODE_OR
, $1, $3, 0, &@$
);
4167 /*% ripper: binary!($1, STATIC_ID2SYM(idOr), $3) %*/
4172 p_lparen
: '(' {$
<tbl
>$
= push_pktbl
(p
);};
4173 p_lbracket
: '[' {$
<tbl
>$
= push_pktbl
(p
);};
4175 p_expr_basic
: p_value
4177 | p_const p_lparen p_args rparen
4179 pop_pktbl
(p
, $
<tbl
>2);
4180 $$
= new_array_pattern
(p
, $1, Qnone
, $3, &@$
);
4182 nd_set_first_loc
($$
, @
1.beg_pos
);
4186 | p_const p_lparen p_find rparen
4188 pop_pktbl
(p
, $
<tbl
>2);
4189 $$
= new_find_pattern
(p
, $1, $3, &@$
);
4191 nd_set_first_loc
($$
, @
1.beg_pos
);
4195 | p_const p_lparen p_kwargs rparen
4197 pop_pktbl
(p
, $
<tbl
>2);
4198 $$
= new_hash_pattern
(p
, $1, $3, &@$
);
4200 nd_set_first_loc
($$
, @
1.beg_pos
);
4204 | p_const
'(' rparen
4206 $$
= new_array_pattern_tail
(p
, Qnone
, 0, 0, Qnone
, &@$
);
4207 $$
= new_array_pattern
(p
, $1, Qnone
, $$
, &@$
);
4209 | p_const p_lbracket p_args rbracket
4211 pop_pktbl
(p
, $
<tbl
>2);
4212 $$
= new_array_pattern
(p
, $1, Qnone
, $3, &@$
);
4214 nd_set_first_loc
($$
, @
1.beg_pos
);
4218 | p_const p_lbracket p_find rbracket
4220 pop_pktbl
(p
, $
<tbl
>2);
4221 $$
= new_find_pattern
(p
, $1, $3, &@$
);
4223 nd_set_first_loc
($$
, @
1.beg_pos
);
4227 | p_const p_lbracket p_kwargs rbracket
4229 pop_pktbl
(p
, $
<tbl
>2);
4230 $$
= new_hash_pattern
(p
, $1, $3, &@$
);
4232 nd_set_first_loc
($$
, @
1.beg_pos
);
4236 | p_const
'[' rbracket
4238 $$
= new_array_pattern_tail
(p
, Qnone
, 0, 0, Qnone
, &@$
);
4239 $$
= new_array_pattern
(p
, $1, Qnone
, $$
, &@$
);
4241 | tLBRACK p_args rbracket
4243 $$
= new_array_pattern
(p
, Qnone
, Qnone
, $2, &@$
);
4245 | tLBRACK p_find rbracket
4247 $$
= new_find_pattern
(p
, Qnone
, $2, &@$
);
4251 $$
= new_array_pattern_tail
(p
, Qnone
, 0, 0, Qnone
, &@$
);
4252 $$
= new_array_pattern
(p
, Qnone
, Qnone
, $$
, &@$
);
4256 $
<tbl
>$
= push_pktbl
(p
);
4258 p
->ctxt.in_kwarg
= 0;
4262 pop_pktbl
(p
, $
<tbl
>2);
4263 p
->ctxt.in_kwarg
= $
<ctxt
>1.in_kwarg
;
4264 $$
= new_hash_pattern
(p
, Qnone
, $3, &@$
);
4268 $$
= new_hash_pattern_tail
(p
, Qnone
, 0, &@$
);
4269 $$
= new_hash_pattern
(p
, Qnone
, $$
, &@$
);
4271 | tLPAREN
{$
<tbl
>$
= push_pktbl
(p
);} p_expr rparen
4273 pop_pktbl
(p
, $
<tbl
>2);
4281 NODE
*pre_args
= NEW_LIST
($1, &@$
);
4282 $$
= new_array_pattern_tail
(p
, pre_args
, 0, 0, Qnone
, &@$
);
4284 $$ = new_array_pattern_tail(p, rb_ary_new_from_args(1, get_value($1)), 0, 0, Qnone, &@$);
4289 $$
= new_array_pattern_tail
(p
, $1, 1, 0, Qnone
, &@$
);
4294 $$
= new_array_pattern_tail
(p
, list_concat
($1, $2), 0, 0, Qnone
, &@$
);
4296 VALUE pre_args = rb_ary_concat($1, get_value($2));
4297 $$ = new_array_pattern_tail(p, pre_args, 0, 0, Qnone, &@$);
4300 | p_args_head tSTAR tIDENTIFIER
4302 $$
= new_array_pattern_tail
(p
, $1, 1, $3, Qnone
, &@$
);
4304 | p_args_head tSTAR tIDENTIFIER
',' p_args_post
4306 $$
= new_array_pattern_tail
(p
, $1, 1, $3, $5, &@$
);
4310 $$
= new_array_pattern_tail
(p
, $1, 1, 0, Qnone
, &@$
);
4312 | p_args_head tSTAR
',' p_args_post
4314 $$
= new_array_pattern_tail
(p
, $1, 1, 0, $4, &@$
);
4319 p_args_head
: p_arg
','
4323 | p_args_head p_arg
','
4326 $$
= list_concat
($1, $2);
4328 /*% ripper: rb_ary_concat($1, get_value($2)) %*/
4332 p_args_tail
: p_rest
4334 $$
= new_array_pattern_tail
(p
, Qnone
, 1, $1, Qnone
, &@$
);
4336 | p_rest
',' p_args_post
4338 $$
= new_array_pattern_tail
(p
, Qnone
, 1, $1, $3, &@$
);
4342 p_find
: p_rest
',' p_args_post
',' p_rest
4344 $$
= new_find_pattern_tail
(p
, $1, $3, $5, &@$
);
4346 if
(rb_warning_category_enabled_p
(RB_WARN_CATEGORY_EXPERIMENTAL
))
4347 rb_warn0L_experimental
(nd_line
($$
), "Find pattern is experimental, and the behavior may change in future versions of Ruby!");
4352 p_rest
: tSTAR tIDENTIFIER
4363 | p_args_post
',' p_arg
4366 $$
= list_concat
($1, $3);
4368 /*% ripper: rb_ary_concat($1, get_value($3)) %*/
4375 $$
= NEW_LIST
($1, &@$
);
4377 /*% ripper: rb_ary_new_from_args(1, get_value($1)) %*/
4381 p_kwargs
: p_kwarg
',' p_any_kwrest
4383 $$
= new_hash_pattern_tail
(p
, new_unique_key_hash
(p
, $1, &@$
), $3, &@$
);
4387 $$
= new_hash_pattern_tail
(p
, new_unique_key_hash
(p
, $1, &@$
), 0, &@$
);
4391 $$
= new_hash_pattern_tail
(p
, new_unique_key_hash
(p
, $1, &@$
), 0, &@$
);
4395 $$
= new_hash_pattern_tail
(p
, new_hash
(p
, Qnone
, &@$
), $1, &@$
);
4400 /*% ripper[brace]: rb_ary_new_from_args(1, $1) %*/
4404 $$
= list_concat
($1, $3);
4406 /*% ripper: rb_ary_push($1, $3) %*/
4410 p_kw
: p_kw_label p_expr
4412 error_duplicate_pattern_key
(p
, get_id
($1), &@
1);
4414 $$
= list_append
(p
, NEW_LIST
(NEW_LIT
(ID2SYM
($1), &@$
), &@$
), $2);
4416 /*% ripper: rb_ary_new_from_args(2, get_value($1), get_value($2)) %*/
4420 error_duplicate_pattern_key
(p
, get_id
($1), &@
1);
4421 if
($1 && !is_local_id
(get_id
($1))) {
4422 yyerror1
(&@
1, "key must be valid as local variables");
4424 error_duplicate_pattern_variable
(p
, get_id
($1), &@
1);
4426 $$
= list_append
(p
, NEW_LIST
(NEW_LIT
(ID2SYM
($1), &@$
), &@$
), assignable
(p
, $1, 0, &@$
));
4428 /*% ripper: rb_ary_new_from_args(2, get_value($1), Qnil) %*/
4433 | tSTRING_BEG string_contents tLABEL_END
4435 YYLTYPE loc
= code_loc_gen
(&@
1, &@
3);
4437 if
(!$2 || nd_type_p
($2, NODE_STR
)) {
4438 NODE
*node
= dsym_node
(p
, $2, &loc
);
4439 $$
= SYM2ID
(node
->nd_lit
);
4442 if (ripper_is_node_yylval($2) && RNODE($2)->nd_cval) {
4443 VALUE label = RNODE($2)->nd_cval;
4444 VALUE rval = RNODE($2)->nd_rval;
4445 $$ = ripper_new_yylval(p, rb_intern_str(label), rval, label);
4446 RNODE($$)->nd_loc = loc;
4450 yyerror1
(&loc
, "symbol literal with interpolation is not allowed");
4456 p_kwrest
: kwrest_mark tIDENTIFIER
4466 p_kwnorest
: kwrest_mark keyword_nil
4472 p_any_kwrest
: p_kwrest
4473 | p_kwnorest
{$$
= ID2VAL
(idNil
);}
4476 p_value
: p_primitive
4477 | p_primitive tDOT2 p_primitive
4482 $$
= NEW_DOT2
($1, $3, &@$
);
4484 /*% ripper: dot2!($1, $3) %*/
4486 | p_primitive tDOT3 p_primitive
4491 $$
= NEW_DOT3
($1, $3, &@$
);
4493 /*% ripper: dot3!($1, $3) %*/
4499 $$
= NEW_DOT2
($1, new_nil_at
(p
, &@
2.end_pos
), &@$
);
4501 /*% ripper: dot2!($1, Qnil) %*/
4507 $$
= NEW_DOT3
($1, new_nil_at
(p
, &@
2.end_pos
), &@$
);
4509 /*% ripper: dot3!($1, Qnil) %*/
4514 | tBDOT2 p_primitive
4518 $$
= NEW_DOT2
(new_nil_at
(p
, &@
1.beg_pos
), $2, &@$
);
4520 /*% ripper: dot2!(Qnil, $2) %*/
4522 | tBDOT3 p_primitive
4526 $$
= NEW_DOT3
(new_nil_at
(p
, &@
1.beg_pos
), $2, &@$
);
4528 /*% ripper: dot3!(Qnil, $2) %*/
4532 p_primitive
: literal
4543 if
(!($$
= gettable
(p
, $1, &@$
))) $$
= NEW_BEGIN
(0, &@$
);
4545 /*% ripper: var_ref!($1) %*/
4550 p_variable
: tIDENTIFIER
4553 error_duplicate_pattern_variable
(p
, $1, &@
1);
4554 $$
= assignable
(p
, $1, 0, &@$
);
4556 /*% ripper: assignable(p, var_field(p, $1)) %*/
4560 p_var_ref
: '^' tIDENTIFIER
4563 NODE
*n
= gettable
(p
, $2, &@$
);
4564 if
(!(nd_type_p
(n
, NODE_LVAR
) || nd_type_p
(n
, NODE_DVAR
))) {
4565 compile_error
(p
, "%"PRIsVALUE
": no such local variable", rb_id2str
($2));
4569 /*% ripper: var_ref!($2) %*/
4574 if
(!($$
= gettable
(p
, $2, &@$
))) $$
= NEW_BEGIN
(0, &@$
);
4576 /*% ripper: var_ref!($2) %*/
4580 p_expr_ref
: '^' tLPAREN expr_value
')'
4583 $$
= NEW_BEGIN
($3, &@$
);
4585 /*% ripper: begin!($3) %*/
4589 p_const
: tCOLON3 cname
4592 $$
= NEW_COLON3
($2, &@$
);
4594 /*% ripper: top_const_ref!($2) %*/
4596 | p_const tCOLON2 cname
4599 $$
= NEW_COLON2
($1, $3, &@$
);
4601 /*% ripper: const_path_ref!($1, $3) %*/
4606 $$
= gettable
(p
, $1, &@$
);
4608 /*% ripper: var_ref!($1) %*/
4612 opt_rescue
: k_rescue exc_list exc_var then
4617 $$
= NEW_RESBODY
($2,
4618 $3 ? block_append
(p
, node_assign
(p
, $3, NEW_ERRINFO
(&@
3), NO_LEX_CTXT
, &@
3), $5) : $5,
4620 fixpos
($$
, $2?
$2:$5);
4622 /*% ripper: rescue!(escape_Qundef($2), escape_Qundef($3), escape_Qundef($5), escape_Qundef($6)) %*/
4627 exc_list
: arg_value
4630 $$
= NEW_LIST
($1, &@$
);
4632 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
4637 if
(!($$
= splat_array
($1))) $$
= $1;
4644 exc_var
: tASSOC lhs
4651 opt_ensure
: k_ensure compstmt
4656 /*% ripper: ensure!($2) %*/
4670 node
= NEW_STR
(STR_NEW0
(), &@$
);
4671 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
);
4674 node
= evstr2dstr
(p
, node
);
4687 $$
= literal_concat
(p
, $1, $2, &@$
);
4689 /*% ripper: string_concat!($1, $2) %*/
4693 string1
: tSTRING_BEG string_contents tSTRING_END
4696 $$
= heredoc_dedent
(p
, $2);
4697 if
($$
) nd_set_loc
($$
, &@$
);
4699 /*% ripper: string_literal!(heredoc_dedent(p, $2)) %*/
4703 xstring
: tXSTRING_BEG xstring_contents tSTRING_END
4706 $$
= new_xstring
(p
, heredoc_dedent
(p
, $2), &@$
);
4708 /*% ripper: xstring_literal!(heredoc_dedent(p, $2)) %*/
4712 regexp
: tREGEXP_BEG regexp_contents tREGEXP_END
4714 $$
= new_regexp
(p
, $2, $3, &@$
);
4718 words
: tWORDS_BEG
' ' word_list tSTRING_END
4721 $$
= make_list
($3, &@$
);
4723 /*% ripper: array!($3) %*/
4727 word_list
: /* none */
4732 /*% ripper: words_new! %*/
4734 | word_list word
' '
4737 $$
= list_append
(p
, $1, evstr2dstr
(p
, $2));
4739 /*% ripper: words_add!($1, $2) %*/
4743 word
: string_content
4744 /*% ripper[brace]: word_add!(word_new!, $1) %*/
4745 | word string_content
4748 $$
= literal_concat
(p
, $1, $2, &@$
);
4750 /*% ripper: word_add!($1, $2) %*/
4754 symbols
: tSYMBOLS_BEG
' ' symbol_list tSTRING_END
4757 $$
= make_list
($3, &@$
);
4759 /*% ripper: array!($3) %*/
4763 symbol_list
: /* none */
4768 /*% ripper: symbols_new! %*/
4770 | symbol_list word
' '
4773 $$
= symbol_append
(p
, $1, evstr2dstr
(p
, $2));
4775 /*% ripper: symbols_add!($1, $2) %*/
4779 qwords
: tQWORDS_BEG
' ' qword_list tSTRING_END
4782 $$
= make_list
($3, &@$
);
4784 /*% ripper: array!($3) %*/
4788 qsymbols
: tQSYMBOLS_BEG
' ' qsym_list tSTRING_END
4791 $$
= make_list
($3, &@$
);
4793 /*% ripper: array!($3) %*/
4797 qword_list
: /* none */
4802 /*% ripper: qwords_new! %*/
4804 | qword_list tSTRING_CONTENT
' '
4807 $$
= list_append
(p
, $1, $2);
4809 /*% ripper: qwords_add!($1, $2) %*/
4813 qsym_list
: /* none */
4818 /*% ripper: qsymbols_new! %*/
4820 | qsym_list tSTRING_CONTENT
' '
4823 $$
= symbol_append
(p
, $1, $2);
4825 /*% ripper: qsymbols_add!($1, $2) %*/
4829 string_contents
: /* none */
4834 /*% ripper: string_content! %*/
4837 $$ = ripper_new_yylval(p, 0, $$, 0);
4840 | string_contents string_content
4843 $$
= literal_concat
(p
, $1, $2, &@$
);
4845 /*% ripper: string_add!($1, $2) %*/
4848 if (ripper_is_node_yylval($1) && ripper_is_node_yylval($2) &&
4849 !RNODE($1)->nd_cval) {
4850 RNODE($1)->nd_cval = RNODE($2)->nd_cval;
4851 RNODE($1)->nd_rval = add_mark_object(p, $$);
4858 xstring_contents: /* none */
4863 /*% ripper: xstring_new! %*/
4865 | xstring_contents string_content
4868 $$
= literal_concat
(p
, $1, $2, &@$
);
4870 /*% ripper: xstring_add!($1, $2) %*/
4874 regexp_contents: /* none */
4879 /*% ripper: regexp_new! %*/
4882 $$ = ripper_new_yylval(p, 0, $$, 0);
4885 | regexp_contents string_content
4888 NODE
*head
= $1, *tail
= $2;
4896 switch
(nd_type
(head
)) {
4898 nd_set_type
(head
, NODE_DSTR
);
4903 head
= list_append
(p
, NEW_DSTR
(Qnil
, &@$
), head
);
4906 $$
= list_append
(p
, head
, tail
);
4909 VALUE s1 = 1, s2 = 0, n1 = $1, n2 = $2;
4910 if (ripper_is_node_yylval(n1)) {
4911 s1 = RNODE(n1)->nd_cval;
4912 n1 = RNODE(n1)->nd_rval;
4914 if (ripper_is_node_yylval(n2)) {
4915 s2 = RNODE(n2)->nd_cval;
4916 n2 = RNODE(n2)->nd_rval;
4918 $$ = dispatch2(regexp_add, n1, n2);
4920 $$ = ripper_new_yylval(p, 0, $$, s2);
4926 string_content
: tSTRING_CONTENT
4927 /*% ripper[brace]: ripper_new_yylval(p, 0, get_value($1), $1) %*/
4930 /* need to backup p->lex.strterm so that a string literal `%&foo,#$&,bar&` can be parsed */
4931 $
<strterm
>$
= p
->lex.strterm
;
4933 SET_LEX_STATE
(EXPR_BEG
);
4937 p
->lex.strterm
= $
<strterm
>2;
4939 $$
= NEW_EVSTR
($3, &@$
);
4940 nd_set_line
($$
, @
3.end_pos.lineno
);
4942 /*% ripper: string_dvar!($3) %*/
4950 /* need to backup p->lex.strterm so that a string literal `%!foo,#{ !0 },bar!` can be parsed */
4951 $
<strterm
>$
= p
->lex.strterm
;
4955 $
<num
>$
= p
->lex.state
;
4956 SET_LEX_STATE
(EXPR_BEG
);
4959 $
<num
>$
= p
->lex.brace_nest
;
4960 p
->lex.brace_nest
= 0;
4963 $
<num
>$
= p
->heredoc_indent
;
4964 p
->heredoc_indent
= 0;
4966 compstmt tSTRING_DEND
4970 p
->lex.strterm
= $
<strterm
>3;
4971 SET_LEX_STATE
($
<num
>4);
4972 p
->lex.brace_nest
= $
<num
>5;
4973 p
->heredoc_indent
= $
<num
>6;
4974 p
->heredoc_line_indent
= -1;
4976 if
($7) $7->flags
&= ~NODE_FL_NEWLINE
;
4977 $$
= new_evstr
(p
, $7, &@$
);
4979 /*% ripper: string_embexpr!($7) %*/
4986 $$
= NEW_GVAR
($1, &@$
);
4988 /*% ripper: var_ref!($1) %*/
4993 $$
= NEW_IVAR
($1, &@$
);
4995 /*% ripper: var_ref!($1) %*/
5000 $$
= NEW_CVAR
($1, &@$
);
5002 /*% ripper: var_ref!($1) %*/
5013 SET_LEX_STATE
(EXPR_END
);
5015 $$
= NEW_LIT
(ID2SYM
($2), &@$
);
5017 /*% ripper: symbol_literal!(symbol!($2)) %*/
5027 dsym
: tSYMBEG string_contents tSTRING_END
5029 SET_LEX_STATE
(EXPR_END
);
5031 $$
= dsym_node
(p
, $2, &@$
);
5033 /*% ripper: dyna_symbol!($2) %*/
5037 numeric
: simple_numeric
5038 | tUMINUS_NUM simple_numeric %prec tLOWEST
5042 RB_OBJ_WRITE
(p
->ast
, &$$
->nd_lit
, negate_lit
(p
, $$
->nd_lit
));
5044 /*% ripper: unary!(ID2VAL(idUMinus), $2) %*/
5048 simple_numeric
: tINTEGER
5054 nonlocal_var
: tIVAR
5059 user_variable
: tIDENTIFIER
5066 keyword_variable: keyword_nil
{$$
= KWD2EID
(nil
, $1);}
5067 | keyword_self
{$$
= KWD2EID
(self
, $1);}
5068 | keyword_true
{$$
= KWD2EID
(true
, $1);}
5069 | keyword_false
{$$
= KWD2EID
(false
, $1);}
5070 | keyword__FILE__
{$$
= KWD2EID
(_FILE__
, $1);}
5071 | keyword__LINE__
{$$
= KWD2EID
(_LINE__
, $1);}
5072 | keyword__ENCODING__
{$$
= KWD2EID
(_ENCODING__
, $1);}
5075 var_ref
: user_variable
5078 if
(!($$
= gettable
(p
, $1, &@$
))) $$
= NEW_BEGIN
(0, &@$
);
5080 if (id_is_var(p, get_id($1))) {
5081 $$ = dispatch1(var_ref, $1);
5084 $$ = dispatch1(vcall, $1);
5091 if
(!($$
= gettable
(p
, $1, &@$
))) $$
= NEW_BEGIN
(0, &@$
);
5093 /*% ripper: var_ref!($1) %*/
5097 var_lhs
: user_variable
5100 $$
= assignable
(p
, $1, 0, &@$
);
5102 /*% ripper: assignable(p, var_field(p, $1)) %*/
5107 $$
= assignable
(p
, $1, 0, &@$
);
5109 /*% ripper: assignable(p, var_field(p, $1)) %*/
5119 SET_LEX_STATE
(EXPR_BEG
);
5120 p
->command_start
= TRUE
;
5131 /*% ripper: Qnil %*/
5135 f_opt_paren_args: f_paren_args
5138 p
->ctxt.in_argdef
= 0;
5139 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
0);
5140 $$
= new_args
(p
, Qnone
, Qnone
, Qnone
, Qnone
, $$
, &@
0);
5144 f_paren_args
: '(' f_args rparen
5149 /*% ripper: paren!($2) %*/
5150 SET_LEX_STATE
(EXPR_BEG
);
5151 p
->command_start
= TRUE
;
5152 p
->ctxt.in_argdef
= 0;
5156 f_arglist
: f_paren_args
5159 p
->ctxt.in_kwarg
= 1;
5160 p
->ctxt.in_argdef
= 1;
5161 SET_LEX_STATE
(p
->lex.state|EXPR_LABEL
); /* force for args */
5165 p
->ctxt.in_kwarg
= $
<ctxt
>1.in_kwarg
;
5166 p
->ctxt.in_argdef
= 0;
5168 SET_LEX_STATE
(EXPR_BEG
);
5169 p
->command_start
= TRUE
;
5173 args_tail
: f_kwarg
',' f_kwrest opt_f_block_arg
5175 $$
= new_args_tail
(p
, $1, $3, $4, &@
3);
5177 | f_kwarg opt_f_block_arg
5179 $$
= new_args_tail
(p
, $1, Qnone
, $2, &@
1);
5181 | f_any_kwrest opt_f_block_arg
5183 $$
= new_args_tail
(p
, Qnone
, $1, $2, &@
1);
5187 $$
= new_args_tail
(p
, Qnone
, Qnone
, $1, &@
1);
5191 add_forwarding_args
(p
);
5192 $$
= new_args_tail
(p
, Qnone
, $1, ID2VAL
(idFWD_BLOCK
), &@
1);
5196 opt_args_tail
: ',' args_tail
5202 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
0);
5206 f_args
: f_arg
',' f_optarg
',' f_rest_arg opt_args_tail
5208 $$
= new_args
(p
, $1, $3, $5, Qnone
, $6, &@$
);
5210 | f_arg
',' f_optarg
',' f_rest_arg
',' f_arg opt_args_tail
5212 $$
= new_args
(p
, $1, $3, $5, $7, $8, &@$
);
5214 | f_arg
',' f_optarg opt_args_tail
5216 $$
= new_args
(p
, $1, $3, Qnone
, Qnone
, $4, &@$
);
5218 | f_arg
',' f_optarg
',' f_arg opt_args_tail
5220 $$
= new_args
(p
, $1, $3, Qnone
, $5, $6, &@$
);
5222 | f_arg
',' f_rest_arg opt_args_tail
5224 $$
= new_args
(p
, $1, Qnone
, $3, Qnone
, $4, &@$
);
5226 | f_arg
',' f_rest_arg
',' f_arg opt_args_tail
5228 $$
= new_args
(p
, $1, Qnone
, $3, $5, $6, &@$
);
5230 | f_arg opt_args_tail
5232 $$
= new_args
(p
, $1, Qnone
, Qnone
, Qnone
, $2, &@$
);
5234 | f_optarg
',' f_rest_arg opt_args_tail
5236 $$
= new_args
(p
, Qnone
, $1, $3, Qnone
, $4, &@$
);
5238 | f_optarg
',' f_rest_arg
',' f_arg opt_args_tail
5240 $$
= new_args
(p
, Qnone
, $1, $3, $5, $6, &@$
);
5242 | f_optarg opt_args_tail
5244 $$
= new_args
(p
, Qnone
, $1, Qnone
, Qnone
, $2, &@$
);
5246 | f_optarg
',' f_arg opt_args_tail
5248 $$
= new_args
(p
, Qnone
, $1, Qnone
, $3, $4, &@$
);
5250 | f_rest_arg opt_args_tail
5252 $$
= new_args
(p
, Qnone
, Qnone
, $1, Qnone
, $2, &@$
);
5254 | f_rest_arg
',' f_arg opt_args_tail
5256 $$
= new_args
(p
, Qnone
, Qnone
, $1, $3, $4, &@$
);
5260 $$
= new_args
(p
, Qnone
, Qnone
, Qnone
, Qnone
, $1, &@$
);
5264 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
0);
5265 $$
= new_args
(p
, Qnone
, Qnone
, Qnone
, Qnone
, $$
, &@
0);
5269 args_forward
: tBDOT3
5274 /*% ripper: args_forward! %*/
5278 f_bad_arg
: tCONSTANT
5280 static const char mesg
[] = "formal argument cannot be a constant";
5282 yyerror1
(&@
1, mesg
);
5285 /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
5289 static const char mesg
[] = "formal argument cannot be an instance variable";
5291 yyerror1
(&@
1, mesg
);
5294 /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
5298 static const char mesg
[] = "formal argument cannot be a global variable";
5300 yyerror1
(&@
1, mesg
);
5303 /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
5307 static const char mesg
[] = "formal argument cannot be a class variable";
5309 yyerror1
(&@
1, mesg
);
5312 /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
5316 f_norm_arg
: f_bad_arg
5319 formal_argument
(p
, $1);
5320 p
->max_numparam
= ORDINAL_PARAM
;
5325 f_arg_asgn
: f_norm_arg
5334 f_arg_item
: f_arg_asgn
5338 $$
= NEW_ARGS_AUX
($1, 1, &NULL_LOC
);
5340 /*% ripper: get_value($1) %*/
5342 | tLPAREN f_margs rparen
5345 ID tid
= internal_id
(p
);
5347 loc.beg_pos
= @
2.beg_pos
;
5348 loc.end_pos
= @
2.beg_pos
;
5350 if
(dyna_in_block
(p
)) {
5351 $2->nd_value
= NEW_DVAR
(tid
, &loc
);
5354 $2->nd_value
= NEW_LVAR
(tid
, &loc
);
5356 $$
= NEW_ARGS_AUX
(tid
, 1, &NULL_LOC
);
5359 /*% ripper: mlhs_paren!($2) %*/
5364 /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
5365 | f_arg
',' f_arg_item
5370 $$
->nd_next
= block_append
(p
, $$
->nd_next
, $3->nd_next
);
5371 rb_discard_node
(p
, $3);
5373 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5380 arg_var
(p
, formal_argument
(p
, $1));
5381 p
->cur_arg
= get_id
($1);
5382 p
->max_numparam
= ORDINAL_PARAM
;
5383 p
->ctxt.in_argdef
= 0;
5388 f_kw
: f_label arg_value
5391 p
->ctxt.in_argdef
= 1;
5393 $$
= new_kw_arg
(p
, assignable
(p
, $1, $2, &@$
), &@$
);
5395 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
5400 p
->ctxt.in_argdef
= 1;
5402 $$
= new_kw_arg
(p
, assignable
(p
, $1, NODE_SPECIAL_REQUIRED_KEYWORD
, &@$
), &@$
);
5404 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
5408 f_block_kw
: f_label primary_value
5410 p
->ctxt.in_argdef
= 1;
5412 $$
= new_kw_arg
(p
, assignable
(p
, $1, $2, &@$
), &@$
);
5414 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
5418 p
->ctxt.in_argdef
= 1;
5420 $$
= new_kw_arg
(p
, assignable
(p
, $1, NODE_SPECIAL_REQUIRED_KEYWORD
, &@$
), &@$
);
5422 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
5426 f_block_kwarg
: f_block_kw
5431 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
5433 | f_block_kwarg
',' f_block_kw
5436 $$
= kwd_append
($1, $3);
5438 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5448 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
5453 $$
= kwd_append
($1, $3);
5455 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5463 f_no_kwarg
: kwrest_mark keyword_nil
5467 /*% ripper: nokw_param!(Qnil) %*/
5471 f_kwrest
: kwrest_mark tIDENTIFIER
5473 arg_var
(p
, shadowing_lvar
(p
, get_id
($2)));
5477 /*% ripper: kwrest_param!($2) %*/
5482 $$
= internal_id
(p
);
5485 /*% ripper: kwrest_param!(Qnil) %*/
5489 f_opt
: f_arg_asgn f_eq arg_value
5492 p
->ctxt.in_argdef
= 1;
5494 $$
= NEW_OPT_ARG
(0, assignable
(p
, $1, $3, &@$
), &@$
);
5496 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
5500 f_block_opt
: f_arg_asgn f_eq primary_value
5503 p
->ctxt.in_argdef
= 1;
5505 $$
= NEW_OPT_ARG
(0, assignable
(p
, $1, $3, &@$
), &@$
);
5507 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
5511 f_block_optarg
: f_block_opt
5516 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
5518 | f_block_optarg
',' f_block_opt
5521 $$
= opt_arg_append
($1, $3);
5523 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5532 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
5534 | f_optarg
',' f_opt
5537 $$
= opt_arg_append
($1, $3);
5539 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5547 f_rest_arg
: restarg_mark tIDENTIFIER
5549 arg_var
(p
, shadowing_lvar
(p
, get_id
($2)));
5553 /*% ripper: rest_param!($2) %*/
5558 $$
= internal_id
(p
);
5561 /*% ripper: rest_param!(Qnil) %*/
5569 f_block_arg
: blkarg_mark tIDENTIFIER
5571 arg_var
(p
, shadowing_lvar
(p
, get_id
($2)));
5575 /*% ripper: blockarg!($2) %*/
5580 arg_var
(p
, shadowing_lvar
(p
, get_id
(ANON_BLOCK_ID
)));
5582 $$ = dispatch1(blockarg, Qnil);
5587 opt_f_block_arg
: ',' f_block_arg
5602 |
'(' {SET_LEX_STATE
(EXPR_BEG
);} expr rparen
5605 switch
(nd_type
($3)) {
5614 yyerror1
(&@
3, "can't define singleton method for literals");
5622 /*% ripper: paren!($3) %*/
5632 /*% ripper: assoclist_from_args!($1) %*/
5637 /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
5647 if
(assocs
->nd_head
&&
5648 !tail
->nd_head
&& nd_type_p
(tail
->nd_next
, NODE_LIST
) &&
5649 nd_type_p
(tail
->nd_next
->nd_head
, NODE_HASH
)) {
5651 tail
= tail
->nd_next
->nd_head
->nd_head
;
5653 assocs
= list_concat
(assocs
, tail
);
5657 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5661 assoc
: arg_value tASSOC arg_value
5664 if
(nd_type_p
($1, NODE_STR
)) {
5665 nd_set_type
($1, NODE_LIT
);
5666 RB_OBJ_WRITE
(p
->ast
, &$1->nd_lit
, rb_fstring
($1->nd_lit
));
5668 $$
= list_append
(p
, NEW_LIST
($1, &@$
), $3);
5670 /*% ripper: assoc_new!($1, $3) %*/
5675 $$
= list_append
(p
, NEW_LIST
(NEW_LIT
(ID2SYM
($1), &@
1), &@$
), $2);
5677 /*% ripper: assoc_new!($1, $2) %*/
5682 NODE
*val
= gettable
(p
, $1, &@$
);
5683 if
(!val
) val
= NEW_BEGIN
(0, &@$
);
5684 $$
= list_append
(p
, NEW_LIST
(NEW_LIT
(ID2SYM
($1), &@
1), &@$
), val
);
5686 /*% ripper: assoc_new!($1, Qnil) %*/
5688 | tSTRING_BEG string_contents tLABEL_END arg_value
5691 YYLTYPE loc
= code_loc_gen
(&@
1, &@
3);
5692 $$
= list_append
(p
, NEW_LIST
(dsym_node
(p
, $2, &loc
), &loc
), $4);
5694 /*% ripper: assoc_new!(dyna_symbol!($2), $4) %*/
5699 if
(nd_type_p
($2, NODE_HASH
) &&
5700 !($2->nd_head
&& $2->nd_head
->nd_alen
)) {
5701 static VALUE empty_hash
;
5703 empty_hash
= rb_obj_freeze
(rb_hash_new
());
5704 rb_gc_register_mark_object
(empty_hash
);
5706 $$
= list_append
(p
, NEW_LIST
(0, &@$
), NEW_LIT
(empty_hash
, &@$
));
5709 $$
= list_append
(p
, NEW_LIST
(0, &@$
), $2);
5711 /*% ripper: assoc_splat!($2) %*/
5715 operation
: tIDENTIFIER
5720 operation2
: tIDENTIFIER
5726 operation3
: tIDENTIFIER
5743 opt_terms
: /* none */
5754 rbracket
: opt_nl
']'
5760 trailer
: /* none */
5765 term
: ';' {yyerrok;token_flush
(p
);}
5766 |
'\n' {token_flush
(p
);}
5770 | terms
';' {yyerrok;}
5782 # define yylval (*p->lval)
5784 static int regx_options
(struct parser_params
*);
5785 static int tokadd_string
(struct parser_params
*,int,int,int,long*,rb_encoding
**,rb_encoding
**);
5786 static void tokaddmbc
(struct parser_params
*p
, int c
, rb_encoding
*enc
);
5787 static enum yytokentype parse_string
(struct parser_params
*,rb_strterm_literal_t
*);
5788 static enum yytokentype here_document
(struct parser_params
*,rb_strterm_heredoc_t
*);
5791 # define set_yylval_node(x) { \
5793 rb_parser_set_location
(p
, &_cur_loc
); \
5794 yylval.node
= (x
); \
5796 # define set_yylval_str(x) \
5798 set_yylval_node
(NEW_STR
(x
, &_cur_loc
)); \
5799 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, x
); \
5801 # define set_yylval_literal(x) \
5803 set_yylval_node
(NEW_LIT
(x
, &_cur_loc
)); \
5804 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, x
); \
5806 # define set_yylval_num(x) (yylval.num = (x))
5807 # define set_yylval_id(x) (yylval.id = (x))
5808 # define set_yylval_name(x) (yylval.id = (x))
5809 # define yylval_id() (yylval.id)
5812 ripper_yylval_id
(struct parser_params
*p
, ID x
)
5814 return ripper_new_yylval
(p
, x
, ID2SYM
(x
), 0);
5816 # define set_yylval_str(x) (yylval.val = add_mark_object(p, (x)))
5817 # define set_yylval_num(x) (yylval.val = ripper_new_yylval(p, (x), 0, 0))
5818 # define set_yylval_id(x) (void)(x)
5819 # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(p, x))
5820 # define set_yylval_literal(x) add_mark_object(p, (x))
5821 # define set_yylval_node(x) (yylval.val = ripper_new_yylval(p, 0, 0, STR_NEW(p->lex.ptok, p->lex.pcur-p->lex.ptok)))
5822 # define yylval_id() yylval.id
5823 # define _cur_loc NULL_LOC /* dummy */
5826 #define set_yylval_noname() set_yylval_id(keyword_nil)
5829 #define literal_flush(p, ptr) ((p)->lex.ptok = (ptr))
5830 #define dispatch_scan_event(p, t) ((void)0)
5831 #define dispatch_delayed_token(p, t) ((void)0)
5832 #define has_delayed_token(p) (0)
5834 #define literal_flush(p, ptr) ((void)(ptr))
5836 #define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
5839 intern_sym
(const char *name
)
5841 ID id
= rb_intern_const
(name
);
5846 ripper_has_scan_event
(struct parser_params
*p
)
5848 if
(p
->lex.pcur
< p
->lex.ptok
) rb_raise
(rb_eRuntimeError
, "lex.pcur < lex.ptok");
5849 return p
->lex.pcur
> p
->lex.ptok
;
5853 ripper_scan_event_val
(struct parser_params
*p
, enum yytokentype t
)
5855 VALUE str
= STR_NEW
(p
->lex.ptok
, p
->lex.pcur
- p
->lex.ptok
);
5856 VALUE rval
= ripper_dispatch1
(p
, ripper_token2eventid
(t
), str
);
5862 ripper_dispatch_scan_event
(struct parser_params
*p
, enum yytokentype t
)
5864 if
(!ripper_has_scan_event
(p
)) return
;
5865 add_mark_object
(p
, yylval_rval
= ripper_scan_event_val
(p
, t
));
5867 #define dispatch_scan_event(p, t) ripper_dispatch_scan_event(p, t)
5870 ripper_dispatch_delayed_token
(struct parser_params
*p
, enum yytokentype t
)
5872 int saved_line
= p
->ruby_sourceline
;
5873 const char *saved_tokp
= p
->lex.ptok
;
5875 if
(NIL_P
(p
->delayed.token
)) return
;
5876 p
->ruby_sourceline
= p
->delayed.line
;
5877 p
->lex.ptok
= p
->lex.pbeg
+ p
->delayed.col
;
5878 add_mark_object
(p
, yylval_rval
= ripper_dispatch1
(p
, ripper_token2eventid
(t
), p
->delayed.token
));
5879 p
->delayed.token
= Qnil
;
5880 p
->ruby_sourceline
= saved_line
;
5881 p
->lex.ptok
= saved_tokp
;
5883 #define dispatch_delayed_token(p, t) ripper_dispatch_delayed_token(p, t)
5884 #define has_delayed_token(p) (!NIL_P(p->delayed.token))
5888 is_identchar
(const char *ptr
, const char *MAYBE_UNUSED
(ptr_end
), rb_encoding
*enc
)
5890 return rb_enc_isalnum
((unsigned char)*ptr
, enc
) ||
*ptr
== '_' ||
!ISASCII
(*ptr
);
5894 parser_is_identchar
(struct parser_params
*p
)
5896 return
!(p
)->eofp
&& is_identchar
(p
->lex.pcur
-1, p
->lex.pend
, p
->enc
);
5900 parser_isascii
(struct parser_params
*p
)
5902 return ISASCII
(*(p
->lex.pcur
-1));
5906 token_info_setup
(token_info
*ptinfo
, const char *ptr
, const rb_code_location_t
*loc
)
5908 int column
= 1, nonspc
= 0, i
;
5909 for
(i
= 0; i
< loc
->beg_pos.column
; i
++, ptr
++) {
5911 column
= (((column
- 1) / TAB_WIDTH
) + 1) * TAB_WIDTH
;
5914 if
(*ptr
!= ' ' && *ptr
!= '\t') {
5919 ptinfo
->beg
= loc
->beg_pos
;
5920 ptinfo
->indent
= column
;
5921 ptinfo
->nonspc
= nonspc
;
5925 token_info_push
(struct parser_params
*p
, const char *token
, const rb_code_location_t
*loc
)
5929 if
(!p
->token_info_enabled
) return
;
5930 ptinfo
= ALLOC
(token_info
);
5931 ptinfo
->token
= token
;
5932 ptinfo
->next
= p
->token_info
;
5933 token_info_setup
(ptinfo
, p
->lex.pbeg
, loc
);
5935 p
->token_info
= ptinfo
;
5939 token_info_pop
(struct parser_params
*p
, const char *token
, const rb_code_location_t
*loc
)
5941 token_info
*ptinfo_beg
= p
->token_info
;
5943 if
(!ptinfo_beg
) return
;
5944 p
->token_info
= ptinfo_beg
->next
;
5946 /* indentation check of matched keywords (begin..end, if..end, etc.) */
5947 token_info_warn
(p
, token
, ptinfo_beg
, 1, loc
);
5948 ruby_sized_xfree
(ptinfo_beg
, sizeof
(*ptinfo_beg
));
5952 token_info_drop
(struct parser_params
*p
, const char *token
, rb_code_position_t beg_pos
)
5954 token_info
*ptinfo_beg
= p
->token_info
;
5956 if
(!ptinfo_beg
) return
;
5957 p
->token_info
= ptinfo_beg
->next
;
5959 if
(ptinfo_beg
->beg.lineno
!= beg_pos.lineno ||
5960 ptinfo_beg
->beg.column
!= beg_pos.column ||
5961 strcmp
(ptinfo_beg
->token
, token
)) {
5962 compile_error
(p
, "token position mismatch: %d:%d:%s expected but %d:%d:%s",
5963 beg_pos.lineno
, beg_pos.column
, token
,
5964 ptinfo_beg
->beg.lineno
, ptinfo_beg
->beg.column
,
5968 ruby_sized_xfree
(ptinfo_beg
, sizeof
(*ptinfo_beg
));
5972 token_info_warn
(struct parser_params
*p
, const char *token
, token_info
*ptinfo_beg
, int same
, const rb_code_location_t
*loc
)
5974 token_info ptinfo_end_body
, *ptinfo_end
= &ptinfo_end_body
;
5975 if
(!p
->token_info_enabled
) return
;
5976 if
(!ptinfo_beg
) return
;
5977 token_info_setup
(ptinfo_end
, p
->lex.pbeg
, loc
);
5978 if
(ptinfo_beg
->beg.lineno
== ptinfo_end
->beg.lineno
) return
; /* ignore one-line block */
5979 if
(ptinfo_beg
->nonspc || ptinfo_end
->nonspc
) return
; /* ignore keyword in the middle of a line */
5980 if
(ptinfo_beg
->indent
== ptinfo_end
->indent
) return
; /* the indents are matched */
5981 if
(!same
&& ptinfo_beg
->indent
< ptinfo_end
->indent
) return
;
5982 rb_warn3L
(ptinfo_end
->beg.lineno
,
5983 "mismatched indentations at '%s' with '%s' at %d",
5984 WARN_S
(token
), WARN_S
(ptinfo_beg
->token
), WARN_I
(ptinfo_beg
->beg.lineno
));
5988 parser_precise_mbclen
(struct parser_params
*p
, const char *ptr
)
5990 int len
= rb_enc_precise_mbclen
(ptr
, p
->lex.pend
, p
->enc
);
5991 if
(!MBCLEN_CHARFOUND_P
(len
)) {
5992 compile_error
(p
, "invalid multibyte char (%s)", rb_enc_name
(p
->enc
));
5999 static void ruby_show_error_line
(VALUE errbuf
, const YYLTYPE *yylloc, int lineno
, VALUE str
);
6002 parser_show_error_line
(struct parser_params
*p
, const YYLTYPE *yylloc)
6005 int lineno
= p
->ruby_sourceline
;
6009 else if
(yylloc->beg_pos.lineno
== lineno
) {
6010 str
= p
->lex.lastline
;
6015 ruby_show_error_line
(p
->error_buffer
, yylloc, lineno
, str
);
6019 parser_yyerror
(struct parser_params
*p
, const YYLTYPE *yylloc, const char *msg
)
6025 yylloc = RUBY_SET_YYLLOC
(current
);
6027 else if
((p
->ruby_sourceline
!= yylloc->beg_pos.lineno
&&
6028 p
->ruby_sourceline
!= yylloc->end_pos.lineno
)) {
6032 compile_error
(p
, "%s", msg
);
6033 parser_show_error_line
(p
, yylloc);
6038 parser_yyerror0
(struct parser_params
*p
, const char *msg
)
6041 return parser_yyerror
(p
, RUBY_SET_YYLLOC
(current
), msg
);
6045 ruby_show_error_line
(VALUE errbuf
, const YYLTYPE *yylloc, int lineno
, VALUE str
)
6048 const int max_line_margin
= 30;
6049 const char *ptr
, *ptr_end
, *pt
, *pb
;
6050 const char *pre
= "", *post
= "", *pend
;
6051 const char *code
= "", *caret
= "";
6053 const char *const pbeg
= RSTRING_PTR
(str
);
6058 if
(!yylloc) return
;
6059 pend
= RSTRING_END
(str
);
6060 if
(pend
> pbeg
&& pend
[-1] == '\n') {
6061 if
(--pend
> pbeg
&& pend
[-1] == '\r') --pend
;
6065 if
(lineno
== yylloc->end_pos.lineno
&&
6066 (pend
- pbeg
) > yylloc->end_pos.column
) {
6067 pt
= pbeg
+ yylloc->end_pos.column
;
6071 lim
= ptr
- pbeg
> max_line_margin ? ptr
- max_line_margin
: pbeg
;
6072 while
((lim
< ptr
) && (*(ptr
-1) != '\n')) ptr
--;
6074 lim
= pend
- ptr_end
> max_line_margin ? ptr_end
+ max_line_margin
: pend
;
6075 while
((ptr_end
< lim
) && (*ptr_end
!= '\n') && (*ptr_end
!= '\r')) ptr_end
++;
6077 len
= ptr_end
- ptr
;
6080 ptr
= rb_enc_prev_char
(pbeg
, ptr
, pt
, rb_enc_get
(str
));
6081 if
(ptr
> pbeg
) pre
= "...";
6083 if
(ptr_end
< pend
) {
6084 ptr_end
= rb_enc_prev_char
(pt
, ptr_end
, pend
, rb_enc_get
(str
));
6085 if
(ptr_end
< pend
) post
= "...";
6089 if
(lineno
== yylloc->beg_pos.lineno
) {
6090 pb
+= yylloc->beg_pos.column
;
6091 if
(pb
> pt
) pb
= pt
;
6093 if
(pb
< ptr
) pb
= ptr
;
6094 if
(len
<= 4 && yylloc->beg_pos.lineno
== yylloc->end_pos.lineno
) {
6097 if
(RTEST
(errbuf
)) {
6098 mesg
= rb_attr_get
(errbuf
, idMesg
);
6099 if
(RSTRING_LEN
(mesg
) > 0 && *(RSTRING_END
(mesg
)-1) != '\n')
6100 rb_str_cat_cstr
(mesg
, "\n");
6103 mesg
= rb_enc_str_new
(0, 0, rb_enc_get
(str
));
6105 if
(!errbuf
&& rb_stderr_tty_p
()) {
6106 #define CSI_BEGIN "\033["
6109 CSI_BEGIN
""CSI_SGR
"%s" /* pre */
6110 CSI_BEGIN
"1"CSI_SGR
"%.*s"
6111 CSI_BEGIN
"1;4"CSI_SGR
"%.*s"
6112 CSI_BEGIN
";1"CSI_SGR
"%.*s"
6113 CSI_BEGIN
""CSI_SGR
"%s" /* post */
6116 (int)(pb
- ptr
), ptr
,
6118 (int)(ptr_end
- pt
), pt
,
6124 len
= ptr_end
- ptr
;
6125 lim
= pt
< pend ? pt
: pend
;
6126 i
= (int)(lim
- ptr
);
6127 buf
= ALLOCA_N
(char, i
+2);
6132 *p2
++ = *ptr
++ == '\t' ?
'\t' : ' ';
6138 memset
(p2
, '~', (lim
- ptr
));
6142 rb_str_catf
(mesg
, "%s%.*s%s\n""%s%s\n",
6143 pre
, (int)len
, code
, post
,
6146 if
(!errbuf
) rb_write_error_str
(mesg
);
6150 parser_yyerror
(struct parser_params
*p
, const YYLTYPE *yylloc, const char *msg
)
6152 const char *pcur
= 0, *ptok
= 0;
6153 if
(p
->ruby_sourceline
== yylloc->beg_pos.lineno
&&
6154 p
->ruby_sourceline
== yylloc->end_pos.lineno
) {
6157 p
->lex.ptok
= p
->lex.pbeg
+ yylloc->beg_pos.column
;
6158 p
->lex.pcur
= p
->lex.pbeg
+ yylloc->end_pos.column
;
6160 parser_yyerror0
(p
, msg
);
6169 parser_yyerror0
(struct parser_params
*p
, const char *msg
)
6171 dispatch1
(parse_error
, STR_NEW2
(msg
));
6177 parser_show_error_line
(struct parser_params
*p
, const YYLTYPE *yylloc)
6180 #endif /* !RIPPER */
6184 vtable_size
(const struct vtable
*tbl
)
6186 if
(!DVARS_TERMINAL_P
(tbl
)) {
6195 static struct vtable
*
6196 vtable_alloc_gen
(struct parser_params
*p
, int line
, struct vtable
*prev
)
6198 struct vtable
*tbl
= ALLOC
(struct vtable
);
6201 tbl
->tbl
= ALLOC_N
(ID
, tbl
->capa
);
6205 rb_parser_printf
(p
, "vtable_alloc:%d: %p\n", line
, (void *)tbl
);
6210 #define vtable_alloc(prev) vtable_alloc_gen(p, __LINE__, prev)
6213 vtable_free_gen
(struct parser_params
*p
, int line
, const char *name
,
6218 rb_parser_printf
(p
, "vtable_free:%d: %s(%p)\n", line
, name
, (void *)tbl
);
6221 if
(!DVARS_TERMINAL_P
(tbl
)) {
6223 ruby_sized_xfree
(tbl
->tbl
, tbl
->capa
* sizeof
(ID
));
6225 ruby_sized_xfree
(tbl
, sizeof
(*tbl
));
6228 #define vtable_free(tbl) vtable_free_gen(p, __LINE__, #tbl, tbl)
6231 vtable_add_gen
(struct parser_params
*p
, int line
, const char *name
,
6232 struct vtable
*tbl
, ID id
)
6236 rb_parser_printf
(p
, "vtable_add:%d: %s(%p), %s\n",
6237 line
, name
, (void *)tbl
, rb_id2name
(id
));
6240 if
(DVARS_TERMINAL_P
(tbl
)) {
6241 rb_parser_fatal
(p
, "vtable_add: vtable is not allocated (%p)", (void *)tbl
);
6244 if
(tbl
->pos
== tbl
->capa
) {
6245 tbl
->capa
= tbl
->capa
* 2;
6246 SIZED_REALLOC_N
(tbl
->tbl
, ID
, tbl
->capa
, tbl
->pos
);
6248 tbl
->tbl
[tbl
->pos
++] = id
;
6250 #define vtable_add(tbl, id) vtable_add_gen(p, __LINE__, #tbl, tbl, id)
6254 vtable_pop_gen
(struct parser_params
*p
, int line
, const char *name
,
6255 struct vtable
*tbl
, int n
)
6258 rb_parser_printf
(p
, "vtable_pop:%d: %s(%p), %d\n",
6259 line
, name
, (void *)tbl
, n
);
6262 rb_parser_fatal
(p
, "vtable_pop: unreachable (%d < %d)", tbl
->pos
, n
);
6267 #define vtable_pop(tbl, n) vtable_pop_gen(p, __LINE__, #tbl, tbl, n)
6271 vtable_included
(const struct vtable
* tbl
, ID id
)
6275 if
(!DVARS_TERMINAL_P
(tbl
)) {
6276 for
(i
= 0; i
< tbl
->pos
; i
++) {
6277 if
(tbl
->tbl
[i
] == id
) {
6285 static void parser_prepare
(struct parser_params
*p
);
6288 static NODE
*parser_append_options
(struct parser_params
*p
, NODE
*node
);
6291 debug_lines
(VALUE fname
)
6294 CONST_ID
(script_lines
, "SCRIPT_LINES__");
6295 if
(rb_const_defined_at
(rb_cObject
, script_lines
)) {
6296 VALUE hash
= rb_const_get_at
(rb_cObject
, script_lines
);
6297 if
(RB_TYPE_P
(hash
, T_HASH
)) {
6298 VALUE lines
= rb_ary_new
();
6299 rb_hash_aset
(hash
, fname
, lines
);
6307 e_option_supplied
(struct parser_params
*p
)
6309 return strcmp
(p
->ruby_sourcefile
, "-e") == 0;
6313 yycompile0
(VALUE arg
)
6317 struct parser_params
*p
= (struct parser_params
*)arg
;
6320 if
(!compile_for_eval
&& !NIL_P
(p
->ruby_sourcefile_string
)) {
6321 p
->debug_lines
= debug_lines
(p
->ruby_sourcefile_string
);
6322 if
(p
->debug_lines
&& p
->ruby_sourceline
> 0) {
6323 VALUE str
= rb_default_rs
;
6324 n
= p
->ruby_sourceline
;
6326 rb_ary_push
(p
->debug_lines
, str
);
6330 if
(!e_option_supplied
(p
)) {
6335 if
(p
->keep_script_lines || ruby_vm_keep_script_lines
) {
6336 if
(!p
->debug_lines
) {
6337 p
->debug_lines
= rb_ary_new
();
6340 RB_OBJ_WRITE
(p
->ast
, &p
->ast
->body.script_lines
, p
->debug_lines
);
6344 #define RUBY_DTRACE_PARSE_HOOK(name) \
6345 if
(RUBY_DTRACE_PARSE_
##name##_ENABLED()) { \
6346 RUBY_DTRACE_PARSE_
##name(p->ruby_sourcefile, p->ruby_sourceline); \
6348 RUBY_DTRACE_PARSE_HOOK
(BEGIN
);
6350 RUBY_DTRACE_PARSE_HOOK
(END
);
6354 p
->lex.pcur
= p
->lex.pbeg
= p
->lex.pend
= 0;
6355 p
->lex.prevline
= p
->lex.lastline
= p
->lex.nextline
= 0;
6356 if
(n || p
->error_p
) {
6357 VALUE mesg
= p
->error_buffer
;
6359 mesg
= rb_class_new_instance
(0, 0, rb_eSyntaxError
);
6361 rb_set_errinfo
(mesg
);
6364 tree
= p
->eval_tree
;
6366 tree
= NEW_NIL
(&NULL_LOC
);
6369 VALUE opt
= p
->compile_option
;
6371 NODE
*body
= parser_append_options
(p
, tree
->nd_body
);
6372 if
(!opt
) opt
= rb_obj_hide
(rb_ident_hash_new
());
6373 rb_hash_aset
(opt
, rb_sym_intern_ascii_cstr
("coverage_enabled"), cov
);
6374 prelude
= block_append
(p
, p
->eval_tree_begin
, body
);
6375 tree
->nd_body
= prelude
;
6376 RB_OBJ_WRITE
(p
->ast
, &p
->ast
->body.compile_option
, opt
);
6378 p
->ast
->body.root
= tree
;
6379 if
(!p
->ast
->body.script_lines
) p
->ast
->body.script_lines
= INT2FIX
(p
->line_count
);
6384 yycompile
(VALUE vparser
, struct parser_params
*p
, VALUE fname
, int line
)
6388 p
->ruby_sourcefile_string
= Qnil
;
6389 p
->ruby_sourcefile
= "(none)";
6392 p
->ruby_sourcefile_string
= rb_fstring
(fname
);
6393 p
->ruby_sourcefile
= StringValueCStr
(fname
);
6395 p
->ruby_sourceline
= line
- 1;
6399 p
->ast
= ast
= rb_ast_new
();
6400 rb_suppress_tracing
(yycompile0
, (VALUE
)p
);
6402 RB_GC_GUARD
(vparser
); /* prohibit tail call optimization */
6410 #endif /* !RIPPER */
6412 static rb_encoding
*
6413 must_be_ascii_compatible
(VALUE s
)
6415 rb_encoding
*enc
= rb_enc_get
(s
);
6416 if
(!rb_enc_asciicompat
(enc
)) {
6417 rb_raise
(rb_eArgError
, "invalid source encoding");
6423 lex_get_str
(struct parser_params
*p
, VALUE s
)
6425 char *beg
, *end
, *start
;
6428 beg
= RSTRING_PTR
(s
);
6429 len
= RSTRING_LEN
(s
);
6431 if
(p
->lex.gets_.ptr
) {
6432 if
(len
== p
->lex.gets_.ptr
) return Qnil
;
6433 beg
+= p
->lex.gets_.ptr
;
6434 len
-= p
->lex.gets_.ptr
;
6436 end
= memchr
(beg
, '\n', len
);
6437 if
(end
) len
= ++end
- beg
;
6438 p
->lex.gets_.ptr
+= len
;
6439 return rb_str_subseq
(s
, beg
- start
, len
);
6443 lex_getline
(struct parser_params
*p
)
6445 VALUE line
= (*p
->lex.gets
)(p
, p
->lex.input
);
6446 if
(NIL_P
(line
)) return line
;
6447 must_be_ascii_compatible
(line
);
6448 if
(RB_OBJ_FROZEN
(line
)) line
= rb_str_dup
(line
); // needed for RubyVM::AST.of because script_lines in iseq is deep-frozen
6450 if
(p
->debug_lines
) {
6451 rb_enc_associate
(line
, p
->enc
);
6452 rb_ary_push
(p
->debug_lines
, line
);
6459 static const rb_data_type_t parser_data_type
;
6463 parser_compile_string
(VALUE vparser
, VALUE fname
, VALUE s
, int line
)
6465 struct parser_params
*p
;
6467 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
6469 p
->lex.gets
= lex_get_str
;
6470 p
->lex.gets_.ptr
= 0;
6471 p
->lex.input
= rb_str_new_frozen
(s
);
6472 p
->lex.pbeg
= p
->lex.pcur
= p
->lex.pend
= 0;
6474 return yycompile
(vparser
, p
, fname
, line
);
6478 rb_parser_compile_string
(VALUE vparser
, const char *f
, VALUE s
, int line
)
6480 return rb_parser_compile_string_path
(vparser
, rb_filesystem_str_new_cstr
(f
), s
, line
);
6484 rb_parser_compile_string_path
(VALUE vparser
, VALUE f
, VALUE s
, int line
)
6486 must_be_ascii_compatible
(s
);
6487 return parser_compile_string
(vparser
, f
, s
, line
);
6490 VALUE rb_io_gets_internal
(VALUE io
);
6493 lex_io_gets
(struct parser_params
*p
, VALUE io
)
6495 return rb_io_gets_internal
(io
);
6499 rb_parser_compile_file_path
(VALUE vparser
, VALUE fname
, VALUE file
, int start
)
6501 struct parser_params
*p
;
6503 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
6505 p
->lex.gets
= lex_io_gets
;
6506 p
->lex.input
= file
;
6507 p
->lex.pbeg
= p
->lex.pcur
= p
->lex.pend
= 0;
6509 return yycompile
(vparser
, p
, fname
, start
);
6513 lex_generic_gets
(struct parser_params
*p
, VALUE input
)
6515 return
(*p
->lex.gets_.call
)(input
, p
->line_count
);
6519 rb_parser_compile_generic
(VALUE vparser
, VALUE
(*lex_gets
)(VALUE
, int), VALUE fname
, VALUE input
, int start
)
6521 struct parser_params
*p
;
6523 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
6525 p
->lex.gets
= lex_generic_gets
;
6526 p
->lex.gets_.call
= lex_gets
;
6527 p
->lex.input
= input
;
6528 p
->lex.pbeg
= p
->lex.pcur
= p
->lex.pend
= 0;
6530 return yycompile
(vparser
, p
, fname
, start
);
6532 #endif /* !RIPPER */
6534 #define STR_FUNC_ESCAPE 0x01
6535 #define STR_FUNC_EXPAND 0x02
6536 #define STR_FUNC_REGEXP 0x04
6537 #define STR_FUNC_QWORDS 0x08
6538 #define STR_FUNC_SYMBOL 0x10
6539 #define STR_FUNC_INDENT 0x20
6540 #define STR_FUNC_LABEL 0x40
6541 #define STR_FUNC_LIST 0x4000
6542 #define STR_FUNC_TERM 0x8000
6545 str_label
= STR_FUNC_LABEL
,
6547 str_dquote
= (STR_FUNC_EXPAND
),
6548 str_xquote
= (STR_FUNC_EXPAND
),
6549 str_regexp
= (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND
),
6550 str_sword
= (STR_FUNC_QWORDS|STR_FUNC_LIST
),
6551 str_dword
= (STR_FUNC_QWORDS|STR_FUNC_EXPAND|STR_FUNC_LIST
),
6552 str_ssym
= (STR_FUNC_SYMBOL
),
6553 str_dsym
= (STR_FUNC_SYMBOL|STR_FUNC_EXPAND
)
6557 parser_str_new
(const char *ptr
, long len
, rb_encoding
*enc
, int func
, rb_encoding
*enc0
)
6561 str
= rb_enc_str_new
(ptr
, len
, enc
);
6562 if
(!(func
& STR_FUNC_REGEXP
) && rb_enc_asciicompat
(enc
)) {
6563 if
(rb_enc_str_coderange
(str
) == ENC_CODERANGE_7BIT
) {
6565 else if
(enc0
== rb_usascii_encoding
() && enc
!= rb_utf8_encoding
()) {
6566 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
6573 #define lex_goto_eol(p) ((p)->lex.pcur = (p)->lex.pend)
6574 #define lex_eol_p(p) ((p)->lex.pcur >= (p)->lex.pend)
6575 #define lex_eol_n_p(p,n) ((p)->lex.pcur+(n) >= (p)->lex.pend)
6576 #define peek(p,c) peek_n(p, (c), 0)
6577 #define peek_n(p,c,n) (!lex_eol_n_p(p, n) && (c) == (unsigned char)(p)->lex.pcur[n])
6578 #define peekc(p) peekc_n(p, 0)
6579 #define peekc_n(p,n) (lex_eol_n_p(p, n) ? -1 : (unsigned char)(p)->lex.pcur[n])
6583 add_delayed_token
(struct parser_params
*p
, const char *tok
, const char *end
)
6586 if
(!has_delayed_token
(p
)) {
6587 p
->delayed.token
= rb_str_buf_new
(end
- tok
);
6588 rb_enc_associate
(p
->delayed.token
, p
->enc
);
6589 p
->delayed.line
= p
->ruby_sourceline
;
6590 p
->delayed.col
= rb_long2int
(tok
- p
->lex.pbeg
);
6592 rb_str_buf_cat
(p
->delayed.token
, tok
, end
- tok
);
6597 #define add_delayed_token(p, tok, end) ((void)(tok), (void)(end))
6601 nextline
(struct parser_params
*p
)
6603 VALUE v
= p
->lex.nextline
;
6604 p
->lex.nextline
= 0;
6609 if
(p
->lex.pend
> p
->lex.pbeg
&& *(p
->lex.pend
-1) != '\n') {
6613 if
(!p
->lex.input || NIL_P
(v
= lex_getline
(p
))) {
6621 else if
(NIL_P
(v
)) {
6622 /* after here-document without terminator */
6625 add_delayed_token
(p
, p
->lex.ptok
, p
->lex.pend
);
6626 if
(p
->heredoc_end
> 0) {
6627 p
->ruby_sourceline
= p
->heredoc_end
;
6630 p
->ruby_sourceline
++;
6631 p
->lex.pbeg
= p
->lex.pcur
= RSTRING_PTR
(v
);
6632 p
->lex.pend
= p
->lex.pcur
+ RSTRING_LEN
(v
);
6634 p
->lex.prevline
= p
->lex.lastline
;
6635 p
->lex.lastline
= v
;
6640 parser_cr
(struct parser_params
*p
, int c
)
6642 if
(peek
(p
, '\n')) {
6650 nextc
(struct parser_params
*p
)
6654 if
(UNLIKELY
((p
->lex.pcur
== p
->lex.pend
) || p
->eofp || RTEST
(p
->lex.nextline
))) {
6655 if
(nextline
(p
)) return
-1;
6657 c
= (unsigned char)*p
->lex.pcur
++;
6658 if
(UNLIKELY
(c
== '\r')) {
6659 c
= parser_cr
(p
, c
);
6666 pushback
(struct parser_params
*p
, int c
)
6668 if
(c
== -1) return
;
6670 if
(p
->lex.pcur
> p
->lex.pbeg
&& p
->lex.pcur
[0] == '\n' && p
->lex.pcur
[-1] == '\r') {
6675 #define was_bol(p) ((p)->lex.pcur == (p)->lex.pbeg + 1)
6677 #define tokfix(p) ((p)->tokenbuf[(p)->tokidx]='\0')
6678 #define tok(p) (p)->tokenbuf
6679 #define toklen(p) (p)->tokidx
6682 looking_at_eol_p
(struct parser_params
*p
)
6684 const char *ptr
= p
->lex.pcur
;
6685 while
(ptr
< p
->lex.pend
) {
6686 int c
= (unsigned char)*ptr
++;
6687 int eol
= (c
== '\n' || c
== '#');
6688 if
(eol ||
!ISSPACE
(c
)) {
6696 newtok
(struct parser_params
*p
)
6699 p
->tokline
= p
->ruby_sourceline
;
6702 p
->tokenbuf
= ALLOC_N
(char, 60);
6704 if
(p
->toksiz
> 4096) {
6706 REALLOC_N
(p
->tokenbuf
, char, 60);
6712 tokspace
(struct parser_params
*p
, int n
)
6716 if
(p
->tokidx
>= p
->toksiz
) {
6717 do
{p
->toksiz
*= 2;} while
(p
->toksiz
< p
->tokidx
);
6718 REALLOC_N
(p
->tokenbuf
, char, p
->toksiz
);
6720 return
&p
->tokenbuf
[p
->tokidx
-n
];
6724 tokadd
(struct parser_params
*p
, int c
)
6726 p
->tokenbuf
[p
->tokidx
++] = (char)c
;
6727 if
(p
->tokidx
>= p
->toksiz
) {
6729 REALLOC_N
(p
->tokenbuf
, char, p
->toksiz
);
6734 tok_hex
(struct parser_params
*p
, size_t *numlen
)
6738 c
= scan_hex
(p
->lex.pcur
, 2, numlen
);
6740 yyerror0
("invalid hex escape");
6744 p
->lex.pcur
+= *numlen
;
6748 #define tokcopy(p, n) memcpy(tokspace(p, n), (p)->lex.pcur - (n), (n))
6751 escaped_control_code
(int c
)
6777 #define WARN_SPACE_CHAR(c, prefix) \
6778 rb_warn1
("invalid character syntax; use "prefix
"\\%c", WARN_I
(c2
))
6781 tokadd_codepoint
(struct parser_params
*p
, rb_encoding
**encp
,
6782 int regexp_literal
, int wide
)
6785 int codepoint
= scan_hex
(p
->lex.pcur
, wide ? p
->lex.pend
- p
->lex.pcur
: 4, &numlen
);
6786 literal_flush
(p
, p
->lex.pcur
);
6787 p
->lex.pcur
+= numlen
;
6788 if
(wide ?
(numlen
== 0 || numlen
> 6) : (numlen
< 4)) {
6789 yyerror0
("invalid Unicode escape");
6790 return wide
&& numlen
> 0;
6792 if
(codepoint
> 0x10ffff) {
6793 yyerror0
("invalid Unicode codepoint (too large)");
6796 if
((codepoint
& 0xfffff800) == 0xd800) {
6797 yyerror0
("invalid Unicode codepoint");
6800 if
(regexp_literal
) {
6801 tokcopy
(p
, (int)numlen
);
6803 else if
(codepoint
>= 0x80) {
6804 rb_encoding
*utf8
= rb_utf8_encoding
();
6805 if
(*encp
&& utf8
!= *encp
) {
6806 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
6807 compile_error
(p
, "UTF-8 mixed within %s source", rb_enc_name
(*encp
));
6808 parser_show_error_line
(p
, &loc
);
6812 tokaddmbc
(p
, codepoint
, *encp
);
6815 tokadd
(p
, codepoint
);
6820 /* return value is for ?\u3042 */
6822 tokadd_utf8
(struct parser_params
*p
, rb_encoding
**encp
,
6823 int term
, int symbol_literal
, int regexp_literal
)
6826 * If `term` is not -1, then we allow multiple codepoints in \u{}
6827 * upto `term` byte, otherwise we're parsing a character literal.
6828 * And then add the codepoints to the current token.
6830 static const char multiple_codepoints
[] = "Multiple codepoints at single character literal";
6832 const int open_brace
= '{', close_brace
= '}';
6834 if
(regexp_literal
) { tokadd
(p
, '\\'); tokadd
(p
, 'u'); }
6836 if
(peek
(p
, open_brace
)) { /* handle \u{...} form */
6837 const char *second
= NULL
;
6838 int c
, last
= nextc
(p
);
6839 if
(p
->lex.pcur
>= p
->lex.pend
) goto unterminated
;
6840 while
(ISSPACE
(c
= *p
->lex.pcur
) && ++p
->lex.pcur
< p
->lex.pend
);
6841 while
(c
!= close_brace
) {
6842 if
(c
== term
) goto unterminated
;
6843 if
(second
== multiple_codepoints
)
6844 second
= p
->lex.pcur
;
6845 if
(regexp_literal
) tokadd
(p
, last
);
6846 if
(!tokadd_codepoint
(p
, encp
, regexp_literal
, TRUE
)) {
6849 while
(ISSPACE
(c
= *p
->lex.pcur
)) {
6850 if
(++p
->lex.pcur
>= p
->lex.pend
) goto unterminated
;
6853 if
(term
== -1 && !second
)
6854 second
= multiple_codepoints
;
6857 if
(c
!= close_brace
) {
6860 yyerror0
("unterminated Unicode escape");
6863 if
(second
&& second
!= multiple_codepoints
) {
6864 const char *pcur
= p
->lex.pcur
;
6865 p
->lex.pcur
= second
;
6866 dispatch_scan_event
(p
, tSTRING_CONTENT
);
6869 yyerror0
(multiple_codepoints
);
6873 if
(regexp_literal
) tokadd
(p
, close_brace
);
6876 else
{ /* handle \uxxxx form */
6877 if
(!tokadd_codepoint
(p
, encp
, regexp_literal
, FALSE
)) {
6884 #define ESCAPE_CONTROL 1
6885 #define ESCAPE_META 2
6888 read_escape
(struct parser_params
*p
, int flags
, rb_encoding
**encp
)
6893 switch
(c
= nextc
(p
)) {
6894 case
'\\': /* Backslash */
6897 case
'n': /* newline */
6900 case
't': /* horizontal tab */
6903 case
'r': /* carriage-return */
6906 case
'f': /* form-feed */
6909 case
'v': /* vertical tab */
6912 case
'a': /* alarm(bell) */
6915 case
'e': /* escape */
6918 case
'0': case
'1': case
'2': case
'3': /* octal constant */
6919 case
'4': case
'5': case
'6': case
'7':
6921 c
= scan_oct
(p
->lex.pcur
, 3, &numlen
);
6922 p
->lex.pcur
+= numlen
;
6925 case
'x': /* hex constant */
6926 c
= tok_hex
(p
, &numlen
);
6927 if
(numlen
== 0) return
0;
6930 case
'b': /* backspace */
6933 case
's': /* space */
6937 if
(flags
& ESCAPE_META
) goto eof
;
6938 if
((c
= nextc
(p
)) != '-') {
6941 if
((c
= nextc
(p
)) == '\\') {
6947 return read_escape
(p
, flags|ESCAPE_META
, encp
) |
0x80;
6949 else if
(c
== -1 ||
!ISASCII
(c
)) goto eof
;
6951 int c2
= escaped_control_code
(c
);
6953 if
(ISCNTRL
(c
) ||
!(flags
& ESCAPE_CONTROL
)) {
6954 WARN_SPACE_CHAR
(c2
, "\\M-");
6957 WARN_SPACE_CHAR
(c2
, "\\C-\\M-");
6960 else if
(ISCNTRL
(c
)) goto eof
;
6961 return
((c
& 0xff) |
0x80);
6965 if
((c
= nextc
(p
)) != '-') {
6969 if
(flags
& ESCAPE_CONTROL
) goto eof
;
6970 if
((c
= nextc
(p
))== '\\') {
6976 c
= read_escape
(p
, flags|ESCAPE_CONTROL
, encp
);
6980 else if
(c
== -1 ||
!ISASCII
(c
)) goto eof
;
6982 int c2
= escaped_control_code
(c
);
6985 if
(flags
& ESCAPE_META
) {
6986 WARN_SPACE_CHAR
(c2
, "\\M-");
6989 WARN_SPACE_CHAR
(c2
, "");
6993 if
(flags
& ESCAPE_META
) {
6994 WARN_SPACE_CHAR
(c2
, "\\M-\\C-");
6997 WARN_SPACE_CHAR
(c2
, "\\C-");
7001 else if
(ISCNTRL
(c
)) goto eof
;
7007 yyerror0
("Invalid escape character syntax");
7017 tokaddmbc
(struct parser_params
*p
, int c
, rb_encoding
*enc
)
7019 int len
= rb_enc_codelen
(c
, enc
);
7020 rb_enc_mbcput
(c
, tokspace
(p
, len
), enc
);
7024 tokadd_escape
(struct parser_params
*p
, rb_encoding
**encp
)
7029 switch
(c
= nextc
(p
)) {
7031 return
0; /* just ignore */
7033 case
'0': case
'1': case
'2': case
'3': /* octal constant */
7034 case
'4': case
'5': case
'6': case
'7':
7036 ruby_scan_oct
(--p
->lex.pcur
, 3, &numlen
);
7037 if
(numlen
== 0) goto eof
;
7038 p
->lex.pcur
+= numlen
;
7039 tokcopy
(p
, (int)numlen
+ 1);
7043 case
'x': /* hex constant */
7045 tok_hex
(p
, &numlen
);
7046 if
(numlen
== 0) return
-1;
7047 tokcopy
(p
, (int)numlen
+ 2);
7053 yyerror0
("Invalid escape character syntax");
7065 regx_options
(struct parser_params
*p
)
7073 while
(c
= nextc
(p
), ISALPHA
(c
)) {
7075 options |
= RE_OPTION_ONCE
;
7077 else if
(rb_char_to_option_kcode
(c
, &opt
, &kc
)) {
7079 if
(kc
!= rb_ascii8bit_encindex
()) kcode
= c
;
7093 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
7095 compile_error
(p
, "unknown regexp option%s - %*s",
7096 toklen
(p
) > 1 ?
"s" : "", toklen
(p
), tok
(p
));
7097 parser_show_error_line
(p
, &loc
);
7099 return options | RE_OPTION_ENCODING
(kcode
);
7103 tokadd_mbchar
(struct parser_params
*p
, int c
)
7105 int len
= parser_precise_mbclen
(p
, p
->lex.pcur
-1);
7106 if
(len
< 0) return
-1;
7108 p
->lex.pcur
+= --len
;
7109 if
(len
> 0) tokcopy
(p
, len
);
7114 simple_re_meta
(int c
)
7117 case
'$': case
'*': case
'+': case
'.':
7118 case
'?': case
'^': case
'|':
7119 case
')': case
']': case
'}': case
'>':
7127 parser_update_heredoc_indent
(struct parser_params
*p
, int c
)
7129 if
(p
->heredoc_line_indent
== -1) {
7130 if
(c
== '\n') p
->heredoc_line_indent
= 0;
7134 p
->heredoc_line_indent
++;
7137 else if
(c
== '\t') {
7138 int w
= (p
->heredoc_line_indent
/ TAB_WIDTH
) + 1;
7139 p
->heredoc_line_indent
= w
* TAB_WIDTH
;
7142 else if
(c
!= '\n') {
7143 if
(p
->heredoc_indent
> p
->heredoc_line_indent
) {
7144 p
->heredoc_indent
= p
->heredoc_line_indent
;
7146 p
->heredoc_line_indent
= -1;
7153 parser_mixed_error
(struct parser_params
*p
, rb_encoding
*enc1
, rb_encoding
*enc2
)
7155 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
7156 const char *n1
= rb_enc_name
(enc1
), *n2
= rb_enc_name
(enc2
);
7157 compile_error
(p
, "%s mixed within %s source", n1
, n2
);
7158 parser_show_error_line
(p
, &loc
);
7162 parser_mixed_escape
(struct parser_params
*p
, const char *beg
, rb_encoding
*enc1
, rb_encoding
*enc2
)
7164 const char *pos
= p
->lex.pcur
;
7166 parser_mixed_error
(p
, enc1
, enc2
);
7171 tokadd_string
(struct parser_params
*p
,
7172 int func
, int term
, int paren
, long *nest
,
7173 rb_encoding
**encp
, rb_encoding
**enc
)
7178 #define mixed_error(enc1, enc2) \
7179 (void)(erred ||
(parser_mixed_error
(p
, enc1
, enc2
), erred
= true
))
7180 #define mixed_escape(beg, enc1, enc2) \
7181 (void)(erred ||
(parser_mixed_escape
(p
, beg
, enc1
, enc2
), erred
= true
))
7183 while
((c
= nextc
(p
)) != -1) {
7184 if
(p
->heredoc_indent
> 0) {
7185 parser_update_heredoc_indent
(p
, c
);
7188 if
(paren
&& c
== paren
) {
7191 else if
(c
== term
) {
7192 if
(!nest ||
!*nest
) {
7198 else if
((func
& STR_FUNC_EXPAND
) && c
== '#' && p
->lex.pcur
< p
->lex.pend
) {
7199 int c2
= *p
->lex.pcur
;
7200 if
(c2
== '$' || c2
== '@' || c2
== '{') {
7205 else if
(c
== '\\') {
7206 literal_flush
(p
, p
->lex.pcur
- 1);
7210 if
(func
& STR_FUNC_QWORDS
) break
;
7211 if
(func
& STR_FUNC_EXPAND
) {
7212 if
(!(func
& STR_FUNC_INDENT
) ||
(p
->heredoc_indent
< 0))
7223 if
(func
& STR_FUNC_ESCAPE
) tokadd
(p
, c
);
7227 if
((func
& STR_FUNC_EXPAND
) == 0) {
7231 tokadd_utf8
(p
, enc
, term
,
7232 func
& STR_FUNC_SYMBOL
,
7233 func
& STR_FUNC_REGEXP
);
7237 if
(c
== -1) return
-1;
7239 if
((func
& STR_FUNC_EXPAND
) == 0) tokadd
(p
, '\\');
7242 if
(func
& STR_FUNC_REGEXP
) {
7248 c
= read_escape
(p
, 0, enc
);
7252 snprintf
(escbuf
, sizeof
(escbuf
), "\\x%02X", c
);
7253 for
(i
= 0; i
< 4; i
++) {
7254 tokadd
(p
, escbuf
[i
]);
7260 if
(c
== term
&& !simple_re_meta
(c
)) {
7265 if
((c
= tokadd_escape
(p
, enc
)) < 0)
7267 if
(*enc
&& *enc
!= *encp
) {
7268 mixed_escape
(p
->lex.ptok
+2, *enc
, *encp
);
7272 else if
(func
& STR_FUNC_EXPAND
) {
7274 if
(func
& STR_FUNC_ESCAPE
) tokadd
(p
, '\\');
7275 c
= read_escape
(p
, 0, enc
);
7277 else if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
7278 /* ignore backslashed spaces in %w */
7280 else if
(c
!= term
&& !(paren
&& c
== paren
)) {
7287 else if
(!parser_isascii
(p
)) {
7292 else if
(*enc
!= *encp
) {
7293 mixed_error
(*enc
, *encp
);
7296 if
(tokadd_mbchar
(p
, c
) == -1) return
-1;
7299 else if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
7307 else if
(*enc
!= *encp
) {
7308 mixed_error
(*enc
, *encp
);
7315 if
(*enc
) *encp
= *enc
;
7319 static inline rb_strterm_t
*
7320 new_strterm
(VALUE v1
, VALUE v2
, VALUE v3
, VALUE v0
)
7322 return
(rb_strterm_t
*)rb_imemo_new
(imemo_parser_strterm
, v1
, v2
, v3
, v0
);
7325 /* imemo_parser_strterm for literal */
7326 #define NEW_STRTERM(func, term, paren) \
7327 new_strterm
((VALUE
)(func
), (VALUE
)(paren
), (VALUE
)(term
), 0)
7331 flush_string_content
(struct parser_params
*p
, rb_encoding
*enc
)
7333 VALUE content
= yylval.val
;
7334 if
(!ripper_is_node_yylval
(content
))
7335 content
= ripper_new_yylval
(p
, 0, 0, content
);
7336 if
(has_delayed_token
(p
)) {
7337 ptrdiff_t len
= p
->lex.pcur
- p
->lex.ptok
;
7339 rb_enc_str_buf_cat
(p
->delayed.token
, p
->lex.ptok
, len
, enc
);
7341 dispatch_delayed_token
(p
, tSTRING_CONTENT
);
7342 p
->lex.ptok
= p
->lex.pcur
;
7343 RNODE
(content
)->nd_rval
= yylval.val
;
7345 dispatch_scan_event
(p
, tSTRING_CONTENT
);
7346 if
(yylval.val
!= content
)
7347 RNODE
(content
)->nd_rval
= yylval.val
;
7348 yylval.val
= content
;
7351 #define flush_string_content(p, enc) ((void)(enc))
7354 RUBY_FUNC_EXPORTED
const unsigned int ruby_global_name_punct_bits
[(0x7e - 0x20 + 31) / 32];
7355 /* this can be shared with ripper, since it's independent from struct
7358 #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
7359 #define SPECIAL_PUNCT(idx) ( \
7360 BIT
('~', idx
) | BIT
('*', idx
) | BIT
('$', idx
) | BIT
('?', idx
) | \
7361 BIT
('!', idx
) | BIT
('@', idx
) | BIT
('/', idx
) | BIT
('\\', idx
) | \
7362 BIT
(';', idx
) | BIT
(',', idx
) | BIT
('.', idx
) | BIT
('=', idx
) | \
7363 BIT
(':', idx
) | BIT
('<', idx
) | BIT
('>', idx
) | BIT
('\"', idx
) | \
7364 BIT
('&', idx
) | BIT
('`', idx
) | BIT
('\'', idx
) | BIT
('+', idx
) | \
7366 const unsigned int ruby_global_name_punct_bits
[] = {
7372 #undef SPECIAL_PUNCT
7375 static enum yytokentype
7376 parser_peek_variable_name
(struct parser_params
*p
)
7379 const char *ptr
= p
->lex.pcur
;
7381 if
(ptr
+ 1 >= p
->lex.pend
) return
0;
7385 if
((c
= *ptr
) == '-') {
7386 if
(++ptr
>= p
->lex.pend
) return
0;
7389 else if
(is_global_name_punct
(c
) || ISDIGIT
(c
)) {
7390 return tSTRING_DVAR
;
7394 if
((c
= *ptr
) == '@') {
7395 if
(++ptr
>= p
->lex.pend
) return
0;
7401 p
->command_start
= TRUE
;
7402 return tSTRING_DBEG
;
7406 if
(!ISASCII
(c
) || c
== '_' || ISALPHA
(c
))
7407 return tSTRING_DVAR
;
7411 #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
7412 #define IS_END() IS_lex_state(EXPR_END_ANY)
7413 #define IS_BEG() (IS_lex_state(EXPR_BEG_ANY) || IS_lex_state_all(EXPR_ARG|EXPR_LABELED))
7414 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
7415 #define IS_LABEL_POSSIBLE() (\
7416 (IS_lex_state
(EXPR_LABEL|EXPR_ENDFN
) && !cmd_state
) || \
7418 #define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
7419 #define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
7421 static inline
enum yytokentype
7422 parser_string_term
(struct parser_params
*p
, int func
)
7425 if
(func
& STR_FUNC_REGEXP
) {
7426 set_yylval_num
(regx_options
(p
));
7427 dispatch_scan_event
(p
, tREGEXP_END
);
7428 SET_LEX_STATE
(EXPR_END
);
7431 if
((func
& STR_FUNC_LABEL
) && IS_LABEL_SUFFIX
(0)) {
7433 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
7436 SET_LEX_STATE
(EXPR_END
);
7440 static enum yytokentype
7441 parse_string
(struct parser_params
*p
, rb_strterm_literal_t
*quote
)
7443 int func
= (int)quote
->u1.func
;
7444 int term
= (int)quote
->u3.term
;
7445 int paren
= (int)quote
->u2.paren
;
7447 rb_encoding
*enc
= p
->enc
;
7448 rb_encoding
*base_enc
= 0;
7451 if
(func
& STR_FUNC_TERM
) {
7452 if
(func
& STR_FUNC_QWORDS
) nextc
(p
); /* delayed term */
7453 SET_LEX_STATE
(EXPR_END
);
7455 return func
& STR_FUNC_REGEXP ? tREGEXP_END
: tSTRING_END
;
7458 if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
7459 do
{c
= nextc
(p
);} while
(ISSPACE
(c
));
7462 if
(func
& STR_FUNC_LIST
) {
7463 quote
->u1.func
&= ~STR_FUNC_LIST
;
7466 if
(c
== term
&& !quote
->u0.nest
) {
7467 if
(func
& STR_FUNC_QWORDS
) {
7468 quote
->u1.func |
= STR_FUNC_TERM
;
7469 pushback
(p
, c
); /* dispatch the term at tSTRING_END */
7470 add_delayed_token
(p
, p
->lex.ptok
, p
->lex.pcur
);
7473 return parser_string_term
(p
, func
);
7477 add_delayed_token
(p
, p
->lex.ptok
, p
->lex.pcur
);
7481 if
((func
& STR_FUNC_EXPAND
) && c
== '#') {
7482 int t
= parser_peek_variable_name
(p
);
7488 if
(tokadd_string
(p
, func
, term
, paren
, "e
->u0.nest
,
7489 &enc
, &base_enc
) == -1) {
7492 # define unterminated_literal(mesg) yyerror0(mesg)
7494 # define unterminated_literal(mesg) compile_error(p, mesg)
7496 literal_flush
(p
, p
->lex.pcur
);
7497 if
(func
& STR_FUNC_QWORDS
) {
7498 /* no content to add, bailing out here */
7499 unterminated_literal
("unterminated list meets end of file");
7503 if
(func
& STR_FUNC_REGEXP
) {
7504 unterminated_literal
("unterminated regexp meets end of file");
7507 unterminated_literal
("unterminated string meets end of file");
7509 quote
->u1.func |
= STR_FUNC_TERM
;
7514 lit
= STR_NEW3
(tok
(p
), toklen
(p
), enc
, func
);
7515 set_yylval_str
(lit
);
7516 flush_string_content
(p
, enc
);
7518 return tSTRING_CONTENT
;
7521 static enum yytokentype
7522 heredoc_identifier
(struct parser_params
*p
)
7525 * term_len is length of `<<"END"` except `END`,
7526 * in this case term_len is 4 (<, <, " and ").
7528 long len
, offset
= p
->lex.pcur
- p
->lex.pbeg
;
7529 int c
= nextc
(p
), term
, func
= 0, quote
= 0;
7530 enum yytokentype token
= tSTRING_BEG
;
7535 func
= STR_FUNC_INDENT
;
7538 else if
(c
== '~') {
7540 func
= STR_FUNC_INDENT
;
7546 func |
= str_squote
; goto quoted
;
7548 func |
= str_dquote
; goto quoted
;
7550 token
= tXSTRING_BEG
;
7551 func |
= str_xquote
; goto quoted
;
7558 while
((c
= nextc
(p
)) != term
) {
7559 if
(c
== -1 || c
== '\r' || c
== '\n') {
7560 yyerror0
("unterminated here document identifier");
7567 if
(!parser_is_identchar
(p
)) {
7569 if
(func
& STR_FUNC_INDENT
) {
7570 pushback
(p
, indent
> 0 ?
'~' : '-');
7576 int n
= parser_precise_mbclen
(p
, p
->lex.pcur
-1);
7577 if
(n
< 0) return
0;
7579 } while
((c
= nextc
(p
)) != -1 && parser_is_identchar
(p
));
7584 len
= p
->lex.pcur
- (p
->lex.pbeg
+ offset
) - quote
;
7585 if
((unsigned long)len
>= HERETERM_LENGTH_MAX
)
7586 yyerror0
("too long here document identifier");
7587 dispatch_scan_event
(p
, tHEREDOC_BEG
);
7590 p
->lex.strterm
= new_strterm
(0, 0, 0, p
->lex.lastline
);
7591 p
->lex.strterm
->flags |
= STRTERM_HEREDOC
;
7592 rb_strterm_heredoc_t
*here
= &p
->lex.strterm
->u.heredoc
;
7593 here
->offset
= offset
;
7594 here
->sourceline
= p
->ruby_sourceline
;
7595 here
->length
= (int)len
;
7596 here
->quote
= quote
;
7600 p
->heredoc_indent
= indent
;
7601 p
->heredoc_line_indent
= 0;
7606 heredoc_restore
(struct parser_params
*p
, rb_strterm_heredoc_t
*here
)
7611 line
= here
->lastline
;
7612 p
->lex.lastline
= line
;
7613 p
->lex.pbeg
= RSTRING_PTR
(line
);
7614 p
->lex.pend
= p
->lex.pbeg
+ RSTRING_LEN
(line
);
7615 p
->lex.pcur
= p
->lex.pbeg
+ here
->offset
+ here
->length
+ here
->quote
;
7616 p
->lex.ptok
= p
->lex.pbeg
+ here
->offset
- here
->quote
;
7617 p
->heredoc_end
= p
->ruby_sourceline
;
7618 p
->ruby_sourceline
= (int)here
->sourceline
;
7619 if
(p
->eofp
) p
->lex.nextline
= Qnil
;
7624 dedent_string
(VALUE
string, int width
)
7630 RSTRING_GETMEM
(string, str
, len
);
7631 for
(i
= 0; i
< len
&& col
< width
; i
++) {
7632 if
(str
[i
] == ' ') {
7635 else if
(str
[i
] == '\t') {
7636 int n
= TAB_WIDTH
* (col
/ TAB_WIDTH
+ 1);
7637 if
(n
> width
) break
;
7645 rb_str_modify
(string);
7646 str
= RSTRING_PTR
(string);
7647 if
(RSTRING_LEN
(string) != len
)
7648 rb_fatal
("literal string changed: %+"PRIsVALUE
, string);
7649 MEMMOVE
(str
, str
+ i
, char, len
- i
);
7650 rb_str_set_len
(string, len
- i
);
7656 heredoc_dedent
(struct parser_params
*p
, NODE
*root
)
7658 NODE
*node
, *str_node
, *prev_node
;
7659 int indent
= p
->heredoc_indent
;
7662 if
(indent
<= 0) return root
;
7663 p
->heredoc_indent
= 0;
7664 if
(!root
) return root
;
7666 prev_node
= node
= str_node
= root
;
7667 if
(nd_type_p
(root
, NODE_LIST
)) str_node
= root
->nd_head
;
7670 VALUE lit
= str_node
->nd_lit
;
7671 if
(str_node
->flags
& NODE_FL_NEWLINE
) {
7672 dedent_string
(lit
, indent
);
7677 else if
(!literal_concat0
(p
, prev_lit
, lit
)) {
7681 NODE
*end
= node
->nd_end
;
7682 node
= prev_node
->nd_next
= node
->nd_next
;
7684 if
(nd_type_p
(prev_node
, NODE_DSTR
))
7685 nd_set_type
(prev_node
, NODE_STR
);
7693 while
((node
= (prev_node
= node
)->nd_next
) != 0) {
7695 if
(!nd_type_p
(node
, NODE_LIST
)) break
;
7696 if
((str_node
= node
->nd_head
) != 0) {
7697 enum node_type type
= nd_type
(str_node
);
7698 if
(type
== NODE_STR || type
== NODE_DSTR
) break
;
7708 heredoc_dedent
(struct parser_params
*p
, VALUE array
)
7710 int indent
= p
->heredoc_indent
;
7712 if
(indent
<= 0) return array
;
7713 p
->heredoc_indent
= 0;
7714 dispatch2
(heredoc_dedent
, array
, INT2NUM
(indent
));
7720 * Ripper.dedent_string(input, width) -> Integer
7722 * USE OF RIPPER LIBRARY ONLY.
7724 * Strips up to +width+ leading whitespaces from +input+,
7725 * and returns the stripped column width.
7728 parser_dedent_string
(VALUE self
, VALUE input
, VALUE width
)
7733 wid
= NUM2UINT
(width
);
7734 col
= dedent_string
(input
, wid
);
7735 return INT2NUM
(col
);
7740 whole_match_p
(struct parser_params
*p
, const char *eos
, long len
, int indent
)
7742 const char *ptr
= p
->lex.pbeg
;
7746 while
(*ptr
&& ISSPACE
(*ptr
)) ptr
++;
7748 n
= p
->lex.pend
- (ptr
+ len
);
7749 if
(n
< 0) return FALSE
;
7750 if
(n
> 0 && ptr
[len
] != '\n') {
7751 if
(ptr
[len
] != '\r') return FALSE
;
7752 if
(n
<= 1 || ptr
[len
+1] != '\n') return FALSE
;
7754 return strncmp
(eos
, ptr
, len
) == 0;
7758 word_match_p
(struct parser_params
*p
, const char *word
, long len
)
7760 if
(strncmp
(p
->lex.pcur
, word
, len
)) return
0;
7761 if
(p
->lex.pcur
+ len
== p
->lex.pend
) return
1;
7762 int c
= (unsigned char)p
->lex.pcur
[len
];
7763 if
(ISSPACE
(c
)) return
1;
7765 case
'\0': case
'\004': case
'\032': return
1;
7770 #define NUM_SUFFIX_R (1<<0)
7771 #define NUM_SUFFIX_I (1<<1)
7772 #define NUM_SUFFIX_ALL 3
7775 number_literal_suffix
(struct parser_params
*p
, int mask
)
7778 const char *lastp
= p
->lex.pcur
;
7780 while
((c
= nextc
(p
)) != -1) {
7781 if
((mask
& NUM_SUFFIX_I
) && c
== 'i') {
7782 result |
= (mask
& NUM_SUFFIX_I
);
7783 mask
&= ~NUM_SUFFIX_I
;
7784 /* r after i, rational of complex is disallowed */
7785 mask
&= ~NUM_SUFFIX_R
;
7788 if
((mask
& NUM_SUFFIX_R
) && c
== 'r') {
7789 result |
= (mask
& NUM_SUFFIX_R
);
7790 mask
&= ~NUM_SUFFIX_R
;
7793 if
(!ISASCII
(c
) || ISALPHA
(c
) || c
== '_') {
7794 p
->lex.pcur
= lastp
;
7795 literal_flush
(p
, p
->lex.pcur
);
7804 static enum yytokentype
7805 set_number_literal
(struct parser_params
*p
, VALUE v
,
7806 enum yytokentype type
, int suffix
)
7808 if
(suffix
& NUM_SUFFIX_I
) {
7809 v
= rb_complex_raw
(INT2FIX
(0), v
);
7812 set_yylval_literal
(v
);
7813 SET_LEX_STATE
(EXPR_END
);
7817 static enum yytokentype
7818 set_integer_literal
(struct parser_params
*p
, VALUE v
, int suffix
)
7820 enum yytokentype type
= tINTEGER
;
7821 if
(suffix
& NUM_SUFFIX_R
) {
7822 v
= rb_rational_raw1
(v
);
7825 return set_number_literal
(p
, v
, type
, suffix
);
7830 dispatch_heredoc_end
(struct parser_params
*p
)
7833 if
(has_delayed_token
(p
))
7834 dispatch_delayed_token
(p
, tSTRING_CONTENT
);
7835 str
= STR_NEW
(p
->lex.ptok
, p
->lex.pend
- p
->lex.ptok
);
7836 ripper_dispatch1
(p
, ripper_token2eventid
(tHEREDOC_END
), str
);
7842 #define dispatch_heredoc_end(p) ((void)0)
7845 static enum yytokentype
7846 here_document
(struct parser_params
*p
, rb_strterm_heredoc_t
*here
)
7848 int c
, func
, indent
= 0;
7849 const char *eos
, *ptr
, *ptr_end
;
7852 rb_encoding
*enc
= p
->enc
;
7853 rb_encoding
*base_enc
= 0;
7856 eos
= RSTRING_PTR
(here
->lastline
) + here
->offset
;
7858 indent
= (func
= here
->func
) & STR_FUNC_INDENT
;
7860 if
((c
= nextc
(p
)) == -1) {
7863 if
(!has_delayed_token
(p
)) {
7864 dispatch_scan_event
(p
, tSTRING_CONTENT
);
7867 if
((len
= p
->lex.pcur
- p
->lex.ptok
) > 0) {
7868 if
(!(func
& STR_FUNC_REGEXP
) && rb_enc_asciicompat
(enc
)) {
7869 int cr
= ENC_CODERANGE_UNKNOWN
;
7870 rb_str_coderange_scan_restartable
(p
->lex.ptok
, p
->lex.pcur
, enc
, &cr
);
7871 if
(cr
!= ENC_CODERANGE_7BIT
&&
7872 p
->enc
== rb_usascii_encoding
() &&
7873 enc
!= rb_utf8_encoding
()) {
7874 enc
= rb_ascii8bit_encoding
();
7877 rb_enc_str_buf_cat
(p
->delayed.token
, p
->lex.ptok
, len
, enc
);
7879 dispatch_delayed_token
(p
, tSTRING_CONTENT
);
7883 heredoc_restore
(p
, &p
->lex.strterm
->u.heredoc
);
7884 compile_error
(p
, "can't find string \"%.*s\" anywhere before EOF",
7888 SET_LEX_STATE
(EXPR_END
);
7893 /* not beginning of line, cannot be the terminator */
7895 else if
(p
->heredoc_line_indent
== -1) {
7896 /* `heredoc_line_indent == -1` means
7897 * - "after an interpolation in the same line", or
7898 * - "in a continuing line"
7900 p
->heredoc_line_indent
= 0;
7902 else if
(whole_match_p
(p
, eos
, len
, indent
)) {
7903 dispatch_heredoc_end
(p
);
7905 heredoc_restore
(p
, &p
->lex.strterm
->u.heredoc
);
7908 SET_LEX_STATE
(EXPR_END
);
7912 if
(!(func
& STR_FUNC_EXPAND
)) {
7914 ptr
= RSTRING_PTR
(p
->lex.lastline
);
7915 ptr_end
= p
->lex.pend
;
7916 if
(ptr_end
> ptr
) {
7917 switch
(ptr_end
[-1]) {
7919 if
(--ptr_end
== ptr || ptr_end
[-1] != '\r') {
7928 if
(p
->heredoc_indent
> 0) {
7930 while
(ptr
+ i
< ptr_end
&& parser_update_heredoc_indent
(p
, ptr
[i
]))
7932 p
->heredoc_line_indent
= 0;
7936 rb_str_cat
(str
, ptr
, ptr_end
- ptr
);
7938 str
= STR_NEW
(ptr
, ptr_end
- ptr
);
7939 if
(ptr_end
< p
->lex.pend
) rb_str_cat
(str
, "\n", 1);
7941 if
(p
->heredoc_indent
> 0) {
7944 if
(nextc
(p
) == -1) {
7950 } while
(!whole_match_p
(p
, eos
, len
, indent
));
7953 /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
7956 int t
= parser_peek_variable_name
(p
);
7957 if
(p
->heredoc_line_indent
!= -1) {
7958 if
(p
->heredoc_indent
> p
->heredoc_line_indent
) {
7959 p
->heredoc_indent
= p
->heredoc_line_indent
;
7961 p
->heredoc_line_indent
= -1;
7970 if
((c
= tokadd_string
(p
, func
, '\n', 0, NULL
, &enc
, &base_enc
)) == -1) {
7971 if
(p
->eofp
) goto
error;
7975 if
(c
== '\\') p
->heredoc_line_indent
= -1;
7977 str
= STR_NEW3
(tok
(p
), toklen
(p
), enc
, func
);
7979 set_yylval_str
(str
);
7981 if
(bol
) yylval.node
->flags |
= NODE_FL_NEWLINE
;
7983 flush_string_content
(p
, enc
);
7984 return tSTRING_CONTENT
;
7986 tokadd
(p
, nextc
(p
));
7987 if
(p
->heredoc_indent
> 0) {
7991 /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
7992 if
((c
= nextc
(p
)) == -1) goto
error;
7993 } while
(!whole_match_p
(p
, eos
, len
, indent
));
7994 str
= STR_NEW3
(tok
(p
), toklen
(p
), enc
, func
);
7996 dispatch_heredoc_end
(p
);
7998 str
= ripper_new_yylval
(p
, ripper_token2eventid
(tSTRING_CONTENT
),
8001 heredoc_restore
(p
, &p
->lex.strterm
->u.heredoc
);
8003 p
->lex.strterm
= NEW_STRTERM
(func | STR_FUNC_TERM
, 0, 0);
8004 set_yylval_str
(str
);
8006 if
(bol
) yylval.node
->flags |
= NODE_FL_NEWLINE
;
8008 return tSTRING_CONTENT
;
8014 arg_ambiguous
(struct parser_params
*p
, char c
)
8018 rb_warning1
("ambiguity between regexp and two divisions: wrap regexp in parentheses or add a space after `%c' operator", WARN_I
(c
));
8021 rb_warning1
("ambiguous first argument; put parentheses or a space even after `%c' operator", WARN_I
(c
));
8024 dispatch1
(arg_ambiguous
, rb_usascii_str_new
(&c
, 1));
8031 formal_argument
(struct parser_params
*p
, ID lhs
)
8033 formal_argument
(struct parser_params
*p
, VALUE lhs
)
8036 ID id
= get_id
(lhs
);
8038 switch
(id_type
(id
)) {
8042 # define ERR(mesg) yyerror0(mesg)
8044 # define ERR(mesg) (dispatch2(param_error, WARN_S(mesg), lhs), ripper_error(p))
8047 ERR
("formal argument cannot be a constant");
8050 ERR
("formal argument cannot be an instance variable");
8053 ERR
("formal argument cannot be a global variable");
8056 ERR
("formal argument cannot be a class variable");
8059 ERR
("formal argument must be local variable");
8063 shadowing_lvar
(p
, id
);
8068 lvar_defined
(struct parser_params
*p
, ID id
)
8070 return
(dyna_in_block
(p
) && dvar_defined
(p
, id
)) || local_id
(p
, id
);
8073 /* emacsen -*- hack */
8075 parser_encode_length
(struct parser_params
*p
, const char *name
, long len
)
8079 if
(len
> 5 && name
[nlen
= len
- 5] == '-') {
8080 if
(rb_memcicmp
(name
+ nlen
+ 1, "unix", 4) == 0)
8083 if
(len
> 4 && name
[nlen
= len
- 4] == '-') {
8084 if
(rb_memcicmp
(name
+ nlen
+ 1, "dos", 3) == 0)
8086 if
(rb_memcicmp
(name
+ nlen
+ 1, "mac", 3) == 0 &&
8087 !(len
== 8 && rb_memcicmp
(name
, "utf8-mac", len
) == 0))
8088 /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
8095 parser_set_encode
(struct parser_params
*p
, const char *name
)
8097 int idx
= rb_enc_find_index
(name
);
8102 excargs
[1] = rb_sprintf
("unknown encoding name: %s", name
);
8104 excargs
[0] = rb_eArgError
;
8105 excargs
[2] = rb_make_backtrace
();
8106 rb_ary_unshift
(excargs
[2], rb_sprintf
("%"PRIsVALUE
":%d", p
->ruby_sourcefile_string
, p
->ruby_sourceline
));
8107 rb_exc_raise
(rb_make_exception
(3, excargs
));
8109 enc
= rb_enc_from_index
(idx
);
8110 if
(!rb_enc_asciicompat
(enc
)) {
8111 excargs
[1] = rb_sprintf
("%s is not ASCII compatible", rb_enc_name
(enc
));
8116 if
(p
->debug_lines
) {
8117 VALUE lines
= p
->debug_lines
;
8118 long i
, n
= RARRAY_LEN
(lines
);
8119 for
(i
= 0; i
< n
; ++i
) {
8120 rb_enc_associate_index
(RARRAY_AREF
(lines
, i
), idx
);
8127 comment_at_top
(struct parser_params
*p
)
8129 const char *ptr
= p
->lex.pbeg
, *ptr_end
= p
->lex.pcur
- 1;
8130 if
(p
->line_count
!= (p
->has_shebang ?
2 : 1)) return
0;
8131 while
(ptr
< ptr_end
) {
8132 if
(!ISSPACE
(*ptr
)) return
0;
8138 typedef
long (*rb_magic_comment_length_t
)(struct parser_params
*p
, const char *name
, long len
);
8139 typedef
void (*rb_magic_comment_setter_t
)(struct parser_params
*p
, const char *name
, const char *val
);
8141 static int parser_invalid_pragma_value
(struct parser_params
*p
, const char *name
, const char *val
);
8144 magic_comment_encoding
(struct parser_params
*p
, const char *name
, const char *val
)
8146 if
(!comment_at_top
(p
)) {
8149 parser_set_encode
(p
, val
);
8153 parser_get_bool
(struct parser_params
*p
, const char *name
, const char *val
)
8157 if
(STRCASECMP
(val
, "true") == 0) {
8162 if
(STRCASECMP
(val
, "false") == 0) {
8167 return parser_invalid_pragma_value
(p
, name
, val
);
8171 parser_invalid_pragma_value
(struct parser_params
*p
, const char *name
, const char *val
)
8173 rb_warning2
("invalid value for %s: %s", WARN_S
(name
), WARN_S
(val
));
8178 parser_set_token_info
(struct parser_params
*p
, const char *name
, const char *val
)
8180 int b
= parser_get_bool
(p
, name
, val
);
8181 if
(b
>= 0) p
->token_info_enabled
= b
;
8185 parser_set_compile_option_flag
(struct parser_params
*p
, const char *name
, const char *val
)
8189 if
(p
->token_seen
) {
8190 rb_warning1
("`%s' is ignored after any tokens", WARN_S
(name
));
8194 b
= parser_get_bool
(p
, name
, val
);
8197 if
(!p
->compile_option
)
8198 p
->compile_option
= rb_obj_hide
(rb_ident_hash_new
());
8199 rb_hash_aset
(p
->compile_option
, ID2SYM
(rb_intern
(name
)),
8204 parser_set_shareable_constant_value
(struct parser_params
*p
, const char *name
, const char *val
)
8206 for
(const char *s
= p
->lex.pbeg
, *e
= p
->lex.pcur
; s
< e
; ++s
) {
8207 if
(*s
== ' ' ||
*s
== '\t') continue
;
8208 if
(*s
== '#') break
;
8209 rb_warning1
("`%s' is ignored unless in comment-only line", WARN_S
(name
));
8215 if
(STRCASECMP
(val
, "none") == 0) {
8216 p
->ctxt.shareable_constant_value
= shareable_none
;
8221 if
(STRCASECMP
(val
, "literal") == 0) {
8222 p
->ctxt.shareable_constant_value
= shareable_literal
;
8227 if
(STRCASECMP
(val
, "experimental_copy") == 0) {
8228 p
->ctxt.shareable_constant_value
= shareable_copy
;
8231 if
(STRCASECMP
(val
, "experimental_everything") == 0) {
8232 p
->ctxt.shareable_constant_value
= shareable_everything
;
8237 parser_invalid_pragma_value
(p
, name
, val
);
8240 # if WARN_PAST_SCOPE
8242 parser_set_past_scope
(struct parser_params
*p
, const char *name
, const char *val
)
8244 int b
= parser_get_bool
(p
, name
, val
);
8245 if
(b
>= 0) p
->past_scope_enabled
= b
;
8249 struct magic_comment
{
8251 rb_magic_comment_setter_t func
;
8252 rb_magic_comment_length_t length
;
8255 static const struct magic_comment magic_comments
[] = {
8256 {"coding", magic_comment_encoding
, parser_encode_length
},
8257 {"encoding", magic_comment_encoding
, parser_encode_length
},
8258 {"frozen_string_literal", parser_set_compile_option_flag
},
8259 {"shareable_constant_value", parser_set_shareable_constant_value
},
8260 {"warn_indent", parser_set_token_info
},
8261 # if WARN_PAST_SCOPE
8262 {"warn_past_scope", parser_set_past_scope
},
8267 magic_comment_marker
(const char *str
, long len
)
8274 if
(str
[i
-1] == '*' && str
[i
-2] == '-') {
8280 if
(i
+ 1 >= len
) return
0;
8281 if
(str
[i
+1] != '-') {
8284 else if
(str
[i
-1] != '-') {
8300 parser_magic_comment
(struct parser_params
*p
, const char *str
, long len
)
8303 VALUE name
= 0, val
= 0;
8304 const char *beg
, *end
, *vbeg
, *vend
;
8305 #define str_copy(_s, _p, _n) ((_s) \
8306 ?
(void)(rb_str_resize
((_s
), (_n
)), \
8307 MEMCPY
(RSTRING_PTR
(_s
), (_p
), char, (_n
)), (_s
)) \
8308 : (void)((_s
) = STR_NEW
((_p
), (_n
))))
8310 if
(len
<= 7) return FALSE
;
8311 if
(!!(beg
= magic_comment_marker
(str
, len
))) {
8312 if
(!(end
= magic_comment_marker
(beg
, str
+ len
- beg
)))
8316 len
= end
- beg
- 3;
8319 /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
8321 const struct magic_comment
*mc
= magic_comments
;
8326 for
(; len
> 0 && *str
; str
++, --len
) {
8328 case
'\'': case
'"': case
':': case
';':
8331 if
(!ISSPACE
(*str
)) break
;
8333 for
(beg
= str
; len
> 0; str
++, --len
) {
8335 case
'\'': case
'"': case
':': case
';':
8338 if
(ISSPACE
(*str
)) break
;
8343 for
(end
= str
; len
> 0 && ISSPACE
(*str
); str
++, --len
);
8346 if
(!indicator
) return FALSE
;
8350 do str
++; while
(--len
> 0 && ISSPACE
(*str
));
8353 for
(vbeg
= ++str
; --len
> 0 && *str
!= '"'; str
++) {
8366 for
(vbeg
= str
; len
> 0 && *str
!= '"' && *str
!= ';' && !ISSPACE
(*str
); --len
, str
++);
8370 while
(len
> 0 && (*str
== ';' || ISSPACE
(*str
))) --len
, str
++;
8373 while
(len
> 0 && (ISSPACE
(*str
))) --len
, str
++;
8374 if
(len
) return FALSE
;
8378 str_copy
(name
, beg
, n
);
8379 s
= RSTRING_PTR
(name
);
8380 for
(i
= 0; i
< n
; ++i
) {
8381 if
(s
[i
] == '-') s
[i
] = '_';
8384 if
(STRNCASECMP
(mc
->name
, s
, n
) == 0 && !mc
->name
[n
]) {
8387 n
= (*mc
->length
)(p
, vbeg
, n
);
8389 str_copy
(val
, vbeg
, n
);
8390 (*mc
->func
)(p
, mc
->name
, RSTRING_PTR
(val
));
8393 } while
(++mc
< magic_comments
+ numberof
(magic_comments
));
8395 str_copy
(val
, vbeg
, vend
- vbeg
);
8396 dispatch2
(magic_comment
, name
, val
);
8404 set_file_encoding
(struct parser_params
*p
, const char *str
, const char *send
)
8407 const char *beg
= str
;
8411 if
(send
- str
<= 6) return
;
8413 case
'C': case
'c': str
+= 6; continue
;
8414 case
'O': case
'o': str
+= 5; continue
;
8415 case
'D': case
'd': str
+= 4; continue
;
8416 case
'I': case
'i': str
+= 3; continue
;
8417 case
'N': case
'n': str
+= 2; continue
;
8418 case
'G': case
'g': str
+= 1; continue
;
8425 if
(ISSPACE
(*str
)) break
;
8428 if
(STRNCASECMP
(str
-6, "coding", 6) == 0) break
;
8433 if
(++str
>= send
) return
;
8434 } while
(ISSPACE
(*str
));
8436 if
(*str
!= '=' && *str
!= ':') return
;
8441 while
((*str
== '-' ||
*str
== '_' || ISALNUM
(*str
)) && ++str
< send
);
8442 s
= rb_str_new
(beg
, parser_encode_length
(p
, beg
, str
- beg
));
8443 parser_set_encode
(p
, RSTRING_PTR
(s
));
8444 rb_str_resize
(s
, 0);
8448 parser_prepare
(struct parser_params
*p
)
8451 p
->token_info_enabled
= !compile_for_eval
&& RTEST
(ruby_verbose
);
8454 if
(peek
(p
, '!')) p
->has_shebang
= 1;
8456 case
0xef: /* UTF-8 BOM marker */
8457 if
(p
->lex.pend
- p
->lex.pcur
>= 2 &&
8458 (unsigned char)p
->lex.pcur
[0] == 0xbb &&
8459 (unsigned char)p
->lex.pcur
[1] == 0xbf) {
8460 p
->enc
= rb_utf8_encoding
();
8462 p
->lex.pbeg
= p
->lex.pcur
;
8470 p
->enc
= rb_enc_get
(p
->lex.lastline
);
8474 #define ambiguous_operator(tok, op, syn) ( \
8475 rb_warning0
("`"op
"' after local variable or literal is interpreted as binary operator"), \
8476 rb_warning0
("even though it seems like "syn
""))
8478 #define ambiguous_operator(tok, op, syn) \
8479 dispatch2
(operator_ambiguous
, TOKEN2VAL
(tok
), rb_str_new_cstr
(syn
))
8481 #define warn_balanced(tok, op, syn) ((void) \
8482 (!IS_lex_state_for
(last_state
, EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN
) && \
8483 space_seen
&& !ISSPACE
(c
) && \
8484 (ambiguous_operator
(tok
, op
, syn
), 0)), \
8485 (enum yytokentype
)(tok
))
8488 parse_rational
(struct parser_params
*p
, char *str
, int len
, int seen_point
)
8491 char *point
= &str
[seen_point
];
8492 size_t fraclen
= len
-seen_point
-1;
8493 memmove
(point
, point
+1, fraclen
+1);
8494 v
= rb_cstr_to_inum
(str
, 10, FALSE
);
8495 return rb_rational_new
(v
, rb_int_positive_pow
(10, fraclen
));
8498 static enum yytokentype
8499 no_digits
(struct parser_params
*p
)
8501 yyerror0
("numeric literal without digits");
8502 if
(peek
(p
, '_')) nextc
(p
);
8503 /* dummy 0, for tUMINUS_NUM at numeric */
8504 return set_integer_literal
(p
, INT2FIX
(0), 0);
8507 static enum yytokentype
8508 parse_numeric
(struct parser_params
*p
, int c
)
8510 int is_float
, seen_point
, seen_e
, nondigit
;
8513 is_float
= seen_point
= seen_e
= nondigit
= 0;
8514 SET_LEX_STATE
(EXPR_END
);
8516 if
(c
== '-' || c
== '+') {
8521 int start
= toklen
(p
);
8523 if
(c
== 'x' || c
== 'X') {
8526 if
(c
!= -1 && ISXDIGIT
(c
)) {
8529 if
(nondigit
) break
;
8533 if
(!ISXDIGIT
(c
)) break
;
8536 } while
((c
= nextc
(p
)) != -1);
8540 if
(toklen
(p
) == start
) {
8541 return no_digits
(p
);
8543 else if
(nondigit
) goto trailing_uc
;
8544 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8545 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 16, FALSE
), suffix
);
8547 if
(c
== 'b' || c
== 'B') {
8550 if
(c
== '0' || c
== '1') {
8553 if
(nondigit
) break
;
8557 if
(c
!= '0' && c
!= '1') break
;
8560 } while
((c
= nextc
(p
)) != -1);
8564 if
(toklen
(p
) == start
) {
8565 return no_digits
(p
);
8567 else if
(nondigit
) goto trailing_uc
;
8568 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8569 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 2, FALSE
), suffix
);
8571 if
(c
== 'd' || c
== 'D') {
8574 if
(c
!= -1 && ISDIGIT
(c
)) {
8577 if
(nondigit
) break
;
8581 if
(!ISDIGIT
(c
)) break
;
8584 } while
((c
= nextc
(p
)) != -1);
8588 if
(toklen
(p
) == start
) {
8589 return no_digits
(p
);
8591 else if
(nondigit
) goto trailing_uc
;
8592 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8593 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 10, FALSE
), suffix
);
8599 if
(c
== 'o' || c
== 'O') {
8600 /* prefixed octal */
8602 if
(c
== -1 || c
== '_' ||
!ISDIGIT
(c
)) {
8603 return no_digits
(p
);
8606 if
(c
>= '0' && c
<= '7') {
8611 if
(nondigit
) break
;
8615 if
(c
< '0' || c
> '9') break
;
8616 if
(c
> '7') goto invalid_octal
;
8619 } while
((c
= nextc
(p
)) != -1);
8620 if
(toklen
(p
) > start
) {
8623 if
(nondigit
) goto trailing_uc
;
8624 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8625 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 8, FALSE
), suffix
);
8632 if
(c
> '7' && c
<= '9') {
8634 yyerror0
("Invalid octal digit");
8636 else if
(c
== '.' || c
== 'e' || c
== 'E') {
8641 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8642 return set_integer_literal
(p
, INT2FIX
(0), suffix
);
8648 case
'0': case
'1': case
'2': case
'3': case
'4':
8649 case
'5': case
'6': case
'7': case
'8': case
'9':
8655 if
(nondigit
) goto trailing_uc
;
8656 if
(seen_point || seen_e
) {
8661 if
(c0
== -1 ||
!ISDIGIT
(c0
)) {
8667 seen_point
= toklen
(p
);
8686 if
(c
!= '-' && c
!= '+' && !ISDIGIT
(c
)) {
8691 tokadd
(p
, nondigit
);
8695 nondigit
= (c
== '-' || c
== '+') ? c
: 0;
8698 case
'_': /* `_' in number just ignored */
8699 if
(nondigit
) goto decode_num
;
8713 literal_flush
(p
, p
->lex.pcur
- 1);
8714 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
8715 compile_error
(p
, "trailing `%c' in number", nondigit
);
8716 parser_show_error_line
(p
, &loc
);
8720 enum yytokentype type
= tFLOAT
;
8723 suffix
= number_literal_suffix
(p
, seen_e ? NUM_SUFFIX_I
: NUM_SUFFIX_ALL
);
8724 if
(suffix
& NUM_SUFFIX_R
) {
8726 v
= parse_rational
(p
, tok
(p
), toklen
(p
), seen_point
);
8729 double d
= strtod
(tok
(p
), 0);
8730 if
(errno
== ERANGE
) {
8731 rb_warning1
("Float %s out of range", WARN_S
(tok
(p
)));
8736 return set_number_literal
(p
, v
, type
, suffix
);
8738 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8739 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 10, FALSE
), suffix
);
8742 static enum yytokentype
8743 parse_qmark
(struct parser_params
*p
, int space_seen
)
8750 SET_LEX_STATE
(EXPR_VALUE
);
8755 compile_error
(p
, "incomplete character syntax");
8758 if
(rb_enc_isspace
(c
, p
->enc
)) {
8760 int c2
= escaped_control_code
(c
);
8762 WARN_SPACE_CHAR
(c2
, "?");
8767 SET_LEX_STATE
(EXPR_VALUE
);
8772 if
(!parser_isascii
(p
)) {
8773 if
(tokadd_mbchar
(p
, c
) == -1) return
0;
8775 else if
((rb_enc_isalnum
(c
, p
->enc
) || c
== '_') &&
8776 p
->lex.pcur
< p
->lex.pend
&& is_identchar
(p
->lex.pcur
, p
->lex.pend
, p
->enc
)) {
8778 const char *start
= p
->lex.pcur
- 1, *ptr
= start
;
8780 int n
= parser_precise_mbclen
(p
, ptr
);
8781 if
(n
< 0) return
-1;
8783 } while
(ptr
< p
->lex.pend
&& is_identchar
(ptr
, p
->lex.pend
, p
->enc
));
8784 rb_warn2
("`?' just followed by `%.*s' is interpreted as" \
8785 " a conditional operator, put a space after `?'",
8786 WARN_I
((int)(ptr
- start
)), WARN_S_L
(start
, (ptr
- start
)));
8790 else if
(c
== '\\') {
8793 enc
= rb_utf8_encoding
();
8794 tokadd_utf8
(p
, &enc
, -1, 0, 0);
8796 else if
(!lex_eol_p
(p
) && !(c
= *p
->lex.pcur
, ISASCII
(c
))) {
8798 if
(tokadd_mbchar
(p
, c
) == -1) return
0;
8801 c
= read_escape
(p
, 0, &enc
);
8809 lit
= STR_NEW3
(tok
(p
), toklen
(p
), enc
, 0);
8810 set_yylval_str
(lit
);
8811 SET_LEX_STATE
(EXPR_END
);
8815 static enum yytokentype
8816 parse_percent
(struct parser_params
*p
, const int space_seen
, const enum lex_state_e last_state
)
8819 const char *ptok
= p
->lex.pcur
;
8827 if
(c
== -1) goto unterminated
;
8830 if
(!ISASCII
(c
)) goto unknown
;
8835 if
(rb_enc_isalnum
(term
, p
->enc
) ||
!parser_isascii
(p
)) {
8838 c
= parser_precise_mbclen
(p
, p
->lex.pcur
);
8839 if
(c
< 0) return
0;
8841 yyerror0
("unknown type of %string");
8847 compile_error
(p
, "unterminated quoted string meets end of file");
8851 if
(term
== '(') term
= ')';
8852 else if
(term
== '[') term
= ']';
8853 else if
(term
== '{') term
= '}';
8854 else if
(term
== '<') term
= '>';
8857 p
->lex.ptok
= ptok
-1;
8860 p
->lex.strterm
= NEW_STRTERM
(str_dquote
, term
, paren
);
8864 p
->lex.strterm
= NEW_STRTERM
(str_squote
, term
, paren
);
8868 p
->lex.strterm
= NEW_STRTERM
(str_dword
, term
, paren
);
8872 p
->lex.strterm
= NEW_STRTERM
(str_sword
, term
, paren
);
8876 p
->lex.strterm
= NEW_STRTERM
(str_dword
, term
, paren
);
8877 return tSYMBOLS_BEG
;
8880 p
->lex.strterm
= NEW_STRTERM
(str_sword
, term
, paren
);
8881 return tQSYMBOLS_BEG
;
8884 p
->lex.strterm
= NEW_STRTERM
(str_xquote
, term
, paren
);
8885 return tXSTRING_BEG
;
8888 p
->lex.strterm
= NEW_STRTERM
(str_regexp
, term
, paren
);
8892 p
->lex.strterm
= NEW_STRTERM
(str_ssym
, term
, paren
);
8893 SET_LEX_STATE
(EXPR_FNAME|EXPR_FITEM
);
8897 yyerror0
("unknown type of %string");
8901 if
((c
= nextc
(p
)) == '=') {
8903 SET_LEX_STATE
(EXPR_BEG
);
8906 if
(IS_SPCARG
(c
) ||
(IS_lex_state
(EXPR_FITEM
) && c
== 's')) {
8909 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
8911 return warn_balanced
('%', "%%", "string literal");
8915 tokadd_ident
(struct parser_params
*p
, int c
)
8918 if
(tokadd_mbchar
(p
, c
) == -1) return
-1;
8920 } while
(parser_is_identchar
(p
));
8926 tokenize_ident
(struct parser_params
*p
, const enum lex_state_e last_state
)
8928 ID ident
= TOK_INTERN
();
8930 set_yylval_name
(ident
);
8936 parse_numvar
(struct parser_params
*p
)
8940 unsigned long n
= ruby_scan_digits
(tok
(p
)+1, toklen
(p
)-1, 10, &len
, &overflow
);
8941 const unsigned long nth_ref_max
=
8942 ((FIXNUM_MAX
< INT_MAX
) ? FIXNUM_MAX
: INT_MAX
) >> 1;
8943 /* NTH_REF is left-shifted to be ORed with back-ref flag and
8944 * turned into a Fixnum, in compile.c */
8946 if
(overflow || n
> nth_ref_max
) {
8947 /* compile_error()? */
8948 rb_warn1
("`%s' is too big for a number variable, always nil", WARN_S
(tok
(p
)));
8949 return
0; /* $0 is $PROGRAM_NAME, not NTH_REF */
8956 static enum yytokentype
8957 parse_gvar
(struct parser_params
*p
, const enum lex_state_e last_state
)
8959 const char *ptr
= p
->lex.pcur
;
8962 SET_LEX_STATE
(EXPR_END
);
8963 p
->lex.ptok
= ptr
- 1; /* from '$' */
8967 case
'_': /* $_: last read line string */
8969 if
(parser_is_identchar
(p
)) {
8977 case
'~': /* $~: match-data */
8978 case
'*': /* $*: argv */
8979 case
'$': /* $$: pid */
8980 case
'?': /* $?: last status */
8981 case
'!': /* $!: error string */
8982 case
'@': /* $@: error position */
8983 case
'/': /* $/: input record separator */
8984 case
'\\': /* $\: output record separator */
8985 case
';': /* $;: field separator */
8986 case
',': /* $,: output field separator */
8987 case
'.': /* $.: last read line number */
8988 case
'=': /* $=: ignorecase */
8989 case
':': /* $:: load path */
8990 case
'<': /* $<: reading filename */
8991 case
'>': /* $>: default output handle */
8992 case
'\"': /* $": already loaded files */
9001 if
(parser_is_identchar
(p
)) {
9002 if
(tokadd_mbchar
(p
, c
) == -1) return
0;
9010 set_yylval_name
(TOK_INTERN
());
9013 case
'&': /* $&: last match */
9014 case
'`': /* $`: string before last match */
9015 case
'\'': /* $': string after last match */
9016 case
'+': /* $+: string matches last paren. */
9017 if
(IS_lex_state_for
(last_state
, EXPR_FNAME
)) {
9022 set_yylval_node
(NEW_BACK_REF
(c
, &_cur_loc
));
9025 case
'1': case
'2': case
'3':
9026 case
'4': case
'5': case
'6':
9027 case
'7': case
'8': case
'9':
9032 } while
(c
!= -1 && ISDIGIT
(c
));
9034 if
(IS_lex_state_for
(last_state
, EXPR_FNAME
)) goto gvar
;
9036 c
= parse_numvar
(p
);
9037 set_yylval_node
(NEW_NTH_REF
(c
, &_cur_loc
));
9041 if
(!parser_is_identchar
(p
)) {
9042 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
9043 if
(c
== -1 || ISSPACE
(c
)) {
9044 compile_error
(p
, "`$' without identifiers is not allowed as a global variable name");
9048 compile_error
(p
, "`$%c' is not allowed as a global variable name", c
);
9050 parser_show_error_line
(p
, &loc
);
9051 set_yylval_noname
();
9059 if
(tokadd_ident
(p
, c
)) return
0;
9060 SET_LEX_STATE
(EXPR_END
);
9061 tokenize_ident
(p
, last_state
);
9067 parser_numbered_param
(struct parser_params
*p
, int n
)
9069 if
(n
< 0) return false
;
9071 if
(DVARS_TERMINAL_P
(p
->lvtbl
->args
) || DVARS_TERMINAL_P
(p
->lvtbl
->args
->prev
)) {
9074 if
(p
->max_numparam
== ORDINAL_PARAM
) {
9075 compile_error
(p
, "ordinary parameter is defined");
9078 struct vtable
*args
= p
->lvtbl
->args
;
9079 if
(p
->max_numparam
< n
) {
9080 p
->max_numparam
= n
;
9082 while
(n
> args
->pos
) {
9083 vtable_add
(args
, NUMPARAM_IDX_TO_ID
(args
->pos
+1));
9089 static enum yytokentype
9090 parse_atmark
(struct parser_params
*p
, const enum lex_state_e last_state
)
9092 const char *ptr
= p
->lex.pcur
;
9093 enum yytokentype result
= tIVAR
;
9094 register
int c
= nextc
(p
);
9097 p
->lex.ptok
= ptr
- 1; /* from '@' */
9105 SET_LEX_STATE
(IS_lex_state_for
(last_state
, EXPR_FNAME
) ? EXPR_ENDFN
: EXPR_END
);
9106 if
(c
== -1 ||
!parser_is_identchar
(p
)) {
9108 RUBY_SET_YYLLOC
(loc
);
9109 if
(result
== tIVAR
) {
9110 compile_error
(p
, "`@' without identifiers is not allowed as an instance variable name");
9113 compile_error
(p
, "`@@' without identifiers is not allowed as a class variable name");
9115 parser_show_error_line
(p
, &loc
);
9116 set_yylval_noname
();
9117 SET_LEX_STATE
(EXPR_END
);
9120 else if
(ISDIGIT
(c
)) {
9122 RUBY_SET_YYLLOC
(loc
);
9123 if
(result
== tIVAR
) {
9124 compile_error
(p
, "`@%c' is not allowed as an instance variable name", c
);
9127 compile_error
(p
, "`@@%c' is not allowed as a class variable name", c
);
9129 parser_show_error_line
(p
, &loc
);
9130 set_yylval_noname
();
9131 SET_LEX_STATE
(EXPR_END
);
9135 if
(tokadd_ident
(p
, c
)) return
0;
9136 tokenize_ident
(p
, last_state
);
9140 static enum yytokentype
9141 parse_ident
(struct parser_params
*p
, int c
, int cmd_state
)
9143 enum yytokentype result
;
9144 int mb
= ENC_CODERANGE_7BIT
;
9145 const enum lex_state_e last_state
= p
->lex.state
;
9149 if
(!ISASCII
(c
)) mb
= ENC_CODERANGE_UNKNOWN
;
9150 if
(tokadd_mbchar
(p
, c
) == -1) return
0;
9152 } while
(parser_is_identchar
(p
));
9153 if
((c
== '!' || c
== '?') && !peek
(p
, '=')) {
9157 else if
(c
== '=' && IS_lex_state
(EXPR_FNAME
) &&
9158 (!peek
(p
, '~') && !peek
(p
, '>') && (!peek
(p
, '=') ||
(peek_n
(p
, '>', 1))))) {
9159 result
= tIDENTIFIER
;
9163 result
= tCONSTANT
; /* assume provisionally */
9168 if
(IS_LABEL_POSSIBLE
()) {
9169 if
(IS_LABEL_SUFFIX
(0)) {
9170 SET_LEX_STATE
(EXPR_ARG|EXPR_LABELED
);
9172 set_yylval_name
(TOK_INTERN
());
9176 if
(mb
== ENC_CODERANGE_7BIT
&& !IS_lex_state
(EXPR_DOT
)) {
9177 const struct kwtable
*kw
;
9179 /* See if it is a reserved word. */
9180 kw
= rb_reserved_word
(tok
(p
), toklen
(p
));
9182 enum lex_state_e state
= p
->lex.state
;
9183 if
(IS_lex_state_for
(state
, EXPR_FNAME
)) {
9184 SET_LEX_STATE
(EXPR_ENDFN
);
9185 set_yylval_name
(rb_intern2
(tok
(p
), toklen
(p
)));
9188 SET_LEX_STATE
(kw
->state
);
9189 if
(IS_lex_state
(EXPR_BEG
)) {
9190 p
->command_start
= TRUE
;
9192 if
(kw
->id
[0] == keyword_do
) {
9193 if
(lambda_beginning_p
()) {
9194 p
->lex.lpar_beg
= -1; /* make lambda_beginning_p() == FALSE in the body of "-> do ... end" */
9195 return keyword_do_LAMBDA
;
9197 if
(COND_P
()) return keyword_do_cond
;
9198 if
(CMDARG_P
() && !IS_lex_state_for
(state
, EXPR_CMDARG
))
9199 return keyword_do_block
;
9202 if
(IS_lex_state_for
(state
, (EXPR_BEG | EXPR_LABELED
)))
9205 if
(kw
->id
[0] != kw
->id
[1])
9206 SET_LEX_STATE
(EXPR_BEG | EXPR_LABEL
);
9212 if
(IS_lex_state
(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT
)) {
9214 SET_LEX_STATE
(EXPR_CMDARG
);
9217 SET_LEX_STATE
(EXPR_ARG
);
9220 else if
(p
->lex.state
== EXPR_FNAME
) {
9221 SET_LEX_STATE
(EXPR_ENDFN
);
9224 SET_LEX_STATE
(EXPR_END
);
9227 ident
= tokenize_ident
(p
, last_state
);
9228 if
(result
== tCONSTANT
&& is_local_id
(ident
)) result
= tIDENTIFIER
;
9229 if
(!IS_lex_state_for
(last_state
, EXPR_DOT|EXPR_FNAME
) &&
9230 (result
== tIDENTIFIER
) && /* not EXPR_FNAME, not attrasgn */
9231 lvar_defined
(p
, ident
)) {
9232 SET_LEX_STATE
(EXPR_END|EXPR_LABEL
);
9237 static enum yytokentype
9238 parser_yylex
(struct parser_params
*p
)
9244 enum lex_state_e last_state
;
9245 int fallthru
= FALSE
;
9246 int token_seen
= p
->token_seen
;
9248 if
(p
->lex.strterm
) {
9249 if
(p
->lex.strterm
->flags
& STRTERM_HEREDOC
) {
9250 return here_document
(p
, &p
->lex.strterm
->u.heredoc
);
9254 return parse_string
(p
, &p
->lex.strterm
->u.literal
);
9257 cmd_state
= p
->command_start
;
9258 p
->command_start
= FALSE
;
9259 p
->token_seen
= TRUE
;
9261 last_state
= p
->lex.state
;
9265 switch
(c
= nextc
(p
)) {
9266 case
'\0': /* NUL */
9267 case
'\004': /* ^D */
9268 case
'\032': /* ^Z */
9269 case
-1: /* end of script. */
9276 /* carried over with p->lex.nextline for nextc() */
9277 rb_warn0
("encountered \\r in middle of line, treated as a mere space");
9280 case
' ': case
'\t': case
'\f':
9281 case
'\13': /* '\v' */
9284 while
((c
= nextc
(p
))) {
9286 case
' ': case
'\t': case
'\f': case
'\r':
9287 case
'\13': /* '\v' */
9295 dispatch_scan_event
(p
, tSP
);
9299 case
'#': /* it's a comment */
9300 p
->token_seen
= token_seen
;
9301 /* no magic_comment in shebang line */
9302 if
(!parser_magic_comment
(p
, p
->lex.pcur
, p
->lex.pend
- p
->lex.pcur
)) {
9303 if
(comment_at_top
(p
)) {
9304 set_file_encoding
(p
, p
->lex.pcur
, p
->lex.pend
);
9308 dispatch_scan_event
(p
, tCOMMENT
);
9312 p
->token_seen
= token_seen
;
9313 c
= (IS_lex_state
(EXPR_BEG|EXPR_CLASS|EXPR_FNAME|EXPR_DOT
) &&
9314 !IS_lex_state
(EXPR_LABELED
));
9315 if
(c || IS_lex_state_all
(EXPR_ARG|EXPR_LABELED
)) {
9317 dispatch_scan_event
(p
, tIGNORED_NL
);
9320 if
(!c
&& p
->ctxt.in_kwarg
) {
9321 goto normal_newline
;
9326 switch
(c
= nextc
(p
)) {
9327 case
' ': case
'\t': case
'\f': case
'\r':
9328 case
'\13': /* '\v' */
9333 if
(space_seen
) dispatch_scan_event
(p
, tSP
);
9337 dispatch_delayed_token
(p
, tIGNORED_NL
);
9338 if
(peek
(p
, '.') == (c
== '&')) {
9340 dispatch_scan_event
(p
, tSP
);
9345 p
->ruby_sourceline
--;
9346 p
->lex.nextline
= p
->lex.lastline
;
9347 case
-1: /* EOF no decrement*/
9349 if
(p
->lex.prevline
&& !p
->eofp
) p
->lex.lastline
= p
->lex.prevline
;
9350 p
->lex.pbeg
= RSTRING_PTR
(p
->lex.lastline
);
9351 p
->lex.pend
= p
->lex.pcur
= p
->lex.pbeg
+ RSTRING_LEN
(p
->lex.lastline
);
9352 pushback
(p
, 1); /* always pushback */
9353 p
->lex.ptok
= p
->lex.pcur
;
9357 p
->lex.ptok
= p
->lex.pcur
;
9360 goto normal_newline
;
9364 p
->command_start
= TRUE
;
9365 SET_LEX_STATE
(EXPR_BEG
);
9369 if
((c
= nextc
(p
)) == '*') {
9370 if
((c
= nextc
(p
)) == '=') {
9371 set_yylval_id
(idPow
);
9372 SET_LEX_STATE
(EXPR_BEG
);
9377 rb_warning0
("`**' interpreted as argument prefix");
9380 else if
(IS_BEG
()) {
9384 c
= warn_balanced
((enum ruby_method_ids
)tPOW
, "**", "argument prefix");
9390 SET_LEX_STATE
(EXPR_BEG
);
9395 rb_warning0
("`*' interpreted as argument prefix");
9398 else if
(IS_BEG
()) {
9402 c
= warn_balanced
('*', "*", "argument prefix");
9405 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9410 if
(IS_AFTER_OPERATOR
()) {
9411 SET_LEX_STATE
(EXPR_ARG
);
9417 SET_LEX_STATE
(EXPR_BEG
);
9430 /* skip embedded rd document */
9431 if
(word_match_p
(p
, "begin", 5)) {
9435 dispatch_scan_event
(p
, tEMBDOC_BEG
);
9439 dispatch_scan_event
(p
, tEMBDOC
);
9444 compile_error
(p
, "embedded document meets end of file");
9447 if
(c
== '=' && word_match_p
(p
, "end", 3)) {
9453 dispatch_scan_event
(p
, tEMBDOC_END
);
9458 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9459 if
((c
= nextc
(p
)) == '=') {
9460 if
((c
= nextc
(p
)) == '=') {
9469 else if
(c
== '>') {
9478 !IS_lex_state
(EXPR_DOT | EXPR_CLASS
) &&
9480 (!IS_ARG
() || IS_lex_state
(EXPR_LABELED
) || space_seen
)) {
9481 int token
= heredoc_identifier
(p
);
9482 if
(token
) return token
< 0 ?
0 : token
;
9484 if
(IS_AFTER_OPERATOR
()) {
9485 SET_LEX_STATE
(EXPR_ARG
);
9488 if
(IS_lex_state
(EXPR_CLASS
))
9489 p
->command_start
= TRUE
;
9490 SET_LEX_STATE
(EXPR_BEG
);
9493 if
((c
= nextc
(p
)) == '>') {
9500 if
((c
= nextc
(p
)) == '=') {
9501 set_yylval_id
(idLTLT
);
9502 SET_LEX_STATE
(EXPR_BEG
);
9506 return warn_balanced
((enum ruby_method_ids
)tLSHFT
, "<<", "here document");
9512 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9513 if
((c
= nextc
(p
)) == '=') {
9517 if
((c
= nextc
(p
)) == '=') {
9518 set_yylval_id
(idGTGT
);
9519 SET_LEX_STATE
(EXPR_BEG
);
9529 label
= (IS_LABEL_POSSIBLE
() ? str_label
: 0);
9530 p
->lex.strterm
= NEW_STRTERM
(str_dquote | label
, '"', 0);
9531 p
->lex.ptok
= p
->lex.pcur
-1;
9535 if
(IS_lex_state
(EXPR_FNAME
)) {
9536 SET_LEX_STATE
(EXPR_ENDFN
);
9539 if
(IS_lex_state
(EXPR_DOT
)) {
9541 SET_LEX_STATE
(EXPR_CMDARG
);
9543 SET_LEX_STATE
(EXPR_ARG
);
9546 p
->lex.strterm
= NEW_STRTERM
(str_xquote
, '`', 0);
9547 return tXSTRING_BEG
;
9550 label
= (IS_LABEL_POSSIBLE
() ? str_label
: 0);
9551 p
->lex.strterm
= NEW_STRTERM
(str_squote | label
, '\'', 0);
9552 p
->lex.ptok
= p
->lex.pcur
-1;
9556 return parse_qmark
(p
, space_seen
);
9559 if
((c
= nextc
(p
)) == '&') {
9560 SET_LEX_STATE
(EXPR_BEG
);
9561 if
((c
= nextc
(p
)) == '=') {
9562 set_yylval_id
(idANDOP
);
9563 SET_LEX_STATE
(EXPR_BEG
);
9569 else if
(c
== '=') {
9571 SET_LEX_STATE
(EXPR_BEG
);
9574 else if
(c
== '.') {
9575 set_yylval_id
(idANDDOT
);
9576 SET_LEX_STATE
(EXPR_DOT
);
9582 (c
= peekc_n
(p
, 1)) == -1 ||
9583 !(c
== '\'' || c
== '"' ||
9584 is_identchar
((p
->lex.pcur
+1), p
->lex.pend
, p
->enc
))) {
9585 rb_warning0
("`&' interpreted as argument prefix");
9589 else if
(IS_BEG
()) {
9593 c
= warn_balanced
('&', "&", "argument prefix");
9595 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9599 if
((c
= nextc
(p
)) == '|') {
9600 SET_LEX_STATE
(EXPR_BEG
);
9601 if
((c
= nextc
(p
)) == '=') {
9602 set_yylval_id
(idOROP
);
9603 SET_LEX_STATE
(EXPR_BEG
);
9607 if
(IS_lex_state_for
(last_state
, EXPR_BEG
)) {
9616 SET_LEX_STATE
(EXPR_BEG
);
9619 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG|EXPR_LABEL
);
9625 if
(IS_AFTER_OPERATOR
()) {
9626 SET_LEX_STATE
(EXPR_ARG
);
9635 SET_LEX_STATE
(EXPR_BEG
);
9638 if
(IS_BEG
() ||
(IS_SPCARG
(c
) && arg_ambiguous
(p
, '+'))) {
9639 SET_LEX_STATE
(EXPR_BEG
);
9641 if
(c
!= -1 && ISDIGIT
(c
)) {
9642 return parse_numeric
(p
, '+');
9646 SET_LEX_STATE
(EXPR_BEG
);
9648 return warn_balanced
('+', "+", "unary operator");
9652 if
(IS_AFTER_OPERATOR
()) {
9653 SET_LEX_STATE
(EXPR_ARG
);
9662 SET_LEX_STATE
(EXPR_BEG
);
9666 SET_LEX_STATE
(EXPR_ENDFN
);
9669 if
(IS_BEG
() ||
(IS_SPCARG
(c
) && arg_ambiguous
(p
, '-'))) {
9670 SET_LEX_STATE
(EXPR_BEG
);
9672 if
(c
!= -1 && ISDIGIT
(c
)) {
9677 SET_LEX_STATE
(EXPR_BEG
);
9679 return warn_balanced
('-', "-", "unary operator");
9682 int is_beg
= IS_BEG
();
9683 SET_LEX_STATE
(EXPR_BEG
);
9684 if
((c
= nextc
(p
)) == '.') {
9685 if
((c
= nextc
(p
)) == '.') {
9686 if
(p
->ctxt.in_argdef
) {
9687 SET_LEX_STATE
(EXPR_ENDARG
);
9690 if
(p
->lex.paren_nest
== 0 && looking_at_eol_p
(p
)) {
9691 rb_warn0
("... at EOL, should be parenthesized?");
9693 else if
(p
->lex.lpar_beg
>= 0 && p
->lex.lpar_beg
+1 == p
->lex.paren_nest
) {
9694 if
(IS_lex_state_for
(last_state
, EXPR_LABEL
))
9697 return is_beg ? tBDOT3
: tDOT3
;
9700 return is_beg ? tBDOT2
: tDOT2
;
9703 if
(c
!= -1 && ISDIGIT
(c
)) {
9704 char prev
= p
->lex.pcur
-1 > p
->lex.pbeg ?
*(p
->lex.pcur
-2) : 0;
9705 parse_numeric
(p
, '.');
9706 if
(ISDIGIT
(prev
)) {
9707 yyerror0
("unexpected fraction part after numeric literal");
9710 yyerror0
("no .<digit> floating literal anymore; put 0 before dot");
9712 SET_LEX_STATE
(EXPR_END
);
9713 p
->lex.ptok
= p
->lex.pcur
;
9717 SET_LEX_STATE
(EXPR_DOT
);
9721 case
'0': case
'1': case
'2': case
'3': case
'4':
9722 case
'5': case
'6': case
'7': case
'8': case
'9':
9723 return parse_numeric
(p
, c
);
9728 SET_LEX_STATE
(EXPR_ENDFN
);
9729 p
->lex.paren_nest
--;
9735 SET_LEX_STATE
(EXPR_END
);
9736 p
->lex.paren_nest
--;
9740 /* tSTRING_DEND does COND_POP and CMDARG_POP in the yacc's rule */
9741 if
(!p
->lex.brace_nest
--) return tSTRING_DEND
;
9744 SET_LEX_STATE
(EXPR_END
);
9745 p
->lex.paren_nest
--;
9751 if
(IS_BEG
() || IS_lex_state
(EXPR_CLASS
) || IS_SPCARG
(-1)) {
9752 SET_LEX_STATE
(EXPR_BEG
);
9755 set_yylval_id
(idCOLON2
);
9756 SET_LEX_STATE
(EXPR_DOT
);
9759 if
(IS_END
() || ISSPACE
(c
) || c
== '#') {
9761 c
= warn_balanced
(':', ":", "symbol literal");
9762 SET_LEX_STATE
(EXPR_BEG
);
9767 p
->lex.strterm
= NEW_STRTERM
(str_ssym
, c
, 0);
9770 p
->lex.strterm
= NEW_STRTERM
(str_dsym
, c
, 0);
9776 SET_LEX_STATE
(EXPR_FNAME
);
9781 p
->lex.strterm
= NEW_STRTERM
(str_regexp
, '/', 0);
9784 if
((c
= nextc
(p
)) == '=') {
9786 SET_LEX_STATE
(EXPR_BEG
);
9791 arg_ambiguous
(p
, '/');
9792 p
->lex.strterm
= NEW_STRTERM
(str_regexp
, '/', 0);
9795 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9796 return warn_balanced
('/', "/", "regexp literal");
9799 if
((c
= nextc
(p
)) == '=') {
9801 SET_LEX_STATE
(EXPR_BEG
);
9804 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9809 SET_LEX_STATE
(EXPR_BEG
);
9810 p
->command_start
= TRUE
;
9814 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
9818 if
(IS_AFTER_OPERATOR
()) {
9819 if
((c
= nextc
(p
)) != '@') {
9822 SET_LEX_STATE
(EXPR_ARG
);
9825 SET_LEX_STATE
(EXPR_BEG
);
9833 else if
(!space_seen
) {
9834 /* foo( ... ) => method call, no ambiguity */
9836 else if
(IS_ARG
() || IS_lex_state_all
(EXPR_END|EXPR_LABEL
)) {
9839 else if
(IS_lex_state
(EXPR_ENDFN
) && !lambda_beginning_p
()) {
9840 rb_warning0
("parentheses after method name is interpreted as "
9841 "an argument list, not a decomposed argument");
9843 p
->lex.paren_nest
++;
9846 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
9850 p
->lex.paren_nest
++;
9851 if
(IS_AFTER_OPERATOR
()) {
9852 if
((c
= nextc
(p
)) == ']') {
9853 p
->lex.paren_nest
--;
9854 SET_LEX_STATE
(EXPR_ARG
);
9855 if
((c
= nextc
(p
)) == '=') {
9862 SET_LEX_STATE
(EXPR_ARG|EXPR_LABEL
);
9865 else if
(IS_BEG
()) {
9868 else if
(IS_ARG
() && (space_seen || IS_lex_state
(EXPR_LABELED
))) {
9871 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
9877 ++p
->lex.brace_nest
;
9878 if
(lambda_beginning_p
())
9880 else if
(IS_lex_state
(EXPR_LABELED
))
9881 c
= tLBRACE
; /* hash */
9882 else if
(IS_lex_state
(EXPR_ARG_ANY | EXPR_END | EXPR_ENDFN
))
9883 c
= '{'; /* block (primary) */
9884 else if
(IS_lex_state
(EXPR_ENDARG
))
9885 c
= tLBRACE_ARG
; /* block (expr) */
9887 c
= tLBRACE
; /* hash */
9889 p
->command_start
= TRUE
;
9890 SET_LEX_STATE
(EXPR_BEG
);
9893 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
9895 ++p
->lex.paren_nest
; /* after lambda_beginning_p() */
9904 dispatch_scan_event
(p
, tSP
);
9905 goto retry
; /* skip \\n */
9907 if
(c
== ' ') return tSP
;
9908 if
(ISSPACE
(c
)) return c
;
9913 return parse_percent
(p
, space_seen
, last_state
);
9916 return parse_gvar
(p
, last_state
);
9919 return parse_atmark
(p
, last_state
);
9922 if
(was_bol
(p
) && whole_match_p
(p
, "__END__", 7, 0)) {
9923 p
->ruby__end__seen
= 1;
9929 dispatch_scan_event
(p
, k__END__
);
9937 if
(!parser_is_identchar
(p
)) {
9938 compile_error
(p
, "Invalid char `\\x%02X' in expression", c
);
9947 return parse_ident
(p
, c
, cmd_state
);
9950 static enum yytokentype
9951 yylex(YYSTYPE *lval
, YYLTYPE *yylloc, struct parser_params
*p
)
9957 t
= parser_yylex
(p
);
9959 if
(p
->lex.strterm
&& (p
->lex.strterm
->flags
& STRTERM_HEREDOC
))
9960 RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC
(*yylloc);
9962 RUBY_SET_YYLLOC
(*yylloc);
9964 if
(has_delayed_token
(p
))
9965 dispatch_delayed_token
(p
, t
);
9967 dispatch_scan_event
(p
, t
);
9972 #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
9975 node_newnode
(struct parser_params
*p
, enum node_type type
, VALUE a0
, VALUE a1
, VALUE a2
, const rb_code_location_t
*loc
)
9977 NODE
*n
= rb_ast_newnode
(p
->ast
, type
);
9979 rb_node_init
(n
, type
, a0
, a1
, a2
);
9982 nd_set_node_id
(n
, parser_get_node_id
(p
));
9987 nd_set_loc
(NODE
*nd
, const YYLTYPE *loc
)
9990 nd_set_line
(nd
, loc
->beg_pos.lineno
);
9995 static enum node_type
9996 nodetype
(NODE
*node
) /* for debug */
9998 return
(enum node_type
)nd_type
(node
);
10002 nodeline
(NODE
*node
)
10004 return nd_line
(node
);
10008 newline_node
(NODE
*node
)
10011 node
= remove_begin
(node
);
10012 node
->flags |
= NODE_FL_NEWLINE
;
10018 fixpos
(NODE
*node
, NODE
*orig
)
10022 nd_set_line
(node
, nd_line
(orig
));
10026 parser_warning
(struct parser_params
*p
, NODE
*node
, const char *mesg
)
10028 rb_compile_warning
(p
->ruby_sourcefile
, nd_line
(node
), "%s", mesg
);
10032 parser_warn
(struct parser_params
*p
, NODE
*node
, const char *mesg
)
10034 rb_compile_warn
(p
->ruby_sourcefile
, nd_line
(node
), "%s", mesg
);
10038 block_append
(struct parser_params
*p
, NODE
*head
, NODE
*tail
)
10040 NODE
*end
, *h
= head
, *nd
;
10042 if
(tail
== 0) return head
;
10044 if
(h
== 0) return tail
;
10045 switch
(nd_type
(h
)) {
10052 parser_warning
(p
, h
, "unused literal ignored");
10055 h
= end
= NEW_BLOCK
(head
, &head
->nd_loc
);
10065 switch
(nd_type
(nd
)) {
10071 if
(RTEST
(ruby_verbose
)) {
10072 parser_warning
(p
, tail
, "statement not reached");
10080 if
(!nd_type_p
(tail
, NODE_BLOCK
)) {
10081 tail
= NEW_BLOCK
(tail
, &tail
->nd_loc
);
10082 tail
->nd_end
= tail
;
10084 end
->nd_next
= tail
;
10085 h
->nd_end
= tail
->nd_end
;
10086 nd_set_last_loc
(head
, nd_last_loc
(tail
));
10090 /* append item to the list */
10092 list_append
(struct parser_params
*p
, NODE
*list
, NODE
*item
)
10096 if
(list
== 0) return NEW_LIST
(item
, &item
->nd_loc
);
10097 if
(list
->nd_next
) {
10098 last
= list
->nd_next
->nd_end
;
10104 list
->nd_alen
+= 1;
10105 last
->nd_next
= NEW_LIST
(item
, &item
->nd_loc
);
10106 list
->nd_next
->nd_end
= last
->nd_next
;
10108 nd_set_last_loc
(list
, nd_last_loc
(item
));
10113 /* concat two lists */
10115 list_concat
(NODE
*head
, NODE
*tail
)
10119 if
(head
->nd_next
) {
10120 last
= head
->nd_next
->nd_end
;
10126 head
->nd_alen
+= tail
->nd_alen
;
10127 last
->nd_next
= tail
;
10128 if
(tail
->nd_next
) {
10129 head
->nd_next
->nd_end
= tail
->nd_next
->nd_end
;
10132 head
->nd_next
->nd_end
= tail
;
10135 nd_set_last_loc
(head
, nd_last_loc
(tail
));
10141 literal_concat0
(struct parser_params
*p
, VALUE head
, VALUE tail
)
10143 if
(NIL_P
(tail
)) return
1;
10144 if
(!rb_enc_compatible
(head
, tail
)) {
10145 compile_error
(p
, "string literal encodings differ (%s / %s)",
10146 rb_enc_name
(rb_enc_get
(head
)),
10147 rb_enc_name
(rb_enc_get
(tail
)));
10148 rb_str_resize
(head
, 0);
10149 rb_str_resize
(tail
, 0);
10152 rb_str_buf_append
(head
, tail
);
10157 string_literal_head
(enum node_type htype
, NODE
*head
)
10159 if
(htype
!= NODE_DSTR
) return Qfalse
;
10160 if
(head
->nd_next
) {
10161 head
= head
->nd_next
->nd_end
->nd_head
;
10162 if
(!head ||
!nd_type_p
(head
, NODE_STR
)) return Qfalse
;
10164 const VALUE lit
= head
->nd_lit
;
10165 ASSUME
(lit
!= Qfalse
);
10169 /* concat two string literals */
10171 literal_concat
(struct parser_params
*p
, NODE
*head
, NODE
*tail
, const YYLTYPE *loc
)
10173 enum node_type htype
;
10176 if
(!head
) return tail
;
10177 if
(!tail
) return head
;
10179 htype
= nd_type
(head
);
10180 if
(htype
== NODE_EVSTR
) {
10181 head
= new_dstr
(p
, head
, loc
);
10184 if
(p
->heredoc_indent
> 0) {
10187 nd_set_type
(head
, NODE_DSTR
);
10189 return list_append
(p
, head
, tail
);
10194 switch
(nd_type
(tail
)) {
10196 if
((lit
= string_literal_head
(htype
, head
)) != Qfalse
) {
10200 lit
= head
->nd_lit
;
10202 if
(htype
== NODE_STR
) {
10203 if
(!literal_concat0
(p
, lit
, tail
->nd_lit
)) {
10205 rb_discard_node
(p
, head
);
10206 rb_discard_node
(p
, tail
);
10209 rb_discard_node
(p
, tail
);
10212 list_append
(p
, head
, tail
);
10217 if
(htype
== NODE_STR
) {
10218 if
(!literal_concat0
(p
, head
->nd_lit
, tail
->nd_lit
))
10220 tail
->nd_lit
= head
->nd_lit
;
10221 rb_discard_node
(p
, head
);
10224 else if
(NIL_P
(tail
->nd_lit
)) {
10226 head
->nd_alen
+= tail
->nd_alen
- 1;
10227 if
(!head
->nd_next
) {
10228 head
->nd_next
= tail
->nd_next
;
10230 else if
(tail
->nd_next
) {
10231 head
->nd_next
->nd_end
->nd_next
= tail
->nd_next
;
10232 head
->nd_next
->nd_end
= tail
->nd_next
->nd_end
;
10234 rb_discard_node
(p
, tail
);
10236 else if
((lit
= string_literal_head
(htype
, head
)) != Qfalse
) {
10237 if
(!literal_concat0
(p
, lit
, tail
->nd_lit
))
10239 tail
->nd_lit
= Qnil
;
10243 list_concat
(head
, NEW_NODE
(NODE_LIST
, NEW_STR
(tail
->nd_lit
, loc
), tail
->nd_alen
, tail
->nd_next
, loc
));
10248 if
(htype
== NODE_STR
) {
10249 nd_set_type
(head
, NODE_DSTR
);
10252 list_append
(p
, head
, tail
);
10259 evstr2dstr
(struct parser_params
*p
, NODE
*node
)
10261 if
(nd_type_p
(node
, NODE_EVSTR
)) {
10262 node
= new_dstr
(p
, node
, &node
->nd_loc
);
10268 new_evstr
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
10273 switch
(nd_type
(node
)) {
10275 nd_set_type
(node
, NODE_DSTR
);
10283 return NEW_EVSTR
(head
, loc
);
10287 new_dstr
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
10289 VALUE lit
= STR_NEW0
();
10290 NODE
*dstr
= NEW_DSTR
(lit
, loc
);
10291 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, lit
);
10292 return list_append
(p
, dstr
, node
);
10296 call_bin_op
(struct parser_params
*p
, NODE
*recv
, ID id
, NODE
*arg1
,
10297 const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10302 expr
= NEW_OPCALL
(recv
, id
, NEW_LIST
(arg1
, &arg1
->nd_loc
), loc
);
10303 nd_set_line
(expr
, op_loc
->beg_pos.lineno
);
10308 call_uni_op
(struct parser_params
*p
, NODE
*recv
, ID id
, const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10312 opcall
= NEW_OPCALL
(recv
, id
, 0, loc
);
10313 nd_set_line
(opcall
, op_loc
->beg_pos.lineno
);
10318 new_qcall
(struct parser_params
* p
, ID atype
, NODE
*recv
, ID mid
, NODE
*args
, const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10320 NODE
*qcall
= NEW_QCALL
(atype
, recv
, mid
, args
, loc
);
10321 nd_set_line
(qcall
, op_loc
->beg_pos.lineno
);
10326 new_command_qcall
(struct parser_params
* p
, ID atype
, NODE
*recv
, ID mid
, NODE
*args
, NODE
*block
, const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10329 if
(block
) block_dup_check
(p
, args
, block
);
10330 ret
= new_qcall
(p
, atype
, recv
, mid
, args
, op_loc
, loc
);
10331 if
(block
) ret
= method_add_block
(p
, ret
, block
, loc
);
10336 #define nd_once_body(node) (nd_type_p((node), NODE_ONCE) ? (node)->nd_body : node)
10338 match_op
(struct parser_params
*p
, NODE
*node1
, NODE
*node2
, const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10341 int line
= op_loc
->beg_pos.lineno
;
10345 if
(node1
&& (n
= nd_once_body
(node1
)) != 0) {
10346 switch
(nd_type
(n
)) {
10349 NODE
*match
= NEW_MATCH2
(node1
, node2
, loc
);
10350 nd_set_line
(match
, line
);
10355 if
(RB_TYPE_P
(n
->nd_lit
, T_REGEXP
)) {
10356 const VALUE lit
= n
->nd_lit
;
10357 NODE
*match
= NEW_MATCH2
(node1
, node2
, loc
);
10358 match
->nd_args
= reg_named_capture_assign
(p
, lit
, loc
);
10359 nd_set_line
(match
, line
);
10365 if
(node2
&& (n
= nd_once_body
(node2
)) != 0) {
10368 switch
(nd_type
(n
)) {
10370 if
(!RB_TYPE_P
(n
->nd_lit
, T_REGEXP
)) break
;
10373 match3
= NEW_MATCH3
(node2
, node1
, loc
);
10378 n
= NEW_CALL
(node1
, tMATCH
, NEW_LIST
(node2
, &node2
->nd_loc
), loc
);
10379 nd_set_line
(n
, line
);
10383 # if WARN_PAST_SCOPE
10385 past_dvar_p
(struct parser_params
*p
, ID id
)
10387 struct vtable
*past
= p
->lvtbl
->past
;
10389 if
(vtable_included
(past
, id
)) return
1;
10397 numparam_nested_p
(struct parser_params
*p
)
10399 struct local_vars
*local
= p
->lvtbl
;
10400 NODE
*outer
= local
->numparam.outer
;
10401 NODE
*inner
= local
->numparam.inner
;
10402 if
(outer || inner
) {
10403 NODE
*used
= outer ? outer
: inner
;
10404 compile_error
(p
, "numbered parameter is already used in\n"
10405 "%s:%d: %s block here",
10406 p
->ruby_sourcefile
, nd_line
(used
),
10407 outer ?
"outer" : "inner");
10408 parser_show_error_line
(p
, &used
->nd_loc
);
10415 gettable
(struct parser_params
*p
, ID id
, const YYLTYPE *loc
)
10421 return NEW_SELF
(loc
);
10423 return NEW_NIL
(loc
);
10425 return NEW_TRUE
(loc
);
10426 case keyword_false
:
10427 return NEW_FALSE
(loc
);
10428 case keyword__FILE__
:
10430 VALUE file
= p
->ruby_sourcefile_string
;
10432 file
= rb_str_new
(0, 0);
10434 file
= rb_str_dup
(file
);
10435 node
= NEW_STR
(file
, loc
);
10436 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, file
);
10439 case keyword__LINE__
:
10440 return NEW_LIT
(INT2FIX
(p
->tokline
), loc
);
10441 case keyword__ENCODING__
:
10442 node
= NEW_LIT
(rb_enc_from_encoding
(p
->enc
), loc
);
10443 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
);
10447 switch
(id_type
(id
)) {
10449 if
(dyna_in_block
(p
) && dvar_defined_ref
(p
, id
, &vidp
)) {
10450 if
(NUMPARAM_ID_P
(id
) && numparam_nested_p
(p
)) return
0;
10451 if
(id
== p
->cur_arg
) {
10452 compile_error
(p
, "circular argument reference - %"PRIsWARN
, rb_id2str
(id
));
10455 if
(vidp
) *vidp |
= LVAR_USED
;
10456 node
= NEW_DVAR
(id
, loc
);
10459 if
(local_id_ref
(p
, id
, &vidp
)) {
10460 if
(id
== p
->cur_arg
) {
10461 compile_error
(p
, "circular argument reference - %"PRIsWARN
, rb_id2str
(id
));
10464 if
(vidp
) *vidp |
= LVAR_USED
;
10465 node
= NEW_LVAR
(id
, loc
);
10468 if
(dyna_in_block
(p
) && NUMPARAM_ID_P
(id
) &&
10469 parser_numbered_param
(p
, NUMPARAM_ID_TO_IDX
(id
))) {
10470 if
(numparam_nested_p
(p
)) return
0;
10471 node
= NEW_DVAR
(id
, loc
);
10472 struct local_vars
*local
= p
->lvtbl
;
10473 if
(!local
->numparam.current
) local
->numparam.current
= node
;
10476 # if WARN_PAST_SCOPE
10477 if
(!p
->ctxt.in_defined
&& RTEST
(ruby_verbose
) && past_dvar_p
(p
, id
)) {
10478 rb_warning1
("possible reference to past scope - %"PRIsWARN
, rb_id2str
(id
));
10481 /* method call without arguments */
10482 return NEW_VCALL
(id
, loc
);
10484 return NEW_GVAR
(id
, loc
);
10486 return NEW_IVAR
(id
, loc
);
10488 return NEW_CONST
(id
, loc
);
10490 return NEW_CVAR
(id
, loc
);
10492 compile_error
(p
, "identifier %"PRIsVALUE
" is not valid to get", rb_id2str
(id
));
10497 opt_arg_append
(NODE
*opt_list
, NODE
*opt
)
10499 NODE
*opts
= opt_list
;
10500 opts
->nd_loc.end_pos
= opt
->nd_loc.end_pos
;
10502 while
(opts
->nd_next
) {
10503 opts
= opts
->nd_next
;
10504 opts
->nd_loc.end_pos
= opt
->nd_loc.end_pos
;
10506 opts
->nd_next
= opt
;
10512 kwd_append
(NODE
*kwlist
, NODE
*kw
)
10515 NODE
*kws
= kwlist
;
10516 kws
->nd_loc.end_pos
= kw
->nd_loc.end_pos
;
10517 while
(kws
->nd_next
) {
10518 kws
= kws
->nd_next
;
10519 kws
->nd_loc.end_pos
= kw
->nd_loc.end_pos
;
10527 new_defined
(struct parser_params
*p
, NODE
*expr
, const YYLTYPE *loc
)
10529 return NEW_DEFINED
(remove_begin_all
(expr
), loc
);
10533 symbol_append
(struct parser_params
*p
, NODE
*symbols
, NODE
*symbol
)
10535 enum node_type type
= nd_type
(symbol
);
10538 nd_set_type
(symbol
, NODE_DSYM
);
10541 nd_set_type
(symbol
, NODE_LIT
);
10542 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, symbol
->nd_lit
= rb_str_intern
(symbol
->nd_lit
));
10545 compile_error
(p
, "unexpected node as symbol: %s", ruby_node_name
(type
));
10547 return list_append
(p
, symbols
, symbol
);
10551 new_regexp
(struct parser_params
*p
, NODE
*node
, int options
, const YYLTYPE *loc
)
10557 node
= NEW_LIT
(reg_compile
(p
, STR_NEW0
(), options
), loc
);
10558 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
);
10561 switch
(nd_type
(node
)) {
10564 VALUE src
= node
->nd_lit
;
10565 nd_set_type
(node
, NODE_LIT
);
10566 nd_set_loc
(node
, loc
);
10567 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
= reg_compile
(p
, src
, options
));
10572 node
= NEW_NODE
(NODE_DSTR
, lit
, 1, NEW_LIST
(node
, loc
), loc
);
10573 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, lit
);
10576 nd_set_type
(node
, NODE_DREGX
);
10577 nd_set_loc
(node
, loc
);
10578 node
->nd_cflag
= options
& RE_OPTION_MASK
;
10579 if
(!NIL_P
(node
->nd_lit
)) reg_fragment_check
(p
, node
->nd_lit
, options
);
10580 for
(list
= (prev
= node
)->nd_next
; list
; list
= list
->nd_next
) {
10581 NODE
*frag
= list
->nd_head
;
10582 enum node_type type
= nd_type
(frag
);
10583 if
(type
== NODE_STR ||
(type
== NODE_DSTR
&& !frag
->nd_next
)) {
10584 VALUE tail
= frag
->nd_lit
;
10585 if
(reg_fragment_check
(p
, tail
, options
) && prev
&& !NIL_P
(prev
->nd_lit
)) {
10586 VALUE lit
= prev
== node ? prev
->nd_lit
: prev
->nd_head
->nd_lit
;
10587 if
(!literal_concat0
(p
, lit
, tail
)) {
10588 return NEW_NIL
(loc
); /* dummy node on error */
10590 rb_str_resize
(tail
, 0);
10591 prev
->nd_next
= list
->nd_next
;
10592 rb_discard_node
(p
, list
->nd_head
);
10593 rb_discard_node
(p
, list
);
10604 if
(!node
->nd_next
) {
10605 VALUE src
= node
->nd_lit
;
10606 nd_set_type
(node
, NODE_LIT
);
10607 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
= reg_compile
(p
, src
, options
));
10609 if
(options
& RE_OPTION_ONCE
) {
10610 node
= NEW_NODE
(NODE_ONCE
, 0, node
, 0, loc
);
10618 new_kw_arg
(struct parser_params
*p
, NODE
*k
, const YYLTYPE *loc
)
10621 return NEW_KW_ARG
(0, (k
), loc
);
10625 new_xstring
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
10628 VALUE lit
= STR_NEW0
();
10629 NODE
*xstr
= NEW_XSTR
(lit
, loc
);
10630 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, lit
);
10633 switch
(nd_type
(node
)) {
10635 nd_set_type
(node
, NODE_XSTR
);
10636 nd_set_loc
(node
, loc
);
10639 nd_set_type
(node
, NODE_DXSTR
);
10640 nd_set_loc
(node
, loc
);
10643 node
= NEW_NODE
(NODE_DXSTR
, Qnil
, 1, NEW_LIST
(node
, loc
), loc
);
10650 check_literal_when
(struct parser_params
*p
, NODE
*arg
, const YYLTYPE *loc
)
10654 if
(!arg ||
!p
->case_labels
) return
;
10656 lit
= rb_node_case_when_optimizable_literal
(arg
);
10657 if
(lit
== Qundef
) return
;
10658 if
(nd_type_p
(arg
, NODE_STR
)) {
10659 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, arg
->nd_lit
= lit
);
10662 if
(NIL_P
(p
->case_labels
)) {
10663 p
->case_labels
= rb_obj_hide
(rb_hash_new
());
10666 VALUE line
= rb_hash_lookup
(p
->case_labels
, lit
);
10667 if
(!NIL_P
(line
)) {
10668 rb_warning1
("duplicated `when' clause with line %d is ignored",
10673 rb_hash_aset
(p
->case_labels
, lit
, INT2NUM
(p
->ruby_sourceline
));
10676 #else /* !RIPPER */
10678 id_is_var
(struct parser_params
*p
, ID id
)
10680 if
(is_notop_id
(id
)) {
10681 switch
(id
& ID_SCOPE_MASK
) {
10682 case ID_GLOBAL
: case ID_INSTANCE
: case ID_CONST
: case ID_CLASS
:
10685 if
(dyna_in_block
(p
)) {
10686 if
(NUMPARAM_ID_P
(id
) || dvar_defined
(p
, id
)) return
1;
10688 if
(local_id
(p
, id
)) return
1;
10689 /* method call without arguments */
10693 compile_error
(p
, "identifier %"PRIsVALUE
" is not valid to get", rb_id2str
(id
));
10698 new_regexp
(struct parser_params
*p
, VALUE re
, VALUE opt
, const YYLTYPE *loc
)
10700 VALUE src
= 0, err
;
10702 if
(ripper_is_node_yylval
(re
)) {
10703 src
= RNODE
(re
)->nd_cval
;
10704 re
= RNODE
(re
)->nd_rval
;
10706 if
(ripper_is_node_yylval
(opt
)) {
10707 options
= (int)RNODE
(opt
)->nd_tag
;
10708 opt
= RNODE
(opt
)->nd_rval
;
10710 if
(src
&& NIL_P
(parser_reg_compile
(p
, src
, options
, &err
))) {
10711 compile_error
(p
, "%"PRIsVALUE
, err
);
10713 return dispatch2
(regexp_literal
, re
, opt
);
10715 #endif /* !RIPPER */
10717 static inline
enum lex_state_e
10718 parser_set_lex_state
(struct parser_params
*p
, enum lex_state_e ls
, int line
)
10721 ls
= rb_parser_trace_lex_state
(p
, p
->lex.state
, ls
, line
);
10723 return p
->lex.state
= ls
;
10727 static const char rb_parser_lex_state_names
[][8] = {
10728 "BEG", "END", "ENDARG", "ENDFN", "ARG",
10729 "CMDARG", "MID", "FNAME", "DOT", "CLASS",
10730 "LABEL", "LABELED","FITEM",
10734 append_lex_state_name
(enum lex_state_e state
, VALUE buf
)
10737 unsigned int mask
= 1;
10738 static const char none
[] = "NONE";
10740 for
(i
= 0; i
< EXPR_MAX_STATE
; ++i
, mask
<<= 1) {
10741 if
((unsigned)state
& mask
) {
10743 rb_str_cat
(buf
, "|", 1);
10746 rb_str_cat_cstr
(buf
, rb_parser_lex_state_names
[i
]);
10750 rb_str_cat
(buf
, none
, sizeof
(none
)-1);
10756 flush_debug_buffer
(struct parser_params
*p
, VALUE out
, VALUE str
)
10758 VALUE mesg
= p
->debug_buffer
;
10760 if
(!NIL_P
(mesg
) && RSTRING_LEN
(mesg
)) {
10761 p
->debug_buffer
= Qnil
;
10762 rb_io_puts
(1, &mesg
, out
);
10764 if
(!NIL_P
(str
) && RSTRING_LEN
(str
)) {
10765 rb_io_write
(p
->debug_output
, str
);
10770 rb_parser_trace_lex_state
(struct parser_params
*p
, enum lex_state_e from
,
10771 enum lex_state_e to
, int line
)
10774 mesg
= rb_str_new_cstr
("lex_state: ");
10775 append_lex_state_name
(from
, mesg
);
10776 rb_str_cat_cstr
(mesg
, " -> ");
10777 append_lex_state_name
(to
, mesg
);
10778 rb_str_catf
(mesg
, " at line %d\n", line
);
10779 flush_debug_buffer
(p
, p
->debug_output
, mesg
);
10784 rb_parser_lex_state_name
(enum lex_state_e state
)
10786 return rb_fstring
(append_lex_state_name
(state
, rb_str_new
(0, 0)));
10790 append_bitstack_value
(stack_type stack
, VALUE mesg
)
10793 rb_str_cat_cstr
(mesg
, "0");
10796 stack_type mask
= (stack_type
)1U << (CHAR_BIT
* sizeof
(stack_type
) - 1);
10797 for
(; mask
&& !(stack
& mask
); mask
>>= 1) continue
;
10798 for
(; mask
; mask
>>= 1) rb_str_cat
(mesg
, stack
& mask ?
"1" : "0", 1);
10803 rb_parser_show_bitstack
(struct parser_params
*p
, stack_type stack
,
10804 const char *name
, int line
)
10806 VALUE mesg
= rb_sprintf
("%s: ", name
);
10807 append_bitstack_value
(stack
, mesg
);
10808 rb_str_catf
(mesg
, " at line %d\n", line
);
10809 flush_debug_buffer
(p
, p
->debug_output
, mesg
);
10813 rb_parser_fatal
(struct parser_params
*p
, const char *fmt
, ...
)
10816 VALUE mesg
= rb_str_new_cstr
("internal parser error: ");
10819 rb_str_vcatf
(mesg
, fmt
, ap
);
10821 yyerror0
(RSTRING_PTR
(mesg
));
10824 mesg
= rb_str_new
(0, 0);
10825 append_lex_state_name
(p
->lex.state
, mesg
);
10826 compile_error
(p
, "lex.state: %"PRIsVALUE
, mesg
);
10827 rb_str_resize
(mesg
, 0);
10828 append_bitstack_value
(p
->cond_stack
, mesg
);
10829 compile_error
(p
, "cond_stack: %"PRIsVALUE
, mesg
);
10830 rb_str_resize
(mesg
, 0);
10831 append_bitstack_value
(p
->cmdarg_stack
, mesg
);
10832 compile_error
(p
, "cmdarg_stack: %"PRIsVALUE
, mesg
);
10833 if
(p
->debug_output
== rb_ractor_stdout
())
10834 p
->debug_output
= rb_ractor_stderr
();
10839 rb_parser_set_pos
(YYLTYPE *yylloc, int sourceline
, int beg_pos
, int end_pos
)
10841 yylloc->beg_pos.lineno
= sourceline
;
10842 yylloc->beg_pos.column
= beg_pos
;
10843 yylloc->end_pos.lineno
= sourceline
;
10844 yylloc->end_pos.column
= end_pos
;
10849 rb_parser_set_location_from_strterm_heredoc
(struct parser_params
*p
, rb_strterm_heredoc_t
*here
, YYLTYPE *yylloc)
10851 int sourceline
= here
->sourceline
;
10852 int beg_pos
= (int)here
->offset
- here
->quote
10853 - (rb_strlen_lit
("<<-") - !(here
->func
& STR_FUNC_INDENT
));
10854 int end_pos
= (int)here
->offset
+ here
->length
+ here
->quote
;
10856 return rb_parser_set_pos
(yylloc, sourceline
, beg_pos
, end_pos
);
10860 rb_parser_set_location_of_none
(struct parser_params
*p
, YYLTYPE *yylloc)
10862 int sourceline
= p
->ruby_sourceline
;
10863 int beg_pos
= (int)(p
->lex.ptok
- p
->lex.pbeg
);
10864 int end_pos
= (int)(p
->lex.ptok
- p
->lex.pbeg
);
10865 return rb_parser_set_pos
(yylloc, sourceline
, beg_pos
, end_pos
);
10869 rb_parser_set_location
(struct parser_params
*p
, YYLTYPE *yylloc)
10871 int sourceline
= p
->ruby_sourceline
;
10872 int beg_pos
= (int)(p
->lex.ptok
- p
->lex.pbeg
);
10873 int end_pos
= (int)(p
->lex.pcur
- p
->lex.pbeg
);
10874 return rb_parser_set_pos
(yylloc, sourceline
, beg_pos
, end_pos
);
10876 #endif /* !RIPPER */
10879 assignable0
(struct parser_params
*p
, ID id
, const char **err
)
10881 if
(!id
) return
-1;
10884 *err
= "Can't change the value of self";
10887 *err
= "Can't assign to nil";
10890 *err
= "Can't assign to true";
10892 case keyword_false
:
10893 *err
= "Can't assign to false";
10895 case keyword__FILE__
:
10896 *err
= "Can't assign to __FILE__";
10898 case keyword__LINE__
:
10899 *err
= "Can't assign to __LINE__";
10901 case keyword__ENCODING__
:
10902 *err
= "Can't assign to __ENCODING__";
10905 switch
(id_type
(id
)) {
10907 if
(dyna_in_block
(p
)) {
10908 if
(p
->max_numparam
> NO_PARAM
&& NUMPARAM_ID_P
(id
)) {
10909 compile_error
(p
, "Can't assign to numbered parameter _%d",
10910 NUMPARAM_ID_TO_IDX
(id
));
10913 if
(dvar_curr
(p
, id
)) return NODE_DASGN
;
10914 if
(dvar_defined
(p
, id
)) return NODE_DASGN
;
10915 if
(local_id
(p
, id
)) return NODE_LASGN
;
10920 if
(!local_id
(p
, id
)) local_var
(p
, id
);
10924 case ID_GLOBAL
: return NODE_GASGN
;
10925 case ID_INSTANCE
: return NODE_IASGN
;
10927 if
(!p
->ctxt.in_def
) return NODE_CDECL
;
10928 *err
= "dynamic constant assignment";
10930 case ID_CLASS
: return NODE_CVASGN
;
10932 compile_error
(p
, "identifier %"PRIsVALUE
" is not valid to set", rb_id2str
(id
));
10939 assignable
(struct parser_params
*p
, ID id
, NODE
*val
, const YYLTYPE *loc
)
10941 const char *err
= 0;
10942 int node_type
= assignable0
(p
, id
, &err
);
10943 switch
(node_type
) {
10944 case NODE_DASGN
: return NEW_DASGN
(id
, val
, loc
);
10945 case NODE_LASGN
: return NEW_LASGN
(id
, val
, loc
);
10946 case NODE_GASGN
: return NEW_GASGN
(id
, val
, loc
);
10947 case NODE_IASGN
: return NEW_IASGN
(id
, val
, loc
);
10948 case NODE_CDECL
: return NEW_CDECL
(id
, val
, 0, loc
);
10949 case NODE_CVASGN
: return NEW_CVASGN
(id
, val
, loc
);
10951 if
(err
) yyerror1
(loc
, err
);
10952 return NEW_BEGIN
(0, loc
);
10956 assignable
(struct parser_params
*p
, VALUE lhs
)
10958 const char *err
= 0;
10959 assignable0
(p
, get_id
(lhs
), &err
);
10960 if
(err
) lhs
= assign_error
(p
, err
, lhs
);
10966 is_private_local_id
(ID name
)
10969 if
(name
== idUScore
) return
1;
10970 if
(!is_local_id
(name
)) return
0;
10971 s
= rb_id2str
(name
);
10973 return RSTRING_PTR
(s
)[0] == '_';
10977 shadowing_lvar_0
(struct parser_params
*p
, ID name
)
10979 if
(is_private_local_id
(name
)) return
1;
10980 if
(dyna_in_block
(p
)) {
10981 if
(dvar_curr
(p
, name
)) {
10982 yyerror0
("duplicated argument name");
10984 else if
(dvar_defined
(p
, name
) || local_id
(p
, name
)) {
10985 vtable_add
(p
->lvtbl
->vars
, name
);
10986 if
(p
->lvtbl
->used
) {
10987 vtable_add
(p
->lvtbl
->used
, (ID
)p
->ruby_sourceline | LVAR_USED
);
10993 if
(local_id
(p
, name
)) {
10994 yyerror0
("duplicated argument name");
11001 shadowing_lvar
(struct parser_params
*p
, ID name
)
11003 shadowing_lvar_0
(p
, name
);
11008 new_bv
(struct parser_params
*p
, ID name
)
11011 if
(!is_local_id
(name
)) {
11012 compile_error
(p
, "invalid local variable - %"PRIsVALUE
,
11016 if
(!shadowing_lvar_0
(p
, name
)) return
;
11022 aryset
(struct parser_params
*p
, NODE
*recv
, NODE
*idx
, const YYLTYPE *loc
)
11024 return NEW_ATTRASGN
(recv
, tASET
, idx
, loc
);
11028 block_dup_check
(struct parser_params
*p
, NODE
*node1
, NODE
*node2
)
11030 if
(node2
&& node1
&& nd_type_p
(node1
, NODE_BLOCK_PASS
)) {
11031 compile_error
(p
, "both block arg and actual block given");
11036 attrset
(struct parser_params
*p
, NODE
*recv
, ID atype
, ID id
, const YYLTYPE *loc
)
11038 if
(!CALL_Q_P
(atype
)) id
= rb_id_attrset
(id
);
11039 return NEW_ATTRASGN
(recv
, id
, 0, loc
);
11043 rb_backref_error
(struct parser_params
*p
, NODE
*node
)
11045 switch
(nd_type
(node
)) {
11047 compile_error
(p
, "Can't set variable $%ld", node
->nd_nth
);
11049 case NODE_BACK_REF
:
11050 compile_error
(p
, "Can't set variable $%c", (int)node
->nd_nth
);
11056 backref_error
(struct parser_params
*p
, NODE
*ref
, VALUE expr
)
11058 VALUE mesg
= rb_str_new_cstr
("Can't set variable ");
11059 rb_str_append
(mesg
, ref
->nd_cval
);
11060 return dispatch2
(assign_error
, mesg
, expr
);
11066 arg_append
(struct parser_params
*p
, NODE
*node1
, NODE
*node2
, const YYLTYPE *loc
)
11068 if
(!node1
) return NEW_LIST
(node2
, &node2
->nd_loc
);
11069 switch
(nd_type
(node1
)) {
11071 return list_append
(p
, node1
, node2
);
11072 case NODE_BLOCK_PASS
:
11073 node1
->nd_head
= arg_append
(p
, node1
->nd_head
, node2
, loc
);
11074 node1
->nd_loc.end_pos
= node1
->nd_head
->nd_loc.end_pos
;
11076 case NODE_ARGSPUSH
:
11077 node1
->nd_body
= list_append
(p
, NEW_LIST
(node1
->nd_body
, &node1
->nd_body
->nd_loc
), node2
);
11078 node1
->nd_loc.end_pos
= node1
->nd_body
->nd_loc.end_pos
;
11079 nd_set_type
(node1
, NODE_ARGSCAT
);
11082 if
(!nd_type_p
(node1
->nd_body
, NODE_LIST
)) break
;
11083 node1
->nd_body
= list_append
(p
, node1
->nd_body
, node2
);
11084 node1
->nd_loc.end_pos
= node1
->nd_body
->nd_loc.end_pos
;
11087 return NEW_ARGSPUSH
(node1
, node2
, loc
);
11091 arg_concat
(struct parser_params
*p
, NODE
*node1
, NODE
*node2
, const YYLTYPE *loc
)
11093 if
(!node2
) return node1
;
11094 switch
(nd_type
(node1
)) {
11095 case NODE_BLOCK_PASS
:
11096 if
(node1
->nd_head
)
11097 node1
->nd_head
= arg_concat
(p
, node1
->nd_head
, node2
, loc
);
11099 node1
->nd_head
= NEW_LIST
(node2
, loc
);
11101 case NODE_ARGSPUSH
:
11102 if
(!nd_type_p
(node2
, NODE_LIST
)) break
;
11103 node1
->nd_body
= list_concat
(NEW_LIST
(node1
->nd_body
, loc
), node2
);
11104 nd_set_type
(node1
, NODE_ARGSCAT
);
11107 if
(!nd_type_p
(node2
, NODE_LIST
) ||
11108 !nd_type_p
(node1
->nd_body
, NODE_LIST
)) break
;
11109 node1
->nd_body
= list_concat
(node1
->nd_body
, node2
);
11112 return NEW_ARGSCAT
(node1
, node2
, loc
);
11116 last_arg_append
(struct parser_params
*p
, NODE
*args
, NODE
*last_arg
, const YYLTYPE *loc
)
11119 if
((n1
= splat_array
(args
)) != 0) {
11120 return list_append
(p
, n1
, last_arg
);
11122 return arg_append
(p
, args
, last_arg
, loc
);
11126 rest_arg_append
(struct parser_params
*p
, NODE
*args
, NODE
*rest_arg
, const YYLTYPE *loc
)
11129 if
((nd_type_p
(rest_arg
, NODE_LIST
)) && (n1
= splat_array
(args
)) != 0) {
11130 return list_concat
(n1
, rest_arg
);
11132 return arg_concat
(p
, args
, rest_arg
, loc
);
11136 splat_array
(NODE
* node
)
11138 if
(nd_type_p
(node
, NODE_SPLAT
)) node
= node
->nd_head
;
11139 if
(nd_type_p
(node
, NODE_LIST
)) return node
;
11144 mark_lvar_used
(struct parser_params
*p
, NODE
*rhs
)
11148 switch
(nd_type
(rhs
)) {
11150 if
(local_id_ref
(p
, rhs
->nd_vid
, &vidp
)) {
11151 if
(vidp
) *vidp |
= LVAR_USED
;
11155 if
(dvar_defined_ref
(p
, rhs
->nd_vid
, &vidp
)) {
11156 if
(vidp
) *vidp |
= LVAR_USED
;
11161 for
(rhs
= rhs
->nd_head
; rhs
; rhs
= rhs
->nd_next
) {
11162 mark_lvar_used
(p
, rhs
->nd_head
);
11170 const_decl_path
(struct parser_params
*p
, NODE
**dest
)
11173 if
(!nd_type_p
(n
, NODE_CALL
)) {
11174 const YYLTYPE *loc
= &n
->nd_loc
;
11177 path
= rb_id2str
(n
->nd_vid
);
11181 path
= rb_ary_new
();
11182 for
(; n
&& nd_type_p
(n
, NODE_COLON2
); n
= n
->nd_head
) {
11183 rb_ary_push
(path
, rb_id2str
(n
->nd_mid
));
11185 if
(n
&& nd_type_p
(n
, NODE_CONST
)) {
11187 rb_ary_push
(path
, rb_id2str
(n
->nd_vid
));
11189 else if
(n
&& nd_type_p
(n
, NODE_COLON3
)) {
11191 rb_ary_push
(path
, rb_str_new
(0, 0));
11194 // expression::Name
11195 rb_ary_push
(path
, rb_str_new_cstr
("..."));
11197 path
= rb_ary_join
(rb_ary_reverse
(path
), rb_str_new_cstr
("::"));
11198 path
= rb_fstring
(path
);
11200 *dest
= n
= NEW_LIT
(path
, loc
);
11201 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, n
->nd_lit
);
11206 extern VALUE rb_mRubyVMFrozenCore
;
11209 make_shareable_node
(struct parser_params
*p
, NODE
*value
, bool copy
, const YYLTYPE *loc
)
11211 NODE
*fcore
= NEW_LIT
(rb_mRubyVMFrozenCore
, loc
);
11214 return NEW_CALL
(fcore
, rb_intern
("make_shareable_copy"),
11215 NEW_LIST
(value
, loc
), loc
);
11218 return NEW_CALL
(fcore
, rb_intern
("make_shareable"),
11219 NEW_LIST
(value
, loc
), loc
);
11224 ensure_shareable_node
(struct parser_params
*p
, NODE
**dest
, NODE
*value
, const YYLTYPE *loc
)
11226 NODE
*fcore
= NEW_LIT
(rb_mRubyVMFrozenCore
, loc
);
11227 NODE
*args
= NEW_LIST
(value
, loc
);
11228 args
= list_append
(p
, args
, const_decl_path
(p
, dest
));
11229 return NEW_CALL
(fcore
, rb_intern
("ensure_shareable"), args
, loc
);
11232 static int is_static_content
(NODE
*node
);
11235 shareable_literal_value
(NODE
*node
)
11237 if
(!node
) return Qnil
;
11238 enum node_type type
= nd_type
(node
);
11247 return node
->nd_lit
;
11253 #ifndef SHAREABLE_BARE_EXPRESSION
11254 #define SHAREABLE_BARE_EXPRESSION 1
11258 shareable_literal_constant
(struct parser_params
*p
, enum shareability shareable
,
11259 NODE
**dest
, NODE
*value
, const YYLTYPE *loc
, size_t level
)
11261 # define shareable_literal_constant_next(n) \
11262 shareable_literal_constant
(p
, shareable
, dest
, (n
), &(n
)->nd_loc
, level
+1)
11265 if
(!value
) return
0;
11266 enum node_type type
= nd_type
(value
);
11275 if
(shareable
== shareable_literal
) {
11276 value
= NEW_CALL
(value
, idUMinus
, 0, loc
);
11281 lit
= rb_fstring
(value
->nd_lit
);
11282 nd_set_type
(value
, NODE_LIT
);
11283 RB_OBJ_WRITE
(p
->ast
, &value
->nd_lit
, lit
);
11287 lit
= rb_ary_new
();
11288 OBJ_FREEZE_RAW
(lit
);
11289 NODE
*n
= NEW_LIT
(lit
, loc
);
11290 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, n
->nd_lit
);
11294 lit
= rb_ary_new
();
11295 for
(NODE
*n
= value
; n
; n
= n
->nd_next
) {
11296 NODE
*elt
= n
->nd_head
;
11298 elt
= shareable_literal_constant_next
(elt
);
11302 else if
(RTEST
(lit
)) {
11308 VALUE e
= shareable_literal_value
(elt
);
11310 rb_ary_push
(lit
, e
);
11314 lit
= Qnil
; /* make shareable at runtime */
11321 if
(!value
->nd_brace
) return
0;
11322 lit
= rb_hash_new
();
11323 for
(NODE
*n
= value
->nd_head
; n
; n
= n
->nd_next
->nd_next
) {
11324 NODE
*key
= n
->nd_head
;
11325 NODE
*val
= n
->nd_next
->nd_head
;
11327 key
= shareable_literal_constant_next
(key
);
11331 else if
(RTEST
(lit
)) {
11332 rb_hash_clear
(lit
);
11337 val
= shareable_literal_constant_next
(val
);
11339 n
->nd_next
->nd_head
= val
;
11341 else if
(RTEST
(lit
)) {
11342 rb_hash_clear
(lit
);
11347 VALUE k
= shareable_literal_value
(key
);
11348 VALUE v
= shareable_literal_value
(val
);
11349 if
(k
!= Qundef
&& v
!= Qundef
) {
11350 rb_hash_aset
(lit
, k
, v
);
11353 rb_hash_clear
(lit
);
11354 lit
= Qnil
; /* make shareable at runtime */
11361 if
(shareable
== shareable_literal
&&
11362 (SHAREABLE_BARE_EXPRESSION || level
> 0)) {
11363 return ensure_shareable_node
(p
, dest
, value
, loc
);
11368 /* Array or Hash */
11369 if
(!lit
) return
0;
11371 // if shareable_literal, all elements should have been ensured
11373 value
= make_shareable_node
(p
, value
, false
, loc
);
11376 value
= NEW_LIT
(rb_ractor_make_shareable
(lit
), loc
);
11377 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, value
->nd_lit
);
11381 # undef shareable_literal_constant_next
11385 shareable_constant_value
(struct parser_params
*p
, enum shareability shareable
,
11386 NODE
*lhs
, NODE
*value
, const YYLTYPE *loc
)
11388 if
(!value
) return
0;
11389 switch
(shareable
) {
11390 case shareable_none
:
11393 case shareable_literal
:
11395 NODE
*lit
= shareable_literal_constant
(p
, shareable
, &lhs
, value
, loc
, 0);
11396 if
(lit
) return lit
;
11401 case shareable_copy
:
11402 case shareable_everything
:
11404 NODE
*lit
= shareable_literal_constant
(p
, shareable
, &lhs
, value
, loc
, 0);
11405 if
(lit
) return lit
;
11406 return make_shareable_node
(p
, value
, shareable
== shareable_copy
, loc
);
11411 UNREACHABLE_RETURN
(0);
11416 node_assign
(struct parser_params
*p
, NODE
*lhs
, NODE
*rhs
, struct lex_context ctxt
, const YYLTYPE *loc
)
11418 if
(!lhs
) return
0;
11420 switch
(nd_type
(lhs
)) {
11422 rhs
= shareable_constant_value
(p
, ctxt.shareable_constant_value
, lhs
, rhs
, loc
);
11431 lhs
->nd_value
= rhs
;
11432 nd_set_loc
(lhs
, loc
);
11435 case NODE_ATTRASGN
:
11436 lhs
->nd_args
= arg_append
(p
, lhs
->nd_args
, rhs
, loc
);
11437 nd_set_loc
(lhs
, loc
);
11441 /* should not happen */
11449 value_expr_check
(struct parser_params
*p
, NODE
*node
)
11451 NODE
*void_node
= 0, *vn
;
11454 rb_warning0
("empty expression");
11457 switch
(nd_type
(node
)) {
11463 return void_node ? void_node
: node
;
11466 if
(!node
->nd_body ||
!nd_type_p
(node
->nd_body
, NODE_IN
)) {
11467 compile_error
(p
, "unexpected node");
11470 if
(node
->nd_body
->nd_body
) {
11473 /* single line pattern matching */
11474 return void_node ? void_node
: node
;
11477 while
(node
->nd_next
) {
11478 node
= node
->nd_next
;
11480 node
= node
->nd_head
;
11484 node
= node
->nd_body
;
11489 if
(!node
->nd_body
) {
11492 else if
(!node
->nd_else
) {
11495 vn
= value_expr_check
(p
, node
->nd_body
);
11496 if
(!vn
) return NULL
;
11497 if
(!void_node
) void_node
= vn
;
11498 node
= node
->nd_else
;
11503 node
= node
->nd_1st
;
11509 mark_lvar_used
(p
, node
);
11521 value_expr_gen
(struct parser_params
*p
, NODE
*node
)
11523 NODE
*void_node
= value_expr_check
(p
, node
);
11525 yyerror1
(&void_node
->nd_loc
, "void value expression");
11526 /* or "control never reach"? */
11532 void_expr
(struct parser_params
*p
, NODE
*node
)
11534 const char *useless
= 0;
11536 if
(!RTEST
(ruby_verbose
)) return
;
11538 if
(!node ||
!(node
= nd_once_body
(node
))) return
;
11539 switch
(nd_type
(node
)) {
11541 switch
(node
->nd_mid
) {
11560 useless
= rb_id2name
(node
->nd_mid
);
11571 case NODE_BACK_REF
:
11572 useless
= "a variable";
11575 useless
= "a constant";
11581 useless
= "a literal";
11606 useless
= "defined?";
11611 rb_warn1L
(nd_line
(node
), "possibly useless use of %s in void context", WARN_S
(useless
));
11616 void_stmts
(struct parser_params
*p
, NODE
*node
)
11618 NODE
*const n
= node
;
11619 if
(!RTEST
(ruby_verbose
)) return n
;
11620 if
(!node
) return n
;
11621 if
(!nd_type_p
(node
, NODE_BLOCK
)) return n
;
11623 while
(node
->nd_next
) {
11624 void_expr
(p
, node
->nd_head
);
11625 node
= node
->nd_next
;
11631 remove_begin
(NODE
*node
)
11633 NODE
**n
= &node
, *n1
= node
;
11634 while
(n1
&& nd_type_p
(n1
, NODE_BEGIN
) && n1
->nd_body
) {
11635 *n
= n1
= n1
->nd_body
;
11641 remove_begin_all
(NODE
*node
)
11643 NODE
**n
= &node
, *n1
= node
;
11644 while
(n1
&& nd_type_p
(n1
, NODE_BEGIN
)) {
11645 *n
= n1
= n1
->nd_body
;
11651 reduce_nodes
(struct parser_params
*p
, NODE
**body
)
11653 NODE
*node
= *body
;
11656 *body
= NEW_NIL
(&NULL_LOC
);
11659 #define subnodes(n1, n2) \
11660 ((!node
->n1
) ?
(node
->n2 ?
(body
= &node
->n2
, 1) : 0) : \
11661 (!node
->n2
) ?
(body
= &node
->n1
, 1) : \
11662 (reduce_nodes
(p
, &node
->n1
), body
= &node
->n2
, 1))
11665 int newline
= (int)(node
->flags
& NODE_FL_NEWLINE
);
11666 switch
(nd_type
(node
)) {
11672 *body
= node
= node
->nd_stts
;
11673 if
(newline
&& node
) node
->flags |
= NODE_FL_NEWLINE
;
11676 *body
= node
= node
->nd_body
;
11677 if
(newline
&& node
) node
->flags |
= NODE_FL_NEWLINE
;
11680 body
= &node
->nd_end
->nd_head
;
11684 if
(subnodes
(nd_body
, nd_else
)) break
;
11687 body
= &node
->nd_body
;
11690 if
(!subnodes
(nd_body
, nd_next
)) goto end
;
11693 if
(!subnodes
(nd_head
, nd_resq
)) goto end
;
11696 if
(node
->nd_else
) {
11697 body
= &node
->nd_resq
;
11700 if
(!subnodes
(nd_head
, nd_resq
)) goto end
;
11706 if
(newline
&& node
) node
->flags |
= NODE_FL_NEWLINE
;
11713 is_static_content
(NODE
*node
)
11715 if
(!node
) return
1;
11716 switch
(nd_type
(node
)) {
11718 if
(!(node
= node
->nd_head
)) break
;
11721 if
(!is_static_content
(node
->nd_head
)) return
0;
11722 } while
((node
= node
->nd_next
) != 0);
11737 assign_in_cond
(struct parser_params
*p
, NODE
*node
)
11739 switch
(nd_type
(node
)) {
11751 if
(!node
->nd_value
) return
1;
11752 if
(is_static_content
(node
->nd_value
)) {
11753 /* reports always */
11754 parser_warn
(p
, node
->nd_value
, "found `= literal' in conditional, should be ==");
11765 #define SWITCH_BY_COND_TYPE(t, w, arg) \
11767 case COND_IN_OP
: break
; \
11768 case COND_IN_COND
: rb_
##w##0(arg "literal in condition"); break; \
11769 case COND_IN_FF
: rb_
##w##0(arg "literal in flip-flop"); break; \
11772 static NODE
*cond0
(struct parser_params
*,NODE
*,enum cond_type
,const YYLTYPE*);
11775 range_op
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
11777 enum node_type type
;
11779 if
(node
== 0) return
0;
11781 type
= nd_type
(node
);
11783 if
(type
== NODE_LIT
&& FIXNUM_P
(node
->nd_lit
)) {
11784 if
(!e_option_supplied
(p
)) parser_warn
(p
, node
, "integer literal in flip-flop");
11785 ID lineno
= rb_intern
("$.");
11786 return NEW_CALL
(node
, tEQ
, NEW_LIST
(NEW_GVAR
(lineno
, loc
), loc
), loc
);
11788 return cond0
(p
, node
, COND_IN_FF
, loc
);
11792 cond0
(struct parser_params
*p
, NODE
*node
, enum cond_type type
, const YYLTYPE *loc
)
11794 if
(node
== 0) return
0;
11795 if
(!(node
= nd_once_body
(node
))) return
0;
11796 assign_in_cond
(p
, node
);
11798 switch
(nd_type
(node
)) {
11802 SWITCH_BY_COND_TYPE
(type
, warn
, "string ")
11806 if
(!e_option_supplied
(p
)) SWITCH_BY_COND_TYPE
(type
, warning
, "regex ")
11808 return NEW_MATCH2
(node
, NEW_GVAR
(idLASTLINE
, loc
), loc
);
11812 node
->nd_1st
= cond0
(p
, node
->nd_1st
, COND_IN_COND
, loc
);
11813 node
->nd_2nd
= cond0
(p
, node
->nd_2nd
, COND_IN_COND
, loc
);
11818 node
->nd_beg
= range_op
(p
, node
->nd_beg
, loc
);
11819 node
->nd_end
= range_op
(p
, node
->nd_end
, loc
);
11820 if
(nd_type_p
(node
, NODE_DOT2
)) nd_set_type
(node
,NODE_FLIP2
);
11821 else if
(nd_type_p
(node
, NODE_DOT3
)) nd_set_type
(node
, NODE_FLIP3
);
11826 SWITCH_BY_COND_TYPE
(type
, warning
, "symbol ")
11830 if
(RB_TYPE_P
(node
->nd_lit
, T_REGEXP
)) {
11831 if
(!e_option_supplied
(p
)) SWITCH_BY_COND_TYPE
(type
, warn
, "regex ")
11832 nd_set_type
(node
, NODE_MATCH
);
11834 else if
(node
->nd_lit
== Qtrue ||
11835 node
->nd_lit
== Qfalse
) {
11836 /* booleans are OK, e.g., while true */
11838 else if
(SYMBOL_P
(node
->nd_lit
)) {
11842 SWITCH_BY_COND_TYPE
(type
, warning
, "")
11851 cond
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
11853 if
(node
== 0) return
0;
11854 return cond0
(p
, node
, COND_IN_COND
, loc
);
11858 method_cond
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
11860 if
(node
== 0) return
0;
11861 return cond0
(p
, node
, COND_IN_OP
, loc
);
11865 new_nil_at
(struct parser_params
*p
, const rb_code_position_t
*pos
)
11867 YYLTYPE loc
= {*pos
, *pos
};
11868 return NEW_NIL
(&loc
);
11872 new_if
(struct parser_params
*p
, NODE
*cc
, NODE
*left
, NODE
*right
, const YYLTYPE *loc
)
11874 if
(!cc
) return right
;
11875 cc
= cond0
(p
, cc
, COND_IN_COND
, loc
);
11876 return newline_node
(NEW_IF
(cc
, left
, right
, loc
));
11880 new_unless
(struct parser_params
*p
, NODE
*cc
, NODE
*left
, NODE
*right
, const YYLTYPE *loc
)
11882 if
(!cc
) return right
;
11883 cc
= cond0
(p
, cc
, COND_IN_COND
, loc
);
11884 return newline_node
(NEW_UNLESS
(cc
, left
, right
, loc
));
11888 logop
(struct parser_params
*p
, ID id
, NODE
*left
, NODE
*right
,
11889 const YYLTYPE *op_loc
, const YYLTYPE *loc
)
11891 enum node_type type
= id
== idAND || id
== idANDOP ? NODE_AND
: NODE_OR
;
11894 if
(left
&& nd_type_p
(left
, type
)) {
11895 NODE
*node
= left
, *second
;
11896 while
((second
= node
->nd_2nd
) != 0 && nd_type_p
(second
, type
)) {
11899 node
->nd_2nd
= NEW_NODE
(type
, second
, right
, 0, loc
);
11900 nd_set_line
(node
->nd_2nd
, op_loc
->beg_pos.lineno
);
11901 left
->nd_loc.end_pos
= loc
->end_pos
;
11904 op
= NEW_NODE
(type
, left
, right
, 0, loc
);
11905 nd_set_line
(op
, op_loc
->beg_pos.lineno
);
11910 no_blockarg
(struct parser_params
*p
, NODE
*node
)
11912 if
(node
&& nd_type_p
(node
, NODE_BLOCK_PASS
)) {
11913 compile_error
(p
, "block argument should not be given");
11918 ret_args
(struct parser_params
*p
, NODE
*node
)
11921 no_blockarg
(p
, node
);
11922 if
(nd_type_p
(node
, NODE_LIST
)) {
11923 if
(node
->nd_next
== 0) {
11924 node
= node
->nd_head
;
11927 nd_set_type
(node
, NODE_VALUES
);
11935 new_yield
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
11937 if
(node
) no_blockarg
(p
, node
);
11939 return NEW_YIELD
(node
, loc
);
11943 negate_lit
(struct parser_params
*p
, VALUE lit
)
11945 if
(FIXNUM_P
(lit
)) {
11946 return LONG2FIX
(-FIX2LONG
(lit
));
11948 if
(SPECIAL_CONST_P
(lit
)) {
11950 if
(FLONUM_P
(lit
)) {
11951 return DBL2NUM
(-RFLOAT_VALUE
(lit
));
11956 switch
(BUILTIN_TYPE
(lit
)) {
11958 BIGNUM_NEGATE
(lit
);
11959 lit
= rb_big_norm
(lit
);
11962 RATIONAL_SET_NUM
(lit
, negate_lit
(p
, RRATIONAL
(lit
)->num
));
11965 RCOMPLEX_SET_REAL
(lit
, negate_lit
(p
, RCOMPLEX
(lit
)->real
));
11966 RCOMPLEX_SET_IMAG
(lit
, negate_lit
(p
, RCOMPLEX
(lit
)->imag
));
11969 lit
= DBL2NUM
(-RFLOAT_VALUE
(lit
));
11973 rb_parser_fatal
(p
, "unknown literal type (%s) passed to negate_lit",
11974 rb_builtin_class_name
(lit
));
11981 arg_blk_pass
(NODE
*node1
, NODE
*node2
)
11984 if
(!node1
) return node2
;
11985 node2
->nd_head
= node1
;
11986 nd_set_first_lineno
(node2
, nd_first_lineno
(node1
));
11987 nd_set_first_column
(node2
, nd_first_column
(node1
));
11994 args_info_empty_p
(struct rb_args_info
*args
)
11996 if
(args
->pre_args_num
) return false
;
11997 if
(args
->post_args_num
) return false
;
11998 if
(args
->rest_arg
) return false
;
11999 if
(args
->opt_args
) return false
;
12000 if
(args
->block_arg
) return false
;
12001 if
(args
->kw_args
) return false
;
12002 if
(args
->kw_rest_arg
) return false
;
12007 new_args
(struct parser_params
*p
, NODE
*pre_args
, NODE
*opt_args
, ID rest_arg
, NODE
*post_args
, NODE
*tail
, const YYLTYPE *loc
)
12009 int saved_line
= p
->ruby_sourceline
;
12010 struct rb_args_info
*args
= tail
->nd_ainfo
;
12012 if
(args
->block_arg
== idFWD_BLOCK
) {
12014 yyerror1
(&tail
->nd_loc
, "... after rest argument");
12017 rest_arg
= idFWD_REST
;
12020 args
->pre_args_num
= pre_args ? rb_long2int
(pre_args
->nd_plen
) : 0;
12021 args
->pre_init
= pre_args ? pre_args
->nd_next
: 0;
12023 args
->post_args_num
= post_args ? rb_long2int
(post_args
->nd_plen
) : 0;
12024 args
->post_init
= post_args ? post_args
->nd_next
: 0;
12025 args
->first_post_arg
= post_args ? post_args
->nd_pid
: 0;
12027 args
->rest_arg
= rest_arg
;
12029 args
->opt_args
= opt_args
;
12031 args
->ruby2_keywords
= rest_arg
== idFWD_REST
;
12033 p
->ruby_sourceline
= saved_line
;
12034 nd_set_loc
(tail
, loc
);
12040 new_args_tail
(struct parser_params
*p
, NODE
*kw_args
, ID kw_rest_arg
, ID block
, const YYLTYPE *kw_rest_loc
)
12042 int saved_line
= p
->ruby_sourceline
;
12044 VALUE tmpbuf
= rb_imemo_tmpbuf_auto_free_pointer
();
12045 struct rb_args_info
*args
= ZALLOC
(struct rb_args_info
);
12046 rb_imemo_tmpbuf_set_ptr
(tmpbuf
, args
);
12047 args
->imemo
= tmpbuf
;
12048 node
= NEW_NODE
(NODE_ARGS
, 0, 0, args
, &NULL_LOC
);
12049 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, tmpbuf
);
12050 if
(p
->error_p
) return node
;
12052 args
->block_arg
= block
;
12053 args
->kw_args
= kw_args
;
12057 * def foo(k1: 1, kr1:, k2: 2, **krest, &b)
12058 * variable order: k1, kr1, k2, &b, internal_id, krest
12060 * variable order: kr1, k1, k2, internal_id, krest, &b
12062 ID kw_bits
= internal_id
(p
), *required_kw_vars
, *kw_vars
;
12063 struct vtable
*vtargs
= p
->lvtbl
->args
;
12064 NODE
*kwn
= kw_args
;
12066 vtable_pop
(vtargs
, !!block
+ !!kw_rest_arg
);
12067 required_kw_vars
= kw_vars
= &vtargs
->tbl
[vtargs
->pos
];
12069 if
(!NODE_REQUIRED_KEYWORD_P
(kwn
->nd_body
))
12071 --required_kw_vars
;
12072 kwn
= kwn
->nd_next
;
12075 for
(kwn
= kw_args
; kwn
; kwn
= kwn
->nd_next
) {
12076 ID vid
= kwn
->nd_body
->nd_vid
;
12077 if
(NODE_REQUIRED_KEYWORD_P
(kwn
->nd_body
)) {
12078 *required_kw_vars
++ = vid
;
12085 arg_var
(p
, kw_bits
);
12086 if
(kw_rest_arg
) arg_var
(p
, kw_rest_arg
);
12087 if
(block
) arg_var
(p
, block
);
12089 args
->kw_rest_arg
= NEW_DVAR
(kw_rest_arg
, kw_rest_loc
);
12090 args
->kw_rest_arg
->nd_cflag
= kw_bits
;
12092 else if
(kw_rest_arg
== idNil
) {
12093 args
->no_kwarg
= 1;
12095 else if
(kw_rest_arg
) {
12096 args
->kw_rest_arg
= NEW_DVAR
(kw_rest_arg
, kw_rest_loc
);
12099 p
->ruby_sourceline
= saved_line
;
12104 args_with_numbered
(struct parser_params
*p
, NODE
*args
, int max_numparam
)
12106 if
(max_numparam
> NO_PARAM
) {
12108 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
12109 args
= new_args_tail
(p
, 0, 0, 0, 0);
12110 nd_set_loc
(args
, &loc
);
12112 args
->nd_ainfo
->pre_args_num
= max_numparam
;
12118 new_array_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*pre_arg
, NODE
*aryptn
, const YYLTYPE *loc
)
12120 struct rb_ary_pattern_info
*apinfo
= aryptn
->nd_apinfo
;
12122 aryptn
->nd_pconst
= constant
;
12125 NODE
*pre_args
= NEW_LIST
(pre_arg
, loc
);
12126 if
(apinfo
->pre_args
) {
12127 apinfo
->pre_args
= list_concat
(pre_args
, apinfo
->pre_args
);
12130 apinfo
->pre_args
= pre_args
;
12137 new_array_pattern_tail
(struct parser_params
*p
, NODE
*pre_args
, int has_rest
, ID rest_arg
, NODE
*post_args
, const YYLTYPE *loc
)
12139 int saved_line
= p
->ruby_sourceline
;
12141 VALUE tmpbuf
= rb_imemo_tmpbuf_auto_free_pointer
();
12142 struct rb_ary_pattern_info
*apinfo
= ZALLOC
(struct rb_ary_pattern_info
);
12143 rb_imemo_tmpbuf_set_ptr
(tmpbuf
, apinfo
);
12144 node
= NEW_NODE
(NODE_ARYPTN
, 0, tmpbuf
, apinfo
, loc
);
12145 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, tmpbuf
);
12147 apinfo
->pre_args
= pre_args
;
12151 apinfo
->rest_arg
= assignable
(p
, rest_arg
, 0, loc
);
12154 apinfo
->rest_arg
= NODE_SPECIAL_NO_NAME_REST
;
12158 apinfo
->rest_arg
= NULL
;
12161 apinfo
->post_args
= post_args
;
12163 p
->ruby_sourceline
= saved_line
;
12168 new_find_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*fndptn
, const YYLTYPE *loc
)
12170 fndptn
->nd_pconst
= constant
;
12176 new_find_pattern_tail
(struct parser_params
*p
, ID pre_rest_arg
, NODE
*args
, ID post_rest_arg
, const YYLTYPE *loc
)
12178 int saved_line
= p
->ruby_sourceline
;
12180 VALUE tmpbuf
= rb_imemo_tmpbuf_auto_free_pointer
();
12181 struct rb_fnd_pattern_info
*fpinfo
= ZALLOC
(struct rb_fnd_pattern_info
);
12182 rb_imemo_tmpbuf_set_ptr
(tmpbuf
, fpinfo
);
12183 node
= NEW_NODE
(NODE_FNDPTN
, 0, tmpbuf
, fpinfo
, loc
);
12184 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, tmpbuf
);
12186 fpinfo
->pre_rest_arg
= pre_rest_arg ? assignable
(p
, pre_rest_arg
, 0, loc
) : NODE_SPECIAL_NO_NAME_REST
;
12187 fpinfo
->args
= args
;
12188 fpinfo
->post_rest_arg
= post_rest_arg ? assignable
(p
, post_rest_arg
, 0, loc
) : NODE_SPECIAL_NO_NAME_REST
;
12190 p
->ruby_sourceline
= saved_line
;
12195 new_hash_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*hshptn
, const YYLTYPE *loc
)
12197 hshptn
->nd_pconst
= constant
;
12202 new_hash_pattern_tail
(struct parser_params
*p
, NODE
*kw_args
, ID kw_rest_arg
, const YYLTYPE *loc
)
12204 int saved_line
= p
->ruby_sourceline
;
12205 NODE
*node
, *kw_rest_arg_node
;
12207 if
(kw_rest_arg
== idNil
) {
12208 kw_rest_arg_node
= NODE_SPECIAL_NO_REST_KEYWORD
;
12210 else if
(kw_rest_arg
) {
12211 kw_rest_arg_node
= assignable
(p
, kw_rest_arg
, 0, loc
);
12214 kw_rest_arg_node
= NULL
;
12217 node
= NEW_NODE
(NODE_HSHPTN
, 0, kw_args
, kw_rest_arg_node
, loc
);
12219 p
->ruby_sourceline
= saved_line
;
12224 dsym_node
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
12229 return NEW_LIT
(ID2SYM
(idNULL
), loc
);
12232 switch
(nd_type
(node
)) {
12234 nd_set_type
(node
, NODE_DSYM
);
12235 nd_set_loc
(node
, loc
);
12238 lit
= node
->nd_lit
;
12239 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
= ID2SYM
(rb_intern_str
(lit
)));
12240 nd_set_type
(node
, NODE_LIT
);
12241 nd_set_loc
(node
, loc
);
12244 node
= NEW_NODE
(NODE_DSYM
, Qnil
, 1, NEW_LIST
(node
, loc
), loc
);
12251 append_literal_keys
(st_data_t k
, st_data_t v
, st_data_t h
)
12253 NODE
*node
= (NODE
*)v
;
12254 NODE
**result
= (NODE
**)h
;
12256 node
->nd_next
->nd_end
= node
->nd_next
;
12257 node
->nd_next
->nd_next
= 0;
12259 list_concat
(*result
, node
);
12262 return ST_CONTINUE
;
12266 hash_literal_key_p
(VALUE k
)
12268 switch
(OBJ_BUILTIN_TYPE
(k
)) {
12277 literal_cmp
(VALUE val
, VALUE lit
)
12279 if
(val
== lit
) return
0;
12280 if
(!hash_literal_key_p
(val
) ||
!hash_literal_key_p
(lit
)) return
-1;
12281 return rb_iseq_cdhash_cmp
(val
, lit
);
12285 literal_hash
(VALUE a
)
12287 if
(!hash_literal_key_p
(a
)) return
(st_index_t
)a
;
12288 return rb_iseq_cdhash_hash
(a
);
12291 static const struct st_hash_type literal_type
= {
12297 remove_duplicate_keys
(struct parser_params
*p
, NODE
*hash
)
12299 st_table
*literal_keys
= st_init_table_with_size
(&literal_type
, hash
->nd_alen
/ 2);
12301 NODE
*last_expr
= 0;
12302 rb_code_location_t loc
= hash
->nd_loc
;
12303 while
(hash
&& hash
->nd_head
&& hash
->nd_next
) {
12304 NODE
*head
= hash
->nd_head
;
12305 NODE
*value
= hash
->nd_next
;
12306 NODE
*next
= value
->nd_next
;
12307 st_data_t key
= (st_data_t
)head
;
12309 value
->nd_next
= 0;
12310 if
(nd_type_p
(head
, NODE_LIT
) &&
12311 st_delete
(literal_keys
, (key
= (st_data_t
)head
->nd_lit
, &key
), &data
)) {
12312 NODE
*dup_value
= ((NODE
*)data
)->nd_next
;
12313 rb_compile_warn
(p
->ruby_sourcefile
, nd_line
((NODE
*)data
),
12314 "key %+"PRIsVALUE
" is duplicated and overwritten on line %d",
12315 head
->nd_lit
, nd_line
(head
));
12316 if
(dup_value
== last_expr
) {
12317 value
->nd_head
= block_append
(p
, dup_value
->nd_head
, value
->nd_head
);
12320 last_expr
->nd_head
= block_append
(p
, dup_value
->nd_head
, last_expr
->nd_head
);
12323 st_insert
(literal_keys
, (st_data_t
)key
, (st_data_t
)hash
);
12324 last_expr
= nd_type_p
(head
, NODE_LIT
) ? value
: head
;
12327 st_foreach
(literal_keys
, append_literal_keys
, (st_data_t
)&result
);
12328 st_free_table
(literal_keys
);
12330 if
(!result
) result
= hash
;
12331 else list_concat
(result
, hash
);
12333 result
->nd_loc
= loc
;
12338 new_hash
(struct parser_params
*p
, NODE
*hash
, const YYLTYPE *loc
)
12340 if
(hash
) hash
= remove_duplicate_keys
(p
, hash
);
12341 return NEW_HASH
(hash
, loc
);
12346 error_duplicate_pattern_variable
(struct parser_params
*p
, ID id
, const YYLTYPE *loc
)
12348 if
(is_private_local_id
(id
)) {
12351 if
(st_is_member
(p
->pvtbl
, id
)) {
12352 yyerror1
(loc
, "duplicated variable name");
12355 st_insert
(p
->pvtbl
, (st_data_t
)id
, 0);
12360 error_duplicate_pattern_key
(struct parser_params
*p
, VALUE key
, const YYLTYPE *loc
)
12363 p
->pktbl
= st_init_numtable
();
12365 else if
(st_is_member
(p
->pktbl
, key
)) {
12366 yyerror1
(loc
, "duplicated key name");
12369 st_insert
(p
->pktbl
, (st_data_t
)key
, 0);
12374 new_unique_key_hash
(struct parser_params
*p
, NODE
*hash
, const YYLTYPE *loc
)
12376 return NEW_HASH
(hash
, loc
);
12378 #endif /* !RIPPER */
12382 new_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID op
, NODE
*rhs
, struct lex_context ctxt
, const YYLTYPE *loc
)
12387 ID vid
= lhs
->nd_vid
;
12388 YYLTYPE lhs_loc
= lhs
->nd_loc
;
12389 int shareable
= ctxt.shareable_constant_value
;
12391 switch
(nd_type
(lhs
)) {
12402 rhs
= shareable_constant_value
(p
, shareable
, lhs
, rhs
, &rhs
->nd_loc
);
12403 lhs
->nd_value
= rhs
;
12404 nd_set_loc
(lhs
, loc
);
12405 asgn
= NEW_OP_ASGN_OR
(gettable
(p
, vid
, &lhs_loc
), lhs
, loc
);
12406 if
(is_notop_id
(vid
)) {
12407 switch
(id_type
(vid
)) {
12411 asgn
->nd_aid
= vid
;
12415 else if
(op
== tANDOP
) {
12417 rhs
= shareable_constant_value
(p
, shareable
, lhs
, rhs
, &rhs
->nd_loc
);
12419 lhs
->nd_value
= rhs
;
12420 nd_set_loc
(lhs
, loc
);
12421 asgn
= NEW_OP_ASGN_AND
(gettable
(p
, vid
, &lhs_loc
), lhs
, loc
);
12425 rhs
= NEW_CALL
(gettable
(p
, vid
, &lhs_loc
), op
, NEW_LIST
(rhs
, &rhs
->nd_loc
), loc
);
12427 rhs
= shareable_constant_value
(p
, shareable
, lhs
, rhs
, &rhs
->nd_loc
);
12429 asgn
->nd_value
= rhs
;
12430 nd_set_loc
(asgn
, loc
);
12434 asgn
= NEW_BEGIN
(0, loc
);
12440 new_ary_op_assign
(struct parser_params
*p
, NODE
*ary
,
12441 NODE
*args
, ID op
, NODE
*rhs
, const YYLTYPE *args_loc
, const YYLTYPE *loc
)
12445 args
= make_list
(args
, args_loc
);
12446 if
(nd_type_p
(args
, NODE_BLOCK_PASS
)) {
12447 args
= NEW_ARGSCAT
(args
, rhs
, loc
);
12450 args
= arg_concat
(p
, args
, rhs
, loc
);
12452 asgn
= NEW_OP_ASGN1
(ary
, op
, args
, loc
);
12458 new_attr_op_assign
(struct parser_params
*p
, NODE
*lhs
,
12459 ID atype
, ID attr
, ID op
, NODE
*rhs
, const YYLTYPE *loc
)
12463 asgn
= NEW_OP_ASGN2
(lhs
, CALL_Q_P
(atype
), attr
, op
, rhs
, loc
);
12469 new_const_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID op
, NODE
*rhs
, struct lex_context ctxt
, const YYLTYPE *loc
)
12474 rhs
= shareable_constant_value
(p
, ctxt.shareable_constant_value
, lhs
, rhs
, loc
);
12475 asgn
= NEW_OP_CDECL
(lhs
, op
, rhs
, loc
);
12478 asgn
= NEW_BEGIN
(0, loc
);
12485 const_decl
(struct parser_params
*p
, NODE
*path
, const YYLTYPE *loc
)
12487 if
(p
->ctxt.in_def
) {
12488 yyerror1
(loc
, "dynamic constant assignment");
12490 return NEW_CDECL
(0, 0, (path
), loc
);
12494 const_decl
(struct parser_params
*p
, VALUE path
)
12496 if
(p
->ctxt.in_def
) {
12497 path
= assign_error
(p
, "dynamic constant assignment", path
);
12503 assign_error
(struct parser_params
*p
, const char *mesg
, VALUE a
)
12505 a
= dispatch2
(assign_error
, ERR_MESG
(), a
);
12511 var_field
(struct parser_params
*p
, VALUE a
)
12513 return ripper_new_yylval
(p
, get_id
(a
), dispatch1
(var_field
, a
), 0);
12519 new_bodystmt
(struct parser_params
*p
, NODE
*head
, NODE
*rescue
, NODE
*rescue_else
, NODE
*ensure
, const YYLTYPE *loc
)
12521 NODE
*result
= head
;
12523 NODE
*tmp
= rescue_else ? rescue_else
: rescue
;
12524 YYLTYPE rescue_loc
= code_loc_gen
(&head
->nd_loc
, &tmp
->nd_loc
);
12526 result
= NEW_RESCUE
(head
, rescue
, rescue_else
, &rescue_loc
);
12527 nd_set_line
(result
, rescue
->nd_loc.beg_pos.lineno
);
12529 else if
(rescue_else
) {
12530 result
= block_append
(p
, result
, rescue_else
);
12533 result
= NEW_ENSURE
(result
, ensure
, loc
);
12535 fixpos
(result
, head
);
12541 warn_unused_var
(struct parser_params
*p
, struct local_vars
*local
)
12545 if
(!local
->used
) return
;
12546 cnt
= local
->used
->pos
;
12547 if
(cnt
!= local
->vars
->pos
) {
12548 rb_parser_fatal
(p
, "local->used->pos != local->vars->pos");
12551 ID
*v
= local
->vars
->tbl
;
12552 ID
*u
= local
->used
->tbl
;
12553 for
(int i
= 0; i
< cnt
; ++i
) {
12554 if
(!v
[i
] ||
(u
[i
] & LVAR_USED
)) continue
;
12555 if
(is_private_local_id
(v
[i
])) continue
;
12556 rb_warn1L
((int)u
[i
], "assigned but unused variable - %"PRIsWARN
, rb_id2str
(v
[i
]));
12562 local_push
(struct parser_params
*p
, int toplevel_scope
)
12564 struct local_vars
*local
;
12565 int inherits_dvars
= toplevel_scope
&& compile_for_eval
;
12566 int warn_unused_vars
= RTEST
(ruby_verbose
);
12568 local
= ALLOC
(struct local_vars
);
12569 local
->prev
= p
->lvtbl
;
12570 local
->args
= vtable_alloc
(0);
12571 local
->vars
= vtable_alloc
(inherits_dvars ? DVARS_INHERIT
: DVARS_TOPSCOPE
);
12573 if
(toplevel_scope
&& compile_for_eval
) warn_unused_vars
= 0;
12574 if
(toplevel_scope
&& e_option_supplied
(p
)) warn_unused_vars
= 0;
12575 local
->numparam.outer
= 0;
12576 local
->numparam.inner
= 0;
12577 local
->numparam.current
= 0;
12579 local
->used
= warn_unused_vars ? vtable_alloc
(0) : 0;
12581 # if WARN_PAST_SCOPE
12590 local_pop
(struct parser_params
*p
)
12592 struct local_vars
*local
= p
->lvtbl
->prev
;
12593 if
(p
->lvtbl
->used
) {
12594 warn_unused_var
(p
, p
->lvtbl
);
12595 vtable_free
(p
->lvtbl
->used
);
12597 # if WARN_PAST_SCOPE
12598 while
(p
->lvtbl
->past
) {
12599 struct vtable
*past
= p
->lvtbl
->past
;
12600 p
->lvtbl
->past
= past
->prev
;
12604 vtable_free
(p
->lvtbl
->args
);
12605 vtable_free
(p
->lvtbl
->vars
);
12608 ruby_sized_xfree
(p
->lvtbl
, sizeof
(*p
->lvtbl
));
12613 static rb_ast_id_table_t
*
12614 local_tbl
(struct parser_params
*p
)
12616 int cnt_args
= vtable_size
(p
->lvtbl
->args
);
12617 int cnt_vars
= vtable_size
(p
->lvtbl
->vars
);
12618 int cnt
= cnt_args
+ cnt_vars
;
12620 rb_ast_id_table_t
*tbl
;
12622 if
(cnt
<= 0) return
0;
12623 tbl
= rb_ast_new_local_table
(p
->ast
, cnt
);
12624 MEMCPY
(tbl
->ids
, p
->lvtbl
->args
->tbl
, ID
, cnt_args
);
12625 /* remove IDs duplicated to warn shadowing */
12626 for
(i
= 0, j
= cnt_args
; i
< cnt_vars
; ++i
) {
12627 ID id
= p
->lvtbl
->vars
->tbl
[i
];
12628 if
(!vtable_included
(p
->lvtbl
->args
, id
)) {
12629 tbl
->ids
[j
++] = id
;
12633 tbl
= rb_ast_resize_latest_local_table
(p
->ast
, j
);
12640 node_newnode_with_locals
(struct parser_params
*p
, enum node_type type
, VALUE a1
, VALUE a2
, const rb_code_location_t
*loc
)
12642 rb_ast_id_table_t
*a0
;
12646 n
= NEW_NODE
(type
, a0
, a1
, a2
, loc
);
12653 numparam_name
(struct parser_params
*p
, ID id
)
12655 if
(!NUMPARAM_ID_P
(id
)) return
;
12656 compile_error
(p
, "_%d is reserved for numbered parameter",
12657 NUMPARAM_ID_TO_IDX
(id
));
12661 arg_var
(struct parser_params
*p
, ID id
)
12663 numparam_name
(p
, id
);
12664 vtable_add
(p
->lvtbl
->args
, id
);
12668 local_var
(struct parser_params
*p
, ID id
)
12670 numparam_name
(p
, id
);
12671 vtable_add
(p
->lvtbl
->vars
, id
);
12672 if
(p
->lvtbl
->used
) {
12673 vtable_add
(p
->lvtbl
->used
, (ID
)p
->ruby_sourceline
);
12678 local_id_ref
(struct parser_params
*p
, ID id
, ID
**vidrefp
)
12680 struct vtable
*vars
, *args
, *used
;
12682 vars
= p
->lvtbl
->vars
;
12683 args
= p
->lvtbl
->args
;
12684 used
= p
->lvtbl
->used
;
12686 while
(vars
&& !DVARS_TERMINAL_P
(vars
->prev
)) {
12689 if
(used
) used
= used
->prev
;
12692 if
(vars
&& vars
->prev
== DVARS_INHERIT
) {
12693 return rb_local_defined
(id
, p
->parent_iseq
);
12695 else if
(vtable_included
(args
, id
)) {
12699 int i
= vtable_included
(vars
, id
);
12700 if
(i
&& used
&& vidrefp
) *vidrefp
= &used
->tbl
[i
-1];
12706 local_id
(struct parser_params
*p
, ID id
)
12708 return local_id_ref
(p
, id
, NULL
);
12712 check_forwarding_args
(struct parser_params
*p
)
12714 if
(local_id
(p
, idFWD_REST
) &&
12716 local_id
(p
, idFWD_KWREST
) &&
12718 local_id
(p
, idFWD_BLOCK
)) return TRUE
;
12719 compile_error
(p
, "unexpected ...");
12724 add_forwarding_args
(struct parser_params
*p
)
12726 arg_var
(p
, idFWD_REST
);
12728 arg_var
(p
, idFWD_KWREST
);
12730 arg_var
(p
, idFWD_BLOCK
);
12735 new_args_forward_call
(struct parser_params
*p
, NODE
*leading
, const YYLTYPE *loc
, const YYLTYPE *argsloc
)
12737 NODE
*splat
= NEW_SPLAT
(NEW_LVAR
(idFWD_REST
, loc
), loc
);
12739 NODE
*kwrest
= list_append
(p
, NEW_LIST
(0, loc
), NEW_LVAR
(idFWD_KWREST
, loc
));
12741 NODE
*block
= NEW_BLOCK_PASS
(NEW_LVAR
(idFWD_BLOCK
, loc
), loc
);
12742 NODE
*args
= leading ? rest_arg_append
(p
, leading
, splat
, argsloc
) : splat
;
12744 args
= arg_append
(p
, splat
, new_hash
(p
, kwrest
, loc
), loc
);
12746 return arg_blk_pass
(args
, block
);
12751 numparam_push
(struct parser_params
*p
)
12754 struct local_vars
*local
= p
->lvtbl
;
12755 NODE
*inner
= local
->numparam.inner
;
12756 if
(!local
->numparam.outer
) {
12757 local
->numparam.outer
= local
->numparam.current
;
12759 local
->numparam.inner
= 0;
12760 local
->numparam.current
= 0;
12768 numparam_pop
(struct parser_params
*p
, NODE
*prev_inner
)
12771 struct local_vars
*local
= p
->lvtbl
;
12773 /* prefer first one */
12774 local
->numparam.inner
= prev_inner
;
12776 else if
(local
->numparam.current
) {
12777 /* current and inner are exclusive */
12778 local
->numparam.inner
= local
->numparam.current
;
12780 if
(p
->max_numparam
> NO_PARAM
) {
12781 /* current and outer are exclusive */
12782 local
->numparam.current
= local
->numparam.outer
;
12783 local
->numparam.outer
= 0;
12786 /* no numbered parameter */
12787 local
->numparam.current
= 0;
12792 static const struct vtable
*
12793 dyna_push
(struct parser_params
*p
)
12795 p
->lvtbl
->args
= vtable_alloc
(p
->lvtbl
->args
);
12796 p
->lvtbl
->vars
= vtable_alloc
(p
->lvtbl
->vars
);
12797 if
(p
->lvtbl
->used
) {
12798 p
->lvtbl
->used
= vtable_alloc
(p
->lvtbl
->used
);
12800 return p
->lvtbl
->args
;
12804 dyna_pop_vtable
(struct parser_params
*p
, struct vtable
**vtblp
)
12806 struct vtable
*tmp
= *vtblp
;
12807 *vtblp
= tmp
->prev
;
12808 # if WARN_PAST_SCOPE
12809 if
(p
->past_scope_enabled
) {
12810 tmp
->prev
= p
->lvtbl
->past
;
12811 p
->lvtbl
->past
= tmp
;
12819 dyna_pop_1
(struct parser_params
*p
)
12821 struct vtable
*tmp
;
12823 if
((tmp
= p
->lvtbl
->used
) != 0) {
12824 warn_unused_var
(p
, p
->lvtbl
);
12825 p
->lvtbl
->used
= p
->lvtbl
->used
->prev
;
12828 dyna_pop_vtable
(p
, &p
->lvtbl
->args
);
12829 dyna_pop_vtable
(p
, &p
->lvtbl
->vars
);
12833 dyna_pop
(struct parser_params
*p
, const struct vtable
*lvargs
)
12835 while
(p
->lvtbl
->args
!= lvargs
) {
12837 if
(!p
->lvtbl
->args
) {
12838 struct local_vars
*local
= p
->lvtbl
->prev
;
12839 ruby_sized_xfree
(p
->lvtbl
, sizeof
(*p
->lvtbl
));
12847 dyna_in_block
(struct parser_params
*p
)
12849 return
!DVARS_TERMINAL_P
(p
->lvtbl
->vars
) && p
->lvtbl
->vars
->prev
!= DVARS_TOPSCOPE
;
12853 dvar_defined_ref
(struct parser_params
*p
, ID id
, ID
**vidrefp
)
12855 struct vtable
*vars
, *args
, *used
;
12858 args
= p
->lvtbl
->args
;
12859 vars
= p
->lvtbl
->vars
;
12860 used
= p
->lvtbl
->used
;
12862 while
(!DVARS_TERMINAL_P
(vars
)) {
12863 if
(vtable_included
(args
, id
)) {
12866 if
((i
= vtable_included
(vars
, id
)) != 0) {
12867 if
(used
&& vidrefp
) *vidrefp
= &used
->tbl
[i
-1];
12872 if
(!vidrefp
) used
= 0;
12873 if
(used
) used
= used
->prev
;
12876 if
(vars
== DVARS_INHERIT
&& !NUMPARAM_ID_P
(id
)) {
12877 return rb_dvar_defined
(id
, p
->parent_iseq
);
12884 dvar_defined
(struct parser_params
*p
, ID id
)
12886 return dvar_defined_ref
(p
, id
, NULL
);
12890 dvar_curr
(struct parser_params
*p
, ID id
)
12892 return
(vtable_included
(p
->lvtbl
->args
, id
) ||
12893 vtable_included
(p
->lvtbl
->vars
, id
));
12897 reg_fragment_enc_error
(struct parser_params
* p
, VALUE str
, int c
)
12900 "regexp encoding option '%c' differs from source encoding '%s'",
12901 c
, rb_enc_name
(rb_enc_get
(str
)));
12906 rb_reg_fragment_setenc
(struct parser_params
* p
, VALUE str
, int options
)
12908 int c
= RE_OPTION_ENCODING_IDX
(options
);
12912 rb_char_to_option_kcode
(c
, &opt
, &idx
);
12913 if
(idx
!= ENCODING_GET
(str
) &&
12914 rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
12917 ENCODING_SET
(str
, idx
);
12919 else if
(RE_OPTION_ENCODING_NONE
(options
)) {
12920 if
(!ENCODING_IS_ASCII8BIT
(str
) &&
12921 rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
12925 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
12927 else if
(p
->enc
== rb_usascii_encoding
()) {
12928 if
(rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
12929 /* raise in re.c */
12930 rb_enc_associate
(str
, rb_usascii_encoding
());
12933 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
12943 reg_fragment_setenc
(struct parser_params
* p
, VALUE str
, int options
)
12945 int c
= rb_reg_fragment_setenc
(p
, str
, options
);
12946 if
(c
) reg_fragment_enc_error
(p
, str
, c
);
12950 reg_fragment_check
(struct parser_params
* p
, VALUE str
, int options
)
12953 reg_fragment_setenc
(p
, str
, options
);
12954 err
= rb_reg_check_preprocess
(str
);
12956 err
= rb_obj_as_string
(err
);
12957 compile_error
(p
, "%"PRIsVALUE
, err
);
12964 struct parser_params
* parser
;
12967 const YYLTYPE *loc
;
12968 } reg_named_capture_assign_t
;
12971 reg_named_capture_assign_iter
(const OnigUChar
*name
, const OnigUChar
*name_end
,
12972 int back_num
, int *back_refs
, OnigRegex regex
, void *arg0
)
12974 reg_named_capture_assign_t
*arg
= (reg_named_capture_assign_t
*)arg0
;
12975 struct parser_params
* p
= arg
->parser
;
12976 rb_encoding
*enc
= arg
->enc
;
12977 long len
= name_end
- name
;
12978 const char *s
= (const char *)name
;
12982 if
(!len
) return ST_CONTINUE
;
12983 if
(rb_enc_symname_type
(s
, len
, enc
, (1U<<ID_LOCAL
)) != ID_LOCAL
)
12984 return ST_CONTINUE
;
12986 var
= intern_cstr
(s
, len
, enc
);
12987 if
(len
< MAX_WORD_LENGTH
&& rb_reserved_word
(s
, (int)len
)) {
12988 if
(!lvar_defined
(p
, var
)) return ST_CONTINUE
;
12990 node
= node_assign
(p
, assignable
(p
, var
, 0, arg
->loc
), NEW_LIT
(ID2SYM
(var
), arg
->loc
), NO_LEX_CTXT
, arg
->loc
);
12991 succ
= arg
->succ_block
;
12992 if
(!succ
) succ
= NEW_BEGIN
(0, arg
->loc
);
12993 succ
= block_append
(p
, succ
, node
);
12994 arg
->succ_block
= succ
;
12995 return ST_CONTINUE
;
12999 reg_named_capture_assign
(struct parser_params
* p
, VALUE regexp
, const YYLTYPE *loc
)
13001 reg_named_capture_assign_t arg
;
13004 arg.enc
= rb_enc_get
(regexp
);
13005 arg.succ_block
= 0;
13007 onig_foreach_name
(RREGEXP_PTR
(regexp
), reg_named_capture_assign_iter
, &arg
);
13009 if
(!arg.succ_block
) return
0;
13010 return arg.succ_block
->nd_next
;
13014 parser_reg_compile
(struct parser_params
* p
, VALUE str
, int options
)
13016 reg_fragment_setenc
(p
, str
, options
);
13017 return rb_parser_reg_compile
(p
, str
, options
);
13021 rb_parser_reg_compile
(struct parser_params
* p
, VALUE str
, int options
)
13023 return rb_reg_compile
(str
, options
& RE_OPTION_MASK
, p
->ruby_sourcefile
, p
->ruby_sourceline
);
13027 reg_compile
(struct parser_params
* p
, VALUE str
, int options
)
13032 err
= rb_errinfo
();
13033 re
= parser_reg_compile
(p
, str
, options
);
13035 VALUE m
= rb_attr_get
(rb_errinfo
(), idMesg
);
13036 rb_set_errinfo
(err
);
13037 compile_error
(p
, "%"PRIsVALUE
, m
);
13044 parser_reg_compile
(struct parser_params
* p
, VALUE str
, int options
, VALUE
*errmsg
)
13046 VALUE err
= rb_errinfo
();
13048 str
= ripper_is_node_yylval
(str
) ? RNODE
(str
)->nd_cval
: str
;
13049 int c
= rb_reg_fragment_setenc
(p
, str
, options
);
13050 if
(c
) reg_fragment_enc_error
(p
, str
, c
);
13051 re
= rb_parser_reg_compile
(p
, str
, options
);
13053 *errmsg
= rb_attr_get
(rb_errinfo
(), idMesg
);
13054 rb_set_errinfo
(err
);
13062 rb_parser_set_options
(VALUE vparser
, int print
, int loop
, int chomp
, int split
)
13064 struct parser_params
*p
;
13065 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13066 p
->do_print
= print
;
13068 p
->do_chomp
= chomp
;
13069 p
->do_split
= split
;
13073 parser_append_options
(struct parser_params
*p
, NODE
*node
)
13075 static const YYLTYPE default_location
= {{1, 0}, {1, 0}};
13076 const YYLTYPE *const LOC
= &default_location
;
13079 NODE
*print
= NEW_FCALL
(rb_intern
("print"),
13080 NEW_LIST
(NEW_GVAR
(idLASTLINE
, LOC
), LOC
),
13082 node
= block_append
(p
, node
, print
);
13087 ID ifs
= rb_intern
("$;");
13088 ID fields
= rb_intern
("$F");
13089 NODE
*args
= NEW_LIST
(NEW_GVAR
(ifs
, LOC
), LOC
);
13090 NODE
*split
= NEW_GASGN
(fields
,
13091 NEW_CALL
(NEW_GVAR
(idLASTLINE
, LOC
),
13092 rb_intern
("split"), args
, LOC
),
13094 node
= block_append
(p
, split
, node
);
13097 NODE
*chomp
= NEW_CALL
(NEW_GVAR
(idLASTLINE
, LOC
),
13098 rb_intern
("chomp!"), 0, LOC
);
13099 node
= block_append
(p
, chomp
, node
);
13102 node
= NEW_WHILE
(NEW_VCALL
(idGets
, LOC
), node
, 1, LOC
);
13109 rb_init_parse
(void)
13111 /* just to suppress unused-function warnings */
13117 internal_id
(struct parser_params
*p
)
13119 return rb_make_temporary_id
(vtable_size
(p
->lvtbl
->args
) + vtable_size
(p
->lvtbl
->vars
));
13121 #endif /* !RIPPER */
13124 parser_initialize
(struct parser_params
*p
)
13126 /* note: we rely on TypedData_Make_Struct to set most fields to 0 */
13127 p
->command_start
= TRUE
;
13128 p
->ruby_sourcefile_string
= Qnil
;
13129 p
->lex.lpar_beg
= -1; /* make lambda_beginning_p() == FALSE at first */
13132 p
->delayed.token
= Qnil
;
13134 p
->parsing_thread
= Qnil
;
13136 p
->error_buffer
= Qfalse
;
13138 p
->debug_buffer
= Qnil
;
13139 p
->debug_output
= rb_ractor_stdout
();
13140 p
->enc
= rb_utf8_encoding
();
13144 #define parser_mark ripper_parser_mark
13145 #define parser_free ripper_parser_free
13149 parser_mark
(void *ptr
)
13151 struct parser_params
*p
= (struct parser_params
*)ptr
;
13153 rb_gc_mark
(p
->lex.input
);
13154 rb_gc_mark
(p
->lex.prevline
);
13155 rb_gc_mark
(p
->lex.lastline
);
13156 rb_gc_mark
(p
->lex.nextline
);
13157 rb_gc_mark
(p
->ruby_sourcefile_string
);
13158 rb_gc_mark
((VALUE
)p
->lex.strterm
);
13159 rb_gc_mark
((VALUE
)p
->ast
);
13160 rb_gc_mark
(p
->case_labels
);
13162 rb_gc_mark
(p
->debug_lines
);
13163 rb_gc_mark
(p
->compile_option
);
13164 rb_gc_mark
(p
->error_buffer
);
13166 rb_gc_mark
(p
->delayed.token
);
13167 rb_gc_mark
(p
->value
);
13168 rb_gc_mark
(p
->result
);
13169 rb_gc_mark
(p
->parsing_thread
);
13171 rb_gc_mark
(p
->debug_buffer
);
13172 rb_gc_mark
(p
->debug_output
);
13174 rb_gc_mark
((VALUE
)p
->heap
);
13179 parser_free
(void *ptr
)
13181 struct parser_params
*p
= (struct parser_params
*)ptr
;
13182 struct local_vars
*local
, *prev
;
13185 ruby_sized_xfree
(p
->tokenbuf
, p
->toksiz
);
13187 for
(local
= p
->lvtbl
; local
; local
= prev
) {
13188 if
(local
->vars
) xfree
(local
->vars
);
13189 prev
= local
->prev
;
13193 token_info
*ptinfo
;
13194 while
((ptinfo
= p
->token_info
) != 0) {
13195 p
->token_info
= ptinfo
->next
;
13203 parser_memsize
(const void *ptr
)
13205 struct parser_params
*p
= (struct parser_params
*)ptr
;
13206 struct local_vars
*local
;
13207 size_t size
= sizeof
(*p
);
13210 for
(local
= p
->lvtbl
; local
; local
= local
->prev
) {
13211 size
+= sizeof
(*local
);
13212 if
(local
->vars
) size
+= local
->vars
->capa
* sizeof
(ID
);
13217 static const rb_data_type_t parser_data_type
= {
13228 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
13232 #undef rb_reserved_word
13234 const struct kwtable
*
13235 rb_reserved_word
(const char *str
, unsigned int len
)
13237 return reserved_word
(str
, len
);
13241 rb_parser_new
(void)
13243 struct parser_params
*p
;
13244 VALUE parser
= TypedData_Make_Struct
(0, struct parser_params
,
13245 &parser_data_type
, p
);
13246 parser_initialize
(p
);
13251 rb_parser_set_context
(VALUE vparser
, const struct rb_iseq_struct
*base
, int main
)
13253 struct parser_params
*p
;
13255 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13256 p
->error_buffer
= main ? Qfalse
: Qnil
;
13257 p
->parent_iseq
= base
;
13262 rb_parser_keep_script_lines
(VALUE vparser
)
13264 struct parser_params
*p
;
13266 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13267 p
->keep_script_lines
= 1;
13272 #define rb_parser_end_seen_p ripper_parser_end_seen_p
13273 #define rb_parser_encoding ripper_parser_encoding
13274 #define rb_parser_get_yydebug ripper_parser_get_yydebug
13275 #define rb_parser_set_yydebug ripper_parser_set_yydebug
13276 #define rb_parser_get_debug_output ripper_parser_get_debug_output
13277 #define rb_parser_set_debug_output ripper_parser_set_debug_output
13278 static VALUE ripper_parser_end_seen_p
(VALUE vparser
);
13279 static VALUE ripper_parser_encoding
(VALUE vparser
);
13280 static VALUE ripper_parser_get_yydebug
(VALUE self
);
13281 static VALUE ripper_parser_set_yydebug
(VALUE self
, VALUE flag
);
13282 static VALUE ripper_parser_get_debug_output
(VALUE self
);
13283 static VALUE ripper_parser_set_debug_output
(VALUE self
, VALUE output
);
13287 * ripper.error? -> Boolean
13289 * Return true if parsed source has errors.
13292 ripper_error_p
(VALUE vparser
)
13294 struct parser_params
*p
;
13296 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13297 return RBOOL
(p
->error_p
);
13303 * ripper.end_seen? -> Boolean
13305 * Return true if parsed source ended by +\_\_END\_\_+.
13308 rb_parser_end_seen_p
(VALUE vparser
)
13310 struct parser_params
*p
;
13312 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13313 return RBOOL
(p
->ruby__end__seen
);
13318 * ripper.encoding -> encoding
13320 * Return encoding of the source.
13323 rb_parser_encoding
(VALUE vparser
)
13325 struct parser_params
*p
;
13327 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13328 return rb_enc_from_encoding
(p
->enc
);
13334 * ripper.yydebug -> true or false
13339 rb_parser_get_yydebug
(VALUE self
)
13341 struct parser_params
*p
;
13343 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13344 return RBOOL
(p
->debug
);
13350 * ripper.yydebug = flag
13355 rb_parser_set_yydebug
(VALUE self
, VALUE flag
)
13357 struct parser_params
*p
;
13359 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13360 p
->debug
= RTEST
(flag
);
13366 * ripper.debug_output -> obj
13368 * Get debug output.
13371 rb_parser_get_debug_output
(VALUE self
)
13373 struct parser_params
*p
;
13375 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13376 return p
->debug_output
;
13381 * ripper.debug_output = obj
13383 * Set debug output.
13386 rb_parser_set_debug_output
(VALUE self
, VALUE output
)
13388 struct parser_params
*p
;
13390 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13391 return p
->debug_output
= output
;
13396 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
13397 /* Keep the order; NEWHEAP then xmalloc and ADD2HEAP to get rid of
13398 * potential memory leak */
13399 #define NEWHEAP() rb_imemo_tmpbuf_parser_heap(0, p->heap, 0)
13400 #define ADD2HEAP(new, cnt, ptr) ((p->heap = (new))->ptr = (ptr), \
13401 (new
)->cnt
= (cnt
), (ptr
))
13404 rb_parser_malloc
(struct parser_params
*p
, size_t size
)
13406 size_t cnt
= HEAPCNT
(1, size
);
13407 rb_imemo_tmpbuf_t
*n
= NEWHEAP
();
13408 void *ptr
= xmalloc
(size
);
13410 return ADD2HEAP
(n
, cnt
, ptr
);
13414 rb_parser_calloc
(struct parser_params
*p
, size_t nelem
, size_t size
)
13416 size_t cnt
= HEAPCNT
(nelem
, size
);
13417 rb_imemo_tmpbuf_t
*n
= NEWHEAP
();
13418 void *ptr
= xcalloc
(nelem
, size
);
13420 return ADD2HEAP
(n
, cnt
, ptr
);
13424 rb_parser_realloc
(struct parser_params
*p
, void *ptr
, size_t size
)
13426 rb_imemo_tmpbuf_t
*n
;
13427 size_t cnt
= HEAPCNT
(1, size
);
13429 if
(ptr
&& (n
= p
->heap
) != NULL
) {
13431 if
(n
->ptr
== ptr
) {
13432 n
->ptr
= ptr
= xrealloc
(ptr
, size
);
13433 if
(n
->cnt
) n
->cnt
= cnt
;
13436 } while
((n
= n
->next
) != NULL
);
13439 ptr
= xrealloc
(ptr
, size
);
13440 return ADD2HEAP
(n
, cnt
, ptr
);
13444 rb_parser_free
(struct parser_params
*p
, void *ptr
)
13446 rb_imemo_tmpbuf_t
**prev
= &p
->heap
, *n
;
13448 while
((n
= *prev
) != NULL
) {
13449 if
(n
->ptr
== ptr
) {
13459 rb_parser_printf
(struct parser_params
*p
, const char *fmt
, ...
)
13462 VALUE mesg
= p
->debug_buffer
;
13464 if
(NIL_P
(mesg
)) p
->debug_buffer
= mesg
= rb_str_new
(0, 0);
13466 rb_str_vcatf
(mesg
, fmt
, ap
);
13468 if
(RSTRING_END
(mesg
)[-1] == '\n') {
13469 rb_io_write
(p
->debug_output
, mesg
);
13470 p
->debug_buffer
= Qnil
;
13475 parser_compile_error
(struct parser_params
*p
, const char *fmt
, ...
)
13479 rb_io_flush
(p
->debug_output
);
13483 rb_syntax_error_append
(p
->error_buffer
,
13484 p
->ruby_sourcefile_string
,
13485 p
->ruby_sourceline
,
13486 rb_long2int
(p
->lex.pcur
- p
->lex.pbeg
),
13492 count_char
(const char *str
, int c
)
13495 while
(str
[n
] == c
) ++n
;
13500 * strip enclosing double-quotes, same as the default yytnamerr except
13501 * for that single-quotes matching back-quotes do not stop stripping.
13503 * "\"`class' keyword\"" => "`class' keyword"
13505 RUBY_FUNC_EXPORTED
size_t
13506 rb_yytnamerr
(struct parser_params
*p
, char *yyres
, const char *yystr
)
13508 if
(*yystr
== '"') {
13509 size_t yyn
= 0, bquote
= 0;
13510 const char *yyp
= yystr
;
13516 bquote
= count_char
(yyp
+1, '`') + 1;
13517 if
(yyres
) memcpy
(&yyres
[yyn
], yyp
, bquote
);
13525 if
(bquote
&& count_char
(yyp
+1, '\'') + 1 == bquote
) {
13526 if
(yyres
) memcpy
(yyres
+ yyn
, yyp
, bquote
);
13532 if
(yyp
[1] && yyp
[1] != '\'' && yyp
[2] == '\'') {
13533 if
(yyres
) memcpy
(yyres
+ yyn
, yyp
, 3);
13538 goto do_not_strip_quotes
;
13541 goto do_not_strip_quotes
;
13544 if
(*++yyp
!= '\\')
13545 goto do_not_strip_quotes
;
13546 /* Fall through. */
13561 do_not_strip_quotes
: ;
13564 if
(!yyres
) return strlen
(yystr
);
13566 return
(YYSIZE_T
)(yystpcpy
(yyres
, yystr
) - yyres
);
13571 #ifdef RIPPER_DEBUG
13574 ripper_validate_object
(VALUE self
, VALUE x
)
13576 if
(x
== Qfalse
) return x
;
13577 if
(x
== Qtrue
) return x
;
13578 if
(x
== Qnil
) return x
;
13580 rb_raise
(rb_eArgError
, "Qundef given");
13581 if
(FIXNUM_P
(x
)) return x
;
13582 if
(SYMBOL_P
(x
)) return x
;
13583 switch
(BUILTIN_TYPE
(x
)) {
13593 if
(!nd_type_p
((NODE
*)x
, NODE_RIPPER
)) {
13594 rb_raise
(rb_eArgError
, "NODE given: %p", (void *)x
);
13596 x
= ((NODE
*)x
)->nd_rval
;
13599 rb_raise
(rb_eArgError
, "wrong type of ruby object: %p (%s)",
13600 (void *)x
, rb_obj_classname
(x
));
13602 if
(!RBASIC_CLASS
(x
)) {
13603 rb_raise
(rb_eArgError
, "hidden ruby object: %p (%s)",
13604 (void *)x
, rb_builtin_type_name
(TYPE
(x
)));
13610 #define validate(x) ((x) = get_value(x))
13613 ripper_dispatch0
(struct parser_params
*p
, ID mid
)
13615 return rb_funcall
(p
->value
, mid
, 0);
13619 ripper_dispatch1
(struct parser_params
*p
, ID mid
, VALUE a
)
13622 return rb_funcall
(p
->value
, mid
, 1, a
);
13626 ripper_dispatch2
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
)
13630 return rb_funcall
(p
->value
, mid
, 2, a
, b
);
13634 ripper_dispatch3
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
, VALUE c
)
13639 return rb_funcall
(p
->value
, mid
, 3, a
, b
, c
);
13643 ripper_dispatch4
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
)
13649 return rb_funcall
(p
->value
, mid
, 4, a
, b
, c
, d
);
13653 ripper_dispatch5
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
, VALUE e
)
13660 return rb_funcall
(p
->value
, mid
, 5, a
, b
, c
, d
, e
);
13664 ripper_dispatch7
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
, VALUE e
, VALUE f
, VALUE g
)
13673 return rb_funcall
(p
->value
, mid
, 7, a
, b
, c
, d
, e
, f
, g
);
13677 ripper_get_id
(VALUE v
)
13680 if
(!RB_TYPE_P
(v
, T_NODE
)) return
0;
13682 if
(!nd_type_p
(nd
, NODE_RIPPER
)) return
0;
13687 ripper_get_value
(VALUE v
)
13690 if
(v
== Qundef
) return Qnil
;
13691 if
(!RB_TYPE_P
(v
, T_NODE
)) return v
;
13693 if
(!nd_type_p
(nd
, NODE_RIPPER
)) return Qnil
;
13694 return nd
->nd_rval
;
13698 ripper_error
(struct parser_params
*p
)
13704 ripper_compile_error
(struct parser_params
*p
, const char *fmt
, ...
)
13709 va_start
(args
, fmt
);
13710 str
= rb_vsprintf
(fmt
, args
);
13712 rb_funcall
(p
->value
, rb_intern
("compile_error"), 1, str
);
13717 ripper_lex_get_generic
(struct parser_params
*p
, VALUE src
)
13719 VALUE line
= rb_funcallv_public
(src
, id_gets
, 0, 0);
13720 if
(!NIL_P
(line
) && !RB_TYPE_P
(line
, T_STRING
)) {
13721 rb_raise
(rb_eTypeError
,
13722 "gets returned %"PRIsVALUE
" (expected String or nil)",
13723 rb_obj_class
(line
));
13729 ripper_lex_io_get
(struct parser_params
*p
, VALUE src
)
13731 return rb_io_gets
(src
);
13735 ripper_s_allocate
(VALUE klass
)
13737 struct parser_params
*p
;
13738 VALUE self
= TypedData_Make_Struct
(klass
, struct parser_params
,
13739 &parser_data_type
, p
);
13744 #define ripper_initialized_p(r) ((r)->lex.input != 0)
13748 * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
13750 * Create a new Ripper object.
13751 * _src_ must be a String, an IO, or an Object which has #gets method.
13753 * This method does not starts parsing.
13754 * See also Ripper#parse and Ripper.parse.
13757 ripper_initialize
(int argc
, VALUE
*argv
, VALUE self
)
13759 struct parser_params
*p
;
13760 VALUE src
, fname
, lineno
;
13762 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13763 rb_scan_args
(argc
, argv
, "12", &src
, &fname
, &lineno
);
13764 if
(RB_TYPE_P
(src
, T_FILE
)) {
13765 p
->lex.gets
= ripper_lex_io_get
;
13767 else if
(rb_respond_to
(src
, id_gets
)) {
13768 p
->lex.gets
= ripper_lex_get_generic
;
13772 p
->lex.gets
= lex_get_str
;
13774 p
->lex.input
= src
;
13776 if
(NIL_P
(fname
)) {
13777 fname
= STR_NEW2
("(ripper)");
13781 StringValueCStr
(fname
);
13782 fname
= rb_str_new_frozen
(fname
);
13784 parser_initialize
(p
);
13786 p
->ruby_sourcefile_string
= fname
;
13787 p
->ruby_sourcefile
= RSTRING_PTR
(fname
);
13788 p
->ruby_sourceline
= NIL_P
(lineno
) ?
0 : NUM2INT
(lineno
) - 1;
13794 ripper_parse0
(VALUE parser_v
)
13796 struct parser_params
*p
;
13798 TypedData_Get_Struct
(parser_v
, struct parser_params
, &parser_data_type
, p
);
13800 p
->ast
= rb_ast_new
();
13801 ripper_yyparse
((void*)p
);
13802 rb_ast_dispose
(p
->ast
);
13808 ripper_ensure
(VALUE parser_v
)
13810 struct parser_params
*p
;
13812 TypedData_Get_Struct
(parser_v
, struct parser_params
, &parser_data_type
, p
);
13813 p
->parsing_thread
= Qnil
;
13821 * Start parsing and returns the value of the root action.
13824 ripper_parse
(VALUE self
)
13826 struct parser_params
*p
;
13828 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13829 if
(!ripper_initialized_p
(p
)) {
13830 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13832 if
(!NIL_P
(p
->parsing_thread
)) {
13833 if
(p
->parsing_thread
== rb_thread_current
())
13834 rb_raise
(rb_eArgError
, "Ripper#parse is not reentrant");
13836 rb_raise
(rb_eArgError
, "Ripper#parse is not multithread-safe");
13838 p
->parsing_thread
= rb_thread_current
();
13839 rb_ensure
(ripper_parse0
, self
, ripper_ensure
, self
);
13846 * ripper.column -> Integer
13848 * Return column number of current parsing line.
13849 * This number starts from 0.
13852 ripper_column
(VALUE self
)
13854 struct parser_params
*p
;
13857 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13858 if
(!ripper_initialized_p
(p
)) {
13859 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13861 if
(NIL_P
(p
->parsing_thread
)) return Qnil
;
13862 col
= p
->lex.ptok
- p
->lex.pbeg
;
13863 return LONG2NUM
(col
);
13868 * ripper.filename -> String
13870 * Return current parsing filename.
13873 ripper_filename
(VALUE self
)
13875 struct parser_params
*p
;
13877 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13878 if
(!ripper_initialized_p
(p
)) {
13879 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13881 return p
->ruby_sourcefile_string
;
13886 * ripper.lineno -> Integer
13888 * Return line number of current parsing line.
13889 * This number starts from 1.
13892 ripper_lineno
(VALUE self
)
13894 struct parser_params
*p
;
13896 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13897 if
(!ripper_initialized_p
(p
)) {
13898 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13900 if
(NIL_P
(p
->parsing_thread
)) return Qnil
;
13901 return INT2NUM
(p
->ruby_sourceline
);
13906 * ripper.state -> Integer
13908 * Return scanner state of current token.
13911 ripper_state
(VALUE self
)
13913 struct parser_params
*p
;
13915 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13916 if
(!ripper_initialized_p
(p
)) {
13917 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13919 if
(NIL_P
(p
->parsing_thread
)) return Qnil
;
13920 return INT2NUM
(p
->lex.state
);
13925 * ripper.token -> String
13927 * Return the current token string.
13930 ripper_token
(VALUE self
)
13932 struct parser_params
*p
;
13935 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13936 if
(!ripper_initialized_p
(p
)) {
13937 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13939 if
(NIL_P
(p
->parsing_thread
)) return Qnil
;
13940 pos
= p
->lex.ptok
- p
->lex.pbeg
;
13941 len
= p
->lex.pcur
- p
->lex.ptok
;
13942 return rb_str_subseq
(p
->lex.lastline
, pos
, len
);
13945 #ifdef RIPPER_DEBUG
13948 ripper_assert_Qundef
(VALUE self
, VALUE obj
, VALUE msg
)
13951 if
(obj
== Qundef
) {
13952 rb_raise
(rb_eArgError
, "%"PRIsVALUE
, msg
);
13959 ripper_value
(VALUE self
, VALUE obj
)
13961 return ULONG2NUM
(obj
);
13967 * Ripper.lex_state_name(integer) -> string
13969 * Returns a string representation of lex_state.
13972 ripper_lex_state_name
(VALUE self
, VALUE state
)
13974 return rb_parser_lex_state_name
(NUM2INT
(state
));
13980 ripper_init_eventids1
();
13981 ripper_init_eventids2
();
13982 id_warn
= rb_intern_const
("warn");
13983 id_warning
= rb_intern_const
("warning");
13984 id_gets
= rb_intern_const
("gets");
13985 id_assoc
= rb_intern_const
("=>");
13987 (void)yystpcpy
; /* may not used in newer bison */
13993 InitVM_ripper
(void)
13997 Ripper
= rb_define_class
("Ripper", rb_cObject
);
13998 /* version of Ripper */
13999 rb_define_const
(Ripper
, "Version", rb_usascii_str_new2
(RIPPER_VERSION
));
14000 rb_define_alloc_func
(Ripper
, ripper_s_allocate
);
14001 rb_define_method
(Ripper
, "initialize", ripper_initialize
, -1);
14002 rb_define_method
(Ripper
, "parse", ripper_parse
, 0);
14003 rb_define_method
(Ripper
, "column", ripper_column
, 0);
14004 rb_define_method
(Ripper
, "filename", ripper_filename
, 0);
14005 rb_define_method
(Ripper
, "lineno", ripper_lineno
, 0);
14006 rb_define_method
(Ripper
, "state", ripper_state
, 0);
14007 rb_define_method
(Ripper
, "token", ripper_token
, 0);
14008 rb_define_method
(Ripper
, "end_seen?", rb_parser_end_seen_p
, 0);
14009 rb_define_method
(Ripper
, "encoding", rb_parser_encoding
, 0);
14010 rb_define_method
(Ripper
, "yydebug", rb_parser_get_yydebug
, 0);
14011 rb_define_method
(Ripper
, "yydebug=", rb_parser_set_yydebug
, 1);
14012 rb_define_method
(Ripper
, "debug_output", rb_parser_get_debug_output
, 0);
14013 rb_define_method
(Ripper
, "debug_output=", rb_parser_set_debug_output
, 1);
14014 rb_define_method
(Ripper
, "error?", ripper_error_p
, 0);
14015 #ifdef RIPPER_DEBUG
14016 rb_define_method
(Ripper
, "assert_Qundef", ripper_assert_Qundef
, 2);
14017 rb_define_method
(Ripper
, "rawVALUE", ripper_value
, 1);
14018 rb_define_method
(Ripper
, "validate_object", ripper_validate_object
, 1);
14021 rb_define_singleton_method
(Ripper
, "dedent_string", parser_dedent_string
, 2);
14022 rb_define_private_method
(Ripper
, "dedent_string", parser_dedent_string
, 2);
14024 rb_define_singleton_method
(Ripper
, "lex_state_name", ripper_lex_state_name
, 1);
14026 <% @exprs.each do |expr
, desc|
-%
>
14028 rb_define_const
(Ripper
, "<%=expr%>", INT2NUM
(<%
=expr%
>));
14030 ripper_init_eventids1_table
(Ripper
);
14031 ripper_init_eventids2_table
(Ripper
);
14034 /* Hack to let RDoc document SCRIPT_LINES__ */
14037 * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
14038 * after the assignment will be added as an Array of lines with the file
14041 rb_define_global_const
("SCRIPT_LINES__", Qnil
);
14045 #endif /* RIPPER */
14050 * c-file-style: "ruby"