2 ** parse.y - mruby parser
4 ** See Copyright Notice in mruby.h
11 #define YYERROR_VERBOSE 1
13 * Force yacc to use our memory management. This is a little evil because
14 * the macros assume that "parser_state *p" is in scope
16 #define YYMALLOC(n) mrb_malloc(p->mrb, (n))
17 #define YYFREE(o) mrb_free(p->mrb, (o))
18 #define YYSTACK_USE_ALLOCA 0
21 #include "mruby/compile.h"
22 #include "mruby/proc.h"
32 typedef mrb_ast_node node
;
33 typedef
struct mrb_parser_state parser_state
;
34 typedef
struct mrb_parser_heredoc_info parser_heredoc_info
;
36 static int yylex(void *lval
, parser_state
*p
);
37 static void yyerror(parser_state
*p
, const char *s
);
38 static void yywarn
(parser_state
*p
, const char *s
);
39 static void yywarning
(parser_state
*p
, const char *s
);
40 static void backref_error
(parser_state
*p
, node
*n
);
42 #define identchar(c) (isalnum(c) || (c) == '_' || !isascii(c))
44 typedef
unsigned int stack_type
;
46 #define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
47 #define BITSTACK_POP(stack) ((stack) = (stack) >> 1)
48 #define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
49 #define BITSTACK_SET_P(stack) ((stack)&1)
51 #define COND_PUSH(n) BITSTACK_PUSH(p->cond_stack, (n))
52 #define COND_POP() BITSTACK_POP(p->cond_stack)
53 #define COND_LEXPOP() BITSTACK_LEXPOP(p->cond_stack)
54 #define COND_P() BITSTACK_SET_P(p->cond_stack)
56 #define CMDARG_PUSH(n) BITSTACK_PUSH(p->cmdarg_stack, (n))
57 #define CMDARG_POP() BITSTACK_POP(p->cmdarg_stack)
58 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(p->cmdarg_stack)
59 #define CMDARG_P() BITSTACK_SET_P(p->cmdarg_stack)
61 #define sym(x) ((mrb_sym)(intptr_t)(x))
62 #define nsym(x) ((node*)(intptr_t)(x))
65 intern_gen
(parser_state
*p
, const char *s
)
67 return mrb_intern
(p
->mrb
, s
);
69 #define intern(s) intern_gen(p,(s))
72 intern_gen2
(parser_state
*p
, const char *s
, size_t len
)
74 return mrb_intern2
(p
->mrb
, s
, len
);
76 #define intern2(s,len) intern_gen2(p,(s),(len))
79 intern_gen_c
(parser_state
*p
, const char c
)
81 return mrb_intern2
(p
->mrb
, &c
, 1);
83 #define intern_c(c) intern_gen_c(p,(c))
86 cons_free_gen
(parser_state
*p
, node
*cons
)
91 #define cons_free(c) cons_free_gen(p, (c))
94 parser_palloc
(parser_state
*p
, size_t size
)
96 void *m
= mrb_pool_alloc
(p
->pool
, size
);
105 cons_gen
(parser_state
*p
, node
*car
, node
*cdr
)
111 p
->cells
= p
->cells
->cdr
;
114 c
= (node
*)parser_palloc
(p
, sizeof
(mrb_ast_node
));
119 c
->lineno
= p
->lineno
;
122 #define cons(a,b) cons_gen(p,(a),(b))
125 list1_gen
(parser_state
*p
, node
*a
)
129 #define list1(a) list1_gen(p, (a))
132 list2_gen
(parser_state
*p
, node
*a
, node
*b
)
134 return cons
(a
, cons
(b
,0));
136 #define list2(a,b) list2_gen(p, (a),(b))
139 list3_gen
(parser_state
*p
, node
*a
, node
*b
, node
*c
)
141 return cons
(a
, cons
(b
, cons
(c
,0)));
143 #define list3(a,b,c) list3_gen(p, (a),(b),(c))
146 list4_gen
(parser_state
*p
, node
*a
, node
*b
, node
*c
, node
*d
)
148 return cons
(a
, cons
(b
, cons
(c
, cons
(d
, 0))));
150 #define list4(a,b,c,d) list4_gen(p, (a),(b),(c),(d))
153 list5_gen
(parser_state
*p
, node
*a
, node
*b
, node
*c
, node
*d
, node
*e
)
155 return cons
(a
, cons
(b
, cons
(c
, cons
(d
, cons
(e
, 0)))));
157 #define list5(a,b,c,d,e) list5_gen(p, (a),(b),(c),(d),(e))
160 list6_gen
(parser_state
*p
, node
*a
, node
*b
, node
*c
, node
*d
, node
*e
, node
*f
)
162 return cons
(a
, cons
(b
, cons
(c
, cons
(d
, cons
(e
, cons
(f
, 0))))));
164 #define list6(a,b,c,d,e,f) list6_gen(p, (a),(b),(c),(d),(e),(f))
167 append_gen
(parser_state
*p
, node
*a
, node
*b
)
180 #define append(a,b) append_gen(p,(a),(b))
181 #define push(a,b) append_gen(p,(a),list1(b))
184 parser_strndup
(parser_state
*p
, const char *s
, size_t len
)
186 char *b
= (char *)parser_palloc
(p
, len
+1);
192 #define strndup(s,len) parser_strndup(p, s, len)
195 parser_strdup
(parser_state
*p
, const char *s
)
197 return parser_strndup
(p
, s
, strlen
(s
));
200 #define strdup(s) parser_strdup(p, s)
202 // xxx -----------------------------
205 local_switch
(parser_state
*p
)
207 node
*prev
= p
->locals
;
209 p
->locals
= cons
(0, 0);
214 local_resume
(parser_state
*p
, node
*prev
)
220 local_nest
(parser_state
*p
)
222 p
->locals
= cons
(0, p
->locals
);
226 local_unnest
(parser_state
*p
)
228 p
->locals
= p
->locals
->cdr
;
232 local_var_p
(parser_state
*p
, mrb_sym sym
)
239 if
(sym
(n
->car
) == sym
) return
1;
248 local_add_f
(parser_state
*p
, mrb_sym sym
)
250 p
->locals
->car
= push
(p
->locals
->car
, nsym
(sym
));
254 local_add
(parser_state
*p
, mrb_sym sym
)
256 if
(!local_var_p
(p
, sym
)) {
261 // (:scope (vars..) (prog...))
263 new_scope
(parser_state
*p
, node
*body
)
265 return cons
((node
*)NODE_SCOPE
, cons
(p
->locals
->car
, body
));
270 new_begin
(parser_state
*p
, node
*body
)
273 return list2
((node
*)NODE_BEGIN
, body
);
274 return cons
((node
*)NODE_BEGIN
, 0);
277 #define newline_node(n) (n)
279 // (:rescue body rescue else)
281 new_rescue
(parser_state
*p
, node
*body
, node
*resq
, node
*els
)
283 return list4
((node
*)NODE_RESCUE
, body
, resq
, els
);
286 // (:ensure body ensure)
288 new_ensure
(parser_state
*p
, node
*a
, node
*b
)
290 return cons
((node
*)NODE_ENSURE
, cons
(a
, cons
(0, b
)));
295 new_nil
(parser_state
*p
)
297 return list1
((node
*)NODE_NIL
);
302 new_true
(parser_state
*p
)
304 return list1
((node
*)NODE_TRUE
);
309 new_false
(parser_state
*p
)
311 return list1
((node
*)NODE_FALSE
);
316 new_alias
(parser_state
*p
, mrb_sym a
, mrb_sym b
)
318 return cons
((node
*)NODE_ALIAS
, cons
(nsym
(a
), nsym
(b
)));
321 // (:if cond then else)
323 new_if
(parser_state
*p
, node
*a
, node
*b
, node
*c
)
325 return list4
((node
*)NODE_IF
, a
, b
, c
);
328 // (:unless cond then else)
330 new_unless
(parser_state
*p
, node
*a
, node
*b
, node
*c
)
332 return list4
((node
*)NODE_IF
, a
, c
, b
);
335 // (:while cond body)
337 new_while
(parser_state
*p
, node
*a
, node
*b
)
339 return cons
((node
*)NODE_WHILE
, cons
(a
, b
));
342 // (:until cond body)
344 new_until
(parser_state
*p
, node
*a
, node
*b
)
346 return cons
((node
*)NODE_UNTIL
, cons
(a
, b
));
349 // (:for var obj body)
351 new_for
(parser_state
*p
, node
*v
, node
*o
, node
*b
)
353 return list4
((node
*)NODE_FOR
, v
, o
, b
);
356 // (:case a ((when ...) body) ((when...) body))
358 new_case
(parser_state
*p
, node
*a
, node
*b
)
360 node
*n
= list2
((node
*)NODE_CASE
, a
);
372 new_postexe
(parser_state
*p
, node
*a
)
374 return cons
((node
*)NODE_POSTEXE
, a
);
379 new_self
(parser_state
*p
)
381 return list1
((node
*)NODE_SELF
);
386 new_call
(parser_state
*p
, node
*a
, mrb_sym b
, node
*c
)
388 return list4
((node
*)NODE_CALL
, a
, nsym
(b
), c
);
391 // (:fcall self mid args)
393 new_fcall
(parser_state
*p
, mrb_sym b
, node
*c
)
395 return list4
((node
*)NODE_FCALL
, new_self
(p
), nsym
(b
), c
);
401 new_vcall
(parser_state
*p
, mrb_sym b
)
403 return list3
((node
*)NODE_VCALL
, new_self
(p
), (node
*)b
);
409 new_super
(parser_state
*p
, node
*c
)
411 return cons
((node
*)NODE_SUPER
, c
);
416 new_zsuper
(parser_state
*p
)
418 return list1
((node
*)NODE_ZSUPER
);
423 new_yield
(parser_state
*p
, node
*c
)
427 yyerror(p
, "both block arg and actual block given");
429 return cons
((node
*)NODE_YIELD
, c
->car
);
431 return cons
((node
*)NODE_YIELD
, 0);
436 new_return
(parser_state
*p
, node
*c
)
438 return cons
((node
*)NODE_RETURN
, c
);
443 new_break
(parser_state
*p
, node
*c
)
445 return cons
((node
*)NODE_BREAK
, c
);
450 new_next
(parser_state
*p
, node
*c
)
452 return cons
((node
*)NODE_NEXT
, c
);
457 new_redo
(parser_state
*p
)
459 return list1
((node
*)NODE_REDO
);
464 new_retry
(parser_state
*p
)
466 return list1
((node
*)NODE_RETRY
);
471 new_dot2
(parser_state
*p
, node
*a
, node
*b
)
473 return cons
((node
*)NODE_DOT2
, cons
(a
, b
));
478 new_dot3
(parser_state
*p
, node
*a
, node
*b
)
480 return cons
((node
*)NODE_DOT3
, cons
(a
, b
));
485 new_colon2
(parser_state
*p
, node
*b
, mrb_sym c
)
487 return cons
((node
*)NODE_COLON2
, cons
(b
, nsym
(c
)));
492 new_colon3
(parser_state
*p
, mrb_sym c
)
494 return cons
((node
*)NODE_COLON3
, nsym
(c
));
499 new_and
(parser_state
*p
, node
*a
, node
*b
)
501 return cons
((node
*)NODE_AND
, cons
(a
, b
));
506 new_or
(parser_state
*p
, node
*a
, node
*b
)
508 return cons
((node
*)NODE_OR
, cons
(a
, b
));
513 new_array
(parser_state
*p
, node
*a
)
515 return cons
((node
*)NODE_ARRAY
, a
);
520 new_splat
(parser_state
*p
, node
*a
)
522 return cons
((node
*)NODE_SPLAT
, a
);
525 // (:hash (k . v) (k . v)...)
527 new_hash
(parser_state
*p
, node
*a
)
529 return cons
((node
*)NODE_HASH
, a
);
534 new_sym
(parser_state
*p
, mrb_sym sym
)
536 return cons
((node
*)NODE_SYM
, nsym
(sym
));
540 new_strsym
(parser_state
*p
, node
* str
)
542 const char *s
= (const char*)str
->cdr
->car
;
543 size_t len
= (size_t)str
->cdr
->cdr
;
545 return mrb_intern2
(p
->mrb
, s
, len
);
550 new_lvar
(parser_state
*p
, mrb_sym sym
)
552 return cons
((node
*)NODE_LVAR
, nsym
(sym
));
557 new_gvar
(parser_state
*p
, mrb_sym sym
)
559 return cons
((node
*)NODE_GVAR
, nsym
(sym
));
564 new_ivar
(parser_state
*p
, mrb_sym sym
)
566 return cons
((node
*)NODE_IVAR
, nsym
(sym
));
571 new_cvar
(parser_state
*p
, mrb_sym sym
)
573 return cons
((node
*)NODE_CVAR
, nsym
(sym
));
578 new_const
(parser_state
*p
, mrb_sym sym
)
580 return cons
((node
*)NODE_CONST
, nsym
(sym
));
585 new_undef
(parser_state
*p
, mrb_sym sym
)
587 return list2
((node
*)NODE_UNDEF
, nsym
(sym
));
590 // (:class class super body)
592 new_class
(parser_state
*p
, node
*c
, node
*s
, node
*b
)
594 return list4
((node
*)NODE_CLASS
, c
, s
, cons
(p
->locals
->car
, b
));
597 // (:sclass obj body)
599 new_sclass
(parser_state
*p
, node
*o
, node
*b
)
601 return list3
((node
*)NODE_SCLASS
, o
, cons
(p
->locals
->car
, b
));
604 // (:module module body)
606 new_module
(parser_state
*p
, node
*m
, node
*b
)
608 return list3
((node
*)NODE_MODULE
, m
, cons
(p
->locals
->car
, b
));
611 // (:def m lv (arg . body))
613 new_def
(parser_state
*p
, mrb_sym m
, node
*a
, node
*b
)
615 return list5
((node
*)NODE_DEF
, nsym
(m
), p
->locals
->car
, a
, b
);
618 // (:sdef obj m lv (arg . body))
620 new_sdef
(parser_state
*p
, node
*o
, mrb_sym m
, node
*a
, node
*b
)
622 return list6
((node
*)NODE_SDEF
, o
, nsym
(m
), p
->locals
->car
, a
, b
);
627 new_arg
(parser_state
*p
, mrb_sym sym
)
629 return cons
((node
*)NODE_ARG
, nsym
(sym
));
634 // o: ((a . e1) (b . e2))
639 new_args
(parser_state
*p
, node
*m
, node
*opt
, mrb_sym rest
, node
*m2
, mrb_sym blk
)
643 n
= cons
(m2
, nsym
(blk
));
644 n
= cons
(nsym
(rest
), n
);
651 new_block_arg
(parser_state
*p
, node
*a
)
653 return cons
((node
*)NODE_BLOCK_ARG
, a
);
658 new_block
(parser_state
*p
, node
*a
, node
*b
)
660 return list4
((node
*)NODE_BLOCK
, p
->locals
->car
, a
, b
);
663 // (:lambda arg body)
665 new_lambda
(parser_state
*p
, node
*a
, node
*b
)
667 return list4
((node
*)NODE_LAMBDA
, p
->locals
->car
, a
, b
);
672 new_asgn
(parser_state
*p
, node
*a
, node
*b
)
674 return cons
((node
*)NODE_ASGN
, cons
(a
, b
));
677 // (:masgn mlhs=(pre rest post) mrhs)
679 new_masgn
(parser_state
*p
, node
*a
, node
*b
)
681 return cons
((node
*)NODE_MASGN
, cons
(a
, b
));
686 new_op_asgn
(parser_state
*p
, node
*a
, mrb_sym op
, node
*b
)
688 return list4
((node
*)NODE_OP_ASGN
, a
, nsym
(op
), b
);
693 new_int
(parser_state
*p
, const char *s
, int base
)
695 return list3
((node
*)NODE_INT
, (node
*)strdup
(s
), (node
*)(intptr_t)base
);
700 new_float
(parser_state
*p
, const char *s
)
702 return cons
((node
*)NODE_FLOAT
, (node
*)strdup
(s
));
705 // (:str . (s . len))
707 new_str
(parser_state
*p
, const char *s
, int len
)
709 return cons
((node
*)NODE_STR
, cons
((node
*)strndup
(s
, len
), (node
*)(intptr_t)len
));
714 new_dstr
(parser_state
*p
, node
*a
)
716 return cons
((node
*)NODE_DSTR
, a
);
719 // (:str . (s . len))
721 new_xstr
(parser_state
*p
, const char *s
, int len
)
723 return cons
((node
*)NODE_XSTR
, cons
((node
*)strndup
(s
, len
), (node
*)(intptr_t)len
));
728 new_dxstr
(parser_state
*p
, node
*a
)
730 return cons
((node
*)NODE_DXSTR
, a
);
735 new_dsym
(parser_state
*p
, node
*a
)
737 return cons
((node
*)NODE_DSYM
, new_dstr
(p
, a
));
742 new_regx
(parser_state
*p
, const char *p1
, const char* p2
)
744 return cons
((node
*)NODE_REGX
, cons
((node
*)p1
, (node
*)p2
));
749 new_dregx
(parser_state
*p
, node
*a
, node
*b
)
751 return cons
((node
*)NODE_DREGX
, cons
(a
, b
));
756 new_back_ref
(parser_state
*p
, int n
)
758 return cons
((node
*)NODE_BACK_REF
, (node
*)(intptr_t)n
);
763 new_nth_ref
(parser_state
*p
, int n
)
765 return cons
((node
*)NODE_NTH_REF
, (node
*)(intptr_t)n
);
770 new_heredoc
(parser_state
*p
)
772 parser_heredoc_info
*inf
= parser_palloc
(p
, sizeof
(parser_heredoc_info
));
773 return cons
((node
*)NODE_HEREDOC
, (node
*)inf
);
777 new_bv
(parser_state
*p
, mrb_sym id
)
782 new_literal_delim
(parser_state
*p
)
784 return cons
((node
*)NODE_LITERAL_DELIM
, 0);
789 new_words
(parser_state
*p
, node
*a
)
791 return cons
((node
*)NODE_WORDS
, a
);
796 new_symbols
(parser_state
*p
, node
*a
)
798 return cons
((node
*)NODE_SYMBOLS
, a
);
801 // xxx -----------------------------
805 call_uni_op
(parser_state
*p
, node
*recv
, char *m
)
807 return new_call
(p
, recv
, intern
(m
), 0);
812 call_bin_op
(parser_state
*p
, node
*recv
, char *m
, node
*arg1
)
814 return new_call
(p
, recv
, intern
(m
), list1
(list1
(arg1
)));
818 args_with_block
(parser_state
*p
, node
*a
, node
*b
)
822 yyerror(p
, "both block arg and actual block given");
829 call_with_block
(parser_state
*p
, node
*a
, node
*b
)
833 if
(a
->car
== (node
*)NODE_SUPER ||
834 a
->car
== (node
*)NODE_ZSUPER
) {
835 if
(!a
->cdr
) a
->cdr
= cons
(0, b
);
837 args_with_block
(p
, a
->cdr
, b
);
841 n
= a
->cdr
->cdr
->cdr
;
842 if
(!n
->car
) n
->car
= cons
(0, b
);
844 args_with_block
(p
, n
->car
, b
);
850 negate_lit
(parser_state
*p
, node
*n
)
852 return cons
((node
*)NODE_NEGATE
, n
);
862 ret_args
(parser_state
*p
, node
*n
)
865 yyerror(p
, "block argument should not be given");
867 if
(!n
->car
->cdr
) return n
->car
->car
;
868 return new_array
(p
, n
->car
);
872 assignable
(parser_state
*p
, node
*lhs
)
874 if
((int)(intptr_t)lhs
->car
== NODE_LVAR
) {
875 local_add
(p
, sym
(lhs
->cdr
));
880 var_reference
(parser_state
*p
, node
*lhs
)
884 if
((int)(intptr_t)lhs
->car
== NODE_LVAR
) {
885 if
(!local_var_p
(p
, sym
(lhs
->cdr
))) {
886 n
= new_fcall
(p
, sym
(lhs
->cdr
), 0);
895 typedef
enum mrb_string_type string_type
;
898 new_strterm
(parser_state
*p
, string_type type
, int term
, int paren
)
900 return cons
((node
*)(intptr_t)type
, cons
((node
*)0, cons
((node
*)(intptr_t)paren
, (node
*)(intptr_t)term
)));
904 end_strterm
(parser_state
*p
)
906 cons_free
(p
->lex_strterm
->cdr
->cdr
);
907 cons_free
(p
->lex_strterm
->cdr
);
908 cons_free
(p
->lex_strterm
);
909 p
->lex_strterm
= NULL
;
912 parser_heredoc_info
*
913 parsing_heredoc_inf
(parser_state
*p
)
915 node
*nd
= p
->parsing_heredoc
;
918 /* assert(nd->car->car == NODE_HEREDOC); */
919 return
(parser_heredoc_info
*)nd
->car
->cdr
;
923 heredoc_end
(parser_state
*p
)
925 p
->parsing_heredoc
= p
->parsing_heredoc
->cdr
;
926 if
(p
->parsing_heredoc
== NULL
) {
927 p
->lstate
= EXPR_BEG
;
930 p
->heredoc_end_now
= TRUE
;
933 p
->lex_strterm
->car
= (node
*)(intptr_t)parsing_heredoc_inf
(p
)->type
;
936 #define is_strterm_type(p,str_func) ((int)(intptr_t)((p)->lex_strterm->car) & (str_func))
938 // xxx -----------------------------
943 %parse
-param
{parser_state
*p
}
944 %lex
-param
{parser_state
*p
}
951 const struct vtable
*vars
;
1004 %token
<id
> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
1005 %token
<nd
> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
1006 %token
<nd
> tSTRING tSTRING_PART tSTRING_MID
1007 %token
<nd
> tNTH_REF tBACK_REF
1008 %token
<num
> tREGEXP_END
1010 %type
<nd
> singleton
string string_rep string_interp xstring regexp
1011 %type
<nd
> literal numeric cpath symbol
1012 %type
<nd
> top_compstmt top_stmts top_stmt
1013 %type
<nd
> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
1014 %type
<nd
> expr_value arg_value primary_value
1015 %type
<nd
> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
1016 %type
<nd
> args call_args opt_call_args
1017 %type
<nd
> paren_args opt_paren_args variable
1018 %type
<nd
> command_args aref_args opt_block_arg block_arg var_ref var_lhs
1019 %type
<nd
> command_asgn mrhs superclass block_call block_command
1020 %type
<nd
> f_block_optarg f_block_opt
1021 %type
<nd
> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
1022 %type
<nd
> assoc_list assocs assoc undef_list backref for_var
1023 %type
<nd
> block_param opt_block_param block_param_def f_opt
1024 %type
<nd
> bv_decls opt_bv_decl bvar f_larglist lambda_body
1025 %type
<nd
> brace_block cmd_brace_block do_block lhs none f_bad_arg
1026 %type
<nd
> mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner
1027 %type
<id
> fsym sym basic_symbol operation operation2 operation3
1028 %type
<id
> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg
1029 %type
<nd
> heredoc words symbols
1031 %token tUPLUS
/* unary+ */
1032 %token tUMINUS
/* unary- */
1033 %token tPOW
/* ** */
1034 %token tCMP
/* <=> */
1036 %token tEQQ
/* === */
1037 %token tNEQ
/* != */
1038 %token tGEQ
/* >= */
1039 %token tLEQ
/* <= */
1040 %token tANDOP tOROP
/* && and || */
1041 %token tMATCH tNMATCH
/* =~ and !~ */
1042 %token tDOT2 tDOT3
/* .. and ... */
1043 %token tAREF tASET
/* [] and []= */
1044 %token tLSHFT tRSHFT
/* << and >> */
1045 %token tCOLON2
/* :: */
1046 %token tCOLON3
/* :: at EXPR_BEG */
1047 %token
<id
> tOP_ASGN
/* +=, -= etc. */
1048 %token tASSOC
/* => */
1049 %token tLPAREN
/* ( */
1050 %token tLPAREN_ARG
/* ( */
1051 %token tRPAREN
/* ) */
1052 %token tLBRACK
/* [ */
1053 %token tLBRACE
/* { */
1054 %token tLBRACE_ARG
/* { */
1055 %token tSTAR
/* * */
1056 %token tAMPER
/* & */
1057 %token tLAMBDA
/* -> */
1058 %token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG
1059 %token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG
1060 %token
<nd
> tHEREDOC_BEG
/* <<, <<- */
1061 %token tHEREDOC_END tLITERAL_DELIM
1068 %nonassoc tLBRACE_ARG
1070 %nonassoc modifier_if modifier_unless modifier_while modifier_until
1071 %left keyword_or keyword_and
1074 %left modifier_rescue
1076 %nonassoc tDOT2 tDOT3
1079 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
1080 %left
'>' tGEQ
'<' tLEQ
1086 %right tUMINUS_NUM tUMINUS
1088 %right
'!' '~' tUPLUS
1091 %nonassoc idRespond_to
1094 %nonassoc id_core_set_method_alias
1095 %nonassoc id_core_set_variable_alias
1096 %nonassoc id_core_undef_method
1097 %nonassoc id_core_define_method
1098 %nonassoc id_core_define_singleton_method
1099 %nonassoc id_core_set_postexe
1105 p
->lstate
= EXPR_BEG
;
1106 if
(!p
->locals
) p
->locals
= cons
(0,0);
1110 p
->tree
= new_scope
(p
, $2);
1114 top_compstmt
: top_stmts opt_terms
1122 $$
= new_begin
(p
, 0);
1126 $$
= new_begin
(p
, $1);
1128 | top_stmts terms top_stmt
1130 $$
= push
($1, newline_node
($3));
1134 $$
= new_begin
(p
, 0);
1141 $
<nd
>$
= local_switch
(p
);
1143 '{' top_compstmt
'}'
1145 yyerror(p
, "BEGIN not supported");
1146 local_resume
(p
, $
<nd
>2);
1157 $$
= new_rescue
(p
, $1, $2, $3);
1160 yywarn
(p
, "else without rescue is useless");
1168 $$
= new_ensure
(p
, $$
, $4);
1171 $$
= push
($4, new_nil
(p
));
1177 compstmt
: stmts opt_terms
1185 $$
= new_begin
(p
, 0);
1189 $$
= new_begin
(p
, $1);
1193 $$
= push
($1, newline_node
($3));
1197 $$
= new_begin
(p
, $2);
1201 stmt
: keyword_alias fsym
{p
->lstate
= EXPR_FNAME
;} fsym
1203 $$
= new_alias
(p
, $2, $4);
1205 | keyword_undef undef_list
1209 | stmt modifier_if expr_value
1211 $$
= new_if
(p
, cond
($3), $1, 0);
1213 | stmt modifier_unless expr_value
1215 $$
= new_unless
(p
, cond
($3), $1, 0);
1217 | stmt modifier_while expr_value
1219 $$
= new_while
(p
, cond
($3), $1);
1221 | stmt modifier_until expr_value
1223 $$
= new_until
(p
, cond
($3), $1);
1225 | stmt modifier_rescue stmt
1227 $$
= new_rescue
(p
, $1, list1
(list3
(0, 0, $3)), 0);
1229 | keyword_END
'{' compstmt
'}'
1231 yyerror(p
, "END not suported");
1232 $$
= new_postexe
(p
, $3);
1235 | mlhs
'=' command_call
1237 $$
= new_masgn
(p
, $1, $3);
1239 | var_lhs tOP_ASGN command_call
1241 $$
= new_op_asgn
(p
, $1, $2, $3);
1243 | primary_value
'[' opt_call_args rbracket tOP_ASGN command_call
1245 $$
= new_op_asgn
(p
, new_call
(p
, $1, intern2
("[]",2), $3), $5, $6);
1247 | primary_value
'.' tIDENTIFIER tOP_ASGN command_call
1249 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1251 | primary_value
'.' tCONSTANT tOP_ASGN command_call
1253 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1255 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
1257 yyerror(p
, "constant re-assignment");
1260 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
1262 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1264 | backref tOP_ASGN command_call
1266 backref_error
(p
, $1);
1267 $$
= new_begin
(p
, 0);
1271 $$
= new_asgn
(p
, $1, new_array
(p
, $3));
1273 | mlhs
'=' arg_value
1275 $$
= new_masgn
(p
, $1, $3);
1279 $$
= new_masgn
(p
, $1, new_array
(p
, $3));
1284 command_asgn
: lhs
'=' command_call
1286 $$
= new_asgn
(p
, $1, $3);
1288 | lhs
'=' command_asgn
1290 $$
= new_asgn
(p
, $1, $3);
1296 | expr keyword_and expr
1298 $$
= new_and
(p
, $1, $3);
1300 | expr keyword_or expr
1302 $$
= new_or
(p
, $1, $3);
1304 | keyword_not opt_nl expr
1306 $$
= call_uni_op
(p
, cond
($3), "!");
1310 $$
= call_uni_op
(p
, cond
($2), "!");
1317 if
(!$1) $$
= new_nil
(p
);
1322 command_call
: command
1326 block_command
: block_call
1327 | block_call dot_or_colon operation2 command_args
1330 cmd_brace_block
: tLBRACE_ARG
1338 $$
= new_block
(p
, $3, $4);
1343 command
: operation command_args %prec tLOWEST
1345 $$
= new_fcall
(p
, $1, $2);
1347 | operation command_args cmd_brace_block
1349 args_with_block
(p
, $2, $3);
1350 $$
= new_fcall
(p
, $1, $2);
1352 | primary_value
'.' operation2 command_args %prec tLOWEST
1354 $$
= new_call
(p
, $1, $3, $4);
1356 | primary_value
'.' operation2 command_args cmd_brace_block
1358 args_with_block
(p
, $4, $5);
1359 $$
= new_call
(p
, $1, $3, $4);
1361 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1363 $$
= new_call
(p
, $1, $3, $4);
1365 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1367 args_with_block
(p
, $4, $5);
1368 $$
= new_call
(p
, $1, $3, $4);
1370 | keyword_super command_args
1372 $$
= new_super
(p
, $2);
1374 | keyword_yield command_args
1376 $$
= new_yield
(p
, $2);
1378 | keyword_return call_args
1380 $$
= new_return
(p
, ret_args
(p
, $2));
1382 | keyword_break call_args
1384 $$
= new_break
(p
, ret_args
(p
, $2));
1386 | keyword_next call_args
1388 $$
= new_next
(p
, ret_args
(p
, $2));
1396 | tLPAREN mlhs_inner rparen
1402 mlhs_inner
: mlhs_basic
1403 | tLPAREN mlhs_inner rparen
1409 mlhs_basic
: mlhs_list
1413 | mlhs_list mlhs_item
1415 $$
= list1
(push
($1,$2));
1417 | mlhs_list tSTAR mlhs_node
1421 | mlhs_list tSTAR mlhs_node
',' mlhs_post
1423 $$
= list3
($1, $3, $5);
1427 $$
= list2
($1, new_nil
(p
));
1429 | mlhs_list tSTAR
',' mlhs_post
1431 $$
= list3
($1, new_nil
(p
), $4);
1437 | tSTAR mlhs_node
',' mlhs_post
1439 $$
= list3
(0, $2, $4);
1443 $$
= list2
(0, new_nil
(p
));
1445 | tSTAR
',' mlhs_post
1447 $$
= list3
(0, new_nil
(p
), $3);
1451 mlhs_item
: mlhs_node
1452 | tLPAREN mlhs_inner rparen
1458 mlhs_list
: mlhs_item
','
1462 | mlhs_list mlhs_item
','
1468 mlhs_post
: mlhs_item
1472 | mlhs_list mlhs_item
1478 mlhs_node
: variable
1482 | primary_value
'[' opt_call_args rbracket
1484 $$
= new_call
(p
, $1, intern2
("[]",2), $3);
1486 | primary_value
'.' tIDENTIFIER
1488 $$
= new_call
(p
, $1, $3, 0);
1490 | primary_value tCOLON2 tIDENTIFIER
1492 $$
= new_call
(p
, $1, $3, 0);
1494 | primary_value
'.' tCONSTANT
1496 $$
= new_call
(p
, $1, $3, 0);
1498 | primary_value tCOLON2 tCONSTANT
1500 if
(p
->in_def || p
->in_single
)
1501 yyerror(p
, "dynamic constant assignment");
1502 $$
= new_colon2
(p
, $1, $3);
1506 if
(p
->in_def || p
->in_single
)
1507 yyerror(p
, "dynamic constant assignment");
1508 $$
= new_colon3
(p
, $2);
1512 backref_error
(p
, $1);
1521 | primary_value
'[' opt_call_args rbracket
1523 $$
= new_call
(p
, $1, intern2
("[]",2), $3);
1525 | primary_value
'.' tIDENTIFIER
1527 $$
= new_call
(p
, $1, $3, 0);
1529 | primary_value tCOLON2 tIDENTIFIER
1531 $$
= new_call
(p
, $1, $3, 0);
1533 | primary_value
'.' tCONSTANT
1535 $$
= new_call
(p
, $1, $3, 0);
1537 | primary_value tCOLON2 tCONSTANT
1539 if
(p
->in_def || p
->in_single
)
1540 yyerror(p
, "dynamic constant assignment");
1541 $$
= new_colon2
(p
, $1, $3);
1545 if
(p
->in_def || p
->in_single
)
1546 yyerror(p
, "dynamic constant assignment");
1547 $$
= new_colon3
(p
, $2);
1551 backref_error
(p
, $1);
1558 yyerror(p
, "class/module name must be CONSTANT");
1563 cpath
: tCOLON3 cname
1565 $$
= cons
((node
*)1, nsym
($2));
1569 $$
= cons
((node
*)0, nsym
($1));
1571 | primary_value tCOLON2 cname
1573 $$
= cons
($1, nsym
($3));
1582 p
->lstate
= EXPR_ENDFN
;
1587 p
->lstate
= EXPR_ENDFN
;
1598 $$
= new_undef
(p
, $1);
1600 | undef_list
',' {p
->lstate
= EXPR_FNAME
;} fsym
1602 $$
= push
($1, nsym
($4));
1606 op
: '|' { $$
= intern_c
('|'); }
1607 |
'^' { $$
= intern_c
('^'); }
1608 |
'&' { $$
= intern_c
('&'); }
1609 | tCMP
{ $$
= intern2
("<=>",3); }
1610 | tEQ
{ $$
= intern2
("==",2); }
1611 | tEQQ
{ $$
= intern2
("===",3); }
1612 | tMATCH
{ $$
= intern2
("=~",2); }
1613 | tNMATCH
{ $$
= intern2
("!~",2); }
1614 |
'>' { $$
= intern_c
('>'); }
1615 | tGEQ
{ $$
= intern2
(">=",2); }
1616 |
'<' { $$
= intern_c
('<'); }
1617 | tLEQ
{ $$
= intern2
("<=",2); }
1618 | tNEQ
{ $$
= intern2
("!=",2); }
1619 | tLSHFT
{ $$
= intern2
("<<",2); }
1620 | tRSHFT
{ $$
= intern2
(">>",2); }
1621 |
'+' { $$
= intern_c
('+'); }
1622 |
'-' { $$
= intern_c
('-'); }
1623 |
'*' { $$
= intern_c
('*'); }
1624 | tSTAR
{ $$
= intern_c
('*'); }
1625 |
'/' { $$
= intern_c
('/'); }
1626 |
'%' { $$
= intern_c
('%'); }
1627 | tPOW
{ $$
= intern2
("**",2); }
1628 |
'!' { $$
= intern_c
('!'); }
1629 |
'~' { $$
= intern_c
('~'); }
1630 | tUPLUS
{ $$
= intern2
("+@",2); }
1631 | tUMINUS
{ $$
= intern2
("-@",2); }
1632 | tAREF
{ $$
= intern2
("[]",2); }
1633 | tASET
{ $$
= intern2
("[]=",3); }
1634 |
'`' { $$
= intern_c
('`'); }
1637 reswords
: keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
1638 | keyword_BEGIN | keyword_END
1639 | keyword_alias | keyword_and | keyword_begin
1640 | keyword_break | keyword_case | keyword_class | keyword_def
1641 | keyword_do | keyword_else | keyword_elsif
1642 | keyword_end | keyword_ensure | keyword_false
1643 | keyword_for | keyword_in | keyword_module | keyword_next
1644 | keyword_nil | keyword_not | keyword_or | keyword_redo
1645 | keyword_rescue | keyword_retry | keyword_return | keyword_self
1646 | keyword_super | keyword_then | keyword_true | keyword_undef
1647 | keyword_when | keyword_yield | keyword_if | keyword_unless
1648 | keyword_while | keyword_until
1653 $$
= new_asgn
(p
, $1, $3);
1655 | lhs
'=' arg modifier_rescue arg
1657 $$
= new_asgn
(p
, $1, new_rescue
(p
, $3, list1
(list3
(0, 0, $5)), 0));
1659 | var_lhs tOP_ASGN arg
1661 $$
= new_op_asgn
(p
, $1, $2, $3);
1663 | var_lhs tOP_ASGN arg modifier_rescue arg
1665 $$
= new_op_asgn
(p
, $1, $2, new_rescue
(p
, $3, list1
(list3
(0, 0, $5)), 0));
1667 | primary_value
'[' opt_call_args rbracket tOP_ASGN arg
1669 $$
= new_op_asgn
(p
, new_call
(p
, $1, intern2
("[]",2), $3), $5, $6);
1671 | primary_value
'.' tIDENTIFIER tOP_ASGN arg
1673 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1675 | primary_value
'.' tCONSTANT tOP_ASGN arg
1677 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1679 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
1681 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1683 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
1685 yyerror(p
, "constant re-assignment");
1686 $$
= new_begin
(p
, 0);
1688 | tCOLON3 tCONSTANT tOP_ASGN arg
1690 yyerror(p
, "constant re-assignment");
1691 $$
= new_begin
(p
, 0);
1693 | backref tOP_ASGN arg
1695 backref_error
(p
, $1);
1696 $$
= new_begin
(p
, 0);
1700 $$
= new_dot2
(p
, $1, $3);
1704 $$
= new_dot3
(p
, $1, $3);
1708 $$
= call_bin_op
(p
, $1, "+", $3);
1712 $$
= call_bin_op
(p
, $1, "-", $3);
1716 $$
= call_bin_op
(p
, $1, "*", $3);
1720 $$
= call_bin_op
(p
, $1, "/", $3);
1724 $$
= call_bin_op
(p
, $1, "%", $3);
1728 $$
= call_bin_op
(p
, $1, "**", $3);
1730 | tUMINUS_NUM tINTEGER tPOW arg
1732 $$
= call_uni_op
(p
, call_bin_op
(p
, $2, "**", $4), "-@");
1734 | tUMINUS_NUM tFLOAT tPOW arg
1736 $$
= call_uni_op
(p
, call_bin_op
(p
, $2, "**", $4), "-@");
1740 $$
= call_uni_op
(p
, $2, "+@");
1744 $$
= call_uni_op
(p
, $2, "-@");
1748 $$
= call_bin_op
(p
, $1, "|", $3);
1752 $$
= call_bin_op
(p
, $1, "^", $3);
1756 $$
= call_bin_op
(p
, $1, "&", $3);
1760 $$
= call_bin_op
(p
, $1, "<=>", $3);
1764 $$
= call_bin_op
(p
, $1, ">", $3);
1768 $$
= call_bin_op
(p
, $1, ">=", $3);
1772 $$
= call_bin_op
(p
, $1, "<", $3);
1776 $$
= call_bin_op
(p
, $1, "<=", $3);
1780 $$
= call_bin_op
(p
, $1, "==", $3);
1784 $$
= call_bin_op
(p
, $1, "===", $3);
1788 $$
= call_bin_op
(p
, $1, "!=", $3);
1792 $$
= call_bin_op
(p
, $1, "=~", $3);
1794 if
(nd_type
($1) == NODE_LIT
&& TYPE
($1->nd_lit
) == T_REGEXP
) {
1795 $$
= reg_named_capture_assign
($1->nd_lit
, $$
);
1801 $$
= call_bin_op
(p
, $1, "!~", $3);
1805 $$
= call_uni_op
(p
, cond
($2), "!");
1809 $$
= call_uni_op
(p
, cond
($2), "~");
1813 $$
= call_bin_op
(p
, $1, "<<", $3);
1817 $$
= call_bin_op
(p
, $1, ">>", $3);
1821 $$
= new_and
(p
, $1, $3);
1825 $$
= new_or
(p
, $1, $3);
1827 | arg
'?' arg opt_nl
':' arg
1829 $$
= new_if
(p
, cond
($1), $3, $6);
1840 if
(!$$
) $$
= new_nil
(p
);
1849 | args
',' assocs trailer
1851 $$
= push
($1, new_hash
(p
, $3));
1855 $$
= cons
(new_hash
(p
, $1), 0);
1859 paren_args
: '(' opt_call_args rparen
1865 opt_paren_args
: none
1869 opt_call_args
: none
1875 | args
',' assocs
','
1877 $$
= cons
(push
($1, new_hash
(p
, $3)), 0);
1881 $$
= cons
(list1
(new_hash
(p
, $1)), 0);
1887 $$
= cons
(list1
($1), 0);
1889 | args opt_block_arg
1893 | assocs opt_block_arg
1895 $$
= cons
(list1
(new_hash
(p
, $1)), $2);
1897 | args
',' assocs opt_block_arg
1899 $$
= cons
(push
($1, new_hash
(p
, $3)), $4);
1908 $
<stack
>$
= p
->cmdarg_stack
;
1913 p
->cmdarg_stack
= $
<stack
>1;
1918 block_arg
: tAMPER arg_value
1920 $$
= new_block_arg
(p
, $2);
1924 opt_block_arg
: ',' block_arg
1940 $$
= cons
(new_splat
(p
, $2), 0);
1942 | args
',' arg_value
1946 | args
',' tSTAR arg_value
1948 $$
= push
($1, new_splat
(p
, $4));
1952 mrhs
: args
',' arg_value
1956 | args
',' tSTAR arg_value
1958 $$
= push
($1, new_splat
(p
, $4));
1962 $$
= list1
(new_splat
(p
, $2));
1975 $$
= new_fcall
(p
, $1, 0);
1979 $
<stack
>1 = p
->cmdarg_stack
;
1980 p
->cmdarg_stack
= 0;
1985 p
->cmdarg_stack
= $
<stack
>1;
1988 | tLPAREN_ARG expr
{p
->lstate
= EXPR_ENDARG
;} rparen
1992 | tLPAREN_ARG
{p
->lstate
= EXPR_ENDARG
;} rparen
1996 | tLPAREN compstmt
')'
2000 | primary_value tCOLON2 tCONSTANT
2002 $$
= new_colon2
(p
, $1, $3);
2006 $$
= new_colon3
(p
, $2);
2008 | tLBRACK aref_args
']'
2010 $$
= new_array
(p
, $2);
2012 | tLBRACE assoc_list
'}'
2014 $$
= new_hash
(p
, $2);
2018 $$
= new_return
(p
, 0);
2020 | keyword_yield
'(' call_args rparen
2022 $$
= new_yield
(p
, $3);
2024 | keyword_yield
'(' rparen
2026 $$
= new_yield
(p
, 0);
2030 $$
= new_yield
(p
, 0);
2032 | keyword_not
'(' expr rparen
2034 $$
= call_uni_op
(p
, cond
($3), "!");
2036 | keyword_not
'(' rparen
2038 $$
= call_uni_op
(p
, new_nil
(p
), "!");
2040 | operation brace_block
2042 $$
= new_fcall
(p
, $1, cons
(0, $2));
2045 | method_call brace_block
2047 call_with_block
(p
, $1, $2);
2053 $
<num
>$
= p
->lpar_beg
;
2054 p
->lpar_beg
= ++p
->paren_nest
;
2059 p
->lpar_beg
= $
<num
>2;
2060 $$
= new_lambda
(p
, $3, $4);
2063 | keyword_if expr_value then
2068 $$
= new_if
(p
, cond
($2), $4, $5);
2070 | keyword_unless expr_value then
2075 $$
= new_unless
(p
, cond
($2), $4, $5);
2077 | keyword_while
{COND_PUSH
(1);} expr_value do
{COND_POP
();}
2081 $$
= new_while
(p
, cond
($3), $6);
2083 | keyword_until
{COND_PUSH
(1);} expr_value do
{COND_POP
();}
2087 $$
= new_until
(p
, cond
($3), $6);
2089 | keyword_case expr_value opt_terms
2093 $$
= new_case
(p
, $2, $4);
2095 | keyword_case opt_terms case_body keyword_end
2097 $$
= new_case
(p
, 0, $3);
2099 | keyword_for for_var keyword_in
2106 $$
= new_for
(p
, $2, $5, $8);
2108 | keyword_class cpath superclass
2110 if
(p
->in_def || p
->in_single
)
2111 yyerror(p
, "class definition in method body");
2112 $
<nd
>$
= local_switch
(p
);
2117 $$
= new_class
(p
, $2, $3, $5);
2118 local_resume
(p
, $
<nd
>4);
2120 | keyword_class tLSHFT expr
2122 $
<num
>$
= p
->in_def
;
2127 $
<nd
>$
= cons
(local_switch
(p
), (node
*)(intptr_t)p
->in_single
);
2133 $$
= new_sclass
(p
, $3, $7);
2134 local_resume
(p
, $
<nd
>6->car
);
2135 p
->in_def
= $
<num
>4;
2136 p
->in_single
= (int)(intptr_t)$
<nd
>6->cdr
;
2138 | keyword_module cpath
2140 if
(p
->in_def || p
->in_single
)
2141 yyerror(p
, "module definition in method body");
2142 $
<nd
>$
= local_switch
(p
);
2147 $$
= new_module
(p
, $2, $4);
2148 local_resume
(p
, $
<nd
>3);
2153 $
<nd
>$
= local_switch
(p
);
2159 $$
= new_def
(p
, $2, $4, $5);
2160 local_resume
(p
, $
<nd
>3);
2163 | keyword_def singleton dot_or_colon
{p
->lstate
= EXPR_FNAME
;} fname
2166 p
->lstate
= EXPR_ENDFN
; /* force for args */
2167 $
<nd
>$
= local_switch
(p
);
2173 $$
= new_sdef
(p
, $2, $5, $7, $8);
2174 local_resume
(p
, $
<nd
>6);
2179 $$
= new_break
(p
, 0);
2183 $$
= new_next
(p
, 0);
2195 primary_value
: primary
2198 if
(!$$
) $$
= new_nil
(p
);
2212 | keyword_elsif expr_value then
2216 $$
= new_if
(p
, cond
($2), $4, $5);
2221 | keyword_else compstmt
2229 $$
= list1
(list1
($1));
2236 $$
= new_arg
(p
, $1);
2238 | tLPAREN f_margs rparen
2240 $$
= new_masgn
(p
, $2, 0);
2244 f_marg_list
: f_marg
2248 | f_marg_list
',' f_marg
2254 f_margs
: f_marg_list
2258 | f_marg_list
',' tSTAR f_norm_arg
2260 $$
= list3
($1, new_arg
(p
, $4), 0);
2262 | f_marg_list
',' tSTAR f_norm_arg
',' f_marg_list
2264 $$
= list3
($1, new_arg
(p
, $4), $6);
2266 | f_marg_list
',' tSTAR
2268 $$
= list3
($1, (node
*)-1, 0);
2270 | f_marg_list
',' tSTAR
',' f_marg_list
2272 $$
= list3
($1, (node
*)-1, $5);
2276 $$
= list3
(0, new_arg
(p
, $2), 0);
2278 | tSTAR f_norm_arg
',' f_marg_list
2280 $$
= list3
(0, new_arg
(p
, $2), $4);
2284 $$
= list3
(0, (node
*)-1, 0);
2286 | tSTAR
',' f_marg_list
2288 $$
= list3
(0, (node
*)-1, $3);
2292 block_param
: f_arg
',' f_block_optarg
',' f_rest_arg opt_f_block_arg
2294 $$
= new_args
(p
, $1, $3, $5, 0, $6);
2296 | f_arg
',' f_block_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
2298 $$
= new_args
(p
, $1, $3, $5, $7, $8);
2300 | f_arg
',' f_block_optarg opt_f_block_arg
2302 $$
= new_args
(p
, $1, $3, 0, 0, $4);
2304 | f_arg
',' f_block_optarg
',' f_arg opt_f_block_arg
2306 $$
= new_args
(p
, $1, $3, 0, $5, $6);
2308 | f_arg
',' f_rest_arg opt_f_block_arg
2310 $$
= new_args
(p
, $1, 0, $3, 0, $4);
2314 $$
= new_args
(p
, $1, 0, 1, 0, 0);
2316 | f_arg
',' f_rest_arg
',' f_arg opt_f_block_arg
2318 $$
= new_args
(p
, $1, 0, $3, $5, $6);
2320 | f_arg opt_f_block_arg
2322 $$
= new_args
(p
, $1, 0, 0, 0, $2);
2324 | f_block_optarg
',' f_rest_arg opt_f_block_arg
2326 $$
= new_args
(p
, 0, $1, $3, 0, $4);
2328 | f_block_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
2330 $$
= new_args
(p
, 0, $1, $3, $5, $6);
2332 | f_block_optarg opt_f_block_arg
2334 $$
= new_args
(p
, 0, $1, 0, 0, $2);
2336 | f_block_optarg
',' f_arg opt_f_block_arg
2338 $$
= new_args
(p
, 0, $1, 0, $3, $4);
2340 | f_rest_arg opt_f_block_arg
2342 $$
= new_args
(p
, 0, 0, $1, 0, $2);
2344 | f_rest_arg
',' f_arg opt_f_block_arg
2346 $$
= new_args
(p
, 0, 0, $1, $3, $4);
2350 $$
= new_args
(p
, 0, 0, 0, 0, $1);
2354 opt_block_param
: none
2357 p
->cmd_start
= TRUE
;
2362 block_param_def
: '|' opt_bv_decl
'|'
2372 |
'|' block_param opt_bv_decl
'|'
2379 opt_bv_decl
: opt_nl
2383 | opt_nl
';' bv_decls opt_nl
2401 f_larglist
: '(' f_args opt_bv_decl
')'
2411 lambda_body
: tLAMBEG compstmt
'}'
2415 | keyword_do_LAMBDA compstmt keyword_end
2421 do_block
: keyword_do_block
2429 $$
= new_block
(p
,$3,$4);
2434 block_call
: command do_block
2436 if
($1->car
== (node
*)NODE_YIELD
) {
2437 yyerror(p
, "block given to yield");
2440 call_with_block
(p
, $1, $2);
2444 | block_call dot_or_colon operation2 opt_paren_args
2446 $$
= new_call
(p
, $1, $3, $4);
2448 | block_call dot_or_colon operation2 opt_paren_args brace_block
2450 $$
= new_call
(p
, $1, $3, $4);
2451 call_with_block
(p
, $$
, $5);
2453 | block_call dot_or_colon operation2 command_args do_block
2455 $$
= new_call
(p
, $1, $3, $4);
2456 call_with_block
(p
, $$
, $5);
2460 method_call
: operation paren_args
2462 $$
= new_fcall
(p
, $1, $2);
2464 | primary_value
'.' operation2 opt_paren_args
2466 $$
= new_call
(p
, $1, $3, $4);
2468 | primary_value tCOLON2 operation2 paren_args
2470 $$
= new_call
(p
, $1, $3, $4);
2472 | primary_value tCOLON2 operation3
2474 $$
= new_call
(p
, $1, $3, 0);
2476 | primary_value
'.' paren_args
2478 $$
= new_call
(p
, $1, intern2
("call",4), $3);
2480 | primary_value tCOLON2 paren_args
2482 $$
= new_call
(p
, $1, intern2
("call",4), $3);
2484 | keyword_super paren_args
2486 $$
= new_super
(p
, $2);
2492 | primary_value
'[' opt_call_args rbracket
2494 $$
= new_call
(p
, $1, intern2
("[]",2), $3);
2505 $$
= new_block
(p
,$3,$4);
2513 compstmt keyword_end
2515 $$
= new_block
(p
,$3,$4);
2520 case_body
: keyword_when args then
2524 $$
= cons
(cons
($2, $4), $5);
2531 $$
= cons
(cons
(0, $1), 0);
2540 opt_rescue
: keyword_rescue exc_list exc_var then
2544 $$
= list1
(list3
($2, $3, $5));
2545 if
($6) $$
= append
($$
, $6);
2550 exc_list
: arg_value
2558 exc_var
: tASSOC lhs
2565 opt_ensure
: keyword_ensure compstmt
2580 | tSTRING_BEG tSTRING
2584 | tSTRING_BEG string_rep tSTRING
2586 $$
= new_dstr
(p
, push
($2, $3));
2590 string_rep
: string_interp
2591 | string_rep string_interp
2593 $$
= append
($1, $2);
2597 string_interp
: tSTRING_MID
2603 $
<nd
>$
= p
->lex_strterm
;
2604 p
->lex_strterm
= NULL
;
2609 p
->lex_strterm
= $
<nd
>2;
2614 $$
= list1
(new_literal_delim
(p
));
2618 xstring
: tXSTRING_BEG tXSTRING
2622 | tXSTRING_BEG string_rep tXSTRING
2624 $$
= new_dxstr
(p
, push
($2, $3));
2628 regexp
: tREGEXP_BEG tREGEXP
2632 | tREGEXP_BEG string_rep tREGEXP
2634 $$
= new_dregx
(p
, $2, $3);
2638 heredoc
: tHEREDOC_BEG
2641 opt_heredoc_bodies
: none
2645 heredoc_bodies
: heredoc_body
2646 | heredoc_bodies heredoc_body
2649 heredoc_body
: tHEREDOC_END
2651 parsing_heredoc_inf
(p
)->doc
= list1
(new_str
(p
, "", 0));
2654 | string_rep tHEREDOC_END
2656 parsing_heredoc_inf
(p
)->doc
= $1;
2661 words
: tWORDS_BEG tSTRING
2663 $$
= new_words
(p
, list1
($2));
2665 | tWORDS_BEG string_rep tSTRING
2667 $$
= new_words
(p
, push
($2, $3));
2672 symbol
: basic_symbol
2674 $$
= new_sym
(p
, $1);
2676 | tSYMBEG tSTRING_BEG string_interp tSTRING
2678 p
->lstate
= EXPR_END
;
2679 $$
= new_dsym
(p
, push
($3, $4));
2683 basic_symbol
: tSYMBEG sym
2685 p
->lstate
= EXPR_END
;
2696 $$
= new_strsym
(p
, $1);
2698 | tSTRING_BEG tSTRING
2700 $$
= new_strsym
(p
, $2);
2704 symbols
: tSYMBOLS_BEG tSTRING
2706 $$
= new_symbols
(p
, list1
($2));
2708 | tSYMBOLS_BEG string_rep tSTRING
2710 $$
= new_symbols
(p
, push
($2, $3));
2716 | tUMINUS_NUM tINTEGER %prec tLOWEST
2718 $$
= negate_lit
(p
, $2);
2720 | tUMINUS_NUM tFLOAT %prec tLOWEST
2722 $$
= negate_lit
(p
, $2);
2726 variable
: tIDENTIFIER
2728 $$
= new_lvar
(p
, $1);
2732 $$
= new_ivar
(p
, $1);
2736 $$
= new_gvar
(p
, $1);
2740 $$
= new_cvar
(p
, $1);
2744 $$
= new_const
(p
, $1);
2756 $$
= var_reference
(p
, $1);
2777 p
->filename
= "(null)";
2779 $$
= new_str
(p
, p
->filename
, strlen
(p
->filename
));
2785 snprintf
(buf
, sizeof
(buf
), "%d", p
->lineno
);
2786 $$
= new_int
(p
, buf
, 10);
2800 p
->lstate
= EXPR_BEG
;
2801 p
->cmd_start
= TRUE
;
2814 f_arglist
: '(' f_args rparen
2817 p
->lstate
= EXPR_BEG
;
2818 p
->cmd_start
= TRUE
;
2826 f_args
: f_arg
',' f_optarg
',' f_rest_arg opt_f_block_arg
2828 $$
= new_args
(p
, $1, $3, $5, 0, $6);
2830 | f_arg
',' f_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
2832 $$
= new_args
(p
, $1, $3, $5, $7, $8);
2834 | f_arg
',' f_optarg opt_f_block_arg
2836 $$
= new_args
(p
, $1, $3, 0, 0, $4);
2838 | f_arg
',' f_optarg
',' f_arg opt_f_block_arg
2840 $$
= new_args
(p
, $1, $3, 0, $5, $6);
2842 | f_arg
',' f_rest_arg opt_f_block_arg
2844 $$
= new_args
(p
, $1, 0, $3, 0, $4);
2846 | f_arg
',' f_rest_arg
',' f_arg opt_f_block_arg
2848 $$
= new_args
(p
, $1, 0, $3, $5, $6);
2850 | f_arg opt_f_block_arg
2852 $$
= new_args
(p
, $1, 0, 0, 0, $2);
2854 | f_optarg
',' f_rest_arg opt_f_block_arg
2856 $$
= new_args
(p
, 0, $1, $3, 0, $4);
2858 | f_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
2860 $$
= new_args
(p
, 0, $1, $3, $5, $6);
2862 | f_optarg opt_f_block_arg
2864 $$
= new_args
(p
, 0, $1, 0, 0, $2);
2866 | f_optarg
',' f_arg opt_f_block_arg
2868 $$
= new_args
(p
, 0, $1, 0, $3, $4);
2870 | f_rest_arg opt_f_block_arg
2872 $$
= new_args
(p
, 0, 0, $1, 0, $2);
2874 | f_rest_arg
',' f_arg opt_f_block_arg
2876 $$
= new_args
(p
, 0, 0, $1, $3, $4);
2880 $$
= new_args
(p
, 0, 0, 0, 0, $1);
2885 $$
= new_args
(p
, 0, 0, 0, 0, 0);
2889 f_bad_arg
: tCONSTANT
2891 yyerror(p
, "formal argument cannot be a constant");
2896 yyerror(p
, "formal argument cannot be an instance variable");
2901 yyerror(p
, "formal argument cannot be a global variable");
2906 yyerror(p
, "formal argument cannot be a class variable");
2911 f_norm_arg
: f_bad_arg
2922 f_arg_item
: f_norm_arg
2924 $$
= new_arg
(p
, $1);
2926 | tLPAREN f_margs rparen
2928 $$
= new_masgn
(p
, $2, 0);
2936 | f_arg
',' f_arg_item
2942 f_opt
: tIDENTIFIER
'=' arg_value
2945 $$
= cons
(nsym
($1), $3);
2949 f_block_opt
: tIDENTIFIER
'=' primary_value
2952 $$
= cons
(nsym
($1), $3);
2956 f_block_optarg
: f_block_opt
2960 | f_block_optarg
',' f_block_opt
2970 | f_optarg
',' f_opt
2980 f_rest_arg
: restarg_mark tIDENTIFIER
2996 f_block_arg
: blkarg_mark tIDENTIFIER
3003 opt_f_block_arg
: ',' f_block_arg
3017 if
(!$$
) $$
= new_nil
(p
);
3019 |
'(' {p
->lstate
= EXPR_BEG
;} expr rparen
3022 yyerror(p
, "can't define singleton method for ().");
3025 switch
((enum node_type
)(int)(intptr_t)$3->car
) {
3035 yyerror(p
, "can't define singleton method for literals");
3061 assoc
: arg_value tASSOC arg_value
3067 $$
= cons
(new_sym
(p
, $1), $2);
3071 operation
: tIDENTIFIER
3076 operation2
: tIDENTIFIER
3082 operation3
: tIDENTIFIER
3091 opt_terms
: /* none */
3102 rbracket
: opt_nl
']'
3105 trailer
: /* none */
3110 term
: ';' {yyerrok;}
3122 | terms
';' {yyerrok;}
3131 #define yylval (*((YYSTYPE*)(p->ylval)))
3134 yyerror(parser_state
*p
, const char *s
)
3139 if
(! p
->capture_errors
) {
3142 fprintf
(stderr
, "%s:%d:%d: %s\n", p
->filename
, p
->lineno
, p
->column
, s
);
3145 fprintf
(stderr
, "line %d:%d: %s\n", p
->lineno
, p
->column
, s
);
3149 else if
(p
->nerr
< sizeof
(p
->error_buffer
) / sizeof
(p
->error_buffer
[0])) {
3151 c
= (char *)parser_palloc
(p
, n
+ 1);
3152 memcpy
(c
, s
, n
+ 1);
3153 p
->error_buffer
[p
->nerr
].message
= c
;
3154 p
->error_buffer
[p
->nerr
].lineno
= p
->lineno
;
3155 p
->error_buffer
[p
->nerr
].column
= p
->column
;
3161 yyerror_i
(parser_state
*p
, const char *fmt
, int i
)
3165 snprintf
(buf
, sizeof
(buf
), fmt
, i
);
3170 yywarn
(parser_state
*p
, const char *s
)
3175 if
(! p
->capture_errors
) {
3178 fprintf
(stderr
, "%s:%d:%d: %s\n", p
->filename
, p
->lineno
, p
->column
, s
);
3181 fprintf
(stderr
, "line %d:%d: %s\n", p
->lineno
, p
->column
, s
);
3185 else if
(p
->nwarn
< sizeof
(p
->warn_buffer
) / sizeof
(p
->warn_buffer
[0])) {
3187 c
= (char *)parser_palloc
(p
, n
+ 1);
3188 memcpy
(c
, s
, n
+ 1);
3189 p
->warn_buffer
[p
->nwarn
].message
= c
;
3190 p
->warn_buffer
[p
->nwarn
].lineno
= p
->lineno
;
3191 p
->warn_buffer
[p
->nwarn
].column
= p
->column
;
3197 yywarning
(parser_state
*p
, const char *s
)
3203 yywarning_s
(parser_state
*p
, const char *fmt
, const char *s
)
3207 snprintf
(buf
, sizeof
(buf
), fmt
, s
);
3212 backref_error
(parser_state
*p
, node
*n
)
3216 c
= (int)(intptr_t)n
->car
;
3218 if
(c
== NODE_NTH_REF
) {
3219 yyerror_i
(p
, "can't set variable $%d", (int)(intptr_t)n
->cdr
);
3220 } else if
(c
== NODE_BACK_REF
) {
3221 yyerror_i
(p
, "can't set variable $%c", (int)(intptr_t)n
->cdr
);
3223 mrb_bug
("Internal error in backref_error() : n=>car == %d", c
);
3227 static int peeks
(parser_state
*p
, const char *s
);
3228 static int skips
(parser_state
*p
, const char *s
);
3231 nextc
(parser_state
*p
)
3238 c
= (int)(intptr_t)p
->pb
->car
;
3245 if
(feof
(p
->f
)) return
-1;
3247 if
(c
== EOF
) return
-1;
3249 else if
(!p
->s || p
->s
>= p
->send
) {
3253 c
= (unsigned char)*p
->s
++;
3261 pushback
(parser_state
*p
, int c
)
3265 p
->pb
= cons
((node
*)(intptr_t)c
, p
->pb
);
3269 skip
(parser_state
*p
, char term
)
3276 if
(c
== term
) break
;
3281 peek_n
(parser_state
*p
, int c
, int n
)
3288 if
(c0
< 0) return FALSE
;
3289 list
= push
(list
, (node
*)(intptr_t)c0
);
3292 p
->pb
= push
(p
->pb
, (node
*)list
);
3297 if
(c0
== c
) return TRUE
;
3300 #define peek(p,c) peek_n((p), (c), 0)
3303 peeks
(parser_state
*p
, const char *s
)
3305 int len
= strlen
(s
);
3310 if
(!peek_n
(p
, *s
++, n
++)) return FALSE
;
3314 else if
(p
->s
&& p
->s
+ len
>= p
->send
) {
3315 if
(memcmp
(p
->s
, s
, len
) == 0) return TRUE
;
3321 skips
(parser_state
*p
, const char *s
)
3326 // skip until first char
3329 if
(c
< 0) return c
;
3334 int len
= strlen
(s
);
3350 newtok
(parser_state
*p
)
3353 return p
->column
- 1;
3357 tokadd
(parser_state
*p
, int c
)
3359 if
(p
->bidx
< MRB_PARSER_BUF_SIZE
) {
3360 p
->buf
[p
->bidx
++] = c
;
3365 toklast
(parser_state
*p
)
3367 return p
->buf
[p
->bidx
-1];
3371 tokfix
(parser_state
*p
)
3373 if
(p
->bidx
>= MRB_PARSER_BUF_SIZE
) {
3374 yyerror(p
, "string too long (truncated)");
3376 p
->buf
[p
->bidx
] = '\0';
3380 tok
(parser_state
*p
)
3386 toklen
(parser_state
*p
)
3391 #define IS_ARG() (p->lstate == EXPR_ARG || p->lstate == EXPR_CMDARG)
3392 #define IS_END() (p->lstate == EXPR_END || p->lstate == EXPR_ENDARG || p->lstate == EXPR_ENDFN)
3393 #define IS_BEG() (p->lstate == EXPR_BEG || p->lstate == EXPR_MID || p->lstate == EXPR_VALUE || p->lstate == EXPR_CLASS)
3394 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
3395 #define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG())
3396 #define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
3399 scan_oct
(const int *start
, int len
, int *retlen
)
3401 const int *s
= start
;
3404 /* assert(len <= 3) */
3405 while
(len
-- && *s
>= '0' && *s
<= '7') {
3407 retval |
= *s
++ - '0';
3409 *retlen
= s
- start
;
3415 scan_hex
(const int *start
, int len
, int *retlen
)
3417 static const char hexdigit
[] = "0123456789abcdef0123456789ABCDEF";
3418 register
const int *s
= start
;
3419 register
int retval
= 0;
3422 /* assert(len <= 2) */
3423 while
(len
-- && *s
&& (tmp
= strchr
(hexdigit
, *s
))) {
3425 retval |
= (tmp
- hexdigit
) & 15;
3428 *retlen
= s
- start
;
3434 read_escape
(parser_state
*p
)
3438 switch
(c
= nextc
(p
)) {
3439 case
'\\': /* Backslash */
3442 case
'n': /* newline */
3445 case
't': /* horizontal tab */
3448 case
'r': /* carriage-return */
3451 case
'f': /* form-feed */
3454 case
'v': /* vertical tab */
3457 case
'a': /* alarm(bell) */
3460 case
'e': /* escape */
3463 case
'0': case
'1': case
'2': case
'3': /* octal constant */
3464 case
'4': case
'5': case
'6': case
'7':
3470 for
(i
=1; i
<3; i
++) {
3472 if
(buf
[i
] == -1) goto eof
;
3473 if
(buf
[i
] < '0' ||
'7' < buf
[i
]) {
3474 pushback
(p
, buf
[i
]);
3478 c
= scan_oct
(buf
, i
, &i
);
3482 case
'x': /* hex constant */
3487 for
(i
=0; i
<2; i
++) {
3489 if
(buf
[i
] == -1) goto eof
;
3490 if
(!isxdigit
(buf
[i
])) {
3491 pushback
(p
, buf
[i
]);
3495 c
= scan_hex
(buf
, i
, &i
);
3497 yyerror(p
, "Invalid escape character syntax");
3503 case
'b': /* backspace */
3506 case
's': /* space */
3510 if
((c
= nextc
(p
)) != '-') {
3511 yyerror(p
, "Invalid escape character syntax");
3515 if
((c
= nextc
(p
)) == '\\') {
3516 return read_escape
(p
) |
0x80;
3518 else if
(c
== -1) goto eof
;
3520 return
((c
& 0xff) |
0x80);
3524 if
((c
= nextc
(p
)) != '-') {
3525 yyerror(p
, "Invalid escape character syntax");
3530 if
((c
= nextc
(p
))== '\\') {
3535 else if
(c
== -1) goto eof
;
3540 yyerror(p
, "Invalid escape character syntax");
3550 parse_string
(parser_state
*p
)
3553 string_type type
= (string_type
)(intptr_t)p
->lex_strterm
->car
;
3554 int nest_level
= (intptr_t)p
->lex_strterm
->cdr
->car
;
3555 int beg
= (intptr_t)p
->lex_strterm
->cdr
->cdr
->car
;
3556 int end
= (intptr_t)p
->lex_strterm
->cdr
->cdr
->cdr
;
3557 parser_heredoc_info
*hinf
= (type
& STR_FUNC_HEREDOC
) ? parsing_heredoc_inf
(p
) : NULL
;
3560 while
((c
= nextc
(p
)) != end || nest_level
!= 0) {
3561 if
(hinf
&& (c
== '\n' || c
== -1)) {
3567 line_head
= hinf
->line_head
;
3568 hinf
->line_head
= TRUE
;
3570 /* check whether end of heredoc */
3571 const char *s
= tok
(p
);
3572 int len
= toklen
(p
);
3573 if
(hinf
->allow_indent
) {
3574 while
(ISSPACE
(*s
) && len
> 0) {
3579 if
((len
-1 == hinf
->term_len
) && (strncmp
(s
, hinf
->term
, len
-1) == 0)) {
3580 return tHEREDOC_END
;
3585 snprintf
(buf
, sizeof
(buf
), "can't find string \"%s\" anywhere before EOF", hinf
->term
);
3589 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
3593 yyerror(p
, "unterminated string meets end of file");
3596 else if
(c
== beg
) {
3598 p
->lex_strterm
->cdr
->car
= (node
*)(intptr_t)nest_level
;
3600 else if
(c
== end
) {
3602 p
->lex_strterm
->cdr
->car
= (node
*)(intptr_t)nest_level
;
3604 else if
(c
== '\\') {
3606 if
(type
& STR_FUNC_EXPAND
) {
3607 if
(c
== end || c
== beg
) {
3610 else if
((c
== '\n') && (type
& STR_FUNC_ARRAY
)) {
3618 if
(type
& STR_FUNC_REGEXP
)
3621 tokadd
(p
, read_escape
(p
));
3623 hinf
->line_head
= FALSE
;
3626 if
(c
!= beg
&& c
!= end
) {
3645 else if
((c
== '#') && (type
& STR_FUNC_EXPAND
)) {
3649 p
->lstate
= EXPR_BEG
;
3650 p
->cmd_start
= TRUE
;
3651 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
3653 hinf
->line_head
= FALSE
;
3654 return tSTRING_PART
;
3660 if
((type
& STR_FUNC_ARRAY
) && ISSPACE
(c
)) {
3661 if
(toklen
(p
) == 0) {
3667 } while
(ISSPACE
(c
= nextc
(p
)));
3669 return tLITERAL_DELIM
;
3673 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
3683 p
->lstate
= EXPR_END
;
3686 if
(type
& STR_FUNC_XQUOTE
) {
3687 yylval.nd
= new_xstr
(p
, tok
(p
), toklen
(p
));
3691 if
(type
& STR_FUNC_REGEXP
) {
3694 char *s
= strndup
(tok
(p
), toklen
(p
));
3695 char flag
[4] = { '\0' };
3698 while
(c
= nextc
(p
), ISALPHA
(c
)) {
3700 case
'i': f |
= 1; break
;
3701 case
'x': f |
= 2; break
;
3702 case
'm': f |
= 4; break
;
3703 default
: tokadd
(p
, c
); break
;
3710 snprintf
(msg
, sizeof
(msg
), "unknown regexp option%s - %s",
3711 toklen
(p
) > 1 ?
"s" : "", tok
(p
));
3714 if
(f
& 1) strcat
(flag
, "i");
3715 if
(f
& 2) strcat
(flag
, "x");
3716 if
(f
& 4) strcat
(flag
, "m");
3717 yylval.nd
= new_regx
(p
, s
, strdup
(flag
));
3722 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
3728 heredoc_identifier
(parser_state
*p
)
3731 int type
= str_heredoc
;
3735 parser_heredoc_info
*info
;
3738 if
(ISSPACE
(c
) || c
== '=') {
3746 if
(c
== '\'' || c
== '"') {
3751 while
((c
= nextc
(p
)) != -1 && c
!= term
) {
3759 yyerror(p
, "unterminated here document identifier");
3763 if
(! identchar
(c
)) {
3765 if
(indent
) pushback
(p
, '-');
3771 } while
((c
= nextc
(p
)) != -1 && identchar
(c
));
3775 newnode
= new_heredoc
(p
);
3776 info
= (parser_heredoc_info
*)newnode
->cdr
;
3777 info
->term
= strndup
(tok
(p
), toklen
(p
));
3778 info
->term_len
= toklen
(p
);
3780 type |
= STR_FUNC_EXPAND
;
3782 info
->allow_indent
= indent
;
3783 info
->line_head
= TRUE
;
3785 p
->heredocs
= push
(p
->heredocs
, newnode
);
3786 if
(p
->parsing_heredoc
== NULL
) {
3787 node
*n
= p
->heredocs
;
3790 p
->parsing_heredoc
= n
;
3792 p
->heredoc_starts_nextline
= TRUE
;
3793 p
->lstate
= EXPR_END
;
3795 yylval.nd
= newnode
;
3796 return tHEREDOC_BEG
;
3800 arg_ambiguous
(parser_state
*p
)
3802 yywarning
(p
, "ambiguous first argument; put parentheses or even spaces");
3809 parser_yylex
(parser_state
*p
)
3814 enum mrb_lex_state_enum last_state
;
3817 if
(p
->lex_strterm
) {
3818 if
(is_strterm_type
(p
, STR_FUNC_HEREDOC
)) {
3819 if
((p
->parsing_heredoc
!= NULL
) && (! p
->heredoc_starts_nextline
))
3820 return parse_string
(p
);
3823 return parse_string
(p
);
3825 cmd_state
= p
->cmd_start
;
3826 p
->cmd_start
= FALSE
;
3828 last_state
= p
->lstate
;
3829 switch
(c
= nextc
(p
)) {
3830 case
'\0': /* NUL */
3831 case
'\004': /* ^D */
3832 case
'\032': /* ^Z */
3833 case
-1: /* end of script. */
3837 case
' ': case
'\t': case
'\f': case
'\r':
3838 case
'\13': /* '\v' */
3842 case
'#': /* it's a comment */
3846 p
->heredoc_starts_nextline
= FALSE
;
3847 if
(p
->parsing_heredoc
!= NULL
) {
3848 p
->lex_strterm
= new_strterm
(p
, parsing_heredoc_inf
(p
)->type
, 0, 0);
3849 goto normal_newline
;
3851 switch
(p
->lstate
) {
3863 while
((c
= nextc
(p
))) {
3865 case
' ': case
'\t': case
'\f': case
'\r':
3866 case
'\13': /* '\v' */
3870 if
((c
= nextc
(p
)) != '.') {
3876 goto normal_newline
;
3879 goto normal_newline
;
3883 p
->cmd_start
= TRUE
;
3884 p
->lstate
= EXPR_BEG
;
3888 if
((c
= nextc
(p
)) == '*') {
3889 if
((c
= nextc
(p
)) == '=') {
3890 yylval.id
= intern2
("**",2);
3891 p
->lstate
= EXPR_BEG
;
3899 yylval.id
= intern_c
('*');
3900 p
->lstate
= EXPR_BEG
;
3905 yywarning
(p
, "`*' interpreted as argument prefix");
3908 else if
(IS_BEG
()) {
3915 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3916 p
->lstate
= EXPR_ARG
;
3918 p
->lstate
= EXPR_BEG
;
3924 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3925 p
->lstate
= EXPR_ARG
;
3931 p
->lstate
= EXPR_BEG
;
3943 if
(p
->column
== 1) {
3944 if
(peeks
(p
, "begin\n")) {
3945 skips
(p
, "\n=end\n");
3949 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3950 p
->lstate
= EXPR_ARG
;
3952 p
->lstate
= EXPR_BEG
;
3954 if
((c
= nextc
(p
)) == '=') {
3955 if
((c
= nextc
(p
)) == '=') {
3964 else if
(c
== '>') {
3971 last_state
= p
->lstate
;
3974 p
->lstate
!= EXPR_DOT
&&
3975 p
->lstate
!= EXPR_CLASS
&&
3977 (!IS_ARG
() || space_seen
)) {
3978 int token
= heredoc_identifier
(p
);
3982 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3983 p
->lstate
= EXPR_ARG
;
3985 p
->lstate
= EXPR_BEG
;
3986 if
(p
->lstate
== EXPR_CLASS
) {
3987 p
->cmd_start
= TRUE
;
3991 if
((c
= nextc
(p
)) == '>') {
3998 if
((c
= nextc
(p
)) == '=') {
3999 yylval.id
= intern2
("<<",2);
4000 p
->lstate
= EXPR_BEG
;
4010 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4011 p
->lstate
= EXPR_ARG
;
4013 p
->lstate
= EXPR_BEG
;
4015 if
((c
= nextc
(p
)) == '=') {
4019 if
((c
= nextc
(p
)) == '=') {
4020 yylval.id
= intern2
(">>",2);
4021 p
->lstate
= EXPR_BEG
;
4031 p
->lex_strterm
= new_strterm
(p
, str_dquote
, '"', 0);
4035 p
->lex_strterm
= new_strterm
(p
, str_squote
, '\'', 0);
4036 return parse_string
(p
);
4039 if
(p
->lstate
== EXPR_FNAME
) {
4040 p
->lstate
= EXPR_ENDFN
;
4043 if
(p
->lstate
== EXPR_DOT
) {
4045 p
->lstate
= EXPR_CMDARG
;
4047 p
->lstate
= EXPR_ARG
;
4050 p
->lex_strterm
= new_strterm
(p
, str_xquote
, '`', 0);
4051 return tXSTRING_BEG
;
4055 p
->lstate
= EXPR_VALUE
;
4060 yyerror(p
, "incomplete character syntax");
4091 snprintf
(buf
, sizeof
(buf
), "invalid character syntax; use ?\\%c", c2
);
4097 p
->lstate
= EXPR_VALUE
;
4100 token_column
= newtok
(p
);
4101 // need support UTF-8 if configured
4102 if
((isalnum
(c
) || c
== '_')) {
4105 if
((isalnum
(c2
) || c2
== '_')) {
4126 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
4127 p
->lstate
= EXPR_END
;
4131 if
((c
= nextc
(p
)) == '&') {
4132 p
->lstate
= EXPR_BEG
;
4133 if
((c
= nextc
(p
)) == '=') {
4134 yylval.id
= intern2
("&&",2);
4135 p
->lstate
= EXPR_BEG
;
4141 else if
(c
== '=') {
4142 yylval.id
= intern_c
('&');
4143 p
->lstate
= EXPR_BEG
;
4148 yywarning
(p
, "`&' interpreted as argument prefix");
4151 else if
(IS_BEG
()) {
4157 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4158 p
->lstate
= EXPR_ARG
;
4160 p
->lstate
= EXPR_BEG
;
4165 if
((c
= nextc
(p
)) == '|') {
4166 p
->lstate
= EXPR_BEG
;
4167 if
((c
= nextc
(p
)) == '=') {
4168 yylval.id
= intern2
("||",2);
4169 p
->lstate
= EXPR_BEG
;
4176 yylval.id
= intern_c
('|');
4177 p
->lstate
= EXPR_BEG
;
4180 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4181 p
->lstate
= EXPR_ARG
;
4184 p
->lstate
= EXPR_BEG
;
4191 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4192 p
->lstate
= EXPR_ARG
;
4200 yylval.id
= intern_c
('+');
4201 p
->lstate
= EXPR_BEG
;
4204 if
(IS_BEG
() ||
(IS_SPCARG
(c
) && arg_ambiguous
(p
))) {
4205 p
->lstate
= EXPR_BEG
;
4207 if
(c
!= -1 && ISDIGIT
(c
)) {
4213 p
->lstate
= EXPR_BEG
;
4219 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4220 p
->lstate
= EXPR_ARG
;
4228 yylval.id
= intern_c
('-');
4229 p
->lstate
= EXPR_BEG
;
4233 p
->lstate
= EXPR_ENDFN
;
4236 if
(IS_BEG
() ||
(IS_SPCARG
(c
) && arg_ambiguous
(p
))) {
4237 p
->lstate
= EXPR_BEG
;
4239 if
(c
!= -1 && ISDIGIT
(c
)) {
4244 p
->lstate
= EXPR_BEG
;
4249 p
->lstate
= EXPR_BEG
;
4250 if
((c
= nextc
(p
)) == '.') {
4251 if
((c
= nextc
(p
)) == '.') {
4258 if
(c
!= -1 && ISDIGIT
(c
)) {
4259 yyerror(p
, "no .<digit> floating literal anymore; put 0 before dot");
4261 p
->lstate
= EXPR_DOT
;
4265 case
'0': case
'1': case
'2': case
'3': case
'4':
4266 case
'5': case
'6': case
'7': case
'8': case
'9':
4268 int is_float
, seen_point
, seen_e
, nondigit
;
4270 is_float
= seen_point
= seen_e
= nondigit
= 0;
4271 p
->lstate
= EXPR_END
;
4272 token_column
= newtok
(p
);
4273 if
(c
== '-' || c
== '+') {
4278 #define no_digits() do {yyerror(p,"numeric literal without digits"); return 0;} while (0)
4279 int start
= toklen
(p
);
4281 if
(c
== 'x' || c
== 'X') {
4284 if
(c
!= -1 && ISXDIGIT
(c
)) {
4287 if
(nondigit
) break
;
4291 if
(!ISXDIGIT
(c
)) break
;
4293 tokadd
(p
, tolower
(c
));
4294 } while
((c
= nextc
(p
)) != -1);
4298 if
(toklen
(p
) == start
) {
4301 else if
(nondigit
) goto trailing_uc
;
4302 yylval.nd
= new_int
(p
, tok
(p
), 16);
4305 if
(c
== 'b' || c
== 'B') {
4308 if
(c
== '0' || c
== '1') {
4311 if
(nondigit
) break
;
4315 if
(c
!= '0' && c
!= '1') break
;
4318 } while
((c
= nextc
(p
)) != -1);
4322 if
(toklen
(p
) == start
) {
4325 else if
(nondigit
) goto trailing_uc
;
4326 yylval.nd
= new_int
(p
, tok
(p
), 2);
4329 if
(c
== 'd' || c
== 'D') {
4332 if
(c
!= -1 && ISDIGIT
(c
)) {
4335 if
(nondigit
) break
;
4339 if
(!ISDIGIT
(c
)) break
;
4342 } while
((c
= nextc
(p
)) != -1);
4346 if
(toklen
(p
) == start
) {
4349 else if
(nondigit
) goto trailing_uc
;
4350 yylval.nd
= new_int
(p
, tok
(p
), 10);
4357 if
(c
== 'o' || c
== 'O') {
4358 /* prefixed octal */
4360 if
(c
== -1 || c
== '_' ||
!ISDIGIT
(c
)) {
4364 if
(c
>= '0' && c
<= '7') {
4369 if
(nondigit
) break
;
4373 if
(c
< '0' || c
> '9') break
;
4374 if
(c
> '7') goto invalid_octal
;
4377 } while
((c
= nextc
(p
)) != -1);
4379 if
(toklen
(p
) > start
) {
4382 if
(nondigit
) goto trailing_uc
;
4383 yylval.nd
= new_int
(p
, tok
(p
), 8);
4391 if
(c
> '7' && c
<= '9') {
4393 yyerror(p
, "Invalid octal digit");
4395 else if
(c
== '.' || c
== 'e' || c
== 'E') {
4400 yylval.nd
= new_int
(p
, "0", 10);
4407 case
'0': case
'1': case
'2': case
'3': case
'4':
4408 case
'5': case
'6': case
'7': case
'8': case
'9':
4414 if
(nondigit
) goto trailing_uc
;
4415 if
(seen_point || seen_e
) {
4420 if
(c0
== -1 ||
!ISDIGIT
(c0
)) {
4448 if
(c
!= '-' && c
!= '+') continue
;
4453 case
'_': /* `_' in number just ignored */
4454 if
(nondigit
) goto decode_num
;
4468 yyerror_i
(p
, "trailing `%c' in number", nondigit
);
4476 d
= strtod
(tok
(p
), &endp
);
4477 if
(d
== 0 && endp
== tok
(p
)) {
4478 yywarning_s
(p
, "corrupted float value %s", tok
(p
));
4480 else if
(errno
== ERANGE
) {
4481 yywarning_s
(p
, "float %s out of range", tok
(p
));
4484 yylval.nd
= new_float
(p
, tok
(p
));
4487 yylval.nd
= new_int
(p
, tok
(p
), 10);
4498 p
->lstate
= EXPR_ENDFN
;
4500 p
->lstate
= EXPR_ENDARG
;
4506 if
(IS_BEG
() || p
->lstate
== EXPR_CLASS || IS_SPCARG
(-1)) {
4507 p
->lstate
= EXPR_BEG
;
4510 p
->lstate
= EXPR_DOT
;
4513 if
(IS_END
() || ISSPACE
(c
)) {
4515 p
->lstate
= EXPR_BEG
;
4519 p
->lstate
= EXPR_FNAME
;
4524 p
->lex_strterm
= new_strterm
(p
, str_regexp
, '/', 0);
4527 if
((c
= nextc
(p
)) == '=') {
4528 yylval.id
= intern_c
('/');
4529 p
->lstate
= EXPR_BEG
;
4534 p
->lex_strterm
= new_strterm
(p
, str_regexp
, '/', 0);
4537 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4538 p
->lstate
= EXPR_ARG
;
4540 p
->lstate
= EXPR_BEG
;
4545 if
((c
= nextc
(p
)) == '=') {
4546 yylval.id
= intern_c
('^');
4547 p
->lstate
= EXPR_BEG
;
4550 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4551 p
->lstate
= EXPR_ARG
;
4553 p
->lstate
= EXPR_BEG
;
4559 p
->lstate
= EXPR_BEG
;
4563 p
->lstate
= EXPR_BEG
;
4567 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4568 if
((c
= nextc
(p
)) != '@') {
4571 p
->lstate
= EXPR_ARG
;
4574 p
->lstate
= EXPR_BEG
;
4582 else if
(IS_SPCARG
(-1)) {
4588 p
->lstate
= EXPR_BEG
;
4593 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4594 p
->lstate
= EXPR_ARG
;
4595 if
((c
= nextc
(p
)) == ']') {
4596 if
((c
= nextc
(p
)) == '=') {
4605 else if
(IS_BEG
()) {
4608 else if
(IS_ARG
() && space_seen
) {
4611 p
->lstate
= EXPR_BEG
;
4617 if
(p
->lpar_beg
&& p
->lpar_beg
== p
->paren_nest
) {
4618 p
->lstate
= EXPR_BEG
;
4625 if
(IS_ARG
() || p
->lstate
== EXPR_END || p
->lstate
== EXPR_ENDFN
)
4626 c
= '{'; /* block (primary) */
4627 else if
(p
->lstate
== EXPR_ENDARG
)
4628 c
= tLBRACE_ARG
; /* block (expr) */
4630 c
= tLBRACE
; /* hash */
4633 p
->lstate
= EXPR_BEG
;
4642 goto retry
; /* skip \\n */
4654 if
(c
== -1 ||
!ISALNUM
(c
)) {
4660 if
(isalnum
(term
)) {
4661 yyerror(p
, "unknown type of %string");
4665 if
(c
== -1 || term
== -1) {
4666 yyerror(p
, "unterminated quoted string meets end of file");
4670 if
(term
== '(') term
= ')';
4671 else if
(term
== '[') term
= ']';
4672 else if
(term
== '{') term
= '}';
4673 else if
(term
== '<') term
= '>';
4678 p
->lex_strterm
= new_strterm
(p
, str_dquote
, term
, paren
);
4682 p
->lex_strterm
= new_strterm
(p
, str_squote
, term
, paren
);
4683 return parse_string
(p
);
4686 p
->lex_strterm
= new_strterm
(p
, str_dword
, term
, paren
);
4690 p
->lex_strterm
= new_strterm
(p
, str_sword
, term
, paren
);
4694 p
->lex_strterm
= new_strterm
(p
, str_xquote
, term
, paren
);
4695 return tXSTRING_BEG
;
4698 p
->lex_strterm
= new_strterm
(p
, str_regexp
, term
, paren
);
4702 p
->lex_strterm
= new_strterm
(p
, str_ssym
, term
, paren
);
4706 p
->lex_strterm
= new_strterm
(p
, str_dsymbols
, term
, paren
);
4707 return tSYMBOLS_BEG
;
4710 p
->lex_strterm
= new_strterm
(p
, str_ssymbols
, term
, paren
);
4711 return tSYMBOLS_BEG
;
4714 yyerror(p
, "unknown type of %string");
4718 if
((c
= nextc
(p
)) == '=') {
4719 yylval.id
= intern_c
('%');
4720 p
->lstate
= EXPR_BEG
;
4726 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4727 p
->lstate
= EXPR_ARG
;
4729 p
->lstate
= EXPR_BEG
;
4735 p
->lstate
= EXPR_END
;
4736 token_column
= newtok
(p
);
4739 case
'_': /* $_: last read line string */
4744 case
'~': /* $~: match-data */
4745 case
'*': /* $*: argv */
4746 case
'$': /* $$: pid */
4747 case
'?': /* $?: last status */
4748 case
'!': /* $!: error string */
4749 case
'@': /* $@: error position */
4750 case
'/': /* $/: input record separator */
4751 case
'\\': /* $\: output record separator */
4752 case
';': /* $;: field separator */
4753 case
',': /* $,: output field separator */
4754 case
'.': /* $.: last read line number */
4755 case
'=': /* $=: ignorecase */
4756 case
':': /* $:: load path */
4757 case
'<': /* $<: reading filename */
4758 case
'>': /* $>: default output handle */
4759 case
'\"': /* $": already loaded files */
4763 yylval.id
= intern
(tok
(p
));
4773 yylval.id
= intern
(tok
(p
));
4776 case
'&': /* $&: last match */
4777 case
'`': /* $`: string before last match */
4778 case
'\'': /* $': string after last match */
4779 case
'+': /* $+: string matches last pattern */
4780 if
(last_state
== EXPR_FNAME
) {
4785 yylval.nd
= new_back_ref
(p
, c
);
4788 case
'1': case
'2': case
'3':
4789 case
'4': case
'5': case
'6':
4790 case
'7': case
'8': case
'9':
4794 } while
(c
!= -1 && isdigit
(c
));
4796 if
(last_state
== EXPR_FNAME
) goto gvar
;
4798 yylval.nd
= new_nth_ref
(p
, atoi
(tok
(p
)));
4802 if
(!identchar
(c
)) {
4813 token_column
= newtok
(p
);
4819 if
(c
!= -1 && isdigit
(c
)) {
4821 yyerror_i
(p
, "`@%c' is not allowed as an instance variable name", c
);
4824 yyerror_i
(p
, "`@@%c' is not allowed as a class variable name", c
);
4828 if
(!identchar
(c
)) {
4835 token_column
= newtok
(p
);
4839 if
(!identchar
(c
)) {
4840 yyerror_i
(p
, "Invalid char `\\x%02X' in expression", c
);
4844 token_column
= newtok
(p
);
4852 } while
(identchar
(c
));
4853 if
(token_column
== 0 && toklen
(p
) == 7 && (c
< 0 || c
== '\n') &&
4854 strncmp
(tok
(p
), "__END__", toklen
(p
)) == 0)
4857 switch
(tok
(p
)[0]) {
4862 if
((c
== '!' || c
== '?') && !peek
(p
, '=')) {
4873 last_state
= p
->lstate
;
4874 switch
(tok
(p
)[0]) {
4876 p
->lstate
= EXPR_END
;
4880 p
->lstate
= EXPR_END
;
4881 if
(tok
(p
)[1] == '@')
4888 if
(toklast
(p
) == '!' || toklast
(p
) == '?') {
4892 if
(p
->lstate
== EXPR_FNAME
) {
4893 if
((c
= nextc
(p
)) == '=' && !peek
(p
, '~') && !peek
(p
, '>') &&
4894 (!peek
(p
, '=') ||
(peek_n
(p
, '>', 1)))) {
4895 result
= tIDENTIFIER
;
4903 if
(result
== 0 && isupper
((int)tok
(p
)[0])) {
4907 result
= tIDENTIFIER
;
4911 if
(IS_LABEL_POSSIBLE
()) {
4912 if
(IS_LABEL_SUFFIX
(0)) {
4913 p
->lstate
= EXPR_BEG
;
4916 yylval.id
= intern
(tok
(p
));
4920 if
(p
->lstate
!= EXPR_DOT
) {
4921 const struct kwtable
*kw
;
4923 /* See if it is a reserved word. */
4924 kw
= mrb_reserved_word
(tok
(p
), toklen
(p
));
4926 enum mrb_lex_state_enum state
= p
->lstate
;
4927 p
->lstate
= kw
->state
;
4928 if
(state
== EXPR_FNAME
) {
4929 yylval.id
= intern
(kw
->name
);
4932 if
(p
->lstate
== EXPR_BEG
) {
4933 p
->cmd_start
= TRUE
;
4935 if
(kw
->id
[0] == keyword_do
) {
4936 if
(p
->lpar_beg
&& p
->lpar_beg
== p
->paren_nest
) {
4939 return keyword_do_LAMBDA
;
4941 if
(COND_P
()) return keyword_do_cond
;
4942 if
(CMDARG_P
() && state
!= EXPR_CMDARG
)
4943 return keyword_do_block
;
4944 if
(state
== EXPR_ENDARG || state
== EXPR_BEG
)
4945 return keyword_do_block
;
4948 if
(state
== EXPR_BEG || state
== EXPR_VALUE
)
4951 if
(kw
->id
[0] != kw
->id
[1])
4952 p
->lstate
= EXPR_BEG
;
4958 if
(IS_BEG
() || p
->lstate
== EXPR_DOT || IS_ARG
()) {
4960 p
->lstate
= EXPR_CMDARG
;
4963 p
->lstate
= EXPR_ARG
;
4966 else if
(p
->lstate
== EXPR_FNAME
) {
4967 p
->lstate
= EXPR_ENDFN
;
4970 p
->lstate
= EXPR_END
;
4974 mrb_sym ident
= intern
(tok
(p
));
4978 if
(last_state
!= EXPR_DOT
&& islower
(tok
(p
)[0]) && lvar_defined
(ident
)) {
4979 p
->lstate
= EXPR_END
;
4988 yylex(void *lval
, parser_state
*p
)
4993 t
= parser_yylex
(p
);
4999 parser_init_cxt
(parser_state
*p
, mrbc_context
*cxt
)
5002 if
(cxt
->lineno
) p
->lineno
= cxt
->lineno
;
5003 if
(cxt
->filename
) p
->filename
= cxt
->filename
;
5007 p
->locals
= cons
(0,0);
5008 for
(i
=0; i
<cxt
->slen
; i
++) {
5009 local_add_f
(p
, cxt
->syms
[i
]);
5012 p
->capture_errors
= cxt
->capture_errors
;
5016 parser_update_cxt
(parser_state
*p
, mrbc_context
*cxt
)
5022 if
((int)(intptr_t)p
->tree
->car
!= NODE_SCOPE
) return
;
5023 n0
= n
= p
->tree
->cdr
->car
;
5028 cxt
->syms
= (mrb_sym
*)mrb_realloc
(p
->mrb
, cxt
->syms
, i
*sizeof
(mrb_sym
));
5030 for
(i
=0, n
=n0
; n
; i
++,n
=n
->cdr
) {
5031 cxt
->syms
[i
] = sym
(n
->car
);
5035 void codedump_all
(mrb_state
*, int);
5036 void parser_dump
(mrb_state
*mrb
, node
*tree
, int offset
);
5039 mrb_parser_parse
(parser_state
*p
, mrbc_context
*c
)
5041 if
(setjmp
(p
->jmp
) != 0) {
5042 yyerror(p
, "memory allocation error");
5048 p
->cmd_start
= TRUE
;
5049 p
->in_def
= p
->in_single
= FALSE
;
5050 p
->nerr
= p
->nwarn
= 0;
5051 p
->lex_strterm
= NULL
;
5053 parser_init_cxt
(p
, c
);
5056 p
->tree
= new_nil
(p
);
5058 parser_update_cxt
(p
, c
);
5059 if
(c
&& c
->dump_result
) {
5060 parser_dump
(p
->mrb
, p
->tree
, 0);
5065 mrb_parser_new
(mrb_state
*mrb
)
5069 static const parser_state parser_state_zero
= { 0 };
5071 pool
= mrb_pool_open
(mrb
);
5072 if
(!pool
) return
0;
5073 p
= (parser_state
*)mrb_pool_alloc
(pool
, sizeof
(parser_state
));
5076 *p
= parser_state_zero
;
5079 p
->in_def
= p
->in_single
= 0;
5081 p
->s
= p
->send
= NULL
;
5084 p
->cmd_start
= TRUE
;
5085 p
->in_def
= p
->in_single
= FALSE
;
5087 p
->capture_errors
= 0;
5090 #if defined(PARSER_TEST) || defined(PARSER_DEBUG)
5094 p
->lex_strterm
= NULL
;
5095 p
->heredocs
= p
->parsing_heredoc
= NULL
;
5101 mrb_parser_free
(parser_state
*p
) {
5102 mrb_pool_close
(p
->pool
);
5106 mrbc_context_new
(mrb_state
*mrb
)
5110 c
= (mrbc_context
*)mrb_calloc
(mrb
, 1, sizeof
(mrbc_context
));
5115 mrbc_context_free
(mrb_state
*mrb
, mrbc_context
*cxt
)
5117 mrb_free
(mrb
, cxt
->syms
);
5122 mrbc_filename
(mrb_state
*mrb
, mrbc_context
*c
, const char *s
)
5125 int len
= strlen
(s
);
5126 char *p
= (char *)mrb_alloca
(mrb
, len
+ 1);
5128 memcpy
(p
, s
, len
+ 1);
5136 mrb_parse_file
(mrb_state
*mrb
, FILE *f
, mrbc_context
*c
)
5140 p
= mrb_parser_new
(mrb
);
5142 p
->s
= p
->send
= NULL
;
5145 mrb_parser_parse
(p
, c
);
5150 mrb_parse_nstring
(mrb_state
*mrb
, const char *s
, int len
, mrbc_context
*c
)
5154 p
= mrb_parser_new
(mrb
);
5159 mrb_parser_parse
(p
, c
);
5164 mrb_parse_string
(mrb_state
*mrb
, const char *s
, mrbc_context
*c
)
5166 return mrb_parse_nstring
(mrb
, s
, strlen
(s
), c
);
5170 load_exec
(mrb_state
*mrb
, parser_state
*p
, mrbc_context
*c
)
5176 return mrb_undef_value
();
5178 if
(!p
->tree || p
->nerr
) {
5179 if
(p
->capture_errors
) {
5182 n
= snprintf
(buf
, sizeof
(buf
), "line %d: %s\n",
5183 p
->error_buffer
[0].lineno
, p
->error_buffer
[0].message
);
5184 mrb
->exc
= mrb_obj_ptr
(mrb_exc_new
(mrb
, E_SYNTAX_ERROR
, buf
, n
));
5186 return mrb_undef_value
();
5189 static const char msg
[] = "syntax error";
5190 mrb
->exc
= mrb_obj_ptr
(mrb_exc_new
(mrb
, E_SYNTAX_ERROR
, msg
, sizeof
(msg
) - 1));
5192 return mrb_undef_value
();
5195 n
= mrb_generate_code
(mrb
, p
);
5198 static const char msg
[] = "codegen error";
5199 mrb
->exc
= mrb_obj_ptr
(mrb_exc_new
(mrb
, E_SCRIPT_ERROR
, msg
, sizeof
(msg
) - 1));
5200 return mrb_nil_value
();
5203 if
(c
->dump_result
) codedump_all
(mrb
, n
);
5204 if
(c
->no_exec
) return mrb_fixnum_value
(n
);
5206 v
= mrb_run
(mrb
, mrb_proc_new
(mrb
, mrb
->irep
[n
]), mrb_top_self
(mrb
));
5207 if
(mrb
->exc
) return mrb_nil_value
();
5212 mrb_load_file_cxt
(mrb_state
*mrb
, FILE *f
, mrbc_context
*c
)
5214 return load_exec
(mrb
, mrb_parse_file
(mrb
, f
, c
), c
);
5218 mrb_load_file
(mrb_state
*mrb
, FILE *f
)
5220 return mrb_load_file_cxt
(mrb
, f
, NULL
);
5224 mrb_load_nstring_cxt
(mrb_state
*mrb
, const char *s
, int len
, mrbc_context
*c
)
5226 return load_exec
(mrb
, mrb_parse_nstring
(mrb
, s
, len
, c
), c
);
5230 mrb_load_nstring
(mrb_state
*mrb
, const char *s
, int len
)
5232 return mrb_load_nstring_cxt
(mrb
, s
, len
, NULL
);
5236 mrb_load_string_cxt
(mrb_state
*mrb
, const char *s
, mrbc_context
*c
)
5238 return mrb_load_nstring_cxt
(mrb
, s
, strlen
(s
), c
);
5242 mrb_load_string
(mrb_state
*mrb
, const char *s
)
5244 return mrb_load_string_cxt
(mrb
, s
, NULL
);
5250 dump_prefix
(int offset
)
5259 dump_recur
(mrb_state
*mrb
, node
*tree
, int offset
)
5262 parser_dump
(mrb
, tree
->car
, offset
);
5270 parser_dump
(mrb_state
*mrb
, node
*tree
, int offset
)
5277 dump_prefix
(offset
);
5278 n
= (int)(intptr_t)tree
->car
;
5282 printf
("NODE_BEGIN:\n");
5283 dump_recur
(mrb
, tree
, offset
+1);
5287 printf
("NODE_RESCUE:\n");
5289 dump_prefix
(offset
+1);
5291 parser_dump
(mrb
, tree
->car
, offset
+2);
5295 node
*n2
= tree
->car
;
5297 dump_prefix
(offset
+1);
5298 printf
("rescue:\n");
5302 dump_prefix
(offset
+2);
5303 printf
("handle classes:\n");
5304 dump_recur
(mrb
, n3
->car
, offset
+3);
5307 dump_prefix
(offset
+2);
5308 printf
("exc_var:\n");
5309 parser_dump
(mrb
, n3
->cdr
->car
, offset
+3);
5311 if
(n3
->cdr
->cdr
->car
) {
5312 dump_prefix
(offset
+2);
5313 printf
("rescue body:\n");
5314 parser_dump
(mrb
, n3
->cdr
->cdr
->car
, offset
+3);
5321 dump_prefix
(offset
+1);
5323 parser_dump
(mrb
, tree
->car
, offset
+2);
5328 printf
("NODE_ENSURE:\n");
5329 dump_prefix
(offset
+1);
5331 parser_dump
(mrb
, tree
->car
, offset
+2);
5332 dump_prefix
(offset
+1);
5333 printf
("ensure:\n");
5334 parser_dump
(mrb
, tree
->cdr
->cdr
, offset
+2);
5338 printf
("NODE_BLOCK:\n");
5343 printf
("NODE_BLOCK:\n");
5346 node
*n
= tree
->car
;
5349 dump_prefix
(offset
+1);
5350 printf
("mandatory args:\n");
5351 dump_recur
(mrb
, n
->car
, offset
+2);
5355 dump_prefix
(offset
+1);
5356 printf
("optional args:\n");
5361 dump_prefix
(offset
+2);
5362 printf
("%s=", mrb_sym2name
(mrb
, sym
(n2
->car
->car
)));
5363 parser_dump
(mrb
, n2
->car
->cdr
, 0);
5370 dump_prefix
(offset
+1);
5371 printf
("rest=*%s\n", mrb_sym2name
(mrb
, sym
(n
->car
)));
5375 dump_prefix
(offset
+1);
5376 printf
("post mandatory args:\n");
5377 dump_recur
(mrb
, n
->car
, offset
+2);
5381 dump_prefix
(offset
+1);
5382 printf
("blk=&%s\n", mrb_sym2name
(mrb
, sym
(n
)));
5385 dump_prefix
(offset
+1);
5387 parser_dump
(mrb
, tree
->cdr
->car
, offset
+2);
5391 printf
("NODE_IF:\n");
5392 dump_prefix
(offset
+1);
5394 parser_dump
(mrb
, tree
->car
, offset
+2);
5395 dump_prefix
(offset
+1);
5397 parser_dump
(mrb
, tree
->cdr
->car
, offset
+2);
5398 if
(tree
->cdr
->cdr
->car
) {
5399 dump_prefix
(offset
+1);
5401 parser_dump
(mrb
, tree
->cdr
->cdr
->car
, offset
+2);
5406 printf
("NODE_AND:\n");
5407 parser_dump
(mrb
, tree
->car
, offset
+1);
5408 parser_dump
(mrb
, tree
->cdr
, offset
+1);
5412 printf
("NODE_OR:\n");
5413 parser_dump
(mrb
, tree
->car
, offset
+1);
5414 parser_dump
(mrb
, tree
->cdr
, offset
+1);
5418 printf
("NODE_CASE:\n");
5420 parser_dump
(mrb
, tree
->car
, offset
+1);
5424 dump_prefix
(offset
+1);
5426 dump_recur
(mrb
, tree
->car
->car
, offset
+2);
5427 dump_prefix
(offset
+1);
5429 parser_dump
(mrb
, tree
->car
->cdr
, offset
+2);
5435 printf
("NODE_WHILE:\n");
5436 dump_prefix
(offset
+1);
5438 parser_dump
(mrb
, tree
->car
, offset
+2);
5439 dump_prefix
(offset
+1);
5441 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5445 printf
("NODE_UNTIL:\n");
5446 dump_prefix
(offset
+1);
5448 parser_dump
(mrb
, tree
->car
, offset
+2);
5449 dump_prefix
(offset
+1);
5451 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5455 printf
("NODE_FOR:\n");
5456 dump_prefix
(offset
+1);
5459 node
*n2
= tree
->car
;
5462 dump_prefix
(offset
+2);
5464 dump_recur
(mrb
, n2
->car
, offset
+3);
5469 dump_prefix
(offset
+2);
5471 parser_dump
(mrb
, n2
->car
, offset
+3);
5476 dump_prefix
(offset
+2);
5478 dump_recur
(mrb
, n2
->car
, offset
+3);
5484 dump_prefix
(offset
+1);
5486 parser_dump
(mrb
, tree
->car
, offset
+2);
5488 dump_prefix
(offset
+1);
5490 parser_dump
(mrb
, tree
->car
, offset
+2);
5494 printf
("NODE_SCOPE:\n");
5496 node
*n2
= tree
->car
;
5498 if
(n2
&& (n2
->car || n2
->cdr
)) {
5499 dump_prefix
(offset
+1);
5500 printf
("local variables:\n");
5501 dump_prefix
(offset
+2);
5504 if
(n2
!= tree
->car
) printf
(", ");
5505 printf
("%s", mrb_sym2name
(mrb
, sym
(n2
->car
)));
5518 printf
("NODE_CALL:\n");
5519 parser_dump
(mrb
, tree
->car
, offset
+1);
5520 dump_prefix
(offset
+1);
5521 printf
("method='%s' (%d)\n",
5522 mrb_sym2name
(mrb
, sym
(tree
->cdr
->car
)),
5523 (int)(intptr_t)tree
->cdr
->car
);
5524 tree
= tree
->cdr
->cdr
->car
;
5526 dump_prefix
(offset
+1);
5528 dump_recur
(mrb
, tree
->car
, offset
+2);
5530 dump_prefix
(offset
+1);
5532 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5538 printf
("NODE_DOT2:\n");
5539 parser_dump
(mrb
, tree
->car
, offset
+1);
5540 parser_dump
(mrb
, tree
->cdr
, offset
+1);
5544 printf
("NODE_DOT3:\n");
5545 parser_dump
(mrb
, tree
->car
, offset
+1);
5546 parser_dump
(mrb
, tree
->cdr
, offset
+1);
5550 printf
("NODE_COLON2:\n");
5551 parser_dump
(mrb
, tree
->car
, offset
+1);
5552 dump_prefix
(offset
+1);
5553 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->cdr
)));
5557 printf
("NODE_COLON3:\n");
5558 dump_prefix
(offset
+1);
5559 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5563 printf
("NODE_ARRAY:\n");
5564 dump_recur
(mrb
, tree
, offset
+1);
5568 printf
("NODE_HASH:\n");
5570 dump_prefix
(offset
+1);
5572 parser_dump
(mrb
, tree
->car
->car
, offset
+2);
5573 dump_prefix
(offset
+1);
5575 parser_dump
(mrb
, tree
->car
->cdr
, offset
+2);
5581 printf
("NODE_SPLAT:\n");
5582 parser_dump
(mrb
, tree
, offset
+1);
5586 printf
("NODE_ASGN:\n");
5587 dump_prefix
(offset
+1);
5589 parser_dump
(mrb
, tree
->car
, offset
+2);
5590 dump_prefix
(offset
+1);
5592 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5596 printf
("NODE_MASGN:\n");
5597 dump_prefix
(offset
+1);
5600 node
*n2
= tree
->car
;
5603 dump_prefix
(offset
+2);
5605 dump_recur
(mrb
, n2
->car
, offset
+3);
5610 dump_prefix
(offset
+2);
5612 if
(n2
->car
== (node
*)-1) {
5613 dump_prefix
(offset
+2);
5614 printf
("(empty)\n");
5617 parser_dump
(mrb
, n2
->car
, offset
+3);
5623 dump_prefix
(offset
+2);
5625 dump_recur
(mrb
, n2
->car
, offset
+3);
5630 dump_prefix
(offset
+1);
5632 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5636 printf
("NODE_OP_ASGN:\n");
5637 dump_prefix
(offset
+1);
5639 parser_dump
(mrb
, tree
->car
, offset
+2);
5641 dump_prefix
(offset
+1);
5642 printf
("op='%s' (%d)\n", mrb_sym2name
(mrb
, sym
(tree
->car
)), (int)(intptr_t)tree
->car
);
5644 parser_dump
(mrb
, tree
->car
, offset
+1);
5648 printf
("NODE_SUPER:\n");
5650 dump_prefix
(offset
+1);
5652 dump_recur
(mrb
, tree
->car
, offset
+2);
5654 dump_prefix
(offset
+1);
5656 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5662 printf
("NODE_ZSUPER\n");
5666 printf
("NODE_RETURN:\n");
5667 parser_dump
(mrb
, tree
, offset
+1);
5671 printf
("NODE_YIELD:\n");
5672 dump_recur
(mrb
, tree
, offset
+1);
5676 printf
("NODE_BREAK:\n");
5677 parser_dump
(mrb
, tree
, offset
+1);
5681 printf
("NODE_NEXT:\n");
5682 parser_dump
(mrb
, tree
, offset
+1);
5686 printf
("NODE_REDO\n");
5690 printf
("NODE_RETRY\n");
5694 printf
("NODE_LVAR %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5698 printf
("NODE_GVAR %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5702 printf
("NODE_IVAR %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5706 printf
("NODE_CVAR %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5710 printf
("NODE_CONST %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5714 printf
("NODE_MATCH:\n");
5715 dump_prefix
(offset
+ 1);
5717 parser_dump
(mrb
, tree
->car
, offset
+ 2);
5718 dump_prefix
(offset
+ 1);
5720 parser_dump
(mrb
, tree
->cdr
, offset
+ 2);
5724 printf
("NODE_BACK_REF: $%c\n", (int)(intptr_t)tree
);
5728 printf
("NODE_NTH_REF: $%d\n", (int)(intptr_t)tree
);
5732 printf
("NODE_ARG %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5735 case NODE_BLOCK_ARG
:
5736 printf
("NODE_BLOCK_ARG:\n");
5737 parser_dump
(mrb
, tree
, offset
+1);
5741 printf
("NODE_INT %s base %d\n", (char*)tree
->car
, (int)(intptr_t)tree
->cdr
->car
);
5745 printf
("NODE_FLOAT %s\n", (char*)tree
);
5749 printf
("NODE_NEGATE\n");
5750 parser_dump
(mrb
, tree
, offset
+1);
5754 printf
("NODE_STR \"%s\" len %d\n", (char*)tree
->car
, (int)(intptr_t)tree
->cdr
);
5758 printf
("NODE_DSTR\n");
5759 dump_recur
(mrb
, tree
, offset
+1);
5763 printf
("NODE_XSTR \"%s\" len %d\n", (char*)tree
->car
, (int)(intptr_t)tree
->cdr
);
5767 printf
("NODE_DXSTR\n");
5768 dump_recur
(mrb
, tree
, offset
+1);
5772 printf
("NODE_REGX /%s/%s\n", (char*)tree
->car
, (char*)tree
->cdr
);
5776 printf
("NODE_DREGX\n");
5777 dump_recur
(mrb
, tree
->car
, offset
+1);
5778 dump_prefix
(offset
);
5779 printf
("tail: %s\n", (char*)tree
->cdr
->cdr
->car
);
5780 dump_prefix
(offset
);
5781 printf
("opt: %s\n", (char*)tree
->cdr
->cdr
->cdr
);
5785 printf
("NODE_SYM :%s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5789 printf
("NODE_SELF\n");
5793 printf
("NODE_NIL\n");
5797 printf
("NODE_TRUE\n");
5801 printf
("NODE_FALSE\n");
5805 printf
("NODE_ALIAS %s %s:\n",
5806 mrb_sym2name
(mrb
, sym
(tree
->car
)),
5807 mrb_sym2name
(mrb
, sym
(tree
->cdr
)));
5811 printf
("NODE_UNDEF");
5815 printf
(" %s", mrb_sym2name
(mrb
, sym
(t
->car
)));
5823 printf
("NODE_CLASS:\n");
5824 if
(tree
->car
->car
== (node
*)0) {
5825 dump_prefix
(offset
+1);
5826 printf
(":%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5828 else if
(tree
->car
->car
== (node
*)1) {
5829 dump_prefix
(offset
+1);
5830 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5833 parser_dump
(mrb
, tree
->car
->car
, offset
+1);
5834 dump_prefix
(offset
+1);
5835 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5837 if
(tree
->cdr
->car
) {
5838 dump_prefix
(offset
+1);
5840 parser_dump
(mrb
, tree
->cdr
->car
, offset
+2);
5842 dump_prefix
(offset
+1);
5844 parser_dump
(mrb
, tree
->cdr
->cdr
->car
->cdr
, offset
+2);
5848 printf
("NODE_MODULE:\n");
5849 if
(tree
->car
->car
== (node
*)0) {
5850 dump_prefix
(offset
+1);
5851 printf
(":%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5853 else if
(tree
->car
->car
== (node
*)1) {
5854 dump_prefix
(offset
+1);
5855 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5858 parser_dump
(mrb
, tree
->car
->car
, offset
+1);
5859 dump_prefix
(offset
+1);
5860 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5862 dump_prefix
(offset
+1);
5864 parser_dump
(mrb
, tree
->cdr
->car
->cdr
, offset
+2);
5868 printf
("NODE_SCLASS:\n");
5869 parser_dump
(mrb
, tree
->car
, offset
+1);
5870 dump_prefix
(offset
+1);
5872 parser_dump
(mrb
, tree
->cdr
->car
->cdr
, offset
+2);
5876 printf
("NODE_DEF:\n");
5877 dump_prefix
(offset
+1);
5878 printf
("%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
)));
5881 node
*n2
= tree
->car
;
5883 if
(n2
&& (n2
->car || n2
->cdr
)) {
5884 dump_prefix
(offset
+1);
5885 printf
("local variables:\n");
5886 dump_prefix
(offset
+2);
5889 if
(n2
!= tree
->car
) printf
(", ");
5890 printf
("%s", mrb_sym2name
(mrb
, sym
(n2
->car
)));
5899 node
*n
= tree
->car
;
5902 dump_prefix
(offset
+1);
5903 printf
("mandatory args:\n");
5904 dump_recur
(mrb
, n
->car
, offset
+2);
5908 dump_prefix
(offset
+1);
5909 printf
("optional args:\n");
5914 dump_prefix
(offset
+2);
5915 printf
("%s=", mrb_sym2name
(mrb
, sym
(n2
->car
->car
)));
5916 parser_dump
(mrb
, n2
->car
->cdr
, 0);
5923 dump_prefix
(offset
+1);
5924 printf
("rest=*%s\n", mrb_sym2name
(mrb
, sym
(n
->car
)));
5928 dump_prefix
(offset
+1);
5929 printf
("post mandatory args:\n");
5930 dump_recur
(mrb
, n
->car
, offset
+2);
5934 dump_prefix
(offset
+1);
5935 printf
("blk=&%s\n", mrb_sym2name
(mrb
, sym
(n
)));
5938 parser_dump
(mrb
, tree
->cdr
->car
, offset
+1);
5942 printf
("NODE_SDEF:\n");
5943 parser_dump
(mrb
, tree
->car
, offset
+1);
5945 dump_prefix
(offset
+1);
5946 printf
(":%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
)));
5947 tree
= tree
->cdr
->cdr
;
5949 node
*n
= tree
->car
;
5952 dump_prefix
(offset
+1);
5953 printf
("mandatory args:\n");
5954 dump_recur
(mrb
, n
->car
, offset
+2);
5958 dump_prefix
(offset
+1);
5959 printf
("optional args:\n");
5964 dump_prefix
(offset
+2);
5965 printf
("%s=", mrb_sym2name
(mrb
, sym
(n2
->car
->car
)));
5966 parser_dump
(mrb
, n2
->car
->cdr
, 0);
5973 dump_prefix
(offset
+1);
5974 printf
("rest=*%s\n", mrb_sym2name
(mrb
, sym
(n
->car
)));
5978 dump_prefix
(offset
+1);
5979 printf
("post mandatory args:\n");
5980 dump_recur
(mrb
, n
->car
, offset
+2);
5984 dump_prefix
(offset
+1);
5985 printf
("blk=&%s\n", mrb_sym2name
(mrb
, sym
(n
)));
5989 parser_dump
(mrb
, tree
->car
, offset
+1);
5993 printf
("NODE_POSTEXE:\n");
5994 parser_dump
(mrb
, tree
, offset
+1);
5998 printf
("NODE_HEREDOC:\n");
5999 parser_dump
(mrb
, ((parser_heredoc_info
*)tree
)->doc
, offset
+1);
6003 printf
("node type: %d (0x%x)\n", (int)n
, (int)n
);