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 '&'
430 #define ANON_REST_ID '*'
431 #define ANON_KEYWORD_REST_ID idPow
433 static enum yytokentype
yylex(YYSTYPE*, YYLTYPE*, struct parser_params
*);
437 rb_discard_node
(struct parser_params
*p
, NODE
*n
)
439 rb_ast_delete_node
(p
->ast
, n
);
445 add_mark_object
(struct parser_params
*p
, VALUE obj
)
447 if
(!SPECIAL_CONST_P
(obj
)
448 && !RB_TYPE_P
(obj
, T_NODE
) /* Ripper jumbles NODE objects and other objects... */
450 rb_ast_add_mark_object
(p
->ast
, obj
);
455 static NODE
* node_newnode_with_locals
(struct parser_params
*, enum node_type
, VALUE
, VALUE
, const rb_code_location_t
*);
458 static NODE
* node_newnode
(struct parser_params
*, enum node_type
, VALUE
, VALUE
, VALUE
, const rb_code_location_t
*);
459 #define rb_node_newnode(type, a1, a2, a3, loc) node_newnode(p, (type), (a1), (a2), (a3), (loc))
461 static NODE
*nd_set_loc
(NODE
*nd
, const YYLTYPE *loc
);
464 parser_get_node_id
(struct parser_params
*p
)
466 int node_id
= p
->node_id
;
473 set_line_body
(NODE
*body
, int line
)
476 switch
(nd_type
(body
)) {
479 nd_set_line
(body
, line
);
483 #define yyparse ruby_yyparse
485 static NODE
* cond
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
);
486 static NODE
* method_cond
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
);
487 #define new_nil(loc) NEW_NIL(loc)
488 static NODE
*new_nil_at
(struct parser_params
*p
, const rb_code_position_t
*pos
);
489 static NODE
*new_if
(struct parser_params
*,NODE
*,NODE
*,NODE
*,const YYLTYPE*);
490 static NODE
*new_unless
(struct parser_params
*,NODE
*,NODE
*,NODE
*,const YYLTYPE*);
491 static NODE
*logop
(struct parser_params
*,ID
,NODE
*,NODE
*,const YYLTYPE*,const YYLTYPE*);
493 static NODE
*newline_node
(NODE
*);
494 static void fixpos
(NODE
*,NODE
*);
496 static int value_expr_gen
(struct parser_params
*,NODE
*);
497 static void void_expr
(struct parser_params
*,NODE
*);
498 static NODE
*remove_begin
(NODE
*);
499 static NODE
*remove_begin_all
(NODE
*);
500 #define value_expr(node) value_expr_gen(p, (node))
501 static NODE
*void_stmts
(struct parser_params
*,NODE
*);
502 static void reduce_nodes
(struct parser_params
*,NODE
**);
503 static void block_dup_check
(struct parser_params
*,NODE
*,NODE
*);
505 static NODE
*block_append
(struct parser_params
*,NODE
*,NODE
*);
506 static NODE
*list_append
(struct parser_params
*,NODE
*,NODE
*);
507 static NODE
*list_concat
(NODE
*,NODE
*);
508 static NODE
*arg_append
(struct parser_params
*,NODE
*,NODE
*,const YYLTYPE*);
509 static NODE
*last_arg_append
(struct parser_params
*p
, NODE
*args
, NODE
*last_arg
, const YYLTYPE *loc
);
510 static NODE
*rest_arg_append
(struct parser_params
*p
, NODE
*args
, NODE
*rest_arg
, const YYLTYPE *loc
);
511 static NODE
*literal_concat
(struct parser_params
*,NODE
*,NODE
*,const YYLTYPE*);
512 static NODE
*new_evstr
(struct parser_params
*,NODE
*,const YYLTYPE*);
513 static NODE
*new_dstr
(struct parser_params
*,NODE
*,const YYLTYPE*);
514 static NODE
*evstr2dstr
(struct parser_params
*,NODE
*);
515 static NODE
*splat_array
(NODE
*);
516 static void mark_lvar_used
(struct parser_params
*p
, NODE
*rhs
);
518 static NODE
*call_bin_op
(struct parser_params
*,NODE
*,ID
,NODE
*,const YYLTYPE*,const YYLTYPE*);
519 static NODE
*call_uni_op
(struct parser_params
*,NODE
*,ID
,const YYLTYPE*,const YYLTYPE*);
520 static NODE
*new_qcall
(struct parser_params
* p
, ID atype
, NODE
*recv
, ID mid
, NODE
*args
, const YYLTYPE *op_loc
, const YYLTYPE *loc
);
521 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
);
522 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
;}
524 static bool args_info_empty_p
(struct rb_args_info
*args
);
525 static NODE
*new_args
(struct parser_params
*,NODE
*,NODE
*,ID
,NODE
*,NODE
*,const YYLTYPE*);
526 static NODE
*new_args_tail
(struct parser_params
*,NODE
*,ID
,ID
,const YYLTYPE*);
527 static NODE
*new_array_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*pre_arg
, NODE
*aryptn
, const YYLTYPE *loc
);
528 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
);
529 static NODE
*new_find_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*fndptn
, const YYLTYPE *loc
);
530 static NODE
*new_find_pattern_tail
(struct parser_params
*p
, ID pre_rest_arg
, NODE
*args
, ID post_rest_arg
, const YYLTYPE *loc
);
531 static NODE
*new_hash_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*hshptn
, const YYLTYPE *loc
);
532 static NODE
*new_hash_pattern_tail
(struct parser_params
*p
, NODE
*kw_args
, ID kw_rest_arg
, const YYLTYPE *loc
);
534 static NODE
*new_kw_arg
(struct parser_params
*p
, NODE
*k
, const YYLTYPE *loc
);
535 static NODE
*args_with_numbered
(struct parser_params
*,NODE
*,int);
537 static VALUE negate_lit
(struct parser_params
*, VALUE
);
538 static NODE
*ret_args
(struct parser_params
*,NODE
*);
539 static NODE
*arg_blk_pass
(NODE
*,NODE
*);
540 static NODE
*new_yield
(struct parser_params
*,NODE
*,const YYLTYPE*);
541 static NODE
*dsym_node
(struct parser_params
*,NODE
*,const YYLTYPE*);
543 static NODE
*gettable
(struct parser_params
*,ID
,const YYLTYPE*);
544 static NODE
*assignable
(struct parser_params
*,ID
,NODE
*,const YYLTYPE*);
546 static NODE
*aryset
(struct parser_params
*,NODE
*,NODE
*,const YYLTYPE*);
547 static NODE
*attrset
(struct parser_params
*,NODE
*,ID
,ID
,const YYLTYPE*);
549 static void rb_backref_error
(struct parser_params
*,NODE
*);
550 static NODE
*node_assign
(struct parser_params
*,NODE
*,NODE
*,struct lex_context
,const YYLTYPE*);
552 static NODE
*new_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID op
, NODE
*rhs
, struct lex_context
, const YYLTYPE *loc
);
553 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
);
554 static NODE
*new_attr_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID atype
, ID attr
, ID op
, NODE
*rhs
, const YYLTYPE *loc
);
555 static NODE
*new_const_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID op
, NODE
*rhs
, struct lex_context
, const YYLTYPE *loc
);
556 static NODE
*new_bodystmt
(struct parser_params
*p
, NODE
*head
, NODE
*rescue
, NODE
*rescue_else
, NODE
*ensure
, const YYLTYPE *loc
);
558 static NODE
*const_decl
(struct parser_params
*p
, NODE
* path
, const YYLTYPE *loc
);
560 static NODE
*opt_arg_append
(NODE
*, NODE
*);
561 static NODE
*kwd_append
(NODE
*, NODE
*);
563 static NODE
*new_hash
(struct parser_params
*p
, NODE
*hash
, const YYLTYPE *loc
);
564 static NODE
*new_unique_key_hash
(struct parser_params
*p
, NODE
*hash
, const YYLTYPE *loc
);
566 static NODE
*new_defined
(struct parser_params
*p
, NODE
*expr
, const YYLTYPE *loc
);
568 static NODE
*new_regexp
(struct parser_params
*, NODE
*, int, const YYLTYPE *);
570 #define make_list(list, loc) ((list) ? (nd_set_loc(list, loc), list) : NEW_ZLIST(loc))
572 static NODE
*new_xstring
(struct parser_params
*, NODE
*, const YYLTYPE *loc
);
574 static NODE
*symbol_append
(struct parser_params
*p
, NODE
*symbols
, NODE
*symbol
);
576 static NODE
*match_op
(struct parser_params
*,NODE
*,NODE
*,const YYLTYPE*,const YYLTYPE*);
578 static rb_ast_id_table_t
*local_tbl
(struct parser_params
*);
580 static VALUE reg_compile
(struct parser_params
*, VALUE
, int);
581 static void reg_fragment_setenc
(struct parser_params
*, VALUE
, int);
582 static int reg_fragment_check
(struct parser_params
*, VALUE
, int);
583 static NODE
*reg_named_capture_assign
(struct parser_params
* p
, VALUE regexp
, const YYLTYPE *loc
);
585 static int literal_concat0
(struct parser_params
*p
, VALUE head
, VALUE tail
);
586 static NODE
*heredoc_dedent
(struct parser_params
*,NODE
*);
588 static void check_literal_when
(struct parser_params
*p
, NODE
*args
, const YYLTYPE *loc
);
590 #define get_id(id) (id)
591 #define get_value(val) (val)
592 #define get_num(num) (num)
594 #define NODE_RIPPER NODE_CDECL
595 #define NEW_RIPPER(a,b,c,loc) (VALUE)NEW_CDECL(a,b,c,loc)
597 static inline
int ripper_is_node_yylval
(VALUE n
);
600 ripper_new_yylval
(struct parser_params
*p
, ID a
, VALUE b
, VALUE c
)
602 if
(ripper_is_node_yylval
(c
)) c
= RNODE
(c
)->nd_cval
;
603 add_mark_object
(p
, b
);
604 add_mark_object
(p
, c
);
605 return NEW_RIPPER
(a
, b
, c
, &NULL_LOC
);
609 ripper_is_node_yylval
(VALUE n
)
611 return RB_TYPE_P
(n
, T_NODE
) && nd_type_p
(RNODE
(n
), NODE_RIPPER
);
614 #define value_expr(node) ((void)(node))
615 #define remove_begin(node) (node)
616 #define void_stmts(p,x) (x)
617 #define rb_dvar_defined(id, base) 0
618 #define rb_local_defined(id, base) 0
619 static ID ripper_get_id
(VALUE
);
620 #define get_id(id) ripper_get_id(id)
621 static VALUE ripper_get_value
(VALUE
);
622 #define get_value(val) ripper_get_value(val)
623 #define get_num(num) (int)get_id(num)
624 static VALUE assignable
(struct parser_params
*,VALUE
);
625 static int id_is_var
(struct parser_params
*p
, ID id
);
627 #define method_cond(p,node,loc) (node)
628 #define call_bin_op(p, recv,id,arg1,op_loc,loc) dispatch3(binary, (recv), STATIC_ID2SYM(id), (arg1))
629 #define match_op(p,node1,node2,op_loc,loc) call_bin_op(0, (node1), idEqTilde, (node2), op_loc, loc)
630 #define call_uni_op(p, recv,id,op_loc,loc) dispatch2(unary, STATIC_ID2SYM(id), (recv))
631 #define logop(p,id,node1,node2,op_loc,loc) call_bin_op(0, (node1), (id), (node2), op_loc, loc)
633 #define new_nil(loc) Qnil
635 static VALUE new_regexp
(struct parser_params
*, VALUE
, VALUE
, const YYLTYPE *);
637 static VALUE const_decl
(struct parser_params
*p
, VALUE path
);
639 static VALUE var_field
(struct parser_params
*p
, VALUE a
);
640 static VALUE assign_error
(struct parser_params
*p
, const char *mesg
, VALUE a
);
642 static VALUE parser_reg_compile
(struct parser_params
*, VALUE
, int, VALUE
*);
644 static VALUE backref_error
(struct parser_params
*, NODE
*, VALUE
);
647 /* forward declaration */
648 typedef
struct rb_strterm_heredoc_struct rb_strterm_heredoc_t
;
650 RUBY_SYMBOL_EXPORT_BEGIN
651 VALUE rb_parser_reg_compile
(struct parser_params
* p
, VALUE str
, int options
);
652 int rb_reg_fragment_setenc
(struct parser_params
*, VALUE
, int);
653 enum lex_state_e rb_parser_trace_lex_state
(struct parser_params
*, enum lex_state_e
, enum lex_state_e
, int);
654 VALUE rb_parser_lex_state_name
(enum lex_state_e state
);
655 void rb_parser_show_bitstack
(struct parser_params
*, stack_type
, const char *, int);
656 PRINTF_ARGS
(void rb_parser_fatal
(struct parser_params
*p
, const char *fmt
, ...
), 2, 3);
657 YYLTYPE *rb_parser_set_location_from_strterm_heredoc
(struct parser_params
*p
, rb_strterm_heredoc_t
*here
, YYLTYPE *yylloc);
658 YYLTYPE *rb_parser_set_location_of_none
(struct parser_params
*p
, YYLTYPE *yylloc);
659 YYLTYPE *rb_parser_set_location
(struct parser_params
*p
, YYLTYPE *yylloc);
660 RUBY_SYMBOL_EXPORT_END
662 static void error_duplicate_pattern_variable
(struct parser_params
*p
, ID id
, const YYLTYPE *loc
);
663 static void error_duplicate_pattern_key
(struct parser_params
*p
, ID id
, const YYLTYPE *loc
);
665 static ID formal_argument
(struct parser_params
*, ID
);
667 static ID formal_argument
(struct parser_params
*, VALUE
);
669 static ID shadowing_lvar
(struct parser_params
*,ID
);
670 static void new_bv
(struct parser_params
*,ID
);
672 static void local_push
(struct parser_params
*,int);
673 static void local_pop
(struct parser_params
*);
674 static void local_var
(struct parser_params
*, ID
);
675 static void arg_var
(struct parser_params
*, ID
);
676 static int local_id
(struct parser_params
*p
, ID id
);
677 static int local_id_ref
(struct parser_params
*, ID
, ID
**);
679 static ID internal_id
(struct parser_params
*);
680 static NODE
*new_args_forward_call
(struct parser_params
*, NODE
*, const YYLTYPE*, const YYLTYPE*);
682 static int check_forwarding_args
(struct parser_params
*);
683 static void add_forwarding_args
(struct parser_params
*p
);
685 static const struct vtable
*dyna_push
(struct parser_params
*);
686 static void dyna_pop
(struct parser_params
*, const struct vtable
*);
687 static int dyna_in_block
(struct parser_params
*);
688 #define dyna_var(p, id) local_var(p, id)
689 static int dvar_defined
(struct parser_params
*, ID
);
690 static int dvar_defined_ref
(struct parser_params
*, ID
, ID
**);
691 static int dvar_curr
(struct parser_params
*,ID
);
693 static int lvar_defined
(struct parser_params
*, ID
);
695 static NODE
*numparam_push
(struct parser_params
*p
);
696 static void numparam_pop
(struct parser_params
*p
, NODE
*prev_inner
);
699 # define METHOD_NOT idNOT
701 # define METHOD_NOT '!'
704 #define idFWD_REST '*'
705 #ifdef RUBY3_KEYWORDS
706 #define idFWD_KWREST idPow /* Use simple "**", as tDSTAR is "**arg" */
708 #define idFWD_KWREST 0
710 #define idFWD_BLOCK '&'
712 #define RE_OPTION_ONCE (1<<16)
713 #define RE_OPTION_ENCODING_SHIFT 8
714 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
715 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
716 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
717 #define RE_OPTION_MASK 0xff
718 #define RE_OPTION_ARG_ENCODING_NONE 32
720 /* structs for managing terminator of string literal and heredocment */
721 typedef
struct rb_strterm_literal_struct
{
728 long func
; /* STR_FUNC_* (e.g., STR_FUNC_ESCAPE and STR_FUNC_EXPAND) */
732 long paren
; /* '(' of `%q(...)` */
736 long term
; /* ')' of `%q(...)` */
738 } rb_strterm_literal_t
;
740 #define HERETERM_LENGTH_BITS ((SIZEOF_VALUE - 1) * CHAR_BIT - 1)
742 struct rb_strterm_heredoc_struct
{
743 VALUE lastline
; /* the string of line that contains `<<"END"` */
744 long offset
; /* the column of END in `<<"END"` */
745 int sourceline
; /* lineno of the line that contains `<<"END"` */
746 unsigned length
/* the length of END in `<<"END"` */
747 #if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
748 : HERETERM_LENGTH_BITS
749 # define HERETERM_LENGTH_MAX ((1U << HERETERM_LENGTH_BITS) - 1)
751 # define HERETERM_LENGTH_MAX UINT_MAX
754 #if HERETERM_LENGTH_BITS < SIZEOF_INT * CHAR_BIT
762 STATIC_ASSERT
(rb_strterm_heredoc_t
, sizeof
(rb_strterm_heredoc_t
) <= 4 * SIZEOF_VALUE
);
764 #define STRTERM_HEREDOC IMEMO_FL_USER0
766 struct rb_strterm_struct
{
769 rb_strterm_literal_t literal
;
770 rb_strterm_heredoc_t heredoc
;
776 rb_strterm_mark
(VALUE obj
)
778 rb_strterm_t
*strterm
= (rb_strterm_t
*)obj
;
779 if
(RBASIC
(obj
)->flags
& STRTERM_HEREDOC
) {
780 rb_strterm_heredoc_t
*heredoc
= &strterm
->u.heredoc
;
781 rb_gc_mark
(heredoc
->lastline
);
786 #define yytnamerr(yyres, yystr) (YYSIZE_T)rb_yytnamerr(p, yyres, yystr)
787 size_t rb_yytnamerr
(struct parser_params
*p
, char *yyres
, const char *yystr
);
789 #define TOKEN2ID(tok) ( \
790 tTOKEN_LOCAL_BEGIN
<(tok
)&&(tok
)<tTOKEN_LOCAL_END ? TOKEN2LOCALID
(tok
) : \
791 tTOKEN_INSTANCE_BEGIN
<(tok
)&&(tok
)<tTOKEN_INSTANCE_END ? TOKEN2INSTANCEID
(tok
) : \
792 tTOKEN_GLOBAL_BEGIN
<(tok
)&&(tok
)<tTOKEN_GLOBAL_END ? TOKEN2GLOBALID
(tok
) : \
793 tTOKEN_CONST_BEGIN
<(tok
)&&(tok
)<tTOKEN_CONST_END ? TOKEN2CONSTID
(tok
) : \
794 tTOKEN_CLASS_BEGIN
<(tok
)&&(tok
)<tTOKEN_CLASS_END ? TOKEN2CLASSID
(tok
) : \
795 tTOKEN_ATTRSET_BEGIN
<(tok
)&&(tok
)<tTOKEN_ATTRSET_END ? TOKEN2ATTRSETID
(tok
) : \
796 ((tok
) / ((tok
)<tPRESERVED_ID_END
&& ((tok
)>=128 || rb_ispunct
(tok
)))))
798 /****** Ripper *******/
801 #define RIPPER_VERSION "0.1.0"
803 static inline VALUE intern_sym
(const char *name
);
805 #include "eventids1.c"
806 #include "eventids2.c"
808 static VALUE ripper_dispatch0
(struct parser_params
*,ID
);
809 static VALUE ripper_dispatch1
(struct parser_params
*,ID
,VALUE
);
810 static VALUE ripper_dispatch2
(struct parser_params
*,ID
,VALUE
,VALUE
);
811 static VALUE ripper_dispatch3
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
);
812 static VALUE ripper_dispatch4
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
);
813 static VALUE ripper_dispatch5
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
);
814 static VALUE ripper_dispatch7
(struct parser_params
*,ID
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
,VALUE
);
815 static void ripper_error
(struct parser_params
*p
);
817 #define dispatch0(n) ripper_dispatch0(p, TOKEN_PASTE(ripper_id_, n))
818 #define dispatch1(n,a) ripper_dispatch1(p, TOKEN_PASTE(ripper_id_, n), (a))
819 #define dispatch2(n,a,b) ripper_dispatch2(p, TOKEN_PASTE(ripper_id_, n), (a), (b))
820 #define dispatch3(n,a,b,c) ripper_dispatch3(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
821 #define dispatch4(n,a,b,c,d) ripper_dispatch4(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
822 #define dispatch5(n,a,b,c,d,e) ripper_dispatch5(p, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
823 #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))
825 #define yyparse ripper_yyparse
827 #define ID2VAL(id) STATIC_ID2SYM(id)
828 #define TOKEN2VAL(t) ID2VAL(TOKEN2ID(t))
829 #define KWD2EID(t, v) ripper_new_yylval(p, keyword_##t, get_value(v), 0)
831 #define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
832 dispatch7
(params
, (pars
), (opts
), (rest
), (pars2
), (kws
), (kwrest
), (blk
))
834 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
837 new_args
(struct parser_params
*p
, VALUE pre_args
, VALUE opt_args
, VALUE rest_arg
, VALUE post_args
, VALUE tail
, YYLTYPE *loc
)
839 NODE
*t
= (NODE
*)tail
;
840 VALUE kw_args
= t
->u1.value
, kw_rest_arg
= t
->u2.value
, block
= t
->u3.value
;
841 return params_new
(pre_args
, opt_args
, rest_arg
, post_args
, kw_args
, kw_rest_arg
, escape_Qundef
(block
));
845 new_args_tail
(struct parser_params
*p
, VALUE kw_args
, VALUE kw_rest_arg
, VALUE block
, YYLTYPE *loc
)
847 NODE
*t
= rb_node_newnode
(NODE_ARGS_AUX
, kw_args
, kw_rest_arg
, block
, &NULL_LOC
);
848 add_mark_object
(p
, kw_args
);
849 add_mark_object
(p
, kw_rest_arg
);
850 add_mark_object
(p
, block
);
855 args_with_numbered
(struct parser_params
*p
, VALUE args
, int max_numparam
)
861 new_array_pattern
(struct parser_params
*p
, VALUE constant
, VALUE pre_arg
, VALUE aryptn
, const YYLTYPE *loc
)
863 NODE
*t
= (NODE
*)aryptn
;
864 VALUE pre_args
= t
->u1.value
, rest_arg
= t
->u2.value
, post_args
= t
->u3.value
;
866 if
(!NIL_P
(pre_arg
)) {
867 if
(!NIL_P
(pre_args
)) {
868 rb_ary_unshift
(pre_args
, pre_arg
);
871 pre_args
= rb_ary_new_from_args
(1, pre_arg
);
874 return dispatch4
(aryptn
, constant
, pre_args
, rest_arg
, post_args
);
878 new_array_pattern_tail
(struct parser_params
*p
, VALUE pre_args
, VALUE has_rest
, VALUE rest_arg
, VALUE post_args
, const YYLTYPE *loc
)
883 rest_arg
= dispatch1
(var_field
, rest_arg ? rest_arg
: Qnil
);
889 t
= rb_node_newnode
(NODE_ARYPTN
, pre_args
, rest_arg
, post_args
, &NULL_LOC
);
890 add_mark_object
(p
, pre_args
);
891 add_mark_object
(p
, rest_arg
);
892 add_mark_object
(p
, post_args
);
897 new_find_pattern
(struct parser_params
*p
, VALUE constant
, VALUE fndptn
, const YYLTYPE *loc
)
899 NODE
*t
= (NODE
*)fndptn
;
900 VALUE pre_rest_arg
= t
->u1.value
, args
= t
->u2.value
, post_rest_arg
= t
->u3.value
;
902 return dispatch4
(fndptn
, constant
, pre_rest_arg
, args
, post_rest_arg
);
906 new_find_pattern_tail
(struct parser_params
*p
, VALUE pre_rest_arg
, VALUE args
, VALUE post_rest_arg
, const YYLTYPE *loc
)
910 pre_rest_arg
= dispatch1
(var_field
, pre_rest_arg ? pre_rest_arg
: Qnil
);
911 post_rest_arg
= dispatch1
(var_field
, post_rest_arg ? post_rest_arg
: Qnil
);
913 t
= rb_node_newnode
(NODE_FNDPTN
, pre_rest_arg
, args
, post_rest_arg
, &NULL_LOC
);
914 add_mark_object
(p
, pre_rest_arg
);
915 add_mark_object
(p
, args
);
916 add_mark_object
(p
, post_rest_arg
);
920 #define new_hash(p,h,l) rb_ary_new_from_args(0)
923 new_unique_key_hash
(struct parser_params
*p
, VALUE ary
, const YYLTYPE *loc
)
929 new_hash_pattern
(struct parser_params
*p
, VALUE constant
, VALUE hshptn
, const YYLTYPE *loc
)
931 NODE
*t
= (NODE
*)hshptn
;
932 VALUE kw_args
= t
->u1.value
, kw_rest_arg
= t
->u2.value
;
933 return dispatch3
(hshptn
, constant
, kw_args
, kw_rest_arg
);
937 new_hash_pattern_tail
(struct parser_params
*p
, VALUE kw_args
, VALUE kw_rest_arg
, const YYLTYPE *loc
)
941 kw_rest_arg
= dispatch1
(var_field
, kw_rest_arg
);
946 t
= rb_node_newnode
(NODE_HSHPTN
, kw_args
, kw_rest_arg
, 0, &NULL_LOC
);
948 add_mark_object
(p
, kw_args
);
949 add_mark_object
(p
, kw_rest_arg
);
953 #define new_defined(p,expr,loc) dispatch1(defined, (expr))
955 static VALUE heredoc_dedent
(struct parser_params
*,VALUE
);
958 #define ID2VAL(id) (id)
959 #define TOKEN2VAL(t) ID2VAL(t)
960 #define KWD2EID(t, v) keyword_##t
963 set_defun_body
(struct parser_params
*p
, NODE
*n
, NODE
*args
, NODE
*body
, const YYLTYPE *loc
)
965 body
= remove_begin
(body
);
966 reduce_nodes
(p
, &body
);
967 n
->nd_defn
= NEW_SCOPE
(args
, body
, loc
);
969 nd_set_line
(n
->nd_defn
, loc
->end_pos.lineno
);
970 set_line_body
(body
, loc
->beg_pos.lineno
);
975 rescued_expr
(struct parser_params
*p
, NODE
*arg
, NODE
*rescue
,
976 const YYLTYPE *arg_loc
, const YYLTYPE *mod_loc
, const YYLTYPE *res_loc
)
978 YYLTYPE loc
= code_loc_gen
(mod_loc
, res_loc
);
979 rescue
= NEW_RESBODY
(0, remove_begin
(rescue
), 0, &loc
);
980 loc.beg_pos
= arg_loc
->beg_pos
;
981 return NEW_RESCUE
(arg
, rescue
, 0, &loc
);
987 restore_defun
(struct parser_params
*p
, NODE
*name
)
989 YYSTYPE c
= {.val
= name
->nd_cval
};
990 p
->cur_arg
= name
->nd_vid
;
991 p
->ctxt.in_def
= c.ctxt.in_def
;
992 p
->ctxt.shareable_constant_value
= c.ctxt.shareable_constant_value
;
996 endless_method_name
(struct parser_params
*p
, NODE
*defn
, const YYLTYPE *loc
)
999 defn
= defn
->nd_defn
;
1001 ID mid
= defn
->nd_mid
;
1002 if
(is_attrset_id
(mid
)) {
1003 yyerror1
(loc
, "setter method cannot be defined in an endless method definition");
1005 token_info_drop
(p
, "def", loc
->beg_pos
);
1011 # define ifndef_ripper(x) (x)
1014 # define Qnull Qundef
1015 # define ifndef_ripper(x)
1018 # define rb_warn0(fmt) WARN_CALL(WARN_ARGS(fmt, 1))
1019 # define rb_warn1(fmt,a) WARN_CALL(WARN_ARGS(fmt, 2), (a))
1020 # define rb_warn2(fmt,a,b) WARN_CALL(WARN_ARGS(fmt, 3), (a), (b))
1021 # define rb_warn3(fmt,a,b,c) WARN_CALL(WARN_ARGS(fmt, 4), (a), (b), (c))
1022 # define rb_warn4(fmt,a,b,c,d) WARN_CALL(WARN_ARGS(fmt, 5), (a), (b), (c), (d))
1023 # define rb_warning0(fmt) WARNING_CALL(WARNING_ARGS(fmt, 1))
1024 # define rb_warning1(fmt,a) WARNING_CALL(WARNING_ARGS(fmt, 2), (a))
1025 # define rb_warning2(fmt,a,b) WARNING_CALL(WARNING_ARGS(fmt, 3), (a), (b))
1026 # define rb_warning3(fmt,a,b,c) WARNING_CALL(WARNING_ARGS(fmt, 4), (a), (b), (c))
1027 # define rb_warning4(fmt,a,b,c,d) WARNING_CALL(WARNING_ARGS(fmt, 5), (a), (b), (c), (d))
1028 # define rb_warn0L(l,fmt) WARN_CALL(WARN_ARGS_L(l, fmt, 1))
1029 # define rb_warn1L(l,fmt,a) WARN_CALL(WARN_ARGS_L(l, fmt, 2), (a))
1030 # define rb_warn2L(l,fmt,a,b) WARN_CALL(WARN_ARGS_L(l, fmt, 3), (a), (b))
1031 # define rb_warn3L(l,fmt,a,b,c) WARN_CALL(WARN_ARGS_L(l, fmt, 4), (a), (b), (c))
1032 # define rb_warn4L(l,fmt,a,b,c,d) WARN_CALL(WARN_ARGS_L(l, fmt, 5), (a), (b), (c), (d))
1033 # define rb_warning0L(l,fmt) WARNING_CALL(WARNING_ARGS_L(l, fmt, 1))
1034 # define rb_warning1L(l,fmt,a) WARNING_CALL(WARNING_ARGS_L(l, fmt, 2), (a))
1035 # define rb_warning2L(l,fmt,a,b) WARNING_CALL(WARNING_ARGS_L(l, fmt, 3), (a), (b))
1036 # define rb_warning3L(l,fmt,a,b,c) WARNING_CALL(WARNING_ARGS_L(l, fmt, 4), (a), (b), (c))
1037 # define rb_warning4L(l,fmt,a,b,c,d) WARNING_CALL(WARNING_ARGS_L(l, fmt, 5), (a), (b), (c), (d))
1039 static ID id_warn
, id_warning
, id_gets
, id_assoc
;
1040 # define ERR_MESG() STR_NEW2(mesg) /* to bypass Ripper DSL */
1041 # define WARN_S_L(s,l) STR_NEW(s,l)
1042 # define WARN_S(s) STR_NEW2(s)
1043 # define WARN_I(i) INT2NUM(i)
1044 # define WARN_ID(i) rb_id2str(i)
1045 # define WARN_IVAL(i) i
1046 # define PRIsWARN "s"
1047 # define rb_warn0L_experimental(l,fmt) WARN_CALL(WARN_ARGS_L(l, fmt, 1))
1048 # define WARN_ARGS(fmt,n) p->value, id_warn, n, rb_usascii_str_new_lit(fmt)
1049 # define WARN_ARGS_L(l,fmt,n) WARN_ARGS(fmt,n)
1050 # ifdef HAVE_VA_ARGS_MACRO
1051 # define WARN_CALL(...) rb_funcall(__VA_ARGS__)
1053 # define WARN_CALL rb_funcall
1055 # define WARNING_ARGS(fmt,n) p->value, id_warning, n, rb_usascii_str_new_lit(fmt)
1056 # define WARNING_ARGS_L(l, fmt,n) WARNING_ARGS(fmt,n)
1057 # ifdef HAVE_VA_ARGS_MACRO
1058 # define WARNING_CALL(...) rb_funcall(__VA_ARGS__)
1060 # define WARNING_CALL rb_funcall
1062 PRINTF_ARGS
(static void ripper_compile_error
(struct parser_params
*, const char *fmt
, ...
), 2, 3);
1063 # define compile_error ripper_compile_error
1065 # define WARN_S_L(s,l) s
1066 # define WARN_S(s) s
1067 # define WARN_I(i) i
1068 # define WARN_ID(i) rb_id2name(i)
1069 # define WARN_IVAL(i) NUM2INT(i)
1070 # define PRIsWARN PRIsVALUE
1071 # define WARN_ARGS(fmt,n) WARN_ARGS_L(p->ruby_sourceline,fmt,n)
1072 # define WARN_ARGS_L(l,fmt,n) p->ruby_sourcefile, (l), (fmt)
1073 # define WARN_CALL rb_compile_warn
1074 # define rb_warn0L_experimental(l,fmt) rb_category_compile_warn(RB_WARN_CATEGORY_EXPERIMENTAL, WARN_ARGS_L(l, fmt, 1))
1075 # define WARNING_ARGS(fmt,n) WARN_ARGS(fmt,n)
1076 # define WARNING_ARGS_L(l,fmt,n) WARN_ARGS_L(l,fmt,n)
1077 # define WARNING_CALL rb_compile_warning
1078 PRINTF_ARGS
(static void parser_compile_error
(struct parser_params
*, const char *fmt
, ...
), 2, 3);
1079 # define compile_error parser_compile_error
1082 #define WARN_EOL(tok) \
1083 (looking_at_eol_p
(p
) ? \
1084 (void)rb_warning0
("`" tok
"' at the end of line without an expression") : \
1086 static int looking_at_eol_p
(struct parser_params
*p
);
1091 %define parse.
error verbose
1094 rb_parser_printf
(p
, "%"PRIsVALUE
, rb_id2str
($$
));
1096 rb_parser_printf
(p
, "%"PRIsVALUE
, RNODE
($$
)->nd_rval
);
1098 } tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL tOP_ASGN
1101 rb_parser_printf
(p
, "%+"PRIsVALUE
, $$
->nd_lit
);
1103 rb_parser_printf
(p
, "%+"PRIsVALUE
, get_value
($$
));
1105 } tINTEGER tFLOAT tRATIONAL tIMAGINARY tSTRING_CONTENT tCHAR
1108 rb_parser_printf
(p
, "$%ld", $$
->nd_nth
);
1110 rb_parser_printf
(p
, "%"PRIsVALUE
, $$
);
1115 rb_parser_printf
(p
, "$%c", (int)$$
->nd_nth
);
1117 rb_parser_printf
(p
, "%"PRIsVALUE
, $$
);
1121 %lex
-param
{struct parser_params
*p
}
1122 %parse
-param
{struct parser_params
*p
}
1125 RUBY_SET_YYLLOC_OF_NONE
(@$
);
1134 const struct vtable
*vars
;
1135 struct rb_strterm_struct
*strterm
;
1136 struct lex_context ctxt
;
1140 keyword_class
"`class'"
1141 keyword_module
"`module'"
1143 keyword_undef
"`undef'"
1144 keyword_begin
"`begin'"
1145 keyword_rescue
"`rescue'"
1146 keyword_ensure
"`ensure'"
1149 keyword_unless
"`unless'"
1150 keyword_then
"`then'"
1151 keyword_elsif
"`elsif'"
1152 keyword_else
"`else'"
1153 keyword_case
"`case'"
1154 keyword_when
"`when'"
1155 keyword_while
"`while'"
1156 keyword_until
"`until'"
1158 keyword_break
"`break'"
1159 keyword_next
"`next'"
1160 keyword_redo
"`redo'"
1161 keyword_retry
"`retry'"
1164 keyword_do_cond
"`do' for condition"
1165 keyword_do_block
"`do' for block"
1166 keyword_do_LAMBDA
"`do' for lambda"
1167 keyword_return
"`return'"
1168 keyword_yield
"`yield'"
1169 keyword_super
"`super'"
1170 keyword_self
"`self'"
1172 keyword_true
"`true'"
1173 keyword_false
"`false'"
1177 modifier_if
"`if' modifier"
1178 modifier_unless
"`unless' modifier"
1179 modifier_while
"`while' modifier"
1180 modifier_until
"`until' modifier"
1181 modifier_rescue
"`rescue' modifier"
1182 keyword_alias
"`alias'"
1183 keyword_defined
"`defined?'"
1184 keyword_BEGIN
"`BEGIN'"
1186 keyword__LINE__
"`__LINE__'"
1187 keyword__FILE__
"`__FILE__'"
1188 keyword__ENCODING__
"`__ENCODING__'"
1190 %token
<id
> tIDENTIFIER
"local variable or method"
1191 %token
<id
> tFID
"method"
1192 %token
<id
> tGVAR
"global variable"
1193 %token
<id
> tIVAR
"instance variable"
1194 %token
<id
> tCONSTANT
"constant"
1195 %token
<id
> tCVAR
"class variable"
1196 %token
<id
> tLABEL
"label"
1197 %token
<node
> tINTEGER
"integer literal"
1198 %token
<node
> tFLOAT
"float literal"
1199 %token
<node
> tRATIONAL
"rational literal"
1200 %token
<node
> tIMAGINARY
"imaginary literal"
1201 %token
<node
> tCHAR
"char literal"
1202 %token
<node
> tNTH_REF
"numbered reference"
1203 %token
<node
> tBACK_REF
"back reference"
1204 %token
<node
> tSTRING_CONTENT
"literal content"
1205 %token
<num
> tREGEXP_END
1207 %type
<node
> singleton strings
string string1 xstring regexp
1208 %type
<node
> string_contents xstring_contents regexp_contents string_content
1209 %type
<node
> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
1210 %type
<node
> literal numeric simple_numeric ssym dsym symbol cpath def_name defn_head defs_head
1211 %type
<node
> top_compstmt top_stmts top_stmt begin_block
1212 %type
<node
> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
1213 %type
<node
> expr_value expr_value_do arg_value primary_value fcall rel_expr
1214 %type
<node
> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
1215 %type
<node
> args call_args opt_call_args
1216 %type
<node
> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
1217 %type
<node
> command_args aref_args opt_block_arg block_arg var_ref var_lhs
1218 %type
<node
> command_rhs arg_rhs
1219 %type
<node
> command_asgn mrhs mrhs_arg superclass block_call block_command
1220 %type
<node
> f_block_optarg f_block_opt
1221 %type
<node
> f_arglist f_opt_paren_args f_paren_args f_args f_arg f_arg_item
1222 %type
<node
> f_optarg f_marg f_marg_list f_margs f_rest_marg
1223 %type
<node
> assoc_list assocs assoc undef_list backref string_dvar for_var
1224 %type
<node
> block_param opt_block_param block_param_def f_opt
1225 %type
<node
> f_kwarg f_kw f_block_kwarg f_block_kw
1226 %type
<node
> bv_decls opt_bv_decl bvar
1227 %type
<node
> lambda f_larglist lambda_body brace_body do_body
1228 %type
<node
> brace_block cmd_brace_block do_block lhs none fitem
1229 %type
<node
> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
1230 %type
<node
> p_case_body p_cases p_top_expr p_top_expr_body
1231 %type
<node
> p_expr p_as p_alt p_expr_basic p_find
1232 %type
<node
> p_args p_args_head p_args_tail p_args_post p_arg
1233 %type
<node
> p_value p_primitive p_variable p_var_ref p_expr_ref p_const
1234 %type
<node
> p_kwargs p_kwarg p_kw
1235 %type
<id
> keyword_variable user_variable sym operation operation2 operation3
1236 %type
<id
> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
1237 %type
<id
> f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon
1238 %type
<id
> p_rest p_kwrest p_kwnorest p_any_kwrest p_kw_label
1239 %type
<id
> f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var
1240 %type
<ctxt
> lex_ctxt
/* keep <ctxt> in ripper */
1241 %token END_OF_INPUT
0 "end-of-input"
1243 /* escaped chars, should be ignored otherwise */
1244 %token
<id
> '\\' "backslash"
1245 %token tSP
"escaped space"
1246 %token
<id
> '\t' "escaped horizontal tab"
1247 %token
<id
> '\f' "escaped form feed"
1248 %token
<id
> '\r' "escaped carriage return"
1249 %token
<id
> '\13' "escaped vertical tab"
1250 %token tUPLUS RUBY_TOKEN
(UPLUS
) "unary+"
1251 %token tUMINUS RUBY_TOKEN
(UMINUS
) "unary-"
1252 %token tPOW RUBY_TOKEN
(POW
) "**"
1253 %token tCMP RUBY_TOKEN
(CMP
) "<=>"
1254 %token tEQ RUBY_TOKEN
(EQ
) "=="
1255 %token tEQQ RUBY_TOKEN
(EQQ
) "==="
1256 %token tNEQ RUBY_TOKEN
(NEQ
) "!="
1257 %token tGEQ RUBY_TOKEN
(GEQ
) ">="
1258 %token tLEQ RUBY_TOKEN
(LEQ
) "<="
1259 %token tANDOP RUBY_TOKEN
(ANDOP
) "&&"
1260 %token tOROP RUBY_TOKEN
(OROP
) "||"
1261 %token tMATCH RUBY_TOKEN
(MATCH
) "=~"
1262 %token tNMATCH RUBY_TOKEN
(NMATCH
) "!~"
1263 %token tDOT2 RUBY_TOKEN
(DOT2
) ".."
1264 %token tDOT3 RUBY_TOKEN
(DOT3
) "..."
1265 %token tBDOT2 RUBY_TOKEN
(BDOT2
) "(.."
1266 %token tBDOT3 RUBY_TOKEN
(BDOT3
) "(..."
1267 %token tAREF RUBY_TOKEN
(AREF
) "[]"
1268 %token tASET RUBY_TOKEN
(ASET
) "[]="
1269 %token tLSHFT RUBY_TOKEN
(LSHFT
) "<<"
1270 %token tRSHFT RUBY_TOKEN
(RSHFT
) ">>"
1271 %token
<id
> tANDDOT RUBY_TOKEN
(ANDDOT
) "&."
1272 %token
<id
> tCOLON2 RUBY_TOKEN
(COLON2
) "::"
1273 %token tCOLON3
":: at EXPR_BEG"
1274 %token
<id
> tOP_ASGN
"operator-assignment" /* +=, -= etc. */
1277 %token tLPAREN_ARG
"( arg"
1281 %token tLBRACE_ARG
"{ arg"
1283 %token tDSTAR
"**arg"
1286 %token tSYMBEG
"symbol literal"
1287 %token tSTRING_BEG
"string literal"
1288 %token tXSTRING_BEG
"backtick literal"
1289 %token tREGEXP_BEG
"regexp literal"
1290 %token tWORDS_BEG
"word list"
1291 %token tQWORDS_BEG
"verbatim word list"
1292 %token tSYMBOLS_BEG
"symbol list"
1293 %token tQSYMBOLS_BEG
"verbatim symbol list"
1294 %token tSTRING_END
"terminator"
1295 %token tSTRING_DEND
"'}'"
1296 %token tSTRING_DBEG tSTRING_DVAR tLAMBEG tLABEL_END
1303 %nonassoc tLBRACE_ARG
1305 %nonassoc modifier_if modifier_unless modifier_while modifier_until keyword_in
1306 %left keyword_or keyword_and
1308 %nonassoc keyword_defined
1310 %left modifier_rescue
1312 %nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
1315 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
1316 %left
'>' tGEQ
'<' tLEQ
1322 %right tUMINUS_NUM tUMINUS
1324 %right
'!' '~' tUPLUS
1330 SET_LEX_STATE
(EXPR_BEG
);
1331 local_push
(p
, ifndef_ripper
(1)+0);
1336 if
($2 && !compile_for_eval
) {
1338 /* last expression should not be void */
1339 if
(nd_type_p
(node
, NODE_BLOCK
)) {
1340 while
(node
->nd_next
) {
1341 node
= node
->nd_next
;
1343 node
= node
->nd_head
;
1345 node
= remove_begin
(node
);
1348 p
->eval_tree
= NEW_SCOPE
(0, block_append
(p
, p
->eval_tree
, $2), &@$
);
1350 /*% ripper[final]: program!($2) %*/
1355 top_compstmt
: top_stmts opt_terms
1357 $$
= void_stmts
(p
, $1);
1364 $$
= NEW_BEGIN
(0, &@$
);
1366 /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
1371 $$
= newline_node
($1);
1373 /*% ripper: stmts_add!(stmts_new!, $1) %*/
1375 | top_stmts terms top_stmt
1378 $$
= block_append
(p
, $1, newline_node
($3));
1380 /*% ripper: stmts_add!($1, $3) %*/
1384 $$
= remove_begin
($2);
1389 | keyword_BEGIN begin_block
1395 begin_block
: '{' top_compstmt
'}'
1398 p
->eval_tree_begin
= block_append
(p
, p
->eval_tree_begin
,
1399 NEW_BEGIN
($2, &@$
));
1400 $$
= NEW_BEGIN
(0, &@$
);
1402 /*% ripper: BEGIN!($2) %*/
1408 k_else
{if
(!$2) {yyerror1
(&@
3, "else without rescue is useless");}}
1413 $$
= new_bodystmt
(p
, $1, $2, $5, $6, &@$
);
1415 /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), escape_Qundef($5), escape_Qundef($6)) %*/
1422 $$
= new_bodystmt
(p
, $1, $2, 0, $3, &@$
);
1424 /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), Qnil, escape_Qundef($3)) %*/
1428 compstmt
: stmts opt_terms
1430 $$
= void_stmts
(p
, $1);
1437 $$
= NEW_BEGIN
(0, &@$
);
1439 /*% ripper: stmts_add!(stmts_new!, void_stmt!) %*/
1444 $$
= newline_node
($1);
1446 /*% ripper: stmts_add!(stmts_new!, $1) %*/
1448 | stmts terms stmt_or_begin
1451 $$
= block_append
(p
, $1, newline_node
($3));
1453 /*% ripper: stmts_add!($1, $3) %*/
1457 $$
= remove_begin
($2);
1461 stmt_or_begin
: stmt
1467 yyerror1
(&@
1, "BEGIN is permitted only at toplevel");
1475 stmt
: keyword_alias fitem
{SET_LEX_STATE
(EXPR_FNAME|EXPR_FITEM
);} fitem
1478 $$
= NEW_ALIAS
($2, $4, &@$
);
1480 /*% ripper: alias!($2, $4) %*/
1482 | keyword_alias tGVAR tGVAR
1485 $$
= NEW_VALIAS
($2, $3, &@$
);
1487 /*% ripper: var_alias!($2, $3) %*/
1489 | keyword_alias tGVAR tBACK_REF
1494 buf
[1] = (char)$3->nd_nth
;
1495 $$
= NEW_VALIAS
($2, rb_intern2
(buf
, 2), &@$
);
1497 /*% ripper: var_alias!($2, $3) %*/
1499 | keyword_alias tGVAR tNTH_REF
1501 static const char mesg
[] = "can't make alias for the number variables";
1503 yyerror1
(&@
3, mesg
);
1504 $$
= NEW_BEGIN
(0, &@$
);
1506 /*% ripper[error]: alias_error!(ERR_MESG(), $3) %*/
1508 | keyword_undef undef_list
1513 /*% ripper: undef!($2) %*/
1515 | stmt modifier_if expr_value
1518 $$
= new_if
(p
, $3, remove_begin
($1), 0, &@$
);
1521 /*% ripper: if_mod!($3, $1) %*/
1523 | stmt modifier_unless expr_value
1526 $$
= new_unless
(p
, $3, remove_begin
($1), 0, &@$
);
1529 /*% ripper: unless_mod!($3, $1) %*/
1531 | stmt modifier_while expr_value
1534 if
($1 && nd_type_p
($1, NODE_BEGIN
)) {
1535 $$
= NEW_WHILE
(cond
(p
, $3, &@
3), $1->nd_body
, 0, &@$
);
1538 $$
= NEW_WHILE
(cond
(p
, $3, &@
3), $1, 1, &@$
);
1541 /*% ripper: while_mod!($3, $1) %*/
1543 | stmt modifier_until expr_value
1546 if
($1 && nd_type_p
($1, NODE_BEGIN
)) {
1547 $$
= NEW_UNTIL
(cond
(p
, $3, &@
3), $1->nd_body
, 0, &@$
);
1550 $$
= NEW_UNTIL
(cond
(p
, $3, &@
3), $1, 1, &@$
);
1553 /*% ripper: until_mod!($3, $1) %*/
1555 | stmt modifier_rescue stmt
1559 YYLTYPE loc
= code_loc_gen
(&@
2, &@
3);
1560 resq
= NEW_RESBODY
(0, remove_begin
($3), 0, &loc
);
1561 $$
= NEW_RESCUE
(remove_begin
($1), resq
, 0, &@$
);
1563 /*% ripper: rescue_mod!($1, $3) %*/
1565 | keyword_END
'{' compstmt
'}'
1567 if
(p
->ctxt.in_def
) {
1568 rb_warn0
("END in method; use at_exit");
1572 NODE
*scope
= NEW_NODE
(
1573 NODE_SCOPE
, 0 /* tbl */, $3 /* body */, 0 /* args */, &@$
);
1574 $$
= NEW_POSTEXE
(scope
, &@$
);
1577 /*% ripper: END!($3) %*/
1580 | mlhs
'=' lex_ctxt command_call
1584 $$
= node_assign
(p
, $1, $4, $3, &@$
);
1586 /*% ripper: massign!($1, $4) %*/
1588 | lhs
'=' lex_ctxt mrhs
1591 $$
= node_assign
(p
, $1, $4, $3, &@$
);
1593 /*% ripper: assign!($1, $4) %*/
1595 | mlhs
'=' lex_ctxt mrhs_arg modifier_rescue stmt
1598 YYLTYPE loc
= code_loc_gen
(&@
5, &@
6);
1599 $$
= node_assign
(p
, $1, NEW_RESCUE
($4, NEW_RESBODY
(0, remove_begin
($6), 0, &loc
), 0, &@$
), $3, &@$
);
1601 /*% ripper: massign!($1, rescue_mod!($4, $6)) %*/
1603 | mlhs
'=' lex_ctxt mrhs_arg
1606 $$
= node_assign
(p
, $1, $4, $3, &@$
);
1608 /*% ripper: massign!($1, $4) %*/
1613 command_asgn
: lhs
'=' lex_ctxt command_rhs
1616 $$
= node_assign
(p
, $1, $4, $3, &@$
);
1618 /*% ripper: assign!($1, $4) %*/
1620 | var_lhs tOP_ASGN lex_ctxt command_rhs
1623 $$
= new_op_assign
(p
, $1, $2, $4, $3, &@$
);
1625 /*% ripper: opassign!($1, $2, $4) %*/
1627 | primary_value
'[' opt_call_args rbracket tOP_ASGN lex_ctxt command_rhs
1630 $$
= new_ary_op_assign
(p
, $1, $3, $5, $7, &@
3, &@$
);
1632 /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/
1635 | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
1638 $$
= new_attr_op_assign
(p
, $1, $2, $3, $4, $6, &@$
);
1640 /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
1642 | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt command_rhs
1645 $$
= new_attr_op_assign
(p
, $1, $2, $3, $4, $6, &@$
);
1647 /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
1649 | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt command_rhs
1652 YYLTYPE loc
= code_loc_gen
(&@
1, &@
3);
1653 $$
= new_const_op_assign
(p
, NEW_COLON2
($1, $3, &loc
), $4, $6, $5, &@$
);
1655 /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
1657 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt command_rhs
1660 $$
= new_attr_op_assign
(p
, $1, ID2VAL
(idCOLON2
), $3, $4, $6, &@$
);
1662 /*% ripper: opassign!(field!($1, ID2VAL(idCOLON2), $3), $4, $6) %*/
1664 | defn_head f_opt_paren_args
'=' command
1666 endless_method_name
(p
, $
<node
>1, &@
1);
1667 restore_defun
(p
, $
<node
>1->nd_defn
);
1669 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
1671 /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
1672 /*% ripper: def!(get_value($1), $2, $4) %*/
1675 | defn_head f_opt_paren_args
'=' command modifier_rescue arg
1677 endless_method_name
(p
, $
<node
>1, &@
1);
1678 restore_defun
(p
, $
<node
>1->nd_defn
);
1680 $4 = rescued_expr
(p
, $4, $6, &@
4, &@
5, &@
6);
1681 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
1683 /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
1684 /*% ripper: def!(get_value($1), $2, $4) %*/
1687 | defs_head f_opt_paren_args
'=' command
1689 endless_method_name
(p
, $
<node
>1, &@
1);
1690 restore_defun
(p
, $
<node
>1->nd_defn
);
1692 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
1696 /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
1697 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
1700 | defs_head f_opt_paren_args
'=' command modifier_rescue arg
1702 endless_method_name
(p
, $
<node
>1, &@
1);
1703 restore_defun
(p
, $
<node
>1->nd_defn
);
1705 $4 = rescued_expr
(p
, $4, $6, &@
4, &@
5, &@
6);
1706 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
1710 /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
1711 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
1714 | backref tOP_ASGN lex_ctxt command_rhs
1717 rb_backref_error
(p
, $1);
1718 $$
= NEW_BEGIN
(0, &@$
);
1720 /*% ripper[error]: backref_error(p, RNODE($1), assign!(var_field(p, $1), $4)) %*/
1724 command_rhs
: command_call %prec tOP_ASGN
1729 | command_call modifier_rescue stmt
1732 YYLTYPE loc
= code_loc_gen
(&@
2, &@
3);
1734 $$
= NEW_RESCUE
($1, NEW_RESBODY
(0, remove_begin
($3), 0, &loc
), 0, &@$
);
1736 /*% ripper: rescue_mod!($1, $3) %*/
1742 | expr keyword_and expr
1744 $$
= logop
(p
, idAND
, $1, $3, &@
2, &@$
);
1746 | expr keyword_or expr
1748 $$
= logop
(p
, idOR
, $1, $3, &@
2, &@$
);
1750 | keyword_not opt_nl expr
1752 $$
= call_uni_op
(p
, method_cond
(p
, $3, &@
3), METHOD_NOT
, &@
1, &@$
);
1756 $$
= call_uni_op
(p
, method_cond
(p
, $2, &@
2), '!', &@
1, &@$
);
1761 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
1762 p
->command_start
= FALSE
;
1764 p
->ctxt.in_kwarg
= 1;
1765 $
<tbl
>$
= push_pvtbl
(p
);
1769 pop_pvtbl
(p
, $
<tbl
>3);
1770 p
->ctxt.in_kwarg
= $
<ctxt
>2.in_kwarg
;
1772 $$
= NEW_CASE3
($1, NEW_IN
($4, 0, 0, &@
4), &@$
);
1774 /*% ripper: case!($1, in!($4, Qnil, Qnil)) %*/
1779 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
1780 p
->command_start
= FALSE
;
1782 p
->ctxt.in_kwarg
= 1;
1783 $
<tbl
>$
= push_pvtbl
(p
);
1787 pop_pvtbl
(p
, $
<tbl
>3);
1788 p
->ctxt.in_kwarg
= $
<ctxt
>1.in_kwarg
;
1790 $$
= NEW_CASE3
($1, NEW_IN
($4, NEW_TRUE
(&@
4), NEW_FALSE
(&@
4), &@
4), &@$
);
1792 /*% ripper: case!($1, in!($4, Qnil, Qnil)) %*/
1794 | arg %prec tLBRACE_ARG
1799 ID fname
= get_id
($1);
1800 ID cur_arg
= p
->cur_arg
;
1801 YYSTYPE c
= {.ctxt
= p
->ctxt
};
1802 numparam_name
(p
, fname
);
1806 $
<node
>$
= NEW_NODE
(NODE_SELF
, /*vid*/cur_arg
, /*mid*/fname
, /*cval*/c.val
, &@$
);
1809 $$ = NEW_RIPPER(fname, get_value($1), $$, &NULL_LOC);
1814 defn_head
: k_def def_name
1818 $$
= NEW_NODE
(NODE_DEFN
, 0, $$
->nd_mid
, $$
, &@$
);
1823 defs_head
: k_def singleton dot_or_colon
1825 SET_LEX_STATE
(EXPR_FNAME
);
1826 p
->ctxt.in_argdef
= 1;
1830 SET_LEX_STATE
(EXPR_ENDFN|EXPR_LABEL
); /* force for args */
1833 $$
= NEW_NODE
(NODE_DEFS
, $2, $$
->nd_mid
, $$
, &@$
);
1835 VALUE ary = rb_ary_new_from_args(3, $2, $3, get_value($$));
1836 add_mark_object(p, ary);
1837 $<node>$->nd_rval = ary;
1849 expr_value_do
: {COND_PUSH
(1);} expr_value do
{COND_POP
();}
1855 command_call
: command
1859 block_command
: block_call
1860 | block_call call_op2 operation2 command_args
1863 $$
= new_qcall
(p
, $2, $1, $3, $4, &@
3, &@$
);
1865 /*% ripper: method_add_arg!(call!($1, $2, $3), $4) %*/
1869 cmd_brace_block
: tLBRACE_ARG brace_body
'}'
1873 $$
->nd_body
->nd_loc
= code_loc_gen
(&@
1, &@
3);
1874 nd_set_line
($$
, @
1.end_pos.lineno
);
1882 $$
= NEW_FCALL
($1, 0, &@$
);
1883 nd_set_line
($$
, p
->tokline
);
1889 command
: fcall command_args %prec tLOWEST
1893 nd_set_last_loc
($1, @
2.end_pos
);
1896 /*% ripper: command!($1, $2) %*/
1898 | fcall command_args cmd_brace_block
1901 block_dup_check
(p
, $2, $3);
1903 $$
= method_add_block
(p
, $1, $3, &@$
);
1905 nd_set_last_loc
($1, @
2.end_pos
);
1907 /*% ripper: method_add_block!(command!($1, $2), $3) %*/
1909 | primary_value call_op operation2 command_args %prec tLOWEST
1912 $$
= new_command_qcall
(p
, $2, $1, $3, $4, Qnull
, &@
3, &@$
);
1914 /*% ripper: command_call!($1, $2, $3, $4) %*/
1916 | primary_value call_op operation2 command_args cmd_brace_block
1919 $$
= new_command_qcall
(p
, $2, $1, $3, $4, $5, &@
3, &@$
);
1921 /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
1923 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1926 $$
= new_command_qcall
(p
, ID2VAL
(idCOLON2
), $1, $3, $4, Qnull
, &@
3, &@$
);
1928 /*% ripper: command_call!($1, ID2VAL(idCOLON2), $3, $4) %*/
1930 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1933 $$
= new_command_qcall
(p
, ID2VAL
(idCOLON2
), $1, $3, $4, $5, &@
3, &@$
);
1935 /*% ripper: method_add_block!(command_call!($1, ID2VAL(idCOLON2), $3, $4), $5) %*/
1937 | keyword_super command_args
1940 $$
= NEW_SUPER
($2, &@$
);
1943 /*% ripper: super!($2) %*/
1945 | keyword_yield command_args
1948 $$
= new_yield
(p
, $2, &@$
);
1951 /*% ripper: yield!($2) %*/
1953 | k_return call_args
1956 $$
= NEW_RETURN
(ret_args
(p
, $2), &@$
);
1958 /*% ripper: return!($2) %*/
1960 | keyword_break call_args
1963 $$
= NEW_BREAK
(ret_args
(p
, $2), &@$
);
1965 /*% ripper: break!($2) %*/
1967 | keyword_next call_args
1970 $$
= NEW_NEXT
(ret_args
(p
, $2), &@$
);
1972 /*% ripper: next!($2) %*/
1977 | tLPAREN mlhs_inner rparen
1982 /*% ripper: mlhs_paren!($2) %*/
1986 mlhs_inner
: mlhs_basic
1987 | tLPAREN mlhs_inner rparen
1990 $$
= NEW_MASGN
(NEW_LIST
($2, &@$
), 0, &@$
);
1992 /*% ripper: mlhs_paren!($2) %*/
1996 mlhs_basic
: mlhs_head
1999 $$
= NEW_MASGN
($1, 0, &@$
);
2003 | mlhs_head mlhs_item
2006 $$
= NEW_MASGN
(list_append
(p
, $1,$2), 0, &@$
);
2008 /*% ripper: mlhs_add!($1, $2) %*/
2010 | mlhs_head tSTAR mlhs_node
2013 $$
= NEW_MASGN
($1, $3, &@$
);
2015 /*% ripper: mlhs_add_star!($1, $3) %*/
2017 | mlhs_head tSTAR mlhs_node
',' mlhs_post
2020 $$
= NEW_MASGN
($1, NEW_POSTARG
($3,$5,&@$
), &@$
);
2022 /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
2027 $$
= NEW_MASGN
($1, NODE_SPECIAL_NO_NAME_REST
, &@$
);
2029 /*% ripper: mlhs_add_star!($1, Qnil) %*/
2031 | mlhs_head tSTAR
',' mlhs_post
2034 $$
= NEW_MASGN
($1, NEW_POSTARG
(NODE_SPECIAL_NO_NAME_REST
, $4, &@$
), &@$
);
2036 /*% ripper: mlhs_add_post!(mlhs_add_star!($1, Qnil), $4) %*/
2041 $$
= NEW_MASGN
(0, $2, &@$
);
2043 /*% ripper: mlhs_add_star!(mlhs_new!, $2) %*/
2045 | tSTAR mlhs_node
',' mlhs_post
2048 $$
= NEW_MASGN
(0, NEW_POSTARG
($2,$4,&@$
), &@$
);
2050 /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $2), $4) %*/
2055 $$
= NEW_MASGN
(0, NODE_SPECIAL_NO_NAME_REST
, &@$
);
2057 /*% ripper: mlhs_add_star!(mlhs_new!, Qnil) %*/
2059 | tSTAR
',' mlhs_post
2062 $$
= NEW_MASGN
(0, NEW_POSTARG
(NODE_SPECIAL_NO_NAME_REST
, $3, &@$
), &@$
);
2064 /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, Qnil), $3) %*/
2068 mlhs_item
: mlhs_node
2069 | tLPAREN mlhs_inner rparen
2074 /*% ripper: mlhs_paren!($2) %*/
2078 mlhs_head
: mlhs_item
','
2081 $$
= NEW_LIST
($1, &@
1);
2083 /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
2085 | mlhs_head mlhs_item
','
2088 $$
= list_append
(p
, $1, $2);
2090 /*% ripper: mlhs_add!($1, $2) %*/
2094 mlhs_post
: mlhs_item
2097 $$
= NEW_LIST
($1, &@$
);
2099 /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
2101 | mlhs_post
',' mlhs_item
2104 $$
= list_append
(p
, $1, $3);
2106 /*% ripper: mlhs_add!($1, $3) %*/
2110 mlhs_node
: user_variable
2113 $$
= assignable
(p
, $1, 0, &@$
);
2115 /*% ripper: assignable(p, var_field(p, $1)) %*/
2120 $$
= assignable
(p
, $1, 0, &@$
);
2122 /*% ripper: assignable(p, var_field(p, $1)) %*/
2124 | primary_value
'[' opt_call_args rbracket
2127 $$
= aryset
(p
, $1, $3, &@$
);
2129 /*% ripper: aref_field!($1, escape_Qundef($3)) %*/
2131 | primary_value call_op tIDENTIFIER
2133 if
($2 == tANDDOT
) {
2134 yyerror1
(&@
2, "&. inside multiple assignment destination");
2137 $$
= attrset
(p
, $1, $2, $3, &@$
);
2139 /*% ripper: field!($1, $2, $3) %*/
2141 | primary_value tCOLON2 tIDENTIFIER
2144 $$
= attrset
(p
, $1, idCOLON2
, $3, &@$
);
2146 /*% ripper: const_path_field!($1, $3) %*/
2148 | primary_value call_op tCONSTANT
2150 if
($2 == tANDDOT
) {
2151 yyerror1
(&@
2, "&. inside multiple assignment destination");
2154 $$
= attrset
(p
, $1, $2, $3, &@$
);
2156 /*% ripper: field!($1, $2, $3) %*/
2158 | primary_value tCOLON2 tCONSTANT
2161 $$
= const_decl
(p
, NEW_COLON2
($1, $3, &@$
), &@$
);
2163 /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
2168 $$
= const_decl
(p
, NEW_COLON3
($2, &@$
), &@$
);
2170 /*% ripper: const_decl(p, top_const_field!($2)) %*/
2175 rb_backref_error
(p
, $1);
2176 $$
= NEW_BEGIN
(0, &@$
);
2178 /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
2185 $$
= assignable
(p
, $1, 0, &@$
);
2187 /*% ripper: assignable(p, var_field(p, $1)) %*/
2192 $$
= assignable
(p
, $1, 0, &@$
);
2194 /*% ripper: assignable(p, var_field(p, $1)) %*/
2196 | primary_value
'[' opt_call_args rbracket
2199 $$
= aryset
(p
, $1, $3, &@$
);
2201 /*% ripper: aref_field!($1, escape_Qundef($3)) %*/
2203 | primary_value call_op tIDENTIFIER
2206 $$
= attrset
(p
, $1, $2, $3, &@$
);
2208 /*% ripper: field!($1, $2, $3) %*/
2210 | primary_value tCOLON2 tIDENTIFIER
2213 $$
= attrset
(p
, $1, idCOLON2
, $3, &@$
);
2215 /*% ripper: field!($1, ID2VAL(idCOLON2), $3) %*/
2217 | primary_value call_op tCONSTANT
2220 $$
= attrset
(p
, $1, $2, $3, &@$
);
2222 /*% ripper: field!($1, $2, $3) %*/
2224 | primary_value tCOLON2 tCONSTANT
2227 $$
= const_decl
(p
, NEW_COLON2
($1, $3, &@$
), &@$
);
2229 /*% ripper: const_decl(p, const_path_field!($1, $3)) %*/
2234 $$
= const_decl
(p
, NEW_COLON3
($2, &@$
), &@$
);
2236 /*% ripper: const_decl(p, top_const_field!($2)) %*/
2241 rb_backref_error
(p
, $1);
2242 $$
= NEW_BEGIN
(0, &@$
);
2244 /*% ripper[error]: backref_error(p, RNODE($1), var_field(p, $1)) %*/
2250 static const char mesg
[] = "class/module name must be CONSTANT";
2252 yyerror1
(&@
1, mesg
);
2254 /*% ripper[error]: class_name_error!(ERR_MESG(), $1) %*/
2259 cpath
: tCOLON3 cname
2262 $$
= NEW_COLON3
($2, &@$
);
2264 /*% ripper: top_const_ref!($2) %*/
2269 $$
= NEW_COLON2
(0, $$
, &@$
);
2271 /*% ripper: const_ref!($1) %*/
2273 | primary_value tCOLON2 cname
2276 $$
= NEW_COLON2
($1, $3, &@$
);
2278 /*% ripper: const_path_ref!($1, $3) %*/
2287 SET_LEX_STATE
(EXPR_ENDFN
);
2296 $$
= NEW_LIT
(ID2SYM
($1), &@$
);
2298 /*% ripper: symbol_literal!($1) %*/
2306 $$
= NEW_UNDEF
($1, &@$
);
2308 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
2310 | undef_list
',' {SET_LEX_STATE
(EXPR_FNAME|EXPR_FITEM
);} fitem
2313 NODE
*undef
= NEW_UNDEF
($4, &@
4);
2314 $$
= block_append
(p
, $1, undef
);
2316 /*% ripper: rb_ary_push($1, get_value($4)) %*/
2320 op
: '|' { ifndef_ripper
($$
= '|'); }
2321 |
'^' { ifndef_ripper
($$
= '^'); }
2322 |
'&' { ifndef_ripper
($$
= '&'); }
2323 | tCMP
{ ifndef_ripper
($$
= tCMP
); }
2324 | tEQ
{ ifndef_ripper
($$
= tEQ
); }
2325 | tEQQ
{ ifndef_ripper
($$
= tEQQ
); }
2326 | tMATCH
{ ifndef_ripper
($$
= tMATCH
); }
2327 | tNMATCH
{ ifndef_ripper
($$
= tNMATCH
); }
2328 |
'>' { ifndef_ripper
($$
= '>'); }
2329 | tGEQ
{ ifndef_ripper
($$
= tGEQ
); }
2330 |
'<' { ifndef_ripper
($$
= '<'); }
2331 | tLEQ
{ ifndef_ripper
($$
= tLEQ
); }
2332 | tNEQ
{ ifndef_ripper
($$
= tNEQ
); }
2333 | tLSHFT
{ ifndef_ripper
($$
= tLSHFT
); }
2334 | tRSHFT
{ ifndef_ripper
($$
= tRSHFT
); }
2335 |
'+' { ifndef_ripper
($$
= '+'); }
2336 |
'-' { ifndef_ripper
($$
= '-'); }
2337 |
'*' { ifndef_ripper
($$
= '*'); }
2338 | tSTAR
{ ifndef_ripper
($$
= '*'); }
2339 |
'/' { ifndef_ripper
($$
= '/'); }
2340 |
'%' { ifndef_ripper
($$
= '%'); }
2341 | tPOW
{ ifndef_ripper
($$
= tPOW
); }
2342 | tDSTAR
{ ifndef_ripper
($$
= tDSTAR
); }
2343 |
'!' { ifndef_ripper
($$
= '!'); }
2344 |
'~' { ifndef_ripper
($$
= '~'); }
2345 | tUPLUS
{ ifndef_ripper
($$
= tUPLUS
); }
2346 | tUMINUS
{ ifndef_ripper
($$
= tUMINUS
); }
2347 | tAREF
{ ifndef_ripper
($$
= tAREF
); }
2348 | tASET
{ ifndef_ripper
($$
= tASET
); }
2349 |
'`' { ifndef_ripper
($$
= '`'); }
2352 reswords
: keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
2353 | keyword_BEGIN | keyword_END
2354 | keyword_alias | keyword_and | keyword_begin
2355 | keyword_break | keyword_case | keyword_class | keyword_def
2356 | keyword_defined | keyword_do | keyword_else | keyword_elsif
2357 | keyword_end | keyword_ensure | keyword_false
2358 | keyword_for | keyword_in | keyword_module | keyword_next
2359 | keyword_nil | keyword_not | keyword_or | keyword_redo
2360 | keyword_rescue | keyword_retry | keyword_return | keyword_self
2361 | keyword_super | keyword_then | keyword_true | keyword_undef
2362 | keyword_when | keyword_yield | keyword_if | keyword_unless
2363 | keyword_while | keyword_until
2366 arg
: lhs
'=' lex_ctxt arg_rhs
2369 $$
= node_assign
(p
, $1, $4, $3, &@$
);
2371 /*% ripper: assign!($1, $4) %*/
2373 | var_lhs tOP_ASGN lex_ctxt arg_rhs
2376 $$
= new_op_assign
(p
, $1, $2, $4, $3, &@$
);
2378 /*% ripper: opassign!($1, $2, $4) %*/
2380 | primary_value
'[' opt_call_args rbracket tOP_ASGN lex_ctxt arg_rhs
2383 $$
= new_ary_op_assign
(p
, $1, $3, $5, $7, &@
3, &@$
);
2385 /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/
2387 | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
2390 $$
= new_attr_op_assign
(p
, $1, $2, $3, $4, $6, &@$
);
2392 /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
2394 | primary_value call_op tCONSTANT tOP_ASGN lex_ctxt arg_rhs
2397 $$
= new_attr_op_assign
(p
, $1, $2, $3, $4, $6, &@$
);
2399 /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/
2401 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs
2404 $$
= new_attr_op_assign
(p
, $1, ID2VAL
(idCOLON2
), $3, $4, $6, &@$
);
2406 /*% ripper: opassign!(field!($1, ID2VAL(idCOLON2), $3), $4, $6) %*/
2408 | primary_value tCOLON2 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
2411 YYLTYPE loc
= code_loc_gen
(&@
1, &@
3);
2412 $$
= new_const_op_assign
(p
, NEW_COLON2
($1, $3, &loc
), $4, $6, $5, &@$
);
2414 /*% ripper: opassign!(const_path_field!($1, $3), $4, $6) %*/
2416 | tCOLON3 tCONSTANT tOP_ASGN lex_ctxt arg_rhs
2419 YYLTYPE loc
= code_loc_gen
(&@
1, &@
2);
2420 $$
= new_const_op_assign
(p
, NEW_COLON3
($2, &loc
), $3, $5, $4, &@$
);
2422 /*% ripper: opassign!(top_const_field!($2), $3, $5) %*/
2424 | backref tOP_ASGN lex_ctxt arg_rhs
2427 rb_backref_error
(p
, $1);
2428 $$
= NEW_BEGIN
(0, &@$
);
2430 /*% ripper[error]: backref_error(p, RNODE($1), opassign!(var_field(p, $1), $2, $4)) %*/
2437 $$
= NEW_DOT2
($1, $3, &@$
);
2439 /*% ripper: dot2!($1, $3) %*/
2446 $$
= NEW_DOT3
($1, $3, &@$
);
2448 /*% ripper: dot3!($1, $3) %*/
2454 $$
= NEW_DOT2
($1, new_nil_at
(p
, &@
2.end_pos
), &@$
);
2456 /*% ripper: dot2!($1, Qnil) %*/
2462 $$
= NEW_DOT3
($1, new_nil_at
(p
, &@
2.end_pos
), &@$
);
2464 /*% ripper: dot3!($1, Qnil) %*/
2470 $$
= NEW_DOT2
(new_nil_at
(p
, &@
1.beg_pos
), $2, &@$
);
2472 /*% ripper: dot2!(Qnil, $2) %*/
2478 $$
= NEW_DOT3
(new_nil_at
(p
, &@
1.beg_pos
), $2, &@$
);
2480 /*% ripper: dot3!(Qnil, $2) %*/
2484 $$
= call_bin_op
(p
, $1, '+', $3, &@
2, &@$
);
2488 $$
= call_bin_op
(p
, $1, '-', $3, &@
2, &@$
);
2492 $$
= call_bin_op
(p
, $1, '*', $3, &@
2, &@$
);
2496 $$
= call_bin_op
(p
, $1, '/', $3, &@
2, &@$
);
2500 $$
= call_bin_op
(p
, $1, '%', $3, &@
2, &@$
);
2504 $$
= call_bin_op
(p
, $1, idPow
, $3, &@
2, &@$
);
2506 | tUMINUS_NUM simple_numeric tPOW arg
2508 $$
= call_uni_op
(p
, call_bin_op
(p
, $2, idPow
, $4, &@
2, &@$
), idUMinus
, &@
1, &@$
);
2512 $$
= call_uni_op
(p
, $2, idUPlus
, &@
1, &@$
);
2516 $$
= call_uni_op
(p
, $2, idUMinus
, &@
1, &@$
);
2520 $$
= call_bin_op
(p
, $1, '|', $3, &@
2, &@$
);
2524 $$
= call_bin_op
(p
, $1, '^', $3, &@
2, &@$
);
2528 $$
= call_bin_op
(p
, $1, '&', $3, &@
2, &@$
);
2532 $$
= call_bin_op
(p
, $1, idCmp
, $3, &@
2, &@$
);
2534 | rel_expr %prec tCMP
2537 $$
= call_bin_op
(p
, $1, idEq
, $3, &@
2, &@$
);
2541 $$
= call_bin_op
(p
, $1, idEqq
, $3, &@
2, &@$
);
2545 $$
= call_bin_op
(p
, $1, idNeq
, $3, &@
2, &@$
);
2549 $$
= match_op
(p
, $1, $3, &@
2, &@$
);
2553 $$
= call_bin_op
(p
, $1, idNeqTilde
, $3, &@
2, &@$
);
2557 $$
= call_uni_op
(p
, method_cond
(p
, $2, &@
2), '!', &@
1, &@$
);
2561 $$
= call_uni_op
(p
, $2, '~', &@
1, &@$
);
2565 $$
= call_bin_op
(p
, $1, idLTLT
, $3, &@
2, &@$
);
2569 $$
= call_bin_op
(p
, $1, idGTGT
, $3, &@
2, &@$
);
2573 $$
= logop
(p
, idANDOP
, $1, $3, &@
2, &@$
);
2577 $$
= logop
(p
, idOROP
, $1, $3, &@
2, &@$
);
2579 | keyword_defined opt_nl
{p
->ctxt.in_defined
= 1;} arg
2581 p
->ctxt.in_defined
= 0;
2582 $$
= new_defined
(p
, $4, &@$
);
2584 | arg
'?' arg opt_nl
':' arg
2588 $$
= new_if
(p
, $1, $3, $6, &@$
);
2591 /*% ripper: ifop!($1, $3, $6) %*/
2593 | defn_head f_opt_paren_args
'=' arg
2595 endless_method_name
(p
, $
<node
>1, &@
1);
2596 restore_defun
(p
, $
<node
>1->nd_defn
);
2598 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
2600 /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
2601 /*% ripper: def!(get_value($1), $2, $4) %*/
2604 | defn_head f_opt_paren_args
'=' arg modifier_rescue arg
2606 endless_method_name
(p
, $
<node
>1, &@
1);
2607 restore_defun
(p
, $
<node
>1->nd_defn
);
2609 $4 = rescued_expr
(p
, $4, $6, &@
4, &@
5, &@
6);
2610 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
2612 /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
2613 /*% ripper: def!(get_value($1), $2, $4) %*/
2616 | defs_head f_opt_paren_args
'=' arg
2618 endless_method_name
(p
, $
<node
>1, &@
1);
2619 restore_defun
(p
, $
<node
>1->nd_defn
);
2621 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
2625 /*% ripper[$4]: bodystmt!($4, Qnil, Qnil, Qnil) %*/
2626 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
2629 | defs_head f_opt_paren_args
'=' arg modifier_rescue arg
2631 endless_method_name
(p
, $
<node
>1, &@
1);
2632 restore_defun
(p
, $
<node
>1->nd_defn
);
2634 $4 = rescued_expr
(p
, $4, $6, &@
4, &@
5, &@
6);
2635 $$
= set_defun_body
(p
, $1, $2, $4, &@$
);
2639 /*% ripper[$4]: bodystmt!(rescue_mod!($4, $6), Qnil, Qnil, Qnil) %*/
2640 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/
2649 relop
: '>' {$$
= '>';}
2655 rel_expr
: arg relop arg %prec
'>'
2657 $$
= call_bin_op
(p
, $1, $2, $3, &@
2, &@$
);
2659 | rel_expr relop arg %prec
'>'
2661 rb_warning1
("comparison '%s' after comparison", WARN_ID
($2));
2662 $$
= call_bin_op
(p
, $1, $2, $3, &@
2, &@$
);
2688 | args
',' assocs trailer
2691 $$
= $3 ? arg_append
(p
, $1, new_hash
(p
, $3, &@
3), &@$
) : $1;
2693 /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
2698 $$
= $1 ? NEW_LIST
(new_hash
(p
, $1, &@
1), &@$
) : 0;
2700 /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
2704 arg_rhs
: arg %prec tOP_ASGN
2709 | arg modifier_rescue arg
2713 $$
= rescued_expr
(p
, $1, $3, &@
1, &@
2, &@
3);
2715 /*% ripper: rescue_mod!($1, $3) %*/
2719 paren_args
: '(' opt_call_args rparen
2724 /*% ripper: arg_paren!(escape_Qundef($2)) %*/
2726 |
'(' args
',' args_forward rparen
2728 if
(!check_forwarding_args
(p
)) {
2733 $$
= new_args_forward_call
(p
, $2, &@
4, &@$
);
2735 /*% ripper: arg_paren!(args_add!($2, $4)) %*/
2738 |
'(' args_forward rparen
2740 if
(!check_forwarding_args
(p
)) {
2745 $$
= new_args_forward_call
(p
, 0, &@
2, &@$
);
2747 /*% ripper: arg_paren!($2) %*/
2752 opt_paren_args
: none
2756 opt_call_args
: none
2762 | args
',' assocs
','
2765 $$
= $3 ? arg_append
(p
, $1, new_hash
(p
, $3, &@
3), &@$
) : $1;
2767 /*% ripper: args_add!($1, bare_assoc_hash!($3)) %*/
2772 $$
= $1 ? NEW_LIST
(new_hash
(p
, $1, &@
1), &@
1) : 0;
2774 /*% ripper: args_add!(args_new!, bare_assoc_hash!($1)) %*/
2782 $$
= NEW_LIST
($1, &@$
);
2784 /*% ripper: args_add!(args_new!, $1) %*/
2786 | args opt_block_arg
2789 $$
= arg_blk_pass
($1, $2);
2791 /*% ripper: args_add_block!($1, $2) %*/
2793 | assocs opt_block_arg
2796 $$
= $1 ? NEW_LIST
(new_hash
(p
, $1, &@
1), &@
1) : 0;
2797 $$
= arg_blk_pass
($$
, $2);
2799 /*% ripper: args_add_block!(args_add!(args_new!, bare_assoc_hash!($1)), $2) %*/
2801 | args
',' assocs opt_block_arg
2804 $$
= $3 ? arg_append
(p
, $1, new_hash
(p
, $3, &@
3), &@$
) : $1;
2805 $$
= arg_blk_pass
($$
, $4);
2807 /*% ripper: args_add_block!(args_add!($1, bare_assoc_hash!($3)), $4) %*/
2810 /*% ripper[brace]: args_add_block!(args_new!, $1) %*/
2814 /* If call_args starts with a open paren '(' or '[',
2815 * look-ahead reading of the letters calls CMDARG_PUSH(0),
2816 * but the push must be done after CMDARG_PUSH(1).
2817 * So this code makes them consistent by first cancelling
2818 * the premature CMDARG_PUSH(0), doing CMDARG_PUSH(1),
2819 * and finally redoing CMDARG_PUSH(0).
2823 case
'(': case tLPAREN
: case tLPAREN_ARG
: case
'[': case tLBRACK
:
2826 if
(lookahead
) CMDARG_POP
();
2828 if
(lookahead
) CMDARG_PUSH
(0);
2832 /* call_args can be followed by tLBRACE_ARG (that does CMDARG_PUSH(0) in the lexer)
2833 * but the push must be done after CMDARG_POP() in the parser.
2834 * So this code does CMDARG_POP() to pop 0 pushed by tLBRACE_ARG,
2835 * CMDARG_POP() to pop 1 pushed by command_args,
2836 * and CMDARG_PUSH(0) to restore back the flag set by tLBRACE_ARG.
2843 if
(lookahead
) CMDARG_POP
();
2845 if
(lookahead
) CMDARG_PUSH
(0);
2850 block_arg
: tAMPER arg_value
2853 $$
= NEW_BLOCK_PASS
($2, &@$
);
2860 if
(!local_id
(p
, ANON_BLOCK_ID
)) {
2861 compile_error
(p
, "no anonymous block parameter");
2863 $$
= NEW_BLOCK_PASS
(NEW_LVAR
(ANON_BLOCK_ID
, &@
1), &@$
);
2870 opt_block_arg
: ',' block_arg
2884 $$
= NEW_LIST
($1, &@$
);
2886 /*% ripper: args_add!(args_new!, $1) %*/
2891 $$
= NEW_SPLAT
($2, &@$
);
2893 /*% ripper: args_add_star!(args_new!, $2) %*/
2898 if
(!local_id
(p
, ANON_REST_ID
)) {
2899 compile_error
(p
, "no anonymous rest parameter");
2901 $$
= NEW_SPLAT
(NEW_LVAR
(ANON_REST_ID
, &@
1), &@$
);
2903 /*% ripper: args_add_star!(args_new!, Qnil) %*/
2905 | args
',' arg_value
2908 $$
= last_arg_append
(p
, $1, $3, &@$
);
2910 /*% ripper: args_add!($1, $3) %*/
2912 | args
',' tSTAR arg_value
2915 $$
= rest_arg_append
(p
, $1, $4, &@$
);
2917 /*% ripper: args_add_star!($1, $4) %*/
2922 if
(!local_id
(p
, ANON_REST_ID
)) {
2923 compile_error
(p
, "no anonymous rest parameter");
2925 $$
= rest_arg_append
(p
, $1, NEW_LVAR
(ANON_REST_ID
, &@
3), &@$
);
2927 /*% ripper: args_add_star!($1, Qnil) %*/
2937 mrhs
: args
',' arg_value
2940 $$
= last_arg_append
(p
, $1, $3, &@$
);
2942 /*% ripper: mrhs_add!(mrhs_new_from_args!($1), $3) %*/
2944 | args
',' tSTAR arg_value
2947 $$
= rest_arg_append
(p
, $1, $4, &@$
);
2949 /*% ripper: mrhs_add_star!(mrhs_new_from_args!($1), $4) %*/
2954 $$
= NEW_SPLAT
($2, &@$
);
2956 /*% ripper: mrhs_add_star!(mrhs_new!, $2) %*/
2973 $$
= NEW_FCALL
($1, 0, &@$
);
2975 /*% ripper: method_add_arg!(fcall!($1), args_new!) %*/
2986 set_line_body
($3, @
1.end_pos.lineno
);
2987 $$
= NEW_BEGIN
($3, &@$
);
2988 nd_set_line
($$
, @
1.end_pos.lineno
);
2990 /*% ripper: begin!($3) %*/
2992 | tLPAREN_ARG
{SET_LEX_STATE
(EXPR_ENDARG
);} rparen
2995 $$
= NEW_BEGIN
(0, &@$
);
2997 /*% ripper: paren!(0) %*/
2999 | tLPAREN_ARG stmt
{SET_LEX_STATE
(EXPR_ENDARG
);} rparen
3002 if
(nd_type_p
($2, NODE_SELF
)) $2->nd_state
= 0;
3005 /*% ripper: paren!($2) %*/
3007 | tLPAREN compstmt
')'
3010 if
(nd_type_p
($2, NODE_SELF
)) $2->nd_state
= 0;
3013 /*% ripper: paren!($2) %*/
3015 | primary_value tCOLON2 tCONSTANT
3018 $$
= NEW_COLON2
($1, $3, &@$
);
3020 /*% ripper: const_path_ref!($1, $3) %*/
3025 $$
= NEW_COLON3
($2, &@$
);
3027 /*% ripper: top_const_ref!($2) %*/
3029 | tLBRACK aref_args
']'
3032 $$
= make_list
($2, &@$
);
3034 /*% ripper: array!(escape_Qundef($2)) %*/
3036 | tLBRACE assoc_list
'}'
3039 $$
= new_hash
(p
, $2, &@$
);
3040 $$
->nd_brace
= TRUE
;
3042 /*% ripper: hash!(escape_Qundef($2)) %*/
3047 $$
= NEW_RETURN
(0, &@$
);
3049 /*% ripper: return0! %*/
3051 | keyword_yield
'(' call_args rparen
3054 $$
= new_yield
(p
, $3, &@$
);
3056 /*% ripper: yield!(paren!($3)) %*/
3058 | keyword_yield
'(' rparen
3061 $$
= NEW_YIELD
(0, &@$
);
3063 /*% ripper: yield!(paren!(args_new!)) %*/
3068 $$
= NEW_YIELD
(0, &@$
);
3070 /*% ripper: yield0! %*/
3072 | keyword_defined opt_nl
'(' {p
->ctxt.in_defined
= 1;} expr rparen
3074 p
->ctxt.in_defined
= 0;
3075 $$
= new_defined
(p
, $5, &@$
);
3077 | keyword_not
'(' expr rparen
3079 $$
= call_uni_op
(p
, method_cond
(p
, $3, &@
3), METHOD_NOT
, &@
1, &@$
);
3081 | keyword_not
'(' rparen
3083 $$
= call_uni_op
(p
, method_cond
(p
, new_nil
(&@
2), &@
2), METHOD_NOT
, &@
1, &@$
);
3088 $$
= method_add_block
(p
, $1, $2, &@$
);
3090 /*% ripper: method_add_block!(method_add_arg!(fcall!($1), args_new!), $2) %*/
3093 | method_call brace_block
3096 block_dup_check
(p
, $1->nd_args
, $2);
3097 $$
= method_add_block
(p
, $1, $2, &@$
);
3099 /*% ripper: method_add_block!($1, $2) %*/
3102 | k_if expr_value then
3108 $$
= new_if
(p
, $2, $4, $5, &@$
);
3111 /*% ripper: if!($2, $4, escape_Qundef($5)) %*/
3113 | k_unless expr_value then
3119 $$
= new_unless
(p
, $2, $4, $5, &@$
);
3122 /*% ripper: unless!($2, $4, escape_Qundef($5)) %*/
3124 | k_while expr_value_do
3129 $$
= NEW_WHILE
(cond
(p
, $2, &@
2), $3, 1, &@$
);
3132 /*% ripper: while!($2, $3) %*/
3134 | k_until expr_value_do
3139 $$
= NEW_UNTIL
(cond
(p
, $2, &@
2), $3, 1, &@$
);
3142 /*% ripper: until!($2, $3) %*/
3144 | k_case expr_value opt_terms
3146 $
<val
>$
= p
->case_labels
;
3147 p
->case_labels
= Qnil
;
3152 if
(RTEST
(p
->case_labels
)) rb_hash_clear
(p
->case_labels
);
3153 p
->case_labels
= $
<val
>4;
3155 $$
= NEW_CASE
($2, $5, &@$
);
3158 /*% ripper: case!($2, $5) %*/
3162 $
<val
>$
= p
->case_labels
;
3168 if
(RTEST
(p
->case_labels
)) rb_hash_clear
(p
->case_labels
);
3169 p
->case_labels
= $
<val
>3;
3171 $$
= NEW_CASE2
($4, &@$
);
3173 /*% ripper: case!(Qnil, $4) %*/
3175 | k_case expr_value opt_terms
3180 $$
= NEW_CASE3
($2, $4, &@$
);
3182 /*% ripper: case!($2, $4) %*/
3184 | k_for for_var keyword_in expr_value_do
3192 * e.each{|*x| a, b, c = x}
3196 * e.each{|x| a, = x}
3198 ID id
= internal_id
(p
);
3199 NODE
*m
= NEW_ARGS_AUX
(0, 0, &NULL_LOC
);
3200 NODE
*args
, *scope
, *internal_var
= NEW_DVAR
(id
, &@
2);
3201 rb_ast_id_table_t
*tbl
= rb_ast_new_local_table
(p
->ast
, 1);
3202 tbl
->ids
[0] = id
; /* internal id */
3204 switch
(nd_type
($2)) {
3206 case NODE_DASGN
: /* e.each {|internal_var| a = internal_var; ... } */
3207 $2->nd_value
= internal_var
;
3212 case NODE_MASGN
: /* e.each {|*internal_var| a, b, c = (internal_var.length == 1 && Array === (tmp = internal_var[0]) ? tmp : internal_var); ... } */
3213 m
->nd_next
= node_assign
(p
, $2, NEW_FOR_MASGN
(internal_var
, &@
2), NO_LEX_CTXT
, &@
2);
3215 default
: /* e.each {|*internal_var| @a, B, c[1], d.attr = internal_val; ... } */
3216 m
->nd_next
= node_assign
(p
, NEW_MASGN
(NEW_LIST
($2, &@
2), 0, &@
2), internal_var
, NO_LEX_CTXT
, &@
2);
3218 /* {|*internal_id| <m> = internal_id; ... } */
3219 args
= new_args
(p
, m
, 0, id
, 0, new_args_tail
(p
, 0, 0, 0, &@
2), &@
2);
3220 scope
= NEW_NODE
(NODE_SCOPE
, tbl
, $5, args
, &@$
);
3221 $$
= NEW_FOR
($4, scope
, &@$
);
3224 /*% ripper: for!($2, $4, $5) %*/
3226 | k_class cpath superclass
3228 if
(p
->ctxt.in_def
) {
3229 YYLTYPE loc
= code_loc_gen
(&@
1, &@
2);
3230 yyerror1
(&loc
, "class definition in method body");
3232 p
->ctxt.in_class
= 1;
3239 $$
= NEW_CLASS
($2, $5, $3, &@$
);
3240 nd_set_line
($$
->nd_body
, @
6.end_pos.lineno
);
3241 set_line_body
($5, @
3.end_pos.lineno
);
3242 nd_set_line
($$
, @
3.end_pos.lineno
);
3244 /*% ripper: class!($2, $3, $5) %*/
3246 p
->ctxt.in_class
= $
<ctxt
>1.in_class
;
3247 p
->ctxt.shareable_constant_value
= $
<ctxt
>1.shareable_constant_value
;
3249 | k_class tLSHFT expr
3252 p
->ctxt.in_class
= 0;
3260 $$
= NEW_SCLASS
($3, $6, &@$
);
3261 nd_set_line
($$
->nd_body
, @
7.end_pos.lineno
);
3262 set_line_body
($6, nd_line
($3));
3265 /*% ripper: sclass!($3, $6) %*/
3267 p
->ctxt.in_def
= $
<ctxt
>1.in_def
;
3268 p
->ctxt.in_class
= $
<ctxt
>1.in_class
;
3269 p
->ctxt.shareable_constant_value
= $
<ctxt
>1.shareable_constant_value
;
3273 if
(p
->ctxt.in_def
) {
3274 YYLTYPE loc
= code_loc_gen
(&@
1, &@
2);
3275 yyerror1
(&loc
, "module definition in method body");
3277 p
->ctxt.in_class
= 1;
3284 $$
= NEW_MODULE
($2, $4, &@$
);
3285 nd_set_line
($$
->nd_body
, @
5.end_pos.lineno
);
3286 set_line_body
($4, @
2.end_pos.lineno
);
3287 nd_set_line
($$
, @
2.end_pos.lineno
);
3289 /*% ripper: module!($2, $4) %*/
3291 p
->ctxt.in_class
= $
<ctxt
>1.in_class
;
3292 p
->ctxt.shareable_constant_value
= $
<ctxt
>1.shareable_constant_value
;
3299 restore_defun
(p
, $
<node
>1->nd_defn
);
3301 $$
= set_defun_body
(p
, $1, $2, $3, &@$
);
3303 /*% ripper: def!(get_value($1), $2, $3) %*/
3311 restore_defun
(p
, $
<node
>1->nd_defn
);
3313 $$
= set_defun_body
(p
, $1, $2, $3, &@$
);
3317 /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $3) %*/
3323 $$
= NEW_BREAK
(0, &@$
);
3325 /*% ripper: break!(args_new!) %*/
3330 $$
= NEW_NEXT
(0, &@$
);
3332 /*% ripper: next!(args_new!) %*/
3339 /*% ripper: redo! %*/
3344 $$
= NEW_RETRY
(&@$
);
3346 /*% ripper: retry! %*/
3350 primary_value
: primary
3357 k_begin
: keyword_begin
3359 token_info_push
(p
, "begin", &@$
);
3366 token_info_push
(p
, "if", &@$
);
3367 if
(p
->token_info
&& p
->token_info
->nonspc
&&
3368 p
->token_info
->next
&& !strcmp
(p
->token_info
->next
->token
, "else")) {
3369 const char *tok
= p
->lex.ptok
;
3370 const char *beg
= p
->lex.pbeg
+ p
->token_info
->next
->beg.column
;
3371 beg
+= rb_strlen_lit
("else");
3372 while
(beg
< tok
&& ISSPACE
(*beg
)) beg
++;
3374 p
->token_info
->nonspc
= 0;
3380 k_unless
: keyword_unless
3382 token_info_push
(p
, "unless", &@$
);
3386 k_while
: keyword_while
3388 token_info_push
(p
, "while", &@$
);
3392 k_until
: keyword_until
3394 token_info_push
(p
, "until", &@$
);
3398 k_case
: keyword_case
3400 token_info_push
(p
, "case", &@$
);
3406 token_info_push
(p
, "for", &@$
);
3410 k_class
: keyword_class
3412 token_info_push
(p
, "class", &@$
);
3417 k_module
: keyword_module
3419 token_info_push
(p
, "module", &@$
);
3426 token_info_push
(p
, "def", &@$
);
3427 p
->ctxt.in_argdef
= 1;
3433 token_info_push
(p
, "do", &@$
);
3437 k_do_block
: keyword_do_block
3439 token_info_push
(p
, "do", &@$
);
3443 k_rescue
: keyword_rescue
3445 token_info_warn
(p
, "rescue", p
->token_info
, 1, &@$
);
3449 k_ensure
: keyword_ensure
3451 token_info_warn
(p
, "ensure", p
->token_info
, 1, &@$
);
3455 k_when
: keyword_when
3457 token_info_warn
(p
, "when", p
->token_info
, 0, &@$
);
3461 k_else
: keyword_else
3463 token_info
*ptinfo_beg
= p
->token_info
;
3464 int same
= ptinfo_beg
&& strcmp
(ptinfo_beg
->token
, "case") != 0;
3465 token_info_warn
(p
, "else", p
->token_info
, same
, &@$
);
3468 e.next
= ptinfo_beg
->next
;
3470 token_info_setup
(&e
, p
->lex.pbeg
, &@$
);
3471 if
(!e.nonspc
) *ptinfo_beg
= e
;
3476 k_elsif
: keyword_elsif
3479 token_info_warn
(p
, "elsif", p
->token_info
, 1, &@$
);
3485 token_info_pop
(p
, "end", &@$
);
3489 k_return
: keyword_return
3491 if
(p
->ctxt.in_class
&& !p
->ctxt.in_def
&& !dyna_in_block
(p
))
3492 yyerror1
(&@
1, "Invalid return in class/module body");
3506 | k_elsif expr_value then
3511 $$
= new_if
(p
, $2, $4, $5, &@$
);
3514 /*% ripper: elsif!($2, $4, escape_Qundef($5)) %*/
3524 /*% ripper: else!($2) %*/
3535 $$
= assignable
(p
, $1, 0, &@$
);
3536 mark_lvar_used
(p
, $$
);
3538 /*% ripper: assignable(p, $1) %*/
3540 | tLPAREN f_margs rparen
3545 /*% ripper: mlhs_paren!($2) %*/
3549 f_marg_list
: f_marg
3552 $$
= NEW_LIST
($1, &@$
);
3554 /*% ripper: mlhs_add!(mlhs_new!, $1) %*/
3556 | f_marg_list
',' f_marg
3559 $$
= list_append
(p
, $1, $3);
3561 /*% ripper: mlhs_add!($1, $3) %*/
3565 f_margs
: f_marg_list
3568 $$
= NEW_MASGN
($1, 0, &@$
);
3572 | f_marg_list
',' f_rest_marg
3575 $$
= NEW_MASGN
($1, $3, &@$
);
3577 /*% ripper: mlhs_add_star!($1, $3) %*/
3579 | f_marg_list
',' f_rest_marg
',' f_marg_list
3582 $$
= NEW_MASGN
($1, NEW_POSTARG
($3, $5, &@$
), &@$
);
3584 /*% ripper: mlhs_add_post!(mlhs_add_star!($1, $3), $5) %*/
3589 $$
= NEW_MASGN
(0, $1, &@$
);
3591 /*% ripper: mlhs_add_star!(mlhs_new!, $1) %*/
3593 | f_rest_marg
',' f_marg_list
3596 $$
= NEW_MASGN
(0, NEW_POSTARG
($1, $3, &@$
), &@$
);
3598 /*% ripper: mlhs_add_post!(mlhs_add_star!(mlhs_new!, $1), $3) %*/
3602 f_rest_marg
: tSTAR f_norm_arg
3605 $$
= assignable
(p
, $2, 0, &@$
);
3606 mark_lvar_used
(p
, $$
);
3608 /*% ripper: assignable(p, $2) %*/
3613 $$
= NODE_SPECIAL_NO_NAME_REST
;
3615 /*% ripper: Qnil %*/
3619 f_any_kwrest
: f_kwrest
3620 | f_no_kwarg
{$$
= ID2VAL
(idNil
);}
3623 f_eq
: {p
->ctxt.in_argdef
= 0;} '=';
3625 block_args_tail
: f_block_kwarg
',' f_kwrest opt_f_block_arg
3627 $$
= new_args_tail
(p
, $1, $3, $4, &@
3);
3629 | f_block_kwarg opt_f_block_arg
3631 $$
= new_args_tail
(p
, $1, Qnone
, $2, &@
1);
3633 | f_any_kwrest opt_f_block_arg
3635 $$
= new_args_tail
(p
, Qnone
, $1, $2, &@
1);
3639 $$
= new_args_tail
(p
, Qnone
, Qnone
, $1, &@
1);
3643 opt_block_args_tail
: ',' block_args_tail
3649 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
0);
3653 excessed_comma
: ','
3655 /* magic number for rest_id in iseq_set_arguments() */
3657 $$
= NODE_SPECIAL_EXCESSIVE_COMMA
;
3659 /*% ripper: excessed_comma! %*/
3663 block_param
: f_arg
',' f_block_optarg
',' f_rest_arg opt_block_args_tail
3665 $$
= new_args
(p
, $1, $3, $5, Qnone
, $6, &@$
);
3667 | f_arg
',' f_block_optarg
',' f_rest_arg
',' f_arg opt_block_args_tail
3669 $$
= new_args
(p
, $1, $3, $5, $7, $8, &@$
);
3671 | f_arg
',' f_block_optarg opt_block_args_tail
3673 $$
= new_args
(p
, $1, $3, Qnone
, Qnone
, $4, &@$
);
3675 | f_arg
',' f_block_optarg
',' f_arg opt_block_args_tail
3677 $$
= new_args
(p
, $1, $3, Qnone
, $5, $6, &@$
);
3679 | f_arg
',' f_rest_arg opt_block_args_tail
3681 $$
= new_args
(p
, $1, Qnone
, $3, Qnone
, $4, &@$
);
3683 | f_arg excessed_comma
3685 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
2);
3686 $$
= new_args
(p
, $1, Qnone
, $2, Qnone
, $$
, &@$
);
3688 | f_arg
',' f_rest_arg
',' f_arg opt_block_args_tail
3690 $$
= new_args
(p
, $1, Qnone
, $3, $5, $6, &@$
);
3692 | f_arg opt_block_args_tail
3694 $$
= new_args
(p
, $1, Qnone
, Qnone
, Qnone
, $2, &@$
);
3696 | f_block_optarg
',' f_rest_arg opt_block_args_tail
3698 $$
= new_args
(p
, Qnone
, $1, $3, Qnone
, $4, &@$
);
3700 | f_block_optarg
',' f_rest_arg
',' f_arg opt_block_args_tail
3702 $$
= new_args
(p
, Qnone
, $1, $3, $5, $6, &@$
);
3704 | f_block_optarg opt_block_args_tail
3706 $$
= new_args
(p
, Qnone
, $1, Qnone
, Qnone
, $2, &@$
);
3708 | f_block_optarg
',' f_arg opt_block_args_tail
3710 $$
= new_args
(p
, Qnone
, $1, Qnone
, $3, $4, &@$
);
3712 | f_rest_arg opt_block_args_tail
3714 $$
= new_args
(p
, Qnone
, Qnone
, $1, Qnone
, $2, &@$
);
3716 | f_rest_arg
',' f_arg opt_block_args_tail
3718 $$
= new_args
(p
, Qnone
, Qnone
, $1, $3, $4, &@$
);
3722 $$
= new_args
(p
, Qnone
, Qnone
, Qnone
, Qnone
, $1, &@$
);
3726 opt_block_param
: none
3729 p
->command_start
= TRUE
;
3733 block_param_def
: '|' opt_bv_decl
'|'
3736 p
->max_numparam
= ORDINAL_PARAM
;
3737 p
->ctxt.in_argdef
= 0;
3741 /*% ripper: block_var!(params!(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil), escape_Qundef($2)) %*/
3743 |
'|' block_param opt_bv_decl
'|'
3746 p
->max_numparam
= ORDINAL_PARAM
;
3747 p
->ctxt.in_argdef
= 0;
3751 /*% ripper: block_var!(escape_Qundef($2), escape_Qundef($3)) %*/
3756 opt_bv_decl
: opt_nl
3760 | opt_nl
';' bv_decls opt_nl
3770 /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
3772 /*% ripper[brace]: rb_ary_push($1, get_value($3)) %*/
3777 new_bv
(p
, get_id
($1));
3778 /*% ripper: get_value($1) %*/
3788 token_info_push
(p
, "->", &@
1);
3789 $
<vars
>1 = dyna_push
(p
);
3790 $
<num
>$
= p
->lex.lpar_beg
;
3791 p
->lex.lpar_beg
= p
->lex.paren_nest
;
3794 $
<num
>$
= p
->max_numparam
;
3795 p
->max_numparam
= 0;
3798 $
<node
>$
= numparam_push
(p
);
3806 int max_numparam
= p
->max_numparam
;
3807 p
->lex.lpar_beg
= $
<num
>2;
3808 p
->max_numparam
= $
<num
>3;
3810 $5 = args_with_numbered
(p
, $5, max_numparam
);
3813 YYLTYPE loc
= code_loc_gen
(&@
5, &@
7);
3814 $$
= NEW_LAMBDA
($5, $7, &loc
);
3815 nd_set_line
($$
->nd_body
, @
7.end_pos.lineno
);
3816 nd_set_line
($$
, @
5.end_pos.lineno
);
3817 nd_set_first_loc
($$
, @
1.beg_pos
);
3820 /*% ripper: lambda!($5, $7) %*/
3821 numparam_pop
(p
, $
<node
>4);
3822 dyna_pop
(p
, $
<vars
>1);
3826 f_larglist
: '(' f_args opt_bv_decl
')'
3828 p
->ctxt.in_argdef
= 0;
3831 p
->max_numparam
= ORDINAL_PARAM
;
3833 /*% ripper: paren!($2) %*/
3837 p
->ctxt.in_argdef
= 0;
3839 if
(!args_info_empty_p
($1->nd_ainfo
))
3840 p
->max_numparam
= ORDINAL_PARAM
;
3846 lambda_body
: tLAMBEG compstmt
'}'
3848 token_info_pop
(p
, "}", &@
3);
3851 | keyword_do_LAMBDA bodystmt k_end
3857 do_block
: k_do_block do_body k_end
3861 $$
->nd_body
->nd_loc
= code_loc_gen
(&@
1, &@
3);
3862 nd_set_line
($$
, @
1.end_pos.lineno
);
3867 block_call
: command do_block
3870 if
(nd_type_p
($1, NODE_YIELD
)) {
3871 compile_error
(p
, "block given to yield");
3874 block_dup_check
(p
, $1->nd_args
, $2);
3876 $$
= method_add_block
(p
, $1, $2, &@$
);
3879 /*% ripper: method_add_block!($1, $2) %*/
3881 | block_call call_op2 operation2 opt_paren_args
3884 $$
= new_qcall
(p
, $2, $1, $3, $4, &@
3, &@$
);
3886 /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
3888 | block_call call_op2 operation2 opt_paren_args brace_block
3891 $$
= new_command_qcall
(p
, $2, $1, $3, $4, $5, &@
3, &@$
);
3893 /*% ripper: opt_event(:method_add_block!, command_call!($1, $2, $3, $4), $5) %*/
3895 | block_call call_op2 operation2 command_args do_block
3898 $$
= new_command_qcall
(p
, $2, $1, $3, $4, $5, &@
3, &@$
);
3900 /*% ripper: method_add_block!(command_call!($1, $2, $3, $4), $5) %*/
3904 method_call
: fcall paren_args
3909 nd_set_last_loc
($1, @
2.end_pos
);
3911 /*% ripper: method_add_arg!(fcall!($1), $2) %*/
3913 | primary_value call_op operation2 opt_paren_args
3916 $$
= new_qcall
(p
, $2, $1, $3, $4, &@
3, &@$
);
3917 nd_set_line
($$
, @
3.end_pos.lineno
);
3919 /*% ripper: opt_event(:method_add_arg!, call!($1, $2, $3), $4) %*/
3921 | primary_value tCOLON2 operation2 paren_args
3924 $$
= new_qcall
(p
, ID2VAL
(idCOLON2
), $1, $3, $4, &@
3, &@$
);
3925 nd_set_line
($$
, @
3.end_pos.lineno
);
3927 /*% ripper: method_add_arg!(call!($1, ID2VAL(idCOLON2), $3), $4) %*/
3929 | primary_value tCOLON2 operation3
3932 $$
= new_qcall
(p
, ID2VAL
(idCOLON2
), $1, $3, Qnull
, &@
3, &@$
);
3934 /*% ripper: call!($1, ID2VAL(idCOLON2), $3) %*/
3936 | primary_value call_op paren_args
3939 $$
= new_qcall
(p
, $2, $1, ID2VAL
(idCall
), $3, &@
2, &@$
);
3940 nd_set_line
($$
, @
2.end_pos.lineno
);
3942 /*% ripper: method_add_arg!(call!($1, $2, ID2VAL(idCall)), $3) %*/
3944 | primary_value tCOLON2 paren_args
3947 $$
= new_qcall
(p
, ID2VAL
(idCOLON2
), $1, ID2VAL
(idCall
), $3, &@
2, &@$
);
3948 nd_set_line
($$
, @
2.end_pos.lineno
);
3950 /*% ripper: method_add_arg!(call!($1, ID2VAL(idCOLON2), ID2VAL(idCall)), $3) %*/
3952 | keyword_super paren_args
3955 $$
= NEW_SUPER
($2, &@$
);
3957 /*% ripper: super!($2) %*/
3962 $$
= NEW_ZSUPER
(&@$
);
3964 /*% ripper: zsuper! %*/
3966 | primary_value
'[' opt_call_args rbracket
3969 if
($1 && nd_type_p
($1, NODE_SELF
))
3970 $$
= NEW_FCALL
(tAREF
, $3, &@$
);
3972 $$
= NEW_CALL
($1, tAREF
, $3, &@$
);
3975 /*% ripper: aref!($1, escape_Qundef($3)) %*/
3979 brace_block
: '{' brace_body
'}'
3983 $$
->nd_body
->nd_loc
= code_loc_gen
(&@
1, &@
3);
3984 nd_set_line
($$
, @
1.end_pos.lineno
);
3987 | k_do do_body k_end
3991 $$
->nd_body
->nd_loc
= code_loc_gen
(&@
1, &@
3);
3992 nd_set_line
($$
, @
1.end_pos.lineno
);
3997 brace_body
: {$
<vars
>$
= dyna_push
(p
);}
3999 $
<num
>$
= p
->max_numparam
;
4000 p
->max_numparam
= 0;
4003 $
<node
>$
= numparam_push
(p
);
4005 opt_block_param compstmt
4007 int max_numparam
= p
->max_numparam
;
4008 p
->max_numparam
= $
<num
>2;
4009 $4 = args_with_numbered
(p
, $4, max_numparam
);
4011 $$
= NEW_ITER
($4, $5, &@$
);
4013 /*% ripper: brace_block!(escape_Qundef($4), $5) %*/
4014 numparam_pop
(p
, $
<node
>3);
4015 dyna_pop
(p
, $
<vars
>1);
4019 do_body
: {$
<vars
>$
= dyna_push
(p
);}
4021 $
<num
>$
= p
->max_numparam
;
4022 p
->max_numparam
= 0;
4025 $
<node
>$
= numparam_push
(p
);
4028 opt_block_param bodystmt
4030 int max_numparam
= p
->max_numparam
;
4031 p
->max_numparam
= $
<num
>2;
4032 $4 = args_with_numbered
(p
, $4, max_numparam
);
4034 $$
= NEW_ITER
($4, $5, &@$
);
4036 /*% ripper: do_block!(escape_Qundef($4), $5) %*/
4038 numparam_pop
(p
, $
<node
>3);
4039 dyna_pop
(p
, $
<vars
>1);
4043 case_args
: arg_value
4046 check_literal_when
(p
, $1, &@
1);
4047 $$
= NEW_LIST
($1, &@$
);
4049 /*% ripper: args_add!(args_new!, $1) %*/
4054 $$
= NEW_SPLAT
($2, &@$
);
4056 /*% ripper: args_add_star!(args_new!, $2) %*/
4058 | case_args
',' arg_value
4061 check_literal_when
(p
, $3, &@
3);
4062 $$
= last_arg_append
(p
, $1, $3, &@$
);
4064 /*% ripper: args_add!($1, $3) %*/
4066 | case_args
',' tSTAR arg_value
4069 $$
= rest_arg_append
(p
, $1, $4, &@$
);
4071 /*% ripper: args_add_star!($1, $4) %*/
4075 case_body
: k_when case_args then
4080 $$
= NEW_WHEN
($2, $4, $5, &@$
);
4083 /*% ripper: when!($2, $4, escape_Qundef($5)) %*/
4091 p_case_body
: keyword_in
4093 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
4094 p
->command_start
= FALSE
;
4096 p
->ctxt.in_kwarg
= 1;
4097 $
<tbl
>$
= push_pvtbl
(p
);
4100 $
<tbl
>$
= push_pktbl
(p
);
4104 pop_pktbl
(p
, $
<tbl
>3);
4105 pop_pvtbl
(p
, $
<tbl
>2);
4106 p
->ctxt.in_kwarg
= $
<ctxt
>1.in_kwarg
;
4112 $$
= NEW_IN
($4, $7, $8, &@$
);
4114 /*% ripper: in!($4, $7, escape_Qundef($8)) %*/
4122 p_top_expr
: p_top_expr_body
4123 | p_top_expr_body modifier_if expr_value
4126 $$
= new_if
(p
, $3, $1, 0, &@$
);
4129 /*% ripper: if_mod!($3, $1) %*/
4131 | p_top_expr_body modifier_unless expr_value
4134 $$
= new_unless
(p
, $3, $1, 0, &@$
);
4137 /*% ripper: unless_mod!($3, $1) %*/
4141 p_top_expr_body
: p_expr
4144 $$
= new_array_pattern_tail
(p
, Qnone
, 1, 0, Qnone
, &@$
);
4145 $$
= new_array_pattern
(p
, Qnone
, get_value
($1), $$
, &@$
);
4149 $$
= new_array_pattern
(p
, Qnone
, get_value
($1), $3, &@$
);
4151 nd_set_first_loc
($$
, @
1.beg_pos
);
4157 $$
= new_find_pattern
(p
, Qnone
, $1, &@$
);
4161 $$
= new_array_pattern
(p
, Qnone
, Qnone
, $1, &@$
);
4165 $$
= new_hash_pattern
(p
, Qnone
, $1, &@$
);
4172 p_as
: p_expr tASSOC p_variable
4175 NODE
*n
= NEW_LIST
($1, &@$
);
4176 n
= list_append
(p
, n
, $3);
4177 $$
= new_hash
(p
, n
, &@$
);
4179 /*% ripper: binary!($1, STATIC_ID2SYM((id_assoc)), $3) %*/
4184 p_alt
: p_alt
'|' p_expr_basic
4187 $$
= NEW_NODE
(NODE_OR
, $1, $3, 0, &@$
);
4189 /*% ripper: binary!($1, STATIC_ID2SYM(idOr), $3) %*/
4194 p_lparen
: '(' {$
<tbl
>$
= push_pktbl
(p
);};
4195 p_lbracket
: '[' {$
<tbl
>$
= push_pktbl
(p
);};
4197 p_expr_basic
: p_value
4199 | p_const p_lparen p_args rparen
4201 pop_pktbl
(p
, $
<tbl
>2);
4202 $$
= new_array_pattern
(p
, $1, Qnone
, $3, &@$
);
4204 nd_set_first_loc
($$
, @
1.beg_pos
);
4208 | p_const p_lparen p_find rparen
4210 pop_pktbl
(p
, $
<tbl
>2);
4211 $$
= new_find_pattern
(p
, $1, $3, &@$
);
4213 nd_set_first_loc
($$
, @
1.beg_pos
);
4217 | p_const p_lparen p_kwargs rparen
4219 pop_pktbl
(p
, $
<tbl
>2);
4220 $$
= new_hash_pattern
(p
, $1, $3, &@$
);
4222 nd_set_first_loc
($$
, @
1.beg_pos
);
4226 | p_const
'(' rparen
4228 $$
= new_array_pattern_tail
(p
, Qnone
, 0, 0, Qnone
, &@$
);
4229 $$
= new_array_pattern
(p
, $1, Qnone
, $$
, &@$
);
4231 | p_const p_lbracket p_args rbracket
4233 pop_pktbl
(p
, $
<tbl
>2);
4234 $$
= new_array_pattern
(p
, $1, Qnone
, $3, &@$
);
4236 nd_set_first_loc
($$
, @
1.beg_pos
);
4240 | p_const p_lbracket p_find rbracket
4242 pop_pktbl
(p
, $
<tbl
>2);
4243 $$
= new_find_pattern
(p
, $1, $3, &@$
);
4245 nd_set_first_loc
($$
, @
1.beg_pos
);
4249 | p_const p_lbracket p_kwargs rbracket
4251 pop_pktbl
(p
, $
<tbl
>2);
4252 $$
= new_hash_pattern
(p
, $1, $3, &@$
);
4254 nd_set_first_loc
($$
, @
1.beg_pos
);
4258 | p_const
'[' rbracket
4260 $$
= new_array_pattern_tail
(p
, Qnone
, 0, 0, Qnone
, &@$
);
4261 $$
= new_array_pattern
(p
, $1, Qnone
, $$
, &@$
);
4263 | tLBRACK p_args rbracket
4265 $$
= new_array_pattern
(p
, Qnone
, Qnone
, $2, &@$
);
4267 | tLBRACK p_find rbracket
4269 $$
= new_find_pattern
(p
, Qnone
, $2, &@$
);
4273 $$
= new_array_pattern_tail
(p
, Qnone
, 0, 0, Qnone
, &@$
);
4274 $$
= new_array_pattern
(p
, Qnone
, Qnone
, $$
, &@$
);
4278 $
<tbl
>$
= push_pktbl
(p
);
4280 p
->ctxt.in_kwarg
= 0;
4284 pop_pktbl
(p
, $
<tbl
>2);
4285 p
->ctxt.in_kwarg
= $
<ctxt
>1.in_kwarg
;
4286 $$
= new_hash_pattern
(p
, Qnone
, $3, &@$
);
4290 $$
= new_hash_pattern_tail
(p
, Qnone
, 0, &@$
);
4291 $$
= new_hash_pattern
(p
, Qnone
, $$
, &@$
);
4293 | tLPAREN
{$
<tbl
>$
= push_pktbl
(p
);} p_expr rparen
4295 pop_pktbl
(p
, $
<tbl
>2);
4303 NODE
*pre_args
= NEW_LIST
($1, &@$
);
4304 $$
= new_array_pattern_tail
(p
, pre_args
, 0, 0, Qnone
, &@$
);
4306 $$ = new_array_pattern_tail(p, rb_ary_new_from_args(1, get_value($1)), 0, 0, Qnone, &@$);
4311 $$
= new_array_pattern_tail
(p
, $1, 1, 0, Qnone
, &@$
);
4316 $$
= new_array_pattern_tail
(p
, list_concat
($1, $2), 0, 0, Qnone
, &@$
);
4318 VALUE pre_args = rb_ary_concat($1, get_value($2));
4319 $$ = new_array_pattern_tail(p, pre_args, 0, 0, Qnone, &@$);
4322 | p_args_head tSTAR tIDENTIFIER
4324 $$
= new_array_pattern_tail
(p
, $1, 1, $3, Qnone
, &@$
);
4326 | p_args_head tSTAR tIDENTIFIER
',' p_args_post
4328 $$
= new_array_pattern_tail
(p
, $1, 1, $3, $5, &@$
);
4332 $$
= new_array_pattern_tail
(p
, $1, 1, 0, Qnone
, &@$
);
4334 | p_args_head tSTAR
',' p_args_post
4336 $$
= new_array_pattern_tail
(p
, $1, 1, 0, $4, &@$
);
4341 p_args_head
: p_arg
','
4345 | p_args_head p_arg
','
4348 $$
= list_concat
($1, $2);
4350 /*% ripper: rb_ary_concat($1, get_value($2)) %*/
4354 p_args_tail
: p_rest
4356 $$
= new_array_pattern_tail
(p
, Qnone
, 1, $1, Qnone
, &@$
);
4358 | p_rest
',' p_args_post
4360 $$
= new_array_pattern_tail
(p
, Qnone
, 1, $1, $3, &@$
);
4364 p_find
: p_rest
',' p_args_post
',' p_rest
4366 $$
= new_find_pattern_tail
(p
, $1, $3, $5, &@$
);
4368 if
(rb_warning_category_enabled_p
(RB_WARN_CATEGORY_EXPERIMENTAL
))
4369 rb_warn0L_experimental
(nd_line
($$
), "Find pattern is experimental, and the behavior may change in future versions of Ruby!");
4374 p_rest
: tSTAR tIDENTIFIER
4385 | p_args_post
',' p_arg
4388 $$
= list_concat
($1, $3);
4390 /*% ripper: rb_ary_concat($1, get_value($3)) %*/
4397 $$
= NEW_LIST
($1, &@$
);
4399 /*% ripper: rb_ary_new_from_args(1, get_value($1)) %*/
4403 p_kwargs
: p_kwarg
',' p_any_kwrest
4405 $$
= new_hash_pattern_tail
(p
, new_unique_key_hash
(p
, $1, &@$
), $3, &@$
);
4409 $$
= new_hash_pattern_tail
(p
, new_unique_key_hash
(p
, $1, &@$
), 0, &@$
);
4413 $$
= new_hash_pattern_tail
(p
, new_unique_key_hash
(p
, $1, &@$
), 0, &@$
);
4417 $$
= new_hash_pattern_tail
(p
, new_hash
(p
, Qnone
, &@$
), $1, &@$
);
4422 /*% ripper[brace]: rb_ary_new_from_args(1, $1) %*/
4426 $$
= list_concat
($1, $3);
4428 /*% ripper: rb_ary_push($1, $3) %*/
4432 p_kw
: p_kw_label p_expr
4434 error_duplicate_pattern_key
(p
, get_id
($1), &@
1);
4436 $$
= list_append
(p
, NEW_LIST
(NEW_LIT
(ID2SYM
($1), &@$
), &@$
), $2);
4438 /*% ripper: rb_ary_new_from_args(2, get_value($1), get_value($2)) %*/
4442 error_duplicate_pattern_key
(p
, get_id
($1), &@
1);
4443 if
($1 && !is_local_id
(get_id
($1))) {
4444 yyerror1
(&@
1, "key must be valid as local variables");
4446 error_duplicate_pattern_variable
(p
, get_id
($1), &@
1);
4448 $$
= list_append
(p
, NEW_LIST
(NEW_LIT
(ID2SYM
($1), &@$
), &@$
), assignable
(p
, $1, 0, &@$
));
4450 /*% ripper: rb_ary_new_from_args(2, get_value($1), Qnil) %*/
4455 | tSTRING_BEG string_contents tLABEL_END
4457 YYLTYPE loc
= code_loc_gen
(&@
1, &@
3);
4459 if
(!$2 || nd_type_p
($2, NODE_STR
)) {
4460 NODE
*node
= dsym_node
(p
, $2, &loc
);
4461 $$
= SYM2ID
(node
->nd_lit
);
4464 if (ripper_is_node_yylval($2) && RNODE($2)->nd_cval) {
4465 VALUE label = RNODE($2)->nd_cval;
4466 VALUE rval = RNODE($2)->nd_rval;
4467 $$ = ripper_new_yylval(p, rb_intern_str(label), rval, label);
4468 RNODE($$)->nd_loc = loc;
4472 yyerror1
(&loc
, "symbol literal with interpolation is not allowed");
4478 p_kwrest
: kwrest_mark tIDENTIFIER
4488 p_kwnorest
: kwrest_mark keyword_nil
4494 p_any_kwrest
: p_kwrest
4495 | p_kwnorest
{$$
= ID2VAL
(idNil
);}
4498 p_value
: p_primitive
4499 | p_primitive tDOT2 p_primitive
4504 $$
= NEW_DOT2
($1, $3, &@$
);
4506 /*% ripper: dot2!($1, $3) %*/
4508 | p_primitive tDOT3 p_primitive
4513 $$
= NEW_DOT3
($1, $3, &@$
);
4515 /*% ripper: dot3!($1, $3) %*/
4521 $$
= NEW_DOT2
($1, new_nil_at
(p
, &@
2.end_pos
), &@$
);
4523 /*% ripper: dot2!($1, Qnil) %*/
4529 $$
= NEW_DOT3
($1, new_nil_at
(p
, &@
2.end_pos
), &@$
);
4531 /*% ripper: dot3!($1, Qnil) %*/
4536 | tBDOT2 p_primitive
4540 $$
= NEW_DOT2
(new_nil_at
(p
, &@
1.beg_pos
), $2, &@$
);
4542 /*% ripper: dot2!(Qnil, $2) %*/
4544 | tBDOT3 p_primitive
4548 $$
= NEW_DOT3
(new_nil_at
(p
, &@
1.beg_pos
), $2, &@$
);
4550 /*% ripper: dot3!(Qnil, $2) %*/
4554 p_primitive
: literal
4565 if
(!($$
= gettable
(p
, $1, &@$
))) $$
= NEW_BEGIN
(0, &@$
);
4567 /*% ripper: var_ref!($1) %*/
4572 p_variable
: tIDENTIFIER
4575 error_duplicate_pattern_variable
(p
, $1, &@
1);
4576 $$
= assignable
(p
, $1, 0, &@$
);
4578 /*% ripper: assignable(p, var_field(p, $1)) %*/
4582 p_var_ref
: '^' tIDENTIFIER
4585 NODE
*n
= gettable
(p
, $2, &@$
);
4586 if
(!(nd_type_p
(n
, NODE_LVAR
) || nd_type_p
(n
, NODE_DVAR
))) {
4587 compile_error
(p
, "%"PRIsVALUE
": no such local variable", rb_id2str
($2));
4591 /*% ripper: var_ref!($2) %*/
4596 if
(!($$
= gettable
(p
, $2, &@$
))) $$
= NEW_BEGIN
(0, &@$
);
4598 /*% ripper: var_ref!($2) %*/
4602 p_expr_ref
: '^' tLPAREN expr_value
')'
4605 $$
= NEW_BEGIN
($3, &@$
);
4607 /*% ripper: begin!($3) %*/
4611 p_const
: tCOLON3 cname
4614 $$
= NEW_COLON3
($2, &@$
);
4616 /*% ripper: top_const_ref!($2) %*/
4618 | p_const tCOLON2 cname
4621 $$
= NEW_COLON2
($1, $3, &@$
);
4623 /*% ripper: const_path_ref!($1, $3) %*/
4628 $$
= gettable
(p
, $1, &@$
);
4630 /*% ripper: var_ref!($1) %*/
4634 opt_rescue
: k_rescue exc_list exc_var then
4639 $$
= NEW_RESBODY
($2,
4640 $3 ? block_append
(p
, node_assign
(p
, $3, NEW_ERRINFO
(&@
3), NO_LEX_CTXT
, &@
3), $5) : $5,
4642 fixpos
($$
, $2?
$2:$5);
4644 /*% ripper: rescue!(escape_Qundef($2), escape_Qundef($3), escape_Qundef($5), escape_Qundef($6)) %*/
4649 exc_list
: arg_value
4652 $$
= NEW_LIST
($1, &@$
);
4654 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
4659 if
(!($$
= splat_array
($1))) $$
= $1;
4666 exc_var
: tASSOC lhs
4673 opt_ensure
: k_ensure compstmt
4678 /*% ripper: ensure!($2) %*/
4692 node
= NEW_STR
(STR_NEW0
(), &@$
);
4693 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
);
4696 node
= evstr2dstr
(p
, node
);
4709 $$
= literal_concat
(p
, $1, $2, &@$
);
4711 /*% ripper: string_concat!($1, $2) %*/
4715 string1
: tSTRING_BEG string_contents tSTRING_END
4718 $$
= heredoc_dedent
(p
, $2);
4719 if
($$
) nd_set_loc
($$
, &@$
);
4721 /*% ripper: string_literal!(heredoc_dedent(p, $2)) %*/
4725 xstring
: tXSTRING_BEG xstring_contents tSTRING_END
4728 $$
= new_xstring
(p
, heredoc_dedent
(p
, $2), &@$
);
4730 /*% ripper: xstring_literal!(heredoc_dedent(p, $2)) %*/
4734 regexp
: tREGEXP_BEG regexp_contents tREGEXP_END
4736 $$
= new_regexp
(p
, $2, $3, &@$
);
4740 words
: tWORDS_BEG
' ' word_list tSTRING_END
4743 $$
= make_list
($3, &@$
);
4745 /*% ripper: array!($3) %*/
4749 word_list
: /* none */
4754 /*% ripper: words_new! %*/
4756 | word_list word
' '
4759 $$
= list_append
(p
, $1, evstr2dstr
(p
, $2));
4761 /*% ripper: words_add!($1, $2) %*/
4765 word
: string_content
4766 /*% ripper[brace]: word_add!(word_new!, $1) %*/
4767 | word string_content
4770 $$
= literal_concat
(p
, $1, $2, &@$
);
4772 /*% ripper: word_add!($1, $2) %*/
4776 symbols
: tSYMBOLS_BEG
' ' symbol_list tSTRING_END
4779 $$
= make_list
($3, &@$
);
4781 /*% ripper: array!($3) %*/
4785 symbol_list
: /* none */
4790 /*% ripper: symbols_new! %*/
4792 | symbol_list word
' '
4795 $$
= symbol_append
(p
, $1, evstr2dstr
(p
, $2));
4797 /*% ripper: symbols_add!($1, $2) %*/
4801 qwords
: tQWORDS_BEG
' ' qword_list tSTRING_END
4804 $$
= make_list
($3, &@$
);
4806 /*% ripper: array!($3) %*/
4810 qsymbols
: tQSYMBOLS_BEG
' ' qsym_list tSTRING_END
4813 $$
= make_list
($3, &@$
);
4815 /*% ripper: array!($3) %*/
4819 qword_list
: /* none */
4824 /*% ripper: qwords_new! %*/
4826 | qword_list tSTRING_CONTENT
' '
4829 $$
= list_append
(p
, $1, $2);
4831 /*% ripper: qwords_add!($1, $2) %*/
4835 qsym_list
: /* none */
4840 /*% ripper: qsymbols_new! %*/
4842 | qsym_list tSTRING_CONTENT
' '
4845 $$
= symbol_append
(p
, $1, $2);
4847 /*% ripper: qsymbols_add!($1, $2) %*/
4851 string_contents
: /* none */
4856 /*% ripper: string_content! %*/
4859 $$ = ripper_new_yylval(p, 0, $$, 0);
4862 | string_contents string_content
4865 $$
= literal_concat
(p
, $1, $2, &@$
);
4867 /*% ripper: string_add!($1, $2) %*/
4870 if (ripper_is_node_yylval($1) && ripper_is_node_yylval($2) &&
4871 !RNODE($1)->nd_cval) {
4872 RNODE($1)->nd_cval = RNODE($2)->nd_cval;
4873 RNODE($1)->nd_rval = add_mark_object(p, $$);
4880 xstring_contents: /* none */
4885 /*% ripper: xstring_new! %*/
4887 | xstring_contents string_content
4890 $$
= literal_concat
(p
, $1, $2, &@$
);
4892 /*% ripper: xstring_add!($1, $2) %*/
4896 regexp_contents: /* none */
4901 /*% ripper: regexp_new! %*/
4904 $$ = ripper_new_yylval(p, 0, $$, 0);
4907 | regexp_contents string_content
4910 NODE
*head
= $1, *tail
= $2;
4918 switch
(nd_type
(head
)) {
4920 nd_set_type
(head
, NODE_DSTR
);
4925 head
= list_append
(p
, NEW_DSTR
(Qnil
, &@$
), head
);
4928 $$
= list_append
(p
, head
, tail
);
4931 VALUE s1 = 1, s2 = 0, n1 = $1, n2 = $2;
4932 if (ripper_is_node_yylval(n1)) {
4933 s1 = RNODE(n1)->nd_cval;
4934 n1 = RNODE(n1)->nd_rval;
4936 if (ripper_is_node_yylval(n2)) {
4937 s2 = RNODE(n2)->nd_cval;
4938 n2 = RNODE(n2)->nd_rval;
4940 $$ = dispatch2(regexp_add, n1, n2);
4942 $$ = ripper_new_yylval(p, 0, $$, s2);
4948 string_content
: tSTRING_CONTENT
4949 /*% ripper[brace]: ripper_new_yylval(p, 0, get_value($1), $1) %*/
4952 /* need to backup p->lex.strterm so that a string literal `%&foo,#$&,bar&` can be parsed */
4953 $
<strterm
>$
= p
->lex.strterm
;
4955 SET_LEX_STATE
(EXPR_BEG
);
4959 p
->lex.strterm
= $
<strterm
>2;
4961 $$
= NEW_EVSTR
($3, &@$
);
4962 nd_set_line
($$
, @
3.end_pos.lineno
);
4964 /*% ripper: string_dvar!($3) %*/
4972 /* need to backup p->lex.strterm so that a string literal `%!foo,#{ !0 },bar!` can be parsed */
4973 $
<strterm
>$
= p
->lex.strterm
;
4977 $
<num
>$
= p
->lex.state
;
4978 SET_LEX_STATE
(EXPR_BEG
);
4981 $
<num
>$
= p
->lex.brace_nest
;
4982 p
->lex.brace_nest
= 0;
4985 $
<num
>$
= p
->heredoc_indent
;
4986 p
->heredoc_indent
= 0;
4988 compstmt tSTRING_DEND
4992 p
->lex.strterm
= $
<strterm
>3;
4993 SET_LEX_STATE
($
<num
>4);
4994 p
->lex.brace_nest
= $
<num
>5;
4995 p
->heredoc_indent
= $
<num
>6;
4996 p
->heredoc_line_indent
= -1;
4998 if
($7) $7->flags
&= ~NODE_FL_NEWLINE
;
4999 $$
= new_evstr
(p
, $7, &@$
);
5001 /*% ripper: string_embexpr!($7) %*/
5008 $$
= NEW_GVAR
($1, &@$
);
5010 /*% ripper: var_ref!($1) %*/
5015 $$
= NEW_IVAR
($1, &@$
);
5017 /*% ripper: var_ref!($1) %*/
5022 $$
= NEW_CVAR
($1, &@$
);
5024 /*% ripper: var_ref!($1) %*/
5035 SET_LEX_STATE
(EXPR_END
);
5037 $$
= NEW_LIT
(ID2SYM
($2), &@$
);
5039 /*% ripper: symbol_literal!(symbol!($2)) %*/
5049 dsym
: tSYMBEG string_contents tSTRING_END
5051 SET_LEX_STATE
(EXPR_END
);
5053 $$
= dsym_node
(p
, $2, &@$
);
5055 /*% ripper: dyna_symbol!($2) %*/
5059 numeric
: simple_numeric
5060 | tUMINUS_NUM simple_numeric %prec tLOWEST
5064 RB_OBJ_WRITE
(p
->ast
, &$$
->nd_lit
, negate_lit
(p
, $$
->nd_lit
));
5066 /*% ripper: unary!(ID2VAL(idUMinus), $2) %*/
5070 simple_numeric
: tINTEGER
5076 nonlocal_var
: tIVAR
5081 user_variable
: tIDENTIFIER
5088 keyword_variable: keyword_nil
{$$
= KWD2EID
(nil
, $1);}
5089 | keyword_self
{$$
= KWD2EID
(self
, $1);}
5090 | keyword_true
{$$
= KWD2EID
(true
, $1);}
5091 | keyword_false
{$$
= KWD2EID
(false
, $1);}
5092 | keyword__FILE__
{$$
= KWD2EID
(_FILE__
, $1);}
5093 | keyword__LINE__
{$$
= KWD2EID
(_LINE__
, $1);}
5094 | keyword__ENCODING__
{$$
= KWD2EID
(_ENCODING__
, $1);}
5097 var_ref
: user_variable
5100 if
(!($$
= gettable
(p
, $1, &@$
))) $$
= NEW_BEGIN
(0, &@$
);
5102 if (id_is_var(p, get_id($1))) {
5103 $$ = dispatch1(var_ref, $1);
5106 $$ = dispatch1(vcall, $1);
5113 if
(!($$
= gettable
(p
, $1, &@$
))) $$
= NEW_BEGIN
(0, &@$
);
5115 /*% ripper: var_ref!($1) %*/
5119 var_lhs
: user_variable
5122 $$
= assignable
(p
, $1, 0, &@$
);
5124 /*% ripper: assignable(p, var_field(p, $1)) %*/
5129 $$
= assignable
(p
, $1, 0, &@$
);
5131 /*% ripper: assignable(p, var_field(p, $1)) %*/
5141 SET_LEX_STATE
(EXPR_BEG
);
5142 p
->command_start
= TRUE
;
5153 /*% ripper: Qnil %*/
5157 f_opt_paren_args: f_paren_args
5160 p
->ctxt.in_argdef
= 0;
5161 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
0);
5162 $$
= new_args
(p
, Qnone
, Qnone
, Qnone
, Qnone
, $$
, &@
0);
5166 f_paren_args
: '(' f_args rparen
5171 /*% ripper: paren!($2) %*/
5172 SET_LEX_STATE
(EXPR_BEG
);
5173 p
->command_start
= TRUE
;
5174 p
->ctxt.in_argdef
= 0;
5178 f_arglist
: f_paren_args
5181 p
->ctxt.in_kwarg
= 1;
5182 p
->ctxt.in_argdef
= 1;
5183 SET_LEX_STATE
(p
->lex.state|EXPR_LABEL
); /* force for args */
5187 p
->ctxt.in_kwarg
= $
<ctxt
>1.in_kwarg
;
5188 p
->ctxt.in_argdef
= 0;
5190 SET_LEX_STATE
(EXPR_BEG
);
5191 p
->command_start
= TRUE
;
5195 args_tail
: f_kwarg
',' f_kwrest opt_f_block_arg
5197 $$
= new_args_tail
(p
, $1, $3, $4, &@
3);
5199 | f_kwarg opt_f_block_arg
5201 $$
= new_args_tail
(p
, $1, Qnone
, $2, &@
1);
5203 | f_any_kwrest opt_f_block_arg
5205 $$
= new_args_tail
(p
, Qnone
, $1, $2, &@
1);
5209 $$
= new_args_tail
(p
, Qnone
, Qnone
, $1, &@
1);
5213 add_forwarding_args
(p
);
5214 $$
= new_args_tail
(p
, Qnone
, $1, ID2VAL
(idFWD_BLOCK
), &@
1);
5218 opt_args_tail
: ',' args_tail
5224 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
0);
5228 f_args
: f_arg
',' f_optarg
',' f_rest_arg opt_args_tail
5230 $$
= new_args
(p
, $1, $3, $5, Qnone
, $6, &@$
);
5232 | f_arg
',' f_optarg
',' f_rest_arg
',' f_arg opt_args_tail
5234 $$
= new_args
(p
, $1, $3, $5, $7, $8, &@$
);
5236 | f_arg
',' f_optarg opt_args_tail
5238 $$
= new_args
(p
, $1, $3, Qnone
, Qnone
, $4, &@$
);
5240 | f_arg
',' f_optarg
',' f_arg opt_args_tail
5242 $$
= new_args
(p
, $1, $3, Qnone
, $5, $6, &@$
);
5244 | f_arg
',' f_rest_arg opt_args_tail
5246 $$
= new_args
(p
, $1, Qnone
, $3, Qnone
, $4, &@$
);
5248 | f_arg
',' f_rest_arg
',' f_arg opt_args_tail
5250 $$
= new_args
(p
, $1, Qnone
, $3, $5, $6, &@$
);
5252 | f_arg opt_args_tail
5254 $$
= new_args
(p
, $1, Qnone
, Qnone
, Qnone
, $2, &@$
);
5256 | f_optarg
',' f_rest_arg opt_args_tail
5258 $$
= new_args
(p
, Qnone
, $1, $3, Qnone
, $4, &@$
);
5260 | f_optarg
',' f_rest_arg
',' f_arg opt_args_tail
5262 $$
= new_args
(p
, Qnone
, $1, $3, $5, $6, &@$
);
5264 | f_optarg opt_args_tail
5266 $$
= new_args
(p
, Qnone
, $1, Qnone
, Qnone
, $2, &@$
);
5268 | f_optarg
',' f_arg opt_args_tail
5270 $$
= new_args
(p
, Qnone
, $1, Qnone
, $3, $4, &@$
);
5272 | f_rest_arg opt_args_tail
5274 $$
= new_args
(p
, Qnone
, Qnone
, $1, Qnone
, $2, &@$
);
5276 | f_rest_arg
',' f_arg opt_args_tail
5278 $$
= new_args
(p
, Qnone
, Qnone
, $1, $3, $4, &@$
);
5282 $$
= new_args
(p
, Qnone
, Qnone
, Qnone
, Qnone
, $1, &@$
);
5286 $$
= new_args_tail
(p
, Qnone
, Qnone
, Qnone
, &@
0);
5287 $$
= new_args
(p
, Qnone
, Qnone
, Qnone
, Qnone
, $$
, &@
0);
5291 args_forward
: tBDOT3
5296 /*% ripper: args_forward! %*/
5300 f_bad_arg
: tCONSTANT
5302 static const char mesg
[] = "formal argument cannot be a constant";
5304 yyerror1
(&@
1, mesg
);
5307 /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
5311 static const char mesg
[] = "formal argument cannot be an instance variable";
5313 yyerror1
(&@
1, mesg
);
5316 /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
5320 static const char mesg
[] = "formal argument cannot be a global variable";
5322 yyerror1
(&@
1, mesg
);
5325 /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
5329 static const char mesg
[] = "formal argument cannot be a class variable";
5331 yyerror1
(&@
1, mesg
);
5334 /*% ripper[error]: param_error!(ERR_MESG(), $1) %*/
5338 f_norm_arg
: f_bad_arg
5341 formal_argument
(p
, $1);
5342 p
->max_numparam
= ORDINAL_PARAM
;
5347 f_arg_asgn
: f_norm_arg
5356 f_arg_item
: f_arg_asgn
5360 $$
= NEW_ARGS_AUX
($1, 1, &NULL_LOC
);
5362 /*% ripper: get_value($1) %*/
5364 | tLPAREN f_margs rparen
5367 ID tid
= internal_id
(p
);
5369 loc.beg_pos
= @
2.beg_pos
;
5370 loc.end_pos
= @
2.beg_pos
;
5372 if
(dyna_in_block
(p
)) {
5373 $2->nd_value
= NEW_DVAR
(tid
, &loc
);
5376 $2->nd_value
= NEW_LVAR
(tid
, &loc
);
5378 $$
= NEW_ARGS_AUX
(tid
, 1, &NULL_LOC
);
5381 /*% ripper: mlhs_paren!($2) %*/
5386 /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
5387 | f_arg
',' f_arg_item
5392 $$
->nd_next
= block_append
(p
, $$
->nd_next
, $3->nd_next
);
5393 rb_discard_node
(p
, $3);
5395 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5402 arg_var
(p
, formal_argument
(p
, $1));
5403 p
->cur_arg
= get_id
($1);
5404 p
->max_numparam
= ORDINAL_PARAM
;
5405 p
->ctxt.in_argdef
= 0;
5410 f_kw
: f_label arg_value
5413 p
->ctxt.in_argdef
= 1;
5415 $$
= new_kw_arg
(p
, assignable
(p
, $1, $2, &@$
), &@$
);
5417 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
5422 p
->ctxt.in_argdef
= 1;
5424 $$
= new_kw_arg
(p
, assignable
(p
, $1, NODE_SPECIAL_REQUIRED_KEYWORD
, &@$
), &@$
);
5426 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
5430 f_block_kw
: f_label primary_value
5432 p
->ctxt.in_argdef
= 1;
5434 $$
= new_kw_arg
(p
, assignable
(p
, $1, $2, &@$
), &@$
);
5436 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($2)) %*/
5440 p
->ctxt.in_argdef
= 1;
5442 $$
= new_kw_arg
(p
, assignable
(p
, $1, NODE_SPECIAL_REQUIRED_KEYWORD
, &@$
), &@$
);
5444 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), 0) %*/
5448 f_block_kwarg
: f_block_kw
5453 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
5455 | f_block_kwarg
',' f_block_kw
5458 $$
= kwd_append
($1, $3);
5460 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5470 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
5475 $$
= kwd_append
($1, $3);
5477 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5485 f_no_kwarg
: kwrest_mark keyword_nil
5489 /*% ripper: nokw_param!(Qnil) %*/
5493 f_kwrest
: kwrest_mark tIDENTIFIER
5495 arg_var
(p
, shadowing_lvar
(p
, get_id
($2)));
5499 /*% ripper: kwrest_param!($2) %*/
5504 arg_var
(p
, shadowing_lvar
(p
, get_id
(ANON_KEYWORD_REST_ID
)));
5506 /*% ripper: kwrest_param!(Qnil) %*/
5510 f_opt
: f_arg_asgn f_eq arg_value
5513 p
->ctxt.in_argdef
= 1;
5515 $$
= NEW_OPT_ARG
(0, assignable
(p
, $1, $3, &@$
), &@$
);
5517 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
5521 f_block_opt
: f_arg_asgn f_eq primary_value
5524 p
->ctxt.in_argdef
= 1;
5526 $$
= NEW_OPT_ARG
(0, assignable
(p
, $1, $3, &@$
), &@$
);
5528 /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/
5532 f_block_optarg
: f_block_opt
5537 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
5539 | f_block_optarg
',' f_block_opt
5542 $$
= opt_arg_append
($1, $3);
5544 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5553 /*% ripper: rb_ary_new3(1, get_value($1)) %*/
5555 | f_optarg
',' f_opt
5558 $$
= opt_arg_append
($1, $3);
5560 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5568 f_rest_arg
: restarg_mark tIDENTIFIER
5570 arg_var
(p
, shadowing_lvar
(p
, get_id
($2)));
5574 /*% ripper: rest_param!($2) %*/
5579 arg_var
(p
, shadowing_lvar
(p
, get_id
(ANON_REST_ID
)));
5581 /*% ripper: rest_param!(Qnil) %*/
5589 f_block_arg
: blkarg_mark tIDENTIFIER
5591 arg_var
(p
, shadowing_lvar
(p
, get_id
($2)));
5595 /*% ripper: blockarg!($2) %*/
5600 arg_var
(p
, shadowing_lvar
(p
, get_id
(ANON_BLOCK_ID
)));
5602 $$ = dispatch1(blockarg, Qnil);
5607 opt_f_block_arg
: ',' f_block_arg
5622 |
'(' {SET_LEX_STATE
(EXPR_BEG
);} expr rparen
5625 switch
(nd_type
($3)) {
5634 yyerror1
(&@
3, "can't define singleton method for literals");
5642 /*% ripper: paren!($3) %*/
5652 /*% ripper: assoclist_from_args!($1) %*/
5657 /*% ripper[brace]: rb_ary_new3(1, get_value($1)) %*/
5667 if
(assocs
->nd_head
&&
5668 !tail
->nd_head
&& nd_type_p
(tail
->nd_next
, NODE_LIST
) &&
5669 nd_type_p
(tail
->nd_next
->nd_head
, NODE_HASH
)) {
5671 tail
= tail
->nd_next
->nd_head
->nd_head
;
5673 assocs
= list_concat
(assocs
, tail
);
5677 /*% ripper: rb_ary_push($1, get_value($3)) %*/
5681 assoc
: arg_value tASSOC arg_value
5684 if
(nd_type_p
($1, NODE_STR
)) {
5685 nd_set_type
($1, NODE_LIT
);
5686 RB_OBJ_WRITE
(p
->ast
, &$1->nd_lit
, rb_fstring
($1->nd_lit
));
5688 $$
= list_append
(p
, NEW_LIST
($1, &@$
), $3);
5690 /*% ripper: assoc_new!($1, $3) %*/
5695 $$
= list_append
(p
, NEW_LIST
(NEW_LIT
(ID2SYM
($1), &@
1), &@$
), $2);
5697 /*% ripper: assoc_new!($1, $2) %*/
5702 NODE
*val
= gettable
(p
, $1, &@$
);
5703 if
(!val
) val
= NEW_BEGIN
(0, &@$
);
5704 $$
= list_append
(p
, NEW_LIST
(NEW_LIT
(ID2SYM
($1), &@
1), &@$
), val
);
5706 /*% ripper: assoc_new!($1, Qnil) %*/
5708 | tSTRING_BEG string_contents tLABEL_END arg_value
5711 YYLTYPE loc
= code_loc_gen
(&@
1, &@
3);
5712 $$
= list_append
(p
, NEW_LIST
(dsym_node
(p
, $2, &loc
), &loc
), $4);
5714 /*% ripper: assoc_new!(dyna_symbol!($2), $4) %*/
5719 if
(nd_type_p
($2, NODE_HASH
) &&
5720 !($2->nd_head
&& $2->nd_head
->nd_alen
)) {
5721 static VALUE empty_hash
;
5723 empty_hash
= rb_obj_freeze
(rb_hash_new
());
5724 rb_gc_register_mark_object
(empty_hash
);
5726 $$
= list_append
(p
, NEW_LIST
(0, &@$
), NEW_LIT
(empty_hash
, &@$
));
5729 $$
= list_append
(p
, NEW_LIST
(0, &@$
), $2);
5731 /*% ripper: assoc_splat!($2) %*/
5736 if
(!local_id
(p
, ANON_KEYWORD_REST_ID
)) {
5737 compile_error
(p
, "no anonymous keyword rest parameter");
5739 $$
= list_append
(p
, NEW_LIST
(0, &@$
),
5740 NEW_LVAR
(ANON_KEYWORD_REST_ID
, &@$
));
5742 /*% ripper: assoc_splat!(Qnil) %*/
5746 operation
: tIDENTIFIER
5751 operation2
: tIDENTIFIER
5757 operation3
: tIDENTIFIER
5774 opt_terms
: /* none */
5785 rbracket
: opt_nl
']'
5791 trailer
: /* none */
5796 term
: ';' {yyerrok;token_flush
(p
);}
5797 |
'\n' {token_flush
(p
);}
5801 | terms
';' {yyerrok;}
5813 # define yylval (*p->lval)
5815 static int regx_options
(struct parser_params
*);
5816 static int tokadd_string
(struct parser_params
*,int,int,int,long*,rb_encoding
**,rb_encoding
**);
5817 static void tokaddmbc
(struct parser_params
*p
, int c
, rb_encoding
*enc
);
5818 static enum yytokentype parse_string
(struct parser_params
*,rb_strterm_literal_t
*);
5819 static enum yytokentype here_document
(struct parser_params
*,rb_strterm_heredoc_t
*);
5822 # define set_yylval_node(x) { \
5824 rb_parser_set_location
(p
, &_cur_loc
); \
5825 yylval.node
= (x
); \
5827 # define set_yylval_str(x) \
5829 set_yylval_node
(NEW_STR
(x
, &_cur_loc
)); \
5830 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, x
); \
5832 # define set_yylval_literal(x) \
5834 set_yylval_node
(NEW_LIT
(x
, &_cur_loc
)); \
5835 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, x
); \
5837 # define set_yylval_num(x) (yylval.num = (x))
5838 # define set_yylval_id(x) (yylval.id = (x))
5839 # define set_yylval_name(x) (yylval.id = (x))
5840 # define yylval_id() (yylval.id)
5843 ripper_yylval_id
(struct parser_params
*p
, ID x
)
5845 return ripper_new_yylval
(p
, x
, ID2SYM
(x
), 0);
5847 # define set_yylval_str(x) (yylval.val = add_mark_object(p, (x)))
5848 # define set_yylval_num(x) (yylval.val = ripper_new_yylval(p, (x), 0, 0))
5849 # define set_yylval_id(x) (void)(x)
5850 # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(p, x))
5851 # define set_yylval_literal(x) add_mark_object(p, (x))
5852 # define set_yylval_node(x) (yylval.val = ripper_new_yylval(p, 0, 0, STR_NEW(p->lex.ptok, p->lex.pcur-p->lex.ptok)))
5853 # define yylval_id() yylval.id
5854 # define _cur_loc NULL_LOC /* dummy */
5857 #define set_yylval_noname() set_yylval_id(keyword_nil)
5860 #define literal_flush(p, ptr) ((p)->lex.ptok = (ptr))
5861 #define dispatch_scan_event(p, t) ((void)0)
5862 #define dispatch_delayed_token(p, t) ((void)0)
5863 #define has_delayed_token(p) (0)
5865 #define literal_flush(p, ptr) ((void)(ptr))
5867 #define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
5870 intern_sym
(const char *name
)
5872 ID id
= rb_intern_const
(name
);
5877 ripper_has_scan_event
(struct parser_params
*p
)
5879 if
(p
->lex.pcur
< p
->lex.ptok
) rb_raise
(rb_eRuntimeError
, "lex.pcur < lex.ptok");
5880 return p
->lex.pcur
> p
->lex.ptok
;
5884 ripper_scan_event_val
(struct parser_params
*p
, enum yytokentype t
)
5886 VALUE str
= STR_NEW
(p
->lex.ptok
, p
->lex.pcur
- p
->lex.ptok
);
5887 VALUE rval
= ripper_dispatch1
(p
, ripper_token2eventid
(t
), str
);
5893 ripper_dispatch_scan_event
(struct parser_params
*p
, enum yytokentype t
)
5895 if
(!ripper_has_scan_event
(p
)) return
;
5896 add_mark_object
(p
, yylval_rval
= ripper_scan_event_val
(p
, t
));
5898 #define dispatch_scan_event(p, t) ripper_dispatch_scan_event(p, t)
5901 ripper_dispatch_delayed_token
(struct parser_params
*p
, enum yytokentype t
)
5903 int saved_line
= p
->ruby_sourceline
;
5904 const char *saved_tokp
= p
->lex.ptok
;
5906 if
(NIL_P
(p
->delayed.token
)) return
;
5907 p
->ruby_sourceline
= p
->delayed.line
;
5908 p
->lex.ptok
= p
->lex.pbeg
+ p
->delayed.col
;
5909 add_mark_object
(p
, yylval_rval
= ripper_dispatch1
(p
, ripper_token2eventid
(t
), p
->delayed.token
));
5910 p
->delayed.token
= Qnil
;
5911 p
->ruby_sourceline
= saved_line
;
5912 p
->lex.ptok
= saved_tokp
;
5914 #define dispatch_delayed_token(p, t) ripper_dispatch_delayed_token(p, t)
5915 #define has_delayed_token(p) (!NIL_P(p->delayed.token))
5919 is_identchar
(const char *ptr
, const char *MAYBE_UNUSED
(ptr_end
), rb_encoding
*enc
)
5921 return rb_enc_isalnum
((unsigned char)*ptr
, enc
) ||
*ptr
== '_' ||
!ISASCII
(*ptr
);
5925 parser_is_identchar
(struct parser_params
*p
)
5927 return
!(p
)->eofp
&& is_identchar
(p
->lex.pcur
-1, p
->lex.pend
, p
->enc
);
5931 parser_isascii
(struct parser_params
*p
)
5933 return ISASCII
(*(p
->lex.pcur
-1));
5937 token_info_setup
(token_info
*ptinfo
, const char *ptr
, const rb_code_location_t
*loc
)
5939 int column
= 1, nonspc
= 0, i
;
5940 for
(i
= 0; i
< loc
->beg_pos.column
; i
++, ptr
++) {
5942 column
= (((column
- 1) / TAB_WIDTH
) + 1) * TAB_WIDTH
;
5945 if
(*ptr
!= ' ' && *ptr
!= '\t') {
5950 ptinfo
->beg
= loc
->beg_pos
;
5951 ptinfo
->indent
= column
;
5952 ptinfo
->nonspc
= nonspc
;
5956 token_info_push
(struct parser_params
*p
, const char *token
, const rb_code_location_t
*loc
)
5960 if
(!p
->token_info_enabled
) return
;
5961 ptinfo
= ALLOC
(token_info
);
5962 ptinfo
->token
= token
;
5963 ptinfo
->next
= p
->token_info
;
5964 token_info_setup
(ptinfo
, p
->lex.pbeg
, loc
);
5966 p
->token_info
= ptinfo
;
5970 token_info_pop
(struct parser_params
*p
, const char *token
, const rb_code_location_t
*loc
)
5972 token_info
*ptinfo_beg
= p
->token_info
;
5974 if
(!ptinfo_beg
) return
;
5975 p
->token_info
= ptinfo_beg
->next
;
5977 /* indentation check of matched keywords (begin..end, if..end, etc.) */
5978 token_info_warn
(p
, token
, ptinfo_beg
, 1, loc
);
5979 ruby_sized_xfree
(ptinfo_beg
, sizeof
(*ptinfo_beg
));
5983 token_info_drop
(struct parser_params
*p
, const char *token
, rb_code_position_t beg_pos
)
5985 token_info
*ptinfo_beg
= p
->token_info
;
5987 if
(!ptinfo_beg
) return
;
5988 p
->token_info
= ptinfo_beg
->next
;
5990 if
(ptinfo_beg
->beg.lineno
!= beg_pos.lineno ||
5991 ptinfo_beg
->beg.column
!= beg_pos.column ||
5992 strcmp
(ptinfo_beg
->token
, token
)) {
5993 compile_error
(p
, "token position mismatch: %d:%d:%s expected but %d:%d:%s",
5994 beg_pos.lineno
, beg_pos.column
, token
,
5995 ptinfo_beg
->beg.lineno
, ptinfo_beg
->beg.column
,
5999 ruby_sized_xfree
(ptinfo_beg
, sizeof
(*ptinfo_beg
));
6003 token_info_warn
(struct parser_params
*p
, const char *token
, token_info
*ptinfo_beg
, int same
, const rb_code_location_t
*loc
)
6005 token_info ptinfo_end_body
, *ptinfo_end
= &ptinfo_end_body
;
6006 if
(!p
->token_info_enabled
) return
;
6007 if
(!ptinfo_beg
) return
;
6008 token_info_setup
(ptinfo_end
, p
->lex.pbeg
, loc
);
6009 if
(ptinfo_beg
->beg.lineno
== ptinfo_end
->beg.lineno
) return
; /* ignore one-line block */
6010 if
(ptinfo_beg
->nonspc || ptinfo_end
->nonspc
) return
; /* ignore keyword in the middle of a line */
6011 if
(ptinfo_beg
->indent
== ptinfo_end
->indent
) return
; /* the indents are matched */
6012 if
(!same
&& ptinfo_beg
->indent
< ptinfo_end
->indent
) return
;
6013 rb_warn3L
(ptinfo_end
->beg.lineno
,
6014 "mismatched indentations at '%s' with '%s' at %d",
6015 WARN_S
(token
), WARN_S
(ptinfo_beg
->token
), WARN_I
(ptinfo_beg
->beg.lineno
));
6019 parser_precise_mbclen
(struct parser_params
*p
, const char *ptr
)
6021 int len
= rb_enc_precise_mbclen
(ptr
, p
->lex.pend
, p
->enc
);
6022 if
(!MBCLEN_CHARFOUND_P
(len
)) {
6023 compile_error
(p
, "invalid multibyte char (%s)", rb_enc_name
(p
->enc
));
6030 static void ruby_show_error_line
(VALUE errbuf
, const YYLTYPE *yylloc, int lineno
, VALUE str
);
6033 parser_show_error_line
(struct parser_params
*p
, const YYLTYPE *yylloc)
6036 int lineno
= p
->ruby_sourceline
;
6040 else if
(yylloc->beg_pos.lineno
== lineno
) {
6041 str
= p
->lex.lastline
;
6046 ruby_show_error_line
(p
->error_buffer
, yylloc, lineno
, str
);
6050 parser_yyerror
(struct parser_params
*p
, const YYLTYPE *yylloc, const char *msg
)
6056 yylloc = RUBY_SET_YYLLOC
(current
);
6058 else if
((p
->ruby_sourceline
!= yylloc->beg_pos.lineno
&&
6059 p
->ruby_sourceline
!= yylloc->end_pos.lineno
)) {
6063 compile_error
(p
, "%s", msg
);
6064 parser_show_error_line
(p
, yylloc);
6069 parser_yyerror0
(struct parser_params
*p
, const char *msg
)
6072 return parser_yyerror
(p
, RUBY_SET_YYLLOC
(current
), msg
);
6076 ruby_show_error_line
(VALUE errbuf
, const YYLTYPE *yylloc, int lineno
, VALUE str
)
6079 const int max_line_margin
= 30;
6080 const char *ptr
, *ptr_end
, *pt
, *pb
;
6081 const char *pre
= "", *post
= "", *pend
;
6082 const char *code
= "", *caret
= "";
6084 const char *const pbeg
= RSTRING_PTR
(str
);
6089 if
(!yylloc) return
;
6090 pend
= RSTRING_END
(str
);
6091 if
(pend
> pbeg
&& pend
[-1] == '\n') {
6092 if
(--pend
> pbeg
&& pend
[-1] == '\r') --pend
;
6096 if
(lineno
== yylloc->end_pos.lineno
&&
6097 (pend
- pbeg
) > yylloc->end_pos.column
) {
6098 pt
= pbeg
+ yylloc->end_pos.column
;
6102 lim
= ptr
- pbeg
> max_line_margin ? ptr
- max_line_margin
: pbeg
;
6103 while
((lim
< ptr
) && (*(ptr
-1) != '\n')) ptr
--;
6105 lim
= pend
- ptr_end
> max_line_margin ? ptr_end
+ max_line_margin
: pend
;
6106 while
((ptr_end
< lim
) && (*ptr_end
!= '\n') && (*ptr_end
!= '\r')) ptr_end
++;
6108 len
= ptr_end
- ptr
;
6111 ptr
= rb_enc_prev_char
(pbeg
, ptr
, pt
, rb_enc_get
(str
));
6112 if
(ptr
> pbeg
) pre
= "...";
6114 if
(ptr_end
< pend
) {
6115 ptr_end
= rb_enc_prev_char
(pt
, ptr_end
, pend
, rb_enc_get
(str
));
6116 if
(ptr_end
< pend
) post
= "...";
6120 if
(lineno
== yylloc->beg_pos.lineno
) {
6121 pb
+= yylloc->beg_pos.column
;
6122 if
(pb
> pt
) pb
= pt
;
6124 if
(pb
< ptr
) pb
= ptr
;
6125 if
(len
<= 4 && yylloc->beg_pos.lineno
== yylloc->end_pos.lineno
) {
6128 if
(RTEST
(errbuf
)) {
6129 mesg
= rb_attr_get
(errbuf
, idMesg
);
6130 if
(RSTRING_LEN
(mesg
) > 0 && *(RSTRING_END
(mesg
)-1) != '\n')
6131 rb_str_cat_cstr
(mesg
, "\n");
6134 mesg
= rb_enc_str_new
(0, 0, rb_enc_get
(str
));
6136 if
(!errbuf
&& rb_stderr_tty_p
()) {
6137 #define CSI_BEGIN "\033["
6140 CSI_BEGIN
""CSI_SGR
"%s" /* pre */
6141 CSI_BEGIN
"1"CSI_SGR
"%.*s"
6142 CSI_BEGIN
"1;4"CSI_SGR
"%.*s"
6143 CSI_BEGIN
";1"CSI_SGR
"%.*s"
6144 CSI_BEGIN
""CSI_SGR
"%s" /* post */
6147 (int)(pb
- ptr
), ptr
,
6149 (int)(ptr_end
- pt
), pt
,
6155 len
= ptr_end
- ptr
;
6156 lim
= pt
< pend ? pt
: pend
;
6157 i
= (int)(lim
- ptr
);
6158 buf
= ALLOCA_N
(char, i
+2);
6163 *p2
++ = *ptr
++ == '\t' ?
'\t' : ' ';
6169 memset
(p2
, '~', (lim
- ptr
));
6173 rb_str_catf
(mesg
, "%s%.*s%s\n""%s%s\n",
6174 pre
, (int)len
, code
, post
,
6177 if
(!errbuf
) rb_write_error_str
(mesg
);
6181 parser_yyerror
(struct parser_params
*p
, const YYLTYPE *yylloc, const char *msg
)
6183 const char *pcur
= 0, *ptok
= 0;
6184 if
(p
->ruby_sourceline
== yylloc->beg_pos.lineno
&&
6185 p
->ruby_sourceline
== yylloc->end_pos.lineno
) {
6188 p
->lex.ptok
= p
->lex.pbeg
+ yylloc->beg_pos.column
;
6189 p
->lex.pcur
= p
->lex.pbeg
+ yylloc->end_pos.column
;
6191 parser_yyerror0
(p
, msg
);
6200 parser_yyerror0
(struct parser_params
*p
, const char *msg
)
6202 dispatch1
(parse_error
, STR_NEW2
(msg
));
6208 parser_show_error_line
(struct parser_params
*p
, const YYLTYPE *yylloc)
6211 #endif /* !RIPPER */
6215 vtable_size
(const struct vtable
*tbl
)
6217 if
(!DVARS_TERMINAL_P
(tbl
)) {
6226 static struct vtable
*
6227 vtable_alloc_gen
(struct parser_params
*p
, int line
, struct vtable
*prev
)
6229 struct vtable
*tbl
= ALLOC
(struct vtable
);
6232 tbl
->tbl
= ALLOC_N
(ID
, tbl
->capa
);
6236 rb_parser_printf
(p
, "vtable_alloc:%d: %p\n", line
, (void *)tbl
);
6241 #define vtable_alloc(prev) vtable_alloc_gen(p, __LINE__, prev)
6244 vtable_free_gen
(struct parser_params
*p
, int line
, const char *name
,
6249 rb_parser_printf
(p
, "vtable_free:%d: %s(%p)\n", line
, name
, (void *)tbl
);
6252 if
(!DVARS_TERMINAL_P
(tbl
)) {
6254 ruby_sized_xfree
(tbl
->tbl
, tbl
->capa
* sizeof
(ID
));
6256 ruby_sized_xfree
(tbl
, sizeof
(*tbl
));
6259 #define vtable_free(tbl) vtable_free_gen(p, __LINE__, #tbl, tbl)
6262 vtable_add_gen
(struct parser_params
*p
, int line
, const char *name
,
6263 struct vtable
*tbl
, ID id
)
6267 rb_parser_printf
(p
, "vtable_add:%d: %s(%p), %s\n",
6268 line
, name
, (void *)tbl
, rb_id2name
(id
));
6271 if
(DVARS_TERMINAL_P
(tbl
)) {
6272 rb_parser_fatal
(p
, "vtable_add: vtable is not allocated (%p)", (void *)tbl
);
6275 if
(tbl
->pos
== tbl
->capa
) {
6276 tbl
->capa
= tbl
->capa
* 2;
6277 SIZED_REALLOC_N
(tbl
->tbl
, ID
, tbl
->capa
, tbl
->pos
);
6279 tbl
->tbl
[tbl
->pos
++] = id
;
6281 #define vtable_add(tbl, id) vtable_add_gen(p, __LINE__, #tbl, tbl, id)
6285 vtable_pop_gen
(struct parser_params
*p
, int line
, const char *name
,
6286 struct vtable
*tbl
, int n
)
6289 rb_parser_printf
(p
, "vtable_pop:%d: %s(%p), %d\n",
6290 line
, name
, (void *)tbl
, n
);
6293 rb_parser_fatal
(p
, "vtable_pop: unreachable (%d < %d)", tbl
->pos
, n
);
6298 #define vtable_pop(tbl, n) vtable_pop_gen(p, __LINE__, #tbl, tbl, n)
6302 vtable_included
(const struct vtable
* tbl
, ID id
)
6306 if
(!DVARS_TERMINAL_P
(tbl
)) {
6307 for
(i
= 0; i
< tbl
->pos
; i
++) {
6308 if
(tbl
->tbl
[i
] == id
) {
6316 static void parser_prepare
(struct parser_params
*p
);
6319 static NODE
*parser_append_options
(struct parser_params
*p
, NODE
*node
);
6322 debug_lines
(VALUE fname
)
6325 CONST_ID
(script_lines
, "SCRIPT_LINES__");
6326 if
(rb_const_defined_at
(rb_cObject
, script_lines
)) {
6327 VALUE hash
= rb_const_get_at
(rb_cObject
, script_lines
);
6328 if
(RB_TYPE_P
(hash
, T_HASH
)) {
6329 VALUE lines
= rb_ary_new
();
6330 rb_hash_aset
(hash
, fname
, lines
);
6338 e_option_supplied
(struct parser_params
*p
)
6340 return strcmp
(p
->ruby_sourcefile
, "-e") == 0;
6344 yycompile0
(VALUE arg
)
6348 struct parser_params
*p
= (struct parser_params
*)arg
;
6351 if
(!compile_for_eval
&& !NIL_P
(p
->ruby_sourcefile_string
)) {
6352 p
->debug_lines
= debug_lines
(p
->ruby_sourcefile_string
);
6353 if
(p
->debug_lines
&& p
->ruby_sourceline
> 0) {
6354 VALUE str
= rb_default_rs
;
6355 n
= p
->ruby_sourceline
;
6357 rb_ary_push
(p
->debug_lines
, str
);
6361 if
(!e_option_supplied
(p
)) {
6366 if
(p
->keep_script_lines || ruby_vm_keep_script_lines
) {
6367 if
(!p
->debug_lines
) {
6368 p
->debug_lines
= rb_ary_new
();
6371 RB_OBJ_WRITE
(p
->ast
, &p
->ast
->body.script_lines
, p
->debug_lines
);
6375 #define RUBY_DTRACE_PARSE_HOOK(name) \
6376 if
(RUBY_DTRACE_PARSE_
##name##_ENABLED()) { \
6377 RUBY_DTRACE_PARSE_
##name(p->ruby_sourcefile, p->ruby_sourceline); \
6379 RUBY_DTRACE_PARSE_HOOK
(BEGIN
);
6381 RUBY_DTRACE_PARSE_HOOK
(END
);
6385 p
->lex.pcur
= p
->lex.pbeg
= p
->lex.pend
= 0;
6386 p
->lex.prevline
= p
->lex.lastline
= p
->lex.nextline
= 0;
6387 if
(n || p
->error_p
) {
6388 VALUE mesg
= p
->error_buffer
;
6390 mesg
= rb_class_new_instance
(0, 0, rb_eSyntaxError
);
6392 rb_set_errinfo
(mesg
);
6395 tree
= p
->eval_tree
;
6397 tree
= NEW_NIL
(&NULL_LOC
);
6400 VALUE opt
= p
->compile_option
;
6402 NODE
*body
= parser_append_options
(p
, tree
->nd_body
);
6403 if
(!opt
) opt
= rb_obj_hide
(rb_ident_hash_new
());
6404 rb_hash_aset
(opt
, rb_sym_intern_ascii_cstr
("coverage_enabled"), cov
);
6405 prelude
= block_append
(p
, p
->eval_tree_begin
, body
);
6406 tree
->nd_body
= prelude
;
6407 RB_OBJ_WRITE
(p
->ast
, &p
->ast
->body.compile_option
, opt
);
6409 p
->ast
->body.root
= tree
;
6410 if
(!p
->ast
->body.script_lines
) p
->ast
->body.script_lines
= INT2FIX
(p
->line_count
);
6415 yycompile
(VALUE vparser
, struct parser_params
*p
, VALUE fname
, int line
)
6419 p
->ruby_sourcefile_string
= Qnil
;
6420 p
->ruby_sourcefile
= "(none)";
6423 p
->ruby_sourcefile_string
= rb_fstring
(fname
);
6424 p
->ruby_sourcefile
= StringValueCStr
(fname
);
6426 p
->ruby_sourceline
= line
- 1;
6430 p
->ast
= ast
= rb_ast_new
();
6431 rb_suppress_tracing
(yycompile0
, (VALUE
)p
);
6433 RB_GC_GUARD
(vparser
); /* prohibit tail call optimization */
6441 #endif /* !RIPPER */
6443 static rb_encoding
*
6444 must_be_ascii_compatible
(VALUE s
)
6446 rb_encoding
*enc
= rb_enc_get
(s
);
6447 if
(!rb_enc_asciicompat
(enc
)) {
6448 rb_raise
(rb_eArgError
, "invalid source encoding");
6454 lex_get_str
(struct parser_params
*p
, VALUE s
)
6456 char *beg
, *end
, *start
;
6459 beg
= RSTRING_PTR
(s
);
6460 len
= RSTRING_LEN
(s
);
6462 if
(p
->lex.gets_.ptr
) {
6463 if
(len
== p
->lex.gets_.ptr
) return Qnil
;
6464 beg
+= p
->lex.gets_.ptr
;
6465 len
-= p
->lex.gets_.ptr
;
6467 end
= memchr
(beg
, '\n', len
);
6468 if
(end
) len
= ++end
- beg
;
6469 p
->lex.gets_.ptr
+= len
;
6470 return rb_str_subseq
(s
, beg
- start
, len
);
6474 lex_getline
(struct parser_params
*p
)
6476 VALUE line
= (*p
->lex.gets
)(p
, p
->lex.input
);
6477 if
(NIL_P
(line
)) return line
;
6478 must_be_ascii_compatible
(line
);
6479 if
(RB_OBJ_FROZEN
(line
)) line
= rb_str_dup
(line
); // needed for RubyVM::AST.of because script_lines in iseq is deep-frozen
6481 if
(p
->debug_lines
) {
6482 rb_enc_associate
(line
, p
->enc
);
6483 rb_ary_push
(p
->debug_lines
, line
);
6490 static const rb_data_type_t parser_data_type
;
6494 parser_compile_string
(VALUE vparser
, VALUE fname
, VALUE s
, int line
)
6496 struct parser_params
*p
;
6498 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
6500 p
->lex.gets
= lex_get_str
;
6501 p
->lex.gets_.ptr
= 0;
6502 p
->lex.input
= rb_str_new_frozen
(s
);
6503 p
->lex.pbeg
= p
->lex.pcur
= p
->lex.pend
= 0;
6505 return yycompile
(vparser
, p
, fname
, line
);
6509 rb_parser_compile_string
(VALUE vparser
, const char *f
, VALUE s
, int line
)
6511 return rb_parser_compile_string_path
(vparser
, rb_filesystem_str_new_cstr
(f
), s
, line
);
6515 rb_parser_compile_string_path
(VALUE vparser
, VALUE f
, VALUE s
, int line
)
6517 must_be_ascii_compatible
(s
);
6518 return parser_compile_string
(vparser
, f
, s
, line
);
6521 VALUE rb_io_gets_internal
(VALUE io
);
6524 lex_io_gets
(struct parser_params
*p
, VALUE io
)
6526 return rb_io_gets_internal
(io
);
6530 rb_parser_compile_file_path
(VALUE vparser
, VALUE fname
, VALUE file
, int start
)
6532 struct parser_params
*p
;
6534 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
6536 p
->lex.gets
= lex_io_gets
;
6537 p
->lex.input
= file
;
6538 p
->lex.pbeg
= p
->lex.pcur
= p
->lex.pend
= 0;
6540 return yycompile
(vparser
, p
, fname
, start
);
6544 lex_generic_gets
(struct parser_params
*p
, VALUE input
)
6546 return
(*p
->lex.gets_.call
)(input
, p
->line_count
);
6550 rb_parser_compile_generic
(VALUE vparser
, VALUE
(*lex_gets
)(VALUE
, int), VALUE fname
, VALUE input
, int start
)
6552 struct parser_params
*p
;
6554 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
6556 p
->lex.gets
= lex_generic_gets
;
6557 p
->lex.gets_.call
= lex_gets
;
6558 p
->lex.input
= input
;
6559 p
->lex.pbeg
= p
->lex.pcur
= p
->lex.pend
= 0;
6561 return yycompile
(vparser
, p
, fname
, start
);
6563 #endif /* !RIPPER */
6565 #define STR_FUNC_ESCAPE 0x01
6566 #define STR_FUNC_EXPAND 0x02
6567 #define STR_FUNC_REGEXP 0x04
6568 #define STR_FUNC_QWORDS 0x08
6569 #define STR_FUNC_SYMBOL 0x10
6570 #define STR_FUNC_INDENT 0x20
6571 #define STR_FUNC_LABEL 0x40
6572 #define STR_FUNC_LIST 0x4000
6573 #define STR_FUNC_TERM 0x8000
6576 str_label
= STR_FUNC_LABEL
,
6578 str_dquote
= (STR_FUNC_EXPAND
),
6579 str_xquote
= (STR_FUNC_EXPAND
),
6580 str_regexp
= (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND
),
6581 str_sword
= (STR_FUNC_QWORDS|STR_FUNC_LIST
),
6582 str_dword
= (STR_FUNC_QWORDS|STR_FUNC_EXPAND|STR_FUNC_LIST
),
6583 str_ssym
= (STR_FUNC_SYMBOL
),
6584 str_dsym
= (STR_FUNC_SYMBOL|STR_FUNC_EXPAND
)
6588 parser_str_new
(const char *ptr
, long len
, rb_encoding
*enc
, int func
, rb_encoding
*enc0
)
6592 str
= rb_enc_str_new
(ptr
, len
, enc
);
6593 if
(!(func
& STR_FUNC_REGEXP
) && rb_enc_asciicompat
(enc
)) {
6594 if
(rb_enc_str_coderange
(str
) == ENC_CODERANGE_7BIT
) {
6596 else if
(enc0
== rb_usascii_encoding
() && enc
!= rb_utf8_encoding
()) {
6597 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
6604 #define lex_goto_eol(p) ((p)->lex.pcur = (p)->lex.pend)
6605 #define lex_eol_p(p) ((p)->lex.pcur >= (p)->lex.pend)
6606 #define lex_eol_n_p(p,n) ((p)->lex.pcur+(n) >= (p)->lex.pend)
6607 #define peek(p,c) peek_n(p, (c), 0)
6608 #define peek_n(p,c,n) (!lex_eol_n_p(p, n) && (c) == (unsigned char)(p)->lex.pcur[n])
6609 #define peekc(p) peekc_n(p, 0)
6610 #define peekc_n(p,n) (lex_eol_n_p(p, n) ? -1 : (unsigned char)(p)->lex.pcur[n])
6614 add_delayed_token
(struct parser_params
*p
, const char *tok
, const char *end
)
6617 if
(!has_delayed_token
(p
)) {
6618 p
->delayed.token
= rb_str_buf_new
(end
- tok
);
6619 rb_enc_associate
(p
->delayed.token
, p
->enc
);
6620 p
->delayed.line
= p
->ruby_sourceline
;
6621 p
->delayed.col
= rb_long2int
(tok
- p
->lex.pbeg
);
6623 rb_str_buf_cat
(p
->delayed.token
, tok
, end
- tok
);
6628 #define add_delayed_token(p, tok, end) ((void)(tok), (void)(end))
6632 nextline
(struct parser_params
*p
)
6634 VALUE v
= p
->lex.nextline
;
6635 p
->lex.nextline
= 0;
6640 if
(p
->lex.pend
> p
->lex.pbeg
&& *(p
->lex.pend
-1) != '\n') {
6644 if
(!p
->lex.input || NIL_P
(v
= lex_getline
(p
))) {
6652 else if
(NIL_P
(v
)) {
6653 /* after here-document without terminator */
6656 add_delayed_token
(p
, p
->lex.ptok
, p
->lex.pend
);
6657 if
(p
->heredoc_end
> 0) {
6658 p
->ruby_sourceline
= p
->heredoc_end
;
6661 p
->ruby_sourceline
++;
6662 p
->lex.pbeg
= p
->lex.pcur
= RSTRING_PTR
(v
);
6663 p
->lex.pend
= p
->lex.pcur
+ RSTRING_LEN
(v
);
6665 p
->lex.prevline
= p
->lex.lastline
;
6666 p
->lex.lastline
= v
;
6671 parser_cr
(struct parser_params
*p
, int c
)
6673 if
(peek
(p
, '\n')) {
6681 nextc
(struct parser_params
*p
)
6685 if
(UNLIKELY
((p
->lex.pcur
== p
->lex.pend
) || p
->eofp || RTEST
(p
->lex.nextline
))) {
6686 if
(nextline
(p
)) return
-1;
6688 c
= (unsigned char)*p
->lex.pcur
++;
6689 if
(UNLIKELY
(c
== '\r')) {
6690 c
= parser_cr
(p
, c
);
6697 pushback
(struct parser_params
*p
, int c
)
6699 if
(c
== -1) return
;
6701 if
(p
->lex.pcur
> p
->lex.pbeg
&& p
->lex.pcur
[0] == '\n' && p
->lex.pcur
[-1] == '\r') {
6706 #define was_bol(p) ((p)->lex.pcur == (p)->lex.pbeg + 1)
6708 #define tokfix(p) ((p)->tokenbuf[(p)->tokidx]='\0')
6709 #define tok(p) (p)->tokenbuf
6710 #define toklen(p) (p)->tokidx
6713 looking_at_eol_p
(struct parser_params
*p
)
6715 const char *ptr
= p
->lex.pcur
;
6716 while
(ptr
< p
->lex.pend
) {
6717 int c
= (unsigned char)*ptr
++;
6718 int eol
= (c
== '\n' || c
== '#');
6719 if
(eol ||
!ISSPACE
(c
)) {
6727 newtok
(struct parser_params
*p
)
6730 p
->tokline
= p
->ruby_sourceline
;
6733 p
->tokenbuf
= ALLOC_N
(char, 60);
6735 if
(p
->toksiz
> 4096) {
6737 REALLOC_N
(p
->tokenbuf
, char, 60);
6743 tokspace
(struct parser_params
*p
, int n
)
6747 if
(p
->tokidx
>= p
->toksiz
) {
6748 do
{p
->toksiz
*= 2;} while
(p
->toksiz
< p
->tokidx
);
6749 REALLOC_N
(p
->tokenbuf
, char, p
->toksiz
);
6751 return
&p
->tokenbuf
[p
->tokidx
-n
];
6755 tokadd
(struct parser_params
*p
, int c
)
6757 p
->tokenbuf
[p
->tokidx
++] = (char)c
;
6758 if
(p
->tokidx
>= p
->toksiz
) {
6760 REALLOC_N
(p
->tokenbuf
, char, p
->toksiz
);
6765 tok_hex
(struct parser_params
*p
, size_t *numlen
)
6769 c
= scan_hex
(p
->lex.pcur
, 2, numlen
);
6771 yyerror0
("invalid hex escape");
6775 p
->lex.pcur
+= *numlen
;
6779 #define tokcopy(p, n) memcpy(tokspace(p, n), (p)->lex.pcur - (n), (n))
6782 escaped_control_code
(int c
)
6808 #define WARN_SPACE_CHAR(c, prefix) \
6809 rb_warn1
("invalid character syntax; use "prefix
"\\%c", WARN_I
(c2
))
6812 tokadd_codepoint
(struct parser_params
*p
, rb_encoding
**encp
,
6813 int regexp_literal
, int wide
)
6816 int codepoint
= scan_hex
(p
->lex.pcur
, wide ? p
->lex.pend
- p
->lex.pcur
: 4, &numlen
);
6817 literal_flush
(p
, p
->lex.pcur
);
6818 p
->lex.pcur
+= numlen
;
6819 if
(wide ?
(numlen
== 0 || numlen
> 6) : (numlen
< 4)) {
6820 yyerror0
("invalid Unicode escape");
6821 return wide
&& numlen
> 0;
6823 if
(codepoint
> 0x10ffff) {
6824 yyerror0
("invalid Unicode codepoint (too large)");
6827 if
((codepoint
& 0xfffff800) == 0xd800) {
6828 yyerror0
("invalid Unicode codepoint");
6831 if
(regexp_literal
) {
6832 tokcopy
(p
, (int)numlen
);
6834 else if
(codepoint
>= 0x80) {
6835 rb_encoding
*utf8
= rb_utf8_encoding
();
6836 if
(*encp
&& utf8
!= *encp
) {
6837 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
6838 compile_error
(p
, "UTF-8 mixed within %s source", rb_enc_name
(*encp
));
6839 parser_show_error_line
(p
, &loc
);
6843 tokaddmbc
(p
, codepoint
, *encp
);
6846 tokadd
(p
, codepoint
);
6851 /* return value is for ?\u3042 */
6853 tokadd_utf8
(struct parser_params
*p
, rb_encoding
**encp
,
6854 int term
, int symbol_literal
, int regexp_literal
)
6857 * If `term` is not -1, then we allow multiple codepoints in \u{}
6858 * upto `term` byte, otherwise we're parsing a character literal.
6859 * And then add the codepoints to the current token.
6861 static const char multiple_codepoints
[] = "Multiple codepoints at single character literal";
6863 const int open_brace
= '{', close_brace
= '}';
6865 if
(regexp_literal
) { tokadd
(p
, '\\'); tokadd
(p
, 'u'); }
6867 if
(peek
(p
, open_brace
)) { /* handle \u{...} form */
6868 const char *second
= NULL
;
6869 int c
, last
= nextc
(p
);
6870 if
(p
->lex.pcur
>= p
->lex.pend
) goto unterminated
;
6871 while
(ISSPACE
(c
= *p
->lex.pcur
) && ++p
->lex.pcur
< p
->lex.pend
);
6872 while
(c
!= close_brace
) {
6873 if
(c
== term
) goto unterminated
;
6874 if
(second
== multiple_codepoints
)
6875 second
= p
->lex.pcur
;
6876 if
(regexp_literal
) tokadd
(p
, last
);
6877 if
(!tokadd_codepoint
(p
, encp
, regexp_literal
, TRUE
)) {
6880 while
(ISSPACE
(c
= *p
->lex.pcur
)) {
6881 if
(++p
->lex.pcur
>= p
->lex.pend
) goto unterminated
;
6884 if
(term
== -1 && !second
)
6885 second
= multiple_codepoints
;
6888 if
(c
!= close_brace
) {
6891 yyerror0
("unterminated Unicode escape");
6894 if
(second
&& second
!= multiple_codepoints
) {
6895 const char *pcur
= p
->lex.pcur
;
6896 p
->lex.pcur
= second
;
6897 dispatch_scan_event
(p
, tSTRING_CONTENT
);
6900 yyerror0
(multiple_codepoints
);
6904 if
(regexp_literal
) tokadd
(p
, close_brace
);
6907 else
{ /* handle \uxxxx form */
6908 if
(!tokadd_codepoint
(p
, encp
, regexp_literal
, FALSE
)) {
6915 #define ESCAPE_CONTROL 1
6916 #define ESCAPE_META 2
6919 read_escape
(struct parser_params
*p
, int flags
, rb_encoding
**encp
)
6924 switch
(c
= nextc
(p
)) {
6925 case
'\\': /* Backslash */
6928 case
'n': /* newline */
6931 case
't': /* horizontal tab */
6934 case
'r': /* carriage-return */
6937 case
'f': /* form-feed */
6940 case
'v': /* vertical tab */
6943 case
'a': /* alarm(bell) */
6946 case
'e': /* escape */
6949 case
'0': case
'1': case
'2': case
'3': /* octal constant */
6950 case
'4': case
'5': case
'6': case
'7':
6952 c
= scan_oct
(p
->lex.pcur
, 3, &numlen
);
6953 p
->lex.pcur
+= numlen
;
6956 case
'x': /* hex constant */
6957 c
= tok_hex
(p
, &numlen
);
6958 if
(numlen
== 0) return
0;
6961 case
'b': /* backspace */
6964 case
's': /* space */
6968 if
(flags
& ESCAPE_META
) goto eof
;
6969 if
((c
= nextc
(p
)) != '-') {
6972 if
((c
= nextc
(p
)) == '\\') {
6978 return read_escape
(p
, flags|ESCAPE_META
, encp
) |
0x80;
6980 else if
(c
== -1 ||
!ISASCII
(c
)) goto eof
;
6982 int c2
= escaped_control_code
(c
);
6984 if
(ISCNTRL
(c
) ||
!(flags
& ESCAPE_CONTROL
)) {
6985 WARN_SPACE_CHAR
(c2
, "\\M-");
6988 WARN_SPACE_CHAR
(c2
, "\\C-\\M-");
6991 else if
(ISCNTRL
(c
)) goto eof
;
6992 return
((c
& 0xff) |
0x80);
6996 if
((c
= nextc
(p
)) != '-') {
7000 if
(flags
& ESCAPE_CONTROL
) goto eof
;
7001 if
((c
= nextc
(p
))== '\\') {
7007 c
= read_escape
(p
, flags|ESCAPE_CONTROL
, encp
);
7011 else if
(c
== -1 ||
!ISASCII
(c
)) goto eof
;
7013 int c2
= escaped_control_code
(c
);
7016 if
(flags
& ESCAPE_META
) {
7017 WARN_SPACE_CHAR
(c2
, "\\M-");
7020 WARN_SPACE_CHAR
(c2
, "");
7024 if
(flags
& ESCAPE_META
) {
7025 WARN_SPACE_CHAR
(c2
, "\\M-\\C-");
7028 WARN_SPACE_CHAR
(c2
, "\\C-");
7032 else if
(ISCNTRL
(c
)) goto eof
;
7038 yyerror0
("Invalid escape character syntax");
7048 tokaddmbc
(struct parser_params
*p
, int c
, rb_encoding
*enc
)
7050 int len
= rb_enc_codelen
(c
, enc
);
7051 rb_enc_mbcput
(c
, tokspace
(p
, len
), enc
);
7055 tokadd_escape
(struct parser_params
*p
, rb_encoding
**encp
)
7060 switch
(c
= nextc
(p
)) {
7062 return
0; /* just ignore */
7064 case
'0': case
'1': case
'2': case
'3': /* octal constant */
7065 case
'4': case
'5': case
'6': case
'7':
7067 ruby_scan_oct
(--p
->lex.pcur
, 3, &numlen
);
7068 if
(numlen
== 0) goto eof
;
7069 p
->lex.pcur
+= numlen
;
7070 tokcopy
(p
, (int)numlen
+ 1);
7074 case
'x': /* hex constant */
7076 tok_hex
(p
, &numlen
);
7077 if
(numlen
== 0) return
-1;
7078 tokcopy
(p
, (int)numlen
+ 2);
7084 yyerror0
("Invalid escape character syntax");
7096 regx_options
(struct parser_params
*p
)
7104 while
(c
= nextc
(p
), ISALPHA
(c
)) {
7106 options |
= RE_OPTION_ONCE
;
7108 else if
(rb_char_to_option_kcode
(c
, &opt
, &kc
)) {
7110 if
(kc
!= rb_ascii8bit_encindex
()) kcode
= c
;
7124 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
7126 compile_error
(p
, "unknown regexp option%s - %*s",
7127 toklen
(p
) > 1 ?
"s" : "", toklen
(p
), tok
(p
));
7128 parser_show_error_line
(p
, &loc
);
7130 return options | RE_OPTION_ENCODING
(kcode
);
7134 tokadd_mbchar
(struct parser_params
*p
, int c
)
7136 int len
= parser_precise_mbclen
(p
, p
->lex.pcur
-1);
7137 if
(len
< 0) return
-1;
7139 p
->lex.pcur
+= --len
;
7140 if
(len
> 0) tokcopy
(p
, len
);
7145 simple_re_meta
(int c
)
7148 case
'$': case
'*': case
'+': case
'.':
7149 case
'?': case
'^': case
'|':
7150 case
')': case
']': case
'}': case
'>':
7158 parser_update_heredoc_indent
(struct parser_params
*p
, int c
)
7160 if
(p
->heredoc_line_indent
== -1) {
7161 if
(c
== '\n') p
->heredoc_line_indent
= 0;
7165 p
->heredoc_line_indent
++;
7168 else if
(c
== '\t') {
7169 int w
= (p
->heredoc_line_indent
/ TAB_WIDTH
) + 1;
7170 p
->heredoc_line_indent
= w
* TAB_WIDTH
;
7173 else if
(c
!= '\n') {
7174 if
(p
->heredoc_indent
> p
->heredoc_line_indent
) {
7175 p
->heredoc_indent
= p
->heredoc_line_indent
;
7177 p
->heredoc_line_indent
= -1;
7184 parser_mixed_error
(struct parser_params
*p
, rb_encoding
*enc1
, rb_encoding
*enc2
)
7186 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
7187 const char *n1
= rb_enc_name
(enc1
), *n2
= rb_enc_name
(enc2
);
7188 compile_error
(p
, "%s mixed within %s source", n1
, n2
);
7189 parser_show_error_line
(p
, &loc
);
7193 parser_mixed_escape
(struct parser_params
*p
, const char *beg
, rb_encoding
*enc1
, rb_encoding
*enc2
)
7195 const char *pos
= p
->lex.pcur
;
7197 parser_mixed_error
(p
, enc1
, enc2
);
7202 tokadd_string
(struct parser_params
*p
,
7203 int func
, int term
, int paren
, long *nest
,
7204 rb_encoding
**encp
, rb_encoding
**enc
)
7209 #define mixed_error(enc1, enc2) \
7210 (void)(erred ||
(parser_mixed_error
(p
, enc1
, enc2
), erred
= true
))
7211 #define mixed_escape(beg, enc1, enc2) \
7212 (void)(erred ||
(parser_mixed_escape
(p
, beg
, enc1
, enc2
), erred
= true
))
7214 while
((c
= nextc
(p
)) != -1) {
7215 if
(p
->heredoc_indent
> 0) {
7216 parser_update_heredoc_indent
(p
, c
);
7219 if
(paren
&& c
== paren
) {
7222 else if
(c
== term
) {
7223 if
(!nest ||
!*nest
) {
7229 else if
((func
& STR_FUNC_EXPAND
) && c
== '#' && p
->lex.pcur
< p
->lex.pend
) {
7230 int c2
= *p
->lex.pcur
;
7231 if
(c2
== '$' || c2
== '@' || c2
== '{') {
7236 else if
(c
== '\\') {
7237 literal_flush
(p
, p
->lex.pcur
- 1);
7241 if
(func
& STR_FUNC_QWORDS
) break
;
7242 if
(func
& STR_FUNC_EXPAND
) {
7243 if
(!(func
& STR_FUNC_INDENT
) ||
(p
->heredoc_indent
< 0))
7254 if
(func
& STR_FUNC_ESCAPE
) tokadd
(p
, c
);
7258 if
((func
& STR_FUNC_EXPAND
) == 0) {
7262 tokadd_utf8
(p
, enc
, term
,
7263 func
& STR_FUNC_SYMBOL
,
7264 func
& STR_FUNC_REGEXP
);
7268 if
(c
== -1) return
-1;
7270 if
((func
& STR_FUNC_EXPAND
) == 0) tokadd
(p
, '\\');
7273 if
(func
& STR_FUNC_REGEXP
) {
7279 c
= read_escape
(p
, 0, enc
);
7283 snprintf
(escbuf
, sizeof
(escbuf
), "\\x%02X", c
);
7284 for
(i
= 0; i
< 4; i
++) {
7285 tokadd
(p
, escbuf
[i
]);
7291 if
(c
== term
&& !simple_re_meta
(c
)) {
7296 if
((c
= tokadd_escape
(p
, enc
)) < 0)
7298 if
(*enc
&& *enc
!= *encp
) {
7299 mixed_escape
(p
->lex.ptok
+2, *enc
, *encp
);
7303 else if
(func
& STR_FUNC_EXPAND
) {
7305 if
(func
& STR_FUNC_ESCAPE
) tokadd
(p
, '\\');
7306 c
= read_escape
(p
, 0, enc
);
7308 else if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
7309 /* ignore backslashed spaces in %w */
7311 else if
(c
!= term
&& !(paren
&& c
== paren
)) {
7318 else if
(!parser_isascii
(p
)) {
7323 else if
(*enc
!= *encp
) {
7324 mixed_error
(*enc
, *encp
);
7327 if
(tokadd_mbchar
(p
, c
) == -1) return
-1;
7330 else if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
7338 else if
(*enc
!= *encp
) {
7339 mixed_error
(*enc
, *encp
);
7346 if
(*enc
) *encp
= *enc
;
7350 static inline rb_strterm_t
*
7351 new_strterm
(VALUE v1
, VALUE v2
, VALUE v3
, VALUE v0
)
7353 return
(rb_strterm_t
*)rb_imemo_new
(imemo_parser_strterm
, v1
, v2
, v3
, v0
);
7356 /* imemo_parser_strterm for literal */
7357 #define NEW_STRTERM(func, term, paren) \
7358 new_strterm
((VALUE
)(func
), (VALUE
)(paren
), (VALUE
)(term
), 0)
7362 flush_string_content
(struct parser_params
*p
, rb_encoding
*enc
)
7364 VALUE content
= yylval.val
;
7365 if
(!ripper_is_node_yylval
(content
))
7366 content
= ripper_new_yylval
(p
, 0, 0, content
);
7367 if
(has_delayed_token
(p
)) {
7368 ptrdiff_t len
= p
->lex.pcur
- p
->lex.ptok
;
7370 rb_enc_str_buf_cat
(p
->delayed.token
, p
->lex.ptok
, len
, enc
);
7372 dispatch_delayed_token
(p
, tSTRING_CONTENT
);
7373 p
->lex.ptok
= p
->lex.pcur
;
7374 RNODE
(content
)->nd_rval
= yylval.val
;
7376 dispatch_scan_event
(p
, tSTRING_CONTENT
);
7377 if
(yylval.val
!= content
)
7378 RNODE
(content
)->nd_rval
= yylval.val
;
7379 yylval.val
= content
;
7382 #define flush_string_content(p, enc) ((void)(enc))
7385 RUBY_FUNC_EXPORTED
const unsigned int ruby_global_name_punct_bits
[(0x7e - 0x20 + 31) / 32];
7386 /* this can be shared with ripper, since it's independent from struct
7389 #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
7390 #define SPECIAL_PUNCT(idx) ( \
7391 BIT
('~', idx
) | BIT
('*', idx
) | BIT
('$', idx
) | BIT
('?', idx
) | \
7392 BIT
('!', idx
) | BIT
('@', idx
) | BIT
('/', idx
) | BIT
('\\', idx
) | \
7393 BIT
(';', idx
) | BIT
(',', idx
) | BIT
('.', idx
) | BIT
('=', idx
) | \
7394 BIT
(':', idx
) | BIT
('<', idx
) | BIT
('>', idx
) | BIT
('\"', idx
) | \
7395 BIT
('&', idx
) | BIT
('`', idx
) | BIT
('\'', idx
) | BIT
('+', idx
) | \
7397 const unsigned int ruby_global_name_punct_bits
[] = {
7403 #undef SPECIAL_PUNCT
7406 static enum yytokentype
7407 parser_peek_variable_name
(struct parser_params
*p
)
7410 const char *ptr
= p
->lex.pcur
;
7412 if
(ptr
+ 1 >= p
->lex.pend
) return
0;
7416 if
((c
= *ptr
) == '-') {
7417 if
(++ptr
>= p
->lex.pend
) return
0;
7420 else if
(is_global_name_punct
(c
) || ISDIGIT
(c
)) {
7421 return tSTRING_DVAR
;
7425 if
((c
= *ptr
) == '@') {
7426 if
(++ptr
>= p
->lex.pend
) return
0;
7432 p
->command_start
= TRUE
;
7433 return tSTRING_DBEG
;
7437 if
(!ISASCII
(c
) || c
== '_' || ISALPHA
(c
))
7438 return tSTRING_DVAR
;
7442 #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
7443 #define IS_END() IS_lex_state(EXPR_END_ANY)
7444 #define IS_BEG() (IS_lex_state(EXPR_BEG_ANY) || IS_lex_state_all(EXPR_ARG|EXPR_LABELED))
7445 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
7446 #define IS_LABEL_POSSIBLE() (\
7447 (IS_lex_state
(EXPR_LABEL|EXPR_ENDFN
) && !cmd_state
) || \
7449 #define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
7450 #define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
7452 static inline
enum yytokentype
7453 parser_string_term
(struct parser_params
*p
, int func
)
7456 if
(func
& STR_FUNC_REGEXP
) {
7457 set_yylval_num
(regx_options
(p
));
7458 dispatch_scan_event
(p
, tREGEXP_END
);
7459 SET_LEX_STATE
(EXPR_END
);
7462 if
((func
& STR_FUNC_LABEL
) && IS_LABEL_SUFFIX
(0)) {
7464 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
7467 SET_LEX_STATE
(EXPR_END
);
7471 static enum yytokentype
7472 parse_string
(struct parser_params
*p
, rb_strterm_literal_t
*quote
)
7474 int func
= (int)quote
->u1.func
;
7475 int term
= (int)quote
->u3.term
;
7476 int paren
= (int)quote
->u2.paren
;
7478 rb_encoding
*enc
= p
->enc
;
7479 rb_encoding
*base_enc
= 0;
7482 if
(func
& STR_FUNC_TERM
) {
7483 if
(func
& STR_FUNC_QWORDS
) nextc
(p
); /* delayed term */
7484 SET_LEX_STATE
(EXPR_END
);
7486 return func
& STR_FUNC_REGEXP ? tREGEXP_END
: tSTRING_END
;
7489 if
((func
& STR_FUNC_QWORDS
) && ISSPACE
(c
)) {
7490 do
{c
= nextc
(p
);} while
(ISSPACE
(c
));
7493 if
(func
& STR_FUNC_LIST
) {
7494 quote
->u1.func
&= ~STR_FUNC_LIST
;
7497 if
(c
== term
&& !quote
->u0.nest
) {
7498 if
(func
& STR_FUNC_QWORDS
) {
7499 quote
->u1.func |
= STR_FUNC_TERM
;
7500 pushback
(p
, c
); /* dispatch the term at tSTRING_END */
7501 add_delayed_token
(p
, p
->lex.ptok
, p
->lex.pcur
);
7504 return parser_string_term
(p
, func
);
7508 add_delayed_token
(p
, p
->lex.ptok
, p
->lex.pcur
);
7512 if
((func
& STR_FUNC_EXPAND
) && c
== '#') {
7513 int t
= parser_peek_variable_name
(p
);
7519 if
(tokadd_string
(p
, func
, term
, paren
, "e
->u0.nest
,
7520 &enc
, &base_enc
) == -1) {
7523 # define unterminated_literal(mesg) yyerror0(mesg)
7525 # define unterminated_literal(mesg) compile_error(p, mesg)
7527 literal_flush
(p
, p
->lex.pcur
);
7528 if
(func
& STR_FUNC_QWORDS
) {
7529 /* no content to add, bailing out here */
7530 unterminated_literal
("unterminated list meets end of file");
7534 if
(func
& STR_FUNC_REGEXP
) {
7535 unterminated_literal
("unterminated regexp meets end of file");
7538 unterminated_literal
("unterminated string meets end of file");
7540 quote
->u1.func |
= STR_FUNC_TERM
;
7545 lit
= STR_NEW3
(tok
(p
), toklen
(p
), enc
, func
);
7546 set_yylval_str
(lit
);
7547 flush_string_content
(p
, enc
);
7549 return tSTRING_CONTENT
;
7552 static enum yytokentype
7553 heredoc_identifier
(struct parser_params
*p
)
7556 * term_len is length of `<<"END"` except `END`,
7557 * in this case term_len is 4 (<, <, " and ").
7559 long len
, offset
= p
->lex.pcur
- p
->lex.pbeg
;
7560 int c
= nextc
(p
), term
, func
= 0, quote
= 0;
7561 enum yytokentype token
= tSTRING_BEG
;
7566 func
= STR_FUNC_INDENT
;
7569 else if
(c
== '~') {
7571 func
= STR_FUNC_INDENT
;
7577 func |
= str_squote
; goto quoted
;
7579 func |
= str_dquote
; goto quoted
;
7581 token
= tXSTRING_BEG
;
7582 func |
= str_xquote
; goto quoted
;
7589 while
((c
= nextc
(p
)) != term
) {
7590 if
(c
== -1 || c
== '\r' || c
== '\n') {
7591 yyerror0
("unterminated here document identifier");
7598 if
(!parser_is_identchar
(p
)) {
7600 if
(func
& STR_FUNC_INDENT
) {
7601 pushback
(p
, indent
> 0 ?
'~' : '-');
7607 int n
= parser_precise_mbclen
(p
, p
->lex.pcur
-1);
7608 if
(n
< 0) return
0;
7610 } while
((c
= nextc
(p
)) != -1 && parser_is_identchar
(p
));
7615 len
= p
->lex.pcur
- (p
->lex.pbeg
+ offset
) - quote
;
7616 if
((unsigned long)len
>= HERETERM_LENGTH_MAX
)
7617 yyerror0
("too long here document identifier");
7618 dispatch_scan_event
(p
, tHEREDOC_BEG
);
7621 p
->lex.strterm
= new_strterm
(0, 0, 0, p
->lex.lastline
);
7622 p
->lex.strterm
->flags |
= STRTERM_HEREDOC
;
7623 rb_strterm_heredoc_t
*here
= &p
->lex.strterm
->u.heredoc
;
7624 here
->offset
= offset
;
7625 here
->sourceline
= p
->ruby_sourceline
;
7626 here
->length
= (int)len
;
7627 here
->quote
= quote
;
7631 p
->heredoc_indent
= indent
;
7632 p
->heredoc_line_indent
= 0;
7637 heredoc_restore
(struct parser_params
*p
, rb_strterm_heredoc_t
*here
)
7642 line
= here
->lastline
;
7643 p
->lex.lastline
= line
;
7644 p
->lex.pbeg
= RSTRING_PTR
(line
);
7645 p
->lex.pend
= p
->lex.pbeg
+ RSTRING_LEN
(line
);
7646 p
->lex.pcur
= p
->lex.pbeg
+ here
->offset
+ here
->length
+ here
->quote
;
7647 p
->lex.ptok
= p
->lex.pbeg
+ here
->offset
- here
->quote
;
7648 p
->heredoc_end
= p
->ruby_sourceline
;
7649 p
->ruby_sourceline
= (int)here
->sourceline
;
7650 if
(p
->eofp
) p
->lex.nextline
= Qnil
;
7655 dedent_string
(VALUE
string, int width
)
7661 RSTRING_GETMEM
(string, str
, len
);
7662 for
(i
= 0; i
< len
&& col
< width
; i
++) {
7663 if
(str
[i
] == ' ') {
7666 else if
(str
[i
] == '\t') {
7667 int n
= TAB_WIDTH
* (col
/ TAB_WIDTH
+ 1);
7668 if
(n
> width
) break
;
7676 rb_str_modify
(string);
7677 str
= RSTRING_PTR
(string);
7678 if
(RSTRING_LEN
(string) != len
)
7679 rb_fatal
("literal string changed: %+"PRIsVALUE
, string);
7680 MEMMOVE
(str
, str
+ i
, char, len
- i
);
7681 rb_str_set_len
(string, len
- i
);
7687 heredoc_dedent
(struct parser_params
*p
, NODE
*root
)
7689 NODE
*node
, *str_node
, *prev_node
;
7690 int indent
= p
->heredoc_indent
;
7693 if
(indent
<= 0) return root
;
7694 p
->heredoc_indent
= 0;
7695 if
(!root
) return root
;
7697 prev_node
= node
= str_node
= root
;
7698 if
(nd_type_p
(root
, NODE_LIST
)) str_node
= root
->nd_head
;
7701 VALUE lit
= str_node
->nd_lit
;
7702 if
(str_node
->flags
& NODE_FL_NEWLINE
) {
7703 dedent_string
(lit
, indent
);
7708 else if
(!literal_concat0
(p
, prev_lit
, lit
)) {
7712 NODE
*end
= node
->nd_end
;
7713 node
= prev_node
->nd_next
= node
->nd_next
;
7715 if
(nd_type_p
(prev_node
, NODE_DSTR
))
7716 nd_set_type
(prev_node
, NODE_STR
);
7724 while
((node
= (prev_node
= node
)->nd_next
) != 0) {
7726 if
(!nd_type_p
(node
, NODE_LIST
)) break
;
7727 if
((str_node
= node
->nd_head
) != 0) {
7728 enum node_type type
= nd_type
(str_node
);
7729 if
(type
== NODE_STR || type
== NODE_DSTR
) break
;
7739 heredoc_dedent
(struct parser_params
*p
, VALUE array
)
7741 int indent
= p
->heredoc_indent
;
7743 if
(indent
<= 0) return array
;
7744 p
->heredoc_indent
= 0;
7745 dispatch2
(heredoc_dedent
, array
, INT2NUM
(indent
));
7751 * Ripper.dedent_string(input, width) -> Integer
7753 * USE OF RIPPER LIBRARY ONLY.
7755 * Strips up to +width+ leading whitespaces from +input+,
7756 * and returns the stripped column width.
7759 parser_dedent_string
(VALUE self
, VALUE input
, VALUE width
)
7764 wid
= NUM2UINT
(width
);
7765 col
= dedent_string
(input
, wid
);
7766 return INT2NUM
(col
);
7771 whole_match_p
(struct parser_params
*p
, const char *eos
, long len
, int indent
)
7773 const char *ptr
= p
->lex.pbeg
;
7777 while
(*ptr
&& ISSPACE
(*ptr
)) ptr
++;
7779 n
= p
->lex.pend
- (ptr
+ len
);
7780 if
(n
< 0) return FALSE
;
7781 if
(n
> 0 && ptr
[len
] != '\n') {
7782 if
(ptr
[len
] != '\r') return FALSE
;
7783 if
(n
<= 1 || ptr
[len
+1] != '\n') return FALSE
;
7785 return strncmp
(eos
, ptr
, len
) == 0;
7789 word_match_p
(struct parser_params
*p
, const char *word
, long len
)
7791 if
(strncmp
(p
->lex.pcur
, word
, len
)) return
0;
7792 if
(p
->lex.pcur
+ len
== p
->lex.pend
) return
1;
7793 int c
= (unsigned char)p
->lex.pcur
[len
];
7794 if
(ISSPACE
(c
)) return
1;
7796 case
'\0': case
'\004': case
'\032': return
1;
7801 #define NUM_SUFFIX_R (1<<0)
7802 #define NUM_SUFFIX_I (1<<1)
7803 #define NUM_SUFFIX_ALL 3
7806 number_literal_suffix
(struct parser_params
*p
, int mask
)
7809 const char *lastp
= p
->lex.pcur
;
7811 while
((c
= nextc
(p
)) != -1) {
7812 if
((mask
& NUM_SUFFIX_I
) && c
== 'i') {
7813 result |
= (mask
& NUM_SUFFIX_I
);
7814 mask
&= ~NUM_SUFFIX_I
;
7815 /* r after i, rational of complex is disallowed */
7816 mask
&= ~NUM_SUFFIX_R
;
7819 if
((mask
& NUM_SUFFIX_R
) && c
== 'r') {
7820 result |
= (mask
& NUM_SUFFIX_R
);
7821 mask
&= ~NUM_SUFFIX_R
;
7824 if
(!ISASCII
(c
) || ISALPHA
(c
) || c
== '_') {
7825 p
->lex.pcur
= lastp
;
7826 literal_flush
(p
, p
->lex.pcur
);
7835 static enum yytokentype
7836 set_number_literal
(struct parser_params
*p
, VALUE v
,
7837 enum yytokentype type
, int suffix
)
7839 if
(suffix
& NUM_SUFFIX_I
) {
7840 v
= rb_complex_raw
(INT2FIX
(0), v
);
7843 set_yylval_literal
(v
);
7844 SET_LEX_STATE
(EXPR_END
);
7848 static enum yytokentype
7849 set_integer_literal
(struct parser_params
*p
, VALUE v
, int suffix
)
7851 enum yytokentype type
= tINTEGER
;
7852 if
(suffix
& NUM_SUFFIX_R
) {
7853 v
= rb_rational_raw1
(v
);
7856 return set_number_literal
(p
, v
, type
, suffix
);
7861 dispatch_heredoc_end
(struct parser_params
*p
)
7864 if
(has_delayed_token
(p
))
7865 dispatch_delayed_token
(p
, tSTRING_CONTENT
);
7866 str
= STR_NEW
(p
->lex.ptok
, p
->lex.pend
- p
->lex.ptok
);
7867 ripper_dispatch1
(p
, ripper_token2eventid
(tHEREDOC_END
), str
);
7873 #define dispatch_heredoc_end(p) ((void)0)
7876 static enum yytokentype
7877 here_document
(struct parser_params
*p
, rb_strterm_heredoc_t
*here
)
7879 int c
, func
, indent
= 0;
7880 const char *eos
, *ptr
, *ptr_end
;
7883 rb_encoding
*enc
= p
->enc
;
7884 rb_encoding
*base_enc
= 0;
7887 eos
= RSTRING_PTR
(here
->lastline
) + here
->offset
;
7889 indent
= (func
= here
->func
) & STR_FUNC_INDENT
;
7891 if
((c
= nextc
(p
)) == -1) {
7894 if
(!has_delayed_token
(p
)) {
7895 dispatch_scan_event
(p
, tSTRING_CONTENT
);
7898 if
((len
= p
->lex.pcur
- p
->lex.ptok
) > 0) {
7899 if
(!(func
& STR_FUNC_REGEXP
) && rb_enc_asciicompat
(enc
)) {
7900 int cr
= ENC_CODERANGE_UNKNOWN
;
7901 rb_str_coderange_scan_restartable
(p
->lex.ptok
, p
->lex.pcur
, enc
, &cr
);
7902 if
(cr
!= ENC_CODERANGE_7BIT
&&
7903 p
->enc
== rb_usascii_encoding
() &&
7904 enc
!= rb_utf8_encoding
()) {
7905 enc
= rb_ascii8bit_encoding
();
7908 rb_enc_str_buf_cat
(p
->delayed.token
, p
->lex.ptok
, len
, enc
);
7910 dispatch_delayed_token
(p
, tSTRING_CONTENT
);
7914 heredoc_restore
(p
, &p
->lex.strterm
->u.heredoc
);
7915 compile_error
(p
, "can't find string \"%.*s\" anywhere before EOF",
7919 SET_LEX_STATE
(EXPR_END
);
7924 /* not beginning of line, cannot be the terminator */
7926 else if
(p
->heredoc_line_indent
== -1) {
7927 /* `heredoc_line_indent == -1` means
7928 * - "after an interpolation in the same line", or
7929 * - "in a continuing line"
7931 p
->heredoc_line_indent
= 0;
7933 else if
(whole_match_p
(p
, eos
, len
, indent
)) {
7934 dispatch_heredoc_end
(p
);
7936 heredoc_restore
(p
, &p
->lex.strterm
->u.heredoc
);
7939 SET_LEX_STATE
(EXPR_END
);
7943 if
(!(func
& STR_FUNC_EXPAND
)) {
7945 ptr
= RSTRING_PTR
(p
->lex.lastline
);
7946 ptr_end
= p
->lex.pend
;
7947 if
(ptr_end
> ptr
) {
7948 switch
(ptr_end
[-1]) {
7950 if
(--ptr_end
== ptr || ptr_end
[-1] != '\r') {
7959 if
(p
->heredoc_indent
> 0) {
7961 while
(ptr
+ i
< ptr_end
&& parser_update_heredoc_indent
(p
, ptr
[i
]))
7963 p
->heredoc_line_indent
= 0;
7967 rb_str_cat
(str
, ptr
, ptr_end
- ptr
);
7969 str
= STR_NEW
(ptr
, ptr_end
- ptr
);
7970 if
(ptr_end
< p
->lex.pend
) rb_str_cat
(str
, "\n", 1);
7972 if
(p
->heredoc_indent
> 0) {
7975 if
(nextc
(p
) == -1) {
7981 } while
(!whole_match_p
(p
, eos
, len
, indent
));
7984 /* int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
7987 int t
= parser_peek_variable_name
(p
);
7988 if
(p
->heredoc_line_indent
!= -1) {
7989 if
(p
->heredoc_indent
> p
->heredoc_line_indent
) {
7990 p
->heredoc_indent
= p
->heredoc_line_indent
;
7992 p
->heredoc_line_indent
= -1;
8001 if
((c
= tokadd_string
(p
, func
, '\n', 0, NULL
, &enc
, &base_enc
)) == -1) {
8002 if
(p
->eofp
) goto
error;
8006 if
(c
== '\\') p
->heredoc_line_indent
= -1;
8008 str
= STR_NEW3
(tok
(p
), toklen
(p
), enc
, func
);
8010 set_yylval_str
(str
);
8012 if
(bol
) yylval.node
->flags |
= NODE_FL_NEWLINE
;
8014 flush_string_content
(p
, enc
);
8015 return tSTRING_CONTENT
;
8017 tokadd
(p
, nextc
(p
));
8018 if
(p
->heredoc_indent
> 0) {
8022 /* if (mbp && mb == ENC_CODERANGE_UNKNOWN) mbp = 0;*/
8023 if
((c
= nextc
(p
)) == -1) goto
error;
8024 } while
(!whole_match_p
(p
, eos
, len
, indent
));
8025 str
= STR_NEW3
(tok
(p
), toklen
(p
), enc
, func
);
8027 dispatch_heredoc_end
(p
);
8029 str
= ripper_new_yylval
(p
, ripper_token2eventid
(tSTRING_CONTENT
),
8032 heredoc_restore
(p
, &p
->lex.strterm
->u.heredoc
);
8034 p
->lex.strterm
= NEW_STRTERM
(func | STR_FUNC_TERM
, 0, 0);
8035 set_yylval_str
(str
);
8037 if
(bol
) yylval.node
->flags |
= NODE_FL_NEWLINE
;
8039 return tSTRING_CONTENT
;
8045 arg_ambiguous
(struct parser_params
*p
, char c
)
8049 rb_warning1
("ambiguity between regexp and two divisions: wrap regexp in parentheses or add a space after `%c' operator", WARN_I
(c
));
8052 rb_warning1
("ambiguous first argument; put parentheses or a space even after `%c' operator", WARN_I
(c
));
8055 dispatch1
(arg_ambiguous
, rb_usascii_str_new
(&c
, 1));
8062 formal_argument
(struct parser_params
*p
, ID lhs
)
8064 formal_argument
(struct parser_params
*p
, VALUE lhs
)
8067 ID id
= get_id
(lhs
);
8069 switch
(id_type
(id
)) {
8073 # define ERR(mesg) yyerror0(mesg)
8075 # define ERR(mesg) (dispatch2(param_error, WARN_S(mesg), lhs), ripper_error(p))
8078 ERR
("formal argument cannot be a constant");
8081 ERR
("formal argument cannot be an instance variable");
8084 ERR
("formal argument cannot be a global variable");
8087 ERR
("formal argument cannot be a class variable");
8090 ERR
("formal argument must be local variable");
8094 shadowing_lvar
(p
, id
);
8099 lvar_defined
(struct parser_params
*p
, ID id
)
8101 return
(dyna_in_block
(p
) && dvar_defined
(p
, id
)) || local_id
(p
, id
);
8104 /* emacsen -*- hack */
8106 parser_encode_length
(struct parser_params
*p
, const char *name
, long len
)
8110 if
(len
> 5 && name
[nlen
= len
- 5] == '-') {
8111 if
(rb_memcicmp
(name
+ nlen
+ 1, "unix", 4) == 0)
8114 if
(len
> 4 && name
[nlen
= len
- 4] == '-') {
8115 if
(rb_memcicmp
(name
+ nlen
+ 1, "dos", 3) == 0)
8117 if
(rb_memcicmp
(name
+ nlen
+ 1, "mac", 3) == 0 &&
8118 !(len
== 8 && rb_memcicmp
(name
, "utf8-mac", len
) == 0))
8119 /* exclude UTF8-MAC because the encoding named "UTF8" doesn't exist in Ruby */
8126 parser_set_encode
(struct parser_params
*p
, const char *name
)
8128 int idx
= rb_enc_find_index
(name
);
8133 excargs
[1] = rb_sprintf
("unknown encoding name: %s", name
);
8135 excargs
[0] = rb_eArgError
;
8136 excargs
[2] = rb_make_backtrace
();
8137 rb_ary_unshift
(excargs
[2], rb_sprintf
("%"PRIsVALUE
":%d", p
->ruby_sourcefile_string
, p
->ruby_sourceline
));
8138 rb_exc_raise
(rb_make_exception
(3, excargs
));
8140 enc
= rb_enc_from_index
(idx
);
8141 if
(!rb_enc_asciicompat
(enc
)) {
8142 excargs
[1] = rb_sprintf
("%s is not ASCII compatible", rb_enc_name
(enc
));
8147 if
(p
->debug_lines
) {
8148 VALUE lines
= p
->debug_lines
;
8149 long i
, n
= RARRAY_LEN
(lines
);
8150 for
(i
= 0; i
< n
; ++i
) {
8151 rb_enc_associate_index
(RARRAY_AREF
(lines
, i
), idx
);
8158 comment_at_top
(struct parser_params
*p
)
8160 const char *ptr
= p
->lex.pbeg
, *ptr_end
= p
->lex.pcur
- 1;
8161 if
(p
->line_count
!= (p
->has_shebang ?
2 : 1)) return
0;
8162 while
(ptr
< ptr_end
) {
8163 if
(!ISSPACE
(*ptr
)) return
0;
8169 typedef
long (*rb_magic_comment_length_t
)(struct parser_params
*p
, const char *name
, long len
);
8170 typedef
void (*rb_magic_comment_setter_t
)(struct parser_params
*p
, const char *name
, const char *val
);
8172 static int parser_invalid_pragma_value
(struct parser_params
*p
, const char *name
, const char *val
);
8175 magic_comment_encoding
(struct parser_params
*p
, const char *name
, const char *val
)
8177 if
(!comment_at_top
(p
)) {
8180 parser_set_encode
(p
, val
);
8184 parser_get_bool
(struct parser_params
*p
, const char *name
, const char *val
)
8188 if
(STRCASECMP
(val
, "true") == 0) {
8193 if
(STRCASECMP
(val
, "false") == 0) {
8198 return parser_invalid_pragma_value
(p
, name
, val
);
8202 parser_invalid_pragma_value
(struct parser_params
*p
, const char *name
, const char *val
)
8204 rb_warning2
("invalid value for %s: %s", WARN_S
(name
), WARN_S
(val
));
8209 parser_set_token_info
(struct parser_params
*p
, const char *name
, const char *val
)
8211 int b
= parser_get_bool
(p
, name
, val
);
8212 if
(b
>= 0) p
->token_info_enabled
= b
;
8216 parser_set_compile_option_flag
(struct parser_params
*p
, const char *name
, const char *val
)
8220 if
(p
->token_seen
) {
8221 rb_warning1
("`%s' is ignored after any tokens", WARN_S
(name
));
8225 b
= parser_get_bool
(p
, name
, val
);
8228 if
(!p
->compile_option
)
8229 p
->compile_option
= rb_obj_hide
(rb_ident_hash_new
());
8230 rb_hash_aset
(p
->compile_option
, ID2SYM
(rb_intern
(name
)),
8235 parser_set_shareable_constant_value
(struct parser_params
*p
, const char *name
, const char *val
)
8237 for
(const char *s
= p
->lex.pbeg
, *e
= p
->lex.pcur
; s
< e
; ++s
) {
8238 if
(*s
== ' ' ||
*s
== '\t') continue
;
8239 if
(*s
== '#') break
;
8240 rb_warning1
("`%s' is ignored unless in comment-only line", WARN_S
(name
));
8246 if
(STRCASECMP
(val
, "none") == 0) {
8247 p
->ctxt.shareable_constant_value
= shareable_none
;
8252 if
(STRCASECMP
(val
, "literal") == 0) {
8253 p
->ctxt.shareable_constant_value
= shareable_literal
;
8258 if
(STRCASECMP
(val
, "experimental_copy") == 0) {
8259 p
->ctxt.shareable_constant_value
= shareable_copy
;
8262 if
(STRCASECMP
(val
, "experimental_everything") == 0) {
8263 p
->ctxt.shareable_constant_value
= shareable_everything
;
8268 parser_invalid_pragma_value
(p
, name
, val
);
8271 # if WARN_PAST_SCOPE
8273 parser_set_past_scope
(struct parser_params
*p
, const char *name
, const char *val
)
8275 int b
= parser_get_bool
(p
, name
, val
);
8276 if
(b
>= 0) p
->past_scope_enabled
= b
;
8280 struct magic_comment
{
8282 rb_magic_comment_setter_t func
;
8283 rb_magic_comment_length_t length
;
8286 static const struct magic_comment magic_comments
[] = {
8287 {"coding", magic_comment_encoding
, parser_encode_length
},
8288 {"encoding", magic_comment_encoding
, parser_encode_length
},
8289 {"frozen_string_literal", parser_set_compile_option_flag
},
8290 {"shareable_constant_value", parser_set_shareable_constant_value
},
8291 {"warn_indent", parser_set_token_info
},
8292 # if WARN_PAST_SCOPE
8293 {"warn_past_scope", parser_set_past_scope
},
8298 magic_comment_marker
(const char *str
, long len
)
8305 if
(str
[i
-1] == '*' && str
[i
-2] == '-') {
8311 if
(i
+ 1 >= len
) return
0;
8312 if
(str
[i
+1] != '-') {
8315 else if
(str
[i
-1] != '-') {
8331 parser_magic_comment
(struct parser_params
*p
, const char *str
, long len
)
8334 VALUE name
= 0, val
= 0;
8335 const char *beg
, *end
, *vbeg
, *vend
;
8336 #define str_copy(_s, _p, _n) ((_s) \
8337 ?
(void)(rb_str_resize
((_s
), (_n
)), \
8338 MEMCPY
(RSTRING_PTR
(_s
), (_p
), char, (_n
)), (_s
)) \
8339 : (void)((_s
) = STR_NEW
((_p
), (_n
))))
8341 if
(len
<= 7) return FALSE
;
8342 if
(!!(beg
= magic_comment_marker
(str
, len
))) {
8343 if
(!(end
= magic_comment_marker
(beg
, str
+ len
- beg
)))
8347 len
= end
- beg
- 3;
8350 /* %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" */
8352 const struct magic_comment
*mc
= magic_comments
;
8357 for
(; len
> 0 && *str
; str
++, --len
) {
8359 case
'\'': case
'"': case
':': case
';':
8362 if
(!ISSPACE
(*str
)) break
;
8364 for
(beg
= str
; len
> 0; str
++, --len
) {
8366 case
'\'': case
'"': case
':': case
';':
8369 if
(ISSPACE
(*str
)) break
;
8374 for
(end
= str
; len
> 0 && ISSPACE
(*str
); str
++, --len
);
8377 if
(!indicator
) return FALSE
;
8381 do str
++; while
(--len
> 0 && ISSPACE
(*str
));
8384 for
(vbeg
= ++str
; --len
> 0 && *str
!= '"'; str
++) {
8397 for
(vbeg
= str
; len
> 0 && *str
!= '"' && *str
!= ';' && !ISSPACE
(*str
); --len
, str
++);
8401 while
(len
> 0 && (*str
== ';' || ISSPACE
(*str
))) --len
, str
++;
8404 while
(len
> 0 && (ISSPACE
(*str
))) --len
, str
++;
8405 if
(len
) return FALSE
;
8409 str_copy
(name
, beg
, n
);
8410 s
= RSTRING_PTR
(name
);
8411 for
(i
= 0; i
< n
; ++i
) {
8412 if
(s
[i
] == '-') s
[i
] = '_';
8415 if
(STRNCASECMP
(mc
->name
, s
, n
) == 0 && !mc
->name
[n
]) {
8418 n
= (*mc
->length
)(p
, vbeg
, n
);
8420 str_copy
(val
, vbeg
, n
);
8421 (*mc
->func
)(p
, mc
->name
, RSTRING_PTR
(val
));
8424 } while
(++mc
< magic_comments
+ numberof
(magic_comments
));
8426 str_copy
(val
, vbeg
, vend
- vbeg
);
8427 dispatch2
(magic_comment
, name
, val
);
8435 set_file_encoding
(struct parser_params
*p
, const char *str
, const char *send
)
8438 const char *beg
= str
;
8442 if
(send
- str
<= 6) return
;
8444 case
'C': case
'c': str
+= 6; continue
;
8445 case
'O': case
'o': str
+= 5; continue
;
8446 case
'D': case
'd': str
+= 4; continue
;
8447 case
'I': case
'i': str
+= 3; continue
;
8448 case
'N': case
'n': str
+= 2; continue
;
8449 case
'G': case
'g': str
+= 1; continue
;
8456 if
(ISSPACE
(*str
)) break
;
8459 if
(STRNCASECMP
(str
-6, "coding", 6) == 0) break
;
8464 if
(++str
>= send
) return
;
8465 } while
(ISSPACE
(*str
));
8467 if
(*str
!= '=' && *str
!= ':') return
;
8472 while
((*str
== '-' ||
*str
== '_' || ISALNUM
(*str
)) && ++str
< send
);
8473 s
= rb_str_new
(beg
, parser_encode_length
(p
, beg
, str
- beg
));
8474 parser_set_encode
(p
, RSTRING_PTR
(s
));
8475 rb_str_resize
(s
, 0);
8479 parser_prepare
(struct parser_params
*p
)
8482 p
->token_info_enabled
= !compile_for_eval
&& RTEST
(ruby_verbose
);
8485 if
(peek
(p
, '!')) p
->has_shebang
= 1;
8487 case
0xef: /* UTF-8 BOM marker */
8488 if
(p
->lex.pend
- p
->lex.pcur
>= 2 &&
8489 (unsigned char)p
->lex.pcur
[0] == 0xbb &&
8490 (unsigned char)p
->lex.pcur
[1] == 0xbf) {
8491 p
->enc
= rb_utf8_encoding
();
8493 p
->lex.pbeg
= p
->lex.pcur
;
8501 p
->enc
= rb_enc_get
(p
->lex.lastline
);
8505 #define ambiguous_operator(tok, op, syn) ( \
8506 rb_warning0
("`"op
"' after local variable or literal is interpreted as binary operator"), \
8507 rb_warning0
("even though it seems like "syn
""))
8509 #define ambiguous_operator(tok, op, syn) \
8510 dispatch2
(operator_ambiguous
, TOKEN2VAL
(tok
), rb_str_new_cstr
(syn
))
8512 #define warn_balanced(tok, op, syn) ((void) \
8513 (!IS_lex_state_for
(last_state
, EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN
) && \
8514 space_seen
&& !ISSPACE
(c
) && \
8515 (ambiguous_operator
(tok
, op
, syn
), 0)), \
8516 (enum yytokentype
)(tok
))
8519 parse_rational
(struct parser_params
*p
, char *str
, int len
, int seen_point
)
8522 char *point
= &str
[seen_point
];
8523 size_t fraclen
= len
-seen_point
-1;
8524 memmove
(point
, point
+1, fraclen
+1);
8525 v
= rb_cstr_to_inum
(str
, 10, FALSE
);
8526 return rb_rational_new
(v
, rb_int_positive_pow
(10, fraclen
));
8529 static enum yytokentype
8530 no_digits
(struct parser_params
*p
)
8532 yyerror0
("numeric literal without digits");
8533 if
(peek
(p
, '_')) nextc
(p
);
8534 /* dummy 0, for tUMINUS_NUM at numeric */
8535 return set_integer_literal
(p
, INT2FIX
(0), 0);
8538 static enum yytokentype
8539 parse_numeric
(struct parser_params
*p
, int c
)
8541 int is_float
, seen_point
, seen_e
, nondigit
;
8544 is_float
= seen_point
= seen_e
= nondigit
= 0;
8545 SET_LEX_STATE
(EXPR_END
);
8547 if
(c
== '-' || c
== '+') {
8552 int start
= toklen
(p
);
8554 if
(c
== 'x' || c
== 'X') {
8557 if
(c
!= -1 && ISXDIGIT
(c
)) {
8560 if
(nondigit
) break
;
8564 if
(!ISXDIGIT
(c
)) break
;
8567 } while
((c
= nextc
(p
)) != -1);
8571 if
(toklen
(p
) == start
) {
8572 return no_digits
(p
);
8574 else if
(nondigit
) goto trailing_uc
;
8575 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8576 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 16, FALSE
), suffix
);
8578 if
(c
== 'b' || c
== 'B') {
8581 if
(c
== '0' || c
== '1') {
8584 if
(nondigit
) break
;
8588 if
(c
!= '0' && c
!= '1') break
;
8591 } while
((c
= nextc
(p
)) != -1);
8595 if
(toklen
(p
) == start
) {
8596 return no_digits
(p
);
8598 else if
(nondigit
) goto trailing_uc
;
8599 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8600 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 2, FALSE
), suffix
);
8602 if
(c
== 'd' || c
== 'D') {
8605 if
(c
!= -1 && ISDIGIT
(c
)) {
8608 if
(nondigit
) break
;
8612 if
(!ISDIGIT
(c
)) break
;
8615 } while
((c
= nextc
(p
)) != -1);
8619 if
(toklen
(p
) == start
) {
8620 return no_digits
(p
);
8622 else if
(nondigit
) goto trailing_uc
;
8623 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8624 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 10, FALSE
), suffix
);
8630 if
(c
== 'o' || c
== 'O') {
8631 /* prefixed octal */
8633 if
(c
== -1 || c
== '_' ||
!ISDIGIT
(c
)) {
8634 return no_digits
(p
);
8637 if
(c
>= '0' && c
<= '7') {
8642 if
(nondigit
) break
;
8646 if
(c
< '0' || c
> '9') break
;
8647 if
(c
> '7') goto invalid_octal
;
8650 } while
((c
= nextc
(p
)) != -1);
8651 if
(toklen
(p
) > start
) {
8654 if
(nondigit
) goto trailing_uc
;
8655 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8656 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 8, FALSE
), suffix
);
8663 if
(c
> '7' && c
<= '9') {
8665 yyerror0
("Invalid octal digit");
8667 else if
(c
== '.' || c
== 'e' || c
== 'E') {
8672 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8673 return set_integer_literal
(p
, INT2FIX
(0), suffix
);
8679 case
'0': case
'1': case
'2': case
'3': case
'4':
8680 case
'5': case
'6': case
'7': case
'8': case
'9':
8686 if
(nondigit
) goto trailing_uc
;
8687 if
(seen_point || seen_e
) {
8692 if
(c0
== -1 ||
!ISDIGIT
(c0
)) {
8698 seen_point
= toklen
(p
);
8717 if
(c
!= '-' && c
!= '+' && !ISDIGIT
(c
)) {
8722 tokadd
(p
, nondigit
);
8726 nondigit
= (c
== '-' || c
== '+') ? c
: 0;
8729 case
'_': /* `_' in number just ignored */
8730 if
(nondigit
) goto decode_num
;
8744 literal_flush
(p
, p
->lex.pcur
- 1);
8745 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
8746 compile_error
(p
, "trailing `%c' in number", nondigit
);
8747 parser_show_error_line
(p
, &loc
);
8751 enum yytokentype type
= tFLOAT
;
8754 suffix
= number_literal_suffix
(p
, seen_e ? NUM_SUFFIX_I
: NUM_SUFFIX_ALL
);
8755 if
(suffix
& NUM_SUFFIX_R
) {
8757 v
= parse_rational
(p
, tok
(p
), toklen
(p
), seen_point
);
8760 double d
= strtod
(tok
(p
), 0);
8761 if
(errno
== ERANGE
) {
8762 rb_warning1
("Float %s out of range", WARN_S
(tok
(p
)));
8767 return set_number_literal
(p
, v
, type
, suffix
);
8769 suffix
= number_literal_suffix
(p
, NUM_SUFFIX_ALL
);
8770 return set_integer_literal
(p
, rb_cstr_to_inum
(tok
(p
), 10, FALSE
), suffix
);
8773 static enum yytokentype
8774 parse_qmark
(struct parser_params
*p
, int space_seen
)
8781 SET_LEX_STATE
(EXPR_VALUE
);
8786 compile_error
(p
, "incomplete character syntax");
8789 if
(rb_enc_isspace
(c
, p
->enc
)) {
8791 int c2
= escaped_control_code
(c
);
8793 WARN_SPACE_CHAR
(c2
, "?");
8798 SET_LEX_STATE
(EXPR_VALUE
);
8803 if
(!parser_isascii
(p
)) {
8804 if
(tokadd_mbchar
(p
, c
) == -1) return
0;
8806 else if
((rb_enc_isalnum
(c
, p
->enc
) || c
== '_') &&
8807 p
->lex.pcur
< p
->lex.pend
&& is_identchar
(p
->lex.pcur
, p
->lex.pend
, p
->enc
)) {
8809 const char *start
= p
->lex.pcur
- 1, *ptr
= start
;
8811 int n
= parser_precise_mbclen
(p
, ptr
);
8812 if
(n
< 0) return
-1;
8814 } while
(ptr
< p
->lex.pend
&& is_identchar
(ptr
, p
->lex.pend
, p
->enc
));
8815 rb_warn2
("`?' just followed by `%.*s' is interpreted as" \
8816 " a conditional operator, put a space after `?'",
8817 WARN_I
((int)(ptr
- start
)), WARN_S_L
(start
, (ptr
- start
)));
8821 else if
(c
== '\\') {
8824 enc
= rb_utf8_encoding
();
8825 tokadd_utf8
(p
, &enc
, -1, 0, 0);
8827 else if
(!lex_eol_p
(p
) && !(c
= *p
->lex.pcur
, ISASCII
(c
))) {
8829 if
(tokadd_mbchar
(p
, c
) == -1) return
0;
8832 c
= read_escape
(p
, 0, &enc
);
8840 lit
= STR_NEW3
(tok
(p
), toklen
(p
), enc
, 0);
8841 set_yylval_str
(lit
);
8842 SET_LEX_STATE
(EXPR_END
);
8846 static enum yytokentype
8847 parse_percent
(struct parser_params
*p
, const int space_seen
, const enum lex_state_e last_state
)
8850 const char *ptok
= p
->lex.pcur
;
8858 if
(c
== -1) goto unterminated
;
8861 if
(!ISASCII
(c
)) goto unknown
;
8866 if
(rb_enc_isalnum
(term
, p
->enc
) ||
!parser_isascii
(p
)) {
8869 c
= parser_precise_mbclen
(p
, p
->lex.pcur
);
8870 if
(c
< 0) return
0;
8872 yyerror0
("unknown type of %string");
8878 compile_error
(p
, "unterminated quoted string meets end of file");
8882 if
(term
== '(') term
= ')';
8883 else if
(term
== '[') term
= ']';
8884 else if
(term
== '{') term
= '}';
8885 else if
(term
== '<') term
= '>';
8888 p
->lex.ptok
= ptok
-1;
8891 p
->lex.strterm
= NEW_STRTERM
(str_dquote
, term
, paren
);
8895 p
->lex.strterm
= NEW_STRTERM
(str_squote
, term
, paren
);
8899 p
->lex.strterm
= NEW_STRTERM
(str_dword
, term
, paren
);
8903 p
->lex.strterm
= NEW_STRTERM
(str_sword
, term
, paren
);
8907 p
->lex.strterm
= NEW_STRTERM
(str_dword
, term
, paren
);
8908 return tSYMBOLS_BEG
;
8911 p
->lex.strterm
= NEW_STRTERM
(str_sword
, term
, paren
);
8912 return tQSYMBOLS_BEG
;
8915 p
->lex.strterm
= NEW_STRTERM
(str_xquote
, term
, paren
);
8916 return tXSTRING_BEG
;
8919 p
->lex.strterm
= NEW_STRTERM
(str_regexp
, term
, paren
);
8923 p
->lex.strterm
= NEW_STRTERM
(str_ssym
, term
, paren
);
8924 SET_LEX_STATE
(EXPR_FNAME|EXPR_FITEM
);
8928 yyerror0
("unknown type of %string");
8932 if
((c
= nextc
(p
)) == '=') {
8934 SET_LEX_STATE
(EXPR_BEG
);
8937 if
(IS_SPCARG
(c
) ||
(IS_lex_state
(EXPR_FITEM
) && c
== 's')) {
8940 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
8942 return warn_balanced
('%', "%%", "string literal");
8946 tokadd_ident
(struct parser_params
*p
, int c
)
8949 if
(tokadd_mbchar
(p
, c
) == -1) return
-1;
8951 } while
(parser_is_identchar
(p
));
8957 tokenize_ident
(struct parser_params
*p
, const enum lex_state_e last_state
)
8959 ID ident
= TOK_INTERN
();
8961 set_yylval_name
(ident
);
8967 parse_numvar
(struct parser_params
*p
)
8971 unsigned long n
= ruby_scan_digits
(tok
(p
)+1, toklen
(p
)-1, 10, &len
, &overflow
);
8972 const unsigned long nth_ref_max
=
8973 ((FIXNUM_MAX
< INT_MAX
) ? FIXNUM_MAX
: INT_MAX
) >> 1;
8974 /* NTH_REF is left-shifted to be ORed with back-ref flag and
8975 * turned into a Fixnum, in compile.c */
8977 if
(overflow || n
> nth_ref_max
) {
8978 /* compile_error()? */
8979 rb_warn1
("`%s' is too big for a number variable, always nil", WARN_S
(tok
(p
)));
8980 return
0; /* $0 is $PROGRAM_NAME, not NTH_REF */
8987 static enum yytokentype
8988 parse_gvar
(struct parser_params
*p
, const enum lex_state_e last_state
)
8990 const char *ptr
= p
->lex.pcur
;
8993 SET_LEX_STATE
(EXPR_END
);
8994 p
->lex.ptok
= ptr
- 1; /* from '$' */
8998 case
'_': /* $_: last read line string */
9000 if
(parser_is_identchar
(p
)) {
9008 case
'~': /* $~: match-data */
9009 case
'*': /* $*: argv */
9010 case
'$': /* $$: pid */
9011 case
'?': /* $?: last status */
9012 case
'!': /* $!: error string */
9013 case
'@': /* $@: error position */
9014 case
'/': /* $/: input record separator */
9015 case
'\\': /* $\: output record separator */
9016 case
';': /* $;: field separator */
9017 case
',': /* $,: output field separator */
9018 case
'.': /* $.: last read line number */
9019 case
'=': /* $=: ignorecase */
9020 case
':': /* $:: load path */
9021 case
'<': /* $<: reading filename */
9022 case
'>': /* $>: default output handle */
9023 case
'\"': /* $": already loaded files */
9032 if
(parser_is_identchar
(p
)) {
9033 if
(tokadd_mbchar
(p
, c
) == -1) return
0;
9041 set_yylval_name
(TOK_INTERN
());
9044 case
'&': /* $&: last match */
9045 case
'`': /* $`: string before last match */
9046 case
'\'': /* $': string after last match */
9047 case
'+': /* $+: string matches last paren. */
9048 if
(IS_lex_state_for
(last_state
, EXPR_FNAME
)) {
9053 set_yylval_node
(NEW_BACK_REF
(c
, &_cur_loc
));
9056 case
'1': case
'2': case
'3':
9057 case
'4': case
'5': case
'6':
9058 case
'7': case
'8': case
'9':
9063 } while
(c
!= -1 && ISDIGIT
(c
));
9065 if
(IS_lex_state_for
(last_state
, EXPR_FNAME
)) goto gvar
;
9067 c
= parse_numvar
(p
);
9068 set_yylval_node
(NEW_NTH_REF
(c
, &_cur_loc
));
9072 if
(!parser_is_identchar
(p
)) {
9073 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
9074 if
(c
== -1 || ISSPACE
(c
)) {
9075 compile_error
(p
, "`$' without identifiers is not allowed as a global variable name");
9079 compile_error
(p
, "`$%c' is not allowed as a global variable name", c
);
9081 parser_show_error_line
(p
, &loc
);
9082 set_yylval_noname
();
9090 if
(tokadd_ident
(p
, c
)) return
0;
9091 SET_LEX_STATE
(EXPR_END
);
9092 tokenize_ident
(p
, last_state
);
9098 parser_numbered_param
(struct parser_params
*p
, int n
)
9100 if
(n
< 0) return false
;
9102 if
(DVARS_TERMINAL_P
(p
->lvtbl
->args
) || DVARS_TERMINAL_P
(p
->lvtbl
->args
->prev
)) {
9105 if
(p
->max_numparam
== ORDINAL_PARAM
) {
9106 compile_error
(p
, "ordinary parameter is defined");
9109 struct vtable
*args
= p
->lvtbl
->args
;
9110 if
(p
->max_numparam
< n
) {
9111 p
->max_numparam
= n
;
9113 while
(n
> args
->pos
) {
9114 vtable_add
(args
, NUMPARAM_IDX_TO_ID
(args
->pos
+1));
9120 static enum yytokentype
9121 parse_atmark
(struct parser_params
*p
, const enum lex_state_e last_state
)
9123 const char *ptr
= p
->lex.pcur
;
9124 enum yytokentype result
= tIVAR
;
9125 register
int c
= nextc
(p
);
9128 p
->lex.ptok
= ptr
- 1; /* from '@' */
9136 SET_LEX_STATE
(IS_lex_state_for
(last_state
, EXPR_FNAME
) ? EXPR_ENDFN
: EXPR_END
);
9137 if
(c
== -1 ||
!parser_is_identchar
(p
)) {
9139 RUBY_SET_YYLLOC
(loc
);
9140 if
(result
== tIVAR
) {
9141 compile_error
(p
, "`@' without identifiers is not allowed as an instance variable name");
9144 compile_error
(p
, "`@@' without identifiers is not allowed as a class variable name");
9146 parser_show_error_line
(p
, &loc
);
9147 set_yylval_noname
();
9148 SET_LEX_STATE
(EXPR_END
);
9151 else if
(ISDIGIT
(c
)) {
9153 RUBY_SET_YYLLOC
(loc
);
9154 if
(result
== tIVAR
) {
9155 compile_error
(p
, "`@%c' is not allowed as an instance variable name", c
);
9158 compile_error
(p
, "`@@%c' is not allowed as a class variable name", c
);
9160 parser_show_error_line
(p
, &loc
);
9161 set_yylval_noname
();
9162 SET_LEX_STATE
(EXPR_END
);
9166 if
(tokadd_ident
(p
, c
)) return
0;
9167 tokenize_ident
(p
, last_state
);
9171 static enum yytokentype
9172 parse_ident
(struct parser_params
*p
, int c
, int cmd_state
)
9174 enum yytokentype result
;
9175 int mb
= ENC_CODERANGE_7BIT
;
9176 const enum lex_state_e last_state
= p
->lex.state
;
9180 if
(!ISASCII
(c
)) mb
= ENC_CODERANGE_UNKNOWN
;
9181 if
(tokadd_mbchar
(p
, c
) == -1) return
0;
9183 } while
(parser_is_identchar
(p
));
9184 if
((c
== '!' || c
== '?') && !peek
(p
, '=')) {
9188 else if
(c
== '=' && IS_lex_state
(EXPR_FNAME
) &&
9189 (!peek
(p
, '~') && !peek
(p
, '>') && (!peek
(p
, '=') ||
(peek_n
(p
, '>', 1))))) {
9190 result
= tIDENTIFIER
;
9194 result
= tCONSTANT
; /* assume provisionally */
9199 if
(IS_LABEL_POSSIBLE
()) {
9200 if
(IS_LABEL_SUFFIX
(0)) {
9201 SET_LEX_STATE
(EXPR_ARG|EXPR_LABELED
);
9203 set_yylval_name
(TOK_INTERN
());
9207 if
(mb
== ENC_CODERANGE_7BIT
&& !IS_lex_state
(EXPR_DOT
)) {
9208 const struct kwtable
*kw
;
9210 /* See if it is a reserved word. */
9211 kw
= rb_reserved_word
(tok
(p
), toklen
(p
));
9213 enum lex_state_e state
= p
->lex.state
;
9214 if
(IS_lex_state_for
(state
, EXPR_FNAME
)) {
9215 SET_LEX_STATE
(EXPR_ENDFN
);
9216 set_yylval_name
(rb_intern2
(tok
(p
), toklen
(p
)));
9219 SET_LEX_STATE
(kw
->state
);
9220 if
(IS_lex_state
(EXPR_BEG
)) {
9221 p
->command_start
= TRUE
;
9223 if
(kw
->id
[0] == keyword_do
) {
9224 if
(lambda_beginning_p
()) {
9225 p
->lex.lpar_beg
= -1; /* make lambda_beginning_p() == FALSE in the body of "-> do ... end" */
9226 return keyword_do_LAMBDA
;
9228 if
(COND_P
()) return keyword_do_cond
;
9229 if
(CMDARG_P
() && !IS_lex_state_for
(state
, EXPR_CMDARG
))
9230 return keyword_do_block
;
9233 if
(IS_lex_state_for
(state
, (EXPR_BEG | EXPR_LABELED
)))
9236 if
(kw
->id
[0] != kw
->id
[1])
9237 SET_LEX_STATE
(EXPR_BEG | EXPR_LABEL
);
9243 if
(IS_lex_state
(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT
)) {
9245 SET_LEX_STATE
(EXPR_CMDARG
);
9248 SET_LEX_STATE
(EXPR_ARG
);
9251 else if
(p
->lex.state
== EXPR_FNAME
) {
9252 SET_LEX_STATE
(EXPR_ENDFN
);
9255 SET_LEX_STATE
(EXPR_END
);
9258 ident
= tokenize_ident
(p
, last_state
);
9259 if
(result
== tCONSTANT
&& is_local_id
(ident
)) result
= tIDENTIFIER
;
9260 if
(!IS_lex_state_for
(last_state
, EXPR_DOT|EXPR_FNAME
) &&
9261 (result
== tIDENTIFIER
) && /* not EXPR_FNAME, not attrasgn */
9262 lvar_defined
(p
, ident
)) {
9263 SET_LEX_STATE
(EXPR_END|EXPR_LABEL
);
9268 static enum yytokentype
9269 parser_yylex
(struct parser_params
*p
)
9275 enum lex_state_e last_state
;
9276 int fallthru
= FALSE
;
9277 int token_seen
= p
->token_seen
;
9279 if
(p
->lex.strterm
) {
9280 if
(p
->lex.strterm
->flags
& STRTERM_HEREDOC
) {
9281 return here_document
(p
, &p
->lex.strterm
->u.heredoc
);
9285 return parse_string
(p
, &p
->lex.strterm
->u.literal
);
9288 cmd_state
= p
->command_start
;
9289 p
->command_start
= FALSE
;
9290 p
->token_seen
= TRUE
;
9292 last_state
= p
->lex.state
;
9296 switch
(c
= nextc
(p
)) {
9297 case
'\0': /* NUL */
9298 case
'\004': /* ^D */
9299 case
'\032': /* ^Z */
9300 case
-1: /* end of script. */
9307 /* carried over with p->lex.nextline for nextc() */
9308 rb_warn0
("encountered \\r in middle of line, treated as a mere space");
9311 case
' ': case
'\t': case
'\f':
9312 case
'\13': /* '\v' */
9315 while
((c
= nextc
(p
))) {
9317 case
' ': case
'\t': case
'\f': case
'\r':
9318 case
'\13': /* '\v' */
9326 dispatch_scan_event
(p
, tSP
);
9330 case
'#': /* it's a comment */
9331 p
->token_seen
= token_seen
;
9332 /* no magic_comment in shebang line */
9333 if
(!parser_magic_comment
(p
, p
->lex.pcur
, p
->lex.pend
- p
->lex.pcur
)) {
9334 if
(comment_at_top
(p
)) {
9335 set_file_encoding
(p
, p
->lex.pcur
, p
->lex.pend
);
9339 dispatch_scan_event
(p
, tCOMMENT
);
9343 p
->token_seen
= token_seen
;
9344 c
= (IS_lex_state
(EXPR_BEG|EXPR_CLASS|EXPR_FNAME|EXPR_DOT
) &&
9345 !IS_lex_state
(EXPR_LABELED
));
9346 if
(c || IS_lex_state_all
(EXPR_ARG|EXPR_LABELED
)) {
9348 dispatch_scan_event
(p
, tIGNORED_NL
);
9351 if
(!c
&& p
->ctxt.in_kwarg
) {
9352 goto normal_newline
;
9357 switch
(c
= nextc
(p
)) {
9358 case
' ': case
'\t': case
'\f': case
'\r':
9359 case
'\13': /* '\v' */
9364 if
(space_seen
) dispatch_scan_event
(p
, tSP
);
9368 dispatch_delayed_token
(p
, tIGNORED_NL
);
9369 if
(peek
(p
, '.') == (c
== '&')) {
9371 dispatch_scan_event
(p
, tSP
);
9376 p
->ruby_sourceline
--;
9377 p
->lex.nextline
= p
->lex.lastline
;
9378 case
-1: /* EOF no decrement*/
9380 if
(p
->lex.prevline
&& !p
->eofp
) p
->lex.lastline
= p
->lex.prevline
;
9381 p
->lex.pbeg
= RSTRING_PTR
(p
->lex.lastline
);
9382 p
->lex.pend
= p
->lex.pcur
= p
->lex.pbeg
+ RSTRING_LEN
(p
->lex.lastline
);
9383 pushback
(p
, 1); /* always pushback */
9384 p
->lex.ptok
= p
->lex.pcur
;
9388 p
->lex.ptok
= p
->lex.pcur
;
9391 goto normal_newline
;
9395 p
->command_start
= TRUE
;
9396 SET_LEX_STATE
(EXPR_BEG
);
9400 if
((c
= nextc
(p
)) == '*') {
9401 if
((c
= nextc
(p
)) == '=') {
9402 set_yylval_id
(idPow
);
9403 SET_LEX_STATE
(EXPR_BEG
);
9408 rb_warning0
("`**' interpreted as argument prefix");
9411 else if
(IS_BEG
()) {
9415 c
= warn_balanced
((enum ruby_method_ids
)tPOW
, "**", "argument prefix");
9421 SET_LEX_STATE
(EXPR_BEG
);
9426 rb_warning0
("`*' interpreted as argument prefix");
9429 else if
(IS_BEG
()) {
9433 c
= warn_balanced
('*', "*", "argument prefix");
9436 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9441 if
(IS_AFTER_OPERATOR
()) {
9442 SET_LEX_STATE
(EXPR_ARG
);
9448 SET_LEX_STATE
(EXPR_BEG
);
9461 /* skip embedded rd document */
9462 if
(word_match_p
(p
, "begin", 5)) {
9466 dispatch_scan_event
(p
, tEMBDOC_BEG
);
9470 dispatch_scan_event
(p
, tEMBDOC
);
9475 compile_error
(p
, "embedded document meets end of file");
9478 if
(c
== '=' && word_match_p
(p
, "end", 3)) {
9484 dispatch_scan_event
(p
, tEMBDOC_END
);
9489 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9490 if
((c
= nextc
(p
)) == '=') {
9491 if
((c
= nextc
(p
)) == '=') {
9500 else if
(c
== '>') {
9509 !IS_lex_state
(EXPR_DOT | EXPR_CLASS
) &&
9511 (!IS_ARG
() || IS_lex_state
(EXPR_LABELED
) || space_seen
)) {
9512 int token
= heredoc_identifier
(p
);
9513 if
(token
) return token
< 0 ?
0 : token
;
9515 if
(IS_AFTER_OPERATOR
()) {
9516 SET_LEX_STATE
(EXPR_ARG
);
9519 if
(IS_lex_state
(EXPR_CLASS
))
9520 p
->command_start
= TRUE
;
9521 SET_LEX_STATE
(EXPR_BEG
);
9524 if
((c
= nextc
(p
)) == '>') {
9531 if
((c
= nextc
(p
)) == '=') {
9532 set_yylval_id
(idLTLT
);
9533 SET_LEX_STATE
(EXPR_BEG
);
9537 return warn_balanced
((enum ruby_method_ids
)tLSHFT
, "<<", "here document");
9543 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9544 if
((c
= nextc
(p
)) == '=') {
9548 if
((c
= nextc
(p
)) == '=') {
9549 set_yylval_id
(idGTGT
);
9550 SET_LEX_STATE
(EXPR_BEG
);
9560 label
= (IS_LABEL_POSSIBLE
() ? str_label
: 0);
9561 p
->lex.strterm
= NEW_STRTERM
(str_dquote | label
, '"', 0);
9562 p
->lex.ptok
= p
->lex.pcur
-1;
9566 if
(IS_lex_state
(EXPR_FNAME
)) {
9567 SET_LEX_STATE
(EXPR_ENDFN
);
9570 if
(IS_lex_state
(EXPR_DOT
)) {
9572 SET_LEX_STATE
(EXPR_CMDARG
);
9574 SET_LEX_STATE
(EXPR_ARG
);
9577 p
->lex.strterm
= NEW_STRTERM
(str_xquote
, '`', 0);
9578 return tXSTRING_BEG
;
9581 label
= (IS_LABEL_POSSIBLE
() ? str_label
: 0);
9582 p
->lex.strterm
= NEW_STRTERM
(str_squote | label
, '\'', 0);
9583 p
->lex.ptok
= p
->lex.pcur
-1;
9587 return parse_qmark
(p
, space_seen
);
9590 if
((c
= nextc
(p
)) == '&') {
9591 SET_LEX_STATE
(EXPR_BEG
);
9592 if
((c
= nextc
(p
)) == '=') {
9593 set_yylval_id
(idANDOP
);
9594 SET_LEX_STATE
(EXPR_BEG
);
9600 else if
(c
== '=') {
9602 SET_LEX_STATE
(EXPR_BEG
);
9605 else if
(c
== '.') {
9606 set_yylval_id
(idANDDOT
);
9607 SET_LEX_STATE
(EXPR_DOT
);
9613 (c
= peekc_n
(p
, 1)) == -1 ||
9614 !(c
== '\'' || c
== '"' ||
9615 is_identchar
((p
->lex.pcur
+1), p
->lex.pend
, p
->enc
))) {
9616 rb_warning0
("`&' interpreted as argument prefix");
9620 else if
(IS_BEG
()) {
9624 c
= warn_balanced
('&', "&", "argument prefix");
9626 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9630 if
((c
= nextc
(p
)) == '|') {
9631 SET_LEX_STATE
(EXPR_BEG
);
9632 if
((c
= nextc
(p
)) == '=') {
9633 set_yylval_id
(idOROP
);
9634 SET_LEX_STATE
(EXPR_BEG
);
9638 if
(IS_lex_state_for
(last_state
, EXPR_BEG
)) {
9647 SET_LEX_STATE
(EXPR_BEG
);
9650 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG|EXPR_LABEL
);
9656 if
(IS_AFTER_OPERATOR
()) {
9657 SET_LEX_STATE
(EXPR_ARG
);
9666 SET_LEX_STATE
(EXPR_BEG
);
9669 if
(IS_BEG
() ||
(IS_SPCARG
(c
) && arg_ambiguous
(p
, '+'))) {
9670 SET_LEX_STATE
(EXPR_BEG
);
9672 if
(c
!= -1 && ISDIGIT
(c
)) {
9673 return parse_numeric
(p
, '+');
9677 SET_LEX_STATE
(EXPR_BEG
);
9679 return warn_balanced
('+', "+", "unary operator");
9683 if
(IS_AFTER_OPERATOR
()) {
9684 SET_LEX_STATE
(EXPR_ARG
);
9693 SET_LEX_STATE
(EXPR_BEG
);
9697 SET_LEX_STATE
(EXPR_ENDFN
);
9700 if
(IS_BEG
() ||
(IS_SPCARG
(c
) && arg_ambiguous
(p
, '-'))) {
9701 SET_LEX_STATE
(EXPR_BEG
);
9703 if
(c
!= -1 && ISDIGIT
(c
)) {
9708 SET_LEX_STATE
(EXPR_BEG
);
9710 return warn_balanced
('-', "-", "unary operator");
9713 int is_beg
= IS_BEG
();
9714 SET_LEX_STATE
(EXPR_BEG
);
9715 if
((c
= nextc
(p
)) == '.') {
9716 if
((c
= nextc
(p
)) == '.') {
9717 if
(p
->ctxt.in_argdef
) {
9718 SET_LEX_STATE
(EXPR_ENDARG
);
9721 if
(p
->lex.paren_nest
== 0 && looking_at_eol_p
(p
)) {
9722 rb_warn0
("... at EOL, should be parenthesized?");
9724 else if
(p
->lex.lpar_beg
>= 0 && p
->lex.lpar_beg
+1 == p
->lex.paren_nest
) {
9725 if
(IS_lex_state_for
(last_state
, EXPR_LABEL
))
9728 return is_beg ? tBDOT3
: tDOT3
;
9731 return is_beg ? tBDOT2
: tDOT2
;
9734 if
(c
!= -1 && ISDIGIT
(c
)) {
9735 char prev
= p
->lex.pcur
-1 > p
->lex.pbeg ?
*(p
->lex.pcur
-2) : 0;
9736 parse_numeric
(p
, '.');
9737 if
(ISDIGIT
(prev
)) {
9738 yyerror0
("unexpected fraction part after numeric literal");
9741 yyerror0
("no .<digit> floating literal anymore; put 0 before dot");
9743 SET_LEX_STATE
(EXPR_END
);
9744 p
->lex.ptok
= p
->lex.pcur
;
9748 SET_LEX_STATE
(EXPR_DOT
);
9752 case
'0': case
'1': case
'2': case
'3': case
'4':
9753 case
'5': case
'6': case
'7': case
'8': case
'9':
9754 return parse_numeric
(p
, c
);
9759 SET_LEX_STATE
(EXPR_ENDFN
);
9760 p
->lex.paren_nest
--;
9766 SET_LEX_STATE
(EXPR_END
);
9767 p
->lex.paren_nest
--;
9771 /* tSTRING_DEND does COND_POP and CMDARG_POP in the yacc's rule */
9772 if
(!p
->lex.brace_nest
--) return tSTRING_DEND
;
9775 SET_LEX_STATE
(EXPR_END
);
9776 p
->lex.paren_nest
--;
9782 if
(IS_BEG
() || IS_lex_state
(EXPR_CLASS
) || IS_SPCARG
(-1)) {
9783 SET_LEX_STATE
(EXPR_BEG
);
9786 set_yylval_id
(idCOLON2
);
9787 SET_LEX_STATE
(EXPR_DOT
);
9790 if
(IS_END
() || ISSPACE
(c
) || c
== '#') {
9792 c
= warn_balanced
(':', ":", "symbol literal");
9793 SET_LEX_STATE
(EXPR_BEG
);
9798 p
->lex.strterm
= NEW_STRTERM
(str_ssym
, c
, 0);
9801 p
->lex.strterm
= NEW_STRTERM
(str_dsym
, c
, 0);
9807 SET_LEX_STATE
(EXPR_FNAME
);
9812 p
->lex.strterm
= NEW_STRTERM
(str_regexp
, '/', 0);
9815 if
((c
= nextc
(p
)) == '=') {
9817 SET_LEX_STATE
(EXPR_BEG
);
9822 arg_ambiguous
(p
, '/');
9823 p
->lex.strterm
= NEW_STRTERM
(str_regexp
, '/', 0);
9826 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9827 return warn_balanced
('/', "/", "regexp literal");
9830 if
((c
= nextc
(p
)) == '=') {
9832 SET_LEX_STATE
(EXPR_BEG
);
9835 SET_LEX_STATE
(IS_AFTER_OPERATOR
() ? EXPR_ARG
: EXPR_BEG
);
9840 SET_LEX_STATE
(EXPR_BEG
);
9841 p
->command_start
= TRUE
;
9845 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
9849 if
(IS_AFTER_OPERATOR
()) {
9850 if
((c
= nextc
(p
)) != '@') {
9853 SET_LEX_STATE
(EXPR_ARG
);
9856 SET_LEX_STATE
(EXPR_BEG
);
9864 else if
(!space_seen
) {
9865 /* foo( ... ) => method call, no ambiguity */
9867 else if
(IS_ARG
() || IS_lex_state_all
(EXPR_END|EXPR_LABEL
)) {
9870 else if
(IS_lex_state
(EXPR_ENDFN
) && !lambda_beginning_p
()) {
9871 rb_warning0
("parentheses after method name is interpreted as "
9872 "an argument list, not a decomposed argument");
9874 p
->lex.paren_nest
++;
9877 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
9881 p
->lex.paren_nest
++;
9882 if
(IS_AFTER_OPERATOR
()) {
9883 if
((c
= nextc
(p
)) == ']') {
9884 p
->lex.paren_nest
--;
9885 SET_LEX_STATE
(EXPR_ARG
);
9886 if
((c
= nextc
(p
)) == '=') {
9893 SET_LEX_STATE
(EXPR_ARG|EXPR_LABEL
);
9896 else if
(IS_BEG
()) {
9899 else if
(IS_ARG
() && (space_seen || IS_lex_state
(EXPR_LABELED
))) {
9902 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
9908 ++p
->lex.brace_nest
;
9909 if
(lambda_beginning_p
())
9911 else if
(IS_lex_state
(EXPR_LABELED
))
9912 c
= tLBRACE
; /* hash */
9913 else if
(IS_lex_state
(EXPR_ARG_ANY | EXPR_END | EXPR_ENDFN
))
9914 c
= '{'; /* block (primary) */
9915 else if
(IS_lex_state
(EXPR_ENDARG
))
9916 c
= tLBRACE_ARG
; /* block (expr) */
9918 c
= tLBRACE
; /* hash */
9920 p
->command_start
= TRUE
;
9921 SET_LEX_STATE
(EXPR_BEG
);
9924 SET_LEX_STATE
(EXPR_BEG|EXPR_LABEL
);
9926 ++p
->lex.paren_nest
; /* after lambda_beginning_p() */
9935 dispatch_scan_event
(p
, tSP
);
9936 goto retry
; /* skip \\n */
9938 if
(c
== ' ') return tSP
;
9939 if
(ISSPACE
(c
)) return c
;
9944 return parse_percent
(p
, space_seen
, last_state
);
9947 return parse_gvar
(p
, last_state
);
9950 return parse_atmark
(p
, last_state
);
9953 if
(was_bol
(p
) && whole_match_p
(p
, "__END__", 7, 0)) {
9954 p
->ruby__end__seen
= 1;
9960 dispatch_scan_event
(p
, k__END__
);
9968 if
(!parser_is_identchar
(p
)) {
9969 compile_error
(p
, "Invalid char `\\x%02X' in expression", c
);
9978 return parse_ident
(p
, c
, cmd_state
);
9981 static enum yytokentype
9982 yylex(YYSTYPE *lval
, YYLTYPE *yylloc, struct parser_params
*p
)
9988 t
= parser_yylex
(p
);
9990 if
(p
->lex.strterm
&& (p
->lex.strterm
->flags
& STRTERM_HEREDOC
))
9991 RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC
(*yylloc);
9993 RUBY_SET_YYLLOC
(*yylloc);
9995 if
(has_delayed_token
(p
))
9996 dispatch_delayed_token
(p
, t
);
9998 dispatch_scan_event
(p
, t
);
10003 #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
10006 node_newnode
(struct parser_params
*p
, enum node_type type
, VALUE a0
, VALUE a1
, VALUE a2
, const rb_code_location_t
*loc
)
10008 NODE
*n
= rb_ast_newnode
(p
->ast
, type
);
10010 rb_node_init
(n
, type
, a0
, a1
, a2
);
10012 nd_set_loc
(n
, loc
);
10013 nd_set_node_id
(n
, parser_get_node_id
(p
));
10018 nd_set_loc
(NODE
*nd
, const YYLTYPE *loc
)
10021 nd_set_line
(nd
, loc
->beg_pos.lineno
);
10026 static enum node_type
10027 nodetype
(NODE
*node
) /* for debug */
10029 return
(enum node_type
)nd_type
(node
);
10033 nodeline
(NODE
*node
)
10035 return nd_line
(node
);
10039 newline_node
(NODE
*node
)
10042 node
= remove_begin
(node
);
10043 node
->flags |
= NODE_FL_NEWLINE
;
10049 fixpos
(NODE
*node
, NODE
*orig
)
10053 nd_set_line
(node
, nd_line
(orig
));
10057 parser_warning
(struct parser_params
*p
, NODE
*node
, const char *mesg
)
10059 rb_compile_warning
(p
->ruby_sourcefile
, nd_line
(node
), "%s", mesg
);
10063 parser_warn
(struct parser_params
*p
, NODE
*node
, const char *mesg
)
10065 rb_compile_warn
(p
->ruby_sourcefile
, nd_line
(node
), "%s", mesg
);
10069 block_append
(struct parser_params
*p
, NODE
*head
, NODE
*tail
)
10071 NODE
*end
, *h
= head
, *nd
;
10073 if
(tail
== 0) return head
;
10075 if
(h
== 0) return tail
;
10076 switch
(nd_type
(h
)) {
10083 parser_warning
(p
, h
, "unused literal ignored");
10086 h
= end
= NEW_BLOCK
(head
, &head
->nd_loc
);
10096 switch
(nd_type
(nd
)) {
10102 if
(RTEST
(ruby_verbose
)) {
10103 parser_warning
(p
, tail
, "statement not reached");
10111 if
(!nd_type_p
(tail
, NODE_BLOCK
)) {
10112 tail
= NEW_BLOCK
(tail
, &tail
->nd_loc
);
10113 tail
->nd_end
= tail
;
10115 end
->nd_next
= tail
;
10116 h
->nd_end
= tail
->nd_end
;
10117 nd_set_last_loc
(head
, nd_last_loc
(tail
));
10121 /* append item to the list */
10123 list_append
(struct parser_params
*p
, NODE
*list
, NODE
*item
)
10127 if
(list
== 0) return NEW_LIST
(item
, &item
->nd_loc
);
10128 if
(list
->nd_next
) {
10129 last
= list
->nd_next
->nd_end
;
10135 list
->nd_alen
+= 1;
10136 last
->nd_next
= NEW_LIST
(item
, &item
->nd_loc
);
10137 list
->nd_next
->nd_end
= last
->nd_next
;
10139 nd_set_last_loc
(list
, nd_last_loc
(item
));
10144 /* concat two lists */
10146 list_concat
(NODE
*head
, NODE
*tail
)
10150 if
(head
->nd_next
) {
10151 last
= head
->nd_next
->nd_end
;
10157 head
->nd_alen
+= tail
->nd_alen
;
10158 last
->nd_next
= tail
;
10159 if
(tail
->nd_next
) {
10160 head
->nd_next
->nd_end
= tail
->nd_next
->nd_end
;
10163 head
->nd_next
->nd_end
= tail
;
10166 nd_set_last_loc
(head
, nd_last_loc
(tail
));
10172 literal_concat0
(struct parser_params
*p
, VALUE head
, VALUE tail
)
10174 if
(NIL_P
(tail
)) return
1;
10175 if
(!rb_enc_compatible
(head
, tail
)) {
10176 compile_error
(p
, "string literal encodings differ (%s / %s)",
10177 rb_enc_name
(rb_enc_get
(head
)),
10178 rb_enc_name
(rb_enc_get
(tail
)));
10179 rb_str_resize
(head
, 0);
10180 rb_str_resize
(tail
, 0);
10183 rb_str_buf_append
(head
, tail
);
10188 string_literal_head
(enum node_type htype
, NODE
*head
)
10190 if
(htype
!= NODE_DSTR
) return Qfalse
;
10191 if
(head
->nd_next
) {
10192 head
= head
->nd_next
->nd_end
->nd_head
;
10193 if
(!head ||
!nd_type_p
(head
, NODE_STR
)) return Qfalse
;
10195 const VALUE lit
= head
->nd_lit
;
10196 ASSUME
(lit
!= Qfalse
);
10200 /* concat two string literals */
10202 literal_concat
(struct parser_params
*p
, NODE
*head
, NODE
*tail
, const YYLTYPE *loc
)
10204 enum node_type htype
;
10207 if
(!head
) return tail
;
10208 if
(!tail
) return head
;
10210 htype
= nd_type
(head
);
10211 if
(htype
== NODE_EVSTR
) {
10212 head
= new_dstr
(p
, head
, loc
);
10215 if
(p
->heredoc_indent
> 0) {
10218 nd_set_type
(head
, NODE_DSTR
);
10220 return list_append
(p
, head
, tail
);
10225 switch
(nd_type
(tail
)) {
10227 if
((lit
= string_literal_head
(htype
, head
)) != Qfalse
) {
10231 lit
= head
->nd_lit
;
10233 if
(htype
== NODE_STR
) {
10234 if
(!literal_concat0
(p
, lit
, tail
->nd_lit
)) {
10236 rb_discard_node
(p
, head
);
10237 rb_discard_node
(p
, tail
);
10240 rb_discard_node
(p
, tail
);
10243 list_append
(p
, head
, tail
);
10248 if
(htype
== NODE_STR
) {
10249 if
(!literal_concat0
(p
, head
->nd_lit
, tail
->nd_lit
))
10251 tail
->nd_lit
= head
->nd_lit
;
10252 rb_discard_node
(p
, head
);
10255 else if
(NIL_P
(tail
->nd_lit
)) {
10257 head
->nd_alen
+= tail
->nd_alen
- 1;
10258 if
(!head
->nd_next
) {
10259 head
->nd_next
= tail
->nd_next
;
10261 else if
(tail
->nd_next
) {
10262 head
->nd_next
->nd_end
->nd_next
= tail
->nd_next
;
10263 head
->nd_next
->nd_end
= tail
->nd_next
->nd_end
;
10265 rb_discard_node
(p
, tail
);
10267 else if
((lit
= string_literal_head
(htype
, head
)) != Qfalse
) {
10268 if
(!literal_concat0
(p
, lit
, tail
->nd_lit
))
10270 tail
->nd_lit
= Qnil
;
10274 list_concat
(head
, NEW_NODE
(NODE_LIST
, NEW_STR
(tail
->nd_lit
, loc
), tail
->nd_alen
, tail
->nd_next
, loc
));
10279 if
(htype
== NODE_STR
) {
10280 nd_set_type
(head
, NODE_DSTR
);
10283 list_append
(p
, head
, tail
);
10290 evstr2dstr
(struct parser_params
*p
, NODE
*node
)
10292 if
(nd_type_p
(node
, NODE_EVSTR
)) {
10293 node
= new_dstr
(p
, node
, &node
->nd_loc
);
10299 new_evstr
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
10304 switch
(nd_type
(node
)) {
10306 nd_set_type
(node
, NODE_DSTR
);
10314 return NEW_EVSTR
(head
, loc
);
10318 new_dstr
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
10320 VALUE lit
= STR_NEW0
();
10321 NODE
*dstr
= NEW_DSTR
(lit
, loc
);
10322 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, lit
);
10323 return list_append
(p
, dstr
, node
);
10327 call_bin_op
(struct parser_params
*p
, NODE
*recv
, ID id
, NODE
*arg1
,
10328 const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10333 expr
= NEW_OPCALL
(recv
, id
, NEW_LIST
(arg1
, &arg1
->nd_loc
), loc
);
10334 nd_set_line
(expr
, op_loc
->beg_pos.lineno
);
10339 call_uni_op
(struct parser_params
*p
, NODE
*recv
, ID id
, const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10343 opcall
= NEW_OPCALL
(recv
, id
, 0, loc
);
10344 nd_set_line
(opcall
, op_loc
->beg_pos.lineno
);
10349 new_qcall
(struct parser_params
* p
, ID atype
, NODE
*recv
, ID mid
, NODE
*args
, const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10351 NODE
*qcall
= NEW_QCALL
(atype
, recv
, mid
, args
, loc
);
10352 nd_set_line
(qcall
, op_loc
->beg_pos.lineno
);
10357 new_command_qcall
(struct parser_params
* p
, ID atype
, NODE
*recv
, ID mid
, NODE
*args
, NODE
*block
, const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10360 if
(block
) block_dup_check
(p
, args
, block
);
10361 ret
= new_qcall
(p
, atype
, recv
, mid
, args
, op_loc
, loc
);
10362 if
(block
) ret
= method_add_block
(p
, ret
, block
, loc
);
10367 #define nd_once_body(node) (nd_type_p((node), NODE_ONCE) ? (node)->nd_body : node)
10369 match_op
(struct parser_params
*p
, NODE
*node1
, NODE
*node2
, const YYLTYPE *op_loc
, const YYLTYPE *loc
)
10372 int line
= op_loc
->beg_pos.lineno
;
10376 if
(node1
&& (n
= nd_once_body
(node1
)) != 0) {
10377 switch
(nd_type
(n
)) {
10380 NODE
*match
= NEW_MATCH2
(node1
, node2
, loc
);
10381 nd_set_line
(match
, line
);
10386 if
(RB_TYPE_P
(n
->nd_lit
, T_REGEXP
)) {
10387 const VALUE lit
= n
->nd_lit
;
10388 NODE
*match
= NEW_MATCH2
(node1
, node2
, loc
);
10389 match
->nd_args
= reg_named_capture_assign
(p
, lit
, loc
);
10390 nd_set_line
(match
, line
);
10396 if
(node2
&& (n
= nd_once_body
(node2
)) != 0) {
10399 switch
(nd_type
(n
)) {
10401 if
(!RB_TYPE_P
(n
->nd_lit
, T_REGEXP
)) break
;
10404 match3
= NEW_MATCH3
(node2
, node1
, loc
);
10409 n
= NEW_CALL
(node1
, tMATCH
, NEW_LIST
(node2
, &node2
->nd_loc
), loc
);
10410 nd_set_line
(n
, line
);
10414 # if WARN_PAST_SCOPE
10416 past_dvar_p
(struct parser_params
*p
, ID id
)
10418 struct vtable
*past
= p
->lvtbl
->past
;
10420 if
(vtable_included
(past
, id
)) return
1;
10428 numparam_nested_p
(struct parser_params
*p
)
10430 struct local_vars
*local
= p
->lvtbl
;
10431 NODE
*outer
= local
->numparam.outer
;
10432 NODE
*inner
= local
->numparam.inner
;
10433 if
(outer || inner
) {
10434 NODE
*used
= outer ? outer
: inner
;
10435 compile_error
(p
, "numbered parameter is already used in\n"
10436 "%s:%d: %s block here",
10437 p
->ruby_sourcefile
, nd_line
(used
),
10438 outer ?
"outer" : "inner");
10439 parser_show_error_line
(p
, &used
->nd_loc
);
10446 gettable
(struct parser_params
*p
, ID id
, const YYLTYPE *loc
)
10452 return NEW_SELF
(loc
);
10454 return NEW_NIL
(loc
);
10456 return NEW_TRUE
(loc
);
10457 case keyword_false
:
10458 return NEW_FALSE
(loc
);
10459 case keyword__FILE__
:
10461 VALUE file
= p
->ruby_sourcefile_string
;
10463 file
= rb_str_new
(0, 0);
10465 file
= rb_str_dup
(file
);
10466 node
= NEW_STR
(file
, loc
);
10467 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, file
);
10470 case keyword__LINE__
:
10471 return NEW_LIT
(INT2FIX
(p
->tokline
), loc
);
10472 case keyword__ENCODING__
:
10473 node
= NEW_LIT
(rb_enc_from_encoding
(p
->enc
), loc
);
10474 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
);
10478 switch
(id_type
(id
)) {
10480 if
(dyna_in_block
(p
) && dvar_defined_ref
(p
, id
, &vidp
)) {
10481 if
(NUMPARAM_ID_P
(id
) && numparam_nested_p
(p
)) return
0;
10482 if
(id
== p
->cur_arg
) {
10483 compile_error
(p
, "circular argument reference - %"PRIsWARN
, rb_id2str
(id
));
10486 if
(vidp
) *vidp |
= LVAR_USED
;
10487 node
= NEW_DVAR
(id
, loc
);
10490 if
(local_id_ref
(p
, id
, &vidp
)) {
10491 if
(id
== p
->cur_arg
) {
10492 compile_error
(p
, "circular argument reference - %"PRIsWARN
, rb_id2str
(id
));
10495 if
(vidp
) *vidp |
= LVAR_USED
;
10496 node
= NEW_LVAR
(id
, loc
);
10499 if
(dyna_in_block
(p
) && NUMPARAM_ID_P
(id
) &&
10500 parser_numbered_param
(p
, NUMPARAM_ID_TO_IDX
(id
))) {
10501 if
(numparam_nested_p
(p
)) return
0;
10502 node
= NEW_DVAR
(id
, loc
);
10503 struct local_vars
*local
= p
->lvtbl
;
10504 if
(!local
->numparam.current
) local
->numparam.current
= node
;
10507 # if WARN_PAST_SCOPE
10508 if
(!p
->ctxt.in_defined
&& RTEST
(ruby_verbose
) && past_dvar_p
(p
, id
)) {
10509 rb_warning1
("possible reference to past scope - %"PRIsWARN
, rb_id2str
(id
));
10512 /* method call without arguments */
10513 return NEW_VCALL
(id
, loc
);
10515 return NEW_GVAR
(id
, loc
);
10517 return NEW_IVAR
(id
, loc
);
10519 return NEW_CONST
(id
, loc
);
10521 return NEW_CVAR
(id
, loc
);
10523 compile_error
(p
, "identifier %"PRIsVALUE
" is not valid to get", rb_id2str
(id
));
10528 opt_arg_append
(NODE
*opt_list
, NODE
*opt
)
10530 NODE
*opts
= opt_list
;
10531 opts
->nd_loc.end_pos
= opt
->nd_loc.end_pos
;
10533 while
(opts
->nd_next
) {
10534 opts
= opts
->nd_next
;
10535 opts
->nd_loc.end_pos
= opt
->nd_loc.end_pos
;
10537 opts
->nd_next
= opt
;
10543 kwd_append
(NODE
*kwlist
, NODE
*kw
)
10546 NODE
*kws
= kwlist
;
10547 kws
->nd_loc.end_pos
= kw
->nd_loc.end_pos
;
10548 while
(kws
->nd_next
) {
10549 kws
= kws
->nd_next
;
10550 kws
->nd_loc.end_pos
= kw
->nd_loc.end_pos
;
10558 new_defined
(struct parser_params
*p
, NODE
*expr
, const YYLTYPE *loc
)
10560 return NEW_DEFINED
(remove_begin_all
(expr
), loc
);
10564 symbol_append
(struct parser_params
*p
, NODE
*symbols
, NODE
*symbol
)
10566 enum node_type type
= nd_type
(symbol
);
10569 nd_set_type
(symbol
, NODE_DSYM
);
10572 nd_set_type
(symbol
, NODE_LIT
);
10573 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, symbol
->nd_lit
= rb_str_intern
(symbol
->nd_lit
));
10576 compile_error
(p
, "unexpected node as symbol: %s", ruby_node_name
(type
));
10578 return list_append
(p
, symbols
, symbol
);
10582 new_regexp
(struct parser_params
*p
, NODE
*node
, int options
, const YYLTYPE *loc
)
10588 node
= NEW_LIT
(reg_compile
(p
, STR_NEW0
(), options
), loc
);
10589 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
);
10592 switch
(nd_type
(node
)) {
10595 VALUE src
= node
->nd_lit
;
10596 nd_set_type
(node
, NODE_LIT
);
10597 nd_set_loc
(node
, loc
);
10598 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
= reg_compile
(p
, src
, options
));
10603 node
= NEW_NODE
(NODE_DSTR
, lit
, 1, NEW_LIST
(node
, loc
), loc
);
10604 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, lit
);
10607 nd_set_type
(node
, NODE_DREGX
);
10608 nd_set_loc
(node
, loc
);
10609 node
->nd_cflag
= options
& RE_OPTION_MASK
;
10610 if
(!NIL_P
(node
->nd_lit
)) reg_fragment_check
(p
, node
->nd_lit
, options
);
10611 for
(list
= (prev
= node
)->nd_next
; list
; list
= list
->nd_next
) {
10612 NODE
*frag
= list
->nd_head
;
10613 enum node_type type
= nd_type
(frag
);
10614 if
(type
== NODE_STR ||
(type
== NODE_DSTR
&& !frag
->nd_next
)) {
10615 VALUE tail
= frag
->nd_lit
;
10616 if
(reg_fragment_check
(p
, tail
, options
) && prev
&& !NIL_P
(prev
->nd_lit
)) {
10617 VALUE lit
= prev
== node ? prev
->nd_lit
: prev
->nd_head
->nd_lit
;
10618 if
(!literal_concat0
(p
, lit
, tail
)) {
10619 return NEW_NIL
(loc
); /* dummy node on error */
10621 rb_str_resize
(tail
, 0);
10622 prev
->nd_next
= list
->nd_next
;
10623 rb_discard_node
(p
, list
->nd_head
);
10624 rb_discard_node
(p
, list
);
10635 if
(!node
->nd_next
) {
10636 VALUE src
= node
->nd_lit
;
10637 nd_set_type
(node
, NODE_LIT
);
10638 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
= reg_compile
(p
, src
, options
));
10640 if
(options
& RE_OPTION_ONCE
) {
10641 node
= NEW_NODE
(NODE_ONCE
, 0, node
, 0, loc
);
10649 new_kw_arg
(struct parser_params
*p
, NODE
*k
, const YYLTYPE *loc
)
10652 return NEW_KW_ARG
(0, (k
), loc
);
10656 new_xstring
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
10659 VALUE lit
= STR_NEW0
();
10660 NODE
*xstr
= NEW_XSTR
(lit
, loc
);
10661 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, lit
);
10664 switch
(nd_type
(node
)) {
10666 nd_set_type
(node
, NODE_XSTR
);
10667 nd_set_loc
(node
, loc
);
10670 nd_set_type
(node
, NODE_DXSTR
);
10671 nd_set_loc
(node
, loc
);
10674 node
= NEW_NODE
(NODE_DXSTR
, Qnil
, 1, NEW_LIST
(node
, loc
), loc
);
10681 check_literal_when
(struct parser_params
*p
, NODE
*arg
, const YYLTYPE *loc
)
10685 if
(!arg ||
!p
->case_labels
) return
;
10687 lit
= rb_node_case_when_optimizable_literal
(arg
);
10688 if
(lit
== Qundef
) return
;
10689 if
(nd_type_p
(arg
, NODE_STR
)) {
10690 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, arg
->nd_lit
= lit
);
10693 if
(NIL_P
(p
->case_labels
)) {
10694 p
->case_labels
= rb_obj_hide
(rb_hash_new
());
10697 VALUE line
= rb_hash_lookup
(p
->case_labels
, lit
);
10698 if
(!NIL_P
(line
)) {
10699 rb_warning1
("duplicated `when' clause with line %d is ignored",
10704 rb_hash_aset
(p
->case_labels
, lit
, INT2NUM
(p
->ruby_sourceline
));
10707 #else /* !RIPPER */
10709 id_is_var
(struct parser_params
*p
, ID id
)
10711 if
(is_notop_id
(id
)) {
10712 switch
(id
& ID_SCOPE_MASK
) {
10713 case ID_GLOBAL
: case ID_INSTANCE
: case ID_CONST
: case ID_CLASS
:
10716 if
(dyna_in_block
(p
)) {
10717 if
(NUMPARAM_ID_P
(id
) || dvar_defined
(p
, id
)) return
1;
10719 if
(local_id
(p
, id
)) return
1;
10720 /* method call without arguments */
10724 compile_error
(p
, "identifier %"PRIsVALUE
" is not valid to get", rb_id2str
(id
));
10729 new_regexp
(struct parser_params
*p
, VALUE re
, VALUE opt
, const YYLTYPE *loc
)
10731 VALUE src
= 0, err
;
10733 if
(ripper_is_node_yylval
(re
)) {
10734 src
= RNODE
(re
)->nd_cval
;
10735 re
= RNODE
(re
)->nd_rval
;
10737 if
(ripper_is_node_yylval
(opt
)) {
10738 options
= (int)RNODE
(opt
)->nd_tag
;
10739 opt
= RNODE
(opt
)->nd_rval
;
10741 if
(src
&& NIL_P
(parser_reg_compile
(p
, src
, options
, &err
))) {
10742 compile_error
(p
, "%"PRIsVALUE
, err
);
10744 return dispatch2
(regexp_literal
, re
, opt
);
10746 #endif /* !RIPPER */
10748 static inline
enum lex_state_e
10749 parser_set_lex_state
(struct parser_params
*p
, enum lex_state_e ls
, int line
)
10752 ls
= rb_parser_trace_lex_state
(p
, p
->lex.state
, ls
, line
);
10754 return p
->lex.state
= ls
;
10758 static const char rb_parser_lex_state_names
[][8] = {
10759 "BEG", "END", "ENDARG", "ENDFN", "ARG",
10760 "CMDARG", "MID", "FNAME", "DOT", "CLASS",
10761 "LABEL", "LABELED","FITEM",
10765 append_lex_state_name
(enum lex_state_e state
, VALUE buf
)
10768 unsigned int mask
= 1;
10769 static const char none
[] = "NONE";
10771 for
(i
= 0; i
< EXPR_MAX_STATE
; ++i
, mask
<<= 1) {
10772 if
((unsigned)state
& mask
) {
10774 rb_str_cat
(buf
, "|", 1);
10777 rb_str_cat_cstr
(buf
, rb_parser_lex_state_names
[i
]);
10781 rb_str_cat
(buf
, none
, sizeof
(none
)-1);
10787 flush_debug_buffer
(struct parser_params
*p
, VALUE out
, VALUE str
)
10789 VALUE mesg
= p
->debug_buffer
;
10791 if
(!NIL_P
(mesg
) && RSTRING_LEN
(mesg
)) {
10792 p
->debug_buffer
= Qnil
;
10793 rb_io_puts
(1, &mesg
, out
);
10795 if
(!NIL_P
(str
) && RSTRING_LEN
(str
)) {
10796 rb_io_write
(p
->debug_output
, str
);
10801 rb_parser_trace_lex_state
(struct parser_params
*p
, enum lex_state_e from
,
10802 enum lex_state_e to
, int line
)
10805 mesg
= rb_str_new_cstr
("lex_state: ");
10806 append_lex_state_name
(from
, mesg
);
10807 rb_str_cat_cstr
(mesg
, " -> ");
10808 append_lex_state_name
(to
, mesg
);
10809 rb_str_catf
(mesg
, " at line %d\n", line
);
10810 flush_debug_buffer
(p
, p
->debug_output
, mesg
);
10815 rb_parser_lex_state_name
(enum lex_state_e state
)
10817 return rb_fstring
(append_lex_state_name
(state
, rb_str_new
(0, 0)));
10821 append_bitstack_value
(stack_type stack
, VALUE mesg
)
10824 rb_str_cat_cstr
(mesg
, "0");
10827 stack_type mask
= (stack_type
)1U << (CHAR_BIT
* sizeof
(stack_type
) - 1);
10828 for
(; mask
&& !(stack
& mask
); mask
>>= 1) continue
;
10829 for
(; mask
; mask
>>= 1) rb_str_cat
(mesg
, stack
& mask ?
"1" : "0", 1);
10834 rb_parser_show_bitstack
(struct parser_params
*p
, stack_type stack
,
10835 const char *name
, int line
)
10837 VALUE mesg
= rb_sprintf
("%s: ", name
);
10838 append_bitstack_value
(stack
, mesg
);
10839 rb_str_catf
(mesg
, " at line %d\n", line
);
10840 flush_debug_buffer
(p
, p
->debug_output
, mesg
);
10844 rb_parser_fatal
(struct parser_params
*p
, const char *fmt
, ...
)
10847 VALUE mesg
= rb_str_new_cstr
("internal parser error: ");
10850 rb_str_vcatf
(mesg
, fmt
, ap
);
10852 yyerror0
(RSTRING_PTR
(mesg
));
10855 mesg
= rb_str_new
(0, 0);
10856 append_lex_state_name
(p
->lex.state
, mesg
);
10857 compile_error
(p
, "lex.state: %"PRIsVALUE
, mesg
);
10858 rb_str_resize
(mesg
, 0);
10859 append_bitstack_value
(p
->cond_stack
, mesg
);
10860 compile_error
(p
, "cond_stack: %"PRIsVALUE
, mesg
);
10861 rb_str_resize
(mesg
, 0);
10862 append_bitstack_value
(p
->cmdarg_stack
, mesg
);
10863 compile_error
(p
, "cmdarg_stack: %"PRIsVALUE
, mesg
);
10864 if
(p
->debug_output
== rb_ractor_stdout
())
10865 p
->debug_output
= rb_ractor_stderr
();
10870 rb_parser_set_pos
(YYLTYPE *yylloc, int sourceline
, int beg_pos
, int end_pos
)
10872 yylloc->beg_pos.lineno
= sourceline
;
10873 yylloc->beg_pos.column
= beg_pos
;
10874 yylloc->end_pos.lineno
= sourceline
;
10875 yylloc->end_pos.column
= end_pos
;
10880 rb_parser_set_location_from_strterm_heredoc
(struct parser_params
*p
, rb_strterm_heredoc_t
*here
, YYLTYPE *yylloc)
10882 int sourceline
= here
->sourceline
;
10883 int beg_pos
= (int)here
->offset
- here
->quote
10884 - (rb_strlen_lit
("<<-") - !(here
->func
& STR_FUNC_INDENT
));
10885 int end_pos
= (int)here
->offset
+ here
->length
+ here
->quote
;
10887 return rb_parser_set_pos
(yylloc, sourceline
, beg_pos
, end_pos
);
10891 rb_parser_set_location_of_none
(struct parser_params
*p
, YYLTYPE *yylloc)
10893 int sourceline
= p
->ruby_sourceline
;
10894 int beg_pos
= (int)(p
->lex.ptok
- p
->lex.pbeg
);
10895 int end_pos
= (int)(p
->lex.ptok
- p
->lex.pbeg
);
10896 return rb_parser_set_pos
(yylloc, sourceline
, beg_pos
, end_pos
);
10900 rb_parser_set_location
(struct parser_params
*p
, YYLTYPE *yylloc)
10902 int sourceline
= p
->ruby_sourceline
;
10903 int beg_pos
= (int)(p
->lex.ptok
- p
->lex.pbeg
);
10904 int end_pos
= (int)(p
->lex.pcur
- p
->lex.pbeg
);
10905 return rb_parser_set_pos
(yylloc, sourceline
, beg_pos
, end_pos
);
10907 #endif /* !RIPPER */
10910 assignable0
(struct parser_params
*p
, ID id
, const char **err
)
10912 if
(!id
) return
-1;
10915 *err
= "Can't change the value of self";
10918 *err
= "Can't assign to nil";
10921 *err
= "Can't assign to true";
10923 case keyword_false
:
10924 *err
= "Can't assign to false";
10926 case keyword__FILE__
:
10927 *err
= "Can't assign to __FILE__";
10929 case keyword__LINE__
:
10930 *err
= "Can't assign to __LINE__";
10932 case keyword__ENCODING__
:
10933 *err
= "Can't assign to __ENCODING__";
10936 switch
(id_type
(id
)) {
10938 if
(dyna_in_block
(p
)) {
10939 if
(p
->max_numparam
> NO_PARAM
&& NUMPARAM_ID_P
(id
)) {
10940 compile_error
(p
, "Can't assign to numbered parameter _%d",
10941 NUMPARAM_ID_TO_IDX
(id
));
10944 if
(dvar_curr
(p
, id
)) return NODE_DASGN
;
10945 if
(dvar_defined
(p
, id
)) return NODE_DASGN
;
10946 if
(local_id
(p
, id
)) return NODE_LASGN
;
10951 if
(!local_id
(p
, id
)) local_var
(p
, id
);
10955 case ID_GLOBAL
: return NODE_GASGN
;
10956 case ID_INSTANCE
: return NODE_IASGN
;
10958 if
(!p
->ctxt.in_def
) return NODE_CDECL
;
10959 *err
= "dynamic constant assignment";
10961 case ID_CLASS
: return NODE_CVASGN
;
10963 compile_error
(p
, "identifier %"PRIsVALUE
" is not valid to set", rb_id2str
(id
));
10970 assignable
(struct parser_params
*p
, ID id
, NODE
*val
, const YYLTYPE *loc
)
10972 const char *err
= 0;
10973 int node_type
= assignable0
(p
, id
, &err
);
10974 switch
(node_type
) {
10975 case NODE_DASGN
: return NEW_DASGN
(id
, val
, loc
);
10976 case NODE_LASGN
: return NEW_LASGN
(id
, val
, loc
);
10977 case NODE_GASGN
: return NEW_GASGN
(id
, val
, loc
);
10978 case NODE_IASGN
: return NEW_IASGN
(id
, val
, loc
);
10979 case NODE_CDECL
: return NEW_CDECL
(id
, val
, 0, loc
);
10980 case NODE_CVASGN
: return NEW_CVASGN
(id
, val
, loc
);
10982 if
(err
) yyerror1
(loc
, err
);
10983 return NEW_BEGIN
(0, loc
);
10987 assignable
(struct parser_params
*p
, VALUE lhs
)
10989 const char *err
= 0;
10990 assignable0
(p
, get_id
(lhs
), &err
);
10991 if
(err
) lhs
= assign_error
(p
, err
, lhs
);
10997 is_private_local_id
(ID name
)
11000 if
(name
== idUScore
) return
1;
11001 if
(!is_local_id
(name
)) return
0;
11002 s
= rb_id2str
(name
);
11004 return RSTRING_PTR
(s
)[0] == '_';
11008 shadowing_lvar_0
(struct parser_params
*p
, ID name
)
11010 if
(is_private_local_id
(name
)) return
1;
11011 if
(dyna_in_block
(p
)) {
11012 if
(dvar_curr
(p
, name
)) {
11013 yyerror0
("duplicated argument name");
11015 else if
(dvar_defined
(p
, name
) || local_id
(p
, name
)) {
11016 vtable_add
(p
->lvtbl
->vars
, name
);
11017 if
(p
->lvtbl
->used
) {
11018 vtable_add
(p
->lvtbl
->used
, (ID
)p
->ruby_sourceline | LVAR_USED
);
11024 if
(local_id
(p
, name
)) {
11025 yyerror0
("duplicated argument name");
11032 shadowing_lvar
(struct parser_params
*p
, ID name
)
11034 shadowing_lvar_0
(p
, name
);
11039 new_bv
(struct parser_params
*p
, ID name
)
11042 if
(!is_local_id
(name
)) {
11043 compile_error
(p
, "invalid local variable - %"PRIsVALUE
,
11047 if
(!shadowing_lvar_0
(p
, name
)) return
;
11053 aryset
(struct parser_params
*p
, NODE
*recv
, NODE
*idx
, const YYLTYPE *loc
)
11055 return NEW_ATTRASGN
(recv
, tASET
, idx
, loc
);
11059 block_dup_check
(struct parser_params
*p
, NODE
*node1
, NODE
*node2
)
11061 if
(node2
&& node1
&& nd_type_p
(node1
, NODE_BLOCK_PASS
)) {
11062 compile_error
(p
, "both block arg and actual block given");
11067 attrset
(struct parser_params
*p
, NODE
*recv
, ID atype
, ID id
, const YYLTYPE *loc
)
11069 if
(!CALL_Q_P
(atype
)) id
= rb_id_attrset
(id
);
11070 return NEW_ATTRASGN
(recv
, id
, 0, loc
);
11074 rb_backref_error
(struct parser_params
*p
, NODE
*node
)
11076 switch
(nd_type
(node
)) {
11078 compile_error
(p
, "Can't set variable $%ld", node
->nd_nth
);
11080 case NODE_BACK_REF
:
11081 compile_error
(p
, "Can't set variable $%c", (int)node
->nd_nth
);
11087 backref_error
(struct parser_params
*p
, NODE
*ref
, VALUE expr
)
11089 VALUE mesg
= rb_str_new_cstr
("Can't set variable ");
11090 rb_str_append
(mesg
, ref
->nd_cval
);
11091 return dispatch2
(assign_error
, mesg
, expr
);
11097 arg_append
(struct parser_params
*p
, NODE
*node1
, NODE
*node2
, const YYLTYPE *loc
)
11099 if
(!node1
) return NEW_LIST
(node2
, &node2
->nd_loc
);
11100 switch
(nd_type
(node1
)) {
11102 return list_append
(p
, node1
, node2
);
11103 case NODE_BLOCK_PASS
:
11104 node1
->nd_head
= arg_append
(p
, node1
->nd_head
, node2
, loc
);
11105 node1
->nd_loc.end_pos
= node1
->nd_head
->nd_loc.end_pos
;
11107 case NODE_ARGSPUSH
:
11108 node1
->nd_body
= list_append
(p
, NEW_LIST
(node1
->nd_body
, &node1
->nd_body
->nd_loc
), node2
);
11109 node1
->nd_loc.end_pos
= node1
->nd_body
->nd_loc.end_pos
;
11110 nd_set_type
(node1
, NODE_ARGSCAT
);
11113 if
(!nd_type_p
(node1
->nd_body
, NODE_LIST
)) break
;
11114 node1
->nd_body
= list_append
(p
, node1
->nd_body
, node2
);
11115 node1
->nd_loc.end_pos
= node1
->nd_body
->nd_loc.end_pos
;
11118 return NEW_ARGSPUSH
(node1
, node2
, loc
);
11122 arg_concat
(struct parser_params
*p
, NODE
*node1
, NODE
*node2
, const YYLTYPE *loc
)
11124 if
(!node2
) return node1
;
11125 switch
(nd_type
(node1
)) {
11126 case NODE_BLOCK_PASS
:
11127 if
(node1
->nd_head
)
11128 node1
->nd_head
= arg_concat
(p
, node1
->nd_head
, node2
, loc
);
11130 node1
->nd_head
= NEW_LIST
(node2
, loc
);
11132 case NODE_ARGSPUSH
:
11133 if
(!nd_type_p
(node2
, NODE_LIST
)) break
;
11134 node1
->nd_body
= list_concat
(NEW_LIST
(node1
->nd_body
, loc
), node2
);
11135 nd_set_type
(node1
, NODE_ARGSCAT
);
11138 if
(!nd_type_p
(node2
, NODE_LIST
) ||
11139 !nd_type_p
(node1
->nd_body
, NODE_LIST
)) break
;
11140 node1
->nd_body
= list_concat
(node1
->nd_body
, node2
);
11143 return NEW_ARGSCAT
(node1
, node2
, loc
);
11147 last_arg_append
(struct parser_params
*p
, NODE
*args
, NODE
*last_arg
, const YYLTYPE *loc
)
11150 if
((n1
= splat_array
(args
)) != 0) {
11151 return list_append
(p
, n1
, last_arg
);
11153 return arg_append
(p
, args
, last_arg
, loc
);
11157 rest_arg_append
(struct parser_params
*p
, NODE
*args
, NODE
*rest_arg
, const YYLTYPE *loc
)
11160 if
((nd_type_p
(rest_arg
, NODE_LIST
)) && (n1
= splat_array
(args
)) != 0) {
11161 return list_concat
(n1
, rest_arg
);
11163 return arg_concat
(p
, args
, rest_arg
, loc
);
11167 splat_array
(NODE
* node
)
11169 if
(nd_type_p
(node
, NODE_SPLAT
)) node
= node
->nd_head
;
11170 if
(nd_type_p
(node
, NODE_LIST
)) return node
;
11175 mark_lvar_used
(struct parser_params
*p
, NODE
*rhs
)
11179 switch
(nd_type
(rhs
)) {
11181 if
(local_id_ref
(p
, rhs
->nd_vid
, &vidp
)) {
11182 if
(vidp
) *vidp |
= LVAR_USED
;
11186 if
(dvar_defined_ref
(p
, rhs
->nd_vid
, &vidp
)) {
11187 if
(vidp
) *vidp |
= LVAR_USED
;
11192 for
(rhs
= rhs
->nd_head
; rhs
; rhs
= rhs
->nd_next
) {
11193 mark_lvar_used
(p
, rhs
->nd_head
);
11201 const_decl_path
(struct parser_params
*p
, NODE
**dest
)
11204 if
(!nd_type_p
(n
, NODE_CALL
)) {
11205 const YYLTYPE *loc
= &n
->nd_loc
;
11208 path
= rb_id2str
(n
->nd_vid
);
11212 path
= rb_ary_new
();
11213 for
(; n
&& nd_type_p
(n
, NODE_COLON2
); n
= n
->nd_head
) {
11214 rb_ary_push
(path
, rb_id2str
(n
->nd_mid
));
11216 if
(n
&& nd_type_p
(n
, NODE_CONST
)) {
11218 rb_ary_push
(path
, rb_id2str
(n
->nd_vid
));
11220 else if
(n
&& nd_type_p
(n
, NODE_COLON3
)) {
11222 rb_ary_push
(path
, rb_str_new
(0, 0));
11225 // expression::Name
11226 rb_ary_push
(path
, rb_str_new_cstr
("..."));
11228 path
= rb_ary_join
(rb_ary_reverse
(path
), rb_str_new_cstr
("::"));
11229 path
= rb_fstring
(path
);
11231 *dest
= n
= NEW_LIT
(path
, loc
);
11232 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, n
->nd_lit
);
11237 extern VALUE rb_mRubyVMFrozenCore
;
11240 make_shareable_node
(struct parser_params
*p
, NODE
*value
, bool copy
, const YYLTYPE *loc
)
11242 NODE
*fcore
= NEW_LIT
(rb_mRubyVMFrozenCore
, loc
);
11245 return NEW_CALL
(fcore
, rb_intern
("make_shareable_copy"),
11246 NEW_LIST
(value
, loc
), loc
);
11249 return NEW_CALL
(fcore
, rb_intern
("make_shareable"),
11250 NEW_LIST
(value
, loc
), loc
);
11255 ensure_shareable_node
(struct parser_params
*p
, NODE
**dest
, NODE
*value
, const YYLTYPE *loc
)
11257 NODE
*fcore
= NEW_LIT
(rb_mRubyVMFrozenCore
, loc
);
11258 NODE
*args
= NEW_LIST
(value
, loc
);
11259 args
= list_append
(p
, args
, const_decl_path
(p
, dest
));
11260 return NEW_CALL
(fcore
, rb_intern
("ensure_shareable"), args
, loc
);
11263 static int is_static_content
(NODE
*node
);
11266 shareable_literal_value
(NODE
*node
)
11268 if
(!node
) return Qnil
;
11269 enum node_type type
= nd_type
(node
);
11278 return node
->nd_lit
;
11284 #ifndef SHAREABLE_BARE_EXPRESSION
11285 #define SHAREABLE_BARE_EXPRESSION 1
11289 shareable_literal_constant
(struct parser_params
*p
, enum shareability shareable
,
11290 NODE
**dest
, NODE
*value
, const YYLTYPE *loc
, size_t level
)
11292 # define shareable_literal_constant_next(n) \
11293 shareable_literal_constant
(p
, shareable
, dest
, (n
), &(n
)->nd_loc
, level
+1)
11296 if
(!value
) return
0;
11297 enum node_type type
= nd_type
(value
);
11306 if
(shareable
== shareable_literal
) {
11307 value
= NEW_CALL
(value
, idUMinus
, 0, loc
);
11312 lit
= rb_fstring
(value
->nd_lit
);
11313 nd_set_type
(value
, NODE_LIT
);
11314 RB_OBJ_WRITE
(p
->ast
, &value
->nd_lit
, lit
);
11318 lit
= rb_ary_new
();
11319 OBJ_FREEZE_RAW
(lit
);
11320 NODE
*n
= NEW_LIT
(lit
, loc
);
11321 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, n
->nd_lit
);
11325 lit
= rb_ary_new
();
11326 for
(NODE
*n
= value
; n
; n
= n
->nd_next
) {
11327 NODE
*elt
= n
->nd_head
;
11329 elt
= shareable_literal_constant_next
(elt
);
11333 else if
(RTEST
(lit
)) {
11339 VALUE e
= shareable_literal_value
(elt
);
11341 rb_ary_push
(lit
, e
);
11345 lit
= Qnil
; /* make shareable at runtime */
11352 if
(!value
->nd_brace
) return
0;
11353 lit
= rb_hash_new
();
11354 for
(NODE
*n
= value
->nd_head
; n
; n
= n
->nd_next
->nd_next
) {
11355 NODE
*key
= n
->nd_head
;
11356 NODE
*val
= n
->nd_next
->nd_head
;
11358 key
= shareable_literal_constant_next
(key
);
11362 else if
(RTEST
(lit
)) {
11363 rb_hash_clear
(lit
);
11368 val
= shareable_literal_constant_next
(val
);
11370 n
->nd_next
->nd_head
= val
;
11372 else if
(RTEST
(lit
)) {
11373 rb_hash_clear
(lit
);
11378 VALUE k
= shareable_literal_value
(key
);
11379 VALUE v
= shareable_literal_value
(val
);
11380 if
(k
!= Qundef
&& v
!= Qundef
) {
11381 rb_hash_aset
(lit
, k
, v
);
11384 rb_hash_clear
(lit
);
11385 lit
= Qnil
; /* make shareable at runtime */
11392 if
(shareable
== shareable_literal
&&
11393 (SHAREABLE_BARE_EXPRESSION || level
> 0)) {
11394 return ensure_shareable_node
(p
, dest
, value
, loc
);
11399 /* Array or Hash */
11400 if
(!lit
) return
0;
11402 // if shareable_literal, all elements should have been ensured
11404 value
= make_shareable_node
(p
, value
, false
, loc
);
11407 value
= NEW_LIT
(rb_ractor_make_shareable
(lit
), loc
);
11408 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, value
->nd_lit
);
11412 # undef shareable_literal_constant_next
11416 shareable_constant_value
(struct parser_params
*p
, enum shareability shareable
,
11417 NODE
*lhs
, NODE
*value
, const YYLTYPE *loc
)
11419 if
(!value
) return
0;
11420 switch
(shareable
) {
11421 case shareable_none
:
11424 case shareable_literal
:
11426 NODE
*lit
= shareable_literal_constant
(p
, shareable
, &lhs
, value
, loc
, 0);
11427 if
(lit
) return lit
;
11432 case shareable_copy
:
11433 case shareable_everything
:
11435 NODE
*lit
= shareable_literal_constant
(p
, shareable
, &lhs
, value
, loc
, 0);
11436 if
(lit
) return lit
;
11437 return make_shareable_node
(p
, value
, shareable
== shareable_copy
, loc
);
11442 UNREACHABLE_RETURN
(0);
11447 node_assign
(struct parser_params
*p
, NODE
*lhs
, NODE
*rhs
, struct lex_context ctxt
, const YYLTYPE *loc
)
11449 if
(!lhs
) return
0;
11451 switch
(nd_type
(lhs
)) {
11453 rhs
= shareable_constant_value
(p
, ctxt.shareable_constant_value
, lhs
, rhs
, loc
);
11462 lhs
->nd_value
= rhs
;
11463 nd_set_loc
(lhs
, loc
);
11466 case NODE_ATTRASGN
:
11467 lhs
->nd_args
= arg_append
(p
, lhs
->nd_args
, rhs
, loc
);
11468 nd_set_loc
(lhs
, loc
);
11472 /* should not happen */
11480 value_expr_check
(struct parser_params
*p
, NODE
*node
)
11482 NODE
*void_node
= 0, *vn
;
11485 rb_warning0
("empty expression");
11488 switch
(nd_type
(node
)) {
11494 return void_node ? void_node
: node
;
11497 if
(!node
->nd_body ||
!nd_type_p
(node
->nd_body
, NODE_IN
)) {
11498 compile_error
(p
, "unexpected node");
11501 if
(node
->nd_body
->nd_body
) {
11504 /* single line pattern matching */
11505 return void_node ? void_node
: node
;
11508 while
(node
->nd_next
) {
11509 node
= node
->nd_next
;
11511 node
= node
->nd_head
;
11515 node
= node
->nd_body
;
11520 if
(!node
->nd_body
) {
11523 else if
(!node
->nd_else
) {
11526 vn
= value_expr_check
(p
, node
->nd_body
);
11527 if
(!vn
) return NULL
;
11528 if
(!void_node
) void_node
= vn
;
11529 node
= node
->nd_else
;
11534 node
= node
->nd_1st
;
11540 mark_lvar_used
(p
, node
);
11552 value_expr_gen
(struct parser_params
*p
, NODE
*node
)
11554 NODE
*void_node
= value_expr_check
(p
, node
);
11556 yyerror1
(&void_node
->nd_loc
, "void value expression");
11557 /* or "control never reach"? */
11563 void_expr
(struct parser_params
*p
, NODE
*node
)
11565 const char *useless
= 0;
11567 if
(!RTEST
(ruby_verbose
)) return
;
11569 if
(!node ||
!(node
= nd_once_body
(node
))) return
;
11570 switch
(nd_type
(node
)) {
11572 switch
(node
->nd_mid
) {
11591 useless
= rb_id2name
(node
->nd_mid
);
11602 case NODE_BACK_REF
:
11603 useless
= "a variable";
11606 useless
= "a constant";
11612 useless
= "a literal";
11637 useless
= "defined?";
11642 rb_warn1L
(nd_line
(node
), "possibly useless use of %s in void context", WARN_S
(useless
));
11647 void_stmts
(struct parser_params
*p
, NODE
*node
)
11649 NODE
*const n
= node
;
11650 if
(!RTEST
(ruby_verbose
)) return n
;
11651 if
(!node
) return n
;
11652 if
(!nd_type_p
(node
, NODE_BLOCK
)) return n
;
11654 while
(node
->nd_next
) {
11655 void_expr
(p
, node
->nd_head
);
11656 node
= node
->nd_next
;
11662 remove_begin
(NODE
*node
)
11664 NODE
**n
= &node
, *n1
= node
;
11665 while
(n1
&& nd_type_p
(n1
, NODE_BEGIN
) && n1
->nd_body
) {
11666 *n
= n1
= n1
->nd_body
;
11672 remove_begin_all
(NODE
*node
)
11674 NODE
**n
= &node
, *n1
= node
;
11675 while
(n1
&& nd_type_p
(n1
, NODE_BEGIN
)) {
11676 *n
= n1
= n1
->nd_body
;
11682 reduce_nodes
(struct parser_params
*p
, NODE
**body
)
11684 NODE
*node
= *body
;
11687 *body
= NEW_NIL
(&NULL_LOC
);
11690 #define subnodes(n1, n2) \
11691 ((!node
->n1
) ?
(node
->n2 ?
(body
= &node
->n2
, 1) : 0) : \
11692 (!node
->n2
) ?
(body
= &node
->n1
, 1) : \
11693 (reduce_nodes
(p
, &node
->n1
), body
= &node
->n2
, 1))
11696 int newline
= (int)(node
->flags
& NODE_FL_NEWLINE
);
11697 switch
(nd_type
(node
)) {
11703 *body
= node
= node
->nd_stts
;
11704 if
(newline
&& node
) node
->flags |
= NODE_FL_NEWLINE
;
11707 *body
= node
= node
->nd_body
;
11708 if
(newline
&& node
) node
->flags |
= NODE_FL_NEWLINE
;
11711 body
= &node
->nd_end
->nd_head
;
11715 if
(subnodes
(nd_body
, nd_else
)) break
;
11718 body
= &node
->nd_body
;
11721 if
(!subnodes
(nd_body
, nd_next
)) goto end
;
11724 if
(!subnodes
(nd_head
, nd_resq
)) goto end
;
11727 if
(node
->nd_else
) {
11728 body
= &node
->nd_resq
;
11731 if
(!subnodes
(nd_head
, nd_resq
)) goto end
;
11737 if
(newline
&& node
) node
->flags |
= NODE_FL_NEWLINE
;
11744 is_static_content
(NODE
*node
)
11746 if
(!node
) return
1;
11747 switch
(nd_type
(node
)) {
11749 if
(!(node
= node
->nd_head
)) break
;
11752 if
(!is_static_content
(node
->nd_head
)) return
0;
11753 } while
((node
= node
->nd_next
) != 0);
11768 assign_in_cond
(struct parser_params
*p
, NODE
*node
)
11770 switch
(nd_type
(node
)) {
11782 if
(!node
->nd_value
) return
1;
11783 if
(is_static_content
(node
->nd_value
)) {
11784 /* reports always */
11785 parser_warn
(p
, node
->nd_value
, "found `= literal' in conditional, should be ==");
11796 #define SWITCH_BY_COND_TYPE(t, w, arg) \
11798 case COND_IN_OP
: break
; \
11799 case COND_IN_COND
: rb_
##w##0(arg "literal in condition"); break; \
11800 case COND_IN_FF
: rb_
##w##0(arg "literal in flip-flop"); break; \
11803 static NODE
*cond0
(struct parser_params
*,NODE
*,enum cond_type
,const YYLTYPE*);
11806 range_op
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
11808 enum node_type type
;
11810 if
(node
== 0) return
0;
11812 type
= nd_type
(node
);
11814 if
(type
== NODE_LIT
&& FIXNUM_P
(node
->nd_lit
)) {
11815 if
(!e_option_supplied
(p
)) parser_warn
(p
, node
, "integer literal in flip-flop");
11816 ID lineno
= rb_intern
("$.");
11817 return NEW_CALL
(node
, tEQ
, NEW_LIST
(NEW_GVAR
(lineno
, loc
), loc
), loc
);
11819 return cond0
(p
, node
, COND_IN_FF
, loc
);
11823 cond0
(struct parser_params
*p
, NODE
*node
, enum cond_type type
, const YYLTYPE *loc
)
11825 if
(node
== 0) return
0;
11826 if
(!(node
= nd_once_body
(node
))) return
0;
11827 assign_in_cond
(p
, node
);
11829 switch
(nd_type
(node
)) {
11833 SWITCH_BY_COND_TYPE
(type
, warn
, "string ")
11837 if
(!e_option_supplied
(p
)) SWITCH_BY_COND_TYPE
(type
, warning
, "regex ")
11839 return NEW_MATCH2
(node
, NEW_GVAR
(idLASTLINE
, loc
), loc
);
11843 node
->nd_1st
= cond0
(p
, node
->nd_1st
, COND_IN_COND
, loc
);
11844 node
->nd_2nd
= cond0
(p
, node
->nd_2nd
, COND_IN_COND
, loc
);
11849 node
->nd_beg
= range_op
(p
, node
->nd_beg
, loc
);
11850 node
->nd_end
= range_op
(p
, node
->nd_end
, loc
);
11851 if
(nd_type_p
(node
, NODE_DOT2
)) nd_set_type
(node
,NODE_FLIP2
);
11852 else if
(nd_type_p
(node
, NODE_DOT3
)) nd_set_type
(node
, NODE_FLIP3
);
11857 SWITCH_BY_COND_TYPE
(type
, warning
, "symbol ")
11861 if
(RB_TYPE_P
(node
->nd_lit
, T_REGEXP
)) {
11862 if
(!e_option_supplied
(p
)) SWITCH_BY_COND_TYPE
(type
, warn
, "regex ")
11863 nd_set_type
(node
, NODE_MATCH
);
11865 else if
(node
->nd_lit
== Qtrue ||
11866 node
->nd_lit
== Qfalse
) {
11867 /* booleans are OK, e.g., while true */
11869 else if
(SYMBOL_P
(node
->nd_lit
)) {
11873 SWITCH_BY_COND_TYPE
(type
, warning
, "")
11882 cond
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
11884 if
(node
== 0) return
0;
11885 return cond0
(p
, node
, COND_IN_COND
, loc
);
11889 method_cond
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
11891 if
(node
== 0) return
0;
11892 return cond0
(p
, node
, COND_IN_OP
, loc
);
11896 new_nil_at
(struct parser_params
*p
, const rb_code_position_t
*pos
)
11898 YYLTYPE loc
= {*pos
, *pos
};
11899 return NEW_NIL
(&loc
);
11903 new_if
(struct parser_params
*p
, NODE
*cc
, NODE
*left
, NODE
*right
, const YYLTYPE *loc
)
11905 if
(!cc
) return right
;
11906 cc
= cond0
(p
, cc
, COND_IN_COND
, loc
);
11907 return newline_node
(NEW_IF
(cc
, left
, right
, loc
));
11911 new_unless
(struct parser_params
*p
, NODE
*cc
, NODE
*left
, NODE
*right
, const YYLTYPE *loc
)
11913 if
(!cc
) return right
;
11914 cc
= cond0
(p
, cc
, COND_IN_COND
, loc
);
11915 return newline_node
(NEW_UNLESS
(cc
, left
, right
, loc
));
11919 logop
(struct parser_params
*p
, ID id
, NODE
*left
, NODE
*right
,
11920 const YYLTYPE *op_loc
, const YYLTYPE *loc
)
11922 enum node_type type
= id
== idAND || id
== idANDOP ? NODE_AND
: NODE_OR
;
11925 if
(left
&& nd_type_p
(left
, type
)) {
11926 NODE
*node
= left
, *second
;
11927 while
((second
= node
->nd_2nd
) != 0 && nd_type_p
(second
, type
)) {
11930 node
->nd_2nd
= NEW_NODE
(type
, second
, right
, 0, loc
);
11931 nd_set_line
(node
->nd_2nd
, op_loc
->beg_pos.lineno
);
11932 left
->nd_loc.end_pos
= loc
->end_pos
;
11935 op
= NEW_NODE
(type
, left
, right
, 0, loc
);
11936 nd_set_line
(op
, op_loc
->beg_pos.lineno
);
11941 no_blockarg
(struct parser_params
*p
, NODE
*node
)
11943 if
(node
&& nd_type_p
(node
, NODE_BLOCK_PASS
)) {
11944 compile_error
(p
, "block argument should not be given");
11949 ret_args
(struct parser_params
*p
, NODE
*node
)
11952 no_blockarg
(p
, node
);
11953 if
(nd_type_p
(node
, NODE_LIST
)) {
11954 if
(node
->nd_next
== 0) {
11955 node
= node
->nd_head
;
11958 nd_set_type
(node
, NODE_VALUES
);
11966 new_yield
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
11968 if
(node
) no_blockarg
(p
, node
);
11970 return NEW_YIELD
(node
, loc
);
11974 negate_lit
(struct parser_params
*p
, VALUE lit
)
11976 if
(FIXNUM_P
(lit
)) {
11977 return LONG2FIX
(-FIX2LONG
(lit
));
11979 if
(SPECIAL_CONST_P
(lit
)) {
11981 if
(FLONUM_P
(lit
)) {
11982 return DBL2NUM
(-RFLOAT_VALUE
(lit
));
11987 switch
(BUILTIN_TYPE
(lit
)) {
11989 BIGNUM_NEGATE
(lit
);
11990 lit
= rb_big_norm
(lit
);
11993 RATIONAL_SET_NUM
(lit
, negate_lit
(p
, RRATIONAL
(lit
)->num
));
11996 RCOMPLEX_SET_REAL
(lit
, negate_lit
(p
, RCOMPLEX
(lit
)->real
));
11997 RCOMPLEX_SET_IMAG
(lit
, negate_lit
(p
, RCOMPLEX
(lit
)->imag
));
12000 lit
= DBL2NUM
(-RFLOAT_VALUE
(lit
));
12004 rb_parser_fatal
(p
, "unknown literal type (%s) passed to negate_lit",
12005 rb_builtin_class_name
(lit
));
12012 arg_blk_pass
(NODE
*node1
, NODE
*node2
)
12015 if
(!node1
) return node2
;
12016 node2
->nd_head
= node1
;
12017 nd_set_first_lineno
(node2
, nd_first_lineno
(node1
));
12018 nd_set_first_column
(node2
, nd_first_column
(node1
));
12025 args_info_empty_p
(struct rb_args_info
*args
)
12027 if
(args
->pre_args_num
) return false
;
12028 if
(args
->post_args_num
) return false
;
12029 if
(args
->rest_arg
) return false
;
12030 if
(args
->opt_args
) return false
;
12031 if
(args
->block_arg
) return false
;
12032 if
(args
->kw_args
) return false
;
12033 if
(args
->kw_rest_arg
) return false
;
12038 new_args
(struct parser_params
*p
, NODE
*pre_args
, NODE
*opt_args
, ID rest_arg
, NODE
*post_args
, NODE
*tail
, const YYLTYPE *loc
)
12040 int saved_line
= p
->ruby_sourceline
;
12041 struct rb_args_info
*args
= tail
->nd_ainfo
;
12043 if
(args
->block_arg
== idFWD_BLOCK
) {
12045 yyerror1
(&tail
->nd_loc
, "... after rest argument");
12048 rest_arg
= idFWD_REST
;
12051 args
->pre_args_num
= pre_args ? rb_long2int
(pre_args
->nd_plen
) : 0;
12052 args
->pre_init
= pre_args ? pre_args
->nd_next
: 0;
12054 args
->post_args_num
= post_args ? rb_long2int
(post_args
->nd_plen
) : 0;
12055 args
->post_init
= post_args ? post_args
->nd_next
: 0;
12056 args
->first_post_arg
= post_args ? post_args
->nd_pid
: 0;
12058 args
->rest_arg
= rest_arg
;
12060 args
->opt_args
= opt_args
;
12062 args
->ruby2_keywords
= rest_arg
== idFWD_REST
;
12064 p
->ruby_sourceline
= saved_line
;
12065 nd_set_loc
(tail
, loc
);
12071 new_args_tail
(struct parser_params
*p
, NODE
*kw_args
, ID kw_rest_arg
, ID block
, const YYLTYPE *kw_rest_loc
)
12073 int saved_line
= p
->ruby_sourceline
;
12075 VALUE tmpbuf
= rb_imemo_tmpbuf_auto_free_pointer
();
12076 struct rb_args_info
*args
= ZALLOC
(struct rb_args_info
);
12077 rb_imemo_tmpbuf_set_ptr
(tmpbuf
, args
);
12078 args
->imemo
= tmpbuf
;
12079 node
= NEW_NODE
(NODE_ARGS
, 0, 0, args
, &NULL_LOC
);
12080 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, tmpbuf
);
12081 if
(p
->error_p
) return node
;
12083 args
->block_arg
= block
;
12084 args
->kw_args
= kw_args
;
12088 * def foo(k1: 1, kr1:, k2: 2, **krest, &b)
12089 * variable order: k1, kr1, k2, &b, internal_id, krest
12091 * variable order: kr1, k1, k2, internal_id, krest, &b
12093 ID kw_bits
= internal_id
(p
), *required_kw_vars
, *kw_vars
;
12094 struct vtable
*vtargs
= p
->lvtbl
->args
;
12095 NODE
*kwn
= kw_args
;
12097 vtable_pop
(vtargs
, !!block
+ !!kw_rest_arg
);
12098 required_kw_vars
= kw_vars
= &vtargs
->tbl
[vtargs
->pos
];
12100 if
(!NODE_REQUIRED_KEYWORD_P
(kwn
->nd_body
))
12102 --required_kw_vars
;
12103 kwn
= kwn
->nd_next
;
12106 for
(kwn
= kw_args
; kwn
; kwn
= kwn
->nd_next
) {
12107 ID vid
= kwn
->nd_body
->nd_vid
;
12108 if
(NODE_REQUIRED_KEYWORD_P
(kwn
->nd_body
)) {
12109 *required_kw_vars
++ = vid
;
12116 arg_var
(p
, kw_bits
);
12117 if
(kw_rest_arg
) arg_var
(p
, kw_rest_arg
);
12118 if
(block
) arg_var
(p
, block
);
12120 args
->kw_rest_arg
= NEW_DVAR
(kw_rest_arg
, kw_rest_loc
);
12121 args
->kw_rest_arg
->nd_cflag
= kw_bits
;
12123 else if
(kw_rest_arg
== idNil
) {
12124 args
->no_kwarg
= 1;
12126 else if
(kw_rest_arg
) {
12127 args
->kw_rest_arg
= NEW_DVAR
(kw_rest_arg
, kw_rest_loc
);
12130 p
->ruby_sourceline
= saved_line
;
12135 args_with_numbered
(struct parser_params
*p
, NODE
*args
, int max_numparam
)
12137 if
(max_numparam
> NO_PARAM
) {
12139 YYLTYPE loc
= RUBY_INIT_YYLLOC
();
12140 args
= new_args_tail
(p
, 0, 0, 0, 0);
12141 nd_set_loc
(args
, &loc
);
12143 args
->nd_ainfo
->pre_args_num
= max_numparam
;
12149 new_array_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*pre_arg
, NODE
*aryptn
, const YYLTYPE *loc
)
12151 struct rb_ary_pattern_info
*apinfo
= aryptn
->nd_apinfo
;
12153 aryptn
->nd_pconst
= constant
;
12156 NODE
*pre_args
= NEW_LIST
(pre_arg
, loc
);
12157 if
(apinfo
->pre_args
) {
12158 apinfo
->pre_args
= list_concat
(pre_args
, apinfo
->pre_args
);
12161 apinfo
->pre_args
= pre_args
;
12168 new_array_pattern_tail
(struct parser_params
*p
, NODE
*pre_args
, int has_rest
, ID rest_arg
, NODE
*post_args
, const YYLTYPE *loc
)
12170 int saved_line
= p
->ruby_sourceline
;
12172 VALUE tmpbuf
= rb_imemo_tmpbuf_auto_free_pointer
();
12173 struct rb_ary_pattern_info
*apinfo
= ZALLOC
(struct rb_ary_pattern_info
);
12174 rb_imemo_tmpbuf_set_ptr
(tmpbuf
, apinfo
);
12175 node
= NEW_NODE
(NODE_ARYPTN
, 0, tmpbuf
, apinfo
, loc
);
12176 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, tmpbuf
);
12178 apinfo
->pre_args
= pre_args
;
12182 apinfo
->rest_arg
= assignable
(p
, rest_arg
, 0, loc
);
12185 apinfo
->rest_arg
= NODE_SPECIAL_NO_NAME_REST
;
12189 apinfo
->rest_arg
= NULL
;
12192 apinfo
->post_args
= post_args
;
12194 p
->ruby_sourceline
= saved_line
;
12199 new_find_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*fndptn
, const YYLTYPE *loc
)
12201 fndptn
->nd_pconst
= constant
;
12207 new_find_pattern_tail
(struct parser_params
*p
, ID pre_rest_arg
, NODE
*args
, ID post_rest_arg
, const YYLTYPE *loc
)
12209 int saved_line
= p
->ruby_sourceline
;
12211 VALUE tmpbuf
= rb_imemo_tmpbuf_auto_free_pointer
();
12212 struct rb_fnd_pattern_info
*fpinfo
= ZALLOC
(struct rb_fnd_pattern_info
);
12213 rb_imemo_tmpbuf_set_ptr
(tmpbuf
, fpinfo
);
12214 node
= NEW_NODE
(NODE_FNDPTN
, 0, tmpbuf
, fpinfo
, loc
);
12215 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, tmpbuf
);
12217 fpinfo
->pre_rest_arg
= pre_rest_arg ? assignable
(p
, pre_rest_arg
, 0, loc
) : NODE_SPECIAL_NO_NAME_REST
;
12218 fpinfo
->args
= args
;
12219 fpinfo
->post_rest_arg
= post_rest_arg ? assignable
(p
, post_rest_arg
, 0, loc
) : NODE_SPECIAL_NO_NAME_REST
;
12221 p
->ruby_sourceline
= saved_line
;
12226 new_hash_pattern
(struct parser_params
*p
, NODE
*constant
, NODE
*hshptn
, const YYLTYPE *loc
)
12228 hshptn
->nd_pconst
= constant
;
12233 new_hash_pattern_tail
(struct parser_params
*p
, NODE
*kw_args
, ID kw_rest_arg
, const YYLTYPE *loc
)
12235 int saved_line
= p
->ruby_sourceline
;
12236 NODE
*node
, *kw_rest_arg_node
;
12238 if
(kw_rest_arg
== idNil
) {
12239 kw_rest_arg_node
= NODE_SPECIAL_NO_REST_KEYWORD
;
12241 else if
(kw_rest_arg
) {
12242 kw_rest_arg_node
= assignable
(p
, kw_rest_arg
, 0, loc
);
12245 kw_rest_arg_node
= NULL
;
12248 node
= NEW_NODE
(NODE_HSHPTN
, 0, kw_args
, kw_rest_arg_node
, loc
);
12250 p
->ruby_sourceline
= saved_line
;
12255 dsym_node
(struct parser_params
*p
, NODE
*node
, const YYLTYPE *loc
)
12260 return NEW_LIT
(ID2SYM
(idNULL
), loc
);
12263 switch
(nd_type
(node
)) {
12265 nd_set_type
(node
, NODE_DSYM
);
12266 nd_set_loc
(node
, loc
);
12269 lit
= node
->nd_lit
;
12270 RB_OBJ_WRITTEN
(p
->ast
, Qnil
, node
->nd_lit
= ID2SYM
(rb_intern_str
(lit
)));
12271 nd_set_type
(node
, NODE_LIT
);
12272 nd_set_loc
(node
, loc
);
12275 node
= NEW_NODE
(NODE_DSYM
, Qnil
, 1, NEW_LIST
(node
, loc
), loc
);
12282 append_literal_keys
(st_data_t k
, st_data_t v
, st_data_t h
)
12284 NODE
*node
= (NODE
*)v
;
12285 NODE
**result
= (NODE
**)h
;
12287 node
->nd_next
->nd_end
= node
->nd_next
;
12288 node
->nd_next
->nd_next
= 0;
12290 list_concat
(*result
, node
);
12293 return ST_CONTINUE
;
12297 hash_literal_key_p
(VALUE k
)
12299 switch
(OBJ_BUILTIN_TYPE
(k
)) {
12308 literal_cmp
(VALUE val
, VALUE lit
)
12310 if
(val
== lit
) return
0;
12311 if
(!hash_literal_key_p
(val
) ||
!hash_literal_key_p
(lit
)) return
-1;
12312 return rb_iseq_cdhash_cmp
(val
, lit
);
12316 literal_hash
(VALUE a
)
12318 if
(!hash_literal_key_p
(a
)) return
(st_index_t
)a
;
12319 return rb_iseq_cdhash_hash
(a
);
12322 static const struct st_hash_type literal_type
= {
12328 remove_duplicate_keys
(struct parser_params
*p
, NODE
*hash
)
12330 st_table
*literal_keys
= st_init_table_with_size
(&literal_type
, hash
->nd_alen
/ 2);
12332 NODE
*last_expr
= 0;
12333 rb_code_location_t loc
= hash
->nd_loc
;
12334 while
(hash
&& hash
->nd_head
&& hash
->nd_next
) {
12335 NODE
*head
= hash
->nd_head
;
12336 NODE
*value
= hash
->nd_next
;
12337 NODE
*next
= value
->nd_next
;
12338 st_data_t key
= (st_data_t
)head
;
12340 value
->nd_next
= 0;
12341 if
(nd_type_p
(head
, NODE_LIT
) &&
12342 st_delete
(literal_keys
, (key
= (st_data_t
)head
->nd_lit
, &key
), &data
)) {
12343 NODE
*dup_value
= ((NODE
*)data
)->nd_next
;
12344 rb_compile_warn
(p
->ruby_sourcefile
, nd_line
((NODE
*)data
),
12345 "key %+"PRIsVALUE
" is duplicated and overwritten on line %d",
12346 head
->nd_lit
, nd_line
(head
));
12347 if
(dup_value
== last_expr
) {
12348 value
->nd_head
= block_append
(p
, dup_value
->nd_head
, value
->nd_head
);
12351 last_expr
->nd_head
= block_append
(p
, dup_value
->nd_head
, last_expr
->nd_head
);
12354 st_insert
(literal_keys
, (st_data_t
)key
, (st_data_t
)hash
);
12355 last_expr
= nd_type_p
(head
, NODE_LIT
) ? value
: head
;
12358 st_foreach
(literal_keys
, append_literal_keys
, (st_data_t
)&result
);
12359 st_free_table
(literal_keys
);
12361 if
(!result
) result
= hash
;
12362 else list_concat
(result
, hash
);
12364 result
->nd_loc
= loc
;
12369 new_hash
(struct parser_params
*p
, NODE
*hash
, const YYLTYPE *loc
)
12371 if
(hash
) hash
= remove_duplicate_keys
(p
, hash
);
12372 return NEW_HASH
(hash
, loc
);
12377 error_duplicate_pattern_variable
(struct parser_params
*p
, ID id
, const YYLTYPE *loc
)
12379 if
(is_private_local_id
(id
)) {
12382 if
(st_is_member
(p
->pvtbl
, id
)) {
12383 yyerror1
(loc
, "duplicated variable name");
12386 st_insert
(p
->pvtbl
, (st_data_t
)id
, 0);
12391 error_duplicate_pattern_key
(struct parser_params
*p
, VALUE key
, const YYLTYPE *loc
)
12394 p
->pktbl
= st_init_numtable
();
12396 else if
(st_is_member
(p
->pktbl
, key
)) {
12397 yyerror1
(loc
, "duplicated key name");
12400 st_insert
(p
->pktbl
, (st_data_t
)key
, 0);
12405 new_unique_key_hash
(struct parser_params
*p
, NODE
*hash
, const YYLTYPE *loc
)
12407 return NEW_HASH
(hash
, loc
);
12409 #endif /* !RIPPER */
12413 new_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID op
, NODE
*rhs
, struct lex_context ctxt
, const YYLTYPE *loc
)
12418 ID vid
= lhs
->nd_vid
;
12419 YYLTYPE lhs_loc
= lhs
->nd_loc
;
12420 int shareable
= ctxt.shareable_constant_value
;
12422 switch
(nd_type
(lhs
)) {
12433 rhs
= shareable_constant_value
(p
, shareable
, lhs
, rhs
, &rhs
->nd_loc
);
12434 lhs
->nd_value
= rhs
;
12435 nd_set_loc
(lhs
, loc
);
12436 asgn
= NEW_OP_ASGN_OR
(gettable
(p
, vid
, &lhs_loc
), lhs
, loc
);
12437 if
(is_notop_id
(vid
)) {
12438 switch
(id_type
(vid
)) {
12442 asgn
->nd_aid
= vid
;
12446 else if
(op
== tANDOP
) {
12448 rhs
= shareable_constant_value
(p
, shareable
, lhs
, rhs
, &rhs
->nd_loc
);
12450 lhs
->nd_value
= rhs
;
12451 nd_set_loc
(lhs
, loc
);
12452 asgn
= NEW_OP_ASGN_AND
(gettable
(p
, vid
, &lhs_loc
), lhs
, loc
);
12456 rhs
= NEW_CALL
(gettable
(p
, vid
, &lhs_loc
), op
, NEW_LIST
(rhs
, &rhs
->nd_loc
), loc
);
12458 rhs
= shareable_constant_value
(p
, shareable
, lhs
, rhs
, &rhs
->nd_loc
);
12460 asgn
->nd_value
= rhs
;
12461 nd_set_loc
(asgn
, loc
);
12465 asgn
= NEW_BEGIN
(0, loc
);
12471 new_ary_op_assign
(struct parser_params
*p
, NODE
*ary
,
12472 NODE
*args
, ID op
, NODE
*rhs
, const YYLTYPE *args_loc
, const YYLTYPE *loc
)
12476 args
= make_list
(args
, args_loc
);
12477 if
(nd_type_p
(args
, NODE_BLOCK_PASS
)) {
12478 args
= NEW_ARGSCAT
(args
, rhs
, loc
);
12481 args
= arg_concat
(p
, args
, rhs
, loc
);
12483 asgn
= NEW_OP_ASGN1
(ary
, op
, args
, loc
);
12489 new_attr_op_assign
(struct parser_params
*p
, NODE
*lhs
,
12490 ID atype
, ID attr
, ID op
, NODE
*rhs
, const YYLTYPE *loc
)
12494 asgn
= NEW_OP_ASGN2
(lhs
, CALL_Q_P
(atype
), attr
, op
, rhs
, loc
);
12500 new_const_op_assign
(struct parser_params
*p
, NODE
*lhs
, ID op
, NODE
*rhs
, struct lex_context ctxt
, const YYLTYPE *loc
)
12505 rhs
= shareable_constant_value
(p
, ctxt.shareable_constant_value
, lhs
, rhs
, loc
);
12506 asgn
= NEW_OP_CDECL
(lhs
, op
, rhs
, loc
);
12509 asgn
= NEW_BEGIN
(0, loc
);
12516 const_decl
(struct parser_params
*p
, NODE
*path
, const YYLTYPE *loc
)
12518 if
(p
->ctxt.in_def
) {
12519 yyerror1
(loc
, "dynamic constant assignment");
12521 return NEW_CDECL
(0, 0, (path
), loc
);
12525 const_decl
(struct parser_params
*p
, VALUE path
)
12527 if
(p
->ctxt.in_def
) {
12528 path
= assign_error
(p
, "dynamic constant assignment", path
);
12534 assign_error
(struct parser_params
*p
, const char *mesg
, VALUE a
)
12536 a
= dispatch2
(assign_error
, ERR_MESG
(), a
);
12542 var_field
(struct parser_params
*p
, VALUE a
)
12544 return ripper_new_yylval
(p
, get_id
(a
), dispatch1
(var_field
, a
), 0);
12550 new_bodystmt
(struct parser_params
*p
, NODE
*head
, NODE
*rescue
, NODE
*rescue_else
, NODE
*ensure
, const YYLTYPE *loc
)
12552 NODE
*result
= head
;
12554 NODE
*tmp
= rescue_else ? rescue_else
: rescue
;
12555 YYLTYPE rescue_loc
= code_loc_gen
(&head
->nd_loc
, &tmp
->nd_loc
);
12557 result
= NEW_RESCUE
(head
, rescue
, rescue_else
, &rescue_loc
);
12558 nd_set_line
(result
, rescue
->nd_loc.beg_pos.lineno
);
12560 else if
(rescue_else
) {
12561 result
= block_append
(p
, result
, rescue_else
);
12564 result
= NEW_ENSURE
(result
, ensure
, loc
);
12566 fixpos
(result
, head
);
12572 warn_unused_var
(struct parser_params
*p
, struct local_vars
*local
)
12576 if
(!local
->used
) return
;
12577 cnt
= local
->used
->pos
;
12578 if
(cnt
!= local
->vars
->pos
) {
12579 rb_parser_fatal
(p
, "local->used->pos != local->vars->pos");
12582 ID
*v
= local
->vars
->tbl
;
12583 ID
*u
= local
->used
->tbl
;
12584 for
(int i
= 0; i
< cnt
; ++i
) {
12585 if
(!v
[i
] ||
(u
[i
] & LVAR_USED
)) continue
;
12586 if
(is_private_local_id
(v
[i
])) continue
;
12587 rb_warn1L
((int)u
[i
], "assigned but unused variable - %"PRIsWARN
, rb_id2str
(v
[i
]));
12593 local_push
(struct parser_params
*p
, int toplevel_scope
)
12595 struct local_vars
*local
;
12596 int inherits_dvars
= toplevel_scope
&& compile_for_eval
;
12597 int warn_unused_vars
= RTEST
(ruby_verbose
);
12599 local
= ALLOC
(struct local_vars
);
12600 local
->prev
= p
->lvtbl
;
12601 local
->args
= vtable_alloc
(0);
12602 local
->vars
= vtable_alloc
(inherits_dvars ? DVARS_INHERIT
: DVARS_TOPSCOPE
);
12604 if
(toplevel_scope
&& compile_for_eval
) warn_unused_vars
= 0;
12605 if
(toplevel_scope
&& e_option_supplied
(p
)) warn_unused_vars
= 0;
12606 local
->numparam.outer
= 0;
12607 local
->numparam.inner
= 0;
12608 local
->numparam.current
= 0;
12610 local
->used
= warn_unused_vars ? vtable_alloc
(0) : 0;
12612 # if WARN_PAST_SCOPE
12621 local_pop
(struct parser_params
*p
)
12623 struct local_vars
*local
= p
->lvtbl
->prev
;
12624 if
(p
->lvtbl
->used
) {
12625 warn_unused_var
(p
, p
->lvtbl
);
12626 vtable_free
(p
->lvtbl
->used
);
12628 # if WARN_PAST_SCOPE
12629 while
(p
->lvtbl
->past
) {
12630 struct vtable
*past
= p
->lvtbl
->past
;
12631 p
->lvtbl
->past
= past
->prev
;
12635 vtable_free
(p
->lvtbl
->args
);
12636 vtable_free
(p
->lvtbl
->vars
);
12639 ruby_sized_xfree
(p
->lvtbl
, sizeof
(*p
->lvtbl
));
12644 static rb_ast_id_table_t
*
12645 local_tbl
(struct parser_params
*p
)
12647 int cnt_args
= vtable_size
(p
->lvtbl
->args
);
12648 int cnt_vars
= vtable_size
(p
->lvtbl
->vars
);
12649 int cnt
= cnt_args
+ cnt_vars
;
12651 rb_ast_id_table_t
*tbl
;
12653 if
(cnt
<= 0) return
0;
12654 tbl
= rb_ast_new_local_table
(p
->ast
, cnt
);
12655 MEMCPY
(tbl
->ids
, p
->lvtbl
->args
->tbl
, ID
, cnt_args
);
12656 /* remove IDs duplicated to warn shadowing */
12657 for
(i
= 0, j
= cnt_args
; i
< cnt_vars
; ++i
) {
12658 ID id
= p
->lvtbl
->vars
->tbl
[i
];
12659 if
(!vtable_included
(p
->lvtbl
->args
, id
)) {
12660 tbl
->ids
[j
++] = id
;
12664 tbl
= rb_ast_resize_latest_local_table
(p
->ast
, j
);
12671 node_newnode_with_locals
(struct parser_params
*p
, enum node_type type
, VALUE a1
, VALUE a2
, const rb_code_location_t
*loc
)
12673 rb_ast_id_table_t
*a0
;
12677 n
= NEW_NODE
(type
, a0
, a1
, a2
, loc
);
12684 numparam_name
(struct parser_params
*p
, ID id
)
12686 if
(!NUMPARAM_ID_P
(id
)) return
;
12687 compile_error
(p
, "_%d is reserved for numbered parameter",
12688 NUMPARAM_ID_TO_IDX
(id
));
12692 arg_var
(struct parser_params
*p
, ID id
)
12694 numparam_name
(p
, id
);
12695 vtable_add
(p
->lvtbl
->args
, id
);
12699 local_var
(struct parser_params
*p
, ID id
)
12701 numparam_name
(p
, id
);
12702 vtable_add
(p
->lvtbl
->vars
, id
);
12703 if
(p
->lvtbl
->used
) {
12704 vtable_add
(p
->lvtbl
->used
, (ID
)p
->ruby_sourceline
);
12709 local_id_ref
(struct parser_params
*p
, ID id
, ID
**vidrefp
)
12711 struct vtable
*vars
, *args
, *used
;
12713 vars
= p
->lvtbl
->vars
;
12714 args
= p
->lvtbl
->args
;
12715 used
= p
->lvtbl
->used
;
12717 while
(vars
&& !DVARS_TERMINAL_P
(vars
->prev
)) {
12720 if
(used
) used
= used
->prev
;
12723 if
(vars
&& vars
->prev
== DVARS_INHERIT
) {
12724 return rb_local_defined
(id
, p
->parent_iseq
);
12726 else if
(vtable_included
(args
, id
)) {
12730 int i
= vtable_included
(vars
, id
);
12731 if
(i
&& used
&& vidrefp
) *vidrefp
= &used
->tbl
[i
-1];
12737 local_id
(struct parser_params
*p
, ID id
)
12739 return local_id_ref
(p
, id
, NULL
);
12743 check_forwarding_args
(struct parser_params
*p
)
12745 if
(local_id
(p
, idFWD_REST
) &&
12747 local_id
(p
, idFWD_KWREST
) &&
12749 local_id
(p
, idFWD_BLOCK
)) return TRUE
;
12750 compile_error
(p
, "unexpected ...");
12755 add_forwarding_args
(struct parser_params
*p
)
12757 arg_var
(p
, idFWD_REST
);
12759 arg_var
(p
, idFWD_KWREST
);
12761 arg_var
(p
, idFWD_BLOCK
);
12766 new_args_forward_call
(struct parser_params
*p
, NODE
*leading
, const YYLTYPE *loc
, const YYLTYPE *argsloc
)
12768 NODE
*splat
= NEW_SPLAT
(NEW_LVAR
(idFWD_REST
, loc
), loc
);
12770 NODE
*kwrest
= list_append
(p
, NEW_LIST
(0, loc
), NEW_LVAR
(idFWD_KWREST
, loc
));
12772 NODE
*block
= NEW_BLOCK_PASS
(NEW_LVAR
(idFWD_BLOCK
, loc
), loc
);
12773 NODE
*args
= leading ? rest_arg_append
(p
, leading
, splat
, argsloc
) : splat
;
12775 args
= arg_append
(p
, splat
, new_hash
(p
, kwrest
, loc
), loc
);
12777 return arg_blk_pass
(args
, block
);
12782 numparam_push
(struct parser_params
*p
)
12785 struct local_vars
*local
= p
->lvtbl
;
12786 NODE
*inner
= local
->numparam.inner
;
12787 if
(!local
->numparam.outer
) {
12788 local
->numparam.outer
= local
->numparam.current
;
12790 local
->numparam.inner
= 0;
12791 local
->numparam.current
= 0;
12799 numparam_pop
(struct parser_params
*p
, NODE
*prev_inner
)
12802 struct local_vars
*local
= p
->lvtbl
;
12804 /* prefer first one */
12805 local
->numparam.inner
= prev_inner
;
12807 else if
(local
->numparam.current
) {
12808 /* current and inner are exclusive */
12809 local
->numparam.inner
= local
->numparam.current
;
12811 if
(p
->max_numparam
> NO_PARAM
) {
12812 /* current and outer are exclusive */
12813 local
->numparam.current
= local
->numparam.outer
;
12814 local
->numparam.outer
= 0;
12817 /* no numbered parameter */
12818 local
->numparam.current
= 0;
12823 static const struct vtable
*
12824 dyna_push
(struct parser_params
*p
)
12826 p
->lvtbl
->args
= vtable_alloc
(p
->lvtbl
->args
);
12827 p
->lvtbl
->vars
= vtable_alloc
(p
->lvtbl
->vars
);
12828 if
(p
->lvtbl
->used
) {
12829 p
->lvtbl
->used
= vtable_alloc
(p
->lvtbl
->used
);
12831 return p
->lvtbl
->args
;
12835 dyna_pop_vtable
(struct parser_params
*p
, struct vtable
**vtblp
)
12837 struct vtable
*tmp
= *vtblp
;
12838 *vtblp
= tmp
->prev
;
12839 # if WARN_PAST_SCOPE
12840 if
(p
->past_scope_enabled
) {
12841 tmp
->prev
= p
->lvtbl
->past
;
12842 p
->lvtbl
->past
= tmp
;
12850 dyna_pop_1
(struct parser_params
*p
)
12852 struct vtable
*tmp
;
12854 if
((tmp
= p
->lvtbl
->used
) != 0) {
12855 warn_unused_var
(p
, p
->lvtbl
);
12856 p
->lvtbl
->used
= p
->lvtbl
->used
->prev
;
12859 dyna_pop_vtable
(p
, &p
->lvtbl
->args
);
12860 dyna_pop_vtable
(p
, &p
->lvtbl
->vars
);
12864 dyna_pop
(struct parser_params
*p
, const struct vtable
*lvargs
)
12866 while
(p
->lvtbl
->args
!= lvargs
) {
12868 if
(!p
->lvtbl
->args
) {
12869 struct local_vars
*local
= p
->lvtbl
->prev
;
12870 ruby_sized_xfree
(p
->lvtbl
, sizeof
(*p
->lvtbl
));
12878 dyna_in_block
(struct parser_params
*p
)
12880 return
!DVARS_TERMINAL_P
(p
->lvtbl
->vars
) && p
->lvtbl
->vars
->prev
!= DVARS_TOPSCOPE
;
12884 dvar_defined_ref
(struct parser_params
*p
, ID id
, ID
**vidrefp
)
12886 struct vtable
*vars
, *args
, *used
;
12889 args
= p
->lvtbl
->args
;
12890 vars
= p
->lvtbl
->vars
;
12891 used
= p
->lvtbl
->used
;
12893 while
(!DVARS_TERMINAL_P
(vars
)) {
12894 if
(vtable_included
(args
, id
)) {
12897 if
((i
= vtable_included
(vars
, id
)) != 0) {
12898 if
(used
&& vidrefp
) *vidrefp
= &used
->tbl
[i
-1];
12903 if
(!vidrefp
) used
= 0;
12904 if
(used
) used
= used
->prev
;
12907 if
(vars
== DVARS_INHERIT
&& !NUMPARAM_ID_P
(id
)) {
12908 return rb_dvar_defined
(id
, p
->parent_iseq
);
12915 dvar_defined
(struct parser_params
*p
, ID id
)
12917 return dvar_defined_ref
(p
, id
, NULL
);
12921 dvar_curr
(struct parser_params
*p
, ID id
)
12923 return
(vtable_included
(p
->lvtbl
->args
, id
) ||
12924 vtable_included
(p
->lvtbl
->vars
, id
));
12928 reg_fragment_enc_error
(struct parser_params
* p
, VALUE str
, int c
)
12931 "regexp encoding option '%c' differs from source encoding '%s'",
12932 c
, rb_enc_name
(rb_enc_get
(str
)));
12937 rb_reg_fragment_setenc
(struct parser_params
* p
, VALUE str
, int options
)
12939 int c
= RE_OPTION_ENCODING_IDX
(options
);
12943 rb_char_to_option_kcode
(c
, &opt
, &idx
);
12944 if
(idx
!= ENCODING_GET
(str
) &&
12945 rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
12948 ENCODING_SET
(str
, idx
);
12950 else if
(RE_OPTION_ENCODING_NONE
(options
)) {
12951 if
(!ENCODING_IS_ASCII8BIT
(str
) &&
12952 rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
12956 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
12958 else if
(p
->enc
== rb_usascii_encoding
()) {
12959 if
(rb_enc_str_coderange
(str
) != ENC_CODERANGE_7BIT
) {
12960 /* raise in re.c */
12961 rb_enc_associate
(str
, rb_usascii_encoding
());
12964 rb_enc_associate
(str
, rb_ascii8bit_encoding
());
12974 reg_fragment_setenc
(struct parser_params
* p
, VALUE str
, int options
)
12976 int c
= rb_reg_fragment_setenc
(p
, str
, options
);
12977 if
(c
) reg_fragment_enc_error
(p
, str
, c
);
12981 reg_fragment_check
(struct parser_params
* p
, VALUE str
, int options
)
12984 reg_fragment_setenc
(p
, str
, options
);
12985 err
= rb_reg_check_preprocess
(str
);
12987 err
= rb_obj_as_string
(err
);
12988 compile_error
(p
, "%"PRIsVALUE
, err
);
12995 struct parser_params
* parser
;
12998 const YYLTYPE *loc
;
12999 } reg_named_capture_assign_t
;
13002 reg_named_capture_assign_iter
(const OnigUChar
*name
, const OnigUChar
*name_end
,
13003 int back_num
, int *back_refs
, OnigRegex regex
, void *arg0
)
13005 reg_named_capture_assign_t
*arg
= (reg_named_capture_assign_t
*)arg0
;
13006 struct parser_params
* p
= arg
->parser
;
13007 rb_encoding
*enc
= arg
->enc
;
13008 long len
= name_end
- name
;
13009 const char *s
= (const char *)name
;
13013 if
(!len
) return ST_CONTINUE
;
13014 if
(rb_enc_symname_type
(s
, len
, enc
, (1U<<ID_LOCAL
)) != ID_LOCAL
)
13015 return ST_CONTINUE
;
13017 var
= intern_cstr
(s
, len
, enc
);
13018 if
(len
< MAX_WORD_LENGTH
&& rb_reserved_word
(s
, (int)len
)) {
13019 if
(!lvar_defined
(p
, var
)) return ST_CONTINUE
;
13021 node
= node_assign
(p
, assignable
(p
, var
, 0, arg
->loc
), NEW_LIT
(ID2SYM
(var
), arg
->loc
), NO_LEX_CTXT
, arg
->loc
);
13022 succ
= arg
->succ_block
;
13023 if
(!succ
) succ
= NEW_BEGIN
(0, arg
->loc
);
13024 succ
= block_append
(p
, succ
, node
);
13025 arg
->succ_block
= succ
;
13026 return ST_CONTINUE
;
13030 reg_named_capture_assign
(struct parser_params
* p
, VALUE regexp
, const YYLTYPE *loc
)
13032 reg_named_capture_assign_t arg
;
13035 arg.enc
= rb_enc_get
(regexp
);
13036 arg.succ_block
= 0;
13038 onig_foreach_name
(RREGEXP_PTR
(regexp
), reg_named_capture_assign_iter
, &arg
);
13040 if
(!arg.succ_block
) return
0;
13041 return arg.succ_block
->nd_next
;
13045 parser_reg_compile
(struct parser_params
* p
, VALUE str
, int options
)
13047 reg_fragment_setenc
(p
, str
, options
);
13048 return rb_parser_reg_compile
(p
, str
, options
);
13052 rb_parser_reg_compile
(struct parser_params
* p
, VALUE str
, int options
)
13054 return rb_reg_compile
(str
, options
& RE_OPTION_MASK
, p
->ruby_sourcefile
, p
->ruby_sourceline
);
13058 reg_compile
(struct parser_params
* p
, VALUE str
, int options
)
13063 err
= rb_errinfo
();
13064 re
= parser_reg_compile
(p
, str
, options
);
13066 VALUE m
= rb_attr_get
(rb_errinfo
(), idMesg
);
13067 rb_set_errinfo
(err
);
13068 compile_error
(p
, "%"PRIsVALUE
, m
);
13075 parser_reg_compile
(struct parser_params
* p
, VALUE str
, int options
, VALUE
*errmsg
)
13077 VALUE err
= rb_errinfo
();
13079 str
= ripper_is_node_yylval
(str
) ? RNODE
(str
)->nd_cval
: str
;
13080 int c
= rb_reg_fragment_setenc
(p
, str
, options
);
13081 if
(c
) reg_fragment_enc_error
(p
, str
, c
);
13082 re
= rb_parser_reg_compile
(p
, str
, options
);
13084 *errmsg
= rb_attr_get
(rb_errinfo
(), idMesg
);
13085 rb_set_errinfo
(err
);
13093 rb_parser_set_options
(VALUE vparser
, int print
, int loop
, int chomp
, int split
)
13095 struct parser_params
*p
;
13096 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13097 p
->do_print
= print
;
13099 p
->do_chomp
= chomp
;
13100 p
->do_split
= split
;
13104 parser_append_options
(struct parser_params
*p
, NODE
*node
)
13106 static const YYLTYPE default_location
= {{1, 0}, {1, 0}};
13107 const YYLTYPE *const LOC
= &default_location
;
13110 NODE
*print
= NEW_FCALL
(rb_intern
("print"),
13111 NEW_LIST
(NEW_GVAR
(idLASTLINE
, LOC
), LOC
),
13113 node
= block_append
(p
, node
, print
);
13118 ID ifs
= rb_intern
("$;");
13119 ID fields
= rb_intern
("$F");
13120 NODE
*args
= NEW_LIST
(NEW_GVAR
(ifs
, LOC
), LOC
);
13121 NODE
*split
= NEW_GASGN
(fields
,
13122 NEW_CALL
(NEW_GVAR
(idLASTLINE
, LOC
),
13123 rb_intern
("split"), args
, LOC
),
13125 node
= block_append
(p
, split
, node
);
13128 NODE
*chomp
= NEW_CALL
(NEW_GVAR
(idLASTLINE
, LOC
),
13129 rb_intern
("chomp!"), 0, LOC
);
13130 node
= block_append
(p
, chomp
, node
);
13133 node
= NEW_WHILE
(NEW_VCALL
(idGets
, LOC
), node
, 1, LOC
);
13140 rb_init_parse
(void)
13142 /* just to suppress unused-function warnings */
13148 internal_id
(struct parser_params
*p
)
13150 return rb_make_temporary_id
(vtable_size
(p
->lvtbl
->args
) + vtable_size
(p
->lvtbl
->vars
));
13152 #endif /* !RIPPER */
13155 parser_initialize
(struct parser_params
*p
)
13157 /* note: we rely on TypedData_Make_Struct to set most fields to 0 */
13158 p
->command_start
= TRUE
;
13159 p
->ruby_sourcefile_string
= Qnil
;
13160 p
->lex.lpar_beg
= -1; /* make lambda_beginning_p() == FALSE at first */
13163 p
->delayed.token
= Qnil
;
13165 p
->parsing_thread
= Qnil
;
13167 p
->error_buffer
= Qfalse
;
13169 p
->debug_buffer
= Qnil
;
13170 p
->debug_output
= rb_ractor_stdout
();
13171 p
->enc
= rb_utf8_encoding
();
13175 #define parser_mark ripper_parser_mark
13176 #define parser_free ripper_parser_free
13180 parser_mark
(void *ptr
)
13182 struct parser_params
*p
= (struct parser_params
*)ptr
;
13184 rb_gc_mark
(p
->lex.input
);
13185 rb_gc_mark
(p
->lex.prevline
);
13186 rb_gc_mark
(p
->lex.lastline
);
13187 rb_gc_mark
(p
->lex.nextline
);
13188 rb_gc_mark
(p
->ruby_sourcefile_string
);
13189 rb_gc_mark
((VALUE
)p
->lex.strterm
);
13190 rb_gc_mark
((VALUE
)p
->ast
);
13191 rb_gc_mark
(p
->case_labels
);
13193 rb_gc_mark
(p
->debug_lines
);
13194 rb_gc_mark
(p
->compile_option
);
13195 rb_gc_mark
(p
->error_buffer
);
13197 rb_gc_mark
(p
->delayed.token
);
13198 rb_gc_mark
(p
->value
);
13199 rb_gc_mark
(p
->result
);
13200 rb_gc_mark
(p
->parsing_thread
);
13202 rb_gc_mark
(p
->debug_buffer
);
13203 rb_gc_mark
(p
->debug_output
);
13205 rb_gc_mark
((VALUE
)p
->heap
);
13210 parser_free
(void *ptr
)
13212 struct parser_params
*p
= (struct parser_params
*)ptr
;
13213 struct local_vars
*local
, *prev
;
13216 ruby_sized_xfree
(p
->tokenbuf
, p
->toksiz
);
13218 for
(local
= p
->lvtbl
; local
; local
= prev
) {
13219 if
(local
->vars
) xfree
(local
->vars
);
13220 prev
= local
->prev
;
13224 token_info
*ptinfo
;
13225 while
((ptinfo
= p
->token_info
) != 0) {
13226 p
->token_info
= ptinfo
->next
;
13234 parser_memsize
(const void *ptr
)
13236 struct parser_params
*p
= (struct parser_params
*)ptr
;
13237 struct local_vars
*local
;
13238 size_t size
= sizeof
(*p
);
13241 for
(local
= p
->lvtbl
; local
; local
= local
->prev
) {
13242 size
+= sizeof
(*local
);
13243 if
(local
->vars
) size
+= local
->vars
->capa
* sizeof
(ID
);
13248 static const rb_data_type_t parser_data_type
= {
13259 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
13263 #undef rb_reserved_word
13265 const struct kwtable
*
13266 rb_reserved_word
(const char *str
, unsigned int len
)
13268 return reserved_word
(str
, len
);
13272 rb_parser_new
(void)
13274 struct parser_params
*p
;
13275 VALUE parser
= TypedData_Make_Struct
(0, struct parser_params
,
13276 &parser_data_type
, p
);
13277 parser_initialize
(p
);
13282 rb_parser_set_context
(VALUE vparser
, const struct rb_iseq_struct
*base
, int main
)
13284 struct parser_params
*p
;
13286 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13287 p
->error_buffer
= main ? Qfalse
: Qnil
;
13288 p
->parent_iseq
= base
;
13293 rb_parser_keep_script_lines
(VALUE vparser
)
13295 struct parser_params
*p
;
13297 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13298 p
->keep_script_lines
= 1;
13303 #define rb_parser_end_seen_p ripper_parser_end_seen_p
13304 #define rb_parser_encoding ripper_parser_encoding
13305 #define rb_parser_get_yydebug ripper_parser_get_yydebug
13306 #define rb_parser_set_yydebug ripper_parser_set_yydebug
13307 #define rb_parser_get_debug_output ripper_parser_get_debug_output
13308 #define rb_parser_set_debug_output ripper_parser_set_debug_output
13309 static VALUE ripper_parser_end_seen_p
(VALUE vparser
);
13310 static VALUE ripper_parser_encoding
(VALUE vparser
);
13311 static VALUE ripper_parser_get_yydebug
(VALUE self
);
13312 static VALUE ripper_parser_set_yydebug
(VALUE self
, VALUE flag
);
13313 static VALUE ripper_parser_get_debug_output
(VALUE self
);
13314 static VALUE ripper_parser_set_debug_output
(VALUE self
, VALUE output
);
13318 * ripper.error? -> Boolean
13320 * Return true if parsed source has errors.
13323 ripper_error_p
(VALUE vparser
)
13325 struct parser_params
*p
;
13327 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13328 return RBOOL
(p
->error_p
);
13334 * ripper.end_seen? -> Boolean
13336 * Return true if parsed source ended by +\_\_END\_\_+.
13339 rb_parser_end_seen_p
(VALUE vparser
)
13341 struct parser_params
*p
;
13343 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13344 return RBOOL
(p
->ruby__end__seen
);
13349 * ripper.encoding -> encoding
13351 * Return encoding of the source.
13354 rb_parser_encoding
(VALUE vparser
)
13356 struct parser_params
*p
;
13358 TypedData_Get_Struct
(vparser
, struct parser_params
, &parser_data_type
, p
);
13359 return rb_enc_from_encoding
(p
->enc
);
13365 * ripper.yydebug -> true or false
13370 rb_parser_get_yydebug
(VALUE self
)
13372 struct parser_params
*p
;
13374 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13375 return RBOOL
(p
->debug
);
13381 * ripper.yydebug = flag
13386 rb_parser_set_yydebug
(VALUE self
, VALUE flag
)
13388 struct parser_params
*p
;
13390 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13391 p
->debug
= RTEST
(flag
);
13397 * ripper.debug_output -> obj
13399 * Get debug output.
13402 rb_parser_get_debug_output
(VALUE self
)
13404 struct parser_params
*p
;
13406 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13407 return p
->debug_output
;
13412 * ripper.debug_output = obj
13414 * Set debug output.
13417 rb_parser_set_debug_output
(VALUE self
, VALUE output
)
13419 struct parser_params
*p
;
13421 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13422 return p
->debug_output
= output
;
13427 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
13428 /* Keep the order; NEWHEAP then xmalloc and ADD2HEAP to get rid of
13429 * potential memory leak */
13430 #define NEWHEAP() rb_imemo_tmpbuf_parser_heap(0, p->heap, 0)
13431 #define ADD2HEAP(new, cnt, ptr) ((p->heap = (new))->ptr = (ptr), \
13432 (new
)->cnt
= (cnt
), (ptr
))
13435 rb_parser_malloc
(struct parser_params
*p
, size_t size
)
13437 size_t cnt
= HEAPCNT
(1, size
);
13438 rb_imemo_tmpbuf_t
*n
= NEWHEAP
();
13439 void *ptr
= xmalloc
(size
);
13441 return ADD2HEAP
(n
, cnt
, ptr
);
13445 rb_parser_calloc
(struct parser_params
*p
, size_t nelem
, size_t size
)
13447 size_t cnt
= HEAPCNT
(nelem
, size
);
13448 rb_imemo_tmpbuf_t
*n
= NEWHEAP
();
13449 void *ptr
= xcalloc
(nelem
, size
);
13451 return ADD2HEAP
(n
, cnt
, ptr
);
13455 rb_parser_realloc
(struct parser_params
*p
, void *ptr
, size_t size
)
13457 rb_imemo_tmpbuf_t
*n
;
13458 size_t cnt
= HEAPCNT
(1, size
);
13460 if
(ptr
&& (n
= p
->heap
) != NULL
) {
13462 if
(n
->ptr
== ptr
) {
13463 n
->ptr
= ptr
= xrealloc
(ptr
, size
);
13464 if
(n
->cnt
) n
->cnt
= cnt
;
13467 } while
((n
= n
->next
) != NULL
);
13470 ptr
= xrealloc
(ptr
, size
);
13471 return ADD2HEAP
(n
, cnt
, ptr
);
13475 rb_parser_free
(struct parser_params
*p
, void *ptr
)
13477 rb_imemo_tmpbuf_t
**prev
= &p
->heap
, *n
;
13479 while
((n
= *prev
) != NULL
) {
13480 if
(n
->ptr
== ptr
) {
13490 rb_parser_printf
(struct parser_params
*p
, const char *fmt
, ...
)
13493 VALUE mesg
= p
->debug_buffer
;
13495 if
(NIL_P
(mesg
)) p
->debug_buffer
= mesg
= rb_str_new
(0, 0);
13497 rb_str_vcatf
(mesg
, fmt
, ap
);
13499 if
(RSTRING_END
(mesg
)[-1] == '\n') {
13500 rb_io_write
(p
->debug_output
, mesg
);
13501 p
->debug_buffer
= Qnil
;
13506 parser_compile_error
(struct parser_params
*p
, const char *fmt
, ...
)
13510 rb_io_flush
(p
->debug_output
);
13514 rb_syntax_error_append
(p
->error_buffer
,
13515 p
->ruby_sourcefile_string
,
13516 p
->ruby_sourceline
,
13517 rb_long2int
(p
->lex.pcur
- p
->lex.pbeg
),
13523 count_char
(const char *str
, int c
)
13526 while
(str
[n
] == c
) ++n
;
13531 * strip enclosing double-quotes, same as the default yytnamerr except
13532 * for that single-quotes matching back-quotes do not stop stripping.
13534 * "\"`class' keyword\"" => "`class' keyword"
13536 RUBY_FUNC_EXPORTED
size_t
13537 rb_yytnamerr
(struct parser_params
*p
, char *yyres
, const char *yystr
)
13539 if
(*yystr
== '"') {
13540 size_t yyn
= 0, bquote
= 0;
13541 const char *yyp
= yystr
;
13547 bquote
= count_char
(yyp
+1, '`') + 1;
13548 if
(yyres
) memcpy
(&yyres
[yyn
], yyp
, bquote
);
13556 if
(bquote
&& count_char
(yyp
+1, '\'') + 1 == bquote
) {
13557 if
(yyres
) memcpy
(yyres
+ yyn
, yyp
, bquote
);
13563 if
(yyp
[1] && yyp
[1] != '\'' && yyp
[2] == '\'') {
13564 if
(yyres
) memcpy
(yyres
+ yyn
, yyp
, 3);
13569 goto do_not_strip_quotes
;
13572 goto do_not_strip_quotes
;
13575 if
(*++yyp
!= '\\')
13576 goto do_not_strip_quotes
;
13577 /* Fall through. */
13592 do_not_strip_quotes
: ;
13595 if
(!yyres
) return strlen
(yystr
);
13597 return
(YYSIZE_T
)(yystpcpy
(yyres
, yystr
) - yyres
);
13602 #ifdef RIPPER_DEBUG
13605 ripper_validate_object
(VALUE self
, VALUE x
)
13607 if
(x
== Qfalse
) return x
;
13608 if
(x
== Qtrue
) return x
;
13609 if
(x
== Qnil
) return x
;
13611 rb_raise
(rb_eArgError
, "Qundef given");
13612 if
(FIXNUM_P
(x
)) return x
;
13613 if
(SYMBOL_P
(x
)) return x
;
13614 switch
(BUILTIN_TYPE
(x
)) {
13624 if
(!nd_type_p
((NODE
*)x
, NODE_RIPPER
)) {
13625 rb_raise
(rb_eArgError
, "NODE given: %p", (void *)x
);
13627 x
= ((NODE
*)x
)->nd_rval
;
13630 rb_raise
(rb_eArgError
, "wrong type of ruby object: %p (%s)",
13631 (void *)x
, rb_obj_classname
(x
));
13633 if
(!RBASIC_CLASS
(x
)) {
13634 rb_raise
(rb_eArgError
, "hidden ruby object: %p (%s)",
13635 (void *)x
, rb_builtin_type_name
(TYPE
(x
)));
13641 #define validate(x) ((x) = get_value(x))
13644 ripper_dispatch0
(struct parser_params
*p
, ID mid
)
13646 return rb_funcall
(p
->value
, mid
, 0);
13650 ripper_dispatch1
(struct parser_params
*p
, ID mid
, VALUE a
)
13653 return rb_funcall
(p
->value
, mid
, 1, a
);
13657 ripper_dispatch2
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
)
13661 return rb_funcall
(p
->value
, mid
, 2, a
, b
);
13665 ripper_dispatch3
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
, VALUE c
)
13670 return rb_funcall
(p
->value
, mid
, 3, a
, b
, c
);
13674 ripper_dispatch4
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
)
13680 return rb_funcall
(p
->value
, mid
, 4, a
, b
, c
, d
);
13684 ripper_dispatch5
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
, VALUE e
)
13691 return rb_funcall
(p
->value
, mid
, 5, a
, b
, c
, d
, e
);
13695 ripper_dispatch7
(struct parser_params
*p
, ID mid
, VALUE a
, VALUE b
, VALUE c
, VALUE d
, VALUE e
, VALUE f
, VALUE g
)
13704 return rb_funcall
(p
->value
, mid
, 7, a
, b
, c
, d
, e
, f
, g
);
13708 ripper_get_id
(VALUE v
)
13711 if
(!RB_TYPE_P
(v
, T_NODE
)) return
0;
13713 if
(!nd_type_p
(nd
, NODE_RIPPER
)) return
0;
13718 ripper_get_value
(VALUE v
)
13721 if
(v
== Qundef
) return Qnil
;
13722 if
(!RB_TYPE_P
(v
, T_NODE
)) return v
;
13724 if
(!nd_type_p
(nd
, NODE_RIPPER
)) return Qnil
;
13725 return nd
->nd_rval
;
13729 ripper_error
(struct parser_params
*p
)
13735 ripper_compile_error
(struct parser_params
*p
, const char *fmt
, ...
)
13740 va_start
(args
, fmt
);
13741 str
= rb_vsprintf
(fmt
, args
);
13743 rb_funcall
(p
->value
, rb_intern
("compile_error"), 1, str
);
13748 ripper_lex_get_generic
(struct parser_params
*p
, VALUE src
)
13750 VALUE line
= rb_funcallv_public
(src
, id_gets
, 0, 0);
13751 if
(!NIL_P
(line
) && !RB_TYPE_P
(line
, T_STRING
)) {
13752 rb_raise
(rb_eTypeError
,
13753 "gets returned %"PRIsVALUE
" (expected String or nil)",
13754 rb_obj_class
(line
));
13760 ripper_lex_io_get
(struct parser_params
*p
, VALUE src
)
13762 return rb_io_gets
(src
);
13766 ripper_s_allocate
(VALUE klass
)
13768 struct parser_params
*p
;
13769 VALUE self
= TypedData_Make_Struct
(klass
, struct parser_params
,
13770 &parser_data_type
, p
);
13775 #define ripper_initialized_p(r) ((r)->lex.input != 0)
13779 * Ripper.new(src, filename="(ripper)", lineno=1) -> ripper
13781 * Create a new Ripper object.
13782 * _src_ must be a String, an IO, or an Object which has #gets method.
13784 * This method does not starts parsing.
13785 * See also Ripper#parse and Ripper.parse.
13788 ripper_initialize
(int argc
, VALUE
*argv
, VALUE self
)
13790 struct parser_params
*p
;
13791 VALUE src
, fname
, lineno
;
13793 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13794 rb_scan_args
(argc
, argv
, "12", &src
, &fname
, &lineno
);
13795 if
(RB_TYPE_P
(src
, T_FILE
)) {
13796 p
->lex.gets
= ripper_lex_io_get
;
13798 else if
(rb_respond_to
(src
, id_gets
)) {
13799 p
->lex.gets
= ripper_lex_get_generic
;
13803 p
->lex.gets
= lex_get_str
;
13805 p
->lex.input
= src
;
13807 if
(NIL_P
(fname
)) {
13808 fname
= STR_NEW2
("(ripper)");
13812 StringValueCStr
(fname
);
13813 fname
= rb_str_new_frozen
(fname
);
13815 parser_initialize
(p
);
13817 p
->ruby_sourcefile_string
= fname
;
13818 p
->ruby_sourcefile
= RSTRING_PTR
(fname
);
13819 p
->ruby_sourceline
= NIL_P
(lineno
) ?
0 : NUM2INT
(lineno
) - 1;
13825 ripper_parse0
(VALUE parser_v
)
13827 struct parser_params
*p
;
13829 TypedData_Get_Struct
(parser_v
, struct parser_params
, &parser_data_type
, p
);
13831 p
->ast
= rb_ast_new
();
13832 ripper_yyparse
((void*)p
);
13833 rb_ast_dispose
(p
->ast
);
13839 ripper_ensure
(VALUE parser_v
)
13841 struct parser_params
*p
;
13843 TypedData_Get_Struct
(parser_v
, struct parser_params
, &parser_data_type
, p
);
13844 p
->parsing_thread
= Qnil
;
13852 * Start parsing and returns the value of the root action.
13855 ripper_parse
(VALUE self
)
13857 struct parser_params
*p
;
13859 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13860 if
(!ripper_initialized_p
(p
)) {
13861 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13863 if
(!NIL_P
(p
->parsing_thread
)) {
13864 if
(p
->parsing_thread
== rb_thread_current
())
13865 rb_raise
(rb_eArgError
, "Ripper#parse is not reentrant");
13867 rb_raise
(rb_eArgError
, "Ripper#parse is not multithread-safe");
13869 p
->parsing_thread
= rb_thread_current
();
13870 rb_ensure
(ripper_parse0
, self
, ripper_ensure
, self
);
13877 * ripper.column -> Integer
13879 * Return column number of current parsing line.
13880 * This number starts from 0.
13883 ripper_column
(VALUE self
)
13885 struct parser_params
*p
;
13888 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13889 if
(!ripper_initialized_p
(p
)) {
13890 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13892 if
(NIL_P
(p
->parsing_thread
)) return Qnil
;
13893 col
= p
->lex.ptok
- p
->lex.pbeg
;
13894 return LONG2NUM
(col
);
13899 * ripper.filename -> String
13901 * Return current parsing filename.
13904 ripper_filename
(VALUE self
)
13906 struct parser_params
*p
;
13908 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13909 if
(!ripper_initialized_p
(p
)) {
13910 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13912 return p
->ruby_sourcefile_string
;
13917 * ripper.lineno -> Integer
13919 * Return line number of current parsing line.
13920 * This number starts from 1.
13923 ripper_lineno
(VALUE self
)
13925 struct parser_params
*p
;
13927 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13928 if
(!ripper_initialized_p
(p
)) {
13929 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13931 if
(NIL_P
(p
->parsing_thread
)) return Qnil
;
13932 return INT2NUM
(p
->ruby_sourceline
);
13937 * ripper.state -> Integer
13939 * Return scanner state of current token.
13942 ripper_state
(VALUE self
)
13944 struct parser_params
*p
;
13946 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13947 if
(!ripper_initialized_p
(p
)) {
13948 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13950 if
(NIL_P
(p
->parsing_thread
)) return Qnil
;
13951 return INT2NUM
(p
->lex.state
);
13956 * ripper.token -> String
13958 * Return the current token string.
13961 ripper_token
(VALUE self
)
13963 struct parser_params
*p
;
13966 TypedData_Get_Struct
(self
, struct parser_params
, &parser_data_type
, p
);
13967 if
(!ripper_initialized_p
(p
)) {
13968 rb_raise
(rb_eArgError
, "method called for uninitialized object");
13970 if
(NIL_P
(p
->parsing_thread
)) return Qnil
;
13971 pos
= p
->lex.ptok
- p
->lex.pbeg
;
13972 len
= p
->lex.pcur
- p
->lex.ptok
;
13973 return rb_str_subseq
(p
->lex.lastline
, pos
, len
);
13976 #ifdef RIPPER_DEBUG
13979 ripper_assert_Qundef
(VALUE self
, VALUE obj
, VALUE msg
)
13982 if
(obj
== Qundef
) {
13983 rb_raise
(rb_eArgError
, "%"PRIsVALUE
, msg
);
13990 ripper_value
(VALUE self
, VALUE obj
)
13992 return ULONG2NUM
(obj
);
13998 * Ripper.lex_state_name(integer) -> string
14000 * Returns a string representation of lex_state.
14003 ripper_lex_state_name
(VALUE self
, VALUE state
)
14005 return rb_parser_lex_state_name
(NUM2INT
(state
));
14011 ripper_init_eventids1
();
14012 ripper_init_eventids2
();
14013 id_warn
= rb_intern_const
("warn");
14014 id_warning
= rb_intern_const
("warning");
14015 id_gets
= rb_intern_const
("gets");
14016 id_assoc
= rb_intern_const
("=>");
14018 (void)yystpcpy
; /* may not used in newer bison */
14024 InitVM_ripper
(void)
14028 Ripper
= rb_define_class
("Ripper", rb_cObject
);
14029 /* version of Ripper */
14030 rb_define_const
(Ripper
, "Version", rb_usascii_str_new2
(RIPPER_VERSION
));
14031 rb_define_alloc_func
(Ripper
, ripper_s_allocate
);
14032 rb_define_method
(Ripper
, "initialize", ripper_initialize
, -1);
14033 rb_define_method
(Ripper
, "parse", ripper_parse
, 0);
14034 rb_define_method
(Ripper
, "column", ripper_column
, 0);
14035 rb_define_method
(Ripper
, "filename", ripper_filename
, 0);
14036 rb_define_method
(Ripper
, "lineno", ripper_lineno
, 0);
14037 rb_define_method
(Ripper
, "state", ripper_state
, 0);
14038 rb_define_method
(Ripper
, "token", ripper_token
, 0);
14039 rb_define_method
(Ripper
, "end_seen?", rb_parser_end_seen_p
, 0);
14040 rb_define_method
(Ripper
, "encoding", rb_parser_encoding
, 0);
14041 rb_define_method
(Ripper
, "yydebug", rb_parser_get_yydebug
, 0);
14042 rb_define_method
(Ripper
, "yydebug=", rb_parser_set_yydebug
, 1);
14043 rb_define_method
(Ripper
, "debug_output", rb_parser_get_debug_output
, 0);
14044 rb_define_method
(Ripper
, "debug_output=", rb_parser_set_debug_output
, 1);
14045 rb_define_method
(Ripper
, "error?", ripper_error_p
, 0);
14046 #ifdef RIPPER_DEBUG
14047 rb_define_method
(Ripper
, "assert_Qundef", ripper_assert_Qundef
, 2);
14048 rb_define_method
(Ripper
, "rawVALUE", ripper_value
, 1);
14049 rb_define_method
(Ripper
, "validate_object", ripper_validate_object
, 1);
14052 rb_define_singleton_method
(Ripper
, "dedent_string", parser_dedent_string
, 2);
14053 rb_define_private_method
(Ripper
, "dedent_string", parser_dedent_string
, 2);
14055 rb_define_singleton_method
(Ripper
, "lex_state_name", ripper_lex_state_name
, 1);
14057 <% @exprs.each do |expr
, desc|
-%
>
14059 rb_define_const
(Ripper
, "<%=expr%>", INT2NUM
(<%
=expr%
>));
14061 ripper_init_eventids1_table
(Ripper
);
14062 ripper_init_eventids2_table
(Ripper
);
14065 /* Hack to let RDoc document SCRIPT_LINES__ */
14068 * When a Hash is assigned to +SCRIPT_LINES__+ the contents of files loaded
14069 * after the assignment will be added as an Array of lines with the file
14072 rb_define_global_const
("SCRIPT_LINES__", Qnil
);
14076 #endif /* RIPPER */
14081 * c-file-style: "ruby"