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 cons_free_gen
(parser_state
*p
, node
*cons
)
77 #define cons_free(c) cons_free_gen(p, (c))
80 parser_palloc
(parser_state
*p
, size_t size
)
82 void *m
= mrb_pool_alloc
(p
->pool
, size
);
91 cons_gen
(parser_state
*p
, node
*car
, node
*cdr
)
97 p
->cells
= p
->cells
->cdr
;
100 c
= (node
*)parser_palloc
(p
, sizeof
(mrb_ast_node
));
105 c
->lineno
= p
->lineno
;
108 #define cons(a,b) cons_gen(p,(a),(b))
111 list1_gen
(parser_state
*p
, node
*a
)
115 #define list1(a) list1_gen(p, (a))
118 list2_gen
(parser_state
*p
, node
*a
, node
*b
)
120 return cons
(a
, cons
(b
,0));
122 #define list2(a,b) list2_gen(p, (a),(b))
125 list3_gen
(parser_state
*p
, node
*a
, node
*b
, node
*c
)
127 return cons
(a
, cons
(b
, cons
(c
,0)));
129 #define list3(a,b,c) list3_gen(p, (a),(b),(c))
132 list4_gen
(parser_state
*p
, node
*a
, node
*b
, node
*c
, node
*d
)
134 return cons
(a
, cons
(b
, cons
(c
, cons
(d
, 0))));
136 #define list4(a,b,c,d) list4_gen(p, (a),(b),(c),(d))
139 list5_gen
(parser_state
*p
, node
*a
, node
*b
, node
*c
, node
*d
, node
*e
)
141 return cons
(a
, cons
(b
, cons
(c
, cons
(d
, cons
(e
, 0)))));
143 #define list5(a,b,c,d,e) list5_gen(p, (a),(b),(c),(d),(e))
146 list6_gen
(parser_state
*p
, node
*a
, node
*b
, node
*c
, node
*d
, node
*e
, node
*f
)
148 return cons
(a
, cons
(b
, cons
(c
, cons
(d
, cons
(e
, cons
(f
, 0))))));
150 #define list6(a,b,c,d,e,f) list6_gen(p, (a),(b),(c),(d),(e),(f))
153 append_gen
(parser_state
*p
, node
*a
, node
*b
)
166 #define append(a,b) append_gen(p,(a),(b))
167 #define push(a,b) append_gen(p,(a),list1(b))
170 parser_strndup
(parser_state
*p
, const char *s
, size_t len
)
172 char *b
= (char *)parser_palloc
(p
, len
+1);
178 #define strndup(s,len) parser_strndup(p, s, len)
181 parser_strdup
(parser_state
*p
, const char *s
)
183 return parser_strndup
(p
, s
, strlen
(s
));
186 #define strdup(s) parser_strdup(p, s)
188 // xxx -----------------------------
191 local_switch
(parser_state
*p
)
193 node
*prev
= p
->locals
;
195 p
->locals
= cons
(0, 0);
200 local_resume
(parser_state
*p
, node
*prev
)
206 local_nest
(parser_state
*p
)
208 p
->locals
= cons
(0, p
->locals
);
212 local_unnest
(parser_state
*p
)
214 p
->locals
= p
->locals
->cdr
;
218 local_var_p
(parser_state
*p
, mrb_sym sym
)
225 if
(sym
(n
->car
) == sym
) return
1;
234 local_add_f
(parser_state
*p
, mrb_sym sym
)
236 p
->locals
->car
= push
(p
->locals
->car
, nsym
(sym
));
240 local_add
(parser_state
*p
, mrb_sym sym
)
242 if
(!local_var_p
(p
, sym
)) {
247 // (:scope (vars..) (prog...))
249 new_scope
(parser_state
*p
, node
*body
)
251 return cons
((node
*)NODE_SCOPE
, cons
(p
->locals
->car
, body
));
256 new_begin
(parser_state
*p
, node
*body
)
259 return list2
((node
*)NODE_BEGIN
, body
);
260 return cons
((node
*)NODE_BEGIN
, 0);
263 #define newline_node(n) (n)
265 // (:rescue body rescue else)
267 new_rescue
(parser_state
*p
, node
*body
, node
*resq
, node
*els
)
269 return list4
((node
*)NODE_RESCUE
, body
, resq
, els
);
272 // (:ensure body ensure)
274 new_ensure
(parser_state
*p
, node
*a
, node
*b
)
276 return cons
((node
*)NODE_ENSURE
, cons
(a
, cons
(0, b
)));
281 new_nil
(parser_state
*p
)
283 return list1
((node
*)NODE_NIL
);
288 new_true
(parser_state
*p
)
290 return list1
((node
*)NODE_TRUE
);
295 new_false
(parser_state
*p
)
297 return list1
((node
*)NODE_FALSE
);
302 new_alias
(parser_state
*p
, mrb_sym a
, mrb_sym b
)
304 return cons
((node
*)NODE_ALIAS
, cons
(nsym
(a
), nsym
(b
)));
307 // (:if cond then else)
309 new_if
(parser_state
*p
, node
*a
, node
*b
, node
*c
)
311 return list4
((node
*)NODE_IF
, a
, b
, c
);
314 // (:unless cond then else)
316 new_unless
(parser_state
*p
, node
*a
, node
*b
, node
*c
)
318 return list4
((node
*)NODE_IF
, a
, c
, b
);
321 // (:while cond body)
323 new_while
(parser_state
*p
, node
*a
, node
*b
)
325 return cons
((node
*)NODE_WHILE
, cons
(a
, b
));
328 // (:until cond body)
330 new_until
(parser_state
*p
, node
*a
, node
*b
)
332 return cons
((node
*)NODE_UNTIL
, cons
(a
, b
));
335 // (:for var obj body)
337 new_for
(parser_state
*p
, node
*v
, node
*o
, node
*b
)
339 return list4
((node
*)NODE_FOR
, v
, o
, b
);
342 // (:case a ((when ...) body) ((when...) body))
344 new_case
(parser_state
*p
, node
*a
, node
*b
)
346 node
*n
= list2
((node
*)NODE_CASE
, a
);
358 new_postexe
(parser_state
*p
, node
*a
)
360 return cons
((node
*)NODE_POSTEXE
, a
);
365 new_self
(parser_state
*p
)
367 return list1
((node
*)NODE_SELF
);
372 new_call
(parser_state
*p
, node
*a
, mrb_sym b
, node
*c
)
374 return list4
((node
*)NODE_CALL
, a
, nsym
(b
), c
);
377 // (:fcall self mid args)
379 new_fcall
(parser_state
*p
, mrb_sym b
, node
*c
)
381 return list4
((node
*)NODE_FCALL
, new_self
(p
), nsym
(b
), c
);
387 new_vcall
(parser_state
*p
, mrb_sym b
)
389 return list3
((node
*)NODE_VCALL
, new_self
(p
), (node
*)b
);
395 new_super
(parser_state
*p
, node
*c
)
397 return cons
((node
*)NODE_SUPER
, c
);
402 new_zsuper
(parser_state
*p
)
404 return list1
((node
*)NODE_ZSUPER
);
409 new_yield
(parser_state
*p
, node
*c
)
413 yyerror(p
, "both block arg and actual block given");
415 return cons
((node
*)NODE_YIELD
, c
->car
);
417 return cons
((node
*)NODE_YIELD
, 0);
422 new_return
(parser_state
*p
, node
*c
)
424 return cons
((node
*)NODE_RETURN
, c
);
429 new_break
(parser_state
*p
, node
*c
)
431 return cons
((node
*)NODE_BREAK
, c
);
436 new_next
(parser_state
*p
, node
*c
)
438 return cons
((node
*)NODE_NEXT
, c
);
443 new_redo
(parser_state
*p
)
445 return list1
((node
*)NODE_REDO
);
450 new_retry
(parser_state
*p
)
452 return list1
((node
*)NODE_RETRY
);
457 new_dot2
(parser_state
*p
, node
*a
, node
*b
)
459 return cons
((node
*)NODE_DOT2
, cons
(a
, b
));
464 new_dot3
(parser_state
*p
, node
*a
, node
*b
)
466 return cons
((node
*)NODE_DOT3
, cons
(a
, b
));
471 new_colon2
(parser_state
*p
, node
*b
, mrb_sym c
)
473 return cons
((node
*)NODE_COLON2
, cons
(b
, nsym
(c
)));
478 new_colon3
(parser_state
*p
, mrb_sym c
)
480 return cons
((node
*)NODE_COLON3
, nsym
(c
));
485 new_and
(parser_state
*p
, node
*a
, node
*b
)
487 return cons
((node
*)NODE_AND
, cons
(a
, b
));
492 new_or
(parser_state
*p
, node
*a
, node
*b
)
494 return cons
((node
*)NODE_OR
, cons
(a
, b
));
499 new_array
(parser_state
*p
, node
*a
)
501 return cons
((node
*)NODE_ARRAY
, a
);
506 new_splat
(parser_state
*p
, node
*a
)
508 return cons
((node
*)NODE_SPLAT
, a
);
511 // (:hash (k . v) (k . v)...)
513 new_hash
(parser_state
*p
, node
*a
)
515 return cons
((node
*)NODE_HASH
, a
);
520 new_sym
(parser_state
*p
, mrb_sym sym
)
522 return cons
((node
*)NODE_SYM
, nsym
(sym
));
526 new_strsym
(parser_state
*p
, node
* str
)
528 const char *s
= (const char*)str
->cdr
->car
;
529 size_t len
= (size_t)str
->cdr
->cdr
;
531 return mrb_intern2
(p
->mrb
, s
, len
);
536 new_lvar
(parser_state
*p
, mrb_sym sym
)
538 return cons
((node
*)NODE_LVAR
, nsym
(sym
));
543 new_gvar
(parser_state
*p
, mrb_sym sym
)
545 return cons
((node
*)NODE_GVAR
, nsym
(sym
));
550 new_ivar
(parser_state
*p
, mrb_sym sym
)
552 return cons
((node
*)NODE_IVAR
, nsym
(sym
));
557 new_cvar
(parser_state
*p
, mrb_sym sym
)
559 return cons
((node
*)NODE_CVAR
, nsym
(sym
));
564 new_const
(parser_state
*p
, mrb_sym sym
)
566 return cons
((node
*)NODE_CONST
, nsym
(sym
));
571 new_undef
(parser_state
*p
, mrb_sym sym
)
573 return list2
((node
*)NODE_UNDEF
, nsym
(sym
));
576 // (:class class super body)
578 new_class
(parser_state
*p
, node
*c
, node
*s
, node
*b
)
580 return list4
((node
*)NODE_CLASS
, c
, s
, cons
(p
->locals
->car
, b
));
583 // (:sclass obj body)
585 new_sclass
(parser_state
*p
, node
*o
, node
*b
)
587 return list3
((node
*)NODE_SCLASS
, o
, cons
(p
->locals
->car
, b
));
590 // (:module module body)
592 new_module
(parser_state
*p
, node
*m
, node
*b
)
594 return list3
((node
*)NODE_MODULE
, m
, cons
(p
->locals
->car
, b
));
597 // (:def m lv (arg . body))
599 new_def
(parser_state
*p
, mrb_sym m
, node
*a
, node
*b
)
601 return list5
((node
*)NODE_DEF
, nsym
(m
), p
->locals
->car
, a
, b
);
604 // (:sdef obj m lv (arg . body))
606 new_sdef
(parser_state
*p
, node
*o
, mrb_sym m
, node
*a
, node
*b
)
608 return list6
((node
*)NODE_SDEF
, o
, nsym
(m
), p
->locals
->car
, a
, b
);
613 new_arg
(parser_state
*p
, mrb_sym sym
)
615 return cons
((node
*)NODE_ARG
, nsym
(sym
));
620 // o: ((a . e1) (b . e2))
625 new_args
(parser_state
*p
, node
*m
, node
*opt
, mrb_sym rest
, node
*m2
, mrb_sym blk
)
629 n
= cons
(m2
, nsym
(blk
));
630 n
= cons
(nsym
(rest
), n
);
637 new_block_arg
(parser_state
*p
, node
*a
)
639 return cons
((node
*)NODE_BLOCK_ARG
, a
);
644 new_block
(parser_state
*p
, node
*a
, node
*b
)
646 return list4
((node
*)NODE_BLOCK
, p
->locals
->car
, a
, b
);
649 // (:lambda arg body)
651 new_lambda
(parser_state
*p
, node
*a
, node
*b
)
653 return list4
((node
*)NODE_LAMBDA
, p
->locals
->car
, a
, b
);
658 new_asgn
(parser_state
*p
, node
*a
, node
*b
)
660 return cons
((node
*)NODE_ASGN
, cons
(a
, b
));
663 // (:masgn mlhs=(pre rest post) mrhs)
665 new_masgn
(parser_state
*p
, node
*a
, node
*b
)
667 return cons
((node
*)NODE_MASGN
, cons
(a
, b
));
672 new_op_asgn
(parser_state
*p
, node
*a
, mrb_sym op
, node
*b
)
674 return list4
((node
*)NODE_OP_ASGN
, a
, nsym
(op
), b
);
679 new_int
(parser_state
*p
, const char *s
, int base
)
681 return list3
((node
*)NODE_INT
, (node
*)strdup
(s
), (node
*)(intptr_t)base
);
686 new_float
(parser_state
*p
, const char *s
)
688 return cons
((node
*)NODE_FLOAT
, (node
*)strdup
(s
));
691 // (:str . (s . len))
693 new_str
(parser_state
*p
, const char *s
, int len
)
695 return cons
((node
*)NODE_STR
, cons
((node
*)strndup
(s
, len
), (node
*)(intptr_t)len
));
700 new_dstr
(parser_state
*p
, node
*a
)
702 return cons
((node
*)NODE_DSTR
, a
);
705 // (:str . (s . len))
707 new_xstr
(parser_state
*p
, const char *s
, int len
)
709 return cons
((node
*)NODE_XSTR
, cons
((node
*)strndup
(s
, len
), (node
*)(intptr_t)len
));
714 new_dxstr
(parser_state
*p
, node
*a
)
716 return cons
((node
*)NODE_DXSTR
, a
);
721 new_dsym
(parser_state
*p
, node
*a
)
723 return cons
((node
*)NODE_DSYM
, new_dstr
(p
, a
));
728 new_regx
(parser_state
*p
, const char *p1
, const char* p2
)
730 return cons
((node
*)NODE_REGX
, cons
((node
*)p1
, (node
*)p2
));
735 new_dregx
(parser_state
*p
, node
*a
, node
*b
)
737 return cons
((node
*)NODE_DREGX
, cons
(a
, b
));
742 new_back_ref
(parser_state
*p
, int n
)
744 return cons
((node
*)NODE_BACK_REF
, (node
*)(intptr_t)n
);
749 new_nth_ref
(parser_state
*p
, int n
)
751 return cons
((node
*)NODE_NTH_REF
, (node
*)(intptr_t)n
);
756 new_heredoc
(parser_state
*p
)
758 parser_heredoc_info
*inf
= parser_palloc
(p
, sizeof
(parser_heredoc_info
));
759 return cons
((node
*)NODE_HEREDOC
, (node
*)inf
);
763 new_bv
(parser_state
*p
, mrb_sym id
)
768 new_literal_delim
(parser_state
*p
)
770 return cons
((node
*)NODE_LITERAL_DELIM
, 0);
775 new_words
(parser_state
*p
, node
*a
)
777 return cons
((node
*)NODE_WORDS
, a
);
782 new_symbols
(parser_state
*p
, node
*a
)
784 return cons
((node
*)NODE_SYMBOLS
, a
);
787 // xxx -----------------------------
791 call_uni_op
(parser_state
*p
, node
*recv
, char *m
)
793 return new_call
(p
, recv
, intern
(m
), 0);
798 call_bin_op
(parser_state
*p
, node
*recv
, char *m
, node
*arg1
)
800 return new_call
(p
, recv
, intern
(m
), list1
(list1
(arg1
)));
804 args_with_block
(parser_state
*p
, node
*a
, node
*b
)
808 yyerror(p
, "both block arg and actual block given");
815 call_with_block
(parser_state
*p
, node
*a
, node
*b
)
819 if
(a
->car
== (node
*)NODE_SUPER ||
820 a
->car
== (node
*)NODE_ZSUPER
) {
821 if
(!a
->cdr
) a
->cdr
= cons
(0, b
);
823 args_with_block
(p
, a
->cdr
, b
);
827 n
= a
->cdr
->cdr
->cdr
;
828 if
(!n
->car
) n
->car
= cons
(0, b
);
830 args_with_block
(p
, n
->car
, b
);
836 negate_lit
(parser_state
*p
, node
*n
)
838 return cons
((node
*)NODE_NEGATE
, n
);
848 ret_args
(parser_state
*p
, node
*n
)
851 yyerror(p
, "block argument should not be given");
853 if
(!n
->car
->cdr
) return n
->car
->car
;
854 return new_array
(p
, n
->car
);
858 assignable
(parser_state
*p
, node
*lhs
)
860 if
((int)(intptr_t)lhs
->car
== NODE_LVAR
) {
861 local_add
(p
, sym
(lhs
->cdr
));
866 var_reference
(parser_state
*p
, node
*lhs
)
870 if
((int)(intptr_t)lhs
->car
== NODE_LVAR
) {
871 if
(!local_var_p
(p
, sym
(lhs
->cdr
))) {
872 n
= new_fcall
(p
, sym
(lhs
->cdr
), 0);
881 typedef
enum mrb_string_type string_type
;
884 new_strterm
(parser_state
*p
, string_type type
, int term
, int paren
)
886 return cons
((node
*)(intptr_t)type
, cons
((node
*)0, cons
((node
*)(intptr_t)paren
, (node
*)(intptr_t)term
)));
890 end_strterm
(parser_state
*p
)
892 cons_free
(p
->lex_strterm
->cdr
->cdr
);
893 cons_free
(p
->lex_strterm
->cdr
);
894 cons_free
(p
->lex_strterm
);
895 p
->lex_strterm
= NULL
;
898 parser_heredoc_info
*
899 parsing_heredoc_inf
(parser_state
*p
)
901 node
*nd
= p
->parsing_heredoc
;
904 /* assert(nd->car->car == NODE_HEREDOC); */
905 return
(parser_heredoc_info
*)nd
->car
->cdr
;
909 heredoc_end
(parser_state
*p
)
911 p
->parsing_heredoc
= p
->parsing_heredoc
->cdr
;
912 if
(p
->parsing_heredoc
== NULL
) {
913 p
->lstate
= EXPR_BEG
;
916 p
->heredoc_end_now
= TRUE
;
919 p
->lex_strterm
->car
= (node
*)(intptr_t)parsing_heredoc_inf
(p
)->type
;
922 #define is_strterm_type(p,str_func) ((int)(intptr_t)((p)->lex_strterm->car) & (str_func))
924 // xxx -----------------------------
929 %parse
-param
{parser_state
*p
}
930 %lex
-param
{parser_state
*p
}
937 const struct vtable
*vars
;
990 %token
<id
> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
991 %token
<nd
> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
992 %token
<nd
> tSTRING tSTRING_PART tSTRING_MID
993 %token
<nd
> tNTH_REF tBACK_REF
994 %token
<num
> tREGEXP_END
996 %type
<nd
> singleton
string string_rep string_interp xstring regexp
997 %type
<nd
> literal numeric cpath symbol
998 %type
<nd
> top_compstmt top_stmts top_stmt
999 %type
<nd
> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
1000 %type
<nd
> expr_value arg_value primary_value
1001 %type
<nd
> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
1002 %type
<nd
> args call_args opt_call_args
1003 %type
<nd
> paren_args opt_paren_args variable
1004 %type
<nd
> command_args aref_args opt_block_arg block_arg var_ref var_lhs
1005 %type
<nd
> command_asgn mrhs superclass block_call block_command
1006 %type
<nd
> f_block_optarg f_block_opt
1007 %type
<nd
> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
1008 %type
<nd
> assoc_list assocs assoc undef_list backref for_var
1009 %type
<nd
> block_param opt_block_param block_param_def f_opt
1010 %type
<nd
> bv_decls opt_bv_decl bvar f_larglist lambda_body
1011 %type
<nd
> brace_block cmd_brace_block do_block lhs none f_bad_arg
1012 %type
<nd
> mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner
1013 %type
<id
> fsym sym basic_symbol operation operation2 operation3
1014 %type
<id
> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg
1015 %type
<nd
> heredoc words symbols
1017 %token tUPLUS
/* unary+ */
1018 %token tUMINUS
/* unary- */
1019 %token tPOW
/* ** */
1020 %token tCMP
/* <=> */
1022 %token tEQQ
/* === */
1023 %token tNEQ
/* != */
1024 %token tGEQ
/* >= */
1025 %token tLEQ
/* <= */
1026 %token tANDOP tOROP
/* && and || */
1027 %token tMATCH tNMATCH
/* =~ and !~ */
1028 %token tDOT2 tDOT3
/* .. and ... */
1029 %token tAREF tASET
/* [] and []= */
1030 %token tLSHFT tRSHFT
/* << and >> */
1031 %token tCOLON2
/* :: */
1032 %token tCOLON3
/* :: at EXPR_BEG */
1033 %token
<id
> tOP_ASGN
/* +=, -= etc. */
1034 %token tASSOC
/* => */
1035 %token tLPAREN
/* ( */
1036 %token tLPAREN_ARG
/* ( */
1037 %token tRPAREN
/* ) */
1038 %token tLBRACK
/* [ */
1039 %token tLBRACE
/* { */
1040 %token tLBRACE_ARG
/* { */
1041 %token tSTAR
/* * */
1042 %token tAMPER
/* & */
1043 %token tLAMBDA
/* -> */
1044 %token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG
1045 %token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG
1046 %token
<nd
> tHEREDOC_BEG
/* <<, <<- */
1047 %token tHEREDOC_END tLITERAL_DELIM
1054 %nonassoc tLBRACE_ARG
1056 %nonassoc modifier_if modifier_unless modifier_while modifier_until
1057 %left keyword_or keyword_and
1060 %left modifier_rescue
1062 %nonassoc tDOT2 tDOT3
1065 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
1066 %left
'>' tGEQ
'<' tLEQ
1072 %right tUMINUS_NUM tUMINUS
1074 %right
'!' '~' tUPLUS
1077 %nonassoc idRespond_to
1080 %nonassoc id_core_set_method_alias
1081 %nonassoc id_core_set_variable_alias
1082 %nonassoc id_core_undef_method
1083 %nonassoc id_core_define_method
1084 %nonassoc id_core_define_singleton_method
1085 %nonassoc id_core_set_postexe
1091 p
->lstate
= EXPR_BEG
;
1092 if
(!p
->locals
) p
->locals
= cons
(0,0);
1096 p
->tree
= new_scope
(p
, $2);
1100 top_compstmt
: top_stmts opt_terms
1108 $$
= new_begin
(p
, 0);
1112 $$
= new_begin
(p
, $1);
1114 | top_stmts terms top_stmt
1116 $$
= push
($1, newline_node
($3));
1120 $$
= new_begin
(p
, 0);
1127 $
<nd
>$
= local_switch
(p
);
1129 '{' top_compstmt
'}'
1131 yyerror(p
, "BEGIN not supported");
1132 local_resume
(p
, $
<nd
>2);
1143 $$
= new_rescue
(p
, $1, $2, $3);
1146 yywarn
(p
, "else without rescue is useless");
1154 $$
= new_ensure
(p
, $$
, $4);
1157 $$
= push
($4, new_nil
(p
));
1163 compstmt
: stmts opt_terms
1171 $$
= new_begin
(p
, 0);
1175 $$
= new_begin
(p
, $1);
1179 $$
= push
($1, newline_node
($3));
1183 $$
= new_begin
(p
, $2);
1187 stmt
: keyword_alias fsym
{p
->lstate
= EXPR_FNAME
;} fsym
1189 $$
= new_alias
(p
, $2, $4);
1191 | keyword_undef undef_list
1195 | stmt modifier_if expr_value
1197 $$
= new_if
(p
, cond
($3), $1, 0);
1199 | stmt modifier_unless expr_value
1201 $$
= new_unless
(p
, cond
($3), $1, 0);
1203 | stmt modifier_while expr_value
1205 $$
= new_while
(p
, cond
($3), $1);
1207 | stmt modifier_until expr_value
1209 $$
= new_until
(p
, cond
($3), $1);
1211 | stmt modifier_rescue stmt
1213 $$
= new_rescue
(p
, $1, list1
(list3
(0, 0, $3)), 0);
1215 | keyword_END
'{' compstmt
'}'
1217 yyerror(p
, "END not suported");
1218 $$
= new_postexe
(p
, $3);
1221 | mlhs
'=' command_call
1223 $$
= new_masgn
(p
, $1, $3);
1225 | var_lhs tOP_ASGN command_call
1227 $$
= new_op_asgn
(p
, $1, $2, $3);
1229 | primary_value
'[' opt_call_args rbracket tOP_ASGN command_call
1231 $$
= new_op_asgn
(p
, new_call
(p
, $1, intern
("[]"), $3), $5, $6);
1233 | primary_value
'.' tIDENTIFIER tOP_ASGN command_call
1235 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1237 | primary_value
'.' tCONSTANT tOP_ASGN command_call
1239 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1241 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
1243 yyerror(p
, "constant re-assignment");
1246 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
1248 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1250 | backref tOP_ASGN command_call
1252 backref_error
(p
, $1);
1253 $$
= new_begin
(p
, 0);
1257 $$
= new_asgn
(p
, $1, new_array
(p
, $3));
1259 | mlhs
'=' arg_value
1261 $$
= new_masgn
(p
, $1, $3);
1265 $$
= new_masgn
(p
, $1, new_array
(p
, $3));
1270 command_asgn
: lhs
'=' command_call
1272 $$
= new_asgn
(p
, $1, $3);
1274 | lhs
'=' command_asgn
1276 $$
= new_asgn
(p
, $1, $3);
1282 | expr keyword_and expr
1284 $$
= new_and
(p
, $1, $3);
1286 | expr keyword_or expr
1288 $$
= new_or
(p
, $1, $3);
1290 | keyword_not opt_nl expr
1292 $$
= call_uni_op
(p
, cond
($3), "!");
1296 $$
= call_uni_op
(p
, cond
($2), "!");
1303 if
(!$1) $$
= new_nil
(p
);
1308 command_call
: command
1312 block_command
: block_call
1313 | block_call dot_or_colon operation2 command_args
1316 cmd_brace_block
: tLBRACE_ARG
1324 $$
= new_block
(p
, $3, $4);
1329 command
: operation command_args %prec tLOWEST
1331 $$
= new_fcall
(p
, $1, $2);
1333 | operation command_args cmd_brace_block
1335 args_with_block
(p
, $2, $3);
1336 $$
= new_fcall
(p
, $1, $2);
1338 | primary_value
'.' operation2 command_args %prec tLOWEST
1340 $$
= new_call
(p
, $1, $3, $4);
1342 | primary_value
'.' operation2 command_args cmd_brace_block
1344 args_with_block
(p
, $4, $5);
1345 $$
= new_call
(p
, $1, $3, $4);
1347 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
1349 $$
= new_call
(p
, $1, $3, $4);
1351 | primary_value tCOLON2 operation2 command_args cmd_brace_block
1353 args_with_block
(p
, $4, $5);
1354 $$
= new_call
(p
, $1, $3, $4);
1356 | keyword_super command_args
1358 $$
= new_super
(p
, $2);
1360 | keyword_yield command_args
1362 $$
= new_yield
(p
, $2);
1364 | keyword_return call_args
1366 $$
= new_return
(p
, ret_args
(p
, $2));
1368 | keyword_break call_args
1370 $$
= new_break
(p
, ret_args
(p
, $2));
1372 | keyword_next call_args
1374 $$
= new_next
(p
, ret_args
(p
, $2));
1382 | tLPAREN mlhs_inner rparen
1388 mlhs_inner
: mlhs_basic
1389 | tLPAREN mlhs_inner rparen
1395 mlhs_basic
: mlhs_list
1399 | mlhs_list mlhs_item
1401 $$
= list1
(push
($1,$2));
1403 | mlhs_list tSTAR mlhs_node
1407 | mlhs_list tSTAR mlhs_node
',' mlhs_post
1409 $$
= list3
($1, $3, $5);
1413 $$
= list2
($1, new_nil
(p
));
1415 | mlhs_list tSTAR
',' mlhs_post
1417 $$
= list3
($1, new_nil
(p
), $4);
1423 | tSTAR mlhs_node
',' mlhs_post
1425 $$
= list3
(0, $2, $4);
1429 $$
= list2
(0, new_nil
(p
));
1431 | tSTAR
',' mlhs_post
1433 $$
= list3
(0, new_nil
(p
), $3);
1437 mlhs_item
: mlhs_node
1438 | tLPAREN mlhs_inner rparen
1444 mlhs_list
: mlhs_item
','
1448 | mlhs_list mlhs_item
','
1454 mlhs_post
: mlhs_item
1458 | mlhs_list mlhs_item
1464 mlhs_node
: variable
1468 | primary_value
'[' opt_call_args rbracket
1470 $$
= new_call
(p
, $1, intern
("[]"), $3);
1472 | primary_value
'.' tIDENTIFIER
1474 $$
= new_call
(p
, $1, $3, 0);
1476 | primary_value tCOLON2 tIDENTIFIER
1478 $$
= new_call
(p
, $1, $3, 0);
1480 | primary_value
'.' tCONSTANT
1482 $$
= new_call
(p
, $1, $3, 0);
1484 | primary_value tCOLON2 tCONSTANT
1486 if
(p
->in_def || p
->in_single
)
1487 yyerror(p
, "dynamic constant assignment");
1488 $$
= new_colon2
(p
, $1, $3);
1492 if
(p
->in_def || p
->in_single
)
1493 yyerror(p
, "dynamic constant assignment");
1494 $$
= new_colon3
(p
, $2);
1498 backref_error
(p
, $1);
1507 | primary_value
'[' opt_call_args rbracket
1509 $$
= new_call
(p
, $1, intern
("[]"), $3);
1511 | primary_value
'.' tIDENTIFIER
1513 $$
= new_call
(p
, $1, $3, 0);
1515 | primary_value tCOLON2 tIDENTIFIER
1517 $$
= new_call
(p
, $1, $3, 0);
1519 | primary_value
'.' tCONSTANT
1521 $$
= new_call
(p
, $1, $3, 0);
1523 | primary_value tCOLON2 tCONSTANT
1525 if
(p
->in_def || p
->in_single
)
1526 yyerror(p
, "dynamic constant assignment");
1527 $$
= new_colon2
(p
, $1, $3);
1531 if
(p
->in_def || p
->in_single
)
1532 yyerror(p
, "dynamic constant assignment");
1533 $$
= new_colon3
(p
, $2);
1537 backref_error
(p
, $1);
1544 yyerror(p
, "class/module name must be CONSTANT");
1549 cpath
: tCOLON3 cname
1551 $$
= cons
((node
*)1, nsym
($2));
1555 $$
= cons
((node
*)0, nsym
($1));
1557 | primary_value tCOLON2 cname
1559 $$
= cons
($1, nsym
($3));
1568 p
->lstate
= EXPR_ENDFN
;
1573 p
->lstate
= EXPR_ENDFN
;
1584 $$
= new_undef
(p
, $1);
1586 | undef_list
',' {p
->lstate
= EXPR_FNAME
;} fsym
1588 $$
= push
($1, nsym
($4));
1592 op
: '|' { $$
= intern
("|"); }
1593 |
'^' { $$
= intern
("^"); }
1594 |
'&' { $$
= intern
("&"); }
1595 | tCMP
{ $$
= intern
("<=>"); }
1596 | tEQ
{ $$
= intern
("=="); }
1597 | tEQQ
{ $$
= intern
("==="); }
1598 | tMATCH
{ $$
= intern
("=~"); }
1599 | tNMATCH
{ $$
= intern
("!~"); }
1600 |
'>' { $$
= intern
(">"); }
1601 | tGEQ
{ $$
= intern
(">="); }
1602 |
'<' { $$
= intern
("<"); }
1603 | tLEQ
{ $$
= intern
("<="); }
1604 | tNEQ
{ $$
= intern
("!="); }
1605 | tLSHFT
{ $$
= intern
("<<"); }
1606 | tRSHFT
{ $$
= intern
(">>"); }
1607 |
'+' { $$
= intern
("+"); }
1608 |
'-' { $$
= intern
("-"); }
1609 |
'*' { $$
= intern
("*"); }
1610 | tSTAR
{ $$
= intern
("*"); }
1611 |
'/' { $$
= intern
("/"); }
1612 |
'%' { $$
= intern
("%"); }
1613 | tPOW
{ $$
= intern
("**"); }
1614 |
'!' { $$
= intern
("!"); }
1615 |
'~' { $$
= intern
("~"); }
1616 | tUPLUS
{ $$
= intern
("+@"); }
1617 | tUMINUS
{ $$
= intern
("-@"); }
1618 | tAREF
{ $$
= intern
("[]"); }
1619 | tASET
{ $$
= intern
("[]="); }
1620 |
'`' { $$
= intern
("`"); }
1623 reswords
: keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
1624 | keyword_BEGIN | keyword_END
1625 | keyword_alias | keyword_and | keyword_begin
1626 | keyword_break | keyword_case | keyword_class | keyword_def
1627 | keyword_do | keyword_else | keyword_elsif
1628 | keyword_end | keyword_ensure | keyword_false
1629 | keyword_for | keyword_in | keyword_module | keyword_next
1630 | keyword_nil | keyword_not | keyword_or | keyword_redo
1631 | keyword_rescue | keyword_retry | keyword_return | keyword_self
1632 | keyword_super | keyword_then | keyword_true | keyword_undef
1633 | keyword_when | keyword_yield | keyword_if | keyword_unless
1634 | keyword_while | keyword_until
1639 $$
= new_asgn
(p
, $1, $3);
1641 | lhs
'=' arg modifier_rescue arg
1643 $$
= new_asgn
(p
, $1, new_rescue
(p
, $3, list1
(list3
(0, 0, $5)), 0));
1645 | var_lhs tOP_ASGN arg
1647 $$
= new_op_asgn
(p
, $1, $2, $3);
1649 | var_lhs tOP_ASGN arg modifier_rescue arg
1651 $$
= new_op_asgn
(p
, $1, $2, new_rescue
(p
, $3, list1
(list3
(0, 0, $5)), 0));
1653 | primary_value
'[' opt_call_args rbracket tOP_ASGN arg
1655 $$
= new_op_asgn
(p
, new_call
(p
, $1, intern
("[]"), $3), $5, $6);
1657 | primary_value
'.' tIDENTIFIER tOP_ASGN arg
1659 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1661 | primary_value
'.' tCONSTANT tOP_ASGN arg
1663 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1665 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
1667 $$
= new_op_asgn
(p
, new_call
(p
, $1, $3, 0), $4, $5);
1669 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
1671 yyerror(p
, "constant re-assignment");
1672 $$
= new_begin
(p
, 0);
1674 | tCOLON3 tCONSTANT tOP_ASGN arg
1676 yyerror(p
, "constant re-assignment");
1677 $$
= new_begin
(p
, 0);
1679 | backref tOP_ASGN arg
1681 backref_error
(p
, $1);
1682 $$
= new_begin
(p
, 0);
1686 $$
= new_dot2
(p
, $1, $3);
1690 $$
= new_dot3
(p
, $1, $3);
1694 $$
= call_bin_op
(p
, $1, "+", $3);
1698 $$
= call_bin_op
(p
, $1, "-", $3);
1702 $$
= call_bin_op
(p
, $1, "*", $3);
1706 $$
= call_bin_op
(p
, $1, "/", $3);
1710 $$
= call_bin_op
(p
, $1, "%", $3);
1714 $$
= call_bin_op
(p
, $1, "**", $3);
1716 | tUMINUS_NUM tINTEGER tPOW arg
1718 $$
= call_uni_op
(p
, call_bin_op
(p
, $2, "**", $4), "-@");
1720 | tUMINUS_NUM tFLOAT tPOW arg
1722 $$
= call_uni_op
(p
, call_bin_op
(p
, $2, "**", $4), "-@");
1726 $$
= call_uni_op
(p
, $2, "+@");
1730 $$
= call_uni_op
(p
, $2, "-@");
1734 $$
= call_bin_op
(p
, $1, "|", $3);
1738 $$
= call_bin_op
(p
, $1, "^", $3);
1742 $$
= call_bin_op
(p
, $1, "&", $3);
1746 $$
= call_bin_op
(p
, $1, "<=>", $3);
1750 $$
= call_bin_op
(p
, $1, ">", $3);
1754 $$
= call_bin_op
(p
, $1, ">=", $3);
1758 $$
= call_bin_op
(p
, $1, "<", $3);
1762 $$
= call_bin_op
(p
, $1, "<=", $3);
1766 $$
= call_bin_op
(p
, $1, "==", $3);
1770 $$
= call_bin_op
(p
, $1, "===", $3);
1774 $$
= call_bin_op
(p
, $1, "!=", $3);
1778 $$
= call_bin_op
(p
, $1, "=~", $3);
1780 if
(nd_type
($1) == NODE_LIT
&& TYPE
($1->nd_lit
) == T_REGEXP
) {
1781 $$
= reg_named_capture_assign
($1->nd_lit
, $$
);
1787 $$
= call_bin_op
(p
, $1, "!~", $3);
1791 $$
= call_uni_op
(p
, cond
($2), "!");
1795 $$
= call_uni_op
(p
, cond
($2), "~");
1799 $$
= call_bin_op
(p
, $1, "<<", $3);
1803 $$
= call_bin_op
(p
, $1, ">>", $3);
1807 $$
= new_and
(p
, $1, $3);
1811 $$
= new_or
(p
, $1, $3);
1813 | arg
'?' arg opt_nl
':' arg
1815 $$
= new_if
(p
, cond
($1), $3, $6);
1826 if
(!$$
) $$
= new_nil
(p
);
1835 | args
',' assocs trailer
1837 $$
= push
($1, new_hash
(p
, $3));
1841 $$
= cons
(new_hash
(p
, $1), 0);
1845 paren_args
: '(' opt_call_args rparen
1851 opt_paren_args
: none
1855 opt_call_args
: none
1861 | args
',' assocs
','
1863 $$
= cons
(push
($1, new_hash
(p
, $3)), 0);
1867 $$
= cons
(list1
(new_hash
(p
, $1)), 0);
1873 $$
= cons
(list1
($1), 0);
1875 | args opt_block_arg
1879 | assocs opt_block_arg
1881 $$
= cons
(list1
(new_hash
(p
, $1)), $2);
1883 | args
',' assocs opt_block_arg
1885 $$
= cons
(push
($1, new_hash
(p
, $3)), $4);
1894 $
<stack
>$
= p
->cmdarg_stack
;
1899 p
->cmdarg_stack
= $
<stack
>1;
1904 block_arg
: tAMPER arg_value
1906 $$
= new_block_arg
(p
, $2);
1910 opt_block_arg
: ',' block_arg
1926 $$
= cons
(new_splat
(p
, $2), 0);
1928 | args
',' arg_value
1932 | args
',' tSTAR arg_value
1934 $$
= push
($1, new_splat
(p
, $4));
1938 mrhs
: args
',' arg_value
1942 | args
',' tSTAR arg_value
1944 $$
= push
($1, new_splat
(p
, $4));
1948 $$
= list1
(new_splat
(p
, $2));
1961 $$
= new_fcall
(p
, $1, 0);
1965 $
<stack
>1 = p
->cmdarg_stack
;
1966 p
->cmdarg_stack
= 0;
1971 p
->cmdarg_stack
= $
<stack
>1;
1974 | tLPAREN_ARG expr
{p
->lstate
= EXPR_ENDARG
;} rparen
1978 | tLPAREN_ARG
{p
->lstate
= EXPR_ENDARG
;} rparen
1982 | tLPAREN compstmt
')'
1986 | primary_value tCOLON2 tCONSTANT
1988 $$
= new_colon2
(p
, $1, $3);
1992 $$
= new_colon3
(p
, $2);
1994 | tLBRACK aref_args
']'
1996 $$
= new_array
(p
, $2);
1998 | tLBRACE assoc_list
'}'
2000 $$
= new_hash
(p
, $2);
2004 $$
= new_return
(p
, 0);
2006 | keyword_yield
'(' call_args rparen
2008 $$
= new_yield
(p
, $3);
2010 | keyword_yield
'(' rparen
2012 $$
= new_yield
(p
, 0);
2016 $$
= new_yield
(p
, 0);
2018 | keyword_not
'(' expr rparen
2020 $$
= call_uni_op
(p
, cond
($3), "!");
2022 | keyword_not
'(' rparen
2024 $$
= call_uni_op
(p
, new_nil
(p
), "!");
2026 | operation brace_block
2028 $$
= new_fcall
(p
, $1, cons
(0, $2));
2031 | method_call brace_block
2033 call_with_block
(p
, $1, $2);
2039 $
<num
>$
= p
->lpar_beg
;
2040 p
->lpar_beg
= ++p
->paren_nest
;
2045 p
->lpar_beg
= $
<num
>2;
2046 $$
= new_lambda
(p
, $3, $4);
2049 | keyword_if expr_value then
2054 $$
= new_if
(p
, cond
($2), $4, $5);
2056 | keyword_unless expr_value then
2061 $$
= new_unless
(p
, cond
($2), $4, $5);
2063 | keyword_while
{COND_PUSH
(1);} expr_value do
{COND_POP
();}
2067 $$
= new_while
(p
, cond
($3), $6);
2069 | keyword_until
{COND_PUSH
(1);} expr_value do
{COND_POP
();}
2073 $$
= new_until
(p
, cond
($3), $6);
2075 | keyword_case expr_value opt_terms
2079 $$
= new_case
(p
, $2, $4);
2081 | keyword_case opt_terms case_body keyword_end
2083 $$
= new_case
(p
, 0, $3);
2085 | keyword_for for_var keyword_in
2092 $$
= new_for
(p
, $2, $5, $8);
2094 | keyword_class cpath superclass
2096 if
(p
->in_def || p
->in_single
)
2097 yyerror(p
, "class definition in method body");
2098 $
<nd
>$
= local_switch
(p
);
2103 $$
= new_class
(p
, $2, $3, $5);
2104 local_resume
(p
, $
<nd
>4);
2106 | keyword_class tLSHFT expr
2108 $
<num
>$
= p
->in_def
;
2113 $
<nd
>$
= cons
(local_switch
(p
), (node
*)(intptr_t)p
->in_single
);
2119 $$
= new_sclass
(p
, $3, $7);
2120 local_resume
(p
, $
<nd
>6->car
);
2121 p
->in_def
= $
<num
>4;
2122 p
->in_single
= (int)(intptr_t)$
<nd
>6->cdr
;
2124 | keyword_module cpath
2126 if
(p
->in_def || p
->in_single
)
2127 yyerror(p
, "module definition in method body");
2128 $
<nd
>$
= local_switch
(p
);
2133 $$
= new_module
(p
, $2, $4);
2134 local_resume
(p
, $
<nd
>3);
2139 $
<nd
>$
= local_switch
(p
);
2145 $$
= new_def
(p
, $2, $4, $5);
2146 local_resume
(p
, $
<nd
>3);
2149 | keyword_def singleton dot_or_colon
{p
->lstate
= EXPR_FNAME
;} fname
2152 p
->lstate
= EXPR_ENDFN
; /* force for args */
2153 $
<nd
>$
= local_switch
(p
);
2159 $$
= new_sdef
(p
, $2, $5, $7, $8);
2160 local_resume
(p
, $
<nd
>6);
2165 $$
= new_break
(p
, 0);
2169 $$
= new_next
(p
, 0);
2181 primary_value
: primary
2184 if
(!$$
) $$
= new_nil
(p
);
2198 | keyword_elsif expr_value then
2202 $$
= new_if
(p
, cond
($2), $4, $5);
2207 | keyword_else compstmt
2215 $$
= list1
(list1
($1));
2222 $$
= new_arg
(p
, $1);
2224 | tLPAREN f_margs rparen
2226 $$
= new_masgn
(p
, $2, 0);
2230 f_marg_list
: f_marg
2234 | f_marg_list
',' f_marg
2240 f_margs
: f_marg_list
2244 | f_marg_list
',' tSTAR f_norm_arg
2246 $$
= list3
($1, new_arg
(p
, $4), 0);
2248 | f_marg_list
',' tSTAR f_norm_arg
',' f_marg_list
2250 $$
= list3
($1, new_arg
(p
, $4), $6);
2252 | f_marg_list
',' tSTAR
2254 $$
= list3
($1, (node
*)-1, 0);
2256 | f_marg_list
',' tSTAR
',' f_marg_list
2258 $$
= list3
($1, (node
*)-1, $5);
2262 $$
= list3
(0, new_arg
(p
, $2), 0);
2264 | tSTAR f_norm_arg
',' f_marg_list
2266 $$
= list3
(0, new_arg
(p
, $2), $4);
2270 $$
= list3
(0, (node
*)-1, 0);
2272 | tSTAR
',' f_marg_list
2274 $$
= list3
(0, (node
*)-1, $3);
2278 block_param
: f_arg
',' f_block_optarg
',' f_rest_arg opt_f_block_arg
2280 $$
= new_args
(p
, $1, $3, $5, 0, $6);
2282 | f_arg
',' f_block_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
2284 $$
= new_args
(p
, $1, $3, $5, $7, $8);
2286 | f_arg
',' f_block_optarg opt_f_block_arg
2288 $$
= new_args
(p
, $1, $3, 0, 0, $4);
2290 | f_arg
',' f_block_optarg
',' f_arg opt_f_block_arg
2292 $$
= new_args
(p
, $1, $3, 0, $5, $6);
2294 | f_arg
',' f_rest_arg opt_f_block_arg
2296 $$
= new_args
(p
, $1, 0, $3, 0, $4);
2300 $$
= new_args
(p
, $1, 0, 1, 0, 0);
2302 | f_arg
',' f_rest_arg
',' f_arg opt_f_block_arg
2304 $$
= new_args
(p
, $1, 0, $3, $5, $6);
2306 | f_arg opt_f_block_arg
2308 $$
= new_args
(p
, $1, 0, 0, 0, $2);
2310 | f_block_optarg
',' f_rest_arg opt_f_block_arg
2312 $$
= new_args
(p
, 0, $1, $3, 0, $4);
2314 | f_block_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
2316 $$
= new_args
(p
, 0, $1, $3, $5, $6);
2318 | f_block_optarg opt_f_block_arg
2320 $$
= new_args
(p
, 0, $1, 0, 0, $2);
2322 | f_block_optarg
',' f_arg opt_f_block_arg
2324 $$
= new_args
(p
, 0, $1, 0, $3, $4);
2326 | f_rest_arg opt_f_block_arg
2328 $$
= new_args
(p
, 0, 0, $1, 0, $2);
2330 | f_rest_arg
',' f_arg opt_f_block_arg
2332 $$
= new_args
(p
, 0, 0, $1, $3, $4);
2336 $$
= new_args
(p
, 0, 0, 0, 0, $1);
2340 opt_block_param
: none
2343 p
->cmd_start
= TRUE
;
2348 block_param_def
: '|' opt_bv_decl
'|'
2358 |
'|' block_param opt_bv_decl
'|'
2365 opt_bv_decl
: opt_nl
2369 | opt_nl
';' bv_decls opt_nl
2387 f_larglist
: '(' f_args opt_bv_decl
')'
2397 lambda_body
: tLAMBEG compstmt
'}'
2401 | keyword_do_LAMBDA compstmt keyword_end
2407 do_block
: keyword_do_block
2415 $$
= new_block
(p
,$3,$4);
2420 block_call
: command do_block
2422 if
($1->car
== (node
*)NODE_YIELD
) {
2423 yyerror(p
, "block given to yield");
2426 call_with_block
(p
, $1, $2);
2430 | block_call dot_or_colon operation2 opt_paren_args
2432 $$
= new_call
(p
, $1, $3, $4);
2434 | block_call dot_or_colon operation2 opt_paren_args brace_block
2436 $$
= new_call
(p
, $1, $3, $4);
2437 call_with_block
(p
, $$
, $5);
2439 | block_call dot_or_colon operation2 command_args do_block
2441 $$
= new_call
(p
, $1, $3, $4);
2442 call_with_block
(p
, $$
, $5);
2446 method_call
: operation paren_args
2448 $$
= new_fcall
(p
, $1, $2);
2450 | primary_value
'.' operation2 opt_paren_args
2452 $$
= new_call
(p
, $1, $3, $4);
2454 | primary_value tCOLON2 operation2 paren_args
2456 $$
= new_call
(p
, $1, $3, $4);
2458 | primary_value tCOLON2 operation3
2460 $$
= new_call
(p
, $1, $3, 0);
2462 | primary_value
'.' paren_args
2464 $$
= new_call
(p
, $1, intern
("call"), $3);
2466 | primary_value tCOLON2 paren_args
2468 $$
= new_call
(p
, $1, intern
("call"), $3);
2470 | keyword_super paren_args
2472 $$
= new_super
(p
, $2);
2478 | primary_value
'[' opt_call_args rbracket
2480 $$
= new_call
(p
, $1, intern
("[]"), $3);
2491 $$
= new_block
(p
,$3,$4);
2499 compstmt keyword_end
2501 $$
= new_block
(p
,$3,$4);
2506 case_body
: keyword_when args then
2510 $$
= cons
(cons
($2, $4), $5);
2517 $$
= cons
(cons
(0, $1), 0);
2526 opt_rescue
: keyword_rescue exc_list exc_var then
2530 $$
= list1
(list3
($2, $3, $5));
2531 if
($6) $$
= append
($$
, $6);
2536 exc_list
: arg_value
2544 exc_var
: tASSOC lhs
2551 opt_ensure
: keyword_ensure compstmt
2566 | tSTRING_BEG tSTRING
2570 | tSTRING_BEG string_rep tSTRING
2572 $$
= new_dstr
(p
, push
($2, $3));
2576 string_rep
: string_interp
2577 | string_rep string_interp
2579 $$
= append
($1, $2);
2583 string_interp
: tSTRING_MID
2589 $
<nd
>$
= p
->lex_strterm
;
2590 p
->lex_strterm
= NULL
;
2595 p
->lex_strterm
= $
<nd
>2;
2600 $$
= list1
(new_literal_delim
(p
));
2604 xstring
: tXSTRING_BEG tXSTRING
2608 | tXSTRING_BEG string_rep tXSTRING
2610 $$
= new_dxstr
(p
, push
($2, $3));
2614 regexp
: tREGEXP_BEG tREGEXP
2618 | tREGEXP_BEG string_rep tREGEXP
2620 $$
= new_dregx
(p
, $2, $3);
2624 heredoc
: tHEREDOC_BEG
2627 opt_heredoc_bodies
: none
2631 heredoc_bodies
: heredoc_body
2632 | heredoc_bodies heredoc_body
2635 heredoc_body
: tHEREDOC_END
2637 parsing_heredoc_inf
(p
)->doc
= list1
(new_str
(p
, "", 0));
2640 | string_rep tHEREDOC_END
2642 parsing_heredoc_inf
(p
)->doc
= $1;
2647 words
: tWORDS_BEG tSTRING
2649 $$
= new_words
(p
, list1
($2));
2651 | tWORDS_BEG string_rep tSTRING
2653 $$
= new_words
(p
, push
($2, $3));
2658 symbol
: basic_symbol
2660 $$
= new_sym
(p
, $1);
2662 | tSYMBEG tSTRING_BEG string_interp tSTRING
2664 p
->lstate
= EXPR_END
;
2665 $$
= new_dsym
(p
, push
($3, $4));
2669 basic_symbol
: tSYMBEG sym
2671 p
->lstate
= EXPR_END
;
2682 $$
= new_strsym
(p
, $1);
2684 | tSTRING_BEG tSTRING
2686 $$
= new_strsym
(p
, $2);
2690 symbols
: tSYMBOLS_BEG tSTRING
2692 $$
= new_symbols
(p
, list1
($2));
2694 | tSYMBOLS_BEG string_rep tSTRING
2696 $$
= new_symbols
(p
, push
($2, $3));
2702 | tUMINUS_NUM tINTEGER %prec tLOWEST
2704 $$
= negate_lit
(p
, $2);
2706 | tUMINUS_NUM tFLOAT %prec tLOWEST
2708 $$
= negate_lit
(p
, $2);
2712 variable
: tIDENTIFIER
2714 $$
= new_lvar
(p
, $1);
2718 $$
= new_ivar
(p
, $1);
2722 $$
= new_gvar
(p
, $1);
2726 $$
= new_cvar
(p
, $1);
2730 $$
= new_const
(p
, $1);
2742 $$
= var_reference
(p
, $1);
2763 p
->filename
= "(null)";
2765 $$
= new_str
(p
, p
->filename
, strlen
(p
->filename
));
2771 snprintf
(buf
, sizeof
(buf
), "%d", p
->lineno
);
2772 $$
= new_int
(p
, buf
, 10);
2786 p
->lstate
= EXPR_BEG
;
2787 p
->cmd_start
= TRUE
;
2800 f_arglist
: '(' f_args rparen
2803 p
->lstate
= EXPR_BEG
;
2804 p
->cmd_start
= TRUE
;
2812 f_args
: f_arg
',' f_optarg
',' f_rest_arg opt_f_block_arg
2814 $$
= new_args
(p
, $1, $3, $5, 0, $6);
2816 | f_arg
',' f_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
2818 $$
= new_args
(p
, $1, $3, $5, $7, $8);
2820 | f_arg
',' f_optarg opt_f_block_arg
2822 $$
= new_args
(p
, $1, $3, 0, 0, $4);
2824 | f_arg
',' f_optarg
',' f_arg opt_f_block_arg
2826 $$
= new_args
(p
, $1, $3, 0, $5, $6);
2828 | f_arg
',' f_rest_arg opt_f_block_arg
2830 $$
= new_args
(p
, $1, 0, $3, 0, $4);
2832 | f_arg
',' f_rest_arg
',' f_arg opt_f_block_arg
2834 $$
= new_args
(p
, $1, 0, $3, $5, $6);
2836 | f_arg opt_f_block_arg
2838 $$
= new_args
(p
, $1, 0, 0, 0, $2);
2840 | f_optarg
',' f_rest_arg opt_f_block_arg
2842 $$
= new_args
(p
, 0, $1, $3, 0, $4);
2844 | f_optarg
',' f_rest_arg
',' f_arg opt_f_block_arg
2846 $$
= new_args
(p
, 0, $1, $3, $5, $6);
2848 | f_optarg opt_f_block_arg
2850 $$
= new_args
(p
, 0, $1, 0, 0, $2);
2852 | f_optarg
',' f_arg opt_f_block_arg
2854 $$
= new_args
(p
, 0, $1, 0, $3, $4);
2856 | f_rest_arg opt_f_block_arg
2858 $$
= new_args
(p
, 0, 0, $1, 0, $2);
2860 | f_rest_arg
',' f_arg opt_f_block_arg
2862 $$
= new_args
(p
, 0, 0, $1, $3, $4);
2866 $$
= new_args
(p
, 0, 0, 0, 0, $1);
2871 $$
= new_args
(p
, 0, 0, 0, 0, 0);
2875 f_bad_arg
: tCONSTANT
2877 yyerror(p
, "formal argument cannot be a constant");
2882 yyerror(p
, "formal argument cannot be an instance variable");
2887 yyerror(p
, "formal argument cannot be a global variable");
2892 yyerror(p
, "formal argument cannot be a class variable");
2897 f_norm_arg
: f_bad_arg
2908 f_arg_item
: f_norm_arg
2910 $$
= new_arg
(p
, $1);
2912 | tLPAREN f_margs rparen
2914 $$
= new_masgn
(p
, $2, 0);
2922 | f_arg
',' f_arg_item
2928 f_opt
: tIDENTIFIER
'=' arg_value
2931 $$
= cons
(nsym
($1), $3);
2935 f_block_opt
: tIDENTIFIER
'=' primary_value
2938 $$
= cons
(nsym
($1), $3);
2942 f_block_optarg
: f_block_opt
2946 | f_block_optarg
',' f_block_opt
2956 | f_optarg
',' f_opt
2966 f_rest_arg
: restarg_mark tIDENTIFIER
2982 f_block_arg
: blkarg_mark tIDENTIFIER
2989 opt_f_block_arg
: ',' f_block_arg
3003 if
(!$$
) $$
= new_nil
(p
);
3005 |
'(' {p
->lstate
= EXPR_BEG
;} expr rparen
3008 yyerror(p
, "can't define singleton method for ().");
3011 switch
((enum node_type
)(int)(intptr_t)$3->car
) {
3021 yyerror(p
, "can't define singleton method for literals");
3047 assoc
: arg_value tASSOC arg_value
3053 $$
= cons
(new_sym
(p
, $1), $2);
3057 operation
: tIDENTIFIER
3062 operation2
: tIDENTIFIER
3068 operation3
: tIDENTIFIER
3077 opt_terms
: /* none */
3088 rbracket
: opt_nl
']'
3091 trailer
: /* none */
3096 term
: ';' {yyerrok;}
3108 | terms
';' {yyerrok;}
3117 #define yylval (*((YYSTYPE*)(p->ylval)))
3120 yyerror(parser_state
*p
, const char *s
)
3125 if
(! p
->capture_errors
) {
3128 fprintf
(stderr
, "%s:%d:%d: %s\n", p
->filename
, p
->lineno
, p
->column
, s
);
3131 fprintf
(stderr
, "line %d:%d: %s\n", p
->lineno
, p
->column
, s
);
3135 else if
(p
->nerr
< sizeof
(p
->error_buffer
) / sizeof
(p
->error_buffer
[0])) {
3137 c
= (char *)parser_palloc
(p
, n
+ 1);
3138 memcpy
(c
, s
, n
+ 1);
3139 p
->error_buffer
[p
->nerr
].message
= c
;
3140 p
->error_buffer
[p
->nerr
].lineno
= p
->lineno
;
3141 p
->error_buffer
[p
->nerr
].column
= p
->column
;
3147 yyerror_i
(parser_state
*p
, const char *fmt
, int i
)
3151 snprintf
(buf
, sizeof
(buf
), fmt
, i
);
3156 yywarn
(parser_state
*p
, const char *s
)
3161 if
(! p
->capture_errors
) {
3164 fprintf
(stderr
, "%s:%d:%d: %s\n", p
->filename
, p
->lineno
, p
->column
, s
);
3167 fprintf
(stderr
, "line %d:%d: %s\n", p
->lineno
, p
->column
, s
);
3171 else if
(p
->nwarn
< sizeof
(p
->warn_buffer
) / sizeof
(p
->warn_buffer
[0])) {
3173 c
= (char *)parser_palloc
(p
, n
+ 1);
3174 memcpy
(c
, s
, n
+ 1);
3175 p
->warn_buffer
[p
->nwarn
].message
= c
;
3176 p
->warn_buffer
[p
->nwarn
].lineno
= p
->lineno
;
3177 p
->warn_buffer
[p
->nwarn
].column
= p
->column
;
3183 yywarning
(parser_state
*p
, const char *s
)
3189 yywarning_s
(parser_state
*p
, const char *fmt
, const char *s
)
3193 snprintf
(buf
, sizeof
(buf
), fmt
, s
);
3198 backref_error
(parser_state
*p
, node
*n
)
3202 c
= (int)(intptr_t)n
->car
;
3204 if
(c
== NODE_NTH_REF
) {
3205 yyerror_i
(p
, "can't set variable $%d", (int)(intptr_t)n
->cdr
);
3206 } else if
(c
== NODE_BACK_REF
) {
3207 yyerror_i
(p
, "can't set variable $%c", (int)(intptr_t)n
->cdr
);
3209 mrb_bug
("Internal error in backref_error() : n=>car == %d", c
);
3213 static int peeks
(parser_state
*p
, const char *s
);
3214 static int skips
(parser_state
*p
, const char *s
);
3217 nextc
(parser_state
*p
)
3224 c
= (int)(intptr_t)p
->pb
->car
;
3231 if
(feof
(p
->f
)) return
-1;
3233 if
(c
== EOF
) return
-1;
3235 else if
(!p
->s || p
->s
>= p
->send
) {
3239 c
= (unsigned char)*p
->s
++;
3247 pushback
(parser_state
*p
, int c
)
3251 p
->pb
= cons
((node
*)(intptr_t)c
, p
->pb
);
3255 skip
(parser_state
*p
, char term
)
3262 if
(c
== term
) break
;
3267 peek_n
(parser_state
*p
, int c
, int n
)
3274 if
(c0
< 0) return FALSE
;
3275 list
= push
(list
, (node
*)(intptr_t)c0
);
3278 p
->pb
= push
(p
->pb
, (node
*)list
);
3283 if
(c0
== c
) return TRUE
;
3286 #define peek(p,c) peek_n((p), (c), 0)
3289 peeks
(parser_state
*p
, const char *s
)
3291 int len
= strlen
(s
);
3296 if
(!peek_n
(p
, *s
++, n
++)) return FALSE
;
3300 else if
(p
->s
&& p
->s
+ len
>= p
->send
) {
3301 if
(memcmp
(p
->s
, s
, len
) == 0) return TRUE
;
3307 skips
(parser_state
*p
, const char *s
)
3312 // skip until first char
3315 if
(c
< 0) return c
;
3320 int len
= strlen
(s
);
3336 newtok
(parser_state
*p
)
3339 return p
->column
- 1;
3343 tokadd
(parser_state
*p
, int c
)
3345 if
(p
->bidx
< MRB_PARSER_BUF_SIZE
) {
3346 p
->buf
[p
->bidx
++] = c
;
3351 toklast
(parser_state
*p
)
3353 return p
->buf
[p
->bidx
-1];
3357 tokfix
(parser_state
*p
)
3359 if
(p
->bidx
>= MRB_PARSER_BUF_SIZE
) {
3360 yyerror(p
, "string too long (truncated)");
3362 p
->buf
[p
->bidx
] = '\0';
3366 tok
(parser_state
*p
)
3372 toklen
(parser_state
*p
)
3377 #define IS_ARG() (p->lstate == EXPR_ARG || p->lstate == EXPR_CMDARG)
3378 #define IS_END() (p->lstate == EXPR_END || p->lstate == EXPR_ENDARG || p->lstate == EXPR_ENDFN)
3379 #define IS_BEG() (p->lstate == EXPR_BEG || p->lstate == EXPR_MID || p->lstate == EXPR_VALUE || p->lstate == EXPR_CLASS)
3380 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
3381 #define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG())
3382 #define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
3385 scan_oct
(const int *start
, int len
, int *retlen
)
3387 const int *s
= start
;
3390 /* assert(len <= 3) */
3391 while
(len
-- && *s
>= '0' && *s
<= '7') {
3393 retval |
= *s
++ - '0';
3395 *retlen
= s
- start
;
3401 scan_hex
(const int *start
, int len
, int *retlen
)
3403 static const char hexdigit
[] = "0123456789abcdef0123456789ABCDEF";
3404 register
const int *s
= start
;
3405 register
int retval
= 0;
3408 /* assert(len <= 2) */
3409 while
(len
-- && *s
&& (tmp
= strchr
(hexdigit
, *s
))) {
3411 retval |
= (tmp
- hexdigit
) & 15;
3414 *retlen
= s
- start
;
3420 read_escape
(parser_state
*p
)
3424 switch
(c
= nextc
(p
)) {
3425 case
'\\': /* Backslash */
3428 case
'n': /* newline */
3431 case
't': /* horizontal tab */
3434 case
'r': /* carriage-return */
3437 case
'f': /* form-feed */
3440 case
'v': /* vertical tab */
3443 case
'a': /* alarm(bell) */
3446 case
'e': /* escape */
3449 case
'0': case
'1': case
'2': case
'3': /* octal constant */
3450 case
'4': case
'5': case
'6': case
'7':
3456 for
(i
=1; i
<3; i
++) {
3458 if
(buf
[i
] == -1) goto eof
;
3459 if
(buf
[i
] < '0' ||
'7' < buf
[i
]) {
3460 pushback
(p
, buf
[i
]);
3464 c
= scan_oct
(buf
, i
, &i
);
3468 case
'x': /* hex constant */
3473 for
(i
=0; i
<2; i
++) {
3475 if
(buf
[i
] == -1) goto eof
;
3476 if
(!isxdigit
(buf
[i
])) {
3477 pushback
(p
, buf
[i
]);
3481 c
= scan_hex
(buf
, i
, &i
);
3483 yyerror(p
, "Invalid escape character syntax");
3489 case
'b': /* backspace */
3492 case
's': /* space */
3496 if
((c
= nextc
(p
)) != '-') {
3497 yyerror(p
, "Invalid escape character syntax");
3501 if
((c
= nextc
(p
)) == '\\') {
3502 return read_escape
(p
) |
0x80;
3504 else if
(c
== -1) goto eof
;
3506 return
((c
& 0xff) |
0x80);
3510 if
((c
= nextc
(p
)) != '-') {
3511 yyerror(p
, "Invalid escape character syntax");
3516 if
((c
= nextc
(p
))== '\\') {
3521 else if
(c
== -1) goto eof
;
3526 yyerror(p
, "Invalid escape character syntax");
3536 parse_string
(parser_state
*p
)
3539 string_type type
= (string_type
)(intptr_t)p
->lex_strterm
->car
;
3540 int nest_level
= (intptr_t)p
->lex_strterm
->cdr
->car
;
3541 int beg
= (intptr_t)p
->lex_strterm
->cdr
->cdr
->car
;
3542 int end
= (intptr_t)p
->lex_strterm
->cdr
->cdr
->cdr
;
3543 parser_heredoc_info
*hinf
= (type
& STR_FUNC_HEREDOC
) ? parsing_heredoc_inf
(p
) : NULL
;
3546 while
((c
= nextc
(p
)) != end || nest_level
!= 0) {
3547 if
(hinf
&& (c
== '\n' || c
== -1)) {
3553 line_head
= hinf
->line_head
;
3554 hinf
->line_head
= TRUE
;
3556 /* check whether end of heredoc */
3557 const char *s
= tok
(p
);
3558 int len
= toklen
(p
);
3559 if
(hinf
->allow_indent
) {
3560 while
(ISSPACE
(*s
) && len
> 0) {
3565 if
((len
-1 == hinf
->term_len
) && (strncmp
(s
, hinf
->term
, len
-1) == 0)) {
3566 return tHEREDOC_END
;
3571 snprintf
(buf
, sizeof
(buf
), "can't find string \"%s\" anywhere before EOF", hinf
->term
);
3575 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
3579 yyerror(p
, "unterminated string meets end of file");
3582 else if
(c
== beg
) {
3584 p
->lex_strterm
->cdr
->car
= (node
*)(intptr_t)nest_level
;
3586 else if
(c
== end
) {
3588 p
->lex_strterm
->cdr
->car
= (node
*)(intptr_t)nest_level
;
3590 else if
(c
== '\\') {
3592 if
(type
& STR_FUNC_EXPAND
) {
3593 if
(c
== end || c
== beg
) {
3596 else if
((c
== '\n') && (type
& STR_FUNC_ARRAY
)) {
3604 if
(type
& STR_FUNC_REGEXP
)
3607 tokadd
(p
, read_escape
(p
));
3609 hinf
->line_head
= FALSE
;
3612 if
(c
!= beg
&& c
!= end
) {
3631 else if
((c
== '#') && (type
& STR_FUNC_EXPAND
)) {
3635 p
->lstate
= EXPR_BEG
;
3636 p
->cmd_start
= TRUE
;
3637 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
3639 hinf
->line_head
= FALSE
;
3640 return tSTRING_PART
;
3646 if
((type
& STR_FUNC_ARRAY
) && ISSPACE
(c
)) {
3647 if
(toklen
(p
) == 0) {
3653 } while
(ISSPACE
(c
= nextc
(p
)));
3655 return tLITERAL_DELIM
;
3659 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
3669 p
->lstate
= EXPR_END
;
3672 if
(type
& STR_FUNC_XQUOTE
) {
3673 yylval.nd
= new_xstr
(p
, tok
(p
), toklen
(p
));
3677 if
(type
& STR_FUNC_REGEXP
) {
3680 char *s
= strndup
(tok
(p
), toklen
(p
));
3681 char flag
[4] = { '\0' };
3684 while
(c
= nextc
(p
), ISALPHA
(c
)) {
3686 case
'i': f |
= 1; break
;
3687 case
'x': f |
= 2; break
;
3688 case
'm': f |
= 4; break
;
3689 default
: tokadd
(p
, c
); break
;
3696 snprintf
(msg
, sizeof
(msg
), "unknown regexp option%s - %s",
3697 toklen
(p
) > 1 ?
"s" : "", tok
(p
));
3700 if
(f
& 1) strcat
(flag
, "i");
3701 if
(f
& 2) strcat
(flag
, "x");
3702 if
(f
& 4) strcat
(flag
, "m");
3703 yylval.nd
= new_regx
(p
, s
, strdup
(flag
));
3708 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
3714 heredoc_identifier
(parser_state
*p
)
3717 int type
= str_heredoc
;
3721 parser_heredoc_info
*info
;
3724 if
(ISSPACE
(c
) || c
== '=') {
3732 if
(c
== '\'' || c
== '"') {
3737 while
((c
= nextc
(p
)) != -1 && c
!= term
) {
3745 yyerror(p
, "unterminated here document identifier");
3749 if
(! identchar
(c
)) {
3751 if
(indent
) pushback
(p
, '-');
3757 } while
((c
= nextc
(p
)) != -1 && identchar
(c
));
3761 newnode
= new_heredoc
(p
);
3762 info
= (parser_heredoc_info
*)newnode
->cdr
;
3763 info
->term
= strndup
(tok
(p
), toklen
(p
));
3764 info
->term_len
= toklen
(p
);
3766 type |
= STR_FUNC_EXPAND
;
3768 info
->allow_indent
= indent
;
3769 info
->line_head
= TRUE
;
3771 p
->heredocs
= push
(p
->heredocs
, newnode
);
3772 if
(p
->parsing_heredoc
== NULL
) {
3773 node
*n
= p
->heredocs
;
3776 p
->parsing_heredoc
= n
;
3778 p
->heredoc_starts_nextline
= TRUE
;
3779 p
->lstate
= EXPR_END
;
3781 yylval.nd
= newnode
;
3782 return tHEREDOC_BEG
;
3786 arg_ambiguous
(parser_state
*p
)
3788 yywarning
(p
, "ambiguous first argument; put parentheses or even spaces");
3795 parser_yylex
(parser_state
*p
)
3800 enum mrb_lex_state_enum last_state
;
3803 if
(p
->lex_strterm
) {
3804 if
(is_strterm_type
(p
, STR_FUNC_HEREDOC
)) {
3805 if
((p
->parsing_heredoc
!= NULL
) && (! p
->heredoc_starts_nextline
))
3806 return parse_string
(p
);
3809 return parse_string
(p
);
3811 cmd_state
= p
->cmd_start
;
3812 p
->cmd_start
= FALSE
;
3814 last_state
= p
->lstate
;
3815 switch
(c
= nextc
(p
)) {
3816 case
'\0': /* NUL */
3817 case
'\004': /* ^D */
3818 case
'\032': /* ^Z */
3819 case
-1: /* end of script. */
3823 case
' ': case
'\t': case
'\f': case
'\r':
3824 case
'\13': /* '\v' */
3828 case
'#': /* it's a comment */
3832 p
->heredoc_starts_nextline
= FALSE
;
3833 if
(p
->parsing_heredoc
!= NULL
) {
3834 p
->lex_strterm
= new_strterm
(p
, parsing_heredoc_inf
(p
)->type
, 0, 0);
3835 goto normal_newline
;
3837 switch
(p
->lstate
) {
3849 while
((c
= nextc
(p
))) {
3851 case
' ': case
'\t': case
'\f': case
'\r':
3852 case
'\13': /* '\v' */
3856 if
((c
= nextc
(p
)) != '.') {
3862 goto normal_newline
;
3865 goto normal_newline
;
3869 p
->cmd_start
= TRUE
;
3870 p
->lstate
= EXPR_BEG
;
3874 if
((c
= nextc
(p
)) == '*') {
3875 if
((c
= nextc
(p
)) == '=') {
3876 yylval.id
= intern
("**");
3877 p
->lstate
= EXPR_BEG
;
3885 yylval.id
= intern
("*");
3886 p
->lstate
= EXPR_BEG
;
3891 yywarning
(p
, "`*' interpreted as argument prefix");
3894 else if
(IS_BEG
()) {
3901 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3902 p
->lstate
= EXPR_ARG
;
3904 p
->lstate
= EXPR_BEG
;
3910 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3911 p
->lstate
= EXPR_ARG
;
3917 p
->lstate
= EXPR_BEG
;
3929 if
(p
->column
== 1) {
3930 if
(peeks
(p
, "begin\n")) {
3931 skips
(p
, "\n=end\n");
3935 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3936 p
->lstate
= EXPR_ARG
;
3938 p
->lstate
= EXPR_BEG
;
3940 if
((c
= nextc
(p
)) == '=') {
3941 if
((c
= nextc
(p
)) == '=') {
3950 else if
(c
== '>') {
3957 last_state
= p
->lstate
;
3960 p
->lstate
!= EXPR_DOT
&&
3961 p
->lstate
!= EXPR_CLASS
&&
3963 (!IS_ARG
() || space_seen
)) {
3964 int token
= heredoc_identifier
(p
);
3968 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3969 p
->lstate
= EXPR_ARG
;
3971 p
->lstate
= EXPR_BEG
;
3972 if
(p
->lstate
== EXPR_CLASS
) {
3973 p
->cmd_start
= TRUE
;
3977 if
((c
= nextc
(p
)) == '>') {
3984 if
((c
= nextc
(p
)) == '=') {
3985 yylval.id
= intern
("<<");
3986 p
->lstate
= EXPR_BEG
;
3996 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
3997 p
->lstate
= EXPR_ARG
;
3999 p
->lstate
= EXPR_BEG
;
4001 if
((c
= nextc
(p
)) == '=') {
4005 if
((c
= nextc
(p
)) == '=') {
4006 yylval.id
= intern
(">>");
4007 p
->lstate
= EXPR_BEG
;
4017 p
->lex_strterm
= new_strterm
(p
, str_dquote
, '"', 0);
4021 p
->lex_strterm
= new_strterm
(p
, str_squote
, '\'', 0);
4022 return parse_string
(p
);
4025 if
(p
->lstate
== EXPR_FNAME
) {
4026 p
->lstate
= EXPR_ENDFN
;
4029 if
(p
->lstate
== EXPR_DOT
) {
4031 p
->lstate
= EXPR_CMDARG
;
4033 p
->lstate
= EXPR_ARG
;
4036 p
->lex_strterm
= new_strterm
(p
, str_xquote
, '`', 0);
4037 return tXSTRING_BEG
;
4041 p
->lstate
= EXPR_VALUE
;
4046 yyerror(p
, "incomplete character syntax");
4077 snprintf
(buf
, sizeof
(buf
), "invalid character syntax; use ?\\%c", c2
);
4083 p
->lstate
= EXPR_VALUE
;
4086 token_column
= newtok
(p
);
4087 // need support UTF-8 if configured
4088 if
((isalnum
(c
) || c
== '_')) {
4091 if
((isalnum
(c2
) || c2
== '_')) {
4112 yylval.nd
= new_str
(p
, tok
(p
), toklen
(p
));
4113 p
->lstate
= EXPR_END
;
4117 if
((c
= nextc
(p
)) == '&') {
4118 p
->lstate
= EXPR_BEG
;
4119 if
((c
= nextc
(p
)) == '=') {
4120 yylval.id
= intern
("&&");
4121 p
->lstate
= EXPR_BEG
;
4127 else if
(c
== '=') {
4128 yylval.id
= intern
("&");
4129 p
->lstate
= EXPR_BEG
;
4134 yywarning
(p
, "`&' interpreted as argument prefix");
4137 else if
(IS_BEG
()) {
4143 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4144 p
->lstate
= EXPR_ARG
;
4146 p
->lstate
= EXPR_BEG
;
4151 if
((c
= nextc
(p
)) == '|') {
4152 p
->lstate
= EXPR_BEG
;
4153 if
((c
= nextc
(p
)) == '=') {
4154 yylval.id
= intern
("||");
4155 p
->lstate
= EXPR_BEG
;
4162 yylval.id
= intern
("|");
4163 p
->lstate
= EXPR_BEG
;
4166 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4167 p
->lstate
= EXPR_ARG
;
4170 p
->lstate
= EXPR_BEG
;
4177 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4178 p
->lstate
= EXPR_ARG
;
4186 yylval.id
= intern
("+");
4187 p
->lstate
= EXPR_BEG
;
4190 if
(IS_BEG
() ||
(IS_SPCARG
(c
) && arg_ambiguous
(p
))) {
4191 p
->lstate
= EXPR_BEG
;
4193 if
(c
!= -1 && ISDIGIT
(c
)) {
4199 p
->lstate
= EXPR_BEG
;
4205 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4206 p
->lstate
= EXPR_ARG
;
4214 yylval.id
= intern
("-");
4215 p
->lstate
= EXPR_BEG
;
4219 p
->lstate
= EXPR_ENDFN
;
4222 if
(IS_BEG
() ||
(IS_SPCARG
(c
) && arg_ambiguous
(p
))) {
4223 p
->lstate
= EXPR_BEG
;
4225 if
(c
!= -1 && ISDIGIT
(c
)) {
4230 p
->lstate
= EXPR_BEG
;
4235 p
->lstate
= EXPR_BEG
;
4236 if
((c
= nextc
(p
)) == '.') {
4237 if
((c
= nextc
(p
)) == '.') {
4244 if
(c
!= -1 && ISDIGIT
(c
)) {
4245 yyerror(p
, "no .<digit> floating literal anymore; put 0 before dot");
4247 p
->lstate
= EXPR_DOT
;
4251 case
'0': case
'1': case
'2': case
'3': case
'4':
4252 case
'5': case
'6': case
'7': case
'8': case
'9':
4254 int is_float
, seen_point
, seen_e
, nondigit
;
4256 is_float
= seen_point
= seen_e
= nondigit
= 0;
4257 p
->lstate
= EXPR_END
;
4258 token_column
= newtok
(p
);
4259 if
(c
== '-' || c
== '+') {
4264 #define no_digits() do {yyerror(p,"numeric literal without digits"); return 0;} while (0)
4265 int start
= toklen
(p
);
4267 if
(c
== 'x' || c
== 'X') {
4270 if
(c
!= -1 && ISXDIGIT
(c
)) {
4273 if
(nondigit
) break
;
4277 if
(!ISXDIGIT
(c
)) break
;
4279 tokadd
(p
, tolower
(c
));
4280 } while
((c
= nextc
(p
)) != -1);
4284 if
(toklen
(p
) == start
) {
4287 else if
(nondigit
) goto trailing_uc
;
4288 yylval.nd
= new_int
(p
, tok
(p
), 16);
4291 if
(c
== 'b' || c
== 'B') {
4294 if
(c
== '0' || c
== '1') {
4297 if
(nondigit
) break
;
4301 if
(c
!= '0' && c
!= '1') break
;
4304 } while
((c
= nextc
(p
)) != -1);
4308 if
(toklen
(p
) == start
) {
4311 else if
(nondigit
) goto trailing_uc
;
4312 yylval.nd
= new_int
(p
, tok
(p
), 2);
4315 if
(c
== 'd' || c
== 'D') {
4318 if
(c
!= -1 && ISDIGIT
(c
)) {
4321 if
(nondigit
) break
;
4325 if
(!ISDIGIT
(c
)) break
;
4328 } while
((c
= nextc
(p
)) != -1);
4332 if
(toklen
(p
) == start
) {
4335 else if
(nondigit
) goto trailing_uc
;
4336 yylval.nd
= new_int
(p
, tok
(p
), 10);
4343 if
(c
== 'o' || c
== 'O') {
4344 /* prefixed octal */
4346 if
(c
== -1 || c
== '_' ||
!ISDIGIT
(c
)) {
4350 if
(c
>= '0' && c
<= '7') {
4355 if
(nondigit
) break
;
4359 if
(c
< '0' || c
> '9') break
;
4360 if
(c
> '7') goto invalid_octal
;
4363 } while
((c
= nextc
(p
)) != -1);
4365 if
(toklen
(p
) > start
) {
4368 if
(nondigit
) goto trailing_uc
;
4369 yylval.nd
= new_int
(p
, tok
(p
), 8);
4377 if
(c
> '7' && c
<= '9') {
4379 yyerror(p
, "Invalid octal digit");
4381 else if
(c
== '.' || c
== 'e' || c
== 'E') {
4386 yylval.nd
= new_int
(p
, "0", 10);
4393 case
'0': case
'1': case
'2': case
'3': case
'4':
4394 case
'5': case
'6': case
'7': case
'8': case
'9':
4400 if
(nondigit
) goto trailing_uc
;
4401 if
(seen_point || seen_e
) {
4406 if
(c0
== -1 ||
!ISDIGIT
(c0
)) {
4434 if
(c
!= '-' && c
!= '+') continue
;
4439 case
'_': /* `_' in number just ignored */
4440 if
(nondigit
) goto decode_num
;
4454 yyerror_i
(p
, "trailing `%c' in number", nondigit
);
4462 d
= strtod
(tok
(p
), &endp
);
4463 if
(d
== 0 && endp
== tok
(p
)) {
4464 yywarning_s
(p
, "corrupted float value %s", tok
(p
));
4466 else if
(errno
== ERANGE
) {
4467 yywarning_s
(p
, "float %s out of range", tok
(p
));
4470 yylval.nd
= new_float
(p
, tok
(p
));
4473 yylval.nd
= new_int
(p
, tok
(p
), 10);
4484 p
->lstate
= EXPR_ENDFN
;
4486 p
->lstate
= EXPR_ENDARG
;
4492 if
(IS_BEG
() || p
->lstate
== EXPR_CLASS || IS_SPCARG
(-1)) {
4493 p
->lstate
= EXPR_BEG
;
4496 p
->lstate
= EXPR_DOT
;
4499 if
(IS_END
() || ISSPACE
(c
)) {
4501 p
->lstate
= EXPR_BEG
;
4505 p
->lstate
= EXPR_FNAME
;
4510 p
->lex_strterm
= new_strterm
(p
, str_regexp
, '/', 0);
4513 if
((c
= nextc
(p
)) == '=') {
4514 yylval.id
= intern
("/");
4515 p
->lstate
= EXPR_BEG
;
4520 p
->lex_strterm
= new_strterm
(p
, str_regexp
, '/', 0);
4523 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4524 p
->lstate
= EXPR_ARG
;
4526 p
->lstate
= EXPR_BEG
;
4531 if
((c
= nextc
(p
)) == '=') {
4532 yylval.id
= intern
("^");
4533 p
->lstate
= EXPR_BEG
;
4536 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4537 p
->lstate
= EXPR_ARG
;
4539 p
->lstate
= EXPR_BEG
;
4545 p
->lstate
= EXPR_BEG
;
4549 p
->lstate
= EXPR_BEG
;
4553 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4554 if
((c
= nextc
(p
)) != '@') {
4557 p
->lstate
= EXPR_ARG
;
4560 p
->lstate
= EXPR_BEG
;
4568 else if
(IS_SPCARG
(-1)) {
4574 p
->lstate
= EXPR_BEG
;
4579 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4580 p
->lstate
= EXPR_ARG
;
4581 if
((c
= nextc
(p
)) == ']') {
4582 if
((c
= nextc
(p
)) == '=') {
4591 else if
(IS_BEG
()) {
4594 else if
(IS_ARG
() && space_seen
) {
4597 p
->lstate
= EXPR_BEG
;
4603 if
(p
->lpar_beg
&& p
->lpar_beg
== p
->paren_nest
) {
4604 p
->lstate
= EXPR_BEG
;
4611 if
(IS_ARG
() || p
->lstate
== EXPR_END || p
->lstate
== EXPR_ENDFN
)
4612 c
= '{'; /* block (primary) */
4613 else if
(p
->lstate
== EXPR_ENDARG
)
4614 c
= tLBRACE_ARG
; /* block (expr) */
4616 c
= tLBRACE
; /* hash */
4619 p
->lstate
= EXPR_BEG
;
4628 goto retry
; /* skip \\n */
4640 if
(c
== -1 ||
!ISALNUM
(c
)) {
4646 if
(isalnum
(term
)) {
4647 yyerror(p
, "unknown type of %string");
4651 if
(c
== -1 || term
== -1) {
4652 yyerror(p
, "unterminated quoted string meets end of file");
4656 if
(term
== '(') term
= ')';
4657 else if
(term
== '[') term
= ']';
4658 else if
(term
== '{') term
= '}';
4659 else if
(term
== '<') term
= '>';
4664 p
->lex_strterm
= new_strterm
(p
, str_dquote
, term
, paren
);
4668 p
->lex_strterm
= new_strterm
(p
, str_squote
, term
, paren
);
4669 return parse_string
(p
);
4672 p
->lex_strterm
= new_strterm
(p
, str_dword
, term
, paren
);
4676 p
->lex_strterm
= new_strterm
(p
, str_sword
, term
, paren
);
4680 p
->lex_strterm
= new_strterm
(p
, str_xquote
, term
, paren
);
4681 return tXSTRING_BEG
;
4684 p
->lex_strterm
= new_strterm
(p
, str_regexp
, term
, paren
);
4688 p
->lex_strterm
= new_strterm
(p
, str_ssym
, term
, paren
);
4692 p
->lex_strterm
= new_strterm
(p
, str_dsymbols
, term
, paren
);
4693 return tSYMBOLS_BEG
;
4696 p
->lex_strterm
= new_strterm
(p
, str_ssymbols
, term
, paren
);
4697 return tSYMBOLS_BEG
;
4700 yyerror(p
, "unknown type of %string");
4704 if
((c
= nextc
(p
)) == '=') {
4705 yylval.id
= intern
("%");
4706 p
->lstate
= EXPR_BEG
;
4712 if
(p
->lstate
== EXPR_FNAME || p
->lstate
== EXPR_DOT
) {
4713 p
->lstate
= EXPR_ARG
;
4715 p
->lstate
= EXPR_BEG
;
4721 p
->lstate
= EXPR_END
;
4722 token_column
= newtok
(p
);
4725 case
'_': /* $_: last read line string */
4730 case
'~': /* $~: match-data */
4731 case
'*': /* $*: argv */
4732 case
'$': /* $$: pid */
4733 case
'?': /* $?: last status */
4734 case
'!': /* $!: error string */
4735 case
'@': /* $@: error position */
4736 case
'/': /* $/: input record separator */
4737 case
'\\': /* $\: output record separator */
4738 case
';': /* $;: field separator */
4739 case
',': /* $,: output field separator */
4740 case
'.': /* $.: last read line number */
4741 case
'=': /* $=: ignorecase */
4742 case
':': /* $:: load path */
4743 case
'<': /* $<: reading filename */
4744 case
'>': /* $>: default output handle */
4745 case
'\"': /* $": already loaded files */
4749 yylval.id
= intern
(tok
(p
));
4759 yylval.id
= intern
(tok
(p
));
4762 case
'&': /* $&: last match */
4763 case
'`': /* $`: string before last match */
4764 case
'\'': /* $': string after last match */
4765 case
'+': /* $+: string matches last pattern */
4766 if
(last_state
== EXPR_FNAME
) {
4771 yylval.nd
= new_back_ref
(p
, c
);
4774 case
'1': case
'2': case
'3':
4775 case
'4': case
'5': case
'6':
4776 case
'7': case
'8': case
'9':
4780 } while
(c
!= -1 && isdigit
(c
));
4782 if
(last_state
== EXPR_FNAME
) goto gvar
;
4784 yylval.nd
= new_nth_ref
(p
, atoi
(tok
(p
)));
4788 if
(!identchar
(c
)) {
4799 token_column
= newtok
(p
);
4805 if
(c
!= -1 && isdigit
(c
)) {
4807 yyerror_i
(p
, "`@%c' is not allowed as an instance variable name", c
);
4810 yyerror_i
(p
, "`@@%c' is not allowed as a class variable name", c
);
4814 if
(!identchar
(c
)) {
4821 token_column
= newtok
(p
);
4825 if
(!identchar
(c
)) {
4826 yyerror_i
(p
, "Invalid char `\\x%02X' in expression", c
);
4830 token_column
= newtok
(p
);
4838 } while
(identchar
(c
));
4839 if
(token_column
== 0 && toklen
(p
) == 7 && (c
< 0 || c
== '\n') &&
4840 strncmp
(tok
(p
), "__END__", toklen
(p
)) == 0)
4843 switch
(tok
(p
)[0]) {
4848 if
((c
== '!' || c
== '?') && !peek
(p
, '=')) {
4859 last_state
= p
->lstate
;
4860 switch
(tok
(p
)[0]) {
4862 p
->lstate
= EXPR_END
;
4866 p
->lstate
= EXPR_END
;
4867 if
(tok
(p
)[1] == '@')
4874 if
(toklast
(p
) == '!' || toklast
(p
) == '?') {
4878 if
(p
->lstate
== EXPR_FNAME
) {
4879 if
((c
= nextc
(p
)) == '=' && !peek
(p
, '~') && !peek
(p
, '>') &&
4880 (!peek
(p
, '=') ||
(peek_n
(p
, '>', 1)))) {
4881 result
= tIDENTIFIER
;
4889 if
(result
== 0 && isupper
((int)tok
(p
)[0])) {
4893 result
= tIDENTIFIER
;
4897 if
(IS_LABEL_POSSIBLE
()) {
4898 if
(IS_LABEL_SUFFIX
(0)) {
4899 p
->lstate
= EXPR_BEG
;
4902 yylval.id
= intern
(tok
(p
));
4906 if
(p
->lstate
!= EXPR_DOT
) {
4907 const struct kwtable
*kw
;
4909 /* See if it is a reserved word. */
4910 kw
= mrb_reserved_word
(tok
(p
), toklen
(p
));
4912 enum mrb_lex_state_enum state
= p
->lstate
;
4913 p
->lstate
= kw
->state
;
4914 if
(state
== EXPR_FNAME
) {
4915 yylval.id
= intern
(kw
->name
);
4918 if
(p
->lstate
== EXPR_BEG
) {
4919 p
->cmd_start
= TRUE
;
4921 if
(kw
->id
[0] == keyword_do
) {
4922 if
(p
->lpar_beg
&& p
->lpar_beg
== p
->paren_nest
) {
4925 return keyword_do_LAMBDA
;
4927 if
(COND_P
()) return keyword_do_cond
;
4928 if
(CMDARG_P
() && state
!= EXPR_CMDARG
)
4929 return keyword_do_block
;
4930 if
(state
== EXPR_ENDARG || state
== EXPR_BEG
)
4931 return keyword_do_block
;
4934 if
(state
== EXPR_BEG || state
== EXPR_VALUE
)
4937 if
(kw
->id
[0] != kw
->id
[1])
4938 p
->lstate
= EXPR_BEG
;
4944 if
(IS_BEG
() || p
->lstate
== EXPR_DOT || IS_ARG
()) {
4946 p
->lstate
= EXPR_CMDARG
;
4949 p
->lstate
= EXPR_ARG
;
4952 else if
(p
->lstate
== EXPR_FNAME
) {
4953 p
->lstate
= EXPR_ENDFN
;
4956 p
->lstate
= EXPR_END
;
4960 mrb_sym ident
= intern
(tok
(p
));
4964 if
(last_state
!= EXPR_DOT
&& islower
(tok
(p
)[0]) && lvar_defined
(ident
)) {
4965 p
->lstate
= EXPR_END
;
4974 yylex(void *lval
, parser_state
*p
)
4979 t
= parser_yylex
(p
);
4985 parser_init_cxt
(parser_state
*p
, mrbc_context
*cxt
)
4988 if
(cxt
->lineno
) p
->lineno
= cxt
->lineno
;
4989 if
(cxt
->filename
) p
->filename
= cxt
->filename
;
4993 p
->locals
= cons
(0,0);
4994 for
(i
=0; i
<cxt
->slen
; i
++) {
4995 local_add_f
(p
, cxt
->syms
[i
]);
4998 p
->capture_errors
= cxt
->capture_errors
;
5002 parser_update_cxt
(parser_state
*p
, mrbc_context
*cxt
)
5008 if
((int)(intptr_t)p
->tree
->car
!= NODE_SCOPE
) return
;
5009 n0
= n
= p
->tree
->cdr
->car
;
5014 cxt
->syms
= (mrb_sym
*)mrb_realloc
(p
->mrb
, cxt
->syms
, i
*sizeof
(mrb_sym
));
5016 for
(i
=0, n
=n0
; n
; i
++,n
=n
->cdr
) {
5017 cxt
->syms
[i
] = sym
(n
->car
);
5021 void codedump_all
(mrb_state
*, int);
5022 void parser_dump
(mrb_state
*mrb
, node
*tree
, int offset
);
5025 mrb_parser_parse
(parser_state
*p
, mrbc_context
*c
)
5027 if
(setjmp
(p
->jmp
) != 0) {
5028 yyerror(p
, "memory allocation error");
5034 p
->cmd_start
= TRUE
;
5035 p
->in_def
= p
->in_single
= FALSE
;
5036 p
->nerr
= p
->nwarn
= 0;
5037 p
->lex_strterm
= NULL
;
5039 parser_init_cxt
(p
, c
);
5042 p
->tree
= new_nil
(p
);
5044 parser_update_cxt
(p
, c
);
5045 if
(c
&& c
->dump_result
) {
5046 parser_dump
(p
->mrb
, p
->tree
, 0);
5051 mrb_parser_new
(mrb_state
*mrb
)
5055 static const parser_state parser_state_zero
= { 0 };
5057 pool
= mrb_pool_open
(mrb
);
5058 if
(!pool
) return
0;
5059 p
= (parser_state
*)mrb_pool_alloc
(pool
, sizeof
(parser_state
));
5062 *p
= parser_state_zero
;
5065 p
->in_def
= p
->in_single
= 0;
5067 p
->s
= p
->send
= NULL
;
5070 p
->cmd_start
= TRUE
;
5071 p
->in_def
= p
->in_single
= FALSE
;
5073 p
->capture_errors
= 0;
5076 #if defined(PARSER_TEST) || defined(PARSER_DEBUG)
5080 p
->lex_strterm
= NULL
;
5081 p
->heredocs
= p
->parsing_heredoc
= NULL
;
5087 mrb_parser_free
(parser_state
*p
) {
5088 mrb_pool_close
(p
->pool
);
5092 mrbc_context_new
(mrb_state
*mrb
)
5096 c
= (mrbc_context
*)mrb_calloc
(mrb
, 1, sizeof
(mrbc_context
));
5101 mrbc_context_free
(mrb_state
*mrb
, mrbc_context
*cxt
)
5103 mrb_free
(mrb
, cxt
->syms
);
5108 mrbc_filename
(mrb_state
*mrb
, mrbc_context
*c
, const char *s
)
5111 int len
= strlen
(s
);
5112 char *p
= (char *)mrb_alloca
(mrb
, len
+ 1);
5114 memcpy
(p
, s
, len
+ 1);
5122 mrb_parse_file
(mrb_state
*mrb
, FILE *f
, mrbc_context
*c
)
5126 p
= mrb_parser_new
(mrb
);
5128 p
->s
= p
->send
= NULL
;
5131 mrb_parser_parse
(p
, c
);
5136 mrb_parse_nstring
(mrb_state
*mrb
, const char *s
, int len
, mrbc_context
*c
)
5140 p
= mrb_parser_new
(mrb
);
5145 mrb_parser_parse
(p
, c
);
5150 mrb_parse_string
(mrb_state
*mrb
, const char *s
, mrbc_context
*c
)
5152 return mrb_parse_nstring
(mrb
, s
, strlen
(s
), c
);
5156 load_exec
(mrb_state
*mrb
, parser_state
*p
, mrbc_context
*c
)
5162 return mrb_undef_value
();
5164 if
(!p
->tree || p
->nerr
) {
5165 if
(p
->capture_errors
) {
5168 n
= snprintf
(buf
, sizeof
(buf
), "line %d: %s\n",
5169 p
->error_buffer
[0].lineno
, p
->error_buffer
[0].message
);
5170 mrb
->exc
= mrb_obj_ptr
(mrb_exc_new
(mrb
, E_SYNTAX_ERROR
, buf
, n
));
5172 return mrb_undef_value
();
5175 static const char msg
[] = "syntax error";
5176 mrb
->exc
= mrb_obj_ptr
(mrb_exc_new
(mrb
, E_SYNTAX_ERROR
, msg
, sizeof
(msg
) - 1));
5178 return mrb_undef_value
();
5181 n
= mrb_generate_code
(mrb
, p
);
5184 static const char msg
[] = "codegen error";
5185 mrb
->exc
= mrb_obj_ptr
(mrb_exc_new
(mrb
, E_SCRIPT_ERROR
, msg
, sizeof
(msg
) - 1));
5186 return mrb_nil_value
();
5189 if
(c
->dump_result
) codedump_all
(mrb
, n
);
5190 if
(c
->no_exec
) return mrb_fixnum_value
(n
);
5192 v
= mrb_run
(mrb
, mrb_proc_new
(mrb
, mrb
->irep
[n
]), mrb_top_self
(mrb
));
5193 if
(mrb
->exc
) return mrb_nil_value
();
5198 mrb_load_file_cxt
(mrb_state
*mrb
, FILE *f
, mrbc_context
*c
)
5200 return load_exec
(mrb
, mrb_parse_file
(mrb
, f
, c
), c
);
5204 mrb_load_file
(mrb_state
*mrb
, FILE *f
)
5206 return mrb_load_file_cxt
(mrb
, f
, NULL
);
5210 mrb_load_nstring_cxt
(mrb_state
*mrb
, const char *s
, int len
, mrbc_context
*c
)
5212 return load_exec
(mrb
, mrb_parse_nstring
(mrb
, s
, len
, c
), c
);
5216 mrb_load_nstring
(mrb_state
*mrb
, const char *s
, int len
)
5218 return mrb_load_nstring_cxt
(mrb
, s
, len
, NULL
);
5222 mrb_load_string_cxt
(mrb_state
*mrb
, const char *s
, mrbc_context
*c
)
5224 return mrb_load_nstring_cxt
(mrb
, s
, strlen
(s
), c
);
5228 mrb_load_string
(mrb_state
*mrb
, const char *s
)
5230 return mrb_load_string_cxt
(mrb
, s
, NULL
);
5236 dump_prefix
(int offset
)
5245 dump_recur
(mrb_state
*mrb
, node
*tree
, int offset
)
5248 parser_dump
(mrb
, tree
->car
, offset
);
5256 parser_dump
(mrb_state
*mrb
, node
*tree
, int offset
)
5263 dump_prefix
(offset
);
5264 n
= (int)(intptr_t)tree
->car
;
5268 printf
("NODE_BEGIN:\n");
5269 dump_recur
(mrb
, tree
, offset
+1);
5273 printf
("NODE_RESCUE:\n");
5275 dump_prefix
(offset
+1);
5277 parser_dump
(mrb
, tree
->car
, offset
+2);
5281 node
*n2
= tree
->car
;
5283 dump_prefix
(offset
+1);
5284 printf
("rescue:\n");
5288 dump_prefix
(offset
+2);
5289 printf
("handle classes:\n");
5290 dump_recur
(mrb
, n3
->car
, offset
+3);
5293 dump_prefix
(offset
+2);
5294 printf
("exc_var:\n");
5295 parser_dump
(mrb
, n3
->cdr
->car
, offset
+3);
5297 if
(n3
->cdr
->cdr
->car
) {
5298 dump_prefix
(offset
+2);
5299 printf
("rescue body:\n");
5300 parser_dump
(mrb
, n3
->cdr
->cdr
->car
, offset
+3);
5307 dump_prefix
(offset
+1);
5309 parser_dump
(mrb
, tree
->car
, offset
+2);
5314 printf
("NODE_ENSURE:\n");
5315 dump_prefix
(offset
+1);
5317 parser_dump
(mrb
, tree
->car
, offset
+2);
5318 dump_prefix
(offset
+1);
5319 printf
("ensure:\n");
5320 parser_dump
(mrb
, tree
->cdr
->cdr
, offset
+2);
5324 printf
("NODE_BLOCK:\n");
5329 printf
("NODE_BLOCK:\n");
5332 node
*n
= tree
->car
;
5335 dump_prefix
(offset
+1);
5336 printf
("mandatory args:\n");
5337 dump_recur
(mrb
, n
->car
, offset
+2);
5341 dump_prefix
(offset
+1);
5342 printf
("optional args:\n");
5347 dump_prefix
(offset
+2);
5348 printf
("%s=", mrb_sym2name
(mrb
, sym
(n2
->car
->car
)));
5349 parser_dump
(mrb
, n2
->car
->cdr
, 0);
5356 dump_prefix
(offset
+1);
5357 printf
("rest=*%s\n", mrb_sym2name
(mrb
, sym
(n
->car
)));
5361 dump_prefix
(offset
+1);
5362 printf
("post mandatory args:\n");
5363 dump_recur
(mrb
, n
->car
, offset
+2);
5367 dump_prefix
(offset
+1);
5368 printf
("blk=&%s\n", mrb_sym2name
(mrb
, sym
(n
)));
5371 dump_prefix
(offset
+1);
5373 parser_dump
(mrb
, tree
->cdr
->car
, offset
+2);
5377 printf
("NODE_IF:\n");
5378 dump_prefix
(offset
+1);
5380 parser_dump
(mrb
, tree
->car
, offset
+2);
5381 dump_prefix
(offset
+1);
5383 parser_dump
(mrb
, tree
->cdr
->car
, offset
+2);
5384 if
(tree
->cdr
->cdr
->car
) {
5385 dump_prefix
(offset
+1);
5387 parser_dump
(mrb
, tree
->cdr
->cdr
->car
, offset
+2);
5392 printf
("NODE_AND:\n");
5393 parser_dump
(mrb
, tree
->car
, offset
+1);
5394 parser_dump
(mrb
, tree
->cdr
, offset
+1);
5398 printf
("NODE_OR:\n");
5399 parser_dump
(mrb
, tree
->car
, offset
+1);
5400 parser_dump
(mrb
, tree
->cdr
, offset
+1);
5404 printf
("NODE_CASE:\n");
5406 parser_dump
(mrb
, tree
->car
, offset
+1);
5410 dump_prefix
(offset
+1);
5412 dump_recur
(mrb
, tree
->car
->car
, offset
+2);
5413 dump_prefix
(offset
+1);
5415 parser_dump
(mrb
, tree
->car
->cdr
, offset
+2);
5421 printf
("NODE_WHILE:\n");
5422 dump_prefix
(offset
+1);
5424 parser_dump
(mrb
, tree
->car
, offset
+2);
5425 dump_prefix
(offset
+1);
5427 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5431 printf
("NODE_UNTIL:\n");
5432 dump_prefix
(offset
+1);
5434 parser_dump
(mrb
, tree
->car
, offset
+2);
5435 dump_prefix
(offset
+1);
5437 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5441 printf
("NODE_FOR:\n");
5442 dump_prefix
(offset
+1);
5445 node
*n2
= tree
->car
;
5448 dump_prefix
(offset
+2);
5450 dump_recur
(mrb
, n2
->car
, offset
+3);
5455 dump_prefix
(offset
+2);
5457 parser_dump
(mrb
, n2
->car
, offset
+3);
5462 dump_prefix
(offset
+2);
5464 dump_recur
(mrb
, n2
->car
, offset
+3);
5470 dump_prefix
(offset
+1);
5472 parser_dump
(mrb
, tree
->car
, offset
+2);
5474 dump_prefix
(offset
+1);
5476 parser_dump
(mrb
, tree
->car
, offset
+2);
5480 printf
("NODE_SCOPE:\n");
5482 node
*n2
= tree
->car
;
5484 if
(n2
&& (n2
->car || n2
->cdr
)) {
5485 dump_prefix
(offset
+1);
5486 printf
("local variables:\n");
5487 dump_prefix
(offset
+2);
5490 if
(n2
!= tree
->car
) printf
(", ");
5491 printf
("%s", mrb_sym2name
(mrb
, sym
(n2
->car
)));
5504 printf
("NODE_CALL:\n");
5505 parser_dump
(mrb
, tree
->car
, offset
+1);
5506 dump_prefix
(offset
+1);
5507 printf
("method='%s' (%d)\n",
5508 mrb_sym2name
(mrb
, sym
(tree
->cdr
->car
)),
5509 (int)(intptr_t)tree
->cdr
->car
);
5510 tree
= tree
->cdr
->cdr
->car
;
5512 dump_prefix
(offset
+1);
5514 dump_recur
(mrb
, tree
->car
, offset
+2);
5516 dump_prefix
(offset
+1);
5518 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5524 printf
("NODE_DOT2:\n");
5525 parser_dump
(mrb
, tree
->car
, offset
+1);
5526 parser_dump
(mrb
, tree
->cdr
, offset
+1);
5530 printf
("NODE_DOT3:\n");
5531 parser_dump
(mrb
, tree
->car
, offset
+1);
5532 parser_dump
(mrb
, tree
->cdr
, offset
+1);
5536 printf
("NODE_COLON2:\n");
5537 parser_dump
(mrb
, tree
->car
, offset
+1);
5538 dump_prefix
(offset
+1);
5539 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->cdr
)));
5543 printf
("NODE_COLON3:\n");
5544 dump_prefix
(offset
+1);
5545 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5549 printf
("NODE_ARRAY:\n");
5550 dump_recur
(mrb
, tree
, offset
+1);
5554 printf
("NODE_HASH:\n");
5556 dump_prefix
(offset
+1);
5558 parser_dump
(mrb
, tree
->car
->car
, offset
+2);
5559 dump_prefix
(offset
+1);
5561 parser_dump
(mrb
, tree
->car
->cdr
, offset
+2);
5567 printf
("NODE_SPLAT:\n");
5568 parser_dump
(mrb
, tree
, offset
+1);
5572 printf
("NODE_ASGN:\n");
5573 dump_prefix
(offset
+1);
5575 parser_dump
(mrb
, tree
->car
, offset
+2);
5576 dump_prefix
(offset
+1);
5578 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5582 printf
("NODE_MASGN:\n");
5583 dump_prefix
(offset
+1);
5586 node
*n2
= tree
->car
;
5589 dump_prefix
(offset
+2);
5591 dump_recur
(mrb
, n2
->car
, offset
+3);
5596 dump_prefix
(offset
+2);
5598 if
(n2
->car
== (node
*)-1) {
5599 dump_prefix
(offset
+2);
5600 printf
("(empty)\n");
5603 parser_dump
(mrb
, n2
->car
, offset
+3);
5609 dump_prefix
(offset
+2);
5611 dump_recur
(mrb
, n2
->car
, offset
+3);
5616 dump_prefix
(offset
+1);
5618 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5622 printf
("NODE_OP_ASGN:\n");
5623 dump_prefix
(offset
+1);
5625 parser_dump
(mrb
, tree
->car
, offset
+2);
5627 dump_prefix
(offset
+1);
5628 printf
("op='%s' (%d)\n", mrb_sym2name
(mrb
, sym
(tree
->car
)), (int)(intptr_t)tree
->car
);
5630 parser_dump
(mrb
, tree
->car
, offset
+1);
5634 printf
("NODE_SUPER:\n");
5636 dump_prefix
(offset
+1);
5638 dump_recur
(mrb
, tree
->car
, offset
+2);
5640 dump_prefix
(offset
+1);
5642 parser_dump
(mrb
, tree
->cdr
, offset
+2);
5648 printf
("NODE_ZSUPER\n");
5652 printf
("NODE_RETURN:\n");
5653 parser_dump
(mrb
, tree
, offset
+1);
5657 printf
("NODE_YIELD:\n");
5658 dump_recur
(mrb
, tree
, offset
+1);
5662 printf
("NODE_BREAK:\n");
5663 parser_dump
(mrb
, tree
, offset
+1);
5667 printf
("NODE_NEXT:\n");
5668 parser_dump
(mrb
, tree
, offset
+1);
5672 printf
("NODE_REDO\n");
5676 printf
("NODE_RETRY\n");
5680 printf
("NODE_LVAR %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5684 printf
("NODE_GVAR %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5688 printf
("NODE_IVAR %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5692 printf
("NODE_CVAR %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5696 printf
("NODE_CONST %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5700 printf
("NODE_MATCH:\n");
5701 dump_prefix
(offset
+ 1);
5703 parser_dump
(mrb
, tree
->car
, offset
+ 2);
5704 dump_prefix
(offset
+ 1);
5706 parser_dump
(mrb
, tree
->cdr
, offset
+ 2);
5710 printf
("NODE_BACK_REF: $%c\n", (int)(intptr_t)tree
);
5714 printf
("NODE_NTH_REF: $%d\n", (int)(intptr_t)tree
);
5718 printf
("NODE_ARG %s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5721 case NODE_BLOCK_ARG
:
5722 printf
("NODE_BLOCK_ARG:\n");
5723 parser_dump
(mrb
, tree
, offset
+1);
5727 printf
("NODE_INT %s base %d\n", (char*)tree
->car
, (int)(intptr_t)tree
->cdr
->car
);
5731 printf
("NODE_FLOAT %s\n", (char*)tree
);
5735 printf
("NODE_NEGATE\n");
5736 parser_dump
(mrb
, tree
, offset
+1);
5740 printf
("NODE_STR \"%s\" len %d\n", (char*)tree
->car
, (int)(intptr_t)tree
->cdr
);
5744 printf
("NODE_DSTR\n");
5745 dump_recur
(mrb
, tree
, offset
+1);
5749 printf
("NODE_XSTR \"%s\" len %d\n", (char*)tree
->car
, (int)(intptr_t)tree
->cdr
);
5753 printf
("NODE_DXSTR\n");
5754 dump_recur
(mrb
, tree
, offset
+1);
5758 printf
("NODE_REGX /%s/%s\n", (char*)tree
->car
, (char*)tree
->cdr
);
5762 printf
("NODE_DREGX\n");
5763 dump_recur
(mrb
, tree
->car
, offset
+1);
5764 dump_prefix
(offset
);
5765 printf
("tail: %s\n", (char*)tree
->cdr
->cdr
->car
);
5766 dump_prefix
(offset
);
5767 printf
("opt: %s\n", (char*)tree
->cdr
->cdr
->cdr
);
5771 printf
("NODE_SYM :%s\n", mrb_sym2name
(mrb
, sym
(tree
)));
5775 printf
("NODE_SELF\n");
5779 printf
("NODE_NIL\n");
5783 printf
("NODE_TRUE\n");
5787 printf
("NODE_FALSE\n");
5791 printf
("NODE_ALIAS %s %s:\n",
5792 mrb_sym2name
(mrb
, sym
(tree
->car
)),
5793 mrb_sym2name
(mrb
, sym
(tree
->cdr
)));
5797 printf
("NODE_UNDEF");
5801 printf
(" %s", mrb_sym2name
(mrb
, sym
(t
->car
)));
5809 printf
("NODE_CLASS:\n");
5810 if
(tree
->car
->car
== (node
*)0) {
5811 dump_prefix
(offset
+1);
5812 printf
(":%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5814 else if
(tree
->car
->car
== (node
*)1) {
5815 dump_prefix
(offset
+1);
5816 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5819 parser_dump
(mrb
, tree
->car
->car
, offset
+1);
5820 dump_prefix
(offset
+1);
5821 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5823 if
(tree
->cdr
->car
) {
5824 dump_prefix
(offset
+1);
5826 parser_dump
(mrb
, tree
->cdr
->car
, offset
+2);
5828 dump_prefix
(offset
+1);
5830 parser_dump
(mrb
, tree
->cdr
->cdr
->car
->cdr
, offset
+2);
5834 printf
("NODE_MODULE:\n");
5835 if
(tree
->car
->car
== (node
*)0) {
5836 dump_prefix
(offset
+1);
5837 printf
(":%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5839 else if
(tree
->car
->car
== (node
*)1) {
5840 dump_prefix
(offset
+1);
5841 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5844 parser_dump
(mrb
, tree
->car
->car
, offset
+1);
5845 dump_prefix
(offset
+1);
5846 printf
("::%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
->cdr
)));
5848 dump_prefix
(offset
+1);
5850 parser_dump
(mrb
, tree
->cdr
->car
->cdr
, offset
+2);
5854 printf
("NODE_SCLASS:\n");
5855 parser_dump
(mrb
, tree
->car
, offset
+1);
5856 dump_prefix
(offset
+1);
5858 parser_dump
(mrb
, tree
->cdr
->car
->cdr
, offset
+2);
5862 printf
("NODE_DEF:\n");
5863 dump_prefix
(offset
+1);
5864 printf
("%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
)));
5867 node
*n2
= tree
->car
;
5869 if
(n2
&& (n2
->car || n2
->cdr
)) {
5870 dump_prefix
(offset
+1);
5871 printf
("local variables:\n");
5872 dump_prefix
(offset
+2);
5875 if
(n2
!= tree
->car
) printf
(", ");
5876 printf
("%s", mrb_sym2name
(mrb
, sym
(n2
->car
)));
5885 node
*n
= tree
->car
;
5888 dump_prefix
(offset
+1);
5889 printf
("mandatory args:\n");
5890 dump_recur
(mrb
, n
->car
, offset
+2);
5894 dump_prefix
(offset
+1);
5895 printf
("optional args:\n");
5900 dump_prefix
(offset
+2);
5901 printf
("%s=", mrb_sym2name
(mrb
, sym
(n2
->car
->car
)));
5902 parser_dump
(mrb
, n2
->car
->cdr
, 0);
5909 dump_prefix
(offset
+1);
5910 printf
("rest=*%s\n", mrb_sym2name
(mrb
, sym
(n
->car
)));
5914 dump_prefix
(offset
+1);
5915 printf
("post mandatory args:\n");
5916 dump_recur
(mrb
, n
->car
, offset
+2);
5920 dump_prefix
(offset
+1);
5921 printf
("blk=&%s\n", mrb_sym2name
(mrb
, sym
(n
)));
5924 parser_dump
(mrb
, tree
->cdr
->car
, offset
+1);
5928 printf
("NODE_SDEF:\n");
5929 parser_dump
(mrb
, tree
->car
, offset
+1);
5931 dump_prefix
(offset
+1);
5932 printf
(":%s\n", mrb_sym2name
(mrb
, sym
(tree
->car
)));
5933 tree
= tree
->cdr
->cdr
;
5935 node
*n
= tree
->car
;
5938 dump_prefix
(offset
+1);
5939 printf
("mandatory args:\n");
5940 dump_recur
(mrb
, n
->car
, offset
+2);
5944 dump_prefix
(offset
+1);
5945 printf
("optional args:\n");
5950 dump_prefix
(offset
+2);
5951 printf
("%s=", mrb_sym2name
(mrb
, sym
(n2
->car
->car
)));
5952 parser_dump
(mrb
, n2
->car
->cdr
, 0);
5959 dump_prefix
(offset
+1);
5960 printf
("rest=*%s\n", mrb_sym2name
(mrb
, sym
(n
->car
)));
5964 dump_prefix
(offset
+1);
5965 printf
("post mandatory args:\n");
5966 dump_recur
(mrb
, n
->car
, offset
+2);
5970 dump_prefix
(offset
+1);
5971 printf
("blk=&%s\n", mrb_sym2name
(mrb
, sym
(n
)));
5975 parser_dump
(mrb
, tree
->car
, offset
+1);
5979 printf
("NODE_POSTEXE:\n");
5980 parser_dump
(mrb
, tree
, offset
+1);
5984 printf
("NODE_HEREDOC:\n");
5985 parser_dump
(mrb
, ((parser_heredoc_info
*)tree
)->doc
, offset
+1);
5989 printf
("node type: %d (0x%x)\n", (int)n
, (int)n
);