00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 %{
00013
00014 #ifndef PARSER_DEBUG
00015 #define PARSER_DEBUG 0
00016 #endif
00017 #define YYDEBUG 1
00018 #define YYERROR_VERBOSE 1
00019 #define YYSTACK_USE_ALLOCA 0
00020
00021 #include "ruby/ruby.h"
00022 #include "ruby/st.h"
00023 #include "ruby/encoding.h"
00024 #include "internal.h"
00025 #include "node.h"
00026 #include "parse.h"
00027 #include "id.h"
00028 #include "regenc.h"
00029 #include <stdio.h>
00030 #include <errno.h>
00031 #include <ctype.h>
00032 #include "probes.h"
00033
00034 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
00035
00036 #define YYMALLOC(size) rb_parser_malloc(parser, (size))
00037 #define YYREALLOC(ptr, size) rb_parser_realloc(parser, (ptr), (size))
00038 #define YYCALLOC(nelem, size) rb_parser_calloc(parser, (nelem), (size))
00039 #define YYFREE(ptr) rb_parser_free(parser, (ptr))
00040 #define malloc YYMALLOC
00041 #define realloc YYREALLOC
00042 #define calloc YYCALLOC
00043 #define free YYFREE
00044
00045 #ifndef RIPPER
00046 static ID register_symid(ID, const char *, long, rb_encoding *);
00047 static ID register_symid_str(ID, VALUE);
00048 #define REGISTER_SYMID(id, name) register_symid((id), (name), strlen(name), enc)
00049 #include "id.c"
00050 #endif
00051
00052 #define is_notop_id(id) ((id)>tLAST_OP_ID)
00053 #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
00054 #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
00055 #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
00056 #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
00057 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
00058 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
00059 #define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
00060 #define id_type(id) (is_notop_id(id) ? (int)((id)&ID_SCOPE_MASK) : -1)
00061
00062 #define is_asgn_or_id(id) ((is_notop_id(id)) && \
00063 (((id)&ID_SCOPE_MASK) == ID_GLOBAL || \
00064 ((id)&ID_SCOPE_MASK) == ID_INSTANCE || \
00065 ((id)&ID_SCOPE_MASK) == ID_CLASS))
00066
00067 enum lex_state_bits {
00068 EXPR_BEG_bit,
00069 EXPR_END_bit,
00070 EXPR_ENDARG_bit,
00071 EXPR_ENDFN_bit,
00072 EXPR_ARG_bit,
00073 EXPR_CMDARG_bit,
00074 EXPR_MID_bit,
00075 EXPR_FNAME_bit,
00076 EXPR_DOT_bit,
00077 EXPR_CLASS_bit,
00078 EXPR_VALUE_bit,
00079 EXPR_MAX_STATE
00080 };
00081
00082 enum lex_state_e {
00083 #define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
00084 DEF_EXPR(BEG),
00085 DEF_EXPR(END),
00086 DEF_EXPR(ENDARG),
00087 DEF_EXPR(ENDFN),
00088 DEF_EXPR(ARG),
00089 DEF_EXPR(CMDARG),
00090 DEF_EXPR(MID),
00091 DEF_EXPR(FNAME),
00092 DEF_EXPR(DOT),
00093 DEF_EXPR(CLASS),
00094 DEF_EXPR(VALUE),
00095 EXPR_BEG_ANY = (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS),
00096 EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
00097 EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
00098 };
00099 #define IS_lex_state_for(x, ls) ((x) & (ls))
00100 #define IS_lex_state(ls) IS_lex_state_for(lex_state, (ls))
00101
00102 #if PARSER_DEBUG
00103 static const char *lex_state_name(enum lex_state_e state);
00104 #endif
00105
00106 typedef VALUE stack_type;
00107
00108 # define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
00109 # define BITSTACK_POP(stack) ((stack) = (stack) >> 1)
00110 # define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
00111 # define BITSTACK_SET_P(stack) ((stack)&1)
00112
00113 #define COND_PUSH(n) BITSTACK_PUSH(cond_stack, (n))
00114 #define COND_POP() BITSTACK_POP(cond_stack)
00115 #define COND_LEXPOP() BITSTACK_LEXPOP(cond_stack)
00116 #define COND_P() BITSTACK_SET_P(cond_stack)
00117
00118 #define CMDARG_PUSH(n) BITSTACK_PUSH(cmdarg_stack, (n))
00119 #define CMDARG_POP() BITSTACK_POP(cmdarg_stack)
00120 #define CMDARG_LEXPOP() BITSTACK_LEXPOP(cmdarg_stack)
00121 #define CMDARG_P() BITSTACK_SET_P(cmdarg_stack)
00122
00123 struct vtable {
00124 ID *tbl;
00125 int pos;
00126 int capa;
00127 struct vtable *prev;
00128 };
00129
00130 struct local_vars {
00131 struct vtable *args;
00132 struct vtable *vars;
00133 struct vtable *used;
00134 struct local_vars *prev;
00135 stack_type cmdargs;
00136 };
00137
00138 #define DVARS_INHERIT ((void*)1)
00139 #define DVARS_TOPSCOPE NULL
00140 #define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
00141 #define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
00142
00143 static int
00144 vtable_size(const struct vtable *tbl)
00145 {
00146 if (POINTER_P(tbl)) {
00147 return tbl->pos;
00148 }
00149 else {
00150 return 0;
00151 }
00152 }
00153
00154 #define VTBL_DEBUG 0
00155
00156 static struct vtable *
00157 vtable_alloc(struct vtable *prev)
00158 {
00159 struct vtable *tbl = ALLOC(struct vtable);
00160 tbl->pos = 0;
00161 tbl->capa = 8;
00162 tbl->tbl = ALLOC_N(ID, tbl->capa);
00163 tbl->prev = prev;
00164 if (VTBL_DEBUG) printf("vtable_alloc: %p\n", (void *)tbl);
00165 return tbl;
00166 }
00167
00168 static void
00169 vtable_free(struct vtable *tbl)
00170 {
00171 if (VTBL_DEBUG)printf("vtable_free: %p\n", (void *)tbl);
00172 if (POINTER_P(tbl)) {
00173 if (tbl->tbl) {
00174 xfree(tbl->tbl);
00175 }
00176 xfree(tbl);
00177 }
00178 }
00179
00180 static void
00181 vtable_add(struct vtable *tbl, ID id)
00182 {
00183 if (!POINTER_P(tbl)) {
00184 rb_bug("vtable_add: vtable is not allocated (%p)", (void *)tbl);
00185 }
00186 if (VTBL_DEBUG) printf("vtable_add: %p, %s\n", (void *)tbl, rb_id2name(id));
00187
00188 if (tbl->pos == tbl->capa) {
00189 tbl->capa = tbl->capa * 2;
00190 REALLOC_N(tbl->tbl, ID, tbl->capa);
00191 }
00192 tbl->tbl[tbl->pos++] = id;
00193 }
00194
00195 static int
00196 vtable_included(const struct vtable * tbl, ID id)
00197 {
00198 int i;
00199
00200 if (POINTER_P(tbl)) {
00201 for (i = 0; i < tbl->pos; i++) {
00202 if (tbl->tbl[i] == id) {
00203 return i+1;
00204 }
00205 }
00206 }
00207 return 0;
00208 }
00209
00210
00211 #ifndef RIPPER
00212 typedef struct token_info {
00213 const char *token;
00214 int linenum;
00215 int column;
00216 int nonspc;
00217 struct token_info *next;
00218 } token_info;
00219 #endif
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 struct parser_params {
00231 int is_ripper;
00232 NODE *heap;
00233
00234 YYSTYPE *parser_yylval;
00235 VALUE eofp;
00236
00237 NODE *parser_lex_strterm;
00238 enum lex_state_e parser_lex_state;
00239 stack_type parser_cond_stack;
00240 stack_type parser_cmdarg_stack;
00241 int parser_class_nest;
00242 int parser_paren_nest;
00243 int parser_lpar_beg;
00244 int parser_in_single;
00245 int parser_in_def;
00246 int parser_brace_nest;
00247 int parser_compile_for_eval;
00248 VALUE parser_cur_mid;
00249 int parser_in_defined;
00250 char *parser_tokenbuf;
00251 int parser_tokidx;
00252 int parser_toksiz;
00253 int parser_tokline;
00254 VALUE parser_lex_input;
00255 VALUE parser_lex_lastline;
00256 VALUE parser_lex_nextline;
00257 const char *parser_lex_pbeg;
00258 const char *parser_lex_p;
00259 const char *parser_lex_pend;
00260 int parser_heredoc_end;
00261 int parser_command_start;
00262 NODE *parser_deferred_nodes;
00263 long parser_lex_gets_ptr;
00264 VALUE (*parser_lex_gets)(struct parser_params*,VALUE);
00265 struct local_vars *parser_lvtbl;
00266 int parser_ruby__end__seen;
00267 int line_count;
00268 int has_shebang;
00269 char *parser_ruby_sourcefile;
00270 int parser_ruby_sourceline;
00271 VALUE parser_ruby_sourcefile_string;
00272 rb_encoding *enc;
00273
00274 int parser_yydebug;
00275
00276 #ifndef RIPPER
00277
00278 NODE *parser_eval_tree_begin;
00279 NODE *parser_eval_tree;
00280 VALUE debug_lines;
00281 VALUE coverage;
00282 int nerr;
00283
00284 int parser_token_info_enabled;
00285 token_info *parser_token_info;
00286 #else
00287
00288 const char *tokp;
00289 VALUE delayed;
00290 int delayed_line;
00291 int delayed_col;
00292
00293 VALUE value;
00294 VALUE result;
00295 VALUE parsing_thread;
00296 int toplevel_p;
00297 #endif
00298 };
00299
00300 #define STR_NEW(p,n) rb_enc_str_new((p),(n),current_enc)
00301 #define STR_NEW0() rb_enc_str_new(0,0,current_enc)
00302 #define STR_NEW2(p) rb_enc_str_new((p),strlen(p),current_enc)
00303 #define STR_NEW3(p,n,e,func) parser_str_new((p),(n),(e),(func),current_enc)
00304 #define ENC_SINGLE(cr) ((cr)==ENC_CODERANGE_7BIT)
00305 #define TOK_INTERN(mb) rb_intern3(tok(), toklen(), current_enc)
00306
00307 static int parser_yyerror(struct parser_params*, const char*);
00308 #define yyerror(msg) parser_yyerror(parser, (msg))
00309
00310 #define lex_strterm (parser->parser_lex_strterm)
00311 #define lex_state (parser->parser_lex_state)
00312 #define cond_stack (parser->parser_cond_stack)
00313 #define cmdarg_stack (parser->parser_cmdarg_stack)
00314 #define class_nest (parser->parser_class_nest)
00315 #define paren_nest (parser->parser_paren_nest)
00316 #define lpar_beg (parser->parser_lpar_beg)
00317 #define brace_nest (parser->parser_brace_nest)
00318 #define in_single (parser->parser_in_single)
00319 #define in_def (parser->parser_in_def)
00320 #define compile_for_eval (parser->parser_compile_for_eval)
00321 #define cur_mid (parser->parser_cur_mid)
00322 #define in_defined (parser->parser_in_defined)
00323 #define tokenbuf (parser->parser_tokenbuf)
00324 #define tokidx (parser->parser_tokidx)
00325 #define toksiz (parser->parser_toksiz)
00326 #define tokline (parser->parser_tokline)
00327 #define lex_input (parser->parser_lex_input)
00328 #define lex_lastline (parser->parser_lex_lastline)
00329 #define lex_nextline (parser->parser_lex_nextline)
00330 #define lex_pbeg (parser->parser_lex_pbeg)
00331 #define lex_p (parser->parser_lex_p)
00332 #define lex_pend (parser->parser_lex_pend)
00333 #define heredoc_end (parser->parser_heredoc_end)
00334 #define command_start (parser->parser_command_start)
00335 #define deferred_nodes (parser->parser_deferred_nodes)
00336 #define lex_gets_ptr (parser->parser_lex_gets_ptr)
00337 #define lex_gets (parser->parser_lex_gets)
00338 #define lvtbl (parser->parser_lvtbl)
00339 #define ruby__end__seen (parser->parser_ruby__end__seen)
00340 #define ruby_sourceline (parser->parser_ruby_sourceline)
00341 #define ruby_sourcefile (parser->parser_ruby_sourcefile)
00342 #define ruby_sourcefile_string (parser->parser_ruby_sourcefile_string)
00343 #define current_enc (parser->enc)
00344 #define yydebug (parser->parser_yydebug)
00345 #ifdef RIPPER
00346 #else
00347 #define ruby_eval_tree (parser->parser_eval_tree)
00348 #define ruby_eval_tree_begin (parser->parser_eval_tree_begin)
00349 #define ruby_debug_lines (parser->debug_lines)
00350 #define ruby_coverage (parser->coverage)
00351 #endif
00352
00353 #if YYPURE
00354 static int yylex(void*, void*);
00355 #else
00356 static int yylex(void*);
00357 #endif
00358
00359 #ifndef RIPPER
00360 #define yyparse ruby_yyparse
00361
00362 static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE);
00363 #define rb_node_newnode(type, a1, a2, a3) node_newnode(parser, (type), (a1), (a2), (a3))
00364
00365 static NODE *cond_gen(struct parser_params*,NODE*);
00366 #define cond(node) cond_gen(parser, (node))
00367 static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*);
00368 #define logop(type,node1,node2) logop_gen(parser, (type), (node1), (node2))
00369
00370 static NODE *newline_node(NODE*);
00371 static void fixpos(NODE*,NODE*);
00372
00373 static int value_expr_gen(struct parser_params*,NODE*);
00374 static void void_expr_gen(struct parser_params*,NODE*);
00375 static NODE *remove_begin(NODE*);
00376 #define value_expr(node) value_expr_gen(parser, (node) = remove_begin(node))
00377 #define void_expr0(node) void_expr_gen(parser, (node))
00378 #define void_expr(node) void_expr0((node) = remove_begin(node))
00379 static void void_stmts_gen(struct parser_params*,NODE*);
00380 #define void_stmts(node) void_stmts_gen(parser, (node))
00381 static void reduce_nodes_gen(struct parser_params*,NODE**);
00382 #define reduce_nodes(n) reduce_nodes_gen(parser,(n))
00383 static void block_dup_check_gen(struct parser_params*,NODE*,NODE*);
00384 #define block_dup_check(n1,n2) block_dup_check_gen(parser,(n1),(n2))
00385
00386 static NODE *block_append_gen(struct parser_params*,NODE*,NODE*);
00387 #define block_append(h,t) block_append_gen(parser,(h),(t))
00388 static NODE *list_append_gen(struct parser_params*,NODE*,NODE*);
00389 #define list_append(l,i) list_append_gen(parser,(l),(i))
00390 static NODE *list_concat_gen(struct parser_params*,NODE*,NODE*);
00391 #define list_concat(h,t) list_concat_gen(parser,(h),(t))
00392 static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*);
00393 #define arg_append(h,t) arg_append_gen(parser,(h),(t))
00394 static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*);
00395 #define arg_concat(h,t) arg_concat_gen(parser,(h),(t))
00396 static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*);
00397 #define literal_concat(h,t) literal_concat_gen(parser,(h),(t))
00398 static int literal_concat0(struct parser_params *, VALUE, VALUE);
00399 static NODE *new_evstr_gen(struct parser_params*,NODE*);
00400 #define new_evstr(n) new_evstr_gen(parser,(n))
00401 static NODE *evstr2dstr_gen(struct parser_params*,NODE*);
00402 #define evstr2dstr(n) evstr2dstr_gen(parser,(n))
00403 static NODE *splat_array(NODE*);
00404
00405 static NODE *call_bin_op_gen(struct parser_params*,NODE*,ID,NODE*);
00406 #define call_bin_op(recv,id,arg1) call_bin_op_gen(parser, (recv),(id),(arg1))
00407 static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID);
00408 #define call_uni_op(recv,id) call_uni_op_gen(parser, (recv),(id))
00409
00410 static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*);
00411 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
00412 static NODE *new_args_tail_gen(struct parser_params*,NODE*,ID,ID);
00413 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
00414
00415 static NODE *negate_lit(NODE*);
00416 static NODE *ret_args_gen(struct parser_params*,NODE*);
00417 #define ret_args(node) ret_args_gen(parser, (node))
00418 static NODE *arg_blk_pass(NODE*,NODE*);
00419 static NODE *new_yield_gen(struct parser_params*,NODE*);
00420 #define new_yield(node) new_yield_gen(parser, (node))
00421 static NODE *dsym_node_gen(struct parser_params*,NODE*);
00422 #define dsym_node(node) dsym_node_gen(parser, (node))
00423
00424 static NODE *gettable_gen(struct parser_params*,ID);
00425 #define gettable(id) gettable_gen(parser,(id))
00426 static NODE *assignable_gen(struct parser_params*,ID,NODE*);
00427 #define assignable(id,node) assignable_gen(parser, (id), (node))
00428
00429 static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
00430 #define aryset(node1,node2) aryset_gen(parser, (node1), (node2))
00431 static NODE *attrset_gen(struct parser_params*,NODE*,ID);
00432 #define attrset(node,id) attrset_gen(parser, (node), (id))
00433
00434 static void rb_backref_error_gen(struct parser_params*,NODE*);
00435 #define rb_backref_error(n) rb_backref_error_gen(parser,(n))
00436 static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
00437 #define node_assign(node1, node2) node_assign_gen(parser, (node1), (node2))
00438
00439 static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
00440 static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs);
00441 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (attr), (op), (rhs))
00442 static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs);
00443 #define new_const_op_assign(lhs, op, rhs) new_const_op_assign_gen(parser, (lhs), (op), (rhs))
00444
00445 static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
00446 #define match_op(node1,node2) match_op_gen(parser, (node1), (node2))
00447
00448 static ID *local_tbl_gen(struct parser_params*);
00449 #define local_tbl() local_tbl_gen(parser)
00450
00451 static void fixup_nodes(NODE **);
00452
00453 static VALUE reg_compile_gen(struct parser_params*, VALUE, int);
00454 #define reg_compile(str,options) reg_compile_gen(parser, (str), (options))
00455 static void reg_fragment_setenc_gen(struct parser_params*, VALUE, int);
00456 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, (str), (options))
00457 static int reg_fragment_check_gen(struct parser_params*, VALUE, int);
00458 #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, (str), (options))
00459 static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match);
00460 #define reg_named_capture_assign(regexp,match) reg_named_capture_assign_gen(parser,(regexp),(match))
00461
00462 #define get_id(id) (id)
00463 #define get_value(val) (val)
00464 #else
00465 #define value_expr(node) ((void)(node))
00466 #define remove_begin(node) (node)
00467 #define rb_dvar_defined(id) 0
00468 #define rb_local_defined(id) 0
00469 static ID ripper_get_id(VALUE);
00470 #define get_id(id) ripper_get_id(id)
00471 static VALUE ripper_get_value(VALUE);
00472 #define get_value(val) ripper_get_value(val)
00473 static VALUE assignable_gen(struct parser_params*,VALUE);
00474 #define assignable(lhs,node) assignable_gen(parser, (lhs))
00475 static int id_is_var_gen(struct parser_params *parser, ID id);
00476 #define id_is_var(id) id_is_var_gen(parser, (id))
00477
00478 #define node_assign(node1, node2) dispatch2(assign, (node1), (node2))
00479
00480 static VALUE new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs);
00481 static VALUE new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs);
00482 #define new_attr_op_assign(lhs, type, attr, op, rhs) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs))
00483
00484 #endif
00485
00486 #define new_op_assign(lhs, op, rhs) new_op_assign_gen(parser, (lhs), (op), (rhs))
00487
00488 static ID formal_argument_gen(struct parser_params*, ID);
00489 #define formal_argument(id) formal_argument_gen(parser, (id))
00490 static ID shadowing_lvar_gen(struct parser_params*,ID);
00491 #define shadowing_lvar(name) shadowing_lvar_gen(parser, (name))
00492 static void new_bv_gen(struct parser_params*,ID);
00493 #define new_bv(id) new_bv_gen(parser, (id))
00494
00495 static void local_push_gen(struct parser_params*,int);
00496 #define local_push(top) local_push_gen(parser,(top))
00497 static void local_pop_gen(struct parser_params*);
00498 #define local_pop() local_pop_gen(parser)
00499 static int local_var_gen(struct parser_params*, ID);
00500 #define local_var(id) local_var_gen(parser, (id))
00501 static int arg_var_gen(struct parser_params*, ID);
00502 #define arg_var(id) arg_var_gen(parser, (id))
00503 static int local_id_gen(struct parser_params*, ID);
00504 #define local_id(id) local_id_gen(parser, (id))
00505 static ID internal_id_gen(struct parser_params*);
00506 #define internal_id() internal_id_gen(parser)
00507
00508 static const struct vtable *dyna_push_gen(struct parser_params *);
00509 #define dyna_push() dyna_push_gen(parser)
00510 static void dyna_pop_gen(struct parser_params*, const struct vtable *);
00511 #define dyna_pop(node) dyna_pop_gen(parser, (node))
00512 static int dyna_in_block_gen(struct parser_params*);
00513 #define dyna_in_block() dyna_in_block_gen(parser)
00514 #define dyna_var(id) local_var(id)
00515 static int dvar_defined_gen(struct parser_params*,ID,int);
00516 #define dvar_defined(id) dvar_defined_gen(parser, (id), 0)
00517 #define dvar_defined_get(id) dvar_defined_gen(parser, (id), 1)
00518 static int dvar_curr_gen(struct parser_params*,ID);
00519 #define dvar_curr(id) dvar_curr_gen(parser, (id))
00520
00521 static int lvar_defined_gen(struct parser_params*, ID);
00522 #define lvar_defined(id) lvar_defined_gen(parser, (id))
00523
00524 #define RE_OPTION_ONCE (1<<16)
00525 #define RE_OPTION_ENCODING_SHIFT 8
00526 #define RE_OPTION_ENCODING(e) (((e)&0xff)<<RE_OPTION_ENCODING_SHIFT)
00527 #define RE_OPTION_ENCODING_IDX(o) (((o)>>RE_OPTION_ENCODING_SHIFT)&0xff)
00528 #define RE_OPTION_ENCODING_NONE(o) ((o)&RE_OPTION_ARG_ENCODING_NONE)
00529 #define RE_OPTION_MASK 0xff
00530 #define RE_OPTION_ARG_ENCODING_NONE 32
00531
00532 #define NODE_STRTERM NODE_ZARRAY
00533 #define NODE_HEREDOC NODE_ARRAY
00534 #define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))
00535 #define nd_func u1.id
00536 #if SIZEOF_SHORT == 2
00537 #define nd_term(node) ((signed short)(node)->u2.id)
00538 #else
00539 #define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)
00540 #endif
00541 #define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)
00542 #define nd_nest u3.cnt
00543
00544
00545
00546 #ifdef RIPPER
00547 #define RIPPER_VERSION "0.1.0"
00548
00549 #include "eventids1.c"
00550 #include "eventids2.c"
00551
00552 static VALUE ripper_dispatch0(struct parser_params*,ID);
00553 static VALUE ripper_dispatch1(struct parser_params*,ID,VALUE);
00554 static VALUE ripper_dispatch2(struct parser_params*,ID,VALUE,VALUE);
00555 static VALUE ripper_dispatch3(struct parser_params*,ID,VALUE,VALUE,VALUE);
00556 static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
00557 static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
00558 static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
00559
00560 #define dispatch0(n) ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
00561 #define dispatch1(n,a) ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
00562 #define dispatch2(n,a,b) ripper_dispatch2(parser, TOKEN_PASTE(ripper_id_, n), (a), (b))
00563 #define dispatch3(n,a,b,c) ripper_dispatch3(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c))
00564 #define dispatch4(n,a,b,c,d) ripper_dispatch4(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d))
00565 #define dispatch5(n,a,b,c,d,e) ripper_dispatch5(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e))
00566 #define dispatch7(n,a,b,c,d,e,f,g) ripper_dispatch7(parser, TOKEN_PASTE(ripper_id_, n), (a), (b), (c), (d), (e), (f), (g))
00567
00568 #define yyparse ripper_yyparse
00569
00570 #define ripper_intern(s) ID2SYM(rb_intern(s))
00571 static VALUE ripper_id2sym(ID);
00572 #ifdef __GNUC__
00573 #define ripper_id2sym(id) ((id) < 256 && rb_ispunct(id) ? \
00574 ID2SYM(id) : ripper_id2sym(id))
00575 #endif
00576
00577 #define arg_new() dispatch0(args_new)
00578 #define arg_add(l,a) dispatch2(args_add, (l), (a))
00579 #define arg_add_star(l,a) dispatch2(args_add_star, (l), (a))
00580 #define arg_add_block(l,b) dispatch2(args_add_block, (l), (b))
00581 #define arg_add_optblock(l,b) ((b)==Qundef? (l) : dispatch2(args_add_block, (l), (b)))
00582 #define bare_assoc(v) dispatch1(bare_assoc_hash, (v))
00583 #define arg_add_assocs(l,b) arg_add((l), bare_assoc(b))
00584
00585 #define args2mrhs(a) dispatch1(mrhs_new_from_args, (a))
00586 #define mrhs_new() dispatch0(mrhs_new)
00587 #define mrhs_add(l,a) dispatch2(mrhs_add, (l), (a))
00588 #define mrhs_add_star(l,a) dispatch2(mrhs_add_star, (l), (a))
00589
00590 #define mlhs_new() dispatch0(mlhs_new)
00591 #define mlhs_add(l,a) dispatch2(mlhs_add, (l), (a))
00592 #define mlhs_add_star(l,a) dispatch2(mlhs_add_star, (l), (a))
00593
00594 #define params_new(pars, opts, rest, pars2, kws, kwrest, blk) \
00595 dispatch7(params, (pars), (opts), (rest), (pars2), (kws), (kwrest), (blk))
00596
00597 #define blockvar_new(p,v) dispatch2(block_var, (p), (v))
00598 #define blockvar_add_star(l,a) dispatch2(block_var_add_star, (l), (a))
00599 #define blockvar_add_block(l,a) dispatch2(block_var_add_block, (l), (a))
00600
00601 #define method_optarg(m,a) ((a)==Qundef ? (m) : dispatch2(method_add_arg,(m),(a)))
00602 #define method_arg(m,a) dispatch2(method_add_arg,(m),(a))
00603 #define method_add_block(m,b) dispatch2(method_add_block, (m), (b))
00604
00605 #define escape_Qundef(x) ((x)==Qundef ? Qnil : (x))
00606
00607 static inline VALUE
00608 new_args_gen(struct parser_params *parser, VALUE f, VALUE o, VALUE r, VALUE p, VALUE tail)
00609 {
00610 NODE *t = (NODE *)tail;
00611 VALUE k = t->u1.value, kr = t->u2.value, b = t->u3.value;
00612 return params_new(f, o, r, p, k, kr, escape_Qundef(b));
00613 }
00614 #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t))
00615
00616 static inline VALUE
00617 new_args_tail_gen(struct parser_params *parser, VALUE k, VALUE kr, VALUE b)
00618 {
00619 return (VALUE)rb_node_newnode(NODE_MEMO, k, kr, b);
00620 }
00621 #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b))
00622
00623 #define FIXME 0
00624
00625 #endif
00626
00627 #ifndef RIPPER
00628 # define Qnone 0
00629 # define ifndef_ripper(x) (x)
00630 #else
00631 # define Qnone Qnil
00632 # define ifndef_ripper(x)
00633 #endif
00634
00635 #ifndef RIPPER
00636 # define rb_warn0(fmt) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt))
00637 # define rb_warnI(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
00638 # define rb_warnS(fmt,a) rb_compile_warn(ruby_sourcefile, ruby_sourceline, (fmt), (a))
00639 # define rb_warn4S(file,line,fmt,a) rb_compile_warn((file), (line), (fmt), (a))
00640 # define rb_warning0(fmt) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt))
00641 # define rb_warningS(fmt,a) rb_compile_warning(ruby_sourcefile, ruby_sourceline, (fmt), (a))
00642 #else
00643 # define rb_warn0(fmt) ripper_warn0(parser, (fmt))
00644 # define rb_warnI(fmt,a) ripper_warnI(parser, (fmt), (a))
00645 # define rb_warnS(fmt,a) ripper_warnS(parser, (fmt), (a))
00646 # define rb_warn4S(file,line,fmt,a) ripper_warnS(parser, (fmt), (a))
00647 # define rb_warning0(fmt) ripper_warning0(parser, (fmt))
00648 # define rb_warningS(fmt,a) ripper_warningS(parser, (fmt), (a))
00649 static void ripper_warn0(struct parser_params*, const char*);
00650 static void ripper_warnI(struct parser_params*, const char*, int);
00651 static void ripper_warnS(struct parser_params*, const char*, const char*);
00652 static void ripper_warning0(struct parser_params*, const char*);
00653 static void ripper_warningS(struct parser_params*, const char*, const char*);
00654 #endif
00655
00656 #ifdef RIPPER
00657 static void ripper_compile_error(struct parser_params*, const char *fmt, ...);
00658 # define rb_compile_error ripper_compile_error
00659 # define compile_error ripper_compile_error
00660 # define PARSER_ARG parser,
00661 #else
00662 # define rb_compile_error rb_compile_error_with_enc
00663 # define compile_error parser->nerr++,rb_compile_error_with_enc
00664 # define PARSER_ARG ruby_sourcefile, ruby_sourceline, current_enc,
00665 #endif
00666
00667
00668
00669
00670 #ifdef OLD_YACC
00671 #ifndef YYMAXDEPTH
00672 #define YYMAXDEPTH 10000
00673 #endif
00674 #endif
00675
00676 #ifndef RIPPER
00677 static void token_info_push(struct parser_params*, const char *token);
00678 static void token_info_pop(struct parser_params*, const char *token);
00679 #define token_info_push(token) (RTEST(ruby_verbose) ? token_info_push(parser, (token)) : (void)0)
00680 #define token_info_pop(token) (RTEST(ruby_verbose) ? token_info_pop(parser, (token)) : (void)0)
00681 #else
00682 #define token_info_push(token)
00683 #define token_info_pop(token)
00684 #endif
00685 %}
00686
00687 %pure-parser
00688 %lex-param {struct parser_params *parser}
00689 %parse-param {struct parser_params *parser}
00690
00691 %union {
00692 VALUE val;
00693 NODE *node;
00694 ID id;
00695 int num;
00696 const struct vtable *vars;
00697 }
00698
00699
00700 %token
00701
00702
00703
00704 keyword_class
00705 keyword_module
00706 keyword_def
00707 keyword_undef
00708 keyword_begin
00709 keyword_rescue
00710 keyword_ensure
00711 keyword_end
00712 keyword_if
00713 keyword_unless
00714 keyword_then
00715 keyword_elsif
00716 keyword_else
00717 keyword_case
00718 keyword_when
00719 keyword_while
00720 keyword_until
00721 keyword_for
00722 keyword_break
00723 keyword_next
00724 keyword_redo
00725 keyword_retry
00726 keyword_in
00727 keyword_do
00728 keyword_do_cond
00729 keyword_do_block
00730 keyword_do_LAMBDA
00731 keyword_return
00732 keyword_yield
00733 keyword_super
00734 keyword_self
00735 keyword_nil
00736 keyword_true
00737 keyword_false
00738 keyword_and
00739 keyword_or
00740 keyword_not
00741 modifier_if
00742 modifier_unless
00743 modifier_while
00744 modifier_until
00745 modifier_rescue
00746 keyword_alias
00747 keyword_defined
00748 keyword_BEGIN
00749 keyword_END
00750 keyword__LINE__
00751 keyword__FILE__
00752 keyword__ENCODING__
00753
00754 %token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
00755 %token <node> tINTEGER tFLOAT tSTRING_CONTENT tCHAR
00756 %token <node> tNTH_REF tBACK_REF
00757 %token <num> tREGEXP_END
00758
00759 %type <node> singleton strings string string1 xstring regexp
00760 %type <node> string_contents xstring_contents regexp_contents string_content
00761 %type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
00762 %type <node> literal numeric dsym cpath
00763 %type <node> top_compstmt top_stmts top_stmt
00764 %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
00765 %type <node> expr_value arg_value primary_value fcall
00766 %type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
00767 %type <node> args call_args opt_call_args
00768 %type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
00769 %type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
00770 %type <node> command_asgn mrhs superclass block_call block_command
00771 %type <node> f_block_optarg f_block_opt
00772 %type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
00773 %type <node> assoc_list assocs assoc undef_list backref string_dvar for_var
00774 %type <node> block_param opt_block_param block_param_def f_opt
00775 %type <node> f_kwarg f_kw f_block_kwarg f_block_kw
00776 %type <node> bv_decls opt_bv_decl bvar
00777 %type <node> lambda f_larglist lambda_body
00778 %type <node> brace_block cmd_brace_block do_block lhs none fitem
00779 %type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
00780 %type <id> fsym keyword_variable user_variable sym symbol operation operation2 operation3
00781 %type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
00782 %type <id> f_kwrest
00783
00784
00785
00786
00787 %token END_OF_INPUT 0 "end-of-input"
00788 %token tUPLUS RUBY_TOKEN(UPLUS) "unary+"
00789 %token tUMINUS RUBY_TOKEN(UMINUS) "unary-"
00790 %token tPOW RUBY_TOKEN(POW) "**"
00791 %token tCMP RUBY_TOKEN(CMP) "<=>"
00792 %token tEQ RUBY_TOKEN(EQ) "=="
00793 %token tEQQ RUBY_TOKEN(EQQ) "==="
00794 %token tNEQ RUBY_TOKEN(NEQ) "!="
00795 %token tGEQ RUBY_TOKEN(GEQ) ">="
00796 %token tLEQ RUBY_TOKEN(LEQ) "<="
00797 %token tANDOP "&&"
00798 %token tOROP "||"
00799 %token tMATCH RUBY_TOKEN(MATCH) "=~"
00800 %token tNMATCH RUBY_TOKEN(NMATCH) "!~"
00801 %token tDOT2 RUBY_TOKEN(DOT2) ".."
00802 %token tDOT3 RUBY_TOKEN(DOT3) "..."
00803 %token tAREF RUBY_TOKEN(AREF) "[]"
00804 %token tASET RUBY_TOKEN(ASET) "[]="
00805 %token tLSHFT RUBY_TOKEN(LSHFT) "<<"
00806 %token tRSHFT RUBY_TOKEN(RSHFT) ">>"
00807 %token tCOLON2 "::"
00808 %token tCOLON3 ":: at EXPR_BEG"
00809 %token <id> tOP_ASGN
00810 %token tASSOC "=>"
00811 %token tLPAREN "("
00812 %token tLPAREN_ARG "( arg"
00813 %token tRPAREN ")"
00814 %token tLBRACK "["
00815 %token tLBRACE "{"
00816 %token tLBRACE_ARG "{ arg"
00817 %token tSTAR "*"
00818 %token tDSTAR "**arg"
00819 %token tAMPER "&"
00820 %token tLAMBDA "->"
00821 %token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG
00822 %token tSTRING_DBEG tSTRING_DEND tSTRING_DVAR tSTRING_END tLAMBEG
00823
00824
00825
00826
00827
00828 %nonassoc tLOWEST
00829 %nonassoc tLBRACE_ARG
00830
00831 %nonassoc modifier_if modifier_unless modifier_while modifier_until
00832 %left keyword_or keyword_and
00833 %right keyword_not
00834 %nonassoc keyword_defined
00835 %right '=' tOP_ASGN
00836 %left modifier_rescue
00837 %right '?' ':'
00838 %nonassoc tDOT2 tDOT3
00839 %left tOROP
00840 %left tANDOP
00841 %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
00842 %left '>' tGEQ '<' tLEQ
00843 %left '|' '^'
00844 %left '&'
00845 %left tLSHFT tRSHFT
00846 %left '+' '-'
00847 %left '*' '/' '%'
00848 %right tUMINUS_NUM tUMINUS
00849 %right tPOW
00850 %right '!' '~' tUPLUS
00851
00852 %token tLAST_TOKEN
00853
00854 %%
00855 program : {
00856 lex_state = EXPR_BEG;
00857
00858 local_push(compile_for_eval || rb_parse_in_main());
00859
00860
00861
00862 }
00863 top_compstmt
00864 {
00865
00866 if ($2 && !compile_for_eval) {
00867
00868 if (nd_type($2) != NODE_BLOCK) void_expr($2);
00869 else {
00870 NODE *node = $2;
00871 while (node->nd_next) {
00872 node = node->nd_next;
00873 }
00874 void_expr(node->nd_head);
00875 }
00876 }
00877 ruby_eval_tree = NEW_SCOPE(0, block_append(ruby_eval_tree, $2));
00878
00879
00880
00881
00882 local_pop();
00883 }
00884 ;
00885
00886 top_compstmt : top_stmts opt_terms
00887 {
00888
00889 void_stmts($1);
00890 fixup_nodes(&deferred_nodes);
00891
00892
00893 $$ = $1;
00894 }
00895 ;
00896
00897 top_stmts : none
00898 {
00899
00900 $$ = NEW_BEGIN(0);
00901
00902
00903
00904
00905 }
00906 | top_stmt
00907 {
00908
00909 $$ = newline_node($1);
00910
00911
00912
00913 }
00914 | top_stmts terms top_stmt
00915 {
00916
00917 $$ = block_append($1, newline_node($3));
00918
00919
00920
00921 }
00922 | error top_stmt
00923 {
00924 $$ = remove_begin($2);
00925 }
00926 ;
00927
00928 top_stmt : stmt
00929 | keyword_BEGIN
00930 {
00931
00932
00933
00934
00935 }
00936 '{' top_compstmt '}'
00937 {
00938
00939 ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
00940 $4);
00941
00942
00943 $$ = NEW_BEGIN(0);
00944
00945
00946
00947 }
00948 ;
00949
00950 bodystmt : compstmt
00951 opt_rescue
00952 opt_else
00953 opt_ensure
00954 {
00955
00956 $$ = $1;
00957 if ($2) {
00958 $$ = NEW_RESCUE($1, $2, $3);
00959 }
00960 else if ($3) {
00961 rb_warn0("else without rescue is useless");
00962 $$ = block_append($$, $3);
00963 }
00964 if ($4) {
00965 if ($$) {
00966 $$ = NEW_ENSURE($$, $4);
00967 }
00968 else {
00969 $$ = block_append($4, NEW_NIL());
00970 }
00971 }
00972 fixpos($$, $1);
00973
00974
00975
00976
00977
00978
00979
00980 }
00981 ;
00982
00983 compstmt : stmts opt_terms
00984 {
00985
00986 void_stmts($1);
00987 fixup_nodes(&deferred_nodes);
00988
00989
00990 $$ = $1;
00991 }
00992 ;
00993
00994 stmts : none
00995 {
00996
00997 $$ = NEW_BEGIN(0);
00998
00999
01000
01001
01002 }
01003 | stmt_or_begin
01004 {
01005
01006 $$ = newline_node($1);
01007
01008
01009
01010 }
01011 | stmts terms stmt_or_begin
01012 {
01013
01014 $$ = block_append($1, newline_node($3));
01015
01016
01017
01018 }
01019 | error stmt
01020 {
01021 $$ = remove_begin($2);
01022 }
01023 ;
01024
01025 stmt_or_begin : stmt
01026 {
01027 $$ = $1;
01028 }
01029 | keyword_BEGIN
01030 {
01031 yyerror("BEGIN is permitted only at toplevel");
01032
01033
01034
01035
01036 }
01037 '{' top_compstmt '}'
01038 {
01039
01040 ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
01041 $4);
01042
01043
01044 $$ = NEW_BEGIN(0);
01045
01046
01047
01048 }
01049
01050 stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
01051 {
01052
01053 $$ = NEW_ALIAS($2, $4);
01054
01055
01056
01057 }
01058 | keyword_alias tGVAR tGVAR
01059 {
01060
01061 $$ = NEW_VALIAS($2, $3);
01062
01063
01064
01065 }
01066 | keyword_alias tGVAR tBACK_REF
01067 {
01068
01069 char buf[2];
01070 buf[0] = '$';
01071 buf[1] = (char)$3->nd_nth;
01072 $$ = NEW_VALIAS($2, rb_intern2(buf, 2));
01073
01074
01075
01076 }
01077 | keyword_alias tGVAR tNTH_REF
01078 {
01079
01080 yyerror("can't make alias for the number variables");
01081 $$ = NEW_BEGIN(0);
01082
01083
01084
01085
01086 }
01087 | keyword_undef undef_list
01088 {
01089
01090 $$ = $2;
01091
01092
01093
01094 }
01095 | stmt modifier_if expr_value
01096 {
01097
01098 $$ = NEW_IF(cond($3), remove_begin($1), 0);
01099 fixpos($$, $3);
01100
01101
01102
01103 }
01104 | stmt modifier_unless expr_value
01105 {
01106
01107 $$ = NEW_UNLESS(cond($3), remove_begin($1), 0);
01108 fixpos($$, $3);
01109
01110
01111
01112 }
01113 | stmt modifier_while expr_value
01114 {
01115
01116 if ($1 && nd_type($1) == NODE_BEGIN) {
01117 $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
01118 }
01119 else {
01120 $$ = NEW_WHILE(cond($3), $1, 1);
01121 }
01122
01123
01124
01125 }
01126 | stmt modifier_until expr_value
01127 {
01128
01129 if ($1 && nd_type($1) == NODE_BEGIN) {
01130 $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
01131 }
01132 else {
01133 $$ = NEW_UNTIL(cond($3), $1, 1);
01134 }
01135
01136
01137
01138 }
01139 | stmt modifier_rescue stmt
01140 {
01141
01142 NODE *resq = NEW_RESBODY(0, remove_begin($3), 0);
01143 $$ = NEW_RESCUE(remove_begin($1), resq, 0);
01144
01145
01146
01147 }
01148 | keyword_END '{' compstmt '}'
01149 {
01150 if (in_def || in_single) {
01151 rb_warn0("END in method; use at_exit");
01152 }
01153
01154 $$ = NEW_POSTEXE(NEW_NODE(
01155 NODE_SCOPE, 0 , $3 , 0 ));
01156
01157
01158
01159 }
01160 | command_asgn
01161 | mlhs '=' command_call
01162 {
01163
01164 value_expr($3);
01165 $1->nd_value = $3;
01166 $$ = $1;
01167
01168
01169
01170 }
01171 | var_lhs tOP_ASGN command_call
01172 {
01173 value_expr($3);
01174 $$ = new_op_assign($1, $2, $3);
01175 }
01176 | primary_value '[' opt_call_args rbracket tOP_ASGN command_call
01177 {
01178
01179 NODE *args;
01180
01181 value_expr($6);
01182 if (!$3) $3 = NEW_ZARRAY();
01183 args = arg_concat($3, $6);
01184 if ($5 == tOROP) {
01185 $5 = 0;
01186 }
01187 else if ($5 == tANDOP) {
01188 $5 = 1;
01189 }
01190 $$ = NEW_OP_ASGN1($1, $5, args);
01191 fixpos($$, $1);
01192
01193
01194
01195
01196 }
01197 | primary_value '.' tIDENTIFIER tOP_ASGN command_call
01198 {
01199 value_expr($5);
01200 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
01201 }
01202 | primary_value '.' tCONSTANT tOP_ASGN command_call
01203 {
01204 value_expr($5);
01205 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
01206 }
01207 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
01208 {
01209
01210 $$ = NEW_COLON2($1, $3);
01211 $$ = new_const_op_assign($$, $4, $5);
01212
01213
01214
01215
01216 }
01217 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
01218 {
01219 value_expr($5);
01220 $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
01221 }
01222 | backref tOP_ASGN command_call
01223 {
01224
01225 rb_backref_error($1);
01226 $$ = NEW_BEGIN(0);
01227
01228
01229
01230
01231 }
01232 | lhs '=' mrhs
01233 {
01234
01235 value_expr($3);
01236 $$ = node_assign($1, $3);
01237
01238
01239
01240 }
01241 | mlhs '=' arg_value
01242 {
01243
01244 $1->nd_value = $3;
01245 $$ = $1;
01246
01247
01248
01249 }
01250 | mlhs '=' mrhs
01251 {
01252
01253 $1->nd_value = $3;
01254 $$ = $1;
01255
01256
01257
01258 }
01259 | expr
01260 ;
01261
01262 command_asgn : lhs '=' command_call
01263 {
01264
01265 value_expr($3);
01266 $$ = node_assign($1, $3);
01267
01268
01269
01270 }
01271 | lhs '=' command_asgn
01272 {
01273
01274 value_expr($3);
01275 $$ = node_assign($1, $3);
01276
01277
01278
01279 }
01280 ;
01281
01282
01283 expr : command_call
01284 | expr keyword_and expr
01285 {
01286
01287 $$ = logop(NODE_AND, $1, $3);
01288
01289
01290
01291 }
01292 | expr keyword_or expr
01293 {
01294
01295 $$ = logop(NODE_OR, $1, $3);
01296
01297
01298
01299 }
01300 | keyword_not opt_nl expr
01301 {
01302
01303 $$ = call_uni_op(cond($3), '!');
01304
01305
01306
01307 }
01308 | '!' command_call
01309 {
01310
01311 $$ = call_uni_op(cond($2), '!');
01312
01313
01314
01315 }
01316 | arg
01317 ;
01318
01319 expr_value : expr
01320 {
01321
01322 value_expr($1);
01323 $$ = $1;
01324 if (!$$) $$ = NEW_NIL();
01325
01326
01327
01328 }
01329 ;
01330
01331 command_call : command
01332 | block_command
01333 ;
01334
01335 block_command : block_call
01336 | block_call dot_or_colon operation2 command_args
01337 {
01338
01339 $$ = NEW_CALL($1, $3, $4);
01340
01341
01342
01343
01344 }
01345 ;
01346
01347 cmd_brace_block : tLBRACE_ARG
01348 {
01349 $<vars>1 = dyna_push();
01350
01351 $<num>$ = ruby_sourceline;
01352
01353
01354 }
01355 opt_block_param
01356 compstmt
01357 '}'
01358 {
01359
01360 $$ = NEW_ITER($3,$4);
01361 nd_set_line($$, $<num>2);
01362
01363
01364
01365 dyna_pop($<vars>1);
01366 }
01367 ;
01368
01369 fcall : operation
01370 {
01371
01372 $$ = NEW_FCALL($1, 0);
01373 nd_set_line($$, tokline);
01374
01375
01376 }
01377 ;
01378
01379 command : fcall command_args %prec tLOWEST
01380 {
01381
01382 $$ = $1;
01383 $$->nd_args = $2;
01384
01385
01386
01387 }
01388 | fcall command_args cmd_brace_block
01389 {
01390
01391 block_dup_check($2,$3);
01392 $1->nd_args = $2;
01393 $3->nd_iter = $1;
01394 $$ = $3;
01395 fixpos($$, $1);
01396
01397
01398
01399
01400 }
01401 | primary_value '.' operation2 command_args %prec tLOWEST
01402 {
01403
01404 $$ = NEW_CALL($1, $3, $4);
01405 fixpos($$, $1);
01406
01407
01408
01409 }
01410 | primary_value '.' operation2 command_args cmd_brace_block
01411 {
01412
01413 block_dup_check($4,$5);
01414 $5->nd_iter = NEW_CALL($1, $3, $4);
01415 $$ = $5;
01416 fixpos($$, $1);
01417
01418
01419
01420
01421 }
01422 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
01423 {
01424
01425 $$ = NEW_CALL($1, $3, $4);
01426 fixpos($$, $1);
01427
01428
01429
01430 }
01431 | primary_value tCOLON2 operation2 command_args cmd_brace_block
01432 {
01433
01434 block_dup_check($4,$5);
01435 $5->nd_iter = NEW_CALL($1, $3, $4);
01436 $$ = $5;
01437 fixpos($$, $1);
01438
01439
01440
01441
01442 }
01443 | keyword_super command_args
01444 {
01445
01446 $$ = NEW_SUPER($2);
01447 fixpos($$, $2);
01448
01449
01450
01451 }
01452 | keyword_yield command_args
01453 {
01454
01455 $$ = new_yield($2);
01456 fixpos($$, $2);
01457
01458
01459
01460 }
01461 | keyword_return call_args
01462 {
01463
01464 $$ = NEW_RETURN(ret_args($2));
01465
01466
01467
01468 }
01469 | keyword_break call_args
01470 {
01471
01472 $$ = NEW_BREAK(ret_args($2));
01473
01474
01475
01476 }
01477 | keyword_next call_args
01478 {
01479
01480 $$ = NEW_NEXT(ret_args($2));
01481
01482
01483
01484 }
01485 ;
01486
01487 mlhs : mlhs_basic
01488 | tLPAREN mlhs_inner rparen
01489 {
01490
01491 $$ = $2;
01492
01493
01494
01495 }
01496 ;
01497
01498 mlhs_inner : mlhs_basic
01499 | tLPAREN mlhs_inner rparen
01500 {
01501
01502 $$ = NEW_MASGN(NEW_LIST($2), 0);
01503
01504
01505
01506 }
01507 ;
01508
01509 mlhs_basic : mlhs_head
01510 {
01511
01512 $$ = NEW_MASGN($1, 0);
01513
01514
01515
01516 }
01517 | mlhs_head mlhs_item
01518 {
01519
01520 $$ = NEW_MASGN(list_append($1,$2), 0);
01521
01522
01523
01524 }
01525 | mlhs_head tSTAR mlhs_node
01526 {
01527
01528 $$ = NEW_MASGN($1, $3);
01529
01530
01531
01532 }
01533 | mlhs_head tSTAR mlhs_node ',' mlhs_post
01534 {
01535
01536 $$ = NEW_MASGN($1, NEW_POSTARG($3,$5));
01537
01538
01539
01540
01541 }
01542 | mlhs_head tSTAR
01543 {
01544
01545 $$ = NEW_MASGN($1, -1);
01546
01547
01548
01549 }
01550 | mlhs_head tSTAR ',' mlhs_post
01551 {
01552
01553 $$ = NEW_MASGN($1, NEW_POSTARG(-1, $4));
01554
01555
01556
01557
01558 }
01559 | tSTAR mlhs_node
01560 {
01561
01562 $$ = NEW_MASGN(0, $2);
01563
01564
01565
01566 }
01567 | tSTAR mlhs_node ',' mlhs_post
01568 {
01569
01570 $$ = NEW_MASGN(0, NEW_POSTARG($2,$4));
01571
01572
01573
01574
01575 }
01576 | tSTAR
01577 {
01578
01579 $$ = NEW_MASGN(0, -1);
01580
01581
01582
01583 }
01584 | tSTAR ',' mlhs_post
01585 {
01586
01587 $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
01588
01589
01590
01591
01592 }
01593 ;
01594
01595 mlhs_item : mlhs_node
01596 | tLPAREN mlhs_inner rparen
01597 {
01598
01599 $$ = $2;
01600
01601
01602
01603 }
01604 ;
01605
01606 mlhs_head : mlhs_item ','
01607 {
01608
01609 $$ = NEW_LIST($1);
01610
01611
01612
01613 }
01614 | mlhs_head mlhs_item ','
01615 {
01616
01617 $$ = list_append($1, $2);
01618
01619
01620
01621 }
01622 ;
01623
01624 mlhs_post : mlhs_item
01625 {
01626
01627 $$ = NEW_LIST($1);
01628
01629
01630
01631 }
01632 | mlhs_post ',' mlhs_item
01633 {
01634
01635 $$ = list_append($1, $3);
01636
01637
01638
01639 }
01640 ;
01641
01642 mlhs_node : user_variable
01643 {
01644 $$ = assignable($1, 0);
01645 }
01646 | keyword_variable
01647 {
01648 $$ = assignable($1, 0);
01649 }
01650 | primary_value '[' opt_call_args rbracket
01651 {
01652
01653 $$ = aryset($1, $3);
01654
01655
01656
01657 }
01658 | primary_value '.' tIDENTIFIER
01659 {
01660
01661 $$ = attrset($1, $3);
01662
01663
01664
01665 }
01666 | primary_value tCOLON2 tIDENTIFIER
01667 {
01668
01669 $$ = attrset($1, $3);
01670
01671
01672
01673 }
01674 | primary_value '.' tCONSTANT
01675 {
01676
01677 $$ = attrset($1, $3);
01678
01679
01680
01681 }
01682 | primary_value tCOLON2 tCONSTANT
01683 {
01684
01685 if (in_def || in_single)
01686 yyerror("dynamic constant assignment");
01687 $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
01688
01689
01690
01691
01692
01693 }
01694 | tCOLON3 tCONSTANT
01695 {
01696
01697 if (in_def || in_single)
01698 yyerror("dynamic constant assignment");
01699 $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
01700
01701
01702
01703 }
01704 | backref
01705 {
01706
01707 rb_backref_error($1);
01708 $$ = NEW_BEGIN(0);
01709
01710
01711
01712
01713 }
01714 ;
01715
01716 lhs : user_variable
01717 {
01718 $$ = assignable($1, 0);
01719
01720 if (!$$) $$ = NEW_BEGIN(0);
01721
01722
01723
01724 }
01725 | keyword_variable
01726 {
01727 $$ = assignable($1, 0);
01728
01729 if (!$$) $$ = NEW_BEGIN(0);
01730
01731
01732
01733 }
01734 | primary_value '[' opt_call_args rbracket
01735 {
01736
01737 $$ = aryset($1, $3);
01738
01739
01740
01741 }
01742 | primary_value '.' tIDENTIFIER
01743 {
01744
01745 $$ = attrset($1, $3);
01746
01747
01748
01749 }
01750 | primary_value tCOLON2 tIDENTIFIER
01751 {
01752
01753 $$ = attrset($1, $3);
01754
01755
01756
01757 }
01758 | primary_value '.' tCONSTANT
01759 {
01760
01761 $$ = attrset($1, $3);
01762
01763
01764
01765 }
01766 | primary_value tCOLON2 tCONSTANT
01767 {
01768
01769 if (in_def || in_single)
01770 yyerror("dynamic constant assignment");
01771 $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
01772
01773
01774
01775
01776
01777
01778 }
01779 | tCOLON3 tCONSTANT
01780 {
01781
01782 if (in_def || in_single)
01783 yyerror("dynamic constant assignment");
01784 $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
01785
01786
01787
01788
01789
01790
01791 }
01792 | backref
01793 {
01794
01795 rb_backref_error($1);
01796 $$ = NEW_BEGIN(0);
01797
01798
01799
01800 }
01801 ;
01802
01803 cname : tIDENTIFIER
01804 {
01805
01806 yyerror("class/module name must be CONSTANT");
01807
01808
01809
01810 }
01811 | tCONSTANT
01812 ;
01813
01814 cpath : tCOLON3 cname
01815 {
01816
01817 $$ = NEW_COLON3($2);
01818
01819
01820
01821 }
01822 | cname
01823 {
01824
01825 $$ = NEW_COLON2(0, $$);
01826
01827
01828
01829 }
01830 | primary_value tCOLON2 cname
01831 {
01832
01833 $$ = NEW_COLON2($1, $3);
01834
01835
01836
01837 }
01838 ;
01839
01840 fname : tIDENTIFIER
01841 | tCONSTANT
01842 | tFID
01843 | op
01844 {
01845 lex_state = EXPR_ENDFN;
01846 $$ = $1;
01847 }
01848 | reswords
01849 {
01850 lex_state = EXPR_ENDFN;
01851
01852 $$ = $<id>1;
01853
01854
01855
01856 }
01857 ;
01858
01859 fsym : fname
01860 | symbol
01861 ;
01862
01863 fitem : fsym
01864 {
01865
01866 $$ = NEW_LIT(ID2SYM($1));
01867
01868
01869
01870 }
01871 | dsym
01872 ;
01873
01874 undef_list : fitem
01875 {
01876
01877 $$ = NEW_UNDEF($1);
01878
01879
01880
01881 }
01882 | undef_list ',' {lex_state = EXPR_FNAME;} fitem
01883 {
01884
01885 $$ = block_append($1, NEW_UNDEF($4));
01886
01887
01888
01889 }
01890 ;
01891
01892 op : '|' { ifndef_ripper($$ = '|'); }
01893 | '^' { ifndef_ripper($$ = '^'); }
01894 | '&' { ifndef_ripper($$ = '&'); }
01895 | tCMP { ifndef_ripper($$ = tCMP); }
01896 | tEQ { ifndef_ripper($$ = tEQ); }
01897 | tEQQ { ifndef_ripper($$ = tEQQ); }
01898 | tMATCH { ifndef_ripper($$ = tMATCH); }
01899 | tNMATCH { ifndef_ripper($$ = tNMATCH); }
01900 | '>' { ifndef_ripper($$ = '>'); }
01901 | tGEQ { ifndef_ripper($$ = tGEQ); }
01902 | '<' { ifndef_ripper($$ = '<'); }
01903 | tLEQ { ifndef_ripper($$ = tLEQ); }
01904 | tNEQ { ifndef_ripper($$ = tNEQ); }
01905 | tLSHFT { ifndef_ripper($$ = tLSHFT); }
01906 | tRSHFT { ifndef_ripper($$ = tRSHFT); }
01907 | '+' { ifndef_ripper($$ = '+'); }
01908 | '-' { ifndef_ripper($$ = '-'); }
01909 | '*' { ifndef_ripper($$ = '*'); }
01910 | tSTAR { ifndef_ripper($$ = '*'); }
01911 | '/' { ifndef_ripper($$ = '/'); }
01912 | '%' { ifndef_ripper($$ = '%'); }
01913 | tPOW { ifndef_ripper($$ = tPOW); }
01914 | tDSTAR { ifndef_ripper($$ = tDSTAR); }
01915 | '!' { ifndef_ripper($$ = '!'); }
01916 | '~' { ifndef_ripper($$ = '~'); }
01917 | tUPLUS { ifndef_ripper($$ = tUPLUS); }
01918 | tUMINUS { ifndef_ripper($$ = tUMINUS); }
01919 | tAREF { ifndef_ripper($$ = tAREF); }
01920 | tASET { ifndef_ripper($$ = tASET); }
01921 | '`' { ifndef_ripper($$ = '`'); }
01922 ;
01923
01924 reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
01925 | keyword_BEGIN | keyword_END
01926 | keyword_alias | keyword_and | keyword_begin
01927 | keyword_break | keyword_case | keyword_class | keyword_def
01928 | keyword_defined | keyword_do | keyword_else | keyword_elsif
01929 | keyword_end | keyword_ensure | keyword_false
01930 | keyword_for | keyword_in | keyword_module | keyword_next
01931 | keyword_nil | keyword_not | keyword_or | keyword_redo
01932 | keyword_rescue | keyword_retry | keyword_return | keyword_self
01933 | keyword_super | keyword_then | keyword_true | keyword_undef
01934 | keyword_when | keyword_yield | keyword_if | keyword_unless
01935 | keyword_while | keyword_until
01936 ;
01937
01938 arg : lhs '=' arg
01939 {
01940
01941 value_expr($3);
01942 $$ = node_assign($1, $3);
01943
01944
01945
01946 }
01947 | lhs '=' arg modifier_rescue arg
01948 {
01949
01950 value_expr($3);
01951 $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
01952 $$ = node_assign($1, $3);
01953
01954
01955
01956 }
01957 | var_lhs tOP_ASGN arg
01958 {
01959 value_expr($3);
01960 $$ = new_op_assign($1, $2, $3);
01961 }
01962 | var_lhs tOP_ASGN arg modifier_rescue arg
01963 {
01964
01965 value_expr($3);
01966 $3 = NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0);
01967
01968
01969
01970 $$ = new_op_assign($1, $2, $3);
01971 }
01972 | primary_value '[' opt_call_args rbracket tOP_ASGN arg
01973 {
01974
01975 NODE *args;
01976
01977 value_expr($6);
01978 if (!$3) $3 = NEW_ZARRAY();
01979 if (nd_type($3) == NODE_BLOCK_PASS) {
01980 args = NEW_ARGSCAT($3, $6);
01981 }
01982 else {
01983 args = arg_concat($3, $6);
01984 }
01985 if ($5 == tOROP) {
01986 $5 = 0;
01987 }
01988 else if ($5 == tANDOP) {
01989 $5 = 1;
01990 }
01991 $$ = NEW_OP_ASGN1($1, $5, args);
01992 fixpos($$, $1);
01993
01994
01995
01996
01997 }
01998 | primary_value '.' tIDENTIFIER tOP_ASGN arg
01999 {
02000 value_expr($5);
02001 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
02002 }
02003 | primary_value '.' tCONSTANT tOP_ASGN arg
02004 {
02005 value_expr($5);
02006 $$ = new_attr_op_assign($1, ripper_id2sym('.'), $3, $4, $5);
02007 }
02008 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
02009 {
02010 value_expr($5);
02011 $$ = new_attr_op_assign($1, ripper_intern("::"), $3, $4, $5);
02012 }
02013 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
02014 {
02015
02016 $$ = NEW_COLON2($1, $3);
02017 $$ = new_const_op_assign($$, $4, $5);
02018
02019
02020
02021
02022 }
02023 | tCOLON3 tCONSTANT tOP_ASGN arg
02024 {
02025
02026 $$ = NEW_COLON3($2);
02027 $$ = new_const_op_assign($$, $3, $4);
02028
02029
02030
02031
02032 }
02033 | backref tOP_ASGN arg
02034 {
02035
02036 rb_backref_error($1);
02037 $$ = NEW_BEGIN(0);
02038
02039
02040
02041
02042
02043 }
02044 | arg tDOT2 arg
02045 {
02046
02047 value_expr($1);
02048 value_expr($3);
02049 $$ = NEW_DOT2($1, $3);
02050 if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
02051 nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
02052 deferred_nodes = list_append(deferred_nodes, $$);
02053 }
02054
02055
02056
02057 }
02058 | arg tDOT3 arg
02059 {
02060
02061 value_expr($1);
02062 value_expr($3);
02063 $$ = NEW_DOT3($1, $3);
02064 if (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&
02065 nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {
02066 deferred_nodes = list_append(deferred_nodes, $$);
02067 }
02068
02069
02070
02071 }
02072 | arg '+' arg
02073 {
02074
02075 $$ = call_bin_op($1, '+', $3);
02076
02077
02078
02079 }
02080 | arg '-' arg
02081 {
02082
02083 $$ = call_bin_op($1, '-', $3);
02084
02085
02086
02087 }
02088 | arg '*' arg
02089 {
02090
02091 $$ = call_bin_op($1, '*', $3);
02092
02093
02094
02095 }
02096 | arg '/' arg
02097 {
02098
02099 $$ = call_bin_op($1, '/', $3);
02100
02101
02102
02103 }
02104 | arg '%' arg
02105 {
02106
02107 $$ = call_bin_op($1, '%', $3);
02108
02109
02110
02111 }
02112 | arg tPOW arg
02113 {
02114
02115 $$ = call_bin_op($1, tPOW, $3);
02116
02117
02118
02119 }
02120 | tUMINUS_NUM tINTEGER tPOW arg
02121 {
02122
02123 $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
02124
02125
02126
02127
02128 }
02129 | tUMINUS_NUM tFLOAT tPOW arg
02130 {
02131
02132 $$ = NEW_CALL(call_bin_op($2, tPOW, $4), tUMINUS, 0);
02133
02134
02135
02136
02137 }
02138 | tUPLUS arg
02139 {
02140
02141 $$ = call_uni_op($2, tUPLUS);
02142
02143
02144
02145 }
02146 | tUMINUS arg
02147 {
02148
02149 $$ = call_uni_op($2, tUMINUS);
02150
02151
02152
02153 }
02154 | arg '|' arg
02155 {
02156
02157 $$ = call_bin_op($1, '|', $3);
02158
02159
02160
02161 }
02162 | arg '^' arg
02163 {
02164
02165 $$ = call_bin_op($1, '^', $3);
02166
02167
02168
02169 }
02170 | arg '&' arg
02171 {
02172
02173 $$ = call_bin_op($1, '&', $3);
02174
02175
02176
02177 }
02178 | arg tCMP arg
02179 {
02180
02181 $$ = call_bin_op($1, tCMP, $3);
02182
02183
02184
02185 }
02186 | arg '>' arg
02187 {
02188
02189 $$ = call_bin_op($1, '>', $3);
02190
02191
02192
02193 }
02194 | arg tGEQ arg
02195 {
02196
02197 $$ = call_bin_op($1, tGEQ, $3);
02198
02199
02200
02201 }
02202 | arg '<' arg
02203 {
02204
02205 $$ = call_bin_op($1, '<', $3);
02206
02207
02208
02209 }
02210 | arg tLEQ arg
02211 {
02212
02213 $$ = call_bin_op($1, tLEQ, $3);
02214
02215
02216
02217 }
02218 | arg tEQ arg
02219 {
02220
02221 $$ = call_bin_op($1, tEQ, $3);
02222
02223
02224
02225 }
02226 | arg tEQQ arg
02227 {
02228
02229 $$ = call_bin_op($1, tEQQ, $3);
02230
02231
02232
02233 }
02234 | arg tNEQ arg
02235 {
02236
02237 $$ = call_bin_op($1, tNEQ, $3);
02238
02239
02240
02241 }
02242 | arg tMATCH arg
02243 {
02244
02245 $$ = match_op($1, $3);
02246 if (nd_type($1) == NODE_LIT && RB_TYPE_P($1->nd_lit, T_REGEXP)) {
02247 $$ = reg_named_capture_assign($1->nd_lit, $$);
02248 }
02249
02250
02251
02252 }
02253 | arg tNMATCH arg
02254 {
02255
02256 $$ = call_bin_op($1, tNMATCH, $3);
02257
02258
02259
02260 }
02261 | '!' arg
02262 {
02263
02264 $$ = call_uni_op(cond($2), '!');
02265
02266
02267
02268 }
02269 | '~' arg
02270 {
02271
02272 $$ = call_uni_op($2, '~');
02273
02274
02275
02276 }
02277 | arg tLSHFT arg
02278 {
02279
02280 $$ = call_bin_op($1, tLSHFT, $3);
02281
02282
02283
02284 }
02285 | arg tRSHFT arg
02286 {
02287
02288 $$ = call_bin_op($1, tRSHFT, $3);
02289
02290
02291
02292 }
02293 | arg tANDOP arg
02294 {
02295
02296 $$ = logop(NODE_AND, $1, $3);
02297
02298
02299
02300 }
02301 | arg tOROP arg
02302 {
02303
02304 $$ = logop(NODE_OR, $1, $3);
02305
02306
02307
02308 }
02309 | keyword_defined opt_nl {in_defined = 1;} arg
02310 {
02311
02312 in_defined = 0;
02313 $$ = NEW_DEFINED($4);
02314
02315
02316
02317
02318 }
02319 | arg '?' arg opt_nl ':' arg
02320 {
02321
02322 value_expr($1);
02323 $$ = NEW_IF(cond($1), $3, $6);
02324 fixpos($$, $1);
02325
02326
02327
02328 }
02329 | primary
02330 {
02331 $$ = $1;
02332 }
02333 ;
02334
02335 arg_value : arg
02336 {
02337
02338 value_expr($1);
02339 $$ = $1;
02340 if (!$$) $$ = NEW_NIL();
02341
02342
02343
02344 }
02345 ;
02346
02347 aref_args : none
02348 | args trailer
02349 {
02350 $$ = $1;
02351 }
02352 | args ',' assocs trailer
02353 {
02354
02355 $$ = arg_append($1, NEW_HASH($3));
02356
02357
02358
02359 }
02360 | assocs trailer
02361 {
02362
02363 $$ = NEW_LIST(NEW_HASH($1));
02364
02365
02366
02367 }
02368 ;
02369
02370 paren_args : '(' opt_call_args rparen
02371 {
02372
02373 $$ = $2;
02374
02375
02376
02377 }
02378 ;
02379
02380 opt_paren_args : none
02381 | paren_args
02382 ;
02383
02384 opt_call_args : none
02385 | call_args
02386 | args ','
02387 {
02388 $$ = $1;
02389 }
02390 | args ',' assocs ','
02391 {
02392
02393 $$ = arg_append($1, NEW_HASH($3));
02394
02395
02396
02397 }
02398 | assocs ','
02399 {
02400
02401 $$ = NEW_LIST(NEW_HASH($1));
02402
02403
02404
02405 }
02406 ;
02407
02408 call_args : command
02409 {
02410
02411 value_expr($1);
02412 $$ = NEW_LIST($1);
02413
02414
02415
02416 }
02417 | args opt_block_arg
02418 {
02419
02420 $$ = arg_blk_pass($1, $2);
02421
02422
02423
02424 }
02425 | assocs opt_block_arg
02426 {
02427
02428 $$ = NEW_LIST(NEW_HASH($1));
02429 $$ = arg_blk_pass($$, $2);
02430
02431
02432
02433
02434 }
02435 | args ',' assocs opt_block_arg
02436 {
02437
02438 $$ = arg_append($1, NEW_HASH($3));
02439 $$ = arg_blk_pass($$, $4);
02440
02441
02442
02443 }
02444 | block_arg
02445
02446
02447
02448
02449
02450
02451 ;
02452
02453 command_args : {
02454 $<val>$ = cmdarg_stack;
02455 CMDARG_PUSH(1);
02456 }
02457 call_args
02458 {
02459
02460 cmdarg_stack = $<val>1;
02461 $$ = $2;
02462 }
02463 ;
02464
02465 block_arg : tAMPER arg_value
02466 {
02467
02468 $$ = NEW_BLOCK_PASS($2);
02469
02470
02471
02472 }
02473 ;
02474
02475 opt_block_arg : ',' block_arg
02476 {
02477 $$ = $2;
02478 }
02479 | none
02480 {
02481 $$ = 0;
02482 }
02483 ;
02484
02485 args : arg_value
02486 {
02487
02488 $$ = NEW_LIST($1);
02489
02490
02491
02492 }
02493 | tSTAR arg_value
02494 {
02495
02496 $$ = NEW_SPLAT($2);
02497
02498
02499
02500 }
02501 | args ',' arg_value
02502 {
02503
02504 NODE *n1;
02505 if ((n1 = splat_array($1)) != 0) {
02506 $$ = list_append(n1, $3);
02507 }
02508 else {
02509 $$ = arg_append($1, $3);
02510 }
02511
02512
02513
02514 }
02515 | args ',' tSTAR arg_value
02516 {
02517
02518 NODE *n1;
02519 if ((nd_type($4) == NODE_ARRAY) && (n1 = splat_array($1)) != 0) {
02520 $$ = list_concat(n1, $4);
02521 }
02522 else {
02523 $$ = arg_concat($1, $4);
02524 }
02525
02526
02527
02528 }
02529 ;
02530
02531 mrhs : args ',' arg_value
02532 {
02533
02534 NODE *n1;
02535 if ((n1 = splat_array($1)) != 0) {
02536 $$ = list_append(n1, $3);
02537 }
02538 else {
02539 $$ = arg_append($1, $3);
02540 }
02541
02542
02543
02544 }
02545 | args ',' tSTAR arg_value
02546 {
02547
02548 NODE *n1;
02549 if (nd_type($4) == NODE_ARRAY &&
02550 (n1 = splat_array($1)) != 0) {
02551 $$ = list_concat(n1, $4);
02552 }
02553 else {
02554 $$ = arg_concat($1, $4);
02555 }
02556
02557
02558
02559 }
02560 | tSTAR arg_value
02561 {
02562
02563 $$ = NEW_SPLAT($2);
02564
02565
02566
02567 }
02568 ;
02569
02570 primary : literal
02571 | strings
02572 | xstring
02573 | regexp
02574 | words
02575 | qwords
02576 | symbols
02577 | qsymbols
02578 | var_ref
02579 | backref
02580 | tFID
02581 {
02582
02583 $$ = NEW_FCALL($1, 0);
02584
02585
02586
02587 }
02588 | k_begin
02589 {
02590 $<val>1 = cmdarg_stack;
02591 cmdarg_stack = 0;
02592
02593 $<num>$ = ruby_sourceline;
02594
02595
02596 }
02597 bodystmt
02598 k_end
02599 {
02600 cmdarg_stack = $<val>1;
02601
02602 if ($3 == NULL) {
02603 $$ = NEW_NIL();
02604 }
02605 else {
02606 if (nd_type($3) == NODE_RESCUE ||
02607 nd_type($3) == NODE_ENSURE)
02608 nd_set_line($3, $<num>2);
02609 $$ = NEW_BEGIN($3);
02610 }
02611 nd_set_line($$, $<num>2);
02612
02613
02614
02615 }
02616 | tLPAREN_ARG {lex_state = EXPR_ENDARG;} rparen
02617 {
02618
02619 $$ = 0;
02620
02621
02622
02623 }
02624 | tLPAREN_ARG
02625 {
02626 $<val>1 = cmdarg_stack;
02627 cmdarg_stack = 0;
02628 }
02629 expr {lex_state = EXPR_ENDARG;} rparen
02630 {
02631 cmdarg_stack = $<val>1;
02632
02633 $$ = $3;
02634
02635
02636
02637 }
02638 | tLPAREN compstmt ')'
02639 {
02640
02641 $$ = $2;
02642
02643
02644
02645 }
02646 | primary_value tCOLON2 tCONSTANT
02647 {
02648
02649 $$ = NEW_COLON2($1, $3);
02650
02651
02652
02653 }
02654 | tCOLON3 tCONSTANT
02655 {
02656
02657 $$ = NEW_COLON3($2);
02658
02659
02660
02661 }
02662 | tLBRACK aref_args ']'
02663 {
02664
02665 if ($2 == 0) {
02666 $$ = NEW_ZARRAY();
02667 }
02668 else {
02669 $$ = $2;
02670 }
02671
02672
02673
02674 }
02675 | tLBRACE assoc_list '}'
02676 {
02677
02678 $$ = NEW_HASH($2);
02679
02680
02681
02682 }
02683 | keyword_return
02684 {
02685
02686 $$ = NEW_RETURN(0);
02687
02688
02689
02690 }
02691 | keyword_yield '(' call_args rparen
02692 {
02693
02694 $$ = new_yield($3);
02695
02696
02697
02698 }
02699 | keyword_yield '(' rparen
02700 {
02701
02702 $$ = NEW_YIELD(0);
02703
02704
02705
02706 }
02707 | keyword_yield
02708 {
02709
02710 $$ = NEW_YIELD(0);
02711
02712
02713
02714 }
02715 | keyword_defined opt_nl '(' {in_defined = 1;} expr rparen
02716 {
02717
02718 in_defined = 0;
02719 $$ = NEW_DEFINED($5);
02720
02721
02722
02723
02724 }
02725 | keyword_not '(' expr rparen
02726 {
02727
02728 $$ = call_uni_op(cond($3), '!');
02729
02730
02731
02732 }
02733 | keyword_not '(' rparen
02734 {
02735
02736 $$ = call_uni_op(cond(NEW_NIL()), '!');
02737
02738
02739
02740 }
02741 | fcall brace_block
02742 {
02743
02744 $2->nd_iter = $1;
02745 $$ = $2;
02746
02747
02748
02749
02750 }
02751 | method_call
02752 | method_call brace_block
02753 {
02754
02755 block_dup_check($1->nd_args, $2);
02756 $2->nd_iter = $1;
02757 $$ = $2;
02758
02759
02760
02761 }
02762 | tLAMBDA lambda
02763 {
02764 $$ = $2;
02765 }
02766 | k_if expr_value then
02767 compstmt
02768 if_tail
02769 k_end
02770 {
02771
02772 $$ = NEW_IF(cond($2), $4, $5);
02773 fixpos($$, $2);
02774
02775
02776
02777 }
02778 | k_unless expr_value then
02779 compstmt
02780 opt_else
02781 k_end
02782 {
02783
02784 $$ = NEW_UNLESS(cond($2), $4, $5);
02785 fixpos($$, $2);
02786
02787
02788
02789 }
02790 | k_while {COND_PUSH(1);} expr_value do {COND_POP();}
02791 compstmt
02792 k_end
02793 {
02794
02795 $$ = NEW_WHILE(cond($3), $6, 1);
02796 fixpos($$, $3);
02797
02798
02799
02800 }
02801 | k_until {COND_PUSH(1);} expr_value do {COND_POP();}
02802 compstmt
02803 k_end
02804 {
02805
02806 $$ = NEW_UNTIL(cond($3), $6, 1);
02807 fixpos($$, $3);
02808
02809
02810
02811 }
02812 | k_case expr_value opt_terms
02813 case_body
02814 k_end
02815 {
02816
02817 $$ = NEW_CASE($2, $4);
02818 fixpos($$, $2);
02819
02820
02821
02822 }
02823 | k_case opt_terms case_body k_end
02824 {
02825
02826 $$ = NEW_CASE(0, $3);
02827
02828
02829
02830 }
02831 | k_for for_var keyword_in
02832 {COND_PUSH(1);}
02833 expr_value do
02834 {COND_POP();}
02835 compstmt
02836 k_end
02837 {
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848 ID id = internal_id();
02849 ID *tbl = ALLOC_N(ID, 2);
02850 NODE *m = NEW_ARGS_AUX(0, 0);
02851 NODE *args, *scope;
02852
02853 if (nd_type($2) == NODE_MASGN) {
02854
02855
02856
02857
02858 NODE *one = NEW_LIST(NEW_LIT(INT2FIX(1)));
02859 NODE *zero = NEW_LIST(NEW_LIT(INT2FIX(0)));
02860 m->nd_next = block_append(
02861 NEW_IF(
02862 NEW_NODE(NODE_AND,
02863 NEW_CALL(NEW_CALL(NEW_DVAR(id), idLength, 0),
02864 idEq, one),
02865 NEW_CALL(NEW_CALL(NEW_DVAR(id), idAREF, zero),
02866 rb_intern("kind_of?"), NEW_LIST(NEW_LIT(rb_cArray))),
02867 0),
02868 NEW_DASGN_CURR(id,
02869 NEW_CALL(NEW_DVAR(id), idAREF, zero)),
02870 0),
02871 node_assign($2, NEW_DVAR(id)));
02872
02873 args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
02874 }
02875 else {
02876 if (nd_type($2) == NODE_LASGN ||
02877 nd_type($2) == NODE_DASGN ||
02878 nd_type($2) == NODE_DASGN_CURR) {
02879 $2->nd_value = NEW_DVAR(id);
02880 m->nd_plen = 1;
02881 m->nd_next = $2;
02882 args = new_args(m, 0, 0, 0, new_args_tail(0, 0, 0));
02883 }
02884 else {
02885 m->nd_next = node_assign(NEW_MASGN(NEW_LIST($2), 0), NEW_DVAR(id));
02886 args = new_args(m, 0, id, 0, new_args_tail(0, 0, 0));
02887 }
02888 }
02889 scope = NEW_NODE(NODE_SCOPE, tbl, $8, args);
02890 tbl[0] = 1; tbl[1] = id;
02891 $$ = NEW_FOR(0, $5, scope);
02892 fixpos($$, $2);
02893
02894
02895
02896 }
02897 | k_class cpath superclass
02898 {
02899 if (in_def || in_single)
02900 yyerror("class definition in method body");
02901 local_push(0);
02902
02903 $<num>$ = ruby_sourceline;
02904
02905
02906 }
02907 bodystmt
02908 k_end
02909 {
02910
02911 $$ = NEW_CLASS($2, $5, $3);
02912 nd_set_line($$, $<num>4);
02913
02914
02915
02916 local_pop();
02917 }
02918 | k_class tLSHFT expr
02919 {
02920 $<num>$ = in_def;
02921 in_def = 0;
02922 }
02923 term
02924 {
02925 $<num>$ = in_single;
02926 in_single = 0;
02927 local_push(0);
02928 }
02929 bodystmt
02930 k_end
02931 {
02932
02933 $$ = NEW_SCLASS($3, $7);
02934 fixpos($$, $3);
02935
02936
02937
02938 local_pop();
02939 in_def = $<num>4;
02940 in_single = $<num>6;
02941 }
02942 | k_module cpath
02943 {
02944 if (in_def || in_single)
02945 yyerror("module definition in method body");
02946 local_push(0);
02947
02948 $<num>$ = ruby_sourceline;
02949
02950
02951 }
02952 bodystmt
02953 k_end
02954 {
02955
02956 $$ = NEW_MODULE($2, $4);
02957 nd_set_line($$, $<num>3);
02958
02959
02960
02961 local_pop();
02962 }
02963 | k_def fname
02964 {
02965 $<id>$ = cur_mid;
02966 cur_mid = $2;
02967 in_def++;
02968 local_push(0);
02969 }
02970 f_arglist
02971 bodystmt
02972 k_end
02973 {
02974
02975 NODE *body = remove_begin($5);
02976 reduce_nodes(&body);
02977 $$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE);
02978 nd_set_line($$, $<num>1);
02979
02980
02981
02982 local_pop();
02983 in_def--;
02984 cur_mid = $<id>3;
02985 }
02986 | k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
02987 {
02988 in_single++;
02989 lex_state = EXPR_ENDFN;
02990 local_push(0);
02991 }
02992 f_arglist
02993 bodystmt
02994 k_end
02995 {
02996
02997 NODE *body = remove_begin($8);
02998 reduce_nodes(&body);
02999 $$ = NEW_DEFS($2, $5, $7, body);
03000 nd_set_line($$, $<num>1);
03001
03002
03003
03004 local_pop();
03005 in_single--;
03006 }
03007 | keyword_break
03008 {
03009
03010 $$ = NEW_BREAK(0);
03011
03012
03013
03014 }
03015 | keyword_next
03016 {
03017
03018 $$ = NEW_NEXT(0);
03019
03020
03021
03022 }
03023 | keyword_redo
03024 {
03025
03026 $$ = NEW_REDO();
03027
03028
03029
03030 }
03031 | keyword_retry
03032 {
03033
03034 $$ = NEW_RETRY();
03035
03036
03037
03038 }
03039 ;
03040
03041 primary_value : primary
03042 {
03043
03044 value_expr($1);
03045 $$ = $1;
03046 if (!$$) $$ = NEW_NIL();
03047
03048
03049
03050 }
03051 ;
03052
03053 k_begin : keyword_begin
03054 {
03055 token_info_push("begin");
03056 }
03057 ;
03058
03059 k_if : keyword_if
03060 {
03061 token_info_push("if");
03062 }
03063 ;
03064
03065 k_unless : keyword_unless
03066 {
03067 token_info_push("unless");
03068 }
03069 ;
03070
03071 k_while : keyword_while
03072 {
03073 token_info_push("while");
03074 }
03075 ;
03076
03077 k_until : keyword_until
03078 {
03079 token_info_push("until");
03080 }
03081 ;
03082
03083 k_case : keyword_case
03084 {
03085 token_info_push("case");
03086 }
03087 ;
03088
03089 k_for : keyword_for
03090 {
03091 token_info_push("for");
03092 }
03093 ;
03094
03095 k_class : keyword_class
03096 {
03097 token_info_push("class");
03098 }
03099 ;
03100
03101 k_module : keyword_module
03102 {
03103 token_info_push("module");
03104 }
03105 ;
03106
03107 k_def : keyword_def
03108 {
03109 token_info_push("def");
03110
03111 $<num>$ = ruby_sourceline;
03112
03113
03114 }
03115 ;
03116
03117 k_end : keyword_end
03118 {
03119 token_info_pop("end");
03120 }
03121 ;
03122
03123 then : term
03124
03125
03126
03127
03128 | keyword_then
03129 | term keyword_then
03130
03131
03132
03133
03134 ;
03135
03136 do : term
03137
03138
03139
03140
03141 | keyword_do_cond
03142 ;
03143
03144 if_tail : opt_else
03145 | keyword_elsif expr_value then
03146 compstmt
03147 if_tail
03148 {
03149
03150 $$ = NEW_IF(cond($2), $4, $5);
03151 fixpos($$, $2);
03152
03153
03154
03155 }
03156 ;
03157
03158 opt_else : none
03159 | keyword_else compstmt
03160 {
03161
03162 $$ = $2;
03163
03164
03165
03166 }
03167 ;
03168
03169 for_var : lhs
03170 | mlhs
03171 ;
03172
03173 f_marg : f_norm_arg
03174 {
03175 $$ = assignable($1, 0);
03176
03177
03178
03179
03180 }
03181 | tLPAREN f_margs rparen
03182 {
03183
03184 $$ = $2;
03185
03186
03187
03188 }
03189 ;
03190
03191 f_marg_list : f_marg
03192 {
03193
03194 $$ = NEW_LIST($1);
03195
03196
03197
03198 }
03199 | f_marg_list ',' f_marg
03200 {
03201
03202 $$ = list_append($1, $3);
03203
03204
03205
03206 }
03207 ;
03208
03209 f_margs : f_marg_list
03210 {
03211
03212 $$ = NEW_MASGN($1, 0);
03213
03214
03215
03216 }
03217 | f_marg_list ',' tSTAR f_norm_arg
03218 {
03219 $$ = assignable($4, 0);
03220
03221 $$ = NEW_MASGN($1, $$);
03222
03223
03224
03225 }
03226 | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
03227 {
03228 $$ = assignable($4, 0);
03229
03230 $$ = NEW_MASGN($1, NEW_POSTARG($$, $6));
03231
03232
03233
03234 }
03235 | f_marg_list ',' tSTAR
03236 {
03237
03238 $$ = NEW_MASGN($1, -1);
03239
03240
03241
03242 }
03243 | f_marg_list ',' tSTAR ',' f_marg_list
03244 {
03245
03246 $$ = NEW_MASGN($1, NEW_POSTARG(-1, $5));
03247
03248
03249
03250 }
03251 | tSTAR f_norm_arg
03252 {
03253 $$ = assignable($2, 0);
03254
03255 $$ = NEW_MASGN(0, $$);
03256
03257
03258
03259 }
03260 | tSTAR f_norm_arg ',' f_marg_list
03261 {
03262 $$ = assignable($2, 0);
03263
03264 $$ = NEW_MASGN(0, NEW_POSTARG($$, $4));
03265
03266
03267
03268
03269
03270
03271 }
03272 | tSTAR
03273 {
03274
03275 $$ = NEW_MASGN(0, -1);
03276
03277
03278
03279 }
03280 | tSTAR ',' f_marg_list
03281 {
03282
03283 $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3));
03284
03285
03286
03287 }
03288 ;
03289
03290
03291 block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg
03292 {
03293 $$ = new_args_tail($1, $3, $4);
03294 }
03295 | f_block_kwarg opt_f_block_arg
03296 {
03297 $$ = new_args_tail($1, Qnone, $2);
03298 }
03299 | f_kwrest opt_f_block_arg
03300 {
03301 $$ = new_args_tail(Qnone, $1, $2);
03302 }
03303 | f_block_arg
03304 {
03305 $$ = new_args_tail(Qnone, Qnone, $1);
03306 }
03307 ;
03308
03309 opt_block_args_tail : ',' block_args_tail
03310 {
03311 $$ = $2;
03312 }
03313 |
03314 {
03315 $$ = new_args_tail(Qnone, Qnone, Qnone);
03316 }
03317 ;
03318
03319 block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail
03320 {
03321 $$ = new_args($1, $3, $5, Qnone, $6);
03322 }
03323 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
03324 {
03325 $$ = new_args($1, $3, $5, $7, $8);
03326 }
03327 | f_arg ',' f_block_optarg opt_block_args_tail
03328 {
03329 $$ = new_args($1, $3, Qnone, Qnone, $4);
03330 }
03331 | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail
03332 {
03333 $$ = new_args($1, $3, Qnone, $5, $6);
03334 }
03335 | f_arg ',' f_rest_arg opt_block_args_tail
03336 {
03337 $$ = new_args($1, Qnone, $3, Qnone, $4);
03338 }
03339 | f_arg ','
03340 {
03341 $$ = new_args($1, Qnone, 1, Qnone, new_args_tail(Qnone, Qnone, Qnone));
03342
03343
03344
03345
03346 }
03347 | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail
03348 {
03349 $$ = new_args($1, Qnone, $3, $5, $6);
03350 }
03351 | f_arg opt_block_args_tail
03352 {
03353 $$ = new_args($1, Qnone, Qnone, Qnone, $2);
03354 }
03355 | f_block_optarg ',' f_rest_arg opt_block_args_tail
03356 {
03357 $$ = new_args(Qnone, $1, $3, Qnone, $4);
03358 }
03359 | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail
03360 {
03361 $$ = new_args(Qnone, $1, $3, $5, $6);
03362 }
03363 | f_block_optarg opt_block_args_tail
03364 {
03365 $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
03366 }
03367 | f_block_optarg ',' f_arg opt_block_args_tail
03368 {
03369 $$ = new_args(Qnone, $1, Qnone, $3, $4);
03370 }
03371 | f_rest_arg opt_block_args_tail
03372 {
03373 $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
03374 }
03375 | f_rest_arg ',' f_arg opt_block_args_tail
03376 {
03377 $$ = new_args(Qnone, Qnone, $1, $3, $4);
03378 }
03379 | block_args_tail
03380 {
03381 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
03382 }
03383 ;
03384
03385 opt_block_param : none
03386 | block_param_def
03387 {
03388 command_start = TRUE;
03389 }
03390 ;
03391
03392 block_param_def : '|' opt_bv_decl '|'
03393 {
03394
03395 $$ = 0;
03396
03397
03398
03399
03400 }
03401 | tOROP
03402 {
03403
03404 $$ = 0;
03405
03406
03407
03408
03409 }
03410 | '|' block_param opt_bv_decl '|'
03411 {
03412
03413 $$ = $2;
03414
03415
03416
03417 }
03418 ;
03419
03420
03421 opt_bv_decl : opt_nl
03422 {
03423 $$ = 0;
03424 }
03425 | opt_nl ';' bv_decls opt_nl
03426 {
03427
03428 $$ = 0;
03429
03430
03431
03432 }
03433 ;
03434
03435 bv_decls : bvar
03436
03437
03438
03439
03440
03441
03442 | bv_decls ',' bvar
03443
03444
03445
03446
03447
03448
03449 ;
03450
03451 bvar : tIDENTIFIER
03452 {
03453 new_bv(get_id($1));
03454
03455
03456
03457
03458 }
03459 | f_bad_arg
03460 {
03461 $$ = 0;
03462 }
03463 ;
03464
03465 lambda : {
03466 $<vars>$ = dyna_push();
03467 }
03468 {
03469 $<num>$ = lpar_beg;
03470 lpar_beg = ++paren_nest;
03471 }
03472 f_larglist
03473 {
03474 $<num>$ = ruby_sourceline;
03475 }
03476 lambda_body
03477 {
03478 lpar_beg = $<num>2;
03479
03480 $$ = NEW_LAMBDA($3, $5);
03481 nd_set_line($$, $<num>4);
03482
03483
03484
03485 dyna_pop($<vars>1);
03486 }
03487 ;
03488
03489 f_larglist : '(' f_args opt_bv_decl ')'
03490 {
03491
03492 $$ = $2;
03493
03494
03495
03496 }
03497 | f_args
03498 {
03499
03500 $$ = $1;
03501
03502
03503
03504 }
03505 ;
03506
03507 lambda_body : tLAMBEG compstmt '}'
03508 {
03509 $$ = $2;
03510 }
03511 | keyword_do_LAMBDA compstmt keyword_end
03512 {
03513 $$ = $2;
03514 }
03515 ;
03516
03517 do_block : keyword_do_block
03518 {
03519 $<vars>1 = dyna_push();
03520
03521 $<num>$ = ruby_sourceline;
03522
03523 }
03524 opt_block_param
03525 compstmt
03526 keyword_end
03527 {
03528
03529 $$ = NEW_ITER($3,$4);
03530 nd_set_line($$, $<num>2);
03531
03532
03533
03534 dyna_pop($<vars>1);
03535 }
03536 ;
03537
03538 block_call : command do_block
03539 {
03540
03541 if (nd_type($1) == NODE_YIELD) {
03542 compile_error(PARSER_ARG "block given to yield");
03543 }
03544 else {
03545 block_dup_check($1->nd_args, $2);
03546 }
03547 $2->nd_iter = $1;
03548 $$ = $2;
03549 fixpos($$, $1);
03550
03551
03552
03553 }
03554 | block_call dot_or_colon operation2 opt_paren_args
03555 {
03556
03557 $$ = NEW_CALL($1, $3, $4);
03558
03559
03560
03561
03562 }
03563 | block_call dot_or_colon operation2 opt_paren_args brace_block
03564 {
03565
03566 block_dup_check($4, $5);
03567 $5->nd_iter = NEW_CALL($1, $3, $4);
03568 $$ = $5;
03569 fixpos($$, $1);
03570
03571
03572
03573
03574 }
03575 | block_call dot_or_colon operation2 command_args do_block
03576 {
03577
03578 block_dup_check($4, $5);
03579 $5->nd_iter = NEW_CALL($1, $3, $4);
03580 $$ = $5;
03581 fixpos($$, $1);
03582
03583
03584
03585
03586 }
03587 ;
03588
03589 method_call : fcall paren_args
03590 {
03591
03592 $$ = $1;
03593 $$->nd_args = $2;
03594
03595
03596
03597 }
03598 | primary_value '.' operation2
03599 {
03600
03601 $<num>$ = ruby_sourceline;
03602
03603 }
03604 opt_paren_args
03605 {
03606
03607 $$ = NEW_CALL($1, $3, $5);
03608 nd_set_line($$, $<num>4);
03609
03610
03611
03612
03613 }
03614 | primary_value tCOLON2 operation2
03615 {
03616
03617 $<num>$ = ruby_sourceline;
03618
03619 }
03620 paren_args
03621 {
03622
03623 $$ = NEW_CALL($1, $3, $5);
03624 nd_set_line($$, $<num>4);
03625
03626
03627
03628
03629 }
03630 | primary_value tCOLON2 operation3
03631 {
03632
03633 $$ = NEW_CALL($1, $3, 0);
03634
03635
03636
03637 }
03638 | primary_value '.'
03639 {
03640
03641 $<num>$ = ruby_sourceline;
03642
03643 }
03644 paren_args
03645 {
03646
03647 $$ = NEW_CALL($1, rb_intern("call"), $4);
03648 nd_set_line($$, $<num>3);
03649
03650
03651
03652
03653
03654 }
03655 | primary_value tCOLON2
03656 {
03657
03658 $<num>$ = ruby_sourceline;
03659
03660 }
03661 paren_args
03662 {
03663
03664 $$ = NEW_CALL($1, rb_intern("call"), $4);
03665 nd_set_line($$, $<num>3);
03666
03667
03668
03669
03670
03671 }
03672 | keyword_super paren_args
03673 {
03674
03675 $$ = NEW_SUPER($2);
03676
03677
03678
03679 }
03680 | keyword_super
03681 {
03682
03683 $$ = NEW_ZSUPER();
03684
03685
03686
03687 }
03688 | primary_value '[' opt_call_args rbracket
03689 {
03690
03691 if ($1 && nd_type($1) == NODE_SELF)
03692 $$ = NEW_FCALL(tAREF, $3);
03693 else
03694 $$ = NEW_CALL($1, tAREF, $3);
03695 fixpos($$, $1);
03696
03697
03698
03699 }
03700 ;
03701
03702 brace_block : '{'
03703 {
03704 $<vars>1 = dyna_push();
03705
03706 $<num>$ = ruby_sourceline;
03707
03708
03709 }
03710 opt_block_param
03711 compstmt '}'
03712 {
03713
03714 $$ = NEW_ITER($3,$4);
03715 nd_set_line($$, $<num>2);
03716
03717
03718
03719 dyna_pop($<vars>1);
03720 }
03721 | keyword_do
03722 {
03723 $<vars>1 = dyna_push();
03724
03725 $<num>$ = ruby_sourceline;
03726
03727
03728 }
03729 opt_block_param
03730 compstmt keyword_end
03731 {
03732
03733 $$ = NEW_ITER($3,$4);
03734 nd_set_line($$, $<num>2);
03735
03736
03737
03738 dyna_pop($<vars>1);
03739 }
03740 ;
03741
03742 case_body : keyword_when args then
03743 compstmt
03744 cases
03745 {
03746
03747 $$ = NEW_WHEN($2, $4, $5);
03748
03749
03750
03751 }
03752 ;
03753
03754 cases : opt_else
03755 | case_body
03756 ;
03757
03758 opt_rescue : keyword_rescue exc_list exc_var then
03759 compstmt
03760 opt_rescue
03761 {
03762
03763 if ($3) {
03764 $3 = node_assign($3, NEW_ERRINFO());
03765 $5 = block_append($3, $5);
03766 }
03767 $$ = NEW_RESBODY($2, $5, $6);
03768 fixpos($$, $2?$2:$5);
03769
03770
03771
03772
03773
03774
03775
03776 }
03777 | none
03778 ;
03779
03780 exc_list : arg_value
03781 {
03782
03783 $$ = NEW_LIST($1);
03784
03785
03786
03787 }
03788 | mrhs
03789 {
03790
03791 if (!($$ = splat_array($1))) $$ = $1;
03792
03793
03794
03795 }
03796 | none
03797 ;
03798
03799 exc_var : tASSOC lhs
03800 {
03801 $$ = $2;
03802 }
03803 | none
03804 ;
03805
03806 opt_ensure : keyword_ensure compstmt
03807 {
03808
03809 $$ = $2;
03810
03811
03812
03813 }
03814 | none
03815 ;
03816
03817 literal : numeric
03818 | symbol
03819 {
03820
03821 $$ = NEW_LIT(ID2SYM($1));
03822
03823
03824
03825 }
03826 | dsym
03827 ;
03828
03829 strings : string
03830 {
03831
03832 NODE *node = $1;
03833 if (!node) {
03834 node = NEW_STR(STR_NEW0());
03835 }
03836 else {
03837 node = evstr2dstr(node);
03838 }
03839 $$ = node;
03840
03841
03842
03843 }
03844 ;
03845
03846 string : tCHAR
03847 | string1
03848 | string string1
03849 {
03850
03851 $$ = literal_concat($1, $2);
03852
03853
03854
03855 }
03856 ;
03857
03858 string1 : tSTRING_BEG string_contents tSTRING_END
03859 {
03860
03861 $$ = $2;
03862
03863
03864
03865 }
03866 ;
03867
03868 xstring : tXSTRING_BEG xstring_contents tSTRING_END
03869 {
03870
03871 NODE *node = $2;
03872 if (!node) {
03873 node = NEW_XSTR(STR_NEW0());
03874 }
03875 else {
03876 switch (nd_type(node)) {
03877 case NODE_STR:
03878 nd_set_type(node, NODE_XSTR);
03879 break;
03880 case NODE_DSTR:
03881 nd_set_type(node, NODE_DXSTR);
03882 break;
03883 default:
03884 node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node));
03885 break;
03886 }
03887 }
03888 $$ = node;
03889
03890
03891
03892 }
03893 ;
03894
03895 regexp : tREGEXP_BEG regexp_contents tREGEXP_END
03896 {
03897
03898 int options = $3;
03899 NODE *node = $2;
03900 NODE *list, *prev;
03901 if (!node) {
03902 node = NEW_LIT(reg_compile(STR_NEW0(), options));
03903 }
03904 else switch (nd_type(node)) {
03905 case NODE_STR:
03906 {
03907 VALUE src = node->nd_lit;
03908 nd_set_type(node, NODE_LIT);
03909 node->nd_lit = reg_compile(src, options);
03910 }
03911 break;
03912 default:
03913 node = NEW_NODE(NODE_DSTR, STR_NEW0(), 1, NEW_LIST(node));
03914 case NODE_DSTR:
03915 if (options & RE_OPTION_ONCE) {
03916 nd_set_type(node, NODE_DREGX_ONCE);
03917 }
03918 else {
03919 nd_set_type(node, NODE_DREGX);
03920 }
03921 node->nd_cflag = options & RE_OPTION_MASK;
03922 if (!NIL_P(node->nd_lit)) reg_fragment_check(node->nd_lit, options);
03923 for (list = (prev = node)->nd_next; list; list = list->nd_next) {
03924 if (nd_type(list->nd_head) == NODE_STR) {
03925 VALUE tail = list->nd_head->nd_lit;
03926 if (reg_fragment_check(tail, options) && prev && !NIL_P(prev->nd_lit)) {
03927 VALUE lit = prev == node ? prev->nd_lit : prev->nd_head->nd_lit;
03928 if (!literal_concat0(parser, lit, tail)) {
03929 node = 0;
03930 break;
03931 }
03932 rb_str_resize(tail, 0);
03933 prev->nd_next = list->nd_next;
03934 rb_gc_force_recycle((VALUE)list->nd_head);
03935 rb_gc_force_recycle((VALUE)list);
03936 list = prev;
03937 }
03938 else {
03939 prev = list;
03940 }
03941 }
03942 else {
03943 prev = 0;
03944 }
03945 }
03946 if (!node->nd_next) {
03947 VALUE src = node->nd_lit;
03948 nd_set_type(node, NODE_LIT);
03949 node->nd_lit = reg_compile(src, options);
03950 }
03951 break;
03952 }
03953 $$ = node;
03954
03955
03956
03957 }
03958 ;
03959
03960 words : tWORDS_BEG ' ' tSTRING_END
03961 {
03962
03963 $$ = NEW_ZARRAY();
03964
03965
03966
03967
03968 }
03969 | tWORDS_BEG word_list tSTRING_END
03970 {
03971
03972 $$ = $2;
03973
03974
03975
03976 }
03977 ;
03978
03979 word_list :
03980 {
03981
03982 $$ = 0;
03983
03984
03985
03986 }
03987 | word_list word ' '
03988 {
03989
03990 $$ = list_append($1, evstr2dstr($2));
03991
03992
03993
03994 }
03995 ;
03996
03997 word : string_content
03998
03999
04000
04001
04002
04003
04004
04005 | word string_content
04006 {
04007
04008 $$ = literal_concat($1, $2);
04009
04010
04011
04012 }
04013 ;
04014
04015 symbols : tSYMBOLS_BEG ' ' tSTRING_END
04016 {
04017
04018 $$ = NEW_ZARRAY();
04019
04020
04021
04022
04023 }
04024 | tSYMBOLS_BEG symbol_list tSTRING_END
04025 {
04026
04027 $$ = $2;
04028
04029
04030
04031 }
04032 ;
04033
04034 symbol_list :
04035 {
04036
04037 $$ = 0;
04038
04039
04040
04041 }
04042 | symbol_list word ' '
04043 {
04044
04045 $2 = evstr2dstr($2);
04046 if (nd_type($2) == NODE_DSTR) {
04047 nd_set_type($2, NODE_DSYM);
04048 }
04049 else {
04050 nd_set_type($2, NODE_LIT);
04051 $2->nd_lit = rb_str_intern($2->nd_lit);
04052 }
04053 $$ = list_append($1, $2);
04054
04055
04056
04057 }
04058 ;
04059
04060 qwords : tQWORDS_BEG ' ' tSTRING_END
04061 {
04062
04063 $$ = NEW_ZARRAY();
04064
04065
04066
04067
04068 }
04069 | tQWORDS_BEG qword_list tSTRING_END
04070 {
04071
04072 $$ = $2;
04073
04074
04075
04076 }
04077 ;
04078
04079 qsymbols : tQSYMBOLS_BEG ' ' tSTRING_END
04080 {
04081
04082 $$ = NEW_ZARRAY();
04083
04084
04085
04086
04087 }
04088 | tQSYMBOLS_BEG qsym_list tSTRING_END
04089 {
04090
04091 $$ = $2;
04092
04093
04094
04095 }
04096 ;
04097
04098 qword_list :
04099 {
04100
04101 $$ = 0;
04102
04103
04104
04105 }
04106 | qword_list tSTRING_CONTENT ' '
04107 {
04108
04109 $$ = list_append($1, $2);
04110
04111
04112
04113 }
04114 ;
04115
04116 qsym_list :
04117 {
04118
04119 $$ = 0;
04120
04121
04122
04123 }
04124 | qsym_list tSTRING_CONTENT ' '
04125 {
04126
04127 VALUE lit;
04128 lit = $2->nd_lit;
04129 $2->nd_lit = ID2SYM(rb_intern_str(lit));
04130 nd_set_type($2, NODE_LIT);
04131 $$ = list_append($1, $2);
04132
04133
04134
04135 }
04136 ;
04137
04138 string_contents :
04139 {
04140
04141 $$ = 0;
04142
04143
04144
04145 }
04146 | string_contents string_content
04147 {
04148
04149 $$ = literal_concat($1, $2);
04150
04151
04152
04153 }
04154 ;
04155
04156 xstring_contents:
04157 {
04158
04159 $$ = 0;
04160
04161
04162
04163 }
04164 | xstring_contents string_content
04165 {
04166
04167 $$ = literal_concat($1, $2);
04168
04169
04170
04171 }
04172 ;
04173
04174 regexp_contents:
04175 {
04176
04177 $$ = 0;
04178
04179
04180
04181 }
04182 | regexp_contents string_content
04183 {
04184
04185 NODE *head = $1, *tail = $2;
04186 if (!head) {
04187 $$ = tail;
04188 }
04189 else if (!tail) {
04190 $$ = head;
04191 }
04192 else {
04193 switch (nd_type(head)) {
04194 case NODE_STR:
04195 nd_set_type(head, NODE_DSTR);
04196 break;
04197 case NODE_DSTR:
04198 break;
04199 default:
04200 head = list_append(NEW_DSTR(Qnil), head);
04201 break;
04202 }
04203 $$ = list_append(head, tail);
04204 }
04205
04206
04207
04208 }
04209 ;
04210
04211 string_content : tSTRING_CONTENT
04212 | tSTRING_DVAR
04213 {
04214 $<node>$ = lex_strterm;
04215 lex_strterm = 0;
04216 lex_state = EXPR_BEG;
04217 }
04218 string_dvar
04219 {
04220
04221 lex_strterm = $<node>2;
04222 $$ = NEW_EVSTR($3);
04223
04224
04225
04226
04227 }
04228 | tSTRING_DBEG
04229 {
04230 $<val>1 = cond_stack;
04231 $<val>$ = cmdarg_stack;
04232 cond_stack = 0;
04233 cmdarg_stack = 0;
04234 }
04235 {
04236 $<node>$ = lex_strterm;
04237 lex_strterm = 0;
04238 lex_state = EXPR_BEG;
04239 }
04240 {
04241 $<num>$ = brace_nest;
04242 brace_nest = 0;
04243 }
04244 compstmt tSTRING_DEND
04245 {
04246 cond_stack = $<val>1;
04247 cmdarg_stack = $<val>2;
04248 lex_strterm = $<node>3;
04249 brace_nest = $<num>4;
04250
04251 if ($5) $5->flags &= ~NODE_FL_NEWLINE;
04252 $$ = new_evstr($5);
04253
04254
04255
04256 }
04257 ;
04258
04259 string_dvar : tGVAR
04260 {
04261
04262 $$ = NEW_GVAR($1);
04263
04264
04265
04266 }
04267 | tIVAR
04268 {
04269
04270 $$ = NEW_IVAR($1);
04271
04272
04273
04274 }
04275 | tCVAR
04276 {
04277
04278 $$ = NEW_CVAR($1);
04279
04280
04281
04282 }
04283 | backref
04284 ;
04285
04286 symbol : tSYMBEG sym
04287 {
04288 lex_state = EXPR_END;
04289
04290 $$ = $2;
04291
04292
04293
04294 }
04295 ;
04296
04297 sym : fname
04298 | tIVAR
04299 | tGVAR
04300 | tCVAR
04301 ;
04302
04303 dsym : tSYMBEG xstring_contents tSTRING_END
04304 {
04305 lex_state = EXPR_END;
04306
04307 $$ = dsym_node($2);
04308
04309
04310
04311 }
04312 ;
04313
04314 numeric : tINTEGER
04315 | tFLOAT
04316 | tUMINUS_NUM tINTEGER %prec tLOWEST
04317 {
04318
04319 $$ = negate_lit($2);
04320
04321
04322
04323 }
04324 | tUMINUS_NUM tFLOAT %prec tLOWEST
04325 {
04326
04327 $$ = negate_lit($2);
04328
04329
04330
04331 }
04332 ;
04333
04334 user_variable : tIDENTIFIER
04335 | tIVAR
04336 | tGVAR
04337 | tCONSTANT
04338 | tCVAR
04339 ;
04340
04341 keyword_variable: keyword_nil {ifndef_ripper($$ = keyword_nil);}
04342 | keyword_self {ifndef_ripper($$ = keyword_self);}
04343 | keyword_true {ifndef_ripper($$ = keyword_true);}
04344 | keyword_false {ifndef_ripper($$ = keyword_false);}
04345 | keyword__FILE__ {ifndef_ripper($$ = keyword__FILE__);}
04346 | keyword__LINE__ {ifndef_ripper($$ = keyword__LINE__);}
04347 | keyword__ENCODING__ {ifndef_ripper($$ = keyword__ENCODING__);}
04348 ;
04349
04350 var_ref : user_variable
04351 {
04352
04353 if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
04354
04355
04356
04357
04358
04359
04360
04361
04362 }
04363 | keyword_variable
04364 {
04365
04366 if (!($$ = gettable($1))) $$ = NEW_BEGIN(0);
04367
04368
04369
04370 }
04371 ;
04372
04373 var_lhs : user_variable
04374 {
04375 $$ = assignable($1, 0);
04376
04377
04378
04379
04380 }
04381 | keyword_variable
04382 {
04383 $$ = assignable($1, 0);
04384
04385
04386
04387
04388 }
04389 ;
04390
04391 backref : tNTH_REF
04392 | tBACK_REF
04393 ;
04394
04395 superclass : term
04396 {
04397
04398 $$ = 0;
04399
04400
04401
04402 }
04403 | '<'
04404 {
04405 lex_state = EXPR_BEG;
04406 command_start = TRUE;
04407 }
04408 expr_value term
04409 {
04410 $$ = $3;
04411 }
04412 | error term
04413 {
04414
04415 yyerrok;
04416 $$ = 0;
04417
04418
04419
04420
04421 }
04422 ;
04423
04424 f_arglist : '(' f_args rparen
04425 {
04426
04427 $$ = $2;
04428
04429
04430
04431 lex_state = EXPR_BEG;
04432 command_start = TRUE;
04433 }
04434 | f_args term
04435 {
04436 $$ = $1;
04437 lex_state = EXPR_BEG;
04438 command_start = TRUE;
04439 }
04440 ;
04441
04442 args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
04443 {
04444 $$ = new_args_tail($1, $3, $4);
04445 }
04446 | f_kwarg opt_f_block_arg
04447 {
04448 $$ = new_args_tail($1, Qnone, $2);
04449 }
04450 | f_kwrest opt_f_block_arg
04451 {
04452 $$ = new_args_tail(Qnone, $1, $2);
04453 }
04454 | f_block_arg
04455 {
04456 $$ = new_args_tail(Qnone, Qnone, $1);
04457 }
04458 ;
04459
04460 opt_args_tail : ',' args_tail
04461 {
04462 $$ = $2;
04463 }
04464 |
04465 {
04466 $$ = new_args_tail(Qnone, Qnone, Qnone);
04467 }
04468 ;
04469
04470 f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
04471 {
04472 $$ = new_args($1, $3, $5, Qnone, $6);
04473 }
04474 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
04475 {
04476 $$ = new_args($1, $3, $5, $7, $8);
04477 }
04478 | f_arg ',' f_optarg opt_args_tail
04479 {
04480 $$ = new_args($1, $3, Qnone, Qnone, $4);
04481 }
04482 | f_arg ',' f_optarg ',' f_arg opt_args_tail
04483 {
04484 $$ = new_args($1, $3, Qnone, $5, $6);
04485 }
04486 | f_arg ',' f_rest_arg opt_args_tail
04487 {
04488 $$ = new_args($1, Qnone, $3, Qnone, $4);
04489 }
04490 | f_arg ',' f_rest_arg ',' f_arg opt_args_tail
04491 {
04492 $$ = new_args($1, Qnone, $3, $5, $6);
04493 }
04494 | f_arg opt_args_tail
04495 {
04496 $$ = new_args($1, Qnone, Qnone, Qnone, $2);
04497 }
04498 | f_optarg ',' f_rest_arg opt_args_tail
04499 {
04500 $$ = new_args(Qnone, $1, $3, Qnone, $4);
04501 }
04502 | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail
04503 {
04504 $$ = new_args(Qnone, $1, $3, $5, $6);
04505 }
04506 | f_optarg opt_args_tail
04507 {
04508 $$ = new_args(Qnone, $1, Qnone, Qnone, $2);
04509 }
04510 | f_optarg ',' f_arg opt_args_tail
04511 {
04512 $$ = new_args(Qnone, $1, Qnone, $3, $4);
04513 }
04514 | f_rest_arg opt_args_tail
04515 {
04516 $$ = new_args(Qnone, Qnone, $1, Qnone, $2);
04517 }
04518 | f_rest_arg ',' f_arg opt_args_tail
04519 {
04520 $$ = new_args(Qnone, Qnone, $1, $3, $4);
04521 }
04522 | args_tail
04523 {
04524 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $1);
04525 }
04526 |
04527 {
04528 $$ = new_args_tail(Qnone, Qnone, Qnone);
04529 $$ = new_args(Qnone, Qnone, Qnone, Qnone, $$);
04530 }
04531 ;
04532
04533 f_bad_arg : tCONSTANT
04534 {
04535
04536 yyerror("formal argument cannot be a constant");
04537 $$ = 0;
04538
04539
04540
04541 }
04542 | tIVAR
04543 {
04544
04545 yyerror("formal argument cannot be an instance variable");
04546 $$ = 0;
04547
04548
04549
04550 }
04551 | tGVAR
04552 {
04553
04554 yyerror("formal argument cannot be a global variable");
04555 $$ = 0;
04556
04557
04558
04559 }
04560 | tCVAR
04561 {
04562
04563 yyerror("formal argument cannot be a class variable");
04564 $$ = 0;
04565
04566
04567
04568 }
04569 ;
04570
04571 f_norm_arg : f_bad_arg
04572 | tIDENTIFIER
04573 {
04574 formal_argument(get_id($1));
04575 $$ = $1;
04576 }
04577 ;
04578
04579 f_arg_item : f_norm_arg
04580 {
04581 arg_var(get_id($1));
04582
04583 $$ = NEW_ARGS_AUX($1, 1);
04584
04585
04586
04587 }
04588 | tLPAREN f_margs rparen
04589 {
04590 ID tid = internal_id();
04591 arg_var(tid);
04592
04593 if (dyna_in_block()) {
04594 $2->nd_value = NEW_DVAR(tid);
04595 }
04596 else {
04597 $2->nd_value = NEW_LVAR(tid);
04598 }
04599 $$ = NEW_ARGS_AUX(tid, 1);
04600 $$->nd_next = $2;
04601
04602
04603
04604 }
04605 ;
04606
04607 f_arg : f_arg_item
04608
04609
04610
04611
04612
04613
04614 | f_arg ',' f_arg_item
04615 {
04616
04617 $$ = $1;
04618 $$->nd_plen++;
04619 $$->nd_next = block_append($$->nd_next, $3->nd_next);
04620 rb_gc_force_recycle((VALUE)$3);
04621
04622
04623
04624 }
04625 ;
04626
04627 f_kw : tLABEL arg_value
04628 {
04629 arg_var(formal_argument(get_id($1)));
04630 $$ = assignable($1, $2);
04631
04632 $$ = NEW_KW_ARG(0, $$);
04633
04634
04635
04636 }
04637 ;
04638
04639 f_block_kw : tLABEL primary_value
04640 {
04641 arg_var(formal_argument(get_id($1)));
04642 $$ = assignable($1, $2);
04643
04644 $$ = NEW_KW_ARG(0, $$);
04645
04646
04647
04648 }
04649 ;
04650
04651 f_block_kwarg : f_block_kw
04652 {
04653
04654 $$ = $1;
04655
04656
04657
04658 }
04659 | f_block_kwarg ',' f_block_kw
04660 {
04661
04662 NODE *kws = $1;
04663
04664 while (kws->nd_next) {
04665 kws = kws->nd_next;
04666 }
04667 kws->nd_next = $3;
04668 $$ = $1;
04669
04670
04671
04672 }
04673 ;
04674
04675
04676 f_kwarg : f_kw
04677 {
04678
04679 $$ = $1;
04680
04681
04682
04683 }
04684 | f_kwarg ',' f_kw
04685 {
04686
04687 NODE *kws = $1;
04688
04689 while (kws->nd_next) {
04690 kws = kws->nd_next;
04691 }
04692 kws->nd_next = $3;
04693 $$ = $1;
04694
04695
04696
04697 }
04698 ;
04699
04700 kwrest_mark : tPOW
04701 | tDSTAR
04702 ;
04703
04704 f_kwrest : kwrest_mark tIDENTIFIER
04705 {
04706 shadowing_lvar(get_id($2));
04707 $$ = $2;
04708 }
04709 | kwrest_mark
04710 {
04711 $$ = internal_id();
04712 }
04713 ;
04714
04715 f_opt : tIDENTIFIER '=' arg_value
04716 {
04717 arg_var(formal_argument(get_id($1)));
04718 $$ = assignable($1, $3);
04719
04720 $$ = NEW_OPT_ARG(0, $$);
04721
04722
04723
04724 }
04725 ;
04726
04727 f_block_opt : tIDENTIFIER '=' primary_value
04728 {
04729 arg_var(formal_argument(get_id($1)));
04730 $$ = assignable($1, $3);
04731
04732 $$ = NEW_OPT_ARG(0, $$);
04733
04734
04735
04736 }
04737 ;
04738
04739 f_block_optarg : f_block_opt
04740 {
04741
04742 $$ = $1;
04743
04744
04745
04746 }
04747 | f_block_optarg ',' f_block_opt
04748 {
04749
04750 NODE *opts = $1;
04751
04752 while (opts->nd_next) {
04753 opts = opts->nd_next;
04754 }
04755 opts->nd_next = $3;
04756 $$ = $1;
04757
04758
04759
04760 }
04761 ;
04762
04763 f_optarg : f_opt
04764 {
04765
04766 $$ = $1;
04767
04768
04769
04770 }
04771 | f_optarg ',' f_opt
04772 {
04773
04774 NODE *opts = $1;
04775
04776 while (opts->nd_next) {
04777 opts = opts->nd_next;
04778 }
04779 opts->nd_next = $3;
04780 $$ = $1;
04781
04782
04783
04784 }
04785 ;
04786
04787 restarg_mark : '*'
04788 | tSTAR
04789 ;
04790
04791 f_rest_arg : restarg_mark tIDENTIFIER
04792 {
04793
04794 if (!is_local_id($2))
04795 yyerror("rest argument must be local variable");
04796
04797 arg_var(shadowing_lvar(get_id($2)));
04798
04799 $$ = $2;
04800
04801
04802
04803 }
04804 | restarg_mark
04805 {
04806
04807 $$ = internal_id();
04808 arg_var($$);
04809
04810
04811
04812 }
04813 ;
04814
04815 blkarg_mark : '&'
04816 | tAMPER
04817 ;
04818
04819 f_block_arg : blkarg_mark tIDENTIFIER
04820 {
04821
04822 if (!is_local_id($2))
04823 yyerror("block argument must be local variable");
04824 else if (!dyna_in_block() && local_id($2))
04825 yyerror("duplicated block argument name");
04826
04827 arg_var(shadowing_lvar(get_id($2)));
04828
04829 $$ = $2;
04830
04831
04832
04833 }
04834 ;
04835
04836 opt_f_block_arg : ',' f_block_arg
04837 {
04838 $$ = $2;
04839 }
04840 | none
04841 {
04842
04843 $$ = 0;
04844
04845
04846
04847 }
04848 ;
04849
04850 singleton : var_ref
04851 {
04852
04853 value_expr($1);
04854 $$ = $1;
04855 if (!$$) $$ = NEW_NIL();
04856
04857
04858
04859 }
04860 | '(' {lex_state = EXPR_BEG;} expr rparen
04861 {
04862
04863 if ($3 == 0) {
04864 yyerror("can't define singleton method for ().");
04865 }
04866 else {
04867 switch (nd_type($3)) {
04868 case NODE_STR:
04869 case NODE_DSTR:
04870 case NODE_XSTR:
04871 case NODE_DXSTR:
04872 case NODE_DREGX:
04873 case NODE_LIT:
04874 case NODE_ARRAY:
04875 case NODE_ZARRAY:
04876 yyerror("can't define singleton method for literals");
04877 default:
04878 value_expr($3);
04879 break;
04880 }
04881 }
04882 $$ = $3;
04883
04884
04885
04886 }
04887 ;
04888
04889 assoc_list : none
04890 | assocs trailer
04891 {
04892
04893 $$ = $1;
04894
04895
04896
04897 }
04898 ;
04899
04900 assocs : assoc
04901
04902
04903
04904
04905
04906
04907 | assocs ',' assoc
04908 {
04909
04910 $$ = list_concat($1, $3);
04911
04912
04913
04914 }
04915 ;
04916
04917 assoc : arg_value tASSOC arg_value
04918 {
04919
04920 $$ = list_append(NEW_LIST($1), $3);
04921
04922
04923
04924 }
04925 | tLABEL arg_value
04926 {
04927
04928 $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
04929
04930
04931
04932 }
04933 | tDSTAR arg_value
04934 {
04935
04936 $$ = list_append(NEW_LIST(0), $2);
04937
04938
04939
04940 }
04941 ;
04942
04943 ;
04944
04945 operation : tIDENTIFIER
04946 | tCONSTANT
04947 | tFID
04948 ;
04949
04950 operation2 : tIDENTIFIER
04951 | tCONSTANT
04952 | tFID
04953 | op
04954 ;
04955
04956 operation3 : tIDENTIFIER
04957 | tFID
04958 | op
04959 ;
04960
04961 dot_or_colon : '.'
04962
04963
04964
04965
04966 | tCOLON2
04967
04968
04969
04970
04971 ;
04972
04973 opt_terms :
04974 | terms
04975 ;
04976
04977 opt_nl :
04978 | '\n'
04979 ;
04980
04981 rparen : opt_nl ')'
04982 ;
04983
04984 rbracket : opt_nl ']'
04985 ;
04986
04987 trailer :
04988 | '\n'
04989 | ','
04990 ;
04991
04992 term : ';' {yyerrok;}
04993 | '\n'
04994 ;
04995
04996 terms : term
04997 | terms ';' {yyerrok;}
04998 ;
04999
05000 none :
05001 {
05002
05003 $$ = 0;
05004
05005
05006
05007 }
05008 ;
05009 %%
05010 # undef parser
05011 # undef yylex
05012 # undef yylval
05013 # define yylval (*((YYSTYPE*)(parser->parser_yylval)))
05014
05015 static int parser_regx_options(struct parser_params*);
05016 static int parser_tokadd_string(struct parser_params*,int,int,int,long*,rb_encoding**);
05017 static void parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc);
05018 static int parser_parse_string(struct parser_params*,NODE*);
05019 static int parser_here_document(struct parser_params*,NODE*);
05020
05021
05022 # define nextc() parser_nextc(parser)
05023 # define pushback(c) parser_pushback(parser, (c))
05024 # define newtok() parser_newtok(parser)
05025 # define tokspace(n) parser_tokspace(parser, (n))
05026 # define tokadd(c) parser_tokadd(parser, (c))
05027 # define tok_hex(numlen) parser_tok_hex(parser, (numlen))
05028 # define read_escape(flags,e) parser_read_escape(parser, (flags), (e))
05029 # define tokadd_escape(e) parser_tokadd_escape(parser, (e))
05030 # define regx_options() parser_regx_options(parser)
05031 # define tokadd_string(f,t,p,n,e) parser_tokadd_string(parser,(f),(t),(p),(n),(e))
05032 # define parse_string(n) parser_parse_string(parser,(n))
05033 # define tokaddmbc(c, enc) parser_tokaddmbc(parser, (c), (enc))
05034 # define here_document(n) parser_here_document(parser,(n))
05035 # define heredoc_identifier() parser_heredoc_identifier(parser)
05036 # define heredoc_restore(n) parser_heredoc_restore(parser,(n))
05037 # define whole_match_p(e,l,i) parser_whole_match_p(parser,(e),(l),(i))
05038
05039 #ifndef RIPPER
05040 # define set_yylval_str(x) (yylval.node = NEW_STR(x))
05041 # define set_yylval_num(x) (yylval.num = (x))
05042 # define set_yylval_id(x) (yylval.id = (x))
05043 # define set_yylval_name(x) (yylval.id = (x))
05044 # define set_yylval_literal(x) (yylval.node = NEW_LIT(x))
05045 # define set_yylval_node(x) (yylval.node = (x))
05046 # define yylval_id() (yylval.id)
05047 #else
05048 static inline VALUE
05049 ripper_yylval_id(ID x)
05050 {
05051 return (VALUE)NEW_LASGN(x, ID2SYM(x));
05052 }
05053 # define set_yylval_str(x) (void)(x)
05054 # define set_yylval_num(x) (void)(x)
05055 # define set_yylval_id(x) (void)(x)
05056 # define set_yylval_name(x) (void)(yylval.val = ripper_yylval_id(x))
05057 # define set_yylval_literal(x) (void)(x)
05058 # define set_yylval_node(x) (void)(x)
05059 # define yylval_id() yylval.id
05060 #endif
05061
05062 #ifndef RIPPER
05063 #define ripper_flush(p) (void)(p)
05064 #else
05065 #define ripper_flush(p) ((p)->tokp = (p)->parser_lex_p)
05066
05067 #define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val))
05068
05069 static int
05070 ripper_has_scan_event(struct parser_params *parser)
05071 {
05072
05073 if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp");
05074 return lex_p > parser->tokp;
05075 }
05076
05077 static VALUE
05078 ripper_scan_event_val(struct parser_params *parser, int t)
05079 {
05080 VALUE str = STR_NEW(parser->tokp, lex_p - parser->tokp);
05081 VALUE rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
05082 ripper_flush(parser);
05083 return rval;
05084 }
05085
05086 static void
05087 ripper_dispatch_scan_event(struct parser_params *parser, int t)
05088 {
05089 if (!ripper_has_scan_event(parser)) return;
05090 yylval_rval = ripper_scan_event_val(parser, t);
05091 }
05092
05093 static void
05094 ripper_dispatch_ignored_scan_event(struct parser_params *parser, int t)
05095 {
05096 if (!ripper_has_scan_event(parser)) return;
05097 (void)ripper_scan_event_val(parser, t);
05098 }
05099
05100 static void
05101 ripper_dispatch_delayed_token(struct parser_params *parser, int t)
05102 {
05103 int saved_line = ruby_sourceline;
05104 const char *saved_tokp = parser->tokp;
05105
05106 ruby_sourceline = parser->delayed_line;
05107 parser->tokp = lex_pbeg + parser->delayed_col;
05108 yylval_rval = ripper_dispatch1(parser, ripper_token2eventid(t), parser->delayed);
05109 parser->delayed = Qnil;
05110 ruby_sourceline = saved_line;
05111 parser->tokp = saved_tokp;
05112 }
05113 #endif
05114
05115 #include "ruby/regex.h"
05116 #include "ruby/util.h"
05117
05118
05119
05120
05121
05122 #undef SIGN_EXTEND_CHAR
05123 #if __STDC__
05124 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
05125 #else
05126
05127 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
05128 #endif
05129
05130 #define parser_encoding_name() (current_enc->name)
05131 #define parser_mbclen() mbclen((lex_p-1),lex_pend,current_enc)
05132 #define parser_precise_mbclen() rb_enc_precise_mbclen((lex_p-1),lex_pend,current_enc)
05133 #define is_identchar(p,e,enc) (rb_enc_isalnum(*(p),(enc)) || (*(p)) == '_' || !ISASCII(*(p)))
05134 #define parser_is_identchar() (!parser->eofp && is_identchar((lex_p-1),lex_pend,current_enc))
05135
05136 #define parser_isascii() ISASCII(*(lex_p-1))
05137
05138 #ifndef RIPPER
05139 static int
05140 token_info_get_column(struct parser_params *parser, const char *token)
05141 {
05142 int column = 1;
05143 const char *p, *pend = lex_p - strlen(token);
05144 for (p = lex_pbeg; p < pend; p++) {
05145 if (*p == '\t') {
05146 column = (((column - 1) / 8) + 1) * 8;
05147 }
05148 column++;
05149 }
05150 return column;
05151 }
05152
05153 static int
05154 token_info_has_nonspaces(struct parser_params *parser, const char *token)
05155 {
05156 const char *p, *pend = lex_p - strlen(token);
05157 for (p = lex_pbeg; p < pend; p++) {
05158 if (*p != ' ' && *p != '\t') {
05159 return 1;
05160 }
05161 }
05162 return 0;
05163 }
05164
05165 #undef token_info_push
05166 static void
05167 token_info_push(struct parser_params *parser, const char *token)
05168 {
05169 token_info *ptinfo;
05170
05171 if (!parser->parser_token_info_enabled) return;
05172 ptinfo = ALLOC(token_info);
05173 ptinfo->token = token;
05174 ptinfo->linenum = ruby_sourceline;
05175 ptinfo->column = token_info_get_column(parser, token);
05176 ptinfo->nonspc = token_info_has_nonspaces(parser, token);
05177 ptinfo->next = parser->parser_token_info;
05178
05179 parser->parser_token_info = ptinfo;
05180 }
05181
05182 #undef token_info_pop
05183 static void
05184 token_info_pop(struct parser_params *parser, const char *token)
05185 {
05186 int linenum;
05187 token_info *ptinfo = parser->parser_token_info;
05188
05189 if (!ptinfo) return;
05190 parser->parser_token_info = ptinfo->next;
05191 if (token_info_get_column(parser, token) == ptinfo->column) {
05192 goto finish;
05193 }
05194 linenum = ruby_sourceline;
05195 if (linenum == ptinfo->linenum) {
05196 goto finish;
05197 }
05198 if (token_info_has_nonspaces(parser, token) || ptinfo->nonspc) {
05199 goto finish;
05200 }
05201 if (parser->parser_token_info_enabled) {
05202 rb_compile_warn(ruby_sourcefile, linenum,
05203 "mismatched indentations at '%s' with '%s' at %d",
05204 token, ptinfo->token, ptinfo->linenum);
05205 }
05206
05207 finish:
05208 xfree(ptinfo);
05209 }
05210 #endif
05211
05212 static int
05213 parser_yyerror(struct parser_params *parser, const char *msg)
05214 {
05215 #ifndef RIPPER
05216 const int max_line_margin = 30;
05217 const char *p, *pe;
05218 char *buf;
05219 long len;
05220 int i;
05221
05222 compile_error(PARSER_ARG "%s", msg);
05223 p = lex_p;
05224 while (lex_pbeg <= p) {
05225 if (*p == '\n') break;
05226 p--;
05227 }
05228 p++;
05229
05230 pe = lex_p;
05231 while (pe < lex_pend) {
05232 if (*pe == '\n') break;
05233 pe++;
05234 }
05235
05236 len = pe - p;
05237 if (len > 4) {
05238 char *p2;
05239 const char *pre = "", *post = "";
05240
05241 if (len > max_line_margin * 2 + 10) {
05242 if (lex_p - p > max_line_margin) {
05243 p = rb_enc_prev_char(p, lex_p - max_line_margin, pe, rb_enc_get(lex_lastline));
05244 pre = "...";
05245 }
05246 if (pe - lex_p > max_line_margin) {
05247 pe = rb_enc_prev_char(lex_p, lex_p + max_line_margin, pe, rb_enc_get(lex_lastline));
05248 post = "...";
05249 }
05250 len = pe - p;
05251 }
05252 buf = ALLOCA_N(char, len+2);
05253 MEMCPY(buf, p, char, len);
05254 buf[len] = '\0';
05255 rb_compile_error_with_enc(NULL, 0, (void *)current_enc, "%s%s%s", pre, buf, post);
05256
05257 i = (int)(lex_p - p);
05258 p2 = buf; pe = buf + len;
05259
05260 while (p2 < pe) {
05261 if (*p2 != '\t') *p2 = ' ';
05262 p2++;
05263 }
05264 buf[i] = '^';
05265 buf[i+1] = '\0';
05266 rb_compile_error_append("%s%s", pre, buf);
05267 }
05268 #else
05269 dispatch1(parse_error, STR_NEW2(msg));
05270 #endif
05271 return 0;
05272 }
05273
05274 static void parser_prepare(struct parser_params *parser);
05275
05276 #ifndef RIPPER
05277 static VALUE
05278 debug_lines(VALUE fname)
05279 {
05280 ID script_lines;
05281 CONST_ID(script_lines, "SCRIPT_LINES__");
05282 if (rb_const_defined_at(rb_cObject, script_lines)) {
05283 VALUE hash = rb_const_get_at(rb_cObject, script_lines);
05284 if (RB_TYPE_P(hash, T_HASH)) {
05285 VALUE lines = rb_ary_new();
05286 rb_hash_aset(hash, fname, lines);
05287 return lines;
05288 }
05289 }
05290 return 0;
05291 }
05292
05293 static VALUE
05294 coverage(VALUE fname, int n)
05295 {
05296 VALUE coverages = rb_get_coverages();
05297 if (RTEST(coverages) && RBASIC(coverages)->klass == 0) {
05298 VALUE lines = rb_ary_new2(n);
05299 int i;
05300 RBASIC(lines)->klass = 0;
05301 for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
05302 RARRAY(lines)->as.heap.len = n;
05303 rb_hash_aset(coverages, fname, lines);
05304 return lines;
05305 }
05306 return 0;
05307 }
05308
05309 static int
05310 e_option_supplied(struct parser_params *parser)
05311 {
05312 return strcmp(ruby_sourcefile, "-e") == 0;
05313 }
05314
05315 static VALUE
05316 yycompile0(VALUE arg)
05317 {
05318 int n;
05319 NODE *tree;
05320 struct parser_params *parser = (struct parser_params *)arg;
05321
05322 if (!compile_for_eval && rb_safe_level() == 0) {
05323 ruby_debug_lines = debug_lines(ruby_sourcefile_string);
05324 if (ruby_debug_lines && ruby_sourceline > 0) {
05325 VALUE str = STR_NEW0();
05326 n = ruby_sourceline;
05327 do {
05328 rb_ary_push(ruby_debug_lines, str);
05329 } while (--n);
05330 }
05331
05332 if (!e_option_supplied(parser)) {
05333 ruby_coverage = coverage(ruby_sourcefile_string, ruby_sourceline);
05334 }
05335 }
05336
05337 parser_prepare(parser);
05338 deferred_nodes = 0;
05339 #ifndef RIPPER
05340 parser->parser_token_info_enabled = !compile_for_eval && RTEST(ruby_verbose);
05341 #endif
05342 #ifndef RIPPER
05343 if (RUBY_DTRACE_PARSE_BEGIN_ENABLED()) {
05344 RUBY_DTRACE_PARSE_BEGIN(parser->parser_ruby_sourcefile,
05345 parser->parser_ruby_sourceline);
05346 }
05347 #endif
05348 n = yyparse((void*)parser);
05349 #ifndef RIPPER
05350 if (RUBY_DTRACE_PARSE_END_ENABLED()) {
05351 RUBY_DTRACE_PARSE_END(parser->parser_ruby_sourcefile,
05352 parser->parser_ruby_sourceline);
05353 }
05354 #endif
05355 ruby_debug_lines = 0;
05356 ruby_coverage = 0;
05357 compile_for_eval = 0;
05358
05359 lex_strterm = 0;
05360 lex_p = lex_pbeg = lex_pend = 0;
05361 lex_lastline = lex_nextline = 0;
05362 if (parser->nerr) {
05363 return 0;
05364 }
05365 tree = ruby_eval_tree;
05366 if (!tree) {
05367 tree = NEW_NIL();
05368 }
05369 else if (ruby_eval_tree_begin) {
05370 tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body);
05371 }
05372 return (VALUE)tree;
05373 }
05374
05375 static NODE*
05376 yycompile(struct parser_params *parser, VALUE fname, int line)
05377 {
05378 ruby_sourcefile_string = rb_str_new_frozen(fname);
05379 ruby_sourcefile = RSTRING_PTR(fname);
05380 ruby_sourceline = line - 1;
05381 return (NODE *)rb_suppress_tracing(yycompile0, (VALUE)parser);
05382 }
05383 #endif
05384
05385 static rb_encoding *
05386 must_be_ascii_compatible(VALUE s)
05387 {
05388 rb_encoding *enc = rb_enc_get(s);
05389 if (!rb_enc_asciicompat(enc)) {
05390 rb_raise(rb_eArgError, "invalid source encoding");
05391 }
05392 return enc;
05393 }
05394
05395 static VALUE
05396 lex_get_str(struct parser_params *parser, VALUE s)
05397 {
05398 char *beg, *end, *pend;
05399 rb_encoding *enc = must_be_ascii_compatible(s);
05400
05401 beg = RSTRING_PTR(s);
05402 if (lex_gets_ptr) {
05403 if (RSTRING_LEN(s) == lex_gets_ptr) return Qnil;
05404 beg += lex_gets_ptr;
05405 }
05406 pend = RSTRING_PTR(s) + RSTRING_LEN(s);
05407 end = beg;
05408 while (end < pend) {
05409 if (*end++ == '\n') break;
05410 }
05411 lex_gets_ptr = end - RSTRING_PTR(s);
05412 return rb_enc_str_new(beg, end - beg, enc);
05413 }
05414
05415 static VALUE
05416 lex_getline(struct parser_params *parser)
05417 {
05418 VALUE line = (*parser->parser_lex_gets)(parser, parser->parser_lex_input);
05419 if (NIL_P(line)) return line;
05420 must_be_ascii_compatible(line);
05421 #ifndef RIPPER
05422 if (ruby_debug_lines) {
05423 rb_enc_associate(line, current_enc);
05424 rb_ary_push(ruby_debug_lines, line);
05425 }
05426 if (ruby_coverage) {
05427 rb_ary_push(ruby_coverage, Qnil);
05428 }
05429 #endif
05430 return line;
05431 }
05432
05433 #ifdef RIPPER
05434 static rb_data_type_t parser_data_type;
05435 #else
05436 static const rb_data_type_t parser_data_type;
05437
05438 static NODE*
05439 parser_compile_string(volatile VALUE vparser, VALUE fname, VALUE s, int line)
05440 {
05441 struct parser_params *parser;
05442 NODE *node;
05443
05444 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
05445 lex_gets = lex_get_str;
05446 lex_gets_ptr = 0;
05447 lex_input = s;
05448 lex_pbeg = lex_p = lex_pend = 0;
05449 compile_for_eval = rb_parse_in_eval();
05450
05451 node = yycompile(parser, fname, line);
05452 RB_GC_GUARD(vparser);
05453
05454 return node;
05455 }
05456
05457 NODE*
05458 rb_compile_string(const char *f, VALUE s, int line)
05459 {
05460 must_be_ascii_compatible(s);
05461 return parser_compile_string(rb_parser_new(), rb_filesystem_str_new_cstr(f), s, line);
05462 }
05463
05464 NODE*
05465 rb_parser_compile_string(volatile VALUE vparser, const char *f, VALUE s, int line)
05466 {
05467 return rb_parser_compile_string_path(vparser, rb_filesystem_str_new_cstr(f), s, line);
05468 }
05469
05470 NODE*
05471 rb_parser_compile_string_path(volatile VALUE vparser, VALUE f, VALUE s, int line)
05472 {
05473 must_be_ascii_compatible(s);
05474 return parser_compile_string(vparser, f, s, line);
05475 }
05476
05477 NODE*
05478 rb_compile_cstr(const char *f, const char *s, int len, int line)
05479 {
05480 VALUE str = rb_str_new(s, len);
05481 return parser_compile_string(rb_parser_new(), rb_filesystem_str_new_cstr(f), str, line);
05482 }
05483
05484 NODE*
05485 rb_parser_compile_cstr(volatile VALUE vparser, const char *f, const char *s, int len, int line)
05486 {
05487 VALUE str = rb_str_new(s, len);
05488 return parser_compile_string(vparser, rb_filesystem_str_new_cstr(f), str, line);
05489 }
05490
05491 static VALUE
05492 lex_io_gets(struct parser_params *parser, VALUE io)
05493 {
05494 return rb_io_gets(io);
05495 }
05496
05497 NODE*
05498 rb_compile_file(const char *f, VALUE file, int start)
05499 {
05500 VALUE volatile vparser = rb_parser_new();
05501
05502 return rb_parser_compile_file(vparser, f, file, start);
05503 }
05504
05505 NODE*
05506 rb_parser_compile_file(volatile VALUE vparser, const char *f, VALUE file, int start)
05507 {
05508 return rb_parser_compile_file_path(vparser, rb_filesystem_str_new_cstr(f), file, start);
05509 }
05510
05511 NODE*
05512 rb_parser_compile_file_path(volatile VALUE vparser, VALUE fname, VALUE file, int start)
05513 {
05514 struct parser_params *parser;
05515 NODE *node;
05516
05517 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
05518 lex_gets = lex_io_gets;
05519 lex_input = file;
05520 lex_pbeg = lex_p = lex_pend = 0;
05521 compile_for_eval = rb_parse_in_eval();
05522
05523 node = yycompile(parser, fname, start);
05524 RB_GC_GUARD(vparser);
05525
05526 return node;
05527 }
05528 #endif
05529
05530 #define STR_FUNC_ESCAPE 0x01
05531 #define STR_FUNC_EXPAND 0x02
05532 #define STR_FUNC_REGEXP 0x04
05533 #define STR_FUNC_QWORDS 0x08
05534 #define STR_FUNC_SYMBOL 0x10
05535 #define STR_FUNC_INDENT 0x20
05536
05537 enum string_type {
05538 str_squote = (0),
05539 str_dquote = (STR_FUNC_EXPAND),
05540 str_xquote = (STR_FUNC_EXPAND),
05541 str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
05542 str_sword = (STR_FUNC_QWORDS),
05543 str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
05544 str_ssym = (STR_FUNC_SYMBOL),
05545 str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND)
05546 };
05547
05548 static VALUE
05549 parser_str_new(const char *p, long n, rb_encoding *enc, int func, rb_encoding *enc0)
05550 {
05551 VALUE str;
05552
05553 str = rb_enc_str_new(p, n, enc);
05554 if (!(func & STR_FUNC_REGEXP) && rb_enc_asciicompat(enc)) {
05555 if (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) {
05556 }
05557 else if (enc0 == rb_usascii_encoding() && enc != rb_utf8_encoding()) {
05558 rb_enc_associate(str, rb_ascii8bit_encoding());
05559 }
05560 }
05561
05562 return str;
05563 }
05564
05565 #define lex_goto_eol(parser) ((parser)->parser_lex_p = (parser)->parser_lex_pend)
05566 #define lex_eol_p() (lex_p >= lex_pend)
05567 #define peek(c) peek_n((c), 0)
05568 #define peek_n(c,n) (lex_p+(n) < lex_pend && (c) == (unsigned char)lex_p[n])
05569
05570 static inline int
05571 parser_nextc(struct parser_params *parser)
05572 {
05573 int c;
05574
05575 if (lex_p == lex_pend) {
05576 VALUE v = lex_nextline;
05577 lex_nextline = 0;
05578 if (!v) {
05579 if (parser->eofp)
05580 return -1;
05581
05582 if (!lex_input || NIL_P(v = lex_getline(parser))) {
05583 parser->eofp = Qtrue;
05584 lex_goto_eol(parser);
05585 return -1;
05586 }
05587 }
05588 {
05589 #ifdef RIPPER
05590 if (parser->tokp < lex_pend) {
05591 if (NIL_P(parser->delayed)) {
05592 parser->delayed = rb_str_buf_new(1024);
05593 rb_enc_associate(parser->delayed, current_enc);
05594 rb_str_buf_cat(parser->delayed,
05595 parser->tokp, lex_pend - parser->tokp);
05596 parser->delayed_line = ruby_sourceline;
05597 parser->delayed_col = (int)(parser->tokp - lex_pbeg);
05598 }
05599 else {
05600 rb_str_buf_cat(parser->delayed,
05601 parser->tokp, lex_pend - parser->tokp);
05602 }
05603 }
05604 #endif
05605 if (heredoc_end > 0) {
05606 ruby_sourceline = heredoc_end;
05607 heredoc_end = 0;
05608 }
05609 ruby_sourceline++;
05610 parser->line_count++;
05611 lex_pbeg = lex_p = RSTRING_PTR(v);
05612 lex_pend = lex_p + RSTRING_LEN(v);
05613 ripper_flush(parser);
05614 lex_lastline = v;
05615 }
05616 }
05617 c = (unsigned char)*lex_p++;
05618 if (c == '\r' && peek('\n')) {
05619 lex_p++;
05620 c = '\n';
05621 }
05622
05623 return c;
05624 }
05625
05626 static void
05627 parser_pushback(struct parser_params *parser, int c)
05628 {
05629 if (c == -1) return;
05630 lex_p--;
05631 if (lex_p > lex_pbeg && lex_p[0] == '\n' && lex_p[-1] == '\r') {
05632 lex_p--;
05633 }
05634 }
05635
05636 #define was_bol() (lex_p == lex_pbeg + 1)
05637
05638 #define tokfix() (tokenbuf[tokidx]='\0')
05639 #define tok() tokenbuf
05640 #define toklen() tokidx
05641 #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
05642
05643 static char*
05644 parser_newtok(struct parser_params *parser)
05645 {
05646 tokidx = 0;
05647 tokline = ruby_sourceline;
05648 if (!tokenbuf) {
05649 toksiz = 60;
05650 tokenbuf = ALLOC_N(char, 60);
05651 }
05652 if (toksiz > 4096) {
05653 toksiz = 60;
05654 REALLOC_N(tokenbuf, char, 60);
05655 }
05656 return tokenbuf;
05657 }
05658
05659 static char *
05660 parser_tokspace(struct parser_params *parser, int n)
05661 {
05662 tokidx += n;
05663
05664 if (tokidx >= toksiz) {
05665 do {toksiz *= 2;} while (toksiz < tokidx);
05666 REALLOC_N(tokenbuf, char, toksiz);
05667 }
05668 return &tokenbuf[tokidx-n];
05669 }
05670
05671 static void
05672 parser_tokadd(struct parser_params *parser, int c)
05673 {
05674 tokenbuf[tokidx++] = (char)c;
05675 if (tokidx >= toksiz) {
05676 toksiz *= 2;
05677 REALLOC_N(tokenbuf, char, toksiz);
05678 }
05679 }
05680
05681 static int
05682 parser_tok_hex(struct parser_params *parser, size_t *numlen)
05683 {
05684 int c;
05685
05686 c = scan_hex(lex_p, 2, numlen);
05687 if (!*numlen) {
05688 yyerror("invalid hex escape");
05689 return 0;
05690 }
05691 lex_p += *numlen;
05692 return c;
05693 }
05694
05695 #define tokcopy(n) memcpy(tokspace(n), lex_p - (n), (n))
05696
05697
05698 static int
05699 parser_tokadd_utf8(struct parser_params *parser, rb_encoding **encp,
05700 int string_literal, int symbol_literal, int regexp_literal)
05701 {
05702
05703
05704
05705
05706
05707
05708
05709 int codepoint;
05710 size_t numlen;
05711
05712 if (regexp_literal) { tokadd('\\'); tokadd('u'); }
05713
05714 if (peek('{')) {
05715 do {
05716 if (regexp_literal) { tokadd(*lex_p); }
05717 nextc();
05718 codepoint = scan_hex(lex_p, 6, &numlen);
05719 if (numlen == 0) {
05720 yyerror("invalid Unicode escape");
05721 return 0;
05722 }
05723 if (codepoint > 0x10ffff) {
05724 yyerror("invalid Unicode codepoint (too large)");
05725 return 0;
05726 }
05727 lex_p += numlen;
05728 if (regexp_literal) {
05729 tokcopy((int)numlen);
05730 }
05731 else if (codepoint >= 0x80) {
05732 *encp = rb_utf8_encoding();
05733 if (string_literal) tokaddmbc(codepoint, *encp);
05734 }
05735 else if (string_literal) {
05736 tokadd(codepoint);
05737 }
05738 } while (string_literal && (peek(' ') || peek('\t')));
05739
05740 if (!peek('}')) {
05741 yyerror("unterminated Unicode escape");
05742 return 0;
05743 }
05744
05745 if (regexp_literal) { tokadd('}'); }
05746 nextc();
05747 }
05748 else {
05749 codepoint = scan_hex(lex_p, 4, &numlen);
05750 if (numlen < 4) {
05751 yyerror("invalid Unicode escape");
05752 return 0;
05753 }
05754 lex_p += 4;
05755 if (regexp_literal) {
05756 tokcopy(4);
05757 }
05758 else if (codepoint >= 0x80) {
05759 *encp = rb_utf8_encoding();
05760 if (string_literal) tokaddmbc(codepoint, *encp);
05761 }
05762 else if (string_literal) {
05763 tokadd(codepoint);
05764 }
05765 }
05766
05767 return codepoint;
05768 }
05769
05770 #define ESCAPE_CONTROL 1
05771 #define ESCAPE_META 2
05772
05773 static int
05774 parser_read_escape(struct parser_params *parser, int flags,
05775 rb_encoding **encp)
05776 {
05777 int c;
05778 size_t numlen;
05779
05780 switch (c = nextc()) {
05781 case '\\':
05782 return c;
05783
05784 case 'n':
05785 return '\n';
05786
05787 case 't':
05788 return '\t';
05789
05790 case 'r':
05791 return '\r';
05792
05793 case 'f':
05794 return '\f';
05795
05796 case 'v':
05797 return '\13';
05798
05799 case 'a':
05800 return '\007';
05801
05802 case 'e':
05803 return 033;
05804
05805 case '0': case '1': case '2': case '3':
05806 case '4': case '5': case '6': case '7':
05807 pushback(c);
05808 c = scan_oct(lex_p, 3, &numlen);
05809 lex_p += numlen;
05810 return c;
05811
05812 case 'x':
05813 c = tok_hex(&numlen);
05814 if (numlen == 0) return 0;
05815 return c;
05816
05817 case 'b':
05818 return '\010';
05819
05820 case 's':
05821 return ' ';
05822
05823 case 'M':
05824 if (flags & ESCAPE_META) goto eof;
05825 if ((c = nextc()) != '-') {
05826 pushback(c);
05827 goto eof;
05828 }
05829 if ((c = nextc()) == '\\') {
05830 if (peek('u')) goto eof;
05831 return read_escape(flags|ESCAPE_META, encp) | 0x80;
05832 }
05833 else if (c == -1 || !ISASCII(c)) goto eof;
05834 else {
05835 return ((c & 0xff) | 0x80);
05836 }
05837
05838 case 'C':
05839 if ((c = nextc()) != '-') {
05840 pushback(c);
05841 goto eof;
05842 }
05843 case 'c':
05844 if (flags & ESCAPE_CONTROL) goto eof;
05845 if ((c = nextc())== '\\') {
05846 if (peek('u')) goto eof;
05847 c = read_escape(flags|ESCAPE_CONTROL, encp);
05848 }
05849 else if (c == '?')
05850 return 0177;
05851 else if (c == -1 || !ISASCII(c)) goto eof;
05852 return c & 0x9f;
05853
05854 eof:
05855 case -1:
05856 yyerror("Invalid escape character syntax");
05857 return '\0';
05858
05859 default:
05860 return c;
05861 }
05862 }
05863
05864 static void
05865 parser_tokaddmbc(struct parser_params *parser, int c, rb_encoding *enc)
05866 {
05867 int len = rb_enc_codelen(c, enc);
05868 rb_enc_mbcput(c, tokspace(len), enc);
05869 }
05870
05871 static int
05872 parser_tokadd_escape(struct parser_params *parser, rb_encoding **encp)
05873 {
05874 int c;
05875 int flags = 0;
05876 size_t numlen;
05877
05878 first:
05879 switch (c = nextc()) {
05880 case '\n':
05881 return 0;
05882
05883 case '0': case '1': case '2': case '3':
05884 case '4': case '5': case '6': case '7':
05885 {
05886 ruby_scan_oct(--lex_p, 3, &numlen);
05887 if (numlen == 0) goto eof;
05888 lex_p += numlen;
05889 tokcopy((int)numlen + 1);
05890 }
05891 return 0;
05892
05893 case 'x':
05894 {
05895 tok_hex(&numlen);
05896 if (numlen == 0) return -1;
05897 tokcopy((int)numlen + 2);
05898 }
05899 return 0;
05900
05901 case 'M':
05902 if (flags & ESCAPE_META) goto eof;
05903 if ((c = nextc()) != '-') {
05904 pushback(c);
05905 goto eof;
05906 }
05907 tokcopy(3);
05908 flags |= ESCAPE_META;
05909 goto escaped;
05910
05911 case 'C':
05912 if (flags & ESCAPE_CONTROL) goto eof;
05913 if ((c = nextc()) != '-') {
05914 pushback(c);
05915 goto eof;
05916 }
05917 tokcopy(3);
05918 goto escaped;
05919
05920 case 'c':
05921 if (flags & ESCAPE_CONTROL) goto eof;
05922 tokcopy(2);
05923 flags |= ESCAPE_CONTROL;
05924 escaped:
05925 if ((c = nextc()) == '\\') {
05926 goto first;
05927 }
05928 else if (c == -1) goto eof;
05929 tokadd(c);
05930 return 0;
05931
05932 eof:
05933 case -1:
05934 yyerror("Invalid escape character syntax");
05935 return -1;
05936
05937 default:
05938 tokadd('\\');
05939 tokadd(c);
05940 }
05941 return 0;
05942 }
05943
05944 static int
05945 parser_regx_options(struct parser_params *parser)
05946 {
05947 int kcode = 0;
05948 int kopt = 0;
05949 int options = 0;
05950 int c, opt, kc;
05951
05952 newtok();
05953 while (c = nextc(), ISALPHA(c)) {
05954 if (c == 'o') {
05955 options |= RE_OPTION_ONCE;
05956 }
05957 else if (rb_char_to_option_kcode(c, &opt, &kc)) {
05958 if (kc >= 0) {
05959 if (kc != rb_ascii8bit_encindex()) kcode = c;
05960 kopt = opt;
05961 }
05962 else {
05963 options |= opt;
05964 }
05965 }
05966 else {
05967 tokadd(c);
05968 }
05969 }
05970 options |= kopt;
05971 pushback(c);
05972 if (toklen()) {
05973 tokfix();
05974 compile_error(PARSER_ARG "unknown regexp option%s - %s",
05975 toklen() > 1 ? "s" : "", tok());
05976 }
05977 return options | RE_OPTION_ENCODING(kcode);
05978 }
05979
05980 static void
05981 dispose_string(VALUE str)
05982 {
05983 rb_str_free(str);
05984 rb_gc_force_recycle(str);
05985 }
05986
05987 static int
05988 parser_tokadd_mbchar(struct parser_params *parser, int c)
05989 {
05990 int len = parser_precise_mbclen();
05991 if (!MBCLEN_CHARFOUND_P(len)) {
05992 compile_error(PARSER_ARG "invalid multibyte char (%s)", parser_encoding_name());
05993 return -1;
05994 }
05995 tokadd(c);
05996 lex_p += --len;
05997 if (len > 0) tokcopy(len);
05998 return c;
05999 }
06000
06001 #define tokadd_mbchar(c) parser_tokadd_mbchar(parser, (c))
06002
06003 static inline int
06004 simple_re_meta(int c)
06005 {
06006 switch (c) {
06007 case '$': case '*': case '+': case '.':
06008 case '?': case '^': case '|':
06009 case ')': case ']': case '}': case '>':
06010 return TRUE;
06011 default:
06012 return FALSE;
06013 }
06014 }
06015
06016 static int
06017 parser_tokadd_string(struct parser_params *parser,
06018 int func, int term, int paren, long *nest,
06019 rb_encoding **encp)
06020 {
06021 int c;
06022 int has_nonascii = 0;
06023 rb_encoding *enc = *encp;
06024 char *errbuf = 0;
06025 static const char mixed_msg[] = "%s mixed within %s source";
06026
06027 #define mixed_error(enc1, enc2) if (!errbuf) { \
06028 size_t len = sizeof(mixed_msg) - 4; \
06029 len += strlen(rb_enc_name(enc1)); \
06030 len += strlen(rb_enc_name(enc2)); \
06031 errbuf = ALLOCA_N(char, len); \
06032 snprintf(errbuf, len, mixed_msg, \
06033 rb_enc_name(enc1), \
06034 rb_enc_name(enc2)); \
06035 yyerror(errbuf); \
06036 }
06037 #define mixed_escape(beg, enc1, enc2) do { \
06038 const char *pos = lex_p; \
06039 lex_p = (beg); \
06040 mixed_error((enc1), (enc2)); \
06041 lex_p = pos; \
06042 } while (0)
06043
06044 while ((c = nextc()) != -1) {
06045 if (paren && c == paren) {
06046 ++*nest;
06047 }
06048 else if (c == term) {
06049 if (!nest || !*nest) {
06050 pushback(c);
06051 break;
06052 }
06053 --*nest;
06054 }
06055 else if ((func & STR_FUNC_EXPAND) && c == '#' && lex_p < lex_pend) {
06056 int c2 = *lex_p;
06057 if (c2 == '$' || c2 == '@' || c2 == '{') {
06058 pushback(c);
06059 break;
06060 }
06061 }
06062 else if (c == '\\') {
06063 const char *beg = lex_p - 1;
06064 c = nextc();
06065 switch (c) {
06066 case '\n':
06067 if (func & STR_FUNC_QWORDS) break;
06068 if (func & STR_FUNC_EXPAND) continue;
06069 tokadd('\\');
06070 break;
06071
06072 case '\\':
06073 if (func & STR_FUNC_ESCAPE) tokadd(c);
06074 break;
06075
06076 case 'u':
06077 if ((func & STR_FUNC_EXPAND) == 0) {
06078 tokadd('\\');
06079 break;
06080 }
06081 parser_tokadd_utf8(parser, &enc, 1,
06082 func & STR_FUNC_SYMBOL,
06083 func & STR_FUNC_REGEXP);
06084 if (has_nonascii && enc != *encp) {
06085 mixed_escape(beg, enc, *encp);
06086 }
06087 continue;
06088
06089 default:
06090 if (c == -1) return -1;
06091 if (!ISASCII(c)) {
06092 if ((func & STR_FUNC_EXPAND) == 0) tokadd('\\');
06093 goto non_ascii;
06094 }
06095 if (func & STR_FUNC_REGEXP) {
06096 if (c == term && !simple_re_meta(c)) {
06097 tokadd(c);
06098 continue;
06099 }
06100 pushback(c);
06101 if ((c = tokadd_escape(&enc)) < 0)
06102 return -1;
06103 if (has_nonascii && enc != *encp) {
06104 mixed_escape(beg, enc, *encp);
06105 }
06106 continue;
06107 }
06108 else if (func & STR_FUNC_EXPAND) {
06109 pushback(c);
06110 if (func & STR_FUNC_ESCAPE) tokadd('\\');
06111 c = read_escape(0, &enc);
06112 }
06113 else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
06114
06115 }
06116 else if (c != term && !(paren && c == paren)) {
06117 tokadd('\\');
06118 pushback(c);
06119 continue;
06120 }
06121 }
06122 }
06123 else if (!parser_isascii()) {
06124 non_ascii:
06125 has_nonascii = 1;
06126 if (enc != *encp) {
06127 mixed_error(enc, *encp);
06128 continue;
06129 }
06130 if (tokadd_mbchar(c) == -1) return -1;
06131 continue;
06132 }
06133 else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
06134 pushback(c);
06135 break;
06136 }
06137 if (c & 0x80) {
06138 has_nonascii = 1;
06139 if (enc != *encp) {
06140 mixed_error(enc, *encp);
06141 continue;
06142 }
06143 }
06144 tokadd(c);
06145 }
06146 *encp = enc;
06147 return c;
06148 }
06149
06150 #define NEW_STRTERM(func, term, paren) \
06151 rb_node_newnode(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)
06152
06153 #ifdef RIPPER
06154 static void
06155 ripper_flush_string_content(struct parser_params *parser, rb_encoding *enc)
06156 {
06157 if (!NIL_P(parser->delayed)) {
06158 ptrdiff_t len = lex_p - parser->tokp;
06159 if (len > 0) {
06160 rb_enc_str_buf_cat(parser->delayed, parser->tokp, len, enc);
06161 }
06162 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
06163 parser->tokp = lex_p;
06164 }
06165 }
06166
06167 #define flush_string_content(enc) ripper_flush_string_content(parser, (enc))
06168 #else
06169 #define flush_string_content(enc) ((void)(enc))
06170 #endif
06171
06172 RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
06173
06174
06175 #ifndef RIPPER
06176 #define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0)
06177 #define SPECIAL_PUNCT(idx) ( \
06178 BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \
06179 BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \
06180 BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \
06181 BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \
06182 BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \
06183 BIT('0', idx))
06184 const unsigned int ruby_global_name_punct_bits[] = {
06185 SPECIAL_PUNCT(0),
06186 SPECIAL_PUNCT(1),
06187 SPECIAL_PUNCT(2),
06188 };
06189 #undef BIT
06190 #undef SPECIAL_PUNCT
06191 #endif
06192
06193 static inline int
06194 is_global_name_punct(const char c)
06195 {
06196 if (c <= 0x20 || 0x7e < c) return 0;
06197 return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
06198 }
06199
06200 static int
06201 parser_peek_variable_name(struct parser_params *parser)
06202 {
06203 int c;
06204 const char *p = lex_p;
06205
06206 if (p + 1 >= lex_pend) return 0;
06207 c = *p++;
06208 switch (c) {
06209 case '$':
06210 if ((c = *p) == '-') {
06211 if (++p >= lex_pend) return 0;
06212 c = *p;
06213 }
06214 else if (is_global_name_punct(c) || ISDIGIT(c)) {
06215 return tSTRING_DVAR;
06216 }
06217 break;
06218 case '@':
06219 if ((c = *p) == '@') {
06220 if (++p >= lex_pend) return 0;
06221 c = *p;
06222 }
06223 break;
06224 case '{':
06225 lex_p = p;
06226 command_start = TRUE;
06227 return tSTRING_DBEG;
06228 default:
06229 return 0;
06230 }
06231 if (!ISASCII(c) || c == '_' || ISALPHA(c))
06232 return tSTRING_DVAR;
06233 return 0;
06234 }
06235
06236 static int
06237 parser_parse_string(struct parser_params *parser, NODE *quote)
06238 {
06239 int func = (int)quote->nd_func;
06240 int term = nd_term(quote);
06241 int paren = nd_paren(quote);
06242 int c, space = 0;
06243 rb_encoding *enc = current_enc;
06244
06245 if (func == -1) return tSTRING_END;
06246 c = nextc();
06247 if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
06248 do {c = nextc();} while (ISSPACE(c));
06249 space = 1;
06250 }
06251 if (c == term && !quote->nd_nest) {
06252 if (func & STR_FUNC_QWORDS) {
06253 quote->nd_func = -1;
06254 return ' ';
06255 }
06256 if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
06257 set_yylval_num(regx_options());
06258 return tREGEXP_END;
06259 }
06260 if (space) {
06261 pushback(c);
06262 return ' ';
06263 }
06264 newtok();
06265 if ((func & STR_FUNC_EXPAND) && c == '#') {
06266 int t = parser_peek_variable_name(parser);
06267 if (t) return t;
06268 tokadd('#');
06269 c = nextc();
06270 }
06271 pushback(c);
06272 if (tokadd_string(func, term, paren, "e->nd_nest,
06273 &enc) == -1) {
06274 ruby_sourceline = nd_line(quote);
06275 if (func & STR_FUNC_REGEXP) {
06276 if (parser->eofp)
06277 compile_error(PARSER_ARG "unterminated regexp meets end of file");
06278 return tREGEXP_END;
06279 }
06280 else {
06281 if (parser->eofp)
06282 compile_error(PARSER_ARG "unterminated string meets end of file");
06283 return tSTRING_END;
06284 }
06285 }
06286
06287 tokfix();
06288 set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
06289 flush_string_content(enc);
06290
06291 return tSTRING_CONTENT;
06292 }
06293
06294 static int
06295 parser_heredoc_identifier(struct parser_params *parser)
06296 {
06297 int c = nextc(), term, func = 0;
06298 long len;
06299
06300 if (c == '-') {
06301 c = nextc();
06302 func = STR_FUNC_INDENT;
06303 }
06304 switch (c) {
06305 case '\'':
06306 func |= str_squote; goto quoted;
06307 case '"':
06308 func |= str_dquote; goto quoted;
06309 case '`':
06310 func |= str_xquote;
06311 quoted:
06312 newtok();
06313 tokadd(func);
06314 term = c;
06315 while ((c = nextc()) != -1 && c != term) {
06316 if (tokadd_mbchar(c) == -1) return 0;
06317 }
06318 if (c == -1) {
06319 compile_error(PARSER_ARG "unterminated here document identifier");
06320 return 0;
06321 }
06322 break;
06323
06324 default:
06325 if (!parser_is_identchar()) {
06326 pushback(c);
06327 if (func & STR_FUNC_INDENT) {
06328 pushback('-');
06329 }
06330 return 0;
06331 }
06332 newtok();
06333 term = '"';
06334 tokadd(func |= str_dquote);
06335 do {
06336 if (tokadd_mbchar(c) == -1) return 0;
06337 } while ((c = nextc()) != -1 && parser_is_identchar());
06338 pushback(c);
06339 break;
06340 }
06341
06342 tokfix();
06343 #ifdef RIPPER
06344 ripper_dispatch_scan_event(parser, tHEREDOC_BEG);
06345 #endif
06346 len = lex_p - lex_pbeg;
06347 lex_goto_eol(parser);
06348 lex_strterm = rb_node_newnode(NODE_HEREDOC,
06349 STR_NEW(tok(), toklen()),
06350 len,
06351 lex_lastline);
06352 nd_set_line(lex_strterm, ruby_sourceline);
06353 ripper_flush(parser);
06354 return term == '`' ? tXSTRING_BEG : tSTRING_BEG;
06355 }
06356
06357 static void
06358 parser_heredoc_restore(struct parser_params *parser, NODE *here)
06359 {
06360 VALUE line;
06361
06362 line = here->nd_orig;
06363 lex_lastline = line;
06364 lex_pbeg = RSTRING_PTR(line);
06365 lex_pend = lex_pbeg + RSTRING_LEN(line);
06366 lex_p = lex_pbeg + here->nd_nth;
06367 heredoc_end = ruby_sourceline;
06368 ruby_sourceline = nd_line(here);
06369 dispose_string(here->nd_lit);
06370 rb_gc_force_recycle((VALUE)here);
06371 ripper_flush(parser);
06372 }
06373
06374 static int
06375 parser_whole_match_p(struct parser_params *parser,
06376 const char *eos, long len, int indent)
06377 {
06378 const char *p = lex_pbeg;
06379 long n;
06380
06381 if (indent) {
06382 while (*p && ISSPACE(*p)) p++;
06383 }
06384 n = lex_pend - (p + len);
06385 if (n < 0 || (n > 0 && p[len] != '\n' && p[len] != '\r')) return FALSE;
06386 return strncmp(eos, p, len) == 0;
06387 }
06388
06389 #ifdef RIPPER
06390 static void
06391 ripper_dispatch_heredoc_end(struct parser_params *parser)
06392 {
06393 if (!NIL_P(parser->delayed))
06394 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
06395 lex_goto_eol(parser);
06396 ripper_dispatch_ignored_scan_event(parser, tHEREDOC_END);
06397 }
06398
06399 #define dispatch_heredoc_end() ripper_dispatch_heredoc_end(parser)
06400 #else
06401 #define dispatch_heredoc_end() ((void)0)
06402 #endif
06403
06404 static int
06405 parser_here_document(struct parser_params *parser, NODE *here)
06406 {
06407 int c, func, indent = 0;
06408 const char *eos, *p, *pend;
06409 long len;
06410 VALUE str = 0;
06411 rb_encoding *enc = current_enc;
06412
06413 eos = RSTRING_PTR(here->nd_lit);
06414 len = RSTRING_LEN(here->nd_lit) - 1;
06415 indent = (func = *eos++) & STR_FUNC_INDENT;
06416
06417 if ((c = nextc()) == -1) {
06418 error:
06419 compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
06420 #ifdef RIPPER
06421 if (NIL_P(parser->delayed)) {
06422 ripper_dispatch_scan_event(parser, tSTRING_CONTENT);
06423 }
06424 else {
06425 if (str ||
06426 ((len = lex_p - parser->tokp) > 0 &&
06427 (str = STR_NEW3(parser->tokp, len, enc, func), 1))) {
06428 rb_str_append(parser->delayed, str);
06429 }
06430 ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
06431 }
06432 lex_goto_eol(parser);
06433 #endif
06434 restore:
06435 heredoc_restore(lex_strterm);
06436 lex_strterm = 0;
06437 return 0;
06438 }
06439 if (was_bol() && whole_match_p(eos, len, indent)) {
06440 dispatch_heredoc_end();
06441 heredoc_restore(lex_strterm);
06442 return tSTRING_END;
06443 }
06444
06445 if (!(func & STR_FUNC_EXPAND)) {
06446 do {
06447 p = RSTRING_PTR(lex_lastline);
06448 pend = lex_pend;
06449 if (pend > p) {
06450 switch (pend[-1]) {
06451 case '\n':
06452 if (--pend == p || pend[-1] != '\r') {
06453 pend++;
06454 break;
06455 }
06456 case '\r':
06457 --pend;
06458 }
06459 }
06460 if (str)
06461 rb_str_cat(str, p, pend - p);
06462 else
06463 str = STR_NEW(p, pend - p);
06464 if (pend < lex_pend) rb_str_cat(str, "\n", 1);
06465 lex_goto_eol(parser);
06466 if (nextc() == -1) {
06467 if (str) {
06468 dispose_string(str);
06469 str = 0;
06470 }
06471 goto error;
06472 }
06473 } while (!whole_match_p(eos, len, indent));
06474 }
06475 else {
06476
06477 newtok();
06478 if (c == '#') {
06479 int t = parser_peek_variable_name(parser);
06480 if (t) return t;
06481 tokadd('#');
06482 c = nextc();
06483 }
06484 do {
06485 pushback(c);
06486 if ((c = tokadd_string(func, '\n', 0, NULL, &enc)) == -1) {
06487 if (parser->eofp) goto error;
06488 goto restore;
06489 }
06490 if (c != '\n') {
06491 set_yylval_str(STR_NEW3(tok(), toklen(), enc, func));
06492 flush_string_content(enc);
06493 return tSTRING_CONTENT;
06494 }
06495 tokadd(nextc());
06496
06497 if ((c = nextc()) == -1) goto error;
06498 } while (!whole_match_p(eos, len, indent));
06499 str = STR_NEW3(tok(), toklen(), enc, func);
06500 }
06501 dispatch_heredoc_end();
06502 heredoc_restore(lex_strterm);
06503 lex_strterm = NEW_STRTERM(-1, 0, 0);
06504 set_yylval_str(str);
06505 return tSTRING_CONTENT;
06506 }
06507
06508 #include "lex.c"
06509
06510 static void
06511 arg_ambiguous_gen(struct parser_params *parser)
06512 {
06513 #ifndef RIPPER
06514 rb_warning0("ambiguous first argument; put parentheses or even spaces");
06515 #else
06516 dispatch0(arg_ambiguous);
06517 #endif
06518 }
06519 #define arg_ambiguous() (arg_ambiguous_gen(parser), 1)
06520
06521 static ID
06522 formal_argument_gen(struct parser_params *parser, ID lhs)
06523 {
06524 #ifndef RIPPER
06525 if (!is_local_id(lhs))
06526 yyerror("formal argument must be local variable");
06527 #endif
06528 shadowing_lvar(lhs);
06529 return lhs;
06530 }
06531
06532 static int
06533 lvar_defined_gen(struct parser_params *parser, ID id)
06534 {
06535 return (dyna_in_block() && dvar_defined_get(id)) || local_id(id);
06536 }
06537
06538
06539 static long
06540 parser_encode_length(struct parser_params *parser, const char *name, long len)
06541 {
06542 long nlen;
06543
06544 if (len > 5 && name[nlen = len - 5] == '-') {
06545 if (rb_memcicmp(name + nlen + 1, "unix", 4) == 0)
06546 return nlen;
06547 }
06548 if (len > 4 && name[nlen = len - 4] == '-') {
06549 if (rb_memcicmp(name + nlen + 1, "dos", 3) == 0)
06550 return nlen;
06551 if (rb_memcicmp(name + nlen + 1, "mac", 3) == 0 &&
06552 !(len == 8 && rb_memcicmp(name, "utf8-mac", len) == 0))
06553
06554 return nlen;
06555 }
06556 return len;
06557 }
06558
06559 static void
06560 parser_set_encode(struct parser_params *parser, const char *name)
06561 {
06562 int idx = rb_enc_find_index(name);
06563 rb_encoding *enc;
06564 VALUE excargs[3];
06565
06566 if (idx < 0) {
06567 excargs[1] = rb_sprintf("unknown encoding name: %s", name);
06568 error:
06569 excargs[0] = rb_eArgError;
06570 excargs[2] = rb_make_backtrace();
06571 rb_ary_unshift(excargs[2], rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline));
06572 rb_exc_raise(rb_make_exception(3, excargs));
06573 }
06574 enc = rb_enc_from_index(idx);
06575 if (!rb_enc_asciicompat(enc)) {
06576 excargs[1] = rb_sprintf("%s is not ASCII compatible", rb_enc_name(enc));
06577 goto error;
06578 }
06579 parser->enc = enc;
06580 #ifndef RIPPER
06581 if (ruby_debug_lines) {
06582 long i, n = RARRAY_LEN(ruby_debug_lines);
06583 const VALUE *p = RARRAY_PTR(ruby_debug_lines);
06584 for (i = 0; i < n; ++i) {
06585 rb_enc_associate_index(*p, idx);
06586 }
06587 }
06588 #endif
06589 }
06590
06591 static int
06592 comment_at_top(struct parser_params *parser)
06593 {
06594 const char *p = lex_pbeg, *pend = lex_p - 1;
06595 if (parser->line_count != (parser->has_shebang ? 2 : 1)) return 0;
06596 while (p < pend) {
06597 if (!ISSPACE(*p)) return 0;
06598 p++;
06599 }
06600 return 1;
06601 }
06602
06603 #ifndef RIPPER
06604 typedef long (*rb_magic_comment_length_t)(struct parser_params *parser, const char *name, long len);
06605 typedef void (*rb_magic_comment_setter_t)(struct parser_params *parser, const char *name, const char *val);
06606
06607 static void
06608 magic_comment_encoding(struct parser_params *parser, const char *name, const char *val)
06609 {
06610 if (!comment_at_top(parser)) {
06611 return;
06612 }
06613 parser_set_encode(parser, val);
06614 }
06615
06616 static void
06617 parser_set_token_info(struct parser_params *parser, const char *name, const char *val)
06618 {
06619 int *p = &parser->parser_token_info_enabled;
06620
06621 switch (*val) {
06622 case 't': case 'T':
06623 if (strcasecmp(val, "true") == 0) {
06624 *p = TRUE;
06625 return;
06626 }
06627 break;
06628 case 'f': case 'F':
06629 if (strcasecmp(val, "false") == 0) {
06630 *p = FALSE;
06631 return;
06632 }
06633 break;
06634 }
06635 rb_compile_warning(ruby_sourcefile, ruby_sourceline, "invalid value for %s: %s", name, val);
06636 }
06637
06638 struct magic_comment {
06639 const char *name;
06640 rb_magic_comment_setter_t func;
06641 rb_magic_comment_length_t length;
06642 };
06643
06644 static const struct magic_comment magic_comments[] = {
06645 {"coding", magic_comment_encoding, parser_encode_length},
06646 {"encoding", magic_comment_encoding, parser_encode_length},
06647 {"warn_indent", parser_set_token_info},
06648 };
06649 #endif
06650
06651 static const char *
06652 magic_comment_marker(const char *str, long len)
06653 {
06654 long i = 2;
06655
06656 while (i < len) {
06657 switch (str[i]) {
06658 case '-':
06659 if (str[i-1] == '*' && str[i-2] == '-') {
06660 return str + i + 1;
06661 }
06662 i += 2;
06663 break;
06664 case '*':
06665 if (i + 1 >= len) return 0;
06666 if (str[i+1] != '-') {
06667 i += 4;
06668 }
06669 else if (str[i-1] != '-') {
06670 i += 2;
06671 }
06672 else {
06673 return str + i + 2;
06674 }
06675 break;
06676 default:
06677 i += 3;
06678 break;
06679 }
06680 }
06681 return 0;
06682 }
06683
06684 static int
06685 parser_magic_comment(struct parser_params *parser, const char *str, long len)
06686 {
06687 VALUE name = 0, val = 0;
06688 const char *beg, *end, *vbeg, *vend;
06689 #define str_copy(_s, _p, _n) ((_s) \
06690 ? (void)(rb_str_resize((_s), (_n)), \
06691 MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \
06692 : (void)((_s) = STR_NEW((_p), (_n))))
06693
06694 if (len <= 7) return FALSE;
06695 if (!(beg = magic_comment_marker(str, len))) return FALSE;
06696 if (!(end = magic_comment_marker(beg, str + len - beg))) return FALSE;
06697 str = beg;
06698 len = end - beg - 3;
06699
06700
06701 while (len > 0) {
06702 #ifndef RIPPER
06703 const struct magic_comment *p = magic_comments;
06704 #endif
06705 char *s;
06706 int i;
06707 long n = 0;
06708
06709 for (; len > 0 && *str; str++, --len) {
06710 switch (*str) {
06711 case '\'': case '"': case ':': case ';':
06712 continue;
06713 }
06714 if (!ISSPACE(*str)) break;
06715 }
06716 for (beg = str; len > 0; str++, --len) {
06717 switch (*str) {
06718 case '\'': case '"': case ':': case ';':
06719 break;
06720 default:
06721 if (ISSPACE(*str)) break;
06722 continue;
06723 }
06724 break;
06725 }
06726 for (end = str; len > 0 && ISSPACE(*str); str++, --len);
06727 if (!len) break;
06728 if (*str != ':') continue;
06729
06730 do str++; while (--len > 0 && ISSPACE(*str));
06731 if (!len) break;
06732 if (*str == '"') {
06733 for (vbeg = ++str; --len > 0 && *str != '"'; str++) {
06734 if (*str == '\\') {
06735 --len;
06736 ++str;
06737 }
06738 }
06739 vend = str;
06740 if (len) {
06741 --len;
06742 ++str;
06743 }
06744 }
06745 else {
06746 for (vbeg = str; len > 0 && *str != '"' && *str != ';' && !ISSPACE(*str); --len, str++);
06747 vend = str;
06748 }
06749 while (len > 0 && (*str == ';' || ISSPACE(*str))) --len, str++;
06750
06751 n = end - beg;
06752 str_copy(name, beg, n);
06753 s = RSTRING_PTR(name);
06754 for (i = 0; i < n; ++i) {
06755 if (s[i] == '-') s[i] = '_';
06756 }
06757 #ifndef RIPPER
06758 do {
06759 if (STRNCASECMP(p->name, s, n) == 0) {
06760 n = vend - vbeg;
06761 if (p->length) {
06762 n = (*p->length)(parser, vbeg, n);
06763 }
06764 str_copy(val, vbeg, n);
06765 (*p->func)(parser, s, RSTRING_PTR(val));
06766 break;
06767 }
06768 } while (++p < magic_comments + numberof(magic_comments));
06769 #else
06770 str_copy(val, vbeg, vend - vbeg);
06771 dispatch2(magic_comment, name, val);
06772 #endif
06773 }
06774
06775 return TRUE;
06776 }
06777
06778 static void
06779 set_file_encoding(struct parser_params *parser, const char *str, const char *send)
06780 {
06781 int sep = 0;
06782 const char *beg = str;
06783 VALUE s;
06784
06785 for (;;) {
06786 if (send - str <= 6) return;
06787 switch (str[6]) {
06788 case 'C': case 'c': str += 6; continue;
06789 case 'O': case 'o': str += 5; continue;
06790 case 'D': case 'd': str += 4; continue;
06791 case 'I': case 'i': str += 3; continue;
06792 case 'N': case 'n': str += 2; continue;
06793 case 'G': case 'g': str += 1; continue;
06794 case '=': case ':':
06795 sep = 1;
06796 str += 6;
06797 break;
06798 default:
06799 str += 6;
06800 if (ISSPACE(*str)) break;
06801 continue;
06802 }
06803 if (STRNCASECMP(str-6, "coding", 6) == 0) break;
06804 }
06805 for (;;) {
06806 do {
06807 if (++str >= send) return;
06808 } while (ISSPACE(*str));
06809 if (sep) break;
06810 if (*str != '=' && *str != ':') return;
06811 sep = 1;
06812 str++;
06813 }
06814 beg = str;
06815 while ((*str == '-' || *str == '_' || ISALNUM(*str)) && ++str < send);
06816 s = rb_str_new(beg, parser_encode_length(parser, beg, str - beg));
06817 parser_set_encode(parser, RSTRING_PTR(s));
06818 rb_str_resize(s, 0);
06819 }
06820
06821 static void
06822 parser_prepare(struct parser_params *parser)
06823 {
06824 int c = nextc();
06825 switch (c) {
06826 case '#':
06827 if (peek('!')) parser->has_shebang = 1;
06828 break;
06829 case 0xef:
06830 if (lex_pend - lex_p >= 2 &&
06831 (unsigned char)lex_p[0] == 0xbb &&
06832 (unsigned char)lex_p[1] == 0xbf) {
06833 parser->enc = rb_utf8_encoding();
06834 lex_p += 2;
06835 lex_pbeg = lex_p;
06836 return;
06837 }
06838 break;
06839 case EOF:
06840 return;
06841 }
06842 pushback(c);
06843 parser->enc = rb_enc_get(lex_lastline);
06844 }
06845
06846 #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
06847 #define IS_END() IS_lex_state(EXPR_END_ANY)
06848 #define IS_BEG() IS_lex_state(EXPR_BEG_ANY)
06849 #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
06850 #define IS_LABEL_POSSIBLE() ((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !cmd_state) || IS_ARG())
06851 #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
06852 #define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
06853
06854 #ifndef RIPPER
06855 #define ambiguous_operator(op, syn) ( \
06856 rb_warning0("`"op"' after local variable is interpreted as binary operator"), \
06857 rb_warning0("even though it seems like "syn""))
06858 #else
06859 #define ambiguous_operator(op, syn) dispatch2(operator_ambiguous, ripper_intern(op), rb_str_new_cstr(syn))
06860 #endif
06861 #define warn_balanced(op, syn) ((void) \
06862 (!IS_lex_state_for(last_state, EXPR_CLASS|EXPR_DOT|EXPR_FNAME|EXPR_ENDFN|EXPR_ENDARG) && \
06863 space_seen && !ISSPACE(c) && \
06864 (ambiguous_operator(op, syn), 0)))
06865
06866 static int
06867 parser_yylex(struct parser_params *parser)
06868 {
06869 register int c;
06870 int space_seen = 0;
06871 int cmd_state;
06872 enum lex_state_e last_state;
06873 rb_encoding *enc;
06874 int mb;
06875 #ifdef RIPPER
06876 int fallthru = FALSE;
06877 #endif
06878
06879 if (lex_strterm) {
06880 int token;
06881 if (nd_type(lex_strterm) == NODE_HEREDOC) {
06882 token = here_document(lex_strterm);
06883 if (token == tSTRING_END) {
06884 lex_strterm = 0;
06885 lex_state = EXPR_END;
06886 }
06887 }
06888 else {
06889 token = parse_string(lex_strterm);
06890 if (token == tSTRING_END || token == tREGEXP_END) {
06891 rb_gc_force_recycle((VALUE)lex_strterm);
06892 lex_strterm = 0;
06893 lex_state = EXPR_END;
06894 }
06895 }
06896 return token;
06897 }
06898 cmd_state = command_start;
06899 command_start = FALSE;
06900 retry:
06901 last_state = lex_state;
06902 switch (c = nextc()) {
06903 case '\0':
06904 case '\004':
06905 case '\032':
06906 case -1:
06907 return 0;
06908
06909
06910 case ' ': case '\t': case '\f': case '\r':
06911 case '\13':
06912 space_seen = 1;
06913 #ifdef RIPPER
06914 while ((c = nextc())) {
06915 switch (c) {
06916 case ' ': case '\t': case '\f': case '\r':
06917 case '\13':
06918 break;
06919 default:
06920 goto outofloop;
06921 }
06922 }
06923 outofloop:
06924 pushback(c);
06925 ripper_dispatch_scan_event(parser, tSP);
06926 #endif
06927 goto retry;
06928
06929 case '#':
06930
06931 if (!parser_magic_comment(parser, lex_p, lex_pend - lex_p)) {
06932 if (comment_at_top(parser)) {
06933 set_file_encoding(parser, lex_p, lex_pend);
06934 }
06935 }
06936 lex_p = lex_pend;
06937 #ifdef RIPPER
06938 ripper_dispatch_scan_event(parser, tCOMMENT);
06939 fallthru = TRUE;
06940 #endif
06941
06942 case '\n':
06943 if (IS_lex_state(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT)) {
06944 #ifdef RIPPER
06945 if (!fallthru) {
06946 ripper_dispatch_scan_event(parser, tIGNORED_NL);
06947 }
06948 fallthru = FALSE;
06949 #endif
06950 goto retry;
06951 }
06952 while ((c = nextc())) {
06953 switch (c) {
06954 case ' ': case '\t': case '\f': case '\r':
06955 case '\13':
06956 space_seen = 1;
06957 break;
06958 case '.': {
06959 if ((c = nextc()) != '.') {
06960 pushback(c);
06961 pushback('.');
06962 goto retry;
06963 }
06964 }
06965 default:
06966 --ruby_sourceline;
06967 lex_nextline = lex_lastline;
06968 case -1:
06969 lex_goto_eol(parser);
06970 #ifdef RIPPER
06971 if (c != -1) {
06972 parser->tokp = lex_p;
06973 }
06974 #endif
06975 goto normal_newline;
06976 }
06977 }
06978 normal_newline:
06979 command_start = TRUE;
06980 lex_state = EXPR_BEG;
06981 return '\n';
06982
06983 case '*':
06984 if ((c = nextc()) == '*') {
06985 if ((c = nextc()) == '=') {
06986 set_yylval_id(tPOW);
06987 lex_state = EXPR_BEG;
06988 return tOP_ASGN;
06989 }
06990 pushback(c);
06991 if (IS_SPCARG(c)) {
06992 rb_warning0("`**' interpreted as argument prefix");
06993 c = tDSTAR;
06994 }
06995 else if (IS_BEG()) {
06996 c = tDSTAR;
06997 }
06998 else {
06999 warn_balanced("**", "argument prefix");
07000 c = tPOW;
07001 }
07002 }
07003 else {
07004 if (c == '=') {
07005 set_yylval_id('*');
07006 lex_state = EXPR_BEG;
07007 return tOP_ASGN;
07008 }
07009 pushback(c);
07010 if (IS_SPCARG(c)) {
07011 rb_warning0("`*' interpreted as argument prefix");
07012 c = tSTAR;
07013 }
07014 else if (IS_BEG()) {
07015 c = tSTAR;
07016 }
07017 else {
07018 warn_balanced("*", "argument prefix");
07019 c = '*';
07020 }
07021 }
07022 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07023 return c;
07024
07025 case '!':
07026 c = nextc();
07027 if (IS_AFTER_OPERATOR()) {
07028 lex_state = EXPR_ARG;
07029 if (c == '@') {
07030 return '!';
07031 }
07032 }
07033 else {
07034 lex_state = EXPR_BEG;
07035 }
07036 if (c == '=') {
07037 return tNEQ;
07038 }
07039 if (c == '~') {
07040 return tNMATCH;
07041 }
07042 pushback(c);
07043 return '!';
07044
07045 case '=':
07046 if (was_bol()) {
07047
07048 if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) {
07049 #ifdef RIPPER
07050 int first_p = TRUE;
07051
07052 lex_goto_eol(parser);
07053 ripper_dispatch_scan_event(parser, tEMBDOC_BEG);
07054 #endif
07055 for (;;) {
07056 lex_goto_eol(parser);
07057 #ifdef RIPPER
07058 if (!first_p) {
07059 ripper_dispatch_scan_event(parser, tEMBDOC);
07060 }
07061 first_p = FALSE;
07062 #endif
07063 c = nextc();
07064 if (c == -1) {
07065 compile_error(PARSER_ARG "embedded document meets end of file");
07066 return 0;
07067 }
07068 if (c != '=') continue;
07069 if (strncmp(lex_p, "end", 3) == 0 &&
07070 (lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {
07071 break;
07072 }
07073 }
07074 lex_goto_eol(parser);
07075 #ifdef RIPPER
07076 ripper_dispatch_scan_event(parser, tEMBDOC_END);
07077 #endif
07078 goto retry;
07079 }
07080 }
07081
07082 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07083 if ((c = nextc()) == '=') {
07084 if ((c = nextc()) == '=') {
07085 return tEQQ;
07086 }
07087 pushback(c);
07088 return tEQ;
07089 }
07090 if (c == '~') {
07091 return tMATCH;
07092 }
07093 else if (c == '>') {
07094 return tASSOC;
07095 }
07096 pushback(c);
07097 return '=';
07098
07099 case '<':
07100 last_state = lex_state;
07101 c = nextc();
07102 if (c == '<' &&
07103 !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
07104 !IS_END() &&
07105 (!IS_ARG() || space_seen)) {
07106 int token = heredoc_identifier();
07107 if (token) return token;
07108 }
07109 if (IS_AFTER_OPERATOR()) {
07110 lex_state = EXPR_ARG;
07111 }
07112 else {
07113 if (IS_lex_state(EXPR_CLASS))
07114 command_start = TRUE;
07115 lex_state = EXPR_BEG;
07116 }
07117 if (c == '=') {
07118 if ((c = nextc()) == '>') {
07119 return tCMP;
07120 }
07121 pushback(c);
07122 return tLEQ;
07123 }
07124 if (c == '<') {
07125 if ((c = nextc()) == '=') {
07126 set_yylval_id(tLSHFT);
07127 lex_state = EXPR_BEG;
07128 return tOP_ASGN;
07129 }
07130 pushback(c);
07131 warn_balanced("<<", "here document");
07132 return tLSHFT;
07133 }
07134 pushback(c);
07135 return '<';
07136
07137 case '>':
07138 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07139 if ((c = nextc()) == '=') {
07140 return tGEQ;
07141 }
07142 if (c == '>') {
07143 if ((c = nextc()) == '=') {
07144 set_yylval_id(tRSHFT);
07145 lex_state = EXPR_BEG;
07146 return tOP_ASGN;
07147 }
07148 pushback(c);
07149 return tRSHFT;
07150 }
07151 pushback(c);
07152 return '>';
07153
07154 case '"':
07155 lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
07156 return tSTRING_BEG;
07157
07158 case '`':
07159 if (IS_lex_state(EXPR_FNAME)) {
07160 lex_state = EXPR_ENDFN;
07161 return c;
07162 }
07163 if (IS_lex_state(EXPR_DOT)) {
07164 if (cmd_state)
07165 lex_state = EXPR_CMDARG;
07166 else
07167 lex_state = EXPR_ARG;
07168 return c;
07169 }
07170 lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
07171 return tXSTRING_BEG;
07172
07173 case '\'':
07174 lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
07175 return tSTRING_BEG;
07176
07177 case '?':
07178 if (IS_END()) {
07179 lex_state = EXPR_VALUE;
07180 return '?';
07181 }
07182 c = nextc();
07183 if (c == -1) {
07184 compile_error(PARSER_ARG "incomplete character syntax");
07185 return 0;
07186 }
07187 if (rb_enc_isspace(c, current_enc)) {
07188 if (!IS_ARG()) {
07189 int c2 = 0;
07190 switch (c) {
07191 case ' ':
07192 c2 = 's';
07193 break;
07194 case '\n':
07195 c2 = 'n';
07196 break;
07197 case '\t':
07198 c2 = 't';
07199 break;
07200 case '\v':
07201 c2 = 'v';
07202 break;
07203 case '\r':
07204 c2 = 'r';
07205 break;
07206 case '\f':
07207 c2 = 'f';
07208 break;
07209 }
07210 if (c2) {
07211 rb_warnI("invalid character syntax; use ?\\%c", c2);
07212 }
07213 }
07214 ternary:
07215 pushback(c);
07216 lex_state = EXPR_VALUE;
07217 return '?';
07218 }
07219 newtok();
07220 enc = current_enc;
07221 if (!parser_isascii()) {
07222 if (tokadd_mbchar(c) == -1) return 0;
07223 }
07224 else if ((rb_enc_isalnum(c, current_enc) || c == '_') &&
07225 lex_p < lex_pend && is_identchar(lex_p, lex_pend, current_enc)) {
07226 goto ternary;
07227 }
07228 else if (c == '\\') {
07229 if (peek('u')) {
07230 nextc();
07231 c = parser_tokadd_utf8(parser, &enc, 0, 0, 0);
07232 if (0x80 <= c) {
07233 tokaddmbc(c, enc);
07234 }
07235 else {
07236 tokadd(c);
07237 }
07238 }
07239 else if (!lex_eol_p() && !(c = *lex_p, ISASCII(c))) {
07240 nextc();
07241 if (tokadd_mbchar(c) == -1) return 0;
07242 }
07243 else {
07244 c = read_escape(0, &enc);
07245 tokadd(c);
07246 }
07247 }
07248 else {
07249 tokadd(c);
07250 }
07251 tokfix();
07252 set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0));
07253 lex_state = EXPR_END;
07254 return tCHAR;
07255
07256 case '&':
07257 if ((c = nextc()) == '&') {
07258 lex_state = EXPR_BEG;
07259 if ((c = nextc()) == '=') {
07260 set_yylval_id(tANDOP);
07261 lex_state = EXPR_BEG;
07262 return tOP_ASGN;
07263 }
07264 pushback(c);
07265 return tANDOP;
07266 }
07267 else if (c == '=') {
07268 set_yylval_id('&');
07269 lex_state = EXPR_BEG;
07270 return tOP_ASGN;
07271 }
07272 pushback(c);
07273 if (IS_SPCARG(c)) {
07274 rb_warning0("`&' interpreted as argument prefix");
07275 c = tAMPER;
07276 }
07277 else if (IS_BEG()) {
07278 c = tAMPER;
07279 }
07280 else {
07281 warn_balanced("&", "argument prefix");
07282 c = '&';
07283 }
07284 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07285 return c;
07286
07287 case '|':
07288 if ((c = nextc()) == '|') {
07289 lex_state = EXPR_BEG;
07290 if ((c = nextc()) == '=') {
07291 set_yylval_id(tOROP);
07292 lex_state = EXPR_BEG;
07293 return tOP_ASGN;
07294 }
07295 pushback(c);
07296 return tOROP;
07297 }
07298 if (c == '=') {
07299 set_yylval_id('|');
07300 lex_state = EXPR_BEG;
07301 return tOP_ASGN;
07302 }
07303 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07304 pushback(c);
07305 return '|';
07306
07307 case '+':
07308 c = nextc();
07309 if (IS_AFTER_OPERATOR()) {
07310 lex_state = EXPR_ARG;
07311 if (c == '@') {
07312 return tUPLUS;
07313 }
07314 pushback(c);
07315 return '+';
07316 }
07317 if (c == '=') {
07318 set_yylval_id('+');
07319 lex_state = EXPR_BEG;
07320 return tOP_ASGN;
07321 }
07322 if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
07323 lex_state = EXPR_BEG;
07324 pushback(c);
07325 if (c != -1 && ISDIGIT(c)) {
07326 c = '+';
07327 goto start_num;
07328 }
07329 return tUPLUS;
07330 }
07331 lex_state = EXPR_BEG;
07332 pushback(c);
07333 warn_balanced("+", "unary operator");
07334 return '+';
07335
07336 case '-':
07337 c = nextc();
07338 if (IS_AFTER_OPERATOR()) {
07339 lex_state = EXPR_ARG;
07340 if (c == '@') {
07341 return tUMINUS;
07342 }
07343 pushback(c);
07344 return '-';
07345 }
07346 if (c == '=') {
07347 set_yylval_id('-');
07348 lex_state = EXPR_BEG;
07349 return tOP_ASGN;
07350 }
07351 if (c == '>') {
07352 lex_state = EXPR_ENDFN;
07353 return tLAMBDA;
07354 }
07355 if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous())) {
07356 lex_state = EXPR_BEG;
07357 pushback(c);
07358 if (c != -1 && ISDIGIT(c)) {
07359 return tUMINUS_NUM;
07360 }
07361 return tUMINUS;
07362 }
07363 lex_state = EXPR_BEG;
07364 pushback(c);
07365 warn_balanced("-", "unary operator");
07366 return '-';
07367
07368 case '.':
07369 lex_state = EXPR_BEG;
07370 if ((c = nextc()) == '.') {
07371 if ((c = nextc()) == '.') {
07372 return tDOT3;
07373 }
07374 pushback(c);
07375 return tDOT2;
07376 }
07377 pushback(c);
07378 if (c != -1 && ISDIGIT(c)) {
07379 yyerror("no .<digit> floating literal anymore; put 0 before dot");
07380 }
07381 lex_state = EXPR_DOT;
07382 return '.';
07383
07384 start_num:
07385 case '0': case '1': case '2': case '3': case '4':
07386 case '5': case '6': case '7': case '8': case '9':
07387 {
07388 int is_float, seen_point, seen_e, nondigit;
07389
07390 is_float = seen_point = seen_e = nondigit = 0;
07391 lex_state = EXPR_END;
07392 newtok();
07393 if (c == '-' || c == '+') {
07394 tokadd(c);
07395 c = nextc();
07396 }
07397 if (c == '0') {
07398 #define no_digits() do {yyerror("numeric literal without digits"); return 0;} while (0)
07399 int start = toklen();
07400 c = nextc();
07401 if (c == 'x' || c == 'X') {
07402
07403 c = nextc();
07404 if (c != -1 && ISXDIGIT(c)) {
07405 do {
07406 if (c == '_') {
07407 if (nondigit) break;
07408 nondigit = c;
07409 continue;
07410 }
07411 if (!ISXDIGIT(c)) break;
07412 nondigit = 0;
07413 tokadd(c);
07414 } while ((c = nextc()) != -1);
07415 }
07416 pushback(c);
07417 tokfix();
07418 if (toklen() == start) {
07419 no_digits();
07420 }
07421 else if (nondigit) goto trailing_uc;
07422 set_yylval_literal(rb_cstr_to_inum(tok(), 16, FALSE));
07423 return tINTEGER;
07424 }
07425 if (c == 'b' || c == 'B') {
07426
07427 c = nextc();
07428 if (c == '0' || c == '1') {
07429 do {
07430 if (c == '_') {
07431 if (nondigit) break;
07432 nondigit = c;
07433 continue;
07434 }
07435 if (c != '0' && c != '1') break;
07436 nondigit = 0;
07437 tokadd(c);
07438 } while ((c = nextc()) != -1);
07439 }
07440 pushback(c);
07441 tokfix();
07442 if (toklen() == start) {
07443 no_digits();
07444 }
07445 else if (nondigit) goto trailing_uc;
07446 set_yylval_literal(rb_cstr_to_inum(tok(), 2, FALSE));
07447 return tINTEGER;
07448 }
07449 if (c == 'd' || c == 'D') {
07450
07451 c = nextc();
07452 if (c != -1 && ISDIGIT(c)) {
07453 do {
07454 if (c == '_') {
07455 if (nondigit) break;
07456 nondigit = c;
07457 continue;
07458 }
07459 if (!ISDIGIT(c)) break;
07460 nondigit = 0;
07461 tokadd(c);
07462 } while ((c = nextc()) != -1);
07463 }
07464 pushback(c);
07465 tokfix();
07466 if (toklen() == start) {
07467 no_digits();
07468 }
07469 else if (nondigit) goto trailing_uc;
07470 set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
07471 return tINTEGER;
07472 }
07473 if (c == '_') {
07474
07475 goto octal_number;
07476 }
07477 if (c == 'o' || c == 'O') {
07478
07479 c = nextc();
07480 if (c == -1 || c == '_' || !ISDIGIT(c)) {
07481 no_digits();
07482 }
07483 }
07484 if (c >= '0' && c <= '7') {
07485
07486 octal_number:
07487 do {
07488 if (c == '_') {
07489 if (nondigit) break;
07490 nondigit = c;
07491 continue;
07492 }
07493 if (c < '0' || c > '9') break;
07494 if (c > '7') goto invalid_octal;
07495 nondigit = 0;
07496 tokadd(c);
07497 } while ((c = nextc()) != -1);
07498 if (toklen() > start) {
07499 pushback(c);
07500 tokfix();
07501 if (nondigit) goto trailing_uc;
07502 set_yylval_literal(rb_cstr_to_inum(tok(), 8, FALSE));
07503 return tINTEGER;
07504 }
07505 if (nondigit) {
07506 pushback(c);
07507 goto trailing_uc;
07508 }
07509 }
07510 if (c > '7' && c <= '9') {
07511 invalid_octal:
07512 yyerror("Invalid octal digit");
07513 }
07514 else if (c == '.' || c == 'e' || c == 'E') {
07515 tokadd('0');
07516 }
07517 else {
07518 pushback(c);
07519 set_yylval_literal(INT2FIX(0));
07520 return tINTEGER;
07521 }
07522 }
07523
07524 for (;;) {
07525 switch (c) {
07526 case '0': case '1': case '2': case '3': case '4':
07527 case '5': case '6': case '7': case '8': case '9':
07528 nondigit = 0;
07529 tokadd(c);
07530 break;
07531
07532 case '.':
07533 if (nondigit) goto trailing_uc;
07534 if (seen_point || seen_e) {
07535 goto decode_num;
07536 }
07537 else {
07538 int c0 = nextc();
07539 if (c0 == -1 || !ISDIGIT(c0)) {
07540 pushback(c0);
07541 goto decode_num;
07542 }
07543 c = c0;
07544 }
07545 tokadd('.');
07546 tokadd(c);
07547 is_float++;
07548 seen_point++;
07549 nondigit = 0;
07550 break;
07551
07552 case 'e':
07553 case 'E':
07554 if (nondigit) {
07555 pushback(c);
07556 c = nondigit;
07557 goto decode_num;
07558 }
07559 if (seen_e) {
07560 goto decode_num;
07561 }
07562 tokadd(c);
07563 seen_e++;
07564 is_float++;
07565 nondigit = c;
07566 c = nextc();
07567 if (c != '-' && c != '+') continue;
07568 tokadd(c);
07569 nondigit = c;
07570 break;
07571
07572 case '_':
07573 if (nondigit) goto decode_num;
07574 nondigit = c;
07575 break;
07576
07577 default:
07578 goto decode_num;
07579 }
07580 c = nextc();
07581 }
07582
07583 decode_num:
07584 pushback(c);
07585 if (nondigit) {
07586 char tmp[30];
07587 trailing_uc:
07588 snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
07589 yyerror(tmp);
07590 }
07591 tokfix();
07592 if (is_float) {
07593 double d = strtod(tok(), 0);
07594 if (errno == ERANGE) {
07595 rb_warningS("Float %s out of range", tok());
07596 errno = 0;
07597 }
07598 set_yylval_literal(DBL2NUM(d));
07599 return tFLOAT;
07600 }
07601 set_yylval_literal(rb_cstr_to_inum(tok(), 10, FALSE));
07602 return tINTEGER;
07603 }
07604
07605 case ')':
07606 case ']':
07607 paren_nest--;
07608 case '}':
07609 COND_LEXPOP();
07610 CMDARG_LEXPOP();
07611 if (c == ')')
07612 lex_state = EXPR_ENDFN;
07613 else
07614 lex_state = EXPR_ENDARG;
07615 if (c == '}') {
07616 if (!brace_nest--) c = tSTRING_DEND;
07617 }
07618 return c;
07619
07620 case ':':
07621 c = nextc();
07622 if (c == ':') {
07623 if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
07624 lex_state = EXPR_BEG;
07625 return tCOLON3;
07626 }
07627 lex_state = EXPR_DOT;
07628 return tCOLON2;
07629 }
07630 if (IS_END() || ISSPACE(c)) {
07631 pushback(c);
07632 warn_balanced(":", "symbol literal");
07633 lex_state = EXPR_BEG;
07634 return ':';
07635 }
07636 switch (c) {
07637 case '\'':
07638 lex_strterm = NEW_STRTERM(str_ssym, c, 0);
07639 break;
07640 case '"':
07641 lex_strterm = NEW_STRTERM(str_dsym, c, 0);
07642 break;
07643 default:
07644 pushback(c);
07645 break;
07646 }
07647 lex_state = EXPR_FNAME;
07648 return tSYMBEG;
07649
07650 case '/':
07651 if (IS_lex_state(EXPR_BEG_ANY)) {
07652 lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
07653 return tREGEXP_BEG;
07654 }
07655 if ((c = nextc()) == '=') {
07656 set_yylval_id('/');
07657 lex_state = EXPR_BEG;
07658 return tOP_ASGN;
07659 }
07660 pushback(c);
07661 if (IS_SPCARG(c)) {
07662 (void)arg_ambiguous();
07663 lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
07664 return tREGEXP_BEG;
07665 }
07666 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07667 warn_balanced("/", "regexp literal");
07668 return '/';
07669
07670 case '^':
07671 if ((c = nextc()) == '=') {
07672 set_yylval_id('^');
07673 lex_state = EXPR_BEG;
07674 return tOP_ASGN;
07675 }
07676 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07677 pushback(c);
07678 return '^';
07679
07680 case ';':
07681 lex_state = EXPR_BEG;
07682 command_start = TRUE;
07683 return ';';
07684
07685 case ',':
07686 lex_state = EXPR_BEG;
07687 return ',';
07688
07689 case '~':
07690 if (IS_AFTER_OPERATOR()) {
07691 if ((c = nextc()) != '@') {
07692 pushback(c);
07693 }
07694 lex_state = EXPR_ARG;
07695 }
07696 else {
07697 lex_state = EXPR_BEG;
07698 }
07699 return '~';
07700
07701 case '(':
07702 if (IS_BEG()) {
07703 c = tLPAREN;
07704 }
07705 else if (IS_SPCARG(-1)) {
07706 c = tLPAREN_ARG;
07707 }
07708 paren_nest++;
07709 COND_PUSH(0);
07710 CMDARG_PUSH(0);
07711 lex_state = EXPR_BEG;
07712 return c;
07713
07714 case '[':
07715 paren_nest++;
07716 if (IS_AFTER_OPERATOR()) {
07717 lex_state = EXPR_ARG;
07718 if ((c = nextc()) == ']') {
07719 if ((c = nextc()) == '=') {
07720 return tASET;
07721 }
07722 pushback(c);
07723 return tAREF;
07724 }
07725 pushback(c);
07726 return '[';
07727 }
07728 else if (IS_BEG()) {
07729 c = tLBRACK;
07730 }
07731 else if (IS_ARG() && space_seen) {
07732 c = tLBRACK;
07733 }
07734 lex_state = EXPR_BEG;
07735 COND_PUSH(0);
07736 CMDARG_PUSH(0);
07737 return c;
07738
07739 case '{':
07740 ++brace_nest;
07741 if (lpar_beg && lpar_beg == paren_nest) {
07742 lex_state = EXPR_BEG;
07743 lpar_beg = 0;
07744 --paren_nest;
07745 COND_PUSH(0);
07746 CMDARG_PUSH(0);
07747 return tLAMBEG;
07748 }
07749 if (IS_ARG() || IS_lex_state(EXPR_END | EXPR_ENDFN))
07750 c = '{';
07751 else if (IS_lex_state(EXPR_ENDARG))
07752 c = tLBRACE_ARG;
07753 else
07754 c = tLBRACE;
07755 COND_PUSH(0);
07756 CMDARG_PUSH(0);
07757 lex_state = EXPR_BEG;
07758 if (c != tLBRACE) command_start = TRUE;
07759 return c;
07760
07761 case '\\':
07762 c = nextc();
07763 if (c == '\n') {
07764 space_seen = 1;
07765 #ifdef RIPPER
07766 ripper_dispatch_scan_event(parser, tSP);
07767 #endif
07768 goto retry;
07769 }
07770 pushback(c);
07771 return '\\';
07772
07773 case '%':
07774 if (IS_lex_state(EXPR_BEG_ANY)) {
07775 int term;
07776 int paren;
07777
07778 c = nextc();
07779 quotation:
07780 if (c == -1 || !ISALNUM(c)) {
07781 term = c;
07782 c = 'Q';
07783 }
07784 else {
07785 term = nextc();
07786 if (rb_enc_isalnum(term, current_enc) || !parser_isascii()) {
07787 yyerror("unknown type of %string");
07788 return 0;
07789 }
07790 }
07791 if (c == -1 || term == -1) {
07792 compile_error(PARSER_ARG "unterminated quoted string meets end of file");
07793 return 0;
07794 }
07795 paren = term;
07796 if (term == '(') term = ')';
07797 else if (term == '[') term = ']';
07798 else if (term == '{') term = '}';
07799 else if (term == '<') term = '>';
07800 else paren = 0;
07801
07802 switch (c) {
07803 case 'Q':
07804 lex_strterm = NEW_STRTERM(str_dquote, term, paren);
07805 return tSTRING_BEG;
07806
07807 case 'q':
07808 lex_strterm = NEW_STRTERM(str_squote, term, paren);
07809 return tSTRING_BEG;
07810
07811 case 'W':
07812 lex_strterm = NEW_STRTERM(str_dword, term, paren);
07813 do {c = nextc();} while (ISSPACE(c));
07814 pushback(c);
07815 return tWORDS_BEG;
07816
07817 case 'w':
07818 lex_strterm = NEW_STRTERM(str_sword, term, paren);
07819 do {c = nextc();} while (ISSPACE(c));
07820 pushback(c);
07821 return tQWORDS_BEG;
07822
07823 case 'I':
07824 lex_strterm = NEW_STRTERM(str_dword, term, paren);
07825 do {c = nextc();} while (ISSPACE(c));
07826 pushback(c);
07827 return tSYMBOLS_BEG;
07828
07829 case 'i':
07830 lex_strterm = NEW_STRTERM(str_sword, term, paren);
07831 do {c = nextc();} while (ISSPACE(c));
07832 pushback(c);
07833 return tQSYMBOLS_BEG;
07834
07835 case 'x':
07836 lex_strterm = NEW_STRTERM(str_xquote, term, paren);
07837 return tXSTRING_BEG;
07838
07839 case 'r':
07840 lex_strterm = NEW_STRTERM(str_regexp, term, paren);
07841 return tREGEXP_BEG;
07842
07843 case 's':
07844 lex_strterm = NEW_STRTERM(str_ssym, term, paren);
07845 lex_state = EXPR_FNAME;
07846 return tSYMBEG;
07847
07848 default:
07849 yyerror("unknown type of %string");
07850 return 0;
07851 }
07852 }
07853 if ((c = nextc()) == '=') {
07854 set_yylval_id('%');
07855 lex_state = EXPR_BEG;
07856 return tOP_ASGN;
07857 }
07858 if (IS_SPCARG(c)) {
07859 goto quotation;
07860 }
07861 lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
07862 pushback(c);
07863 warn_balanced("%%", "string literal");
07864 return '%';
07865
07866 case '$':
07867 lex_state = EXPR_END;
07868 newtok();
07869 c = nextc();
07870 switch (c) {
07871 case '_':
07872 c = nextc();
07873 if (parser_is_identchar()) {
07874 tokadd('$');
07875 tokadd('_');
07876 break;
07877 }
07878 pushback(c);
07879 c = '_';
07880
07881 case '~':
07882 case '*':
07883 case '$':
07884 case '?':
07885 case '!':
07886 case '@':
07887 case '/':
07888 case '\\':
07889 case ';':
07890 case ',':
07891 case '.':
07892 case '=':
07893 case ':':
07894 case '<':
07895 case '>':
07896 case '\"':
07897 tokadd('$');
07898 tokadd(c);
07899 tokfix();
07900 set_yylval_name(rb_intern(tok()));
07901 return tGVAR;
07902
07903 case '-':
07904 tokadd('$');
07905 tokadd(c);
07906 c = nextc();
07907 if (parser_is_identchar()) {
07908 if (tokadd_mbchar(c) == -1) return 0;
07909 }
07910 else {
07911 pushback(c);
07912 }
07913 gvar:
07914 tokfix();
07915 set_yylval_name(rb_intern(tok()));
07916 return tGVAR;
07917
07918 case '&':
07919 case '`':
07920 case '\'':
07921 case '+':
07922 if (IS_lex_state_for(last_state, EXPR_FNAME)) {
07923 tokadd('$');
07924 tokadd(c);
07925 goto gvar;
07926 }
07927 set_yylval_node(NEW_BACK_REF(c));
07928 return tBACK_REF;
07929
07930 case '1': case '2': case '3':
07931 case '4': case '5': case '6':
07932 case '7': case '8': case '9':
07933 tokadd('$');
07934 do {
07935 tokadd(c);
07936 c = nextc();
07937 } while (c != -1 && ISDIGIT(c));
07938 pushback(c);
07939 if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
07940 tokfix();
07941 set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
07942 return tNTH_REF;
07943
07944 default:
07945 if (!parser_is_identchar()) {
07946 pushback(c);
07947 compile_error(PARSER_ARG "`$%c' is not allowed as a global variable name", c);
07948 return 0;
07949 }
07950 case '0':
07951 tokadd('$');
07952 }
07953 break;
07954
07955 case '@':
07956 c = nextc();
07957 newtok();
07958 tokadd('@');
07959 if (c == '@') {
07960 tokadd('@');
07961 c = nextc();
07962 }
07963 if (c != -1 && (ISDIGIT(c) || !parser_is_identchar())) {
07964 pushback(c);
07965 if (tokidx == 1) {
07966 compile_error(PARSER_ARG "`@%c' is not allowed as an instance variable name", c);
07967 }
07968 else {
07969 compile_error(PARSER_ARG "`@@%c' is not allowed as a class variable name", c);
07970 }
07971 return 0;
07972 }
07973 break;
07974
07975 case '_':
07976 if (was_bol() && whole_match_p("__END__", 7, 0)) {
07977 ruby__end__seen = 1;
07978 parser->eofp = Qtrue;
07979 #ifndef RIPPER
07980 return -1;
07981 #else
07982 lex_goto_eol(parser);
07983 ripper_dispatch_scan_event(parser, k__END__);
07984 return 0;
07985 #endif
07986 }
07987 newtok();
07988 break;
07989
07990 default:
07991 if (!parser_is_identchar()) {
07992 compile_error(PARSER_ARG "Invalid char `\\x%02X' in expression", c);
07993 goto retry;
07994 }
07995
07996 newtok();
07997 break;
07998 }
07999
08000 mb = ENC_CODERANGE_7BIT;
08001 do {
08002 if (!ISASCII(c)) mb = ENC_CODERANGE_UNKNOWN;
08003 if (tokadd_mbchar(c) == -1) return 0;
08004 c = nextc();
08005 } while (parser_is_identchar());
08006 switch (tok()[0]) {
08007 case '@': case '$':
08008 pushback(c);
08009 break;
08010 default:
08011 if ((c == '!' || c == '?') && !peek('=')) {
08012 tokadd(c);
08013 }
08014 else {
08015 pushback(c);
08016 }
08017 }
08018 tokfix();
08019
08020 {
08021 int result = 0;
08022
08023 last_state = lex_state;
08024 switch (tok()[0]) {
08025 case '$':
08026 lex_state = EXPR_END;
08027 result = tGVAR;
08028 break;
08029 case '@':
08030 lex_state = EXPR_END;
08031 if (tok()[1] == '@')
08032 result = tCVAR;
08033 else
08034 result = tIVAR;
08035 break;
08036
08037 default:
08038 if (toklast() == '!' || toklast() == '?') {
08039 result = tFID;
08040 }
08041 else {
08042 if (IS_lex_state(EXPR_FNAME)) {
08043 if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
08044 (!peek('=') || (peek_n('>', 1)))) {
08045 result = tIDENTIFIER;
08046 tokadd(c);
08047 tokfix();
08048 }
08049 else {
08050 pushback(c);
08051 }
08052 }
08053 if (result == 0 && ISUPPER(tok()[0])) {
08054 result = tCONSTANT;
08055 }
08056 else {
08057 result = tIDENTIFIER;
08058 }
08059 }
08060
08061 if (IS_LABEL_POSSIBLE()) {
08062 if (IS_LABEL_SUFFIX(0)) {
08063 lex_state = EXPR_BEG;
08064 nextc();
08065 set_yylval_name(TOK_INTERN(!ENC_SINGLE(mb)));
08066 return tLABEL;
08067 }
08068 }
08069 if (mb == ENC_CODERANGE_7BIT && !IS_lex_state(EXPR_DOT)) {
08070 const struct kwtable *kw;
08071
08072
08073 kw = rb_reserved_word(tok(), toklen());
08074 if (kw) {
08075 enum lex_state_e state = lex_state;
08076 lex_state = kw->state;
08077 if (state == EXPR_FNAME) {
08078 set_yylval_name(rb_intern(kw->name));
08079 return kw->id[0];
08080 }
08081 if (lex_state == EXPR_BEG) {
08082 command_start = TRUE;
08083 }
08084 if (kw->id[0] == keyword_do) {
08085 if (lpar_beg && lpar_beg == paren_nest) {
08086 lpar_beg = 0;
08087 --paren_nest;
08088 return keyword_do_LAMBDA;
08089 }
08090 if (COND_P()) return keyword_do_cond;
08091 if (CMDARG_P() && state != EXPR_CMDARG)
08092 return keyword_do_block;
08093 if (state & (EXPR_BEG | EXPR_ENDARG))
08094 return keyword_do_block;
08095 return keyword_do;
08096 }
08097 if (state & (EXPR_BEG | EXPR_VALUE))
08098 return kw->id[0];
08099 else {
08100 if (kw->id[0] != kw->id[1])
08101 lex_state = EXPR_BEG;
08102 return kw->id[1];
08103 }
08104 }
08105 }
08106
08107 if (IS_lex_state(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT)) {
08108 if (cmd_state) {
08109 lex_state = EXPR_CMDARG;
08110 }
08111 else {
08112 lex_state = EXPR_ARG;
08113 }
08114 }
08115 else if (lex_state == EXPR_FNAME) {
08116 lex_state = EXPR_ENDFN;
08117 }
08118 else {
08119 lex_state = EXPR_END;
08120 }
08121 }
08122 {
08123 ID ident = TOK_INTERN(!ENC_SINGLE(mb));
08124
08125 set_yylval_name(ident);
08126 if (!IS_lex_state_for(last_state, EXPR_DOT|EXPR_FNAME) &&
08127 is_local_id(ident) && lvar_defined(ident)) {
08128 lex_state = EXPR_END;
08129 }
08130 }
08131 return result;
08132 }
08133 }
08134
08135 #if YYPURE
08136 static int
08137 yylex(void *lval, void *p)
08138 #else
08139 yylex(void *p)
08140 #endif
08141 {
08142 struct parser_params *parser = (struct parser_params*)p;
08143 int t;
08144
08145 #if YYPURE
08146 parser->parser_yylval = lval;
08147 parser->parser_yylval->val = Qundef;
08148 #endif
08149 t = parser_yylex(parser);
08150 #ifdef RIPPER
08151 if (!NIL_P(parser->delayed)) {
08152 ripper_dispatch_delayed_token(parser, t);
08153 return t;
08154 }
08155 if (t != 0)
08156 ripper_dispatch_scan_event(parser, t);
08157 #endif
08158
08159 return t;
08160 }
08161
08162 #ifndef RIPPER
08163 static NODE*
08164 node_newnode(struct parser_params *parser, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
08165 {
08166 NODE *n = (rb_node_newnode)(type, a0, a1, a2);
08167 nd_set_line(n, ruby_sourceline);
08168 return n;
08169 }
08170
08171 static enum node_type
08172 nodetype(NODE *node)
08173 {
08174 return (enum node_type)nd_type(node);
08175 }
08176
08177 static int
08178 nodeline(NODE *node)
08179 {
08180 return nd_line(node);
08181 }
08182
08183 static NODE*
08184 newline_node(NODE *node)
08185 {
08186 if (node) {
08187 node = remove_begin(node);
08188 node->flags |= NODE_FL_NEWLINE;
08189 }
08190 return node;
08191 }
08192
08193 static void
08194 fixpos(NODE *node, NODE *orig)
08195 {
08196 if (!node) return;
08197 if (!orig) return;
08198 if (orig == (NODE*)1) return;
08199 nd_set_line(node, nd_line(orig));
08200 }
08201
08202 static void
08203 parser_warning(struct parser_params *parser, NODE *node, const char *mesg)
08204 {
08205 rb_compile_warning(ruby_sourcefile, nd_line(node), "%s", mesg);
08206 }
08207 #define parser_warning(node, mesg) parser_warning(parser, (node), (mesg))
08208
08209 static void
08210 parser_warn(struct parser_params *parser, NODE *node, const char *mesg)
08211 {
08212 rb_compile_warn(ruby_sourcefile, nd_line(node), "%s", mesg);
08213 }
08214 #define parser_warn(node, mesg) parser_warn(parser, (node), (mesg))
08215
08216 static NODE*
08217 block_append_gen(struct parser_params *parser, NODE *head, NODE *tail)
08218 {
08219 NODE *end, *h = head, *nd;
08220
08221 if (tail == 0) return head;
08222
08223 if (h == 0) return tail;
08224 switch (nd_type(h)) {
08225 case NODE_LIT:
08226 case NODE_STR:
08227 case NODE_SELF:
08228 case NODE_TRUE:
08229 case NODE_FALSE:
08230 case NODE_NIL:
08231 parser_warning(h, "unused literal ignored");
08232 return tail;
08233 default:
08234 h = end = NEW_BLOCK(head);
08235 end->nd_end = end;
08236 fixpos(end, head);
08237 head = end;
08238 break;
08239 case NODE_BLOCK:
08240 end = h->nd_end;
08241 break;
08242 }
08243
08244 nd = end->nd_head;
08245 switch (nd_type(nd)) {
08246 case NODE_RETURN:
08247 case NODE_BREAK:
08248 case NODE_NEXT:
08249 case NODE_REDO:
08250 case NODE_RETRY:
08251 if (RTEST(ruby_verbose)) {
08252 parser_warning(tail, "statement not reached");
08253 }
08254 break;
08255
08256 default:
08257 break;
08258 }
08259
08260 if (nd_type(tail) != NODE_BLOCK) {
08261 tail = NEW_BLOCK(tail);
08262 tail->nd_end = tail;
08263 }
08264 end->nd_next = tail;
08265 h->nd_end = tail->nd_end;
08266 return head;
08267 }
08268
08269
08270 static NODE*
08271 list_append_gen(struct parser_params *parser, NODE *list, NODE *item)
08272 {
08273 NODE *last;
08274
08275 if (list == 0) return NEW_LIST(item);
08276 if (list->nd_next) {
08277 last = list->nd_next->nd_end;
08278 }
08279 else {
08280 last = list;
08281 }
08282
08283 list->nd_alen += 1;
08284 last->nd_next = NEW_LIST(item);
08285 list->nd_next->nd_end = last->nd_next;
08286 return list;
08287 }
08288
08289
08290 static NODE*
08291 list_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
08292 {
08293 NODE *last;
08294
08295 if (head->nd_next) {
08296 last = head->nd_next->nd_end;
08297 }
08298 else {
08299 last = head;
08300 }
08301
08302 head->nd_alen += tail->nd_alen;
08303 last->nd_next = tail;
08304 if (tail->nd_next) {
08305 head->nd_next->nd_end = tail->nd_next->nd_end;
08306 }
08307 else {
08308 head->nd_next->nd_end = tail;
08309 }
08310
08311 return head;
08312 }
08313
08314 static int
08315 literal_concat0(struct parser_params *parser, VALUE head, VALUE tail)
08316 {
08317 if (NIL_P(tail)) return 1;
08318 if (!rb_enc_compatible(head, tail)) {
08319 compile_error(PARSER_ARG "string literal encodings differ (%s / %s)",
08320 rb_enc_name(rb_enc_get(head)),
08321 rb_enc_name(rb_enc_get(tail)));
08322 rb_str_resize(head, 0);
08323 rb_str_resize(tail, 0);
08324 return 0;
08325 }
08326 rb_str_buf_append(head, tail);
08327 return 1;
08328 }
08329
08330
08331 static NODE *
08332 literal_concat_gen(struct parser_params *parser, NODE *head, NODE *tail)
08333 {
08334 enum node_type htype;
08335 NODE *headlast;
08336 VALUE lit;
08337
08338 if (!head) return tail;
08339 if (!tail) return head;
08340
08341 htype = nd_type(head);
08342 if (htype == NODE_EVSTR) {
08343 NODE *node = NEW_DSTR(Qnil);
08344 head = list_append(node, head);
08345 htype = NODE_DSTR;
08346 }
08347 switch (nd_type(tail)) {
08348 case NODE_STR:
08349 if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
08350 nd_type(headlast) == NODE_STR) {
08351 htype = NODE_STR;
08352 lit = headlast->nd_lit;
08353 }
08354 else {
08355 lit = head->nd_lit;
08356 }
08357 if (htype == NODE_STR) {
08358 if (!literal_concat0(parser, lit, tail->nd_lit)) {
08359 error:
08360 rb_gc_force_recycle((VALUE)head);
08361 rb_gc_force_recycle((VALUE)tail);
08362 return 0;
08363 }
08364 rb_gc_force_recycle((VALUE)tail);
08365 }
08366 else {
08367 list_append(head, tail);
08368 }
08369 break;
08370
08371 case NODE_DSTR:
08372 if (htype == NODE_STR) {
08373 if (!literal_concat0(parser, head->nd_lit, tail->nd_lit))
08374 goto error;
08375 tail->nd_lit = head->nd_lit;
08376 rb_gc_force_recycle((VALUE)head);
08377 head = tail;
08378 }
08379 else if (NIL_P(tail->nd_lit)) {
08380 append:
08381 head->nd_alen += tail->nd_alen - 1;
08382 head->nd_next->nd_end->nd_next = tail->nd_next;
08383 head->nd_next->nd_end = tail->nd_next->nd_end;
08384 rb_gc_force_recycle((VALUE)tail);
08385 }
08386 else if (htype == NODE_DSTR && (headlast = head->nd_next->nd_end->nd_head) &&
08387 nd_type(headlast) == NODE_STR) {
08388 lit = headlast->nd_lit;
08389 if (!literal_concat0(parser, lit, tail->nd_lit))
08390 goto error;
08391 tail->nd_lit = Qnil;
08392 goto append;
08393 }
08394 else {
08395 nd_set_type(tail, NODE_ARRAY);
08396 tail->nd_head = NEW_STR(tail->nd_lit);
08397 list_concat(head, tail);
08398 }
08399 break;
08400
08401 case NODE_EVSTR:
08402 if (htype == NODE_STR) {
08403 nd_set_type(head, NODE_DSTR);
08404 head->nd_alen = 1;
08405 }
08406 list_append(head, tail);
08407 break;
08408 }
08409 return head;
08410 }
08411
08412 static NODE *
08413 evstr2dstr_gen(struct parser_params *parser, NODE *node)
08414 {
08415 if (nd_type(node) == NODE_EVSTR) {
08416 node = list_append(NEW_DSTR(Qnil), node);
08417 }
08418 return node;
08419 }
08420
08421 static NODE *
08422 new_evstr_gen(struct parser_params *parser, NODE *node)
08423 {
08424 NODE *head = node;
08425
08426 if (node) {
08427 switch (nd_type(node)) {
08428 case NODE_STR: case NODE_DSTR: case NODE_EVSTR:
08429 return node;
08430 }
08431 }
08432 return NEW_EVSTR(head);
08433 }
08434
08435 static NODE *
08436 call_bin_op_gen(struct parser_params *parser, NODE *recv, ID id, NODE *arg1)
08437 {
08438 value_expr(recv);
08439 value_expr(arg1);
08440 return NEW_CALL(recv, id, NEW_LIST(arg1));
08441 }
08442
08443 static NODE *
08444 call_uni_op_gen(struct parser_params *parser, NODE *recv, ID id)
08445 {
08446 value_expr(recv);
08447 return NEW_CALL(recv, id, 0);
08448 }
08449
08450 static NODE*
08451 match_op_gen(struct parser_params *parser, NODE *node1, NODE *node2)
08452 {
08453 value_expr(node1);
08454 value_expr(node2);
08455 if (node1) {
08456 switch (nd_type(node1)) {
08457 case NODE_DREGX:
08458 case NODE_DREGX_ONCE:
08459 return NEW_MATCH2(node1, node2);
08460
08461 case NODE_LIT:
08462 if (RB_TYPE_P(node1->nd_lit, T_REGEXP)) {
08463 return NEW_MATCH2(node1, node2);
08464 }
08465 }
08466 }
08467
08468 if (node2) {
08469 switch (nd_type(node2)) {
08470 case NODE_DREGX:
08471 case NODE_DREGX_ONCE:
08472 return NEW_MATCH3(node2, node1);
08473
08474 case NODE_LIT:
08475 if (RB_TYPE_P(node2->nd_lit, T_REGEXP)) {
08476 return NEW_MATCH3(node2, node1);
08477 }
08478 }
08479 }
08480
08481 return NEW_CALL(node1, tMATCH, NEW_LIST(node2));
08482 }
08483
08484 static NODE*
08485 gettable_gen(struct parser_params *parser, ID id)
08486 {
08487 switch (id) {
08488 case keyword_self:
08489 return NEW_SELF();
08490 case keyword_nil:
08491 return NEW_NIL();
08492 case keyword_true:
08493 return NEW_TRUE();
08494 case keyword_false:
08495 return NEW_FALSE();
08496 case keyword__FILE__:
08497 return NEW_STR(rb_str_dup(ruby_sourcefile_string));
08498 case keyword__LINE__:
08499 return NEW_LIT(INT2FIX(tokline));
08500 case keyword__ENCODING__:
08501 return NEW_LIT(rb_enc_from_encoding(current_enc));
08502 }
08503 switch (id_type(id)) {
08504 case ID_LOCAL:
08505 if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id);
08506 if (local_id(id)) return NEW_LVAR(id);
08507
08508 return NEW_VCALL(id);
08509 case ID_GLOBAL:
08510 return NEW_GVAR(id);
08511 case ID_INSTANCE:
08512 return NEW_IVAR(id);
08513 case ID_CONST:
08514 return NEW_CONST(id);
08515 case ID_CLASS:
08516 return NEW_CVAR(id);
08517 }
08518 compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
08519 return 0;
08520 }
08521 #else
08522 static int
08523 id_is_var_gen(struct parser_params *parser, ID id)
08524 {
08525 if (is_notop_id(id)) {
08526 switch (id & ID_SCOPE_MASK) {
08527 case ID_GLOBAL: case ID_INSTANCE: case ID_CONST: case ID_CLASS:
08528 return 1;
08529 case ID_LOCAL:
08530 if (dyna_in_block() && dvar_defined(id)) return 1;
08531 if (local_id(id)) return 1;
08532
08533 return 0;
08534 }
08535 }
08536 compile_error(PARSER_ARG "identifier %s is not valid to get", rb_id2name(id));
08537 return 0;
08538 }
08539 #endif
08540
08541 #if PARSER_DEBUG
08542 static const char *
08543 lex_state_name(enum lex_state_e state)
08544 {
08545 static const char names[][12] = {
08546 "EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
08547 "EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
08548 "EXPR_VALUE",
08549 };
08550
08551 if ((unsigned)state & ~(~0u << EXPR_MAX_STATE))
08552 return names[ffs(state)];
08553 return NULL;
08554 }
08555 #endif
08556
08557 #ifdef RIPPER
08558 static VALUE
08559 assignable_gen(struct parser_params *parser, VALUE lhs)
08560 #else
08561 static NODE*
08562 assignable_gen(struct parser_params *parser, ID id, NODE *val)
08563 #endif
08564 {
08565 #ifdef RIPPER
08566 ID id = get_id(lhs);
08567 # define assignable_result(x) get_value(lhs)
08568 # define parser_yyerror(parser, x) dispatch1(assign_error, lhs)
08569 #else
08570 # define assignable_result(x) (x)
08571 #endif
08572 if (!id) return assignable_result(0);
08573 switch (id) {
08574 case keyword_self:
08575 yyerror("Can't change the value of self");
08576 goto error;
08577 case keyword_nil:
08578 yyerror("Can't assign to nil");
08579 goto error;
08580 case keyword_true:
08581 yyerror("Can't assign to true");
08582 goto error;
08583 case keyword_false:
08584 yyerror("Can't assign to false");
08585 goto error;
08586 case keyword__FILE__:
08587 yyerror("Can't assign to __FILE__");
08588 goto error;
08589 case keyword__LINE__:
08590 yyerror("Can't assign to __LINE__");
08591 goto error;
08592 case keyword__ENCODING__:
08593 yyerror("Can't assign to __ENCODING__");
08594 goto error;
08595 }
08596 switch (id_type(id)) {
08597 case ID_LOCAL:
08598 if (dyna_in_block()) {
08599 if (dvar_curr(id)) {
08600 return assignable_result(NEW_DASGN_CURR(id, val));
08601 }
08602 else if (dvar_defined(id)) {
08603 return assignable_result(NEW_DASGN(id, val));
08604 }
08605 else if (local_id(id)) {
08606 return assignable_result(NEW_LASGN(id, val));
08607 }
08608 else {
08609 dyna_var(id);
08610 return assignable_result(NEW_DASGN_CURR(id, val));
08611 }
08612 }
08613 else {
08614 if (!local_id(id)) {
08615 local_var(id);
08616 }
08617 return assignable_result(NEW_LASGN(id, val));
08618 }
08619 break;
08620 case ID_GLOBAL:
08621 return assignable_result(NEW_GASGN(id, val));
08622 case ID_INSTANCE:
08623 return assignable_result(NEW_IASGN(id, val));
08624 case ID_CONST:
08625 if (!in_def && !in_single)
08626 return assignable_result(NEW_CDECL(id, val, 0));
08627 yyerror("dynamic constant assignment");
08628 break;
08629 case ID_CLASS:
08630 return assignable_result(NEW_CVASGN(id, val));
08631 default:
08632 compile_error(PARSER_ARG "identifier %s is not valid to set", rb_id2name(id));
08633 }
08634 error:
08635 return assignable_result(0);
08636 #undef assignable_result
08637 #undef parser_yyerror
08638 }
08639
08640 static int
08641 is_private_local_id(ID name)
08642 {
08643 VALUE s;
08644 if (name == idUScore) return 1;
08645 if (!is_local_id(name)) return 0;
08646 s = rb_id2str(name);
08647 if (!s) return 0;
08648 return RSTRING_PTR(s)[0] == '_';
08649 }
08650
08651 #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1))
08652
08653 static ID
08654 shadowing_lvar_gen(struct parser_params *parser, ID name)
08655 {
08656 if (is_private_local_id(name)) return name;
08657 if (dyna_in_block()) {
08658 if (dvar_curr(name)) {
08659 yyerror("duplicated argument name");
08660 }
08661 else if (dvar_defined_get(name) || local_id(name)) {
08662 rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
08663 vtable_add(lvtbl->vars, name);
08664 if (lvtbl->used) {
08665 vtable_add(lvtbl->used, (ID)ruby_sourceline | LVAR_USED);
08666 }
08667 }
08668 }
08669 else {
08670 if (local_id(name)) {
08671 yyerror("duplicated argument name");
08672 }
08673 }
08674 return name;
08675 }
08676
08677 static void
08678 new_bv_gen(struct parser_params *parser, ID name)
08679 {
08680 if (!name) return;
08681 if (!is_local_id(name)) {
08682 compile_error(PARSER_ARG "invalid local variable - %s",
08683 rb_id2name(name));
08684 return;
08685 }
08686 shadowing_lvar(name);
08687 dyna_var(name);
08688 }
08689
08690 #ifndef RIPPER
08691 static NODE *
08692 aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
08693 {
08694 if (recv && nd_type(recv) == NODE_SELF)
08695 recv = (NODE *)1;
08696 return NEW_ATTRASGN(recv, tASET, idx);
08697 }
08698
08699 static void
08700 block_dup_check_gen(struct parser_params *parser, NODE *node1, NODE *node2)
08701 {
08702 if (node2 && node1 && nd_type(node1) == NODE_BLOCK_PASS) {
08703 compile_error(PARSER_ARG "both block arg and actual block given");
08704 }
08705 }
08706
08707 static const char id_type_names[][9] = {
08708 "LOCAL",
08709 "INSTANCE",
08710 "",
08711 "GLOBAL",
08712 "ATTRSET",
08713 "CONST",
08714 "CLASS",
08715 "JUNK",
08716 };
08717
08718 ID
08719 rb_id_attrset(ID id)
08720 {
08721 if (!is_notop_id(id)) {
08722 switch (id) {
08723 case tAREF: case tASET:
08724 return tASET;
08725 }
08726 rb_name_error(id, "cannot make operator ID :%s attrset", rb_id2name(id));
08727 }
08728 else {
08729 int scope = (int)(id & ID_SCOPE_MASK);
08730 switch (scope) {
08731 case ID_LOCAL: case ID_INSTANCE: case ID_GLOBAL:
08732 case ID_CONST: case ID_CLASS: case ID_JUNK:
08733 break;
08734 case ID_ATTRSET:
08735 return id;
08736 default:
08737 rb_name_error(id, "cannot make %s ID %+"PRIsVALUE" attrset",
08738 id_type_names[scope], ID2SYM(id));
08739
08740 }
08741 }
08742 id &= ~ID_SCOPE_MASK;
08743 id |= ID_ATTRSET;
08744 return id;
08745 }
08746
08747 static NODE *
08748 attrset_gen(struct parser_params *parser, NODE *recv, ID id)
08749 {
08750 if (recv && nd_type(recv) == NODE_SELF)
08751 recv = (NODE *)1;
08752 return NEW_ATTRASGN(recv, rb_id_attrset(id), 0);
08753 }
08754
08755 static void
08756 rb_backref_error_gen(struct parser_params *parser, NODE *node)
08757 {
08758 switch (nd_type(node)) {
08759 case NODE_NTH_REF:
08760 compile_error(PARSER_ARG "Can't set variable $%ld", node->nd_nth);
08761 break;
08762 case NODE_BACK_REF:
08763 compile_error(PARSER_ARG "Can't set variable $%c", (int)node->nd_nth);
08764 break;
08765 }
08766 }
08767
08768 static NODE *
08769 arg_concat_gen(struct parser_params *parser, NODE *node1, NODE *node2)
08770 {
08771 if (!node2) return node1;
08772 switch (nd_type(node1)) {
08773 case NODE_BLOCK_PASS:
08774 if (node1->nd_head)
08775 node1->nd_head = arg_concat(node1->nd_head, node2);
08776 else
08777 node1->nd_head = NEW_LIST(node2);
08778 return node1;
08779 case NODE_ARGSPUSH:
08780 if (nd_type(node2) != NODE_ARRAY) break;
08781 node1->nd_body = list_concat(NEW_LIST(node1->nd_body), node2);
08782 nd_set_type(node1, NODE_ARGSCAT);
08783 return node1;
08784 case NODE_ARGSCAT:
08785 if (nd_type(node2) != NODE_ARRAY ||
08786 nd_type(node1->nd_body) != NODE_ARRAY) break;
08787 node1->nd_body = list_concat(node1->nd_body, node2);
08788 return node1;
08789 }
08790 return NEW_ARGSCAT(node1, node2);
08791 }
08792
08793 static NODE *
08794 arg_append_gen(struct parser_params *parser, NODE *node1, NODE *node2)
08795 {
08796 if (!node1) return NEW_LIST(node2);
08797 switch (nd_type(node1)) {
08798 case NODE_ARRAY:
08799 return list_append(node1, node2);
08800 case NODE_BLOCK_PASS:
08801 node1->nd_head = arg_append(node1->nd_head, node2);
08802 return node1;
08803 case NODE_ARGSPUSH:
08804 node1->nd_body = list_append(NEW_LIST(node1->nd_body), node2);
08805 nd_set_type(node1, NODE_ARGSCAT);
08806 return node1;
08807 }
08808 return NEW_ARGSPUSH(node1, node2);
08809 }
08810
08811 static NODE *
08812 splat_array(NODE* node)
08813 {
08814 if (nd_type(node) == NODE_SPLAT) node = node->nd_head;
08815 if (nd_type(node) == NODE_ARRAY) return node;
08816 return 0;
08817 }
08818
08819 static NODE *
08820 node_assign_gen(struct parser_params *parser, NODE *lhs, NODE *rhs)
08821 {
08822 if (!lhs) return 0;
08823
08824 switch (nd_type(lhs)) {
08825 case NODE_GASGN:
08826 case NODE_IASGN:
08827 case NODE_IASGN2:
08828 case NODE_LASGN:
08829 case NODE_DASGN:
08830 case NODE_DASGN_CURR:
08831 case NODE_MASGN:
08832 case NODE_CDECL:
08833 case NODE_CVASGN:
08834 lhs->nd_value = rhs;
08835 break;
08836
08837 case NODE_ATTRASGN:
08838 case NODE_CALL:
08839 lhs->nd_args = arg_append(lhs->nd_args, rhs);
08840 break;
08841
08842 default:
08843
08844 break;
08845 }
08846
08847 return lhs;
08848 }
08849
08850 static int
08851 value_expr_gen(struct parser_params *parser, NODE *node)
08852 {
08853 int cond = 0;
08854
08855 if (!node) {
08856 rb_warning0("empty expression");
08857 }
08858 while (node) {
08859 switch (nd_type(node)) {
08860 case NODE_DEFN:
08861 case NODE_DEFS:
08862 parser_warning(node, "void value expression");
08863 return FALSE;
08864
08865 case NODE_RETURN:
08866 case NODE_BREAK:
08867 case NODE_NEXT:
08868 case NODE_REDO:
08869 case NODE_RETRY:
08870 if (!cond) yyerror("void value expression");
08871
08872 return FALSE;
08873
08874 case NODE_BLOCK:
08875 while (node->nd_next) {
08876 node = node->nd_next;
08877 }
08878 node = node->nd_head;
08879 break;
08880
08881 case NODE_BEGIN:
08882 node = node->nd_body;
08883 break;
08884
08885 case NODE_IF:
08886 if (!node->nd_body) {
08887 node = node->nd_else;
08888 break;
08889 }
08890 else if (!node->nd_else) {
08891 node = node->nd_body;
08892 break;
08893 }
08894 if (!value_expr(node->nd_body)) return FALSE;
08895 node = node->nd_else;
08896 break;
08897
08898 case NODE_AND:
08899 case NODE_OR:
08900 cond = 1;
08901 node = node->nd_2nd;
08902 break;
08903
08904 default:
08905 return TRUE;
08906 }
08907 }
08908
08909 return TRUE;
08910 }
08911
08912 static void
08913 void_expr_gen(struct parser_params *parser, NODE *node)
08914 {
08915 const char *useless = 0;
08916
08917 if (!RTEST(ruby_verbose)) return;
08918
08919 if (!node) return;
08920 switch (nd_type(node)) {
08921 case NODE_CALL:
08922 switch (node->nd_mid) {
08923 case '+':
08924 case '-':
08925 case '*':
08926 case '/':
08927 case '%':
08928 case tPOW:
08929 case tUPLUS:
08930 case tUMINUS:
08931 case '|':
08932 case '^':
08933 case '&':
08934 case tCMP:
08935 case '>':
08936 case tGEQ:
08937 case '<':
08938 case tLEQ:
08939 case tEQ:
08940 case tNEQ:
08941 useless = rb_id2name(node->nd_mid);
08942 break;
08943 }
08944 break;
08945
08946 case NODE_LVAR:
08947 case NODE_DVAR:
08948 case NODE_GVAR:
08949 case NODE_IVAR:
08950 case NODE_CVAR:
08951 case NODE_NTH_REF:
08952 case NODE_BACK_REF:
08953 useless = "a variable";
08954 break;
08955 case NODE_CONST:
08956 useless = "a constant";
08957 break;
08958 case NODE_LIT:
08959 case NODE_STR:
08960 case NODE_DSTR:
08961 case NODE_DREGX:
08962 case NODE_DREGX_ONCE:
08963 useless = "a literal";
08964 break;
08965 case NODE_COLON2:
08966 case NODE_COLON3:
08967 useless = "::";
08968 break;
08969 case NODE_DOT2:
08970 useless = "..";
08971 break;
08972 case NODE_DOT3:
08973 useless = "...";
08974 break;
08975 case NODE_SELF:
08976 useless = "self";
08977 break;
08978 case NODE_NIL:
08979 useless = "nil";
08980 break;
08981 case NODE_TRUE:
08982 useless = "true";
08983 break;
08984 case NODE_FALSE:
08985 useless = "false";
08986 break;
08987 case NODE_DEFINED:
08988 useless = "defined?";
08989 break;
08990 }
08991
08992 if (useless) {
08993 int line = ruby_sourceline;
08994
08995 ruby_sourceline = nd_line(node);
08996 rb_warnS("possibly useless use of %s in void context", useless);
08997 ruby_sourceline = line;
08998 }
08999 }
09000
09001 static void
09002 void_stmts_gen(struct parser_params *parser, NODE *node)
09003 {
09004 if (!RTEST(ruby_verbose)) return;
09005 if (!node) return;
09006 if (nd_type(node) != NODE_BLOCK) return;
09007
09008 for (;;) {
09009 if (!node->nd_next) return;
09010 void_expr0(node->nd_head);
09011 node = node->nd_next;
09012 }
09013 }
09014
09015 static NODE *
09016 remove_begin(NODE *node)
09017 {
09018 NODE **n = &node, *n1 = node;
09019 while (n1 && nd_type(n1) == NODE_BEGIN && n1->nd_body) {
09020 *n = n1 = n1->nd_body;
09021 }
09022 return node;
09023 }
09024
09025 static void
09026 reduce_nodes_gen(struct parser_params *parser, NODE **body)
09027 {
09028 NODE *node = *body;
09029
09030 if (!node) {
09031 *body = NEW_NIL();
09032 return;
09033 }
09034 #define subnodes(n1, n2) \
09035 ((!node->n1) ? (node->n2 ? (body = &node->n2, 1) : 0) : \
09036 (!node->n2) ? (body = &node->n1, 1) : \
09037 (reduce_nodes(&node->n1), body = &node->n2, 1))
09038
09039 while (node) {
09040 int newline = (int)(node->flags & NODE_FL_NEWLINE);
09041 switch (nd_type(node)) {
09042 end:
09043 case NODE_NIL:
09044 *body = 0;
09045 return;
09046 case NODE_RETURN:
09047 *body = node = node->nd_stts;
09048 if (newline && node) node->flags |= NODE_FL_NEWLINE;
09049 continue;
09050 case NODE_BEGIN:
09051 *body = node = node->nd_body;
09052 if (newline && node) node->flags |= NODE_FL_NEWLINE;
09053 continue;
09054 case NODE_BLOCK:
09055 body = &node->nd_end->nd_head;
09056 break;
09057 case NODE_IF:
09058 if (subnodes(nd_body, nd_else)) break;
09059 return;
09060 case NODE_CASE:
09061 body = &node->nd_body;
09062 break;
09063 case NODE_WHEN:
09064 if (!subnodes(nd_body, nd_next)) goto end;
09065 break;
09066 case NODE_ENSURE:
09067 if (!subnodes(nd_head, nd_resq)) goto end;
09068 break;
09069 case NODE_RESCUE:
09070 if (node->nd_else) {
09071 body = &node->nd_resq;
09072 break;
09073 }
09074 if (!subnodes(nd_head, nd_resq)) goto end;
09075 break;
09076 default:
09077 return;
09078 }
09079 node = *body;
09080 if (newline && node) node->flags |= NODE_FL_NEWLINE;
09081 }
09082
09083 #undef subnodes
09084 }
09085
09086 static int
09087 is_static_content(NODE *node)
09088 {
09089 if (!node) return 1;
09090 switch (nd_type(node)) {
09091 case NODE_HASH:
09092 if (!(node = node->nd_head)) break;
09093 case NODE_ARRAY:
09094 do {
09095 if (!is_static_content(node->nd_head)) return 0;
09096 } while ((node = node->nd_next) != 0);
09097 case NODE_LIT:
09098 case NODE_STR:
09099 case NODE_NIL:
09100 case NODE_TRUE:
09101 case NODE_FALSE:
09102 case NODE_ZARRAY:
09103 break;
09104 default:
09105 return 0;
09106 }
09107 return 1;
09108 }
09109
09110 static int
09111 assign_in_cond(struct parser_params *parser, NODE *node)
09112 {
09113 switch (nd_type(node)) {
09114 case NODE_MASGN:
09115 yyerror("multiple assignment in conditional");
09116 return 1;
09117
09118 case NODE_LASGN:
09119 case NODE_DASGN:
09120 case NODE_DASGN_CURR:
09121 case NODE_GASGN:
09122 case NODE_IASGN:
09123 break;
09124
09125 default:
09126 return 0;
09127 }
09128
09129 if (!node->nd_value) return 1;
09130 if (is_static_content(node->nd_value)) {
09131
09132 parser_warn(node->nd_value, "found = in conditional, should be ==");
09133 }
09134 return 1;
09135 }
09136
09137 static void
09138 warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
09139 {
09140 if (!e_option_supplied(parser)) parser_warn(node, str);
09141 }
09142
09143 static void
09144 warning_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
09145 {
09146 if (!e_option_supplied(parser)) parser_warning(node, str);
09147 }
09148
09149 static void
09150 fixup_nodes(NODE **rootnode)
09151 {
09152 NODE *node, *next, *head;
09153
09154 for (node = *rootnode; node; node = next) {
09155 enum node_type type;
09156 VALUE val;
09157
09158 next = node->nd_next;
09159 head = node->nd_head;
09160 rb_gc_force_recycle((VALUE)node);
09161 *rootnode = next;
09162 switch (type = nd_type(head)) {
09163 case NODE_DOT2:
09164 case NODE_DOT3:
09165 val = rb_range_new(head->nd_beg->nd_lit, head->nd_end->nd_lit,
09166 type == NODE_DOT3);
09167 rb_gc_force_recycle((VALUE)head->nd_beg);
09168 rb_gc_force_recycle((VALUE)head->nd_end);
09169 nd_set_type(head, NODE_LIT);
09170 head->nd_lit = val;
09171 break;
09172 default:
09173 break;
09174 }
09175 }
09176 }
09177
09178 static NODE *cond0(struct parser_params*,NODE*);
09179
09180 static NODE*
09181 range_op(struct parser_params *parser, NODE *node)
09182 {
09183 enum node_type type;
09184
09185 if (node == 0) return 0;
09186
09187 type = nd_type(node);
09188 value_expr(node);
09189 if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
09190 warn_unless_e_option(parser, node, "integer literal in conditional range");
09191 return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(rb_intern("$."))));
09192 }
09193 return cond0(parser, node);
09194 }
09195
09196 static int
09197 literal_node(NODE *node)
09198 {
09199 if (!node) return 1;
09200 switch (nd_type(node)) {
09201 case NODE_LIT:
09202 case NODE_STR:
09203 case NODE_DSTR:
09204 case NODE_EVSTR:
09205 case NODE_DREGX:
09206 case NODE_DREGX_ONCE:
09207 case NODE_DSYM:
09208 return 2;
09209 case NODE_TRUE:
09210 case NODE_FALSE:
09211 case NODE_NIL:
09212 return 1;
09213 }
09214 return 0;
09215 }
09216
09217 static NODE*
09218 cond0(struct parser_params *parser, NODE *node)
09219 {
09220 if (node == 0) return 0;
09221 assign_in_cond(parser, node);
09222
09223 switch (nd_type(node)) {
09224 case NODE_DSTR:
09225 case NODE_EVSTR:
09226 case NODE_STR:
09227 rb_warn0("string literal in condition");
09228 break;
09229
09230 case NODE_DREGX:
09231 case NODE_DREGX_ONCE:
09232 warning_unless_e_option(parser, node, "regex literal in condition");
09233 return NEW_MATCH2(node, NEW_GVAR(rb_intern("$_")));
09234
09235 case NODE_AND:
09236 case NODE_OR:
09237 node->nd_1st = cond0(parser, node->nd_1st);
09238 node->nd_2nd = cond0(parser, node->nd_2nd);
09239 break;
09240
09241 case NODE_DOT2:
09242 case NODE_DOT3:
09243 node->nd_beg = range_op(parser, node->nd_beg);
09244 node->nd_end = range_op(parser, node->nd_end);
09245 if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
09246 else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
09247 if (!e_option_supplied(parser)) {
09248 int b = literal_node(node->nd_beg);
09249 int e = literal_node(node->nd_end);
09250 if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
09251 parser_warn(node, "range literal in condition");
09252 }
09253 }
09254 break;
09255
09256 case NODE_DSYM:
09257 parser_warning(node, "literal in condition");
09258 break;
09259
09260 case NODE_LIT:
09261 if (RB_TYPE_P(node->nd_lit, T_REGEXP)) {
09262 warn_unless_e_option(parser, node, "regex literal in condition");
09263 nd_set_type(node, NODE_MATCH);
09264 }
09265 else {
09266 parser_warning(node, "literal in condition");
09267 }
09268 default:
09269 break;
09270 }
09271 return node;
09272 }
09273
09274 static NODE*
09275 cond_gen(struct parser_params *parser, NODE *node)
09276 {
09277 if (node == 0) return 0;
09278 return cond0(parser, node);
09279 }
09280
09281 static NODE*
09282 logop_gen(struct parser_params *parser, enum node_type type, NODE *left, NODE *right)
09283 {
09284 value_expr(left);
09285 if (left && (enum node_type)nd_type(left) == type) {
09286 NODE *node = left, *second;
09287 while ((second = node->nd_2nd) != 0 && (enum node_type)nd_type(second) == type) {
09288 node = second;
09289 }
09290 node->nd_2nd = NEW_NODE(type, second, right, 0);
09291 return left;
09292 }
09293 return NEW_NODE(type, left, right, 0);
09294 }
09295
09296 static void
09297 no_blockarg(struct parser_params *parser, NODE *node)
09298 {
09299 if (node && nd_type(node) == NODE_BLOCK_PASS) {
09300 compile_error(PARSER_ARG "block argument should not be given");
09301 }
09302 }
09303
09304 static NODE *
09305 ret_args_gen(struct parser_params *parser, NODE *node)
09306 {
09307 if (node) {
09308 no_blockarg(parser, node);
09309 if (nd_type(node) == NODE_ARRAY) {
09310 if (node->nd_next == 0) {
09311 node = node->nd_head;
09312 }
09313 else {
09314 nd_set_type(node, NODE_VALUES);
09315 }
09316 }
09317 }
09318 return node;
09319 }
09320
09321 static NODE *
09322 new_yield_gen(struct parser_params *parser, NODE *node)
09323 {
09324 if (node) no_blockarg(parser, node);
09325
09326 return NEW_YIELD(node);
09327 }
09328
09329 static NODE*
09330 negate_lit(NODE *node)
09331 {
09332 switch (TYPE(node->nd_lit)) {
09333 case T_FIXNUM:
09334 node->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit));
09335 break;
09336 case T_BIGNUM:
09337 node->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0);
09338 break;
09339 case T_FLOAT:
09340 #if USE_FLONUM
09341 if (FLONUM_P(node->nd_lit)) {
09342 node->nd_lit = DBL2NUM(-RFLOAT_VALUE(node->nd_lit));
09343 }
09344 else {
09345 RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
09346 }
09347 #else
09348 RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
09349 #endif
09350 break;
09351 default:
09352 break;
09353 }
09354 return node;
09355 }
09356
09357 static NODE *
09358 arg_blk_pass(NODE *node1, NODE *node2)
09359 {
09360 if (node2) {
09361 node2->nd_head = node1;
09362 return node2;
09363 }
09364 return node1;
09365 }
09366
09367
09368 static NODE*
09369 new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, NODE *tail)
09370 {
09371 int saved_line = ruby_sourceline;
09372 struct rb_args_info *args = tail->nd_ainfo;
09373
09374 args->pre_args_num = m ? rb_long2int(m->nd_plen) : 0;
09375 args->pre_init = m ? m->nd_next : 0;
09376
09377 args->post_args_num = p ? rb_long2int(p->nd_plen) : 0;
09378 args->post_init = p ? p->nd_next : 0;
09379 args->first_post_arg = p ? p->nd_pid : 0;
09380
09381 args->rest_arg = r;
09382
09383 args->opt_args = o;
09384
09385 ruby_sourceline = saved_line;
09386
09387 return tail;
09388 }
09389
09390 static NODE*
09391 new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
09392 {
09393 int saved_line = ruby_sourceline;
09394 struct rb_args_info *args;
09395 NODE *kw_rest_arg = 0;
09396 NODE *node;
09397
09398 args = ALLOC(struct rb_args_info);
09399 MEMZERO(args, struct rb_args_info, 1);
09400 node = NEW_NODE(NODE_ARGS, 0, 0, args);
09401
09402 args->block_arg = b;
09403 args->kw_args = k;
09404 if (k && !kr) kr = internal_id();
09405 if (kr) {
09406 arg_var(kr);
09407 kw_rest_arg = NEW_DVAR(kr);
09408 }
09409 args->kw_rest_arg = kw_rest_arg;
09410
09411 ruby_sourceline = saved_line;
09412 return node;
09413 }
09414
09415 static NODE*
09416 dsym_node_gen(struct parser_params *parser, NODE *node)
09417 {
09418 VALUE lit;
09419
09420 if (!node) {
09421 return NEW_LIT(ID2SYM(idNULL));
09422 }
09423
09424 switch (nd_type(node)) {
09425 case NODE_DSTR:
09426 nd_set_type(node, NODE_DSYM);
09427 break;
09428 case NODE_STR:
09429 lit = node->nd_lit;
09430 node->nd_lit = ID2SYM(rb_intern_str(lit));
09431 nd_set_type(node, NODE_LIT);
09432 break;
09433 default:
09434 node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node));
09435 break;
09436 }
09437 return node;
09438 }
09439 #endif
09440
09441 #ifndef RIPPER
09442 static NODE *
09443 new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
09444 {
09445 NODE *asgn;
09446
09447 if (lhs) {
09448 ID vid = lhs->nd_vid;
09449 if (op == tOROP) {
09450 lhs->nd_value = rhs;
09451 asgn = NEW_OP_ASGN_OR(gettable(vid), lhs);
09452 if (is_asgn_or_id(vid)) {
09453 asgn->nd_aid = vid;
09454 }
09455 }
09456 else if (op == tANDOP) {
09457 lhs->nd_value = rhs;
09458 asgn = NEW_OP_ASGN_AND(gettable(vid), lhs);
09459 }
09460 else {
09461 asgn = lhs;
09462 asgn->nd_value = NEW_CALL(gettable(vid), op, NEW_LIST(rhs));
09463 }
09464 }
09465 else {
09466 asgn = NEW_BEGIN(0);
09467 }
09468 return asgn;
09469 }
09470
09471 static NODE *
09472 new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID attr, ID op, NODE *rhs)
09473 {
09474 NODE *asgn;
09475
09476 if (op == tOROP) {
09477 op = 0;
09478 }
09479 else if (op == tANDOP) {
09480 op = 1;
09481 }
09482 asgn = NEW_OP_ASGN2(lhs, attr, op, rhs);
09483 fixpos(asgn, lhs);
09484 return asgn;
09485 }
09486
09487 static NODE *
09488 new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs)
09489 {
09490 NODE *asgn;
09491
09492 if (op == tOROP) {
09493 op = 0;
09494 }
09495 else if (op == tANDOP) {
09496 op = 1;
09497 }
09498 if (lhs) {
09499 asgn = NEW_OP_CDECL(lhs, op, rhs);
09500 }
09501 else {
09502 asgn = NEW_BEGIN(0);
09503 }
09504 fixpos(asgn, lhs);
09505 return asgn;
09506 }
09507 #else
09508 static VALUE
09509 new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs)
09510 {
09511 return dispatch3(opassign, lhs, op, rhs);
09512 }
09513
09514 static VALUE
09515 new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs)
09516 {
09517 VALUE recv = dispatch3(field, lhs, type, attr);
09518 return dispatch3(opassign, recv, op, rhs);
09519 }
09520 #endif
09521
09522 static void
09523 warn_unused_var(struct parser_params *parser, struct local_vars *local)
09524 {
09525 int i, cnt;
09526 ID *v, *u;
09527
09528 if (!local->used) return;
09529 v = local->vars->tbl;
09530 u = local->used->tbl;
09531 cnt = local->used->pos;
09532 if (cnt != local->vars->pos) {
09533 rb_bug("local->used->pos != local->vars->pos");
09534 }
09535 for (i = 0; i < cnt; ++i) {
09536 if (!v[i] || (u[i] & LVAR_USED)) continue;
09537 if (is_private_local_id(v[i])) continue;
09538 rb_warn4S(ruby_sourcefile, (int)u[i], "assigned but unused variable - %s", rb_id2name(v[i]));
09539 }
09540 }
09541
09542 static void
09543 local_push_gen(struct parser_params *parser, int inherit_dvars)
09544 {
09545 struct local_vars *local;
09546
09547 local = ALLOC(struct local_vars);
09548 local->prev = lvtbl;
09549 local->args = vtable_alloc(0);
09550 local->vars = vtable_alloc(inherit_dvars ? DVARS_INHERIT : DVARS_TOPSCOPE);
09551 local->used = !(inherit_dvars &&
09552 (ifndef_ripper(compile_for_eval || e_option_supplied(parser))+0)) &&
09553 RTEST(ruby_verbose) ? vtable_alloc(0) : 0;
09554 local->cmdargs = cmdarg_stack;
09555 cmdarg_stack = 0;
09556 lvtbl = local;
09557 }
09558
09559 static void
09560 local_pop_gen(struct parser_params *parser)
09561 {
09562 struct local_vars *local = lvtbl->prev;
09563 if (lvtbl->used) {
09564 warn_unused_var(parser, lvtbl);
09565 vtable_free(lvtbl->used);
09566 }
09567 vtable_free(lvtbl->args);
09568 vtable_free(lvtbl->vars);
09569 cmdarg_stack = lvtbl->cmdargs;
09570 xfree(lvtbl);
09571 lvtbl = local;
09572 }
09573
09574 #ifndef RIPPER
09575 static ID*
09576 local_tbl_gen(struct parser_params *parser)
09577 {
09578 int cnt_args = vtable_size(lvtbl->args);
09579 int cnt_vars = vtable_size(lvtbl->vars);
09580 int cnt = cnt_args + cnt_vars;
09581 int i, j;
09582 ID *buf;
09583
09584 if (cnt <= 0) return 0;
09585 buf = ALLOC_N(ID, cnt + 1);
09586 MEMCPY(buf+1, lvtbl->args->tbl, ID, cnt_args);
09587
09588 for (i = 0, j = cnt_args+1; i < cnt_vars; ++i) {
09589 ID id = lvtbl->vars->tbl[i];
09590 if (!vtable_included(lvtbl->args, id)) {
09591 buf[j++] = id;
09592 }
09593 }
09594 if (--j < cnt) REALLOC_N(buf, ID, (cnt = j) + 1);
09595 buf[0] = cnt;
09596 return buf;
09597 }
09598 #endif
09599
09600 static int
09601 arg_var_gen(struct parser_params *parser, ID id)
09602 {
09603 vtable_add(lvtbl->args, id);
09604 return vtable_size(lvtbl->args) - 1;
09605 }
09606
09607 static int
09608 local_var_gen(struct parser_params *parser, ID id)
09609 {
09610 vtable_add(lvtbl->vars, id);
09611 if (lvtbl->used) {
09612 vtable_add(lvtbl->used, (ID)ruby_sourceline);
09613 }
09614 return vtable_size(lvtbl->vars) - 1;
09615 }
09616
09617 static int
09618 local_id_gen(struct parser_params *parser, ID id)
09619 {
09620 struct vtable *vars, *args, *used;
09621
09622 vars = lvtbl->vars;
09623 args = lvtbl->args;
09624 used = lvtbl->used;
09625
09626 while (vars && POINTER_P(vars->prev)) {
09627 vars = vars->prev;
09628 args = args->prev;
09629 if (used) used = used->prev;
09630 }
09631
09632 if (vars && vars->prev == DVARS_INHERIT) {
09633 return rb_local_defined(id);
09634 }
09635 else if (vtable_included(args, id)) {
09636 return 1;
09637 }
09638 else {
09639 int i = vtable_included(vars, id);
09640 if (i && used) used->tbl[i-1] |= LVAR_USED;
09641 return i != 0;
09642 }
09643 }
09644
09645 static const struct vtable *
09646 dyna_push_gen(struct parser_params *parser)
09647 {
09648 lvtbl->args = vtable_alloc(lvtbl->args);
09649 lvtbl->vars = vtable_alloc(lvtbl->vars);
09650 if (lvtbl->used) {
09651 lvtbl->used = vtable_alloc(lvtbl->used);
09652 }
09653 return lvtbl->args;
09654 }
09655
09656 static void
09657 dyna_pop_1(struct parser_params *parser)
09658 {
09659 struct vtable *tmp;
09660
09661 if ((tmp = lvtbl->used) != 0) {
09662 warn_unused_var(parser, lvtbl);
09663 lvtbl->used = lvtbl->used->prev;
09664 vtable_free(tmp);
09665 }
09666 tmp = lvtbl->args;
09667 lvtbl->args = lvtbl->args->prev;
09668 vtable_free(tmp);
09669 tmp = lvtbl->vars;
09670 lvtbl->vars = lvtbl->vars->prev;
09671 vtable_free(tmp);
09672 }
09673
09674 static void
09675 dyna_pop_gen(struct parser_params *parser, const struct vtable *lvargs)
09676 {
09677 while (lvtbl->args != lvargs) {
09678 dyna_pop_1(parser);
09679 if (!lvtbl->args) {
09680 struct local_vars *local = lvtbl->prev;
09681 xfree(lvtbl);
09682 lvtbl = local;
09683 }
09684 }
09685 dyna_pop_1(parser);
09686 }
09687
09688 static int
09689 dyna_in_block_gen(struct parser_params *parser)
09690 {
09691 return POINTER_P(lvtbl->vars) && lvtbl->vars->prev != DVARS_TOPSCOPE;
09692 }
09693
09694 static int
09695 dvar_defined_gen(struct parser_params *parser, ID id, int get)
09696 {
09697 struct vtable *vars, *args, *used;
09698 int i;
09699
09700 args = lvtbl->args;
09701 vars = lvtbl->vars;
09702 used = lvtbl->used;
09703
09704 while (POINTER_P(vars)) {
09705 if (vtable_included(args, id)) {
09706 return 1;
09707 }
09708 if ((i = vtable_included(vars, id)) != 0) {
09709 if (used) used->tbl[i-1] |= LVAR_USED;
09710 return 1;
09711 }
09712 args = args->prev;
09713 vars = vars->prev;
09714 if (get) used = 0;
09715 if (used) used = used->prev;
09716 }
09717
09718 if (vars == DVARS_INHERIT) {
09719 return rb_dvar_defined(id);
09720 }
09721
09722 return 0;
09723 }
09724
09725 static int
09726 dvar_curr_gen(struct parser_params *parser, ID id)
09727 {
09728 return (vtable_included(lvtbl->args, id) ||
09729 vtable_included(lvtbl->vars, id));
09730 }
09731
09732 #ifndef RIPPER
09733 static void
09734 reg_fragment_setenc_gen(struct parser_params* parser, VALUE str, int options)
09735 {
09736 int c = RE_OPTION_ENCODING_IDX(options);
09737
09738 if (c) {
09739 int opt, idx;
09740 rb_char_to_option_kcode(c, &opt, &idx);
09741 if (idx != ENCODING_GET(str) &&
09742 rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
09743 goto error;
09744 }
09745 ENCODING_SET(str, idx);
09746 }
09747 else if (RE_OPTION_ENCODING_NONE(options)) {
09748 if (!ENCODING_IS_ASCII8BIT(str) &&
09749 rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
09750 c = 'n';
09751 goto error;
09752 }
09753 rb_enc_associate(str, rb_ascii8bit_encoding());
09754 }
09755 else if (current_enc == rb_usascii_encoding()) {
09756 if (rb_enc_str_coderange(str) != ENC_CODERANGE_7BIT) {
09757
09758 rb_enc_associate(str, rb_usascii_encoding());
09759 }
09760 else {
09761 rb_enc_associate(str, rb_ascii8bit_encoding());
09762 }
09763 }
09764 return;
09765
09766 error:
09767 compile_error(PARSER_ARG
09768 "regexp encoding option '%c' differs from source encoding '%s'",
09769 c, rb_enc_name(rb_enc_get(str)));
09770 }
09771
09772 static int
09773 reg_fragment_check_gen(struct parser_params* parser, VALUE str, int options)
09774 {
09775 VALUE err;
09776 reg_fragment_setenc(str, options);
09777 err = rb_reg_check_preprocess(str);
09778 if (err != Qnil) {
09779 err = rb_obj_as_string(err);
09780 compile_error(PARSER_ARG "%s", RSTRING_PTR(err));
09781 RB_GC_GUARD(err);
09782 return 0;
09783 }
09784 return 1;
09785 }
09786
09787 typedef struct {
09788 struct parser_params* parser;
09789 rb_encoding *enc;
09790 NODE *succ_block;
09791 NODE *fail_block;
09792 int num;
09793 } reg_named_capture_assign_t;
09794
09795 static int
09796 reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
09797 int back_num, int *back_refs, OnigRegex regex, void *arg0)
09798 {
09799 reg_named_capture_assign_t *arg = (reg_named_capture_assign_t*)arg0;
09800 struct parser_params* parser = arg->parser;
09801 rb_encoding *enc = arg->enc;
09802 long len = name_end - name;
09803 const char *s = (const char *)name;
09804 ID var;
09805
09806 arg->num++;
09807
09808 if (arg->succ_block == 0) {
09809 arg->succ_block = NEW_BEGIN(0);
09810 arg->fail_block = NEW_BEGIN(0);
09811 }
09812
09813 if (!len || (*name != '_' && ISASCII(*name) && !rb_enc_islower(*name, enc)) ||
09814 (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) ||
09815 !rb_enc_symname2_p(s, len, enc)) {
09816 return ST_CONTINUE;
09817 }
09818 var = rb_intern3(s, len, enc);
09819 if (dvar_defined(var) || local_id(var)) {
09820 rb_warningS("named capture conflicts a local variable - %s",
09821 rb_id2name(var));
09822 }
09823 arg->succ_block = block_append(arg->succ_block,
09824 newline_node(node_assign(assignable(var,0),
09825 NEW_CALL(
09826 gettable(rb_intern("$~")),
09827 idAREF,
09828 NEW_LIST(NEW_LIT(ID2SYM(var))))
09829 )));
09830 arg->fail_block = block_append(arg->fail_block,
09831 newline_node(node_assign(assignable(var,0), NEW_LIT(Qnil))));
09832 return ST_CONTINUE;
09833 }
09834
09835 static NODE *
09836 reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, NODE *match)
09837 {
09838 reg_named_capture_assign_t arg;
09839
09840 arg.parser = parser;
09841 arg.enc = rb_enc_get(regexp);
09842 arg.succ_block = 0;
09843 arg.fail_block = 0;
09844 arg.num = 0;
09845 onig_foreach_name(RREGEXP(regexp)->ptr, reg_named_capture_assign_iter, (void*)&arg);
09846
09847 if (arg.num == 0)
09848 return match;
09849
09850 return
09851 block_append(
09852 newline_node(match),
09853 NEW_IF(gettable(rb_intern("$~")),
09854 block_append(
09855 newline_node(arg.succ_block),
09856 newline_node(
09857 NEW_CALL(
09858 gettable(rb_intern("$~")),
09859 rb_intern("begin"),
09860 NEW_LIST(NEW_LIT(INT2FIX(0)))))),
09861 block_append(
09862 newline_node(arg.fail_block),
09863 newline_node(
09864 NEW_LIT(Qnil)))));
09865 }
09866
09867 static VALUE
09868 reg_compile_gen(struct parser_params* parser, VALUE str, int options)
09869 {
09870 VALUE re;
09871 VALUE err;
09872
09873 reg_fragment_setenc(str, options);
09874 err = rb_errinfo();
09875 re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
09876 if (NIL_P(re)) {
09877 ID mesg = rb_intern("mesg");
09878 VALUE m = rb_attr_get(rb_errinfo(), mesg);
09879 rb_set_errinfo(err);
09880 if (!NIL_P(err)) {
09881 rb_str_append(rb_str_cat(rb_attr_get(err, mesg), "\n", 1), m);
09882 }
09883 else {
09884 compile_error(PARSER_ARG "%s", RSTRING_PTR(m));
09885 }
09886 return Qnil;
09887 }
09888 return re;
09889 }
09890
09891 void
09892 rb_gc_mark_parser(void)
09893 {
09894 }
09895
09896 NODE*
09897 rb_parser_append_print(VALUE vparser, NODE *node)
09898 {
09899 NODE *prelude = 0;
09900 NODE *scope = node;
09901 struct parser_params *parser;
09902
09903 if (!node) return node;
09904
09905 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
09906
09907 node = node->nd_body;
09908
09909 if (nd_type(node) == NODE_PRELUDE) {
09910 prelude = node;
09911 node = node->nd_body;
09912 }
09913
09914 node = block_append(node,
09915 NEW_FCALL(rb_intern("print"),
09916 NEW_ARRAY(NEW_GVAR(rb_intern("$_")))));
09917 if (prelude) {
09918 prelude->nd_body = node;
09919 scope->nd_body = prelude;
09920 }
09921 else {
09922 scope->nd_body = node;
09923 }
09924
09925 return scope;
09926 }
09927
09928 NODE *
09929 rb_parser_while_loop(VALUE vparser, NODE *node, int chop, int split)
09930 {
09931 NODE *prelude = 0;
09932 NODE *scope = node;
09933 struct parser_params *parser;
09934
09935 if (!node) return node;
09936
09937 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
09938
09939 node = node->nd_body;
09940
09941 if (nd_type(node) == NODE_PRELUDE) {
09942 prelude = node;
09943 node = node->nd_body;
09944 }
09945 if (split) {
09946 node = block_append(NEW_GASGN(rb_intern("$F"),
09947 NEW_CALL(NEW_GVAR(rb_intern("$_")),
09948 rb_intern("split"), 0)),
09949 node);
09950 }
09951 if (chop) {
09952 node = block_append(NEW_CALL(NEW_GVAR(rb_intern("$_")),
09953 rb_intern("chop!"), 0), node);
09954 }
09955
09956 node = NEW_OPT_N(node);
09957
09958 if (prelude) {
09959 prelude->nd_body = node;
09960 scope->nd_body = prelude;
09961 }
09962 else {
09963 scope->nd_body = node;
09964 }
09965
09966 return scope;
09967 }
09968
09969 static const struct {
09970 ID token;
09971 const char *name;
09972 } op_tbl[] = {
09973 {tDOT2, ".."},
09974 {tDOT3, "..."},
09975 {tPOW, "**"},
09976 {tDSTAR, "**"},
09977 {tUPLUS, "+@"},
09978 {tUMINUS, "-@"},
09979 {tCMP, "<=>"},
09980 {tGEQ, ">="},
09981 {tLEQ, "<="},
09982 {tEQ, "=="},
09983 {tEQQ, "==="},
09984 {tNEQ, "!="},
09985 {tMATCH, "=~"},
09986 {tNMATCH, "!~"},
09987 {tAREF, "[]"},
09988 {tASET, "[]="},
09989 {tLSHFT, "<<"},
09990 {tRSHFT, ">>"},
09991 {tCOLON2, "::"},
09992 };
09993
09994 #define op_tbl_count numberof(op_tbl)
09995
09996 #ifndef ENABLE_SELECTOR_NAMESPACE
09997 #define ENABLE_SELECTOR_NAMESPACE 0
09998 #endif
09999
10000 static struct symbols {
10001 ID last_id;
10002 st_table *sym_id;
10003 st_table *id_str;
10004 #if ENABLE_SELECTOR_NAMESPACE
10005 st_table *ivar2_id;
10006 st_table *id_ivar2;
10007 #endif
10008 VALUE op_sym[tLAST_OP_ID];
10009 } global_symbols = {tLAST_TOKEN};
10010
10011 static const struct st_hash_type symhash = {
10012 rb_str_hash_cmp,
10013 rb_str_hash,
10014 };
10015
10016 #if ENABLE_SELECTOR_NAMESPACE
10017 struct ivar2_key {
10018 ID id;
10019 VALUE klass;
10020 };
10021
10022 static int
10023 ivar2_cmp(struct ivar2_key *key1, struct ivar2_key *key2)
10024 {
10025 if (key1->id == key2->id && key1->klass == key2->klass) {
10026 return 0;
10027 }
10028 return 1;
10029 }
10030
10031 static int
10032 ivar2_hash(struct ivar2_key *key)
10033 {
10034 return (key->id << 8) ^ (key->klass >> 2);
10035 }
10036
10037 static const struct st_hash_type ivar2_hash_type = {
10038 ivar2_cmp,
10039 ivar2_hash,
10040 };
10041 #endif
10042
10043 void
10044 Init_sym(void)
10045 {
10046 global_symbols.sym_id = st_init_table_with_size(&symhash, 1000);
10047 global_symbols.id_str = st_init_numtable_with_size(1000);
10048 #if ENABLE_SELECTOR_NAMESPACE
10049 global_symbols.ivar2_id = st_init_table_with_size(&ivar2_hash_type, 1000);
10050 global_symbols.id_ivar2 = st_init_numtable_with_size(1000);
10051 #endif
10052
10053 (void)nodetype;
10054 (void)nodeline;
10055 #if PARSER_DEBUG
10056 (void)lex_state_name(-1);
10057 #endif
10058
10059 Init_id();
10060 }
10061
10062 void
10063 rb_gc_mark_symbols(void)
10064 {
10065 rb_mark_tbl(global_symbols.id_str);
10066 rb_gc_mark_locations(global_symbols.op_sym,
10067 global_symbols.op_sym + numberof(global_symbols.op_sym));
10068 }
10069 #endif
10070
10071 static ID
10072 internal_id_gen(struct parser_params *parser)
10073 {
10074 ID id = (ID)vtable_size(lvtbl->args) + (ID)vtable_size(lvtbl->vars);
10075 id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1;
10076 return ID_INTERNAL | (id << ID_SCOPE_SHIFT);
10077 }
10078
10079 #ifndef RIPPER
10080 static int
10081 is_special_global_name(const char *m, const char *e, rb_encoding *enc)
10082 {
10083 int mb = 0;
10084
10085 if (m >= e) return 0;
10086 if (is_global_name_punct(*m)) {
10087 ++m;
10088 }
10089 else if (*m == '-') {
10090 ++m;
10091 if (m < e && is_identchar(m, e, enc)) {
10092 if (!ISASCII(*m)) mb = 1;
10093 m += rb_enc_mbclen(m, e, enc);
10094 }
10095 }
10096 else {
10097 if (!rb_enc_isdigit(*m, enc)) return 0;
10098 do {
10099 if (!ISASCII(*m)) mb = 1;
10100 ++m;
10101 } while (m < e && rb_enc_isdigit(*m, enc));
10102 }
10103 return m == e ? mb + 1 : 0;
10104 }
10105
10106 int
10107 rb_symname_p(const char *name)
10108 {
10109 return rb_enc_symname_p(name, rb_ascii8bit_encoding());
10110 }
10111
10112 int
10113 rb_enc_symname_p(const char *name, rb_encoding *enc)
10114 {
10115 return rb_enc_symname2_p(name, strlen(name), enc);
10116 }
10117
10118 #define IDSET_ATTRSET_FOR_SYNTAX ((1U<<ID_LOCAL)|(1U<<ID_CONST))
10119 #define IDSET_ATTRSET_FOR_INTERN (~(~0U<<(1<<ID_SCOPE_SHIFT)) & ~(1U<<ID_ATTRSET))
10120
10121 static int
10122 rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_atttset)
10123 {
10124 const char *m = name;
10125 const char *e = m + len;
10126 int type = ID_JUNK;
10127
10128 if (!m || len <= 0) return -1;
10129 switch (*m) {
10130 case '\0':
10131 return -1;
10132
10133 case '$':
10134 type = ID_GLOBAL;
10135 if (is_special_global_name(++m, e, enc)) return type;
10136 goto id;
10137
10138 case '@':
10139 type = ID_INSTANCE;
10140 if (*++m == '@') {
10141 ++m;
10142 type = ID_CLASS;
10143 }
10144 goto id;
10145
10146 case '<':
10147 switch (*++m) {
10148 case '<': ++m; break;
10149 case '=': if (*++m == '>') ++m; break;
10150 default: break;
10151 }
10152 break;
10153
10154 case '>':
10155 switch (*++m) {
10156 case '>': case '=': ++m; break;
10157 }
10158 break;
10159
10160 case '=':
10161 switch (*++m) {
10162 case '~': ++m; break;
10163 case '=': if (*++m == '=') ++m; break;
10164 default: return -1;
10165 }
10166 break;
10167
10168 case '*':
10169 if (*++m == '*') ++m;
10170 break;
10171
10172 case '+': case '-':
10173 if (*++m == '@') ++m;
10174 break;
10175
10176 case '|': case '^': case '&': case '/': case '%': case '~': case '`':
10177 ++m;
10178 break;
10179
10180 case '[':
10181 if (*++m != ']') return -1;
10182 if (*++m == '=') ++m;
10183 break;
10184
10185 case '!':
10186 if (len == 1) return ID_JUNK;
10187 switch (*++m) {
10188 case '=': case '~': ++m; break;
10189 default: return -1;
10190 }
10191 break;
10192
10193 default:
10194 type = rb_enc_isupper(*m, enc) ? ID_CONST : ID_LOCAL;
10195 id:
10196 if (m >= e || (*m != '_' && !rb_enc_isalpha(*m, enc) && ISASCII(*m)))
10197 return -1;
10198 while (m < e && is_identchar(m, e, enc)) m += rb_enc_mbclen(m, e, enc);
10199 if (m >= e) break;
10200 switch (*m) {
10201 case '!': case '?':
10202 if (type == ID_GLOBAL || type == ID_CLASS || type == ID_INSTANCE) return -1;
10203 type = ID_JUNK;
10204 ++m;
10205 if (m + 1 < e || *m != '=') break;
10206
10207 case '=':
10208 if (!(allowed_atttset & (1U << type))) return -1;
10209 type = ID_ATTRSET;
10210 ++m;
10211 break;
10212 }
10213 break;
10214 }
10215 return m == e ? type : -1;
10216 }
10217
10218 int
10219 rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
10220 {
10221 return rb_enc_symname_type(name, len, enc, IDSET_ATTRSET_FOR_SYNTAX) != -1;
10222 }
10223
10224 static int
10225 rb_str_symname_type(VALUE name, unsigned int allowed_atttset)
10226 {
10227 const char *ptr = StringValuePtr(name);
10228 long len = RSTRING_LEN(name);
10229 int type = rb_enc_symname_type(ptr, len, rb_enc_get(name), allowed_atttset);
10230 RB_GC_GUARD(name);
10231 return type;
10232 }
10233
10234 static ID
10235 register_symid(ID id, const char *name, long len, rb_encoding *enc)
10236 {
10237 VALUE str = rb_enc_str_new(name, len, enc);
10238 return register_symid_str(id, str);
10239 }
10240
10241 static ID
10242 register_symid_str(ID id, VALUE str)
10243 {
10244 OBJ_FREEZE(str);
10245 st_add_direct(global_symbols.sym_id, (st_data_t)str, id);
10246 st_add_direct(global_symbols.id_str, id, (st_data_t)str);
10247 return id;
10248 }
10249
10250 static int
10251 sym_check_asciionly(VALUE str)
10252 {
10253 if (!rb_enc_asciicompat(rb_enc_get(str))) return FALSE;
10254 switch (rb_enc_str_coderange(str)) {
10255 case ENC_CODERANGE_BROKEN:
10256 rb_raise(rb_eEncodingError, "invalid encoding symbol");
10257 case ENC_CODERANGE_7BIT:
10258 return TRUE;
10259 }
10260 return FALSE;
10261 }
10262
10263
10264
10265
10266
10267
10268 static ID intern_str(VALUE str);
10269
10270 ID
10271 rb_intern3(const char *name, long len, rb_encoding *enc)
10272 {
10273 VALUE str;
10274 st_data_t data;
10275 struct RString fake_str;
10276 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10277 fake_str.basic.klass = rb_cString;
10278 fake_str.as.heap.len = len;
10279 fake_str.as.heap.ptr = (char *)name;
10280 fake_str.as.heap.aux.capa = len;
10281 str = (VALUE)&fake_str;
10282 rb_enc_associate(str, enc);
10283 OBJ_FREEZE(str);
10284
10285 if (st_lookup(global_symbols.sym_id, str, &data))
10286 return (ID)data;
10287
10288 str = rb_enc_str_new(name, len, enc);
10289 return intern_str(str);
10290 }
10291
10292 static ID
10293 intern_str(VALUE str)
10294 {
10295 const char *name, *m, *e;
10296 long len, last;
10297 rb_encoding *enc, *symenc;
10298 unsigned char c;
10299 ID id;
10300 int mb;
10301
10302 RSTRING_GETMEM(str, name, len);
10303 m = name;
10304 e = m + len;
10305 enc = rb_enc_get(str);
10306 symenc = enc;
10307
10308 if (!len || (rb_cString && !rb_enc_asciicompat(enc))) {
10309 junk:
10310 id = ID_JUNK;
10311 goto new_id;
10312 }
10313 last = len-1;
10314 id = 0;
10315 switch (*m) {
10316 case '$':
10317 if (len < 2) goto junk;
10318 id |= ID_GLOBAL;
10319 if ((mb = is_special_global_name(++m, e, enc)) != 0) {
10320 if (!--mb) symenc = rb_usascii_encoding();
10321 goto new_id;
10322 }
10323 break;
10324 case '@':
10325 if (m[1] == '@') {
10326 if (len < 3) goto junk;
10327 m++;
10328 id |= ID_CLASS;
10329 }
10330 else {
10331 if (len < 2) goto junk;
10332 id |= ID_INSTANCE;
10333 }
10334 m++;
10335 break;
10336 default:
10337 c = m[0];
10338 if (c != '_' && rb_enc_isascii(c, enc) && rb_enc_ispunct(c, enc)) {
10339
10340 int i;
10341
10342 if (len == 1) {
10343 id = c;
10344 goto id_register;
10345 }
10346 for (i = 0; i < op_tbl_count; i++) {
10347 if (*op_tbl[i].name == *m &&
10348 strcmp(op_tbl[i].name, m) == 0) {
10349 id = op_tbl[i].token;
10350 goto id_register;
10351 }
10352 }
10353 }
10354 break;
10355 }
10356 if (name[last] == '=') {
10357
10358 if (last > 1 && name[last-1] == '=')
10359 goto junk;
10360 id = rb_intern3(name, last, enc);
10361 if (id > tLAST_OP_ID && !is_attrset_id(id)) {
10362 enc = rb_enc_get(rb_id2str(id));
10363 id = rb_id_attrset(id);
10364 goto id_register;
10365 }
10366 id = ID_ATTRSET;
10367 }
10368 else if (id == 0) {
10369 if (rb_enc_isupper(m[0], enc)) {
10370 id = ID_CONST;
10371 }
10372 else {
10373 id = ID_LOCAL;
10374 }
10375 }
10376 if (!rb_enc_isdigit(*m, enc)) {
10377 while (m <= name + last && is_identchar(m, e, enc)) {
10378 if (ISASCII(*m)) {
10379 m++;
10380 }
10381 else {
10382 m += rb_enc_mbclen(m, e, enc);
10383 }
10384 }
10385 }
10386 if (id != ID_ATTRSET && m - name < len) id = ID_JUNK;
10387 if (sym_check_asciionly(str)) symenc = rb_usascii_encoding();
10388 new_id:
10389 if (symenc != enc) rb_enc_associate(str, symenc);
10390 if (global_symbols.last_id >= ~(ID)0 >> (ID_SCOPE_SHIFT+RUBY_SPECIAL_SHIFT)) {
10391 if (len > 20) {
10392 rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.20s...)",
10393 name);
10394 }
10395 else {
10396 rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %.*s)",
10397 (int)len, name);
10398 }
10399 }
10400 id |= ++global_symbols.last_id << ID_SCOPE_SHIFT;
10401 id_register:
10402 return register_symid_str(id, str);
10403 }
10404
10405 ID
10406 rb_intern2(const char *name, long len)
10407 {
10408 return rb_intern3(name, len, rb_usascii_encoding());
10409 }
10410
10411 #undef rb_intern
10412 ID
10413 rb_intern(const char *name)
10414 {
10415 return rb_intern2(name, strlen(name));
10416 }
10417
10418 ID
10419 rb_intern_str(VALUE str)
10420 {
10421 st_data_t id;
10422
10423 if (st_lookup(global_symbols.sym_id, str, &id))
10424 return (ID)id;
10425 return intern_str(rb_str_dup(str));
10426 }
10427
10428 VALUE
10429 rb_id2str(ID id)
10430 {
10431 st_data_t data;
10432
10433 if (id < tLAST_TOKEN) {
10434 int i = 0;
10435
10436 if (id < INT_MAX && rb_ispunct((int)id)) {
10437 VALUE str = global_symbols.op_sym[i = (int)id];
10438 if (!str) {
10439 char name[2];
10440 name[0] = (char)id;
10441 name[1] = 0;
10442 str = rb_usascii_str_new(name, 1);
10443 OBJ_FREEZE(str);
10444 global_symbols.op_sym[i] = str;
10445 }
10446 return str;
10447 }
10448 for (i = 0; i < op_tbl_count; i++) {
10449 if (op_tbl[i].token == id) {
10450 VALUE str = global_symbols.op_sym[i];
10451 if (!str) {
10452 str = rb_usascii_str_new2(op_tbl[i].name);
10453 OBJ_FREEZE(str);
10454 global_symbols.op_sym[i] = str;
10455 }
10456 return str;
10457 }
10458 }
10459 }
10460
10461 if (st_lookup(global_symbols.id_str, id, &data)) {
10462 VALUE str = (VALUE)data;
10463 if (RBASIC(str)->klass == 0)
10464 RBASIC(str)->klass = rb_cString;
10465 return str;
10466 }
10467
10468 if (is_attrset_id(id)) {
10469 ID id_stem = (id & ~ID_SCOPE_MASK);
10470 VALUE str;
10471
10472 do {
10473 if (!!(str = rb_id2str(id_stem | ID_LOCAL))) break;
10474 if (!!(str = rb_id2str(id_stem | ID_CONST))) break;
10475 if (!!(str = rb_id2str(id_stem | ID_INSTANCE))) break;
10476 if (!!(str = rb_id2str(id_stem | ID_GLOBAL))) break;
10477 if (!!(str = rb_id2str(id_stem | ID_CLASS))) break;
10478 if (!!(str = rb_id2str(id_stem | ID_JUNK))) break;
10479 return 0;
10480 } while (0);
10481 str = rb_str_dup(str);
10482 rb_str_cat(str, "=", 1);
10483 register_symid_str(id, str);
10484 if (st_lookup(global_symbols.id_str, id, &data)) {
10485 VALUE str = (VALUE)data;
10486 if (RBASIC(str)->klass == 0)
10487 RBASIC(str)->klass = rb_cString;
10488 return str;
10489 }
10490 }
10491 return 0;
10492 }
10493
10494 const char *
10495 rb_id2name(ID id)
10496 {
10497 VALUE str = rb_id2str(id);
10498
10499 if (!str) return 0;
10500 return RSTRING_PTR(str);
10501 }
10502
10503 static int
10504 symbols_i(VALUE sym, ID value, VALUE ary)
10505 {
10506 rb_ary_push(ary, ID2SYM(value));
10507 return ST_CONTINUE;
10508 }
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526 VALUE
10527 rb_sym_all_symbols(void)
10528 {
10529 VALUE ary = rb_ary_new2(global_symbols.sym_id->num_entries);
10530
10531 st_foreach(global_symbols.sym_id, symbols_i, ary);
10532 return ary;
10533 }
10534
10535 int
10536 rb_is_const_id(ID id)
10537 {
10538 return is_const_id(id);
10539 }
10540
10541 int
10542 rb_is_class_id(ID id)
10543 {
10544 return is_class_id(id);
10545 }
10546
10547 int
10548 rb_is_global_id(ID id)
10549 {
10550 return is_global_id(id);
10551 }
10552
10553 int
10554 rb_is_instance_id(ID id)
10555 {
10556 return is_instance_id(id);
10557 }
10558
10559 int
10560 rb_is_attrset_id(ID id)
10561 {
10562 return is_attrset_id(id);
10563 }
10564
10565 int
10566 rb_is_local_id(ID id)
10567 {
10568 return is_local_id(id);
10569 }
10570
10571 int
10572 rb_is_junk_id(ID id)
10573 {
10574 return is_junk_id(id);
10575 }
10576
10588 ID
10589 rb_check_id(volatile VALUE *namep)
10590 {
10591 st_data_t id;
10592 VALUE tmp;
10593 VALUE name = *namep;
10594
10595 if (SYMBOL_P(name)) {
10596 return SYM2ID(name);
10597 }
10598 else if (!RB_TYPE_P(name, T_STRING)) {
10599 tmp = rb_check_string_type(name);
10600 if (NIL_P(tmp)) {
10601 tmp = rb_inspect(name);
10602 rb_raise(rb_eTypeError, "%s is not a symbol",
10603 RSTRING_PTR(tmp));
10604 }
10605 name = tmp;
10606 *namep = name;
10607 }
10608
10609 sym_check_asciionly(name);
10610
10611 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10612 return (ID)id;
10613
10614 if (rb_is_attrset_name(name)) {
10615 struct RString fake_str;
10616 const VALUE localname = (VALUE)&fake_str;
10617
10618 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10619 fake_str.basic.klass = rb_cString;
10620 fake_str.as.heap.len = RSTRING_LEN(name) - 1;
10621 fake_str.as.heap.ptr = RSTRING_PTR(name);
10622 fake_str.as.heap.aux.capa = fake_str.as.heap.len;
10623 rb_enc_copy(localname, name);
10624 OBJ_FREEZE(localname);
10625
10626 if (st_lookup(global_symbols.sym_id, (st_data_t)localname, &id)) {
10627 return rb_id_attrset((ID)id);
10628 }
10629 RB_GC_GUARD(name);
10630 }
10631
10632 return (ID)0;
10633 }
10634
10635 ID
10636 rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
10637 {
10638 st_data_t id;
10639 struct RString fake_str;
10640 const VALUE name = (VALUE)&fake_str;
10641 fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
10642 fake_str.basic.klass = rb_cString;
10643 fake_str.as.heap.len = len;
10644 fake_str.as.heap.ptr = (char *)ptr;
10645 fake_str.as.heap.aux.capa = len;
10646 rb_enc_associate(name, enc);
10647
10648 sym_check_asciionly(name);
10649
10650 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id))
10651 return (ID)id;
10652
10653 if (rb_is_attrset_name(name)) {
10654 fake_str.as.heap.len = len - 1;
10655 if (st_lookup(global_symbols.sym_id, (st_data_t)name, &id)) {
10656 return rb_id_attrset((ID)id);
10657 }
10658 }
10659
10660 return (ID)0;
10661 }
10662
10663 int
10664 rb_is_const_name(VALUE name)
10665 {
10666 return rb_str_symname_type(name, 0) == ID_CONST;
10667 }
10668
10669 int
10670 rb_is_class_name(VALUE name)
10671 {
10672 return rb_str_symname_type(name, 0) == ID_CLASS;
10673 }
10674
10675 int
10676 rb_is_global_name(VALUE name)
10677 {
10678 return rb_str_symname_type(name, 0) == ID_GLOBAL;
10679 }
10680
10681 int
10682 rb_is_instance_name(VALUE name)
10683 {
10684 return rb_str_symname_type(name, 0) == ID_INSTANCE;
10685 }
10686
10687 int
10688 rb_is_attrset_name(VALUE name)
10689 {
10690 return rb_str_symname_type(name, IDSET_ATTRSET_FOR_INTERN) == ID_ATTRSET;
10691 }
10692
10693 int
10694 rb_is_local_name(VALUE name)
10695 {
10696 return rb_str_symname_type(name, 0) == ID_LOCAL;
10697 }
10698
10699 int
10700 rb_is_method_name(VALUE name)
10701 {
10702 switch (rb_str_symname_type(name, 0)) {
10703 case ID_LOCAL: case ID_ATTRSET: case ID_JUNK:
10704 return TRUE;
10705 }
10706 return FALSE;
10707 }
10708
10709 int
10710 rb_is_junk_name(VALUE name)
10711 {
10712 return rb_str_symname_type(name, IDSET_ATTRSET_FOR_SYNTAX) == -1;
10713 }
10714
10715 #endif
10716
10717 static void
10718 parser_initialize(struct parser_params *parser)
10719 {
10720 parser->eofp = Qfalse;
10721
10722 parser->parser_lex_strterm = 0;
10723 parser->parser_cond_stack = 0;
10724 parser->parser_cmdarg_stack = 0;
10725 parser->parser_class_nest = 0;
10726 parser->parser_paren_nest = 0;
10727 parser->parser_lpar_beg = 0;
10728 parser->parser_brace_nest = 0;
10729 parser->parser_in_single = 0;
10730 parser->parser_in_def = 0;
10731 parser->parser_in_defined = 0;
10732 parser->parser_compile_for_eval = 0;
10733 parser->parser_cur_mid = 0;
10734 parser->parser_tokenbuf = NULL;
10735 parser->parser_tokidx = 0;
10736 parser->parser_toksiz = 0;
10737 parser->parser_heredoc_end = 0;
10738 parser->parser_command_start = TRUE;
10739 parser->parser_deferred_nodes = 0;
10740 parser->parser_lex_pbeg = 0;
10741 parser->parser_lex_p = 0;
10742 parser->parser_lex_pend = 0;
10743 parser->parser_lvtbl = 0;
10744 parser->parser_ruby__end__seen = 0;
10745 parser->parser_ruby_sourcefile = 0;
10746 parser->parser_ruby_sourcefile_string = Qnil;
10747 #ifndef RIPPER
10748 parser->is_ripper = 0;
10749 parser->parser_eval_tree_begin = 0;
10750 parser->parser_eval_tree = 0;
10751 #else
10752 parser->is_ripper = 1;
10753 parser->delayed = Qnil;
10754
10755 parser->result = Qnil;
10756 parser->parsing_thread = Qnil;
10757 parser->toplevel_p = TRUE;
10758 #endif
10759 #ifdef YYMALLOC
10760 parser->heap = NULL;
10761 #endif
10762 parser->enc = rb_utf8_encoding();
10763 }
10764
10765 #ifdef RIPPER
10766 #define parser_mark ripper_parser_mark
10767 #define parser_free ripper_parser_free
10768 #endif
10769
10770 static void
10771 parser_mark(void *ptr)
10772 {
10773 struct parser_params *p = (struct parser_params*)ptr;
10774
10775 rb_gc_mark((VALUE)p->parser_lex_strterm);
10776 rb_gc_mark((VALUE)p->parser_deferred_nodes);
10777 rb_gc_mark(p->parser_lex_input);
10778 rb_gc_mark(p->parser_lex_lastline);
10779 rb_gc_mark(p->parser_lex_nextline);
10780 rb_gc_mark(p->parser_ruby_sourcefile_string);
10781 #ifndef RIPPER
10782 rb_gc_mark((VALUE)p->parser_eval_tree_begin) ;
10783 rb_gc_mark((VALUE)p->parser_eval_tree) ;
10784 rb_gc_mark(p->debug_lines);
10785 #else
10786 rb_gc_mark(p->delayed);
10787 rb_gc_mark(p->value);
10788 rb_gc_mark(p->result);
10789 rb_gc_mark(p->parsing_thread);
10790 #endif
10791 #ifdef YYMALLOC
10792 rb_gc_mark((VALUE)p->heap);
10793 #endif
10794 }
10795
10796 static void
10797 parser_free(void *ptr)
10798 {
10799 struct parser_params *p = (struct parser_params*)ptr;
10800 struct local_vars *local, *prev;
10801
10802 if (p->parser_tokenbuf) {
10803 xfree(p->parser_tokenbuf);
10804 }
10805 for (local = p->parser_lvtbl; local; local = prev) {
10806 if (local->vars) xfree(local->vars);
10807 prev = local->prev;
10808 xfree(local);
10809 }
10810 xfree(p);
10811 }
10812
10813 static size_t
10814 parser_memsize(const void *ptr)
10815 {
10816 struct parser_params *p = (struct parser_params*)ptr;
10817 struct local_vars *local;
10818 size_t size = sizeof(*p);
10819
10820 if (!ptr) return 0;
10821 size += p->parser_toksiz;
10822 for (local = p->parser_lvtbl; local; local = local->prev) {
10823 size += sizeof(*local);
10824 if (local->vars) size += local->vars->capa * sizeof(ID);
10825 }
10826 return size;
10827 }
10828
10829 static
10830 #ifndef RIPPER
10831 const
10832 #endif
10833 rb_data_type_t parser_data_type = {
10834 "parser",
10835 {
10836 parser_mark,
10837 parser_free,
10838 parser_memsize,
10839 },
10840 };
10841
10842 #ifndef RIPPER
10843 #undef rb_reserved_word
10844
10845 const struct kwtable *
10846 rb_reserved_word(const char *str, unsigned int len)
10847 {
10848 return reserved_word(str, len);
10849 }
10850
10851 static struct parser_params *
10852 parser_new(void)
10853 {
10854 struct parser_params *p;
10855
10856 p = ALLOC_N(struct parser_params, 1);
10857 MEMZERO(p, struct parser_params, 1);
10858 parser_initialize(p);
10859 return p;
10860 }
10861
10862 VALUE
10863 rb_parser_new(void)
10864 {
10865 struct parser_params *p = parser_new();
10866
10867 return TypedData_Wrap_Struct(0, &parser_data_type, p);
10868 }
10869
10870
10871
10872
10873
10874
10875
10876 VALUE
10877 rb_parser_end_seen_p(VALUE vparser)
10878 {
10879 struct parser_params *parser;
10880
10881 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10882 return ruby__end__seen ? Qtrue : Qfalse;
10883 }
10884
10885
10886
10887
10888
10889
10890
10891 VALUE
10892 rb_parser_encoding(VALUE vparser)
10893 {
10894 struct parser_params *parser;
10895
10896 TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
10897 return rb_enc_from_encoding(current_enc);
10898 }
10899
10900
10901
10902
10903
10904
10905
10906 VALUE
10907 rb_parser_get_yydebug(VALUE self)
10908 {
10909 struct parser_params *parser;
10910
10911 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10912 return yydebug ? Qtrue : Qfalse;
10913 }
10914
10915
10916
10917
10918
10919
10920
10921 VALUE
10922 rb_parser_set_yydebug(VALUE self, VALUE flag)
10923 {
10924 struct parser_params *parser;
10925
10926 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
10927 yydebug = RTEST(flag);
10928 return flag;
10929 }
10930
10931 #ifdef YYMALLOC
10932 #define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
10933 #define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
10934 #define ADD2HEAP(n, c, p) ((parser->heap = (n))->u1.node = (p), \
10935 (n)->u3.cnt = (c), (p))
10936
10937 void *
10938 rb_parser_malloc(struct parser_params *parser, size_t size)
10939 {
10940 size_t cnt = HEAPCNT(1, size);
10941 NODE *n = NEWHEAP();
10942 void *ptr = xmalloc(size);
10943
10944 return ADD2HEAP(n, cnt, ptr);
10945 }
10946
10947 void *
10948 rb_parser_calloc(struct parser_params *parser, size_t nelem, size_t size)
10949 {
10950 size_t cnt = HEAPCNT(nelem, size);
10951 NODE *n = NEWHEAP();
10952 void *ptr = xcalloc(nelem, size);
10953
10954 return ADD2HEAP(n, cnt, ptr);
10955 }
10956
10957 void *
10958 rb_parser_realloc(struct parser_params *parser, void *ptr, size_t size)
10959 {
10960 NODE *n;
10961 size_t cnt = HEAPCNT(1, size);
10962
10963 if (ptr && (n = parser->heap) != NULL) {
10964 do {
10965 if (n->u1.node == ptr) {
10966 n->u1.node = ptr = xrealloc(ptr, size);
10967 if (n->u3.cnt) n->u3.cnt = cnt;
10968 return ptr;
10969 }
10970 } while ((n = n->u2.node) != NULL);
10971 }
10972 n = NEWHEAP();
10973 ptr = xrealloc(ptr, size);
10974 return ADD2HEAP(n, cnt, ptr);
10975 }
10976
10977 void
10978 rb_parser_free(struct parser_params *parser, void *ptr)
10979 {
10980 NODE **prev = &parser->heap, *n;
10981
10982 while ((n = *prev) != NULL) {
10983 if (n->u1.node == ptr) {
10984 *prev = n->u2.node;
10985 rb_gc_force_recycle((VALUE)n);
10986 break;
10987 }
10988 prev = &n->u2.node;
10989 }
10990 xfree(ptr);
10991 }
10992 #endif
10993 #endif
10994
10995 #ifdef RIPPER
10996 #ifdef RIPPER_DEBUG
10997 extern int rb_is_pointer_to_heap(VALUE);
10998
10999
11000 static VALUE
11001 ripper_validate_object(VALUE self, VALUE x)
11002 {
11003 if (x == Qfalse) return x;
11004 if (x == Qtrue) return x;
11005 if (x == Qnil) return x;
11006 if (x == Qundef)
11007 rb_raise(rb_eArgError, "Qundef given");
11008 if (FIXNUM_P(x)) return x;
11009 if (SYMBOL_P(x)) return x;
11010 if (!rb_is_pointer_to_heap(x))
11011 rb_raise(rb_eArgError, "invalid pointer: %p", x);
11012 switch (TYPE(x)) {
11013 case T_STRING:
11014 case T_OBJECT:
11015 case T_ARRAY:
11016 case T_BIGNUM:
11017 case T_FLOAT:
11018 return x;
11019 case T_NODE:
11020 if (nd_type(x) != NODE_LASGN) {
11021 rb_raise(rb_eArgError, "NODE given: %p", x);
11022 }
11023 return ((NODE *)x)->nd_rval;
11024 default:
11025 rb_raise(rb_eArgError, "wrong type of ruby object: %p (%s)",
11026 x, rb_obj_classname(x));
11027 }
11028 return x;
11029 }
11030 #endif
11031
11032 #define validate(x) ((x) = get_value(x))
11033
11034 static VALUE
11035 ripper_dispatch0(struct parser_params *parser, ID mid)
11036 {
11037 return rb_funcall(parser->value, mid, 0);
11038 }
11039
11040 static VALUE
11041 ripper_dispatch1(struct parser_params *parser, ID mid, VALUE a)
11042 {
11043 validate(a);
11044 return rb_funcall(parser->value, mid, 1, a);
11045 }
11046
11047 static VALUE
11048 ripper_dispatch2(struct parser_params *parser, ID mid, VALUE a, VALUE b)
11049 {
11050 validate(a);
11051 validate(b);
11052 return rb_funcall(parser->value, mid, 2, a, b);
11053 }
11054
11055 static VALUE
11056 ripper_dispatch3(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c)
11057 {
11058 validate(a);
11059 validate(b);
11060 validate(c);
11061 return rb_funcall(parser->value, mid, 3, a, b, c);
11062 }
11063
11064 static VALUE
11065 ripper_dispatch4(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d)
11066 {
11067 validate(a);
11068 validate(b);
11069 validate(c);
11070 validate(d);
11071 return rb_funcall(parser->value, mid, 4, a, b, c, d);
11072 }
11073
11074 static VALUE
11075 ripper_dispatch5(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e)
11076 {
11077 validate(a);
11078 validate(b);
11079 validate(c);
11080 validate(d);
11081 validate(e);
11082 return rb_funcall(parser->value, mid, 5, a, b, c, d, e);
11083 }
11084
11085 static VALUE
11086 ripper_dispatch7(struct parser_params *parser, ID mid, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g)
11087 {
11088 validate(a);
11089 validate(b);
11090 validate(c);
11091 validate(d);
11092 validate(e);
11093 validate(f);
11094 validate(g);
11095 return rb_funcall(parser->value, mid, 7, a, b, c, d, e, f, g);
11096 }
11097
11098 static const struct kw_assoc {
11099 ID id;
11100 const char *name;
11101 } keyword_to_name[] = {
11102 {keyword_class, "class"},
11103 {keyword_module, "module"},
11104 {keyword_def, "def"},
11105 {keyword_undef, "undef"},
11106 {keyword_begin, "begin"},
11107 {keyword_rescue, "rescue"},
11108 {keyword_ensure, "ensure"},
11109 {keyword_end, "end"},
11110 {keyword_if, "if"},
11111 {keyword_unless, "unless"},
11112 {keyword_then, "then"},
11113 {keyword_elsif, "elsif"},
11114 {keyword_else, "else"},
11115 {keyword_case, "case"},
11116 {keyword_when, "when"},
11117 {keyword_while, "while"},
11118 {keyword_until, "until"},
11119 {keyword_for, "for"},
11120 {keyword_break, "break"},
11121 {keyword_next, "next"},
11122 {keyword_redo, "redo"},
11123 {keyword_retry, "retry"},
11124 {keyword_in, "in"},
11125 {keyword_do, "do"},
11126 {keyword_do_cond, "do"},
11127 {keyword_do_block, "do"},
11128 {keyword_return, "return"},
11129 {keyword_yield, "yield"},
11130 {keyword_super, "super"},
11131 {keyword_self, "self"},
11132 {keyword_nil, "nil"},
11133 {keyword_true, "true"},
11134 {keyword_false, "false"},
11135 {keyword_and, "and"},
11136 {keyword_or, "or"},
11137 {keyword_not, "not"},
11138 {modifier_if, "if"},
11139 {modifier_unless, "unless"},
11140 {modifier_while, "while"},
11141 {modifier_until, "until"},
11142 {modifier_rescue, "rescue"},
11143 {keyword_alias, "alias"},
11144 {keyword_defined, "defined?"},
11145 {keyword_BEGIN, "BEGIN"},
11146 {keyword_END, "END"},
11147 {keyword__LINE__, "__LINE__"},
11148 {keyword__FILE__, "__FILE__"},
11149 {keyword__ENCODING__, "__ENCODING__"},
11150 {0, NULL}
11151 };
11152
11153 static const char*
11154 keyword_id_to_str(ID id)
11155 {
11156 const struct kw_assoc *a;
11157
11158 for (a = keyword_to_name; a->id; a++) {
11159 if (a->id == id)
11160 return a->name;
11161 }
11162 return NULL;
11163 }
11164
11165 #undef ripper_id2sym
11166 static VALUE
11167 ripper_id2sym(ID id)
11168 {
11169 const char *name;
11170 char buf[8];
11171
11172 if (id <= 256) {
11173 buf[0] = (char)id;
11174 buf[1] = '\0';
11175 return ID2SYM(rb_intern2(buf, 1));
11176 }
11177 if ((name = keyword_id_to_str(id))) {
11178 return ID2SYM(rb_intern(name));
11179 }
11180 switch (id) {
11181 case tOROP:
11182 name = "||";
11183 break;
11184 case tANDOP:
11185 name = "&&";
11186 break;
11187 default:
11188 name = rb_id2name(id);
11189 if (!name) {
11190 rb_bug("cannot convert ID to string: %ld", (unsigned long)id);
11191 }
11192 return ID2SYM(id);
11193 }
11194 return ID2SYM(rb_intern(name));
11195 }
11196
11197 static ID
11198 ripper_get_id(VALUE v)
11199 {
11200 NODE *nd;
11201 if (!RB_TYPE_P(v, T_NODE)) return 0;
11202 nd = (NODE *)v;
11203 if (nd_type(nd) != NODE_LASGN) return 0;
11204 return nd->nd_vid;
11205 }
11206
11207 static VALUE
11208 ripper_get_value(VALUE v)
11209 {
11210 NODE *nd;
11211 if (v == Qundef) return Qnil;
11212 if (!RB_TYPE_P(v, T_NODE)) return v;
11213 nd = (NODE *)v;
11214 if (nd_type(nd) != NODE_LASGN) return Qnil;
11215 return nd->nd_rval;
11216 }
11217
11218 static void
11219 ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
11220 {
11221 VALUE str;
11222 va_list args;
11223
11224 va_start(args, fmt);
11225 str = rb_vsprintf(fmt, args);
11226 va_end(args);
11227 rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
11228 }
11229
11230 static void
11231 ripper_warn0(struct parser_params *parser, const char *fmt)
11232 {
11233 rb_funcall(parser->value, rb_intern("warn"), 1, STR_NEW2(fmt));
11234 }
11235
11236 static void
11237 ripper_warnI(struct parser_params *parser, const char *fmt, int a)
11238 {
11239 rb_funcall(parser->value, rb_intern("warn"), 2,
11240 STR_NEW2(fmt), INT2NUM(a));
11241 }
11242
11243 static void
11244 ripper_warnS(struct parser_params *parser, const char *fmt, const char *str)
11245 {
11246 rb_funcall(parser->value, rb_intern("warn"), 2,
11247 STR_NEW2(fmt), STR_NEW2(str));
11248 }
11249
11250 static void
11251 ripper_warning0(struct parser_params *parser, const char *fmt)
11252 {
11253 rb_funcall(parser->value, rb_intern("warning"), 1, STR_NEW2(fmt));
11254 }
11255
11256 static void
11257 ripper_warningS(struct parser_params *parser, const char *fmt, const char *str)
11258 {
11259 rb_funcall(parser->value, rb_intern("warning"), 2,
11260 STR_NEW2(fmt), STR_NEW2(str));
11261 }
11262
11263 static VALUE
11264 ripper_lex_get_generic(struct parser_params *parser, VALUE src)
11265 {
11266 return rb_io_gets(src);
11267 }
11268
11269 static VALUE
11270 ripper_s_allocate(VALUE klass)
11271 {
11272 struct parser_params *p;
11273 VALUE self;
11274
11275 p = ALLOC_N(struct parser_params, 1);
11276 MEMZERO(p, struct parser_params, 1);
11277 self = TypedData_Wrap_Struct(klass, &parser_data_type, p);
11278 p->value = self;
11279 return self;
11280 }
11281
11282 #define ripper_initialized_p(r) ((r)->parser_lex_input != 0)
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294 static VALUE
11295 ripper_initialize(int argc, VALUE *argv, VALUE self)
11296 {
11297 struct parser_params *parser;
11298 VALUE src, fname, lineno;
11299
11300 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11301 rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
11302 if (RB_TYPE_P(src, T_FILE)) {
11303 parser->parser_lex_gets = ripper_lex_get_generic;
11304 }
11305 else {
11306 StringValue(src);
11307 parser->parser_lex_gets = lex_get_str;
11308 }
11309 parser->parser_lex_input = src;
11310 parser->eofp = Qfalse;
11311 if (NIL_P(fname)) {
11312 fname = STR_NEW2("(ripper)");
11313 }
11314 else {
11315 StringValue(fname);
11316 }
11317 parser_initialize(parser);
11318
11319 parser->parser_ruby_sourcefile_string = fname;
11320 parser->parser_ruby_sourcefile = RSTRING_PTR(fname);
11321 parser->parser_ruby_sourceline = NIL_P(lineno) ? 0 : NUM2INT(lineno) - 1;
11322
11323 return Qnil;
11324 }
11325
11326 struct ripper_args {
11327 struct parser_params *parser;
11328 int argc;
11329 VALUE *argv;
11330 };
11331
11332 static VALUE
11333 ripper_parse0(VALUE parser_v)
11334 {
11335 struct parser_params *parser;
11336
11337 TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11338 parser_prepare(parser);
11339 ripper_yyparse((void*)parser);
11340 return parser->result;
11341 }
11342
11343 static VALUE
11344 ripper_ensure(VALUE parser_v)
11345 {
11346 struct parser_params *parser;
11347
11348 TypedData_Get_Struct(parser_v, struct parser_params, &parser_data_type, parser);
11349 parser->parsing_thread = Qnil;
11350 return Qnil;
11351 }
11352
11353
11354
11355
11356
11357
11358
11359 static VALUE
11360 ripper_parse(VALUE self)
11361 {
11362 struct parser_params *parser;
11363
11364 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11365 if (!ripper_initialized_p(parser)) {
11366 rb_raise(rb_eArgError, "method called for uninitialized object");
11367 }
11368 if (!NIL_P(parser->parsing_thread)) {
11369 if (parser->parsing_thread == rb_thread_current())
11370 rb_raise(rb_eArgError, "Ripper#parse is not reentrant");
11371 else
11372 rb_raise(rb_eArgError, "Ripper#parse is not multithread-safe");
11373 }
11374 parser->parsing_thread = rb_thread_current();
11375 rb_ensure(ripper_parse0, self, ripper_ensure, self);
11376
11377 return parser->result;
11378 }
11379
11380
11381
11382
11383
11384
11385
11386
11387 static VALUE
11388 ripper_column(VALUE self)
11389 {
11390 struct parser_params *parser;
11391 long col;
11392
11393 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11394 if (!ripper_initialized_p(parser)) {
11395 rb_raise(rb_eArgError, "method called for uninitialized object");
11396 }
11397 if (NIL_P(parser->parsing_thread)) return Qnil;
11398 col = parser->tokp - parser->parser_lex_pbeg;
11399 return LONG2NUM(col);
11400 }
11401
11402
11403
11404
11405
11406
11407
11408 static VALUE
11409 ripper_filename(VALUE self)
11410 {
11411 struct parser_params *parser;
11412
11413 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11414 if (!ripper_initialized_p(parser)) {
11415 rb_raise(rb_eArgError, "method called for uninitialized object");
11416 }
11417 return parser->parser_ruby_sourcefile_string;
11418 }
11419
11420
11421
11422
11423
11424
11425
11426
11427 static VALUE
11428 ripper_lineno(VALUE self)
11429 {
11430 struct parser_params *parser;
11431
11432 TypedData_Get_Struct(self, struct parser_params, &parser_data_type, parser);
11433 if (!ripper_initialized_p(parser)) {
11434 rb_raise(rb_eArgError, "method called for uninitialized object");
11435 }
11436 if (NIL_P(parser->parsing_thread)) return Qnil;
11437 return INT2NUM(parser->parser_ruby_sourceline);
11438 }
11439
11440 #ifdef RIPPER_DEBUG
11441
11442 static VALUE
11443 ripper_assert_Qundef(VALUE self, VALUE obj, VALUE msg)
11444 {
11445 StringValue(msg);
11446 if (obj == Qundef) {
11447 rb_raise(rb_eArgError, "%s", RSTRING_PTR(msg));
11448 }
11449 return Qnil;
11450 }
11451
11452
11453 static VALUE
11454 ripper_value(VALUE self, VALUE obj)
11455 {
11456 return ULONG2NUM(obj);
11457 }
11458 #endif
11459
11460
11461 void
11462 Init_ripper(void)
11463 {
11464 parser_data_type.parent = RTYPEDDATA_TYPE(rb_parser_new());
11465
11466 ripper_init_eventids1();
11467 ripper_init_eventids2();
11468
11469 (void)rb_intern("||");
11470 (void)rb_intern("&&");
11471
11472 InitVM(ripper);
11473 }
11474
11475 void
11476 InitVM_ripper(void)
11477 {
11478 VALUE Ripper;
11479
11480 Ripper = rb_define_class("Ripper", rb_cObject);
11481 rb_define_const(Ripper, "Version", rb_usascii_str_new2(RIPPER_VERSION));
11482 rb_define_alloc_func(Ripper, ripper_s_allocate);
11483 rb_define_method(Ripper, "initialize", ripper_initialize, -1);
11484 rb_define_method(Ripper, "parse", ripper_parse, 0);
11485 rb_define_method(Ripper, "column", ripper_column, 0);
11486 rb_define_method(Ripper, "filename", ripper_filename, 0);
11487 rb_define_method(Ripper, "lineno", ripper_lineno, 0);
11488 rb_define_method(Ripper, "end_seen?", rb_parser_end_seen_p, 0);
11489 rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
11490 rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
11491 rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
11492 #ifdef RIPPER_DEBUG
11493 rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
11494 rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
11495 rb_define_method(rb_mKernel, "validate_object", ripper_validate_object, 1);
11496 #endif
11497
11498 ripper_init_eventids1_table(Ripper);
11499 ripper_init_eventids2_table(Ripper);
11500
11501 # if 0
11502
11503
11504
11505
11506
11507
11508
11509 rb_define_global_const("SCRIPT_LINES__", Qnil);
11510 #endif
11511
11512 }
11513 #endif
11514