PageRenderTime 42ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/vm/parser/grammar.y

https://github.com/vasco/rubinius
Happy | 5899 lines | 5381 code | 518 blank | 0 comment | 0 complexity | aaf3402f7f095f9d63e9e0e227071d1c MD5 | raw file
Possible License(s): GPL-2.0, BSD-2-Clause, LGPL-2.1, BSD-3-Clause
  1. /**********************************************************************
  2. parse.y -
  3. $Author: matz $
  4. $Date: 2004/11/29 06:13:51 $
  5. created at: Fri May 28 18:02:42 JST 1993
  6. Copyright (C) 1993-2003 Yukihiro Matsumoto
  7. **********************************************************************/
  8. %{
  9. #define YYDEBUG 1
  10. #define YYERROR_VERBOSE 1
  11. #include <stdio.h>
  12. #include <errno.h>
  13. #include <ctype.h>
  14. #include <string.h>
  15. #include <stdbool.h>
  16. #include "builtin/array.hpp"
  17. #include "parser/grammar_internal.hpp"
  18. #include "parser/grammar_runtime.hpp"
  19. #include "parser/local_state.hpp"
  20. #include "objectmemory.hpp"
  21. namespace rubinius {
  22. namespace parser {
  23. #undef VALUE
  24. #ifndef isnumber
  25. #define isnumber isdigit
  26. #endif
  27. /* Defined at least in mach/boolean.h on OS X. */
  28. #ifdef TRUE
  29. #undef TRUE
  30. #endif
  31. #ifdef FALSE
  32. #undef FALSE
  33. #endif
  34. #define TRUE true
  35. #define FALSE false
  36. #define ISALPHA isalpha
  37. #define ISSPACE isspace
  38. #define ISALNUM(x) (isalpha(x) || isnumber(x))
  39. #define ISDIGIT isdigit
  40. #define ISXDIGIT isxdigit
  41. #define ISUPPER isupper
  42. #define ismbchar(c) (0)
  43. #define mbclen(c) (1)
  44. #define ID2SYM(i) (Object*)i
  45. #define string_new(ptr, len) blk2bstr(ptr, len)
  46. #define string_new2(ptr) cstr2bstr(ptr)
  47. intptr_t syd_sourceline;
  48. static char *syd_sourcefile;
  49. #define ruby_sourceline syd_sourceline
  50. #define ruby_sourcefile syd_sourcefile
  51. static int
  52. syd_yyerror(const char *, rb_parse_state*);
  53. #define yyparse syd_yyparse
  54. #define yylex syd_yylex
  55. #define yyerror(str) syd_yyerror(str, (rb_parse_state*)parse_state)
  56. #define yylval syd_yylval
  57. #define yychar syd_yychar
  58. #define yydebug syd_yydebug
  59. #define YYPARSE_PARAM parse_state
  60. #define YYLEX_PARAM parse_state
  61. #define ID_SCOPE_SHIFT 3
  62. #define ID_SCOPE_MASK 0x07
  63. #define ID_LOCAL 0x01
  64. #define ID_INSTANCE 0x02
  65. #define ID_GLOBAL 0x03
  66. #define ID_ATTRSET 0x04
  67. #define ID_CONST 0x05
  68. #define ID_CLASS 0x06
  69. #define ID_JUNK 0x07
  70. #define ID_INTERNAL ID_JUNK
  71. #define is_notop_id(id) ((id)>tLAST_TOKEN)
  72. #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
  73. #define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
  74. #define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
  75. #define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
  76. #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
  77. #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
  78. #define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
  79. #define is_asgn_or_id(id) ((is_notop_id(id)) && \
  80. (((id)&ID_SCOPE_MASK) == ID_GLOBAL || \
  81. ((id)&ID_SCOPE_MASK) == ID_INSTANCE || \
  82. ((id)&ID_SCOPE_MASK) == ID_CLASS))
  83. /* FIXME these went into the ruby_state instead of parse_state
  84. because a ton of other crap depends on it
  85. char *ruby_sourcefile; current source file
  86. int ruby_sourceline; current line no.
  87. */
  88. static int yylex(void*, void *);
  89. #define BITSTACK_PUSH(stack, n) (stack = (stack<<1)|((n)&1))
  90. #define BITSTACK_POP(stack) (stack >>= 1)
  91. #define BITSTACK_LEXPOP(stack) (stack = (stack >> 1) | (stack & 1))
  92. #define BITSTACK_SET_P(stack) (stack&1)
  93. #define COND_PUSH(n) BITSTACK_PUSH(vps->cond_stack, n)
  94. #define COND_POP() BITSTACK_POP(vps->cond_stack)
  95. #define COND_LEXPOP() BITSTACK_LEXPOP(vps->cond_stack)
  96. #define COND_P() BITSTACK_SET_P(vps->cond_stack)
  97. #define CMDARG_PUSH(n) BITSTACK_PUSH(vps->cmdarg_stack, n)
  98. #define CMDARG_POP() BITSTACK_POP(vps->cmdarg_stack)
  99. #define CMDARG_LEXPOP() BITSTACK_LEXPOP(vps->cmdarg_stack)
  100. #define CMDARG_P() BITSTACK_SET_P(vps->cmdarg_stack)
  101. /*
  102. static int class_nest = 0;
  103. static int in_single = 0;
  104. static int in_def = 0;
  105. static int compile_for_eval = 0;
  106. static ID cur_mid = 0;
  107. */
  108. static NODE *cond(NODE*,rb_parse_state*);
  109. static NODE *logop(enum node_type,NODE*,NODE*,rb_parse_state*);
  110. static int cond_negative(NODE**);
  111. static NODE *newline_node(rb_parse_state*,NODE*);
  112. static void fixpos(NODE*,NODE*);
  113. static int value_expr0(NODE*,rb_parse_state*);
  114. static void void_expr0(NODE *);
  115. static void void_stmts(NODE*,rb_parse_state*);
  116. static NODE *remove_begin(NODE*,rb_parse_state*);
  117. #define value_expr(node) value_expr0((node) = \
  118. remove_begin(node, (rb_parse_state*)parse_state), \
  119. (rb_parse_state*)parse_state)
  120. #define void_expr(node) void_expr0((node) = remove_begin(node, (rb_parse_state*)parse_state))
  121. static NODE *block_append(rb_parse_state*,NODE*,NODE*);
  122. static NODE *list_append(rb_parse_state*,NODE*,NODE*);
  123. static NODE *list_concat(NODE*,NODE*);
  124. static NODE *arg_concat(rb_parse_state*,NODE*,NODE*);
  125. static NODE *arg_prepend(rb_parse_state*,NODE*,NODE*);
  126. static NODE *literal_concat(rb_parse_state*,NODE*,NODE*);
  127. static NODE *new_evstr(rb_parse_state*,NODE*);
  128. static NODE *evstr2dstr(rb_parse_state*,NODE*);
  129. static NODE *call_op(NODE*,ID,int,NODE*,rb_parse_state*);
  130. /* static NODE *negate_lit(NODE*); */
  131. static NODE *ret_args(rb_parse_state*,NODE*);
  132. static NODE *arg_blk_pass(NODE*,NODE*);
  133. static NODE *new_call(rb_parse_state*,NODE*,ID,NODE*);
  134. static NODE *new_fcall(rb_parse_state*,ID,NODE*);
  135. static NODE *new_super(rb_parse_state*,NODE*);
  136. static NODE *new_yield(rb_parse_state*,NODE*);
  137. static NODE *syd_gettable(rb_parse_state*,ID);
  138. #define gettable(i) syd_gettable((rb_parse_state*)parse_state, i)
  139. static NODE *assignable(ID,NODE*,rb_parse_state*);
  140. static NODE *aryset(NODE*,NODE*,rb_parse_state*);
  141. static NODE *attrset(NODE*,ID,rb_parse_state*);
  142. static void rb_backref_error(NODE*,rb_parse_state*);
  143. static NODE *node_assign(NODE*,NODE*,rb_parse_state*);
  144. static NODE *match_gen(NODE*,NODE*,rb_parse_state*);
  145. static void syd_local_push(rb_parse_state*, int cnt);
  146. #define local_push(cnt) syd_local_push(vps, cnt)
  147. static void syd_local_pop(rb_parse_state*);
  148. #define local_pop() syd_local_pop(vps)
  149. static intptr_t syd_local_cnt(rb_parse_state*,ID);
  150. #define local_cnt(i) syd_local_cnt(vps, i)
  151. static int syd_local_id(rb_parse_state*,ID);
  152. #define local_id(i) syd_local_id(vps, i)
  153. static ID *syd_local_tbl(rb_parse_state *st);
  154. static ID convert_op(ID id);
  155. static void tokadd(char c, rb_parse_state *parse_state);
  156. static int tokadd_string(int, int, int, quark *, rb_parse_state*);
  157. #define SHOW_PARSER_WARNS 0
  158. static int rb_compile_error(rb_parse_state *st, const char *fmt, ...) {
  159. va_list ar;
  160. char msg[256];
  161. int count;
  162. va_start(ar, fmt);
  163. count = vsnprintf(msg, 256, fmt, ar);
  164. va_end(ar);
  165. syd_yyerror(msg, st);
  166. return count;
  167. }
  168. static int _debug_print(const char *fmt, ...) {
  169. #if SHOW_PARSER_WARNS
  170. va_list ar;
  171. int i;
  172. va_start(ar, fmt);
  173. i = vprintf(fmt, ar);
  174. va_end(ar);
  175. return i;
  176. #else
  177. return 0;
  178. #endif
  179. }
  180. #define rb_warn _debug_print
  181. #define rb_warning _debug_print
  182. static ID rb_intern(const char *name);
  183. static ID rb_id_attrset(ID);
  184. rb_parse_state *alloc_parse_state();
  185. static unsigned long scan_oct(const char *start, int len, int *retlen);
  186. static unsigned long scan_hex(const char *start, int len, int *retlen);
  187. static void reset_block(rb_parse_state *parse_state);
  188. static NODE *extract_block_vars(rb_parse_state *parse_state, NODE* node, var_table vars);
  189. #define ruby_verbose 0
  190. #define RE_OPTION_ONCE 0x80
  191. #define RE_OPTION_IGNORECASE (1L)
  192. #define RE_OPTION_EXTENDED (RE_OPTION_IGNORECASE<<1)
  193. #define RE_OPTION_MULTILINE (RE_OPTION_EXTENDED<<1)
  194. #define RE_OPTION_SINGLELINE (RE_OPTION_MULTILINE<<1)
  195. #define RE_OPTION_LONGEST (RE_OPTION_SINGLELINE<<1)
  196. #define RE_MAY_IGNORECASE (RE_OPTION_LONGEST<<1)
  197. #define RE_OPTIMIZE_ANCHOR (RE_MAY_IGNORECASE<<1)
  198. #define RE_OPTIMIZE_EXACTN (RE_OPTIMIZE_ANCHOR<<1)
  199. #define RE_OPTIMIZE_NO_BM (RE_OPTIMIZE_EXACTN<<1)
  200. #define RE_OPTIMIZE_BMATCH (RE_OPTIMIZE_NO_BM<<1)
  201. #define NODE_STRTERM NODE_ZARRAY /* nothing to gc */
  202. #define NODE_HEREDOC NODE_ARRAY /* 1, 3 to gc */
  203. #define SIGN_EXTEND(x,n) (((1<<((n)-1))^((x)&~(~0<<(n))))-(1<<((n)-1)))
  204. #define nd_func u1.id
  205. #if SIZEOF_SHORT != 2
  206. #define nd_term(node) SIGN_EXTEND((node)->u2.id, (CHAR_BIT*2))
  207. #else
  208. #define nd_term(node) ((signed short)(node)->u2.id)
  209. #endif
  210. #define nd_paren(node) (char)((node)->u2.id >> (CHAR_BIT*2))
  211. #define nd_nest u3.id
  212. /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,
  213. for instance). This is too low for Ruby to parse some files, such as
  214. date/format.rb, therefore bump the value up to at least Bison's default. */
  215. #ifdef OLD_YACC
  216. #ifndef YYMAXDEPTH
  217. #define YYMAXDEPTH 10000
  218. #endif
  219. #endif
  220. #define vps ((rb_parse_state*)parse_state)
  221. %}
  222. %pure-parser
  223. %union {
  224. NODE *node;
  225. ID id;
  226. int num;
  227. var_table vars;
  228. }
  229. %token kCLASS
  230. kMODULE
  231. kDEF
  232. kUNDEF
  233. kBEGIN
  234. kRESCUE
  235. kENSURE
  236. kEND
  237. kIF
  238. kUNLESS
  239. kTHEN
  240. kELSIF
  241. kELSE
  242. kCASE
  243. kWHEN
  244. kWHILE
  245. kUNTIL
  246. kFOR
  247. kBREAK
  248. kNEXT
  249. kREDO
  250. kRETRY
  251. kIN
  252. kDO
  253. kDO_COND
  254. kDO_BLOCK
  255. kRETURN
  256. kYIELD
  257. kSUPER
  258. kSELF
  259. kNIL
  260. kTRUE
  261. kFALSE
  262. kAND
  263. kOR
  264. kNOT
  265. kIF_MOD
  266. kUNLESS_MOD
  267. kWHILE_MOD
  268. kUNTIL_MOD
  269. kRESCUE_MOD
  270. kALIAS
  271. kDEFINED
  272. klBEGIN
  273. klEND
  274. k__LINE__
  275. k__FILE__
  276. k__END__
  277. %token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tXSTRING_BEG
  278. %token <node> tINTEGER tFLOAT tSTRING_CONTENT tEND_DATA
  279. %token <node> tNTH_REF tBACK_REF
  280. %token <num> tREGEXP_END
  281. %type <node> singleton strings string string1 xstring regexp
  282. %type <node> string_contents xstring_contents string_content
  283. %type <node> words qwords word_list qword_list word
  284. %type <node> literal numeric dsym cpath
  285. %type <node> bodystmt compstmt opt_end_data stmts stmt expr arg primary command command_call method_call
  286. %type <node> expr_value arg_value primary_value
  287. %type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
  288. %type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args
  289. %type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
  290. %type <node> mrhs superclass block_call block_command
  291. %type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
  292. %type <node> assoc_list assocs assoc undef_list backref string_dvar
  293. %type <node> block_var opt_block_var brace_block cmd_brace_block do_block lhs none fitem
  294. %type <node> mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node
  295. %type <id> fsym variable sym symbol operation operation2 operation3
  296. %type <id> cname fname op f_rest_arg
  297. %type <num> f_norm_arg f_arg
  298. %token tUPLUS /* unary+ */
  299. %token tUMINUS /* unary- */
  300. %token tUBS /* unary\ */
  301. %token tPOW /* ** */
  302. %token tCMP /* <=> */
  303. %token tEQ /* == */
  304. %token tEQQ /* === */
  305. %token tNEQ /* != */
  306. %token tGEQ /* >= */
  307. %token tLEQ /* <= */
  308. %token tANDOP tOROP /* && and || */
  309. %token tMATCH tNMATCH /* =~ and !~ */
  310. %token tDOT2 tDOT3 /* .. and ... */
  311. %token tAREF tASET /* [] and []= */
  312. %token tLSHFT tRSHFT /* << and >> */
  313. %token tCOLON2 /* :: */
  314. %token tCOLON3 /* :: at EXPR_BEG */
  315. %token <id> tOP_ASGN /* +=, -= etc. */
  316. %token tASSOC /* => */
  317. %token tLPAREN /* ( */
  318. %token tLPAREN_ARG /* ( */
  319. %token tRPAREN /* ) */
  320. %token tLBRACK /* [ */
  321. %token tLBRACE /* { */
  322. %token tLBRACE_ARG /* { */
  323. %token tSTAR /* * */
  324. %token tAMPER /* & */
  325. %token tSYMBEG tSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
  326. %token tSTRING_DBEG tSTRING_DVAR tSTRING_END
  327. /*
  328. * precedence table
  329. */
  330. %nonassoc tLOWEST
  331. %nonassoc tLBRACE_ARG
  332. %nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
  333. %left kOR kAND
  334. %right kNOT
  335. %nonassoc kDEFINED
  336. %right '=' tOP_ASGN
  337. %left kRESCUE_MOD
  338. %right '?' ':'
  339. %nonassoc tDOT2 tDOT3
  340. %left tOROP
  341. %left tANDOP
  342. %nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
  343. %left '>' tGEQ '<' tLEQ
  344. %left '|' '^'
  345. %left '&'
  346. %left tLSHFT tRSHFT
  347. %left '+' '-'
  348. %left '*' '/' '%'
  349. %right tUMINUS_NUM tUMINUS
  350. %right tPOW
  351. %right '!' '~' tUPLUS
  352. %token tLAST_TOKEN
  353. %%
  354. program : {
  355. vps->lex_state = EXPR_BEG;
  356. vps->variables = new LocalState(0);
  357. class_nest = 0;
  358. }
  359. compstmt opt_end_data
  360. {
  361. if ($2 && !compile_for_eval) {
  362. /* last expression should not be void */
  363. if (nd_type($2) != NODE_BLOCK) void_expr($2);
  364. else {
  365. NODE *node = $2;
  366. while (node->nd_next) {
  367. node = node->nd_next;
  368. }
  369. void_expr(node->nd_head);
  370. }
  371. }
  372. vps->top = block_append(vps, vps->top, $2);
  373. if ($3)
  374. vps->top = block_append(vps, $3, vps->top);
  375. class_nest = 0;
  376. }
  377. ;
  378. bodystmt : compstmt
  379. opt_rescue
  380. opt_else
  381. opt_ensure
  382. {
  383. $$ = $1;
  384. if ($2) {
  385. $$ = NEW_RESCUE($1, $2, $3);
  386. }
  387. else if ($3) {
  388. rb_warn("else without rescue is useless");
  389. $$ = block_append(vps, $$, $3);
  390. }
  391. if ($4) {
  392. $$ = NEW_ENSURE($$, $4);
  393. }
  394. fixpos($$, $1);
  395. }
  396. ;
  397. compstmt : stmts opt_terms
  398. {
  399. void_stmts($1, vps);
  400. $$ = $1;
  401. }
  402. ;
  403. opt_end_data : none
  404. | k__END__ tEND_DATA
  405. {
  406. $$ = $2;
  407. }
  408. stmts : none
  409. | stmt
  410. {
  411. $$ = newline_node(vps, $1);
  412. }
  413. | stmts terms stmt
  414. {
  415. $$ = block_append(vps, $1, newline_node(vps, $3));
  416. }
  417. | error stmt
  418. {
  419. $$ = remove_begin($2, vps);
  420. }
  421. ;
  422. stmt : kALIAS fitem {vps->lex_state = EXPR_FNAME;} fitem
  423. {
  424. $$ = NEW_ALIAS($2, $4);
  425. }
  426. | kALIAS tGVAR tGVAR
  427. {
  428. $$ = NEW_VALIAS($2, $3);
  429. }
  430. | kALIAS tGVAR tBACK_REF
  431. {
  432. char buf[3];
  433. snprintf(buf, sizeof(buf), "$%c", (char)$3->nd_nth);
  434. $$ = NEW_VALIAS($2, rb_intern(buf));
  435. }
  436. | kALIAS tGVAR tNTH_REF
  437. {
  438. yyerror("can't make alias for the number variables");
  439. $$ = 0;
  440. }
  441. | kUNDEF undef_list
  442. {
  443. $$ = $2;
  444. }
  445. | stmt kIF_MOD expr_value
  446. {
  447. $$ = NEW_IF(cond($3, vps), remove_begin($1, vps), 0);
  448. fixpos($$, $3);
  449. if (cond_negative(&$$->nd_cond)) {
  450. $$->nd_else = $$->nd_body;
  451. $$->nd_body = 0;
  452. }
  453. }
  454. | stmt kUNLESS_MOD expr_value
  455. {
  456. $$ = NEW_UNLESS(cond($3, vps), remove_begin($1, vps), 0);
  457. fixpos($$, $3);
  458. if (cond_negative(&$$->nd_cond)) {
  459. $$->nd_body = $$->nd_else;
  460. $$->nd_else = 0;
  461. }
  462. }
  463. | stmt kWHILE_MOD expr_value
  464. {
  465. if ($1 && nd_type($1) == NODE_BEGIN) {
  466. $$ = NEW_WHILE(cond($3, vps), $1->nd_body, 0);
  467. }
  468. else {
  469. $$ = NEW_WHILE(cond($3, vps), $1, 1);
  470. }
  471. if (cond_negative(&$$->nd_cond)) {
  472. nd_set_type($$, NODE_UNTIL);
  473. }
  474. }
  475. | stmt kUNTIL_MOD expr_value
  476. {
  477. if ($1 && nd_type($1) == NODE_BEGIN) {
  478. $$ = NEW_UNTIL(cond($3, vps), $1->nd_body, 0);
  479. }
  480. else {
  481. $$ = NEW_UNTIL(cond($3, vps), $1, 1);
  482. }
  483. if (cond_negative(&$$->nd_cond)) {
  484. nd_set_type($$, NODE_WHILE);
  485. }
  486. }
  487. | stmt kRESCUE_MOD stmt
  488. {
  489. NODE *resq = NEW_RESBODY(0, remove_begin($3, vps), 0);
  490. $$ = NEW_RESCUE(remove_begin($1, vps), resq, 0);
  491. }
  492. | klBEGIN
  493. {
  494. if (in_def || in_single) {
  495. yyerror("BEGIN in method");
  496. }
  497. local_push(0);
  498. }
  499. '{' compstmt '}'
  500. {
  501. /*
  502. ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
  503. NEW_PREEXE($4));
  504. */
  505. local_pop();
  506. $$ = 0;
  507. }
  508. | klEND '{' compstmt '}'
  509. {
  510. if (in_def || in_single) {
  511. rb_warn("END in method; use at_exit");
  512. }
  513. $$ = NEW_ITER(0, NEW_POSTEXE(), $3);
  514. }
  515. | lhs '=' command_call
  516. {
  517. $$ = node_assign($1, $3, vps);
  518. }
  519. | mlhs '=' command_call
  520. {
  521. value_expr($3);
  522. $1->nd_value = ($1->nd_head) ? NEW_TO_ARY($3) : NEW_ARRAY($3);
  523. $$ = $1;
  524. }
  525. | var_lhs tOP_ASGN command_call
  526. {
  527. value_expr($3);
  528. if ($1) {
  529. ID vid = $1->nd_vid;
  530. if ($2 == tOROP) {
  531. $1->nd_value = $3;
  532. $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
  533. if (is_asgn_or_id(vid)) {
  534. $$->nd_aid = vid;
  535. }
  536. }
  537. else if ($2 == tANDOP) {
  538. $1->nd_value = $3;
  539. $$ = NEW_OP_ASGN_AND(gettable(vid), $1);
  540. }
  541. else {
  542. $$ = $1;
  543. $$->nd_value = call_op(gettable(vid),$2,1,$3, vps);
  544. }
  545. }
  546. else {
  547. $$ = 0;
  548. }
  549. }
  550. | primary_value '[' aref_args ']' tOP_ASGN command_call
  551. {
  552. NODE *args;
  553. value_expr($6);
  554. if (!$3) $3 = NEW_ZARRAY();
  555. args = arg_concat(vps, $6, $3);
  556. if ($5 == tOROP) {
  557. $5 = 0;
  558. }
  559. else if ($5 == tANDOP) {
  560. $5 = 1;
  561. }
  562. $$ = NEW_OP_ASGN1($1, $5, args);
  563. fixpos($$, $1);
  564. }
  565. | primary_value '.' tIDENTIFIER tOP_ASGN command_call
  566. {
  567. value_expr($5);
  568. if ($4 == tOROP) {
  569. $4 = 0;
  570. }
  571. else if ($4 == tANDOP) {
  572. $4 = 1;
  573. }
  574. $$ = NEW_OP_ASGN2($1, $3, $4, $5);
  575. fixpos($$, $1);
  576. }
  577. | primary_value '.' tCONSTANT tOP_ASGN command_call
  578. {
  579. value_expr($5);
  580. if ($4 == tOROP) {
  581. $4 = 0;
  582. }
  583. else if ($4 == tANDOP) {
  584. $4 = 1;
  585. }
  586. $$ = NEW_OP_ASGN2($1, $3, $4, $5);
  587. fixpos($$, $1);
  588. }
  589. | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
  590. {
  591. value_expr($5);
  592. if ($4 == tOROP) {
  593. $4 = 0;
  594. }
  595. else if ($4 == tANDOP) {
  596. $4 = 1;
  597. }
  598. $$ = NEW_OP_ASGN2($1, $3, $4, $5);
  599. fixpos($$, $1);
  600. }
  601. | backref tOP_ASGN command_call
  602. {
  603. rb_backref_error($1, vps);
  604. $$ = 0;
  605. }
  606. | lhs '=' mrhs
  607. {
  608. $$ = node_assign($1, NEW_SVALUE($3), vps);
  609. }
  610. | mlhs '=' arg_value
  611. {
  612. $1->nd_value = ($1->nd_head) ? NEW_TO_ARY($3) : NEW_ARRAY($3);
  613. $$ = $1;
  614. }
  615. | mlhs '=' mrhs
  616. {
  617. $1->nd_value = $3;
  618. $$ = $1;
  619. }
  620. | expr
  621. ;
  622. expr : command_call
  623. | expr kAND expr
  624. {
  625. $$ = logop(NODE_AND, $1, $3, vps);
  626. }
  627. | expr kOR expr
  628. {
  629. $$ = logop(NODE_OR, $1, $3, vps);
  630. }
  631. | kNOT expr
  632. {
  633. $$ = NEW_NOT(cond($2, vps));
  634. }
  635. | '!' command_call
  636. {
  637. $$ = NEW_NOT(cond($2, vps));
  638. }
  639. | arg
  640. ;
  641. expr_value : expr
  642. {
  643. value_expr($$);
  644. $$ = $1;
  645. }
  646. ;
  647. command_call : command
  648. | block_command
  649. | kRETURN call_args
  650. {
  651. $$ = NEW_RETURN(ret_args(vps, $2));
  652. }
  653. | kBREAK call_args
  654. {
  655. $$ = NEW_BREAK(ret_args(vps, $2));
  656. }
  657. | kNEXT call_args
  658. {
  659. $$ = NEW_NEXT(ret_args(vps, $2));
  660. }
  661. ;
  662. block_command : block_call
  663. | block_call '.' operation2 command_args
  664. {
  665. $$ = new_call(vps, $1, $3, $4);
  666. }
  667. | block_call tCOLON2 operation2 command_args
  668. {
  669. $$ = new_call(vps, $1, $3, $4);
  670. }
  671. ;
  672. cmd_brace_block : tLBRACE_ARG
  673. {
  674. $<num>1 = ruby_sourceline;
  675. reset_block(vps);
  676. }
  677. opt_block_var { $<vars>$ = vps->variables->block_vars; }
  678. compstmt
  679. '}'
  680. {
  681. $$ = NEW_ITER($3, 0, extract_block_vars(vps, $5, $<vars>4));
  682. nd_set_line($$, $<num>1);
  683. }
  684. ;
  685. command : operation command_args %prec tLOWEST
  686. {
  687. $$ = new_fcall(vps, $1, $2);
  688. fixpos($$, $2);
  689. }
  690. | operation command_args cmd_brace_block
  691. {
  692. $$ = new_fcall(vps, $1, $2);
  693. if ($3) {
  694. if (nd_type($$) == NODE_BLOCK_PASS) {
  695. rb_compile_error(vps, "both block arg and actual block given");
  696. }
  697. $3->nd_iter = $$;
  698. $$ = $3;
  699. }
  700. fixpos($$, $2);
  701. }
  702. | primary_value '.' operation2 command_args %prec tLOWEST
  703. {
  704. $$ = new_call(vps, $1, $3, $4);
  705. fixpos($$, $1);
  706. }
  707. | primary_value '.' operation2 command_args cmd_brace_block
  708. {
  709. $$ = new_call(vps, $1, $3, $4);
  710. if ($5) {
  711. if (nd_type($$) == NODE_BLOCK_PASS) {
  712. rb_compile_error(vps, "both block arg and actual block given");
  713. }
  714. $5->nd_iter = $$;
  715. $$ = $5;
  716. }
  717. fixpos($$, $1);
  718. }
  719. | primary_value tCOLON2 operation2 command_args %prec tLOWEST
  720. {
  721. $$ = new_call(vps, $1, $3, $4);
  722. fixpos($$, $1);
  723. }
  724. | primary_value tCOLON2 operation2 command_args cmd_brace_block
  725. {
  726. $$ = new_call(vps, $1, $3, $4);
  727. if ($5) {
  728. if (nd_type($$) == NODE_BLOCK_PASS) {
  729. rb_compile_error(vps, "both block arg and actual block given");
  730. }
  731. $5->nd_iter = $$;
  732. $$ = $5;
  733. }
  734. fixpos($$, $1);
  735. }
  736. | kSUPER command_args
  737. {
  738. $$ = new_super(vps, $2);
  739. fixpos($$, $2);
  740. }
  741. | kYIELD command_args
  742. {
  743. $$ = new_yield(vps, $2);
  744. fixpos($$, $2);
  745. }
  746. ;
  747. mlhs : mlhs_basic
  748. | tLPAREN mlhs_entry ')'
  749. {
  750. $$ = $2;
  751. }
  752. ;
  753. mlhs_entry : mlhs_basic
  754. | tLPAREN mlhs_entry ')'
  755. {
  756. $$ = NEW_MASGN(NEW_LIST($2), 0);
  757. }
  758. ;
  759. mlhs_basic : mlhs_head
  760. {
  761. $$ = NEW_MASGN($1, 0);
  762. }
  763. | mlhs_head mlhs_item
  764. {
  765. $$ = NEW_MASGN(list_append(vps, $1,$2), 0);
  766. }
  767. | mlhs_head tSTAR mlhs_node
  768. {
  769. $$ = NEW_MASGN($1, $3);
  770. }
  771. | mlhs_head tSTAR
  772. {
  773. $$ = NEW_MASGN($1, -1);
  774. }
  775. | tSTAR mlhs_node
  776. {
  777. $$ = NEW_MASGN(0, $2);
  778. }
  779. | tSTAR
  780. {
  781. $$ = NEW_MASGN(0, -1);
  782. }
  783. ;
  784. mlhs_item : mlhs_node
  785. | tLPAREN mlhs_entry ')'
  786. {
  787. $$ = $2;
  788. }
  789. ;
  790. mlhs_head : mlhs_item ','
  791. {
  792. $$ = NEW_LIST($1);
  793. }
  794. | mlhs_head mlhs_item ','
  795. {
  796. $$ = list_append(vps, $1, $2);
  797. }
  798. ;
  799. mlhs_node : variable
  800. {
  801. $$ = assignable($1, 0, vps);
  802. }
  803. | primary_value '[' aref_args ']'
  804. {
  805. $$ = aryset($1, $3, vps);
  806. }
  807. | primary_value '.' tIDENTIFIER
  808. {
  809. $$ = attrset($1, $3, vps);
  810. }
  811. | primary_value tCOLON2 tIDENTIFIER
  812. {
  813. $$ = attrset($1, $3, vps);
  814. }
  815. | primary_value '.' tCONSTANT
  816. {
  817. $$ = attrset($1, $3, vps);
  818. }
  819. | primary_value tCOLON2 tCONSTANT
  820. {
  821. if (in_def || in_single)
  822. yyerror("dynamic constant assignment");
  823. $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
  824. }
  825. | tCOLON3 tCONSTANT
  826. {
  827. if (in_def || in_single)
  828. yyerror("dynamic constant assignment");
  829. $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
  830. }
  831. | backref
  832. {
  833. rb_backref_error($1, vps);
  834. $$ = 0;
  835. }
  836. ;
  837. lhs : variable
  838. {
  839. $$ = assignable($1, 0, vps);
  840. }
  841. | primary_value '[' aref_args ']'
  842. {
  843. $$ = aryset($1, $3, vps);
  844. }
  845. | primary_value '.' tIDENTIFIER
  846. {
  847. $$ = attrset($1, $3, vps);
  848. }
  849. | primary_value tCOLON2 tIDENTIFIER
  850. {
  851. $$ = attrset($1, $3, vps);
  852. }
  853. | primary_value '.' tCONSTANT
  854. {
  855. $$ = attrset($1, $3, vps);
  856. }
  857. | primary_value tCOLON2 tCONSTANT
  858. {
  859. if (in_def || in_single)
  860. yyerror("dynamic constant assignment");
  861. $$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));
  862. }
  863. | tCOLON3 tCONSTANT
  864. {
  865. if (in_def || in_single)
  866. yyerror("dynamic constant assignment");
  867. $$ = NEW_CDECL(0, 0, NEW_COLON3($2));
  868. }
  869. | backref
  870. {
  871. rb_backref_error($1, vps);
  872. $$ = 0;
  873. }
  874. ;
  875. cname : tIDENTIFIER
  876. {
  877. yyerror("class/module name must be CONSTANT");
  878. }
  879. | tCONSTANT
  880. ;
  881. cpath : tCOLON3 cname
  882. {
  883. $$ = NEW_COLON3($2);
  884. }
  885. | cname
  886. {
  887. $$ = NEW_COLON2(0, $$);
  888. }
  889. | primary_value tCOLON2 cname
  890. {
  891. $$ = NEW_COLON2($1, $3);
  892. }
  893. ;
  894. fname : tIDENTIFIER
  895. | tCONSTANT
  896. | tFID
  897. | op
  898. {
  899. vps->lex_state = EXPR_END;
  900. $$ = convert_op($1);
  901. }
  902. | reswords
  903. {
  904. vps->lex_state = EXPR_END;
  905. $$ = $<id>1;
  906. }
  907. ;
  908. fsym : fname
  909. | symbol
  910. ;
  911. fitem : fsym
  912. {
  913. $$ = NEW_LIT(ID2SYM($1));
  914. }
  915. | dsym
  916. ;
  917. undef_list : fitem
  918. {
  919. $$ = NEW_UNDEF($1);
  920. }
  921. | undef_list ',' {vps->lex_state = EXPR_FNAME;} fitem
  922. {
  923. $$ = block_append(vps, $1, NEW_UNDEF($4));
  924. }
  925. ;
  926. op : '|' { $$ = '|'; }
  927. | '^' { $$ = '^'; }
  928. | '&' { $$ = '&'; }
  929. | tCMP { $$ = tCMP; }
  930. | tEQ { $$ = tEQ; }
  931. | tEQQ { $$ = tEQQ; }
  932. | tMATCH { $$ = tMATCH; }
  933. | '>' { $$ = '>'; }
  934. | tGEQ { $$ = tGEQ; }
  935. | '<' { $$ = '<'; }
  936. | tLEQ { $$ = tLEQ; }
  937. | tLSHFT { $$ = tLSHFT; }
  938. | tRSHFT { $$ = tRSHFT; }
  939. | '+' { $$ = '+'; }
  940. | '-' { $$ = '-'; }
  941. | '*' { $$ = '*'; }
  942. | tSTAR { $$ = '*'; }
  943. | '/' { $$ = '/'; }
  944. | '%' { $$ = '%'; }
  945. | tPOW { $$ = tPOW; }
  946. | '~' { $$ = '~'; }
  947. | tUPLUS { $$ = tUPLUS; }
  948. | tUMINUS { $$ = tUMINUS; }
  949. | tAREF { $$ = tAREF; }
  950. | tASET { $$ = tASET; }
  951. | '`' { $$ = '`'; }
  952. ;
  953. reswords : k__LINE__ | k__FILE__ | klBEGIN | klEND | k__END__
  954. | kALIAS | kAND | kBEGIN | kBREAK | kCASE | kCLASS | kDEF
  955. | kDEFINED | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE
  956. | kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT
  957. | kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF | kSUPER
  958. | kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD
  959. | kIF_MOD | kUNLESS_MOD | kWHILE_MOD | kUNTIL_MOD | kRESCUE_MOD
  960. ;
  961. arg : lhs '=' arg
  962. {
  963. $$ = node_assign($1, $3, vps);
  964. }
  965. | lhs '=' arg kRESCUE_MOD arg
  966. {
  967. $$ = node_assign($1, NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0), vps);
  968. }
  969. | var_lhs tOP_ASGN arg
  970. {
  971. value_expr($3);
  972. if ($1) {
  973. ID vid = $1->nd_vid;
  974. if ($2 == tOROP) {
  975. $1->nd_value = $3;
  976. $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
  977. if (is_asgn_or_id(vid)) {
  978. $$->nd_aid = vid;
  979. }
  980. }
  981. else if ($2 == tANDOP) {
  982. $1->nd_value = $3;
  983. $$ = NEW_OP_ASGN_AND(gettable(vid), $1);
  984. }
  985. else {
  986. $$ = $1;
  987. $$->nd_value = call_op(gettable(vid),$2,1,$3, vps);
  988. }
  989. }
  990. else {
  991. $$ = 0;
  992. }
  993. }
  994. | primary_value '[' aref_args ']' tOP_ASGN arg
  995. {
  996. NODE *args;
  997. value_expr($6);
  998. if (!$3) $3 = NEW_ZARRAY();
  999. args = arg_concat(vps, $6, $3);
  1000. if ($5 == tOROP) {
  1001. $5 = 0;
  1002. }
  1003. else if ($5 == tANDOP) {
  1004. $5 = 1;
  1005. }
  1006. $$ = NEW_OP_ASGN1($1, $5, args);
  1007. fixpos($$, $1);
  1008. }
  1009. | primary_value '.' tIDENTIFIER tOP_ASGN arg
  1010. {
  1011. value_expr($5);
  1012. if ($4 == tOROP) {
  1013. $4 = 0;
  1014. }
  1015. else if ($4 == tANDOP) {
  1016. $4 = 1;
  1017. }
  1018. $$ = NEW_OP_ASGN2($1, $3, $4, $5);
  1019. fixpos($$, $1);
  1020. }
  1021. | primary_value '.' tCONSTANT tOP_ASGN arg
  1022. {
  1023. value_expr($5);
  1024. if ($4 == tOROP) {
  1025. $4 = 0;
  1026. }
  1027. else if ($4 == tANDOP) {
  1028. $4 = 1;
  1029. }
  1030. $$ = NEW_OP_ASGN2($1, $3, $4, $5);
  1031. fixpos($$, $1);
  1032. }
  1033. | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
  1034. {
  1035. value_expr($5);
  1036. if ($4 == tOROP) {
  1037. $4 = 0;
  1038. }
  1039. else if ($4 == tANDOP) {
  1040. $4 = 1;
  1041. }
  1042. $$ = NEW_OP_ASGN2($1, $3, $4, $5);
  1043. fixpos($$, $1);
  1044. }
  1045. | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
  1046. {
  1047. yyerror("constant re-assignment");
  1048. $$ = 0;
  1049. }
  1050. | tCOLON3 tCONSTANT tOP_ASGN arg
  1051. {
  1052. yyerror("constant re-assignment");
  1053. $$ = 0;
  1054. }
  1055. | backref tOP_ASGN arg
  1056. {
  1057. rb_backref_error($1, vps);
  1058. $$ = 0;
  1059. }
  1060. | arg tDOT2 arg
  1061. {
  1062. value_expr($1);
  1063. value_expr($3);
  1064. $$ = NEW_DOT2($1, $3);
  1065. }
  1066. | arg tDOT3 arg
  1067. {
  1068. value_expr($1);
  1069. value_expr($3);
  1070. $$ = NEW_DOT3($1, $3);
  1071. }
  1072. | arg '+' arg
  1073. {
  1074. $$ = call_op($1, '+', 1, $3, vps);
  1075. }
  1076. | arg '-' arg
  1077. {
  1078. $$ = call_op($1, '-', 1, $3, vps);
  1079. }
  1080. | arg '*' arg
  1081. {
  1082. $$ = call_op($1, '*', 1, $3, vps);
  1083. }
  1084. | arg '/' arg
  1085. {
  1086. $$ = call_op($1, '/', 1, $3, vps);
  1087. }
  1088. | arg '%' arg
  1089. {
  1090. $$ = call_op($1, '%', 1, $3, vps);
  1091. }
  1092. | arg tPOW arg
  1093. {
  1094. $$ = call_op($1, tPOW, 1, $3, vps);
  1095. }
  1096. | tUMINUS_NUM tINTEGER tPOW arg
  1097. {
  1098. $$ = call_op(call_op($2, tPOW, 1, $4, vps), tUMINUS, 0, 0, vps);
  1099. }
  1100. | tUMINUS_NUM tFLOAT tPOW arg
  1101. {
  1102. $$ = call_op(call_op($2, tPOW, 1, $4, vps), tUMINUS, 0, 0, vps);
  1103. }
  1104. | tUPLUS arg
  1105. {
  1106. if ($2 && nd_type($2) == NODE_LIT) {
  1107. $$ = $2;
  1108. }
  1109. else {
  1110. $$ = call_op($2, tUPLUS, 0, 0, vps);
  1111. }
  1112. }
  1113. | tUMINUS arg
  1114. {
  1115. $$ = call_op($2, tUMINUS, 0, 0, vps);
  1116. }
  1117. | arg '|' arg
  1118. {
  1119. $$ = call_op($1, '|', 1, $3, vps);
  1120. }
  1121. | arg '^' arg
  1122. {
  1123. $$ = call_op($1, '^', 1, $3, vps);
  1124. }
  1125. | arg '&' arg
  1126. {
  1127. $$ = call_op($1, '&', 1, $3, vps);
  1128. }
  1129. | arg tCMP arg
  1130. {
  1131. $$ = call_op($1, tCMP, 1, $3, vps);
  1132. }
  1133. | arg '>' arg
  1134. {
  1135. $$ = call_op($1, '>', 1, $3, vps);
  1136. }
  1137. | arg tGEQ arg
  1138. {
  1139. $$ = call_op($1, tGEQ, 1, $3, vps);
  1140. }
  1141. | arg '<' arg
  1142. {
  1143. $$ = call_op($1, '<', 1, $3, vps);
  1144. }
  1145. | arg tLEQ arg
  1146. {
  1147. $$ = call_op($1, tLEQ, 1, $3, vps);
  1148. }
  1149. | arg tEQ arg
  1150. {
  1151. $$ = call_op($1, tEQ, 1, $3, vps);
  1152. }
  1153. | arg tEQQ arg
  1154. {
  1155. $$ = call_op($1, tEQQ, 1, $3, vps);
  1156. }
  1157. | arg tNEQ arg
  1158. {
  1159. $$ = NEW_NOT(call_op($1, tEQ, 1, $3, vps));
  1160. }
  1161. | arg tMATCH arg
  1162. {
  1163. $$ = match_gen($1, $3, vps);
  1164. }
  1165. | arg tNMATCH arg
  1166. {
  1167. $$ = NEW_NOT(match_gen($1, $3, vps));
  1168. }
  1169. | '!' arg
  1170. {
  1171. $$ = NEW_NOT(cond($2, vps));
  1172. }
  1173. | '~' arg
  1174. {
  1175. $$ = call_op($2, '~', 0, 0, vps);
  1176. }
  1177. | arg tLSHFT arg
  1178. {
  1179. $$ = call_op($1, tLSHFT, 1, $3, vps);
  1180. }
  1181. | arg tRSHFT arg
  1182. {
  1183. $$ = call_op($1, tRSHFT, 1, $3, vps);
  1184. }
  1185. | arg tANDOP arg
  1186. {
  1187. $$ = logop(NODE_AND, $1, $3, vps);
  1188. }
  1189. | arg tOROP arg
  1190. {
  1191. $$ = logop(NODE_OR, $1, $3, vps);
  1192. }
  1193. | kDEFINED opt_nl {vps->in_defined = 1;} arg
  1194. {
  1195. vps->in_defined = 0;
  1196. $$ = NEW_DEFINED($4);
  1197. }
  1198. | arg '?' {vps->ternary_colon++;} arg ':' arg
  1199. {
  1200. $$ = NEW_IF(cond($1, vps), $4, $6);
  1201. fixpos($$, $1);
  1202. vps->ternary_colon--;
  1203. }
  1204. | primary
  1205. {
  1206. $$ = $1;
  1207. }
  1208. ;
  1209. arg_value : arg
  1210. {
  1211. value_expr($1);
  1212. $$ = $1;
  1213. }
  1214. ;
  1215. aref_args : none
  1216. | command opt_nl
  1217. {
  1218. rb_warn("parenthesize argument(s) for future version");
  1219. $$ = NEW_LIST($1);
  1220. }
  1221. | args trailer
  1222. {
  1223. $$ = $1;
  1224. }
  1225. | args ',' tSTAR arg opt_nl
  1226. {
  1227. value_expr($4);
  1228. $$ = arg_concat(vps, $1, $4);
  1229. }
  1230. | assocs trailer
  1231. {
  1232. $$ = NEW_LIST(NEW_HASH($1));
  1233. }
  1234. | tSTAR arg opt_nl
  1235. {
  1236. value_expr($2);
  1237. $$ = NEW_NEWLINE(NEW_SPLAT($2));
  1238. }
  1239. ;
  1240. paren_args : '(' none ')'
  1241. {
  1242. $$ = $2;
  1243. }
  1244. | '(' call_args opt_nl ')'
  1245. {
  1246. $$ = $2;
  1247. }
  1248. | '(' block_call opt_nl ')'
  1249. {
  1250. rb_warn("parenthesize argument for future version");
  1251. $$ = NEW_LIST($2);
  1252. }
  1253. | '(' args ',' block_call opt_nl ')'
  1254. {
  1255. rb_warn("parenthesize argument for future version");
  1256. $$ = list_append(vps, $2, $4);
  1257. }
  1258. ;
  1259. opt_paren_args : none
  1260. | paren_args
  1261. ;
  1262. call_args : command
  1263. {
  1264. rb_warn("parenthesize argument(s) for future version");
  1265. $$ = NEW_LIST($1);
  1266. }
  1267. | args opt_block_arg
  1268. {
  1269. $$ = arg_blk_pass($1, $2);
  1270. }
  1271. | args ',' tSTAR arg_value opt_block_arg
  1272. {
  1273. $$ = arg_concat(vps, $1, $4);
  1274. $$ = arg_blk_pass($$, $5);
  1275. }
  1276. | assocs opt_block_arg
  1277. {
  1278. $$ = NEW_LIST(NEW_HASH($1));
  1279. $$ = arg_blk_pass($$, $2);
  1280. }
  1281. | assocs ',' tSTAR arg_value opt_block_arg
  1282. {
  1283. $$ = arg_concat(vps, NEW_LIST(NEW_HASH($1)), $4);
  1284. $$ = arg_blk_pass($$, $5);
  1285. }
  1286. | args ',' assocs opt_block_arg
  1287. {
  1288. $$ = list_append(vps, $1, NEW_HASH($3));
  1289. $$ = arg_blk_pass($$, $4);
  1290. }
  1291. | args ',' assocs ',' tSTAR arg opt_block_arg
  1292. {
  1293. value_expr($6);
  1294. $$ = arg_concat(vps, list_append(vps, $1, NEW_HASH($3)), $6);
  1295. $$ = arg_blk_pass($$, $7);
  1296. }
  1297. | tSTAR arg_value opt_block_arg
  1298. {
  1299. $$ = arg_blk_pass(NEW_SPLAT($2), $3);
  1300. }
  1301. | block_arg
  1302. ;
  1303. call_args2 : arg_value ',' args opt_block_arg
  1304. {
  1305. $$ = arg_blk_pass(list_concat(NEW_LIST($1),$3), $4);
  1306. }
  1307. | arg_value ',' block_arg
  1308. {
  1309. $$ = arg_blk_pass($1, $3);
  1310. }
  1311. | arg_value ',' tSTAR arg_value opt_block_arg
  1312. {
  1313. $$ = arg_concat(vps, NEW_LIST($1), $4);
  1314. $$ = arg_blk_pass($$, $5);
  1315. }
  1316. | arg_value ',' args ',' tSTAR arg_value opt_block_arg
  1317. {
  1318. $$ = arg_concat(vps, list_concat(NEW_LIST($1),$3), $6);
  1319. $$ = arg_blk_pass($$, $7);
  1320. }
  1321. | assocs opt_block_arg
  1322. {
  1323. $$ = NEW_LIST(NEW_HASH($1));
  1324. $$ = arg_blk_pass($$, $2);
  1325. }
  1326. | assocs ',' tSTAR arg_value opt_block_arg
  1327. {
  1328. $$ = arg_concat(vps, NEW_LIST(NEW_HASH($1)), $4);
  1329. $$ = arg_blk_pass($$, $5);
  1330. }
  1331. | arg_value ',' assocs opt_block_arg
  1332. {
  1333. $$ = list_append(vps, NEW_LIST($1), NEW_HASH($3));
  1334. $$ = arg_blk_pass($$, $4);
  1335. }
  1336. | arg_value ',' args ',' assocs opt_block_arg
  1337. {
  1338. $$ = list_append(vps, list_concat(NEW_LIST($1),$3), NEW_HASH($5));
  1339. $$ = arg_blk_pass($$, $6);
  1340. }
  1341. | arg_value ',' assocs ',' tSTAR arg_value opt_block_arg
  1342. {
  1343. $$ = arg_concat(vps, list_append(vps, NEW_LIST($1), NEW_HASH($3)), $6);
  1344. $$ = arg_blk_pass($$, $7);
  1345. }
  1346. | arg_value ',' args ',' assocs ',' tSTAR arg_value opt_block_arg
  1347. {
  1348. $$ = arg_concat(vps, list_append(vps,
  1349. list_concat(NEW_LIST($1), $3), NEW_HASH($5)), $8);
  1350. $$ = arg_blk_pass($$, $9);
  1351. }
  1352. | tSTAR arg_value opt_block_arg
  1353. {
  1354. $$ = arg_blk_pass(NEW_SPLAT($2), $3);
  1355. }
  1356. | block_arg
  1357. ;
  1358. command_args : {
  1359. $<num>$ = vps->cmdarg_stack;
  1360. CMDARG_PUSH(1);
  1361. }
  1362. open_args
  1363. {
  1364. /* CMDARG_POP() */
  1365. vps->cmdarg_stack = $<num>1;
  1366. $$ = $2;
  1367. }
  1368. ;
  1369. open_args : call_args
  1370. | tLPAREN_ARG {vps->lex_state = EXPR_ENDARG;} ')'
  1371. {
  1372. rb_warn("don't put space before argument parentheses");
  1373. $$ = 0;
  1374. }
  1375. | tLPAREN_ARG call_args2 {vps->lex_state = EXPR_ENDARG;} ')'
  1376. {
  1377. rb_warn("don't put space before argument parentheses");
  1378. $$ = $2;
  1379. }
  1380. ;
  1381. block_arg : tAMPER arg_value
  1382. {
  1383. $$ = NEW_BLOCK_PASS($2);
  1384. }
  1385. ;
  1386. opt_block_arg : ',' block_arg
  1387. {
  1388. $$ = $2;
  1389. }
  1390. | none
  1391. ;
  1392. args : arg_value
  1393. {
  1394. $$ = NEW_LIST($1);
  1395. }
  1396. | args ',' arg_value
  1397. {
  1398. $$ = list_append(vps, $1, $3);
  1399. }
  1400. ;
  1401. mrhs : args ',' arg_value
  1402. {
  1403. $$ = list_append(vps, $1, $3);
  1404. }
  1405. | args ',' tSTAR arg_value
  1406. {
  1407. $$ = arg_concat(vps, $1, $4);
  1408. }
  1409. | tSTAR arg_value
  1410. {
  1411. $$ = NEW_SPLAT($2);
  1412. }
  1413. ;
  1414. primary : literal
  1415. | strings
  1416. | xstring
  1417. | regexp
  1418. | words
  1419. | qwords
  1420. | var_ref
  1421. | backref
  1422. | tFID
  1423. {
  1424. $$ = NEW_FCALL($1, 0);
  1425. }
  1426. | kBEGIN
  1427. {
  1428. $<num>1 = ruby_sourceline;
  1429. }
  1430. bodystmt
  1431. kEND
  1432. {
  1433. if ($3 == NULL)
  1434. $$ = NEW_NIL();
  1435. else
  1436. $$ = NEW_BEGIN($3);
  1437. nd_set_line($$, $<num>1);
  1438. }
  1439. | tLPAREN_ARG expr {vps->lex_state = EXPR_ENDARG;} opt_nl ')'
  1440. {
  1441. rb_warning("(...) interpreted as grouped expression");
  1442. $$ = $2;
  1443. }
  1444. | tLPAREN compstmt ')'
  1445. {
  1446. if (!$2) $$ = NEW_NIL();
  1447. else $$ = $2;
  1448. }
  1449. | primary_value tCOLON2 tCONSTANT
  1450. {
  1451. $$ = NEW_COLON2($1, $3);
  1452. }
  1453. | tCOLON3 tCONSTANT
  1454. {
  1455. $$ = NEW_COLON3($2);
  1456. }
  1457. | primary_value '[' aref_args ']'
  1458. {
  1459. if ($1 && nd_type($1) == NODE_SELF) {
  1460. $$ = NEW_FCALL(convert_op(tAREF), $3);
  1461. } else {
  1462. $$ = NEW_CALL($1, convert_op(tAREF), $3);
  1463. }
  1464. fixpos($$, $1);
  1465. }
  1466. | tLBRACK aref_args ']'
  1467. {
  1468. if ($2 == 0) {
  1469. $$ = NEW_ZARRAY(); /* zero length array*/
  1470. }
  1471. else {
  1472. $$ = $2;
  1473. }
  1474. }
  1475. | tLBRACE assoc_list '}'
  1476. {
  1477. $$ = NEW_HASH($2);
  1478. }
  1479. | kRETURN
  1480. {
  1481. $$ = NEW_RETURN(0);
  1482. }
  1483. | kYIELD '(' call_args ')'
  1484. {
  1485. $$ = new_yield(vps, $3);
  1486. }
  1487. | kYIELD '(' ')'
  1488. {
  1489. $$ = NEW_YIELD(0, Qfalse);
  1490. }
  1491. | kYIELD
  1492. {
  1493. $$ = NEW_YIELD(0, Qfalse);
  1494. }
  1495. | kDEFINED opt_nl '(' {vps->in_defined = 1;} expr ')'
  1496. {
  1497. vps->in_defined = 0;
  1498. $$ = NEW_DEFINED($5);
  1499. }
  1500. | operation brace_block
  1501. {
  1502. $2->nd_iter = NEW_FCALL($1, 0);
  1503. $$ = $2;
  1504. fixpos($2->nd_iter, $2);
  1505. }
  1506. | method_call
  1507. | method_call brace_block
  1508. {
  1509. if ($1 && nd_type($1) == NODE_BLOCK_PASS) {
  1510. rb_compile_error(vps, "both block arg and actual block given");
  1511. }
  1512. $2->nd_iter = $1;
  1513. $$ = $2;
  1514. fixpos($$, $1);
  1515. }
  1516. | kIF expr_value then
  1517. compstmt
  1518. if_tail
  1519. kEND
  1520. {
  1521. $$ = NEW_IF(cond($2, vps), $4, $5);
  1522. fixpos($$, $2);
  1523. if (cond_negative(&$$->nd_cond)) {
  1524. NODE *tmp = $$->nd_body;
  1525. $$->nd_body = $$->nd_else;
  1526. $$->nd_else = tmp;
  1527. }
  1528. }
  1529. | kUNLESS expr_value then
  1530. compstmt
  1531. opt_else
  1532. kEND
  1533. {
  1534. $$ = NEW_UNLESS(cond($2, vps), $4, $5);
  1535. fixpos($$, $2);
  1536. if (cond_negative(&$$->nd_cond)) {
  1537. NODE *tmp = $$->nd_body;
  1538. $$->nd_body = $$->nd_else;
  1539. $$->nd_else = tmp;
  1540. }
  1541. }
  1542. | kWHILE {COND_PUSH(1);} expr_value do {COND_POP();}
  1543. compstmt
  1544. kEND
  1545. {
  1546. $$ = NEW_WHILE(cond($3, vps), $6, 1);
  1547. fixpos($$, $3);
  1548. if (cond_negative(&$$->nd_cond)) {
  1549. nd_set_type($$, NODE_UNTIL);
  1550. }
  1551. }
  1552. | kUNTIL {COND_PUSH(1);} expr_value do {COND_POP();}
  1553. compstmt
  1554. kEND
  1555. {
  1556. $$ = NEW_UNTIL(cond($3, vps), $6, 1);
  1557. fixpos($$, $3);
  1558. if (cond_negative(&$$->nd_cond)) {
  1559. nd_set_type($$, NODE_WHILE);
  1560. }
  1561. }
  1562. | kCASE expr_value opt_terms
  1563. case_body
  1564. kEND
  1565. {
  1566. $$ = NEW_CASE($2, $4);
  1567. fixpos($$, $2);
  1568. }
  1569. | kCASE opt_terms case_body kEND
  1570. {
  1571. $$ = $3;
  1572. }
  1573. | kCASE opt_terms kELSE compstmt kEND
  1574. {
  1575. $$ = $4;
  1576. }
  1577. | kFOR block_var kIN {COND_PUSH(1);} expr_value do {COND_POP();}
  1578. compstmt
  1579. kEND
  1580. {
  1581. $$ = NEW_FOR($2, $5, $8);
  1582. fixpos($$, $2);
  1583. }
  1584. | kCLASS cpath superclass
  1585. {
  1586. if (in_def || in_single)
  1587. yyerror("class definition in method body");
  1588. class_nest++;
  1589. local_push(0);
  1590. $<num>$ = ruby_sourceline;
  1591. }
  1592. bodystmt
  1593. kEND
  1594. {
  1595. $$ = NEW_CLASS($2, $5, $3);
  1596. nd_set_line($$, $<num>4);
  1597. local_pop();
  1598. class_nest--;
  1599. }
  1600. | kCLASS tLSHFT expr
  1601. {
  1602. $<num>$ = in_def;
  1603. in_def = 0;
  1604. }
  1605. term
  1606. {
  1607. $<num>$ = in_single;
  1608. in_single = 0;
  1609. class_nest++;
  1610. local_push(0);
  1611. }
  1612. bodystmt
  1613. kEND
  1614. {
  1615. $$ = NEW_SCLASS($3, $7);
  1616. fixpos($$, $3);
  1617. local_pop();
  1618. class_nest--;
  1619. in_def = $<num>4;
  1620. in_single = $<num>6;
  1621. }
  1622. | kMODULE cpath
  1623. {
  1624. if (in_def || in_single)
  1625. yyerror("module definition in method body");
  1626. class_nest++;
  1627. local_push(0);
  1628. $<num>$ = ruby_sourceline;
  1629. }
  1630. bodystmt
  1631. kEND
  1632. {
  1633. $$ = NEW_MODULE($2, $4);
  1634. nd_set_line($$, $<num>3);
  1635. local_pop();
  1636. class_nest--;
  1637. }
  1638. | kDEF fname
  1639. {
  1640. $<id>$ = cur_mid;
  1641. cur_mid = $2;
  1642. in_def++;
  1643. local_push(0);
  1644. }
  1645. f_arglist
  1646. bodystmt
  1647. kEND
  1648. {
  1649. if (!$5) $5 = NEW_NIL();
  1650. $$ = NEW_DEFN($2, $4, $5, NOEX_PRIVATE);
  1651. fixpos($$, $4);
  1652. local_pop();
  1653. in_def--;
  1654. cur_mid = $<id>3;
  1655. }
  1656. | kDEF singleton dot_or_colon {vps->lex_state = EXPR_FNAME;} fname
  1657. {
  1658. in_single++;
  1659. local_push(0);
  1660. vps->lex_state = EXPR_END; /* force for args */
  1661. }
  1662. f_arglist
  1663. bodystmt
  1664. kEND
  1665. {
  1666. $$ = NEW_DEFS($2, $5, $7, $8);
  1667. fixpos($$, $2);
  1668. local_pop();
  1669. in_single--;
  1670. }
  1671. | kBREAK
  1672. {
  1673. $$ = NEW_BREAK(0);
  1674. }
  1675. | kNEXT
  1676. {
  1677. $$ = NEW_NEXT(0);
  1678. }
  1679. | kREDO
  1680. {
  1681. $$ = NEW_REDO();
  1682. }
  1683. | kRETRY
  1684. {
  1685. $$ = NEW_RETRY();
  1686. }
  1687. ;
  1688. primary_value : primary
  1689. {
  1690. value_expr($1);
  1691. $$ = $1;
  1692. }
  1693. ;
  1694. then : term
  1695. | ':'
  1696. | kTHEN
  1697. | term kTHEN
  1698. ;
  1699. do : term
  1700. | ':'
  1701. | kDO_COND
  1702. ;
  1703. if_tail : opt_else
  1704. | kELSIF expr_value then
  1705. compstmt
  1706. if_tail
  1707. {
  1708. $$ = NEW_IF(cond($2, vps), $4, $5);
  1709. fixpos($$, $2);
  1710. }
  1711. ;
  1712. opt_else : none
  1713. | kELSE compstmt
  1714. {
  1715. $$ = $2;
  1716. }
  1717. ;
  1718. block_var : lhs
  1719. | mlhs
  1720. ;
  1721. opt_block_var : none
  1722. | '|' /* none */ '|'
  1723. {
  1724. $$ = (NODE*)1;
  1725. command_start = TRUE;
  1726. }
  1727. | tOROP
  1728. {
  1729. $$ = (NODE*)1;
  1730. command_start = TRUE;
  1731. }
  1732. | '|' block_var '|'
  1733. {
  1734. $$ = $2;
  1735. command_start = TRUE;
  1736. }
  1737. ;
  1738. do_block : kDO_BLOCK
  1739. {
  1740. $<num>1 = ruby_sourceline;
  1741. reset_block(vps);
  1742. }
  1743. opt_block_var
  1744. {
  1745. $<vars>$ = vps->variables->block_vars;
  1746. }
  1747. compstmt
  1748. kEND
  1749. {
  1750. $$ = NEW_ITER($3, 0, extract_block_vars(vps, $5, $<vars>4));
  1751. nd_set_line($$, $<num>1);
  1752. }
  1753. ;
  1754. block_call : command do_block
  1755. {
  1756. if ($1 && nd_type($1) == NODE_BLOCK_PASS) {
  1757. rb_compile_error(vps, "both block arg and actual block given");
  1758. }
  1759. $2->nd_iter = $1;
  1760. $$ = $2;
  1761. fixpos($$, $1);
  1762. }
  1763. | block_call '.' operation2 opt_paren_args
  1764. {
  1765. $$ = new_call(vps, $1, $3, $4);
  1766. }
  1767. | block_call tCOLON2 operation2 opt_paren_args
  1768. {
  1769. $$ = new_call(vps, $1, $3, $4);
  1770. }
  1771. ;
  1772. method_call : operation paren_args
  1773. {
  1774. $$ = new_fcall(vps, $1, $2);
  1775. fixpos($$, $2);
  1776. }
  1777. | primary_value '.' operation2 opt_paren_args
  1778. {
  1779. $$ = new_call(vps, $1, $3, $4);
  1780. fixpos($$, $1);
  1781. }
  1782. | primary_value tCOLON2 operation2 paren_args
  1783. {
  1784. $$ = new_call(vps, $1, $3, $4);
  1785. fixpos($$, $1);
  1786. }
  1787. | primary_value tCOLON2 operation3
  1788. {
  1789. $$ = new_call(vps, $1, $3, 0);
  1790. }
  1791. | primary_value '\\' operation2
  1792. {
  1793. $$ = NEW_CALL($1, rb_intern("get_reference"), NEW_LIST(NEW_LIT(ID2SYM($3))));
  1794. }
  1795. | tUBS operation2
  1796. {
  1797. $$ = NEW_FCALL(rb_intern("get_reference"), NEW_LIST(NEW_LIT(ID2SYM($2))));
  1798. }
  1799. | kSUPER paren_args
  1800. {
  1801. $$ = new_super(vps, $2);
  1802. }
  1803. | kSUPER
  1804. {
  1805. $$ = NEW_ZSUPER();
  1806. }
  1807. ;
  1808. brace_block : '{'
  1809. {
  1810. $<num>1 = ruby_sourceline;
  1811. reset_block(vps);
  1812. }
  1813. opt_block_var { $<vars>$ = vps->variables->block_vars; }
  1814. compstmt '}'
  1815. {
  1816. $$ = NEW_ITER($3, 0, extract_block_vars(vps, $5, $<vars>4));
  1817. nd_set_line($$, $<num>1);
  1818. }
  1819. | kDO
  1820. {
  1821. $<num>1 = ruby_sourceline;
  1822. reset_block(vps);
  1823. }
  1824. opt_block_var { $<vars>$ = vps->variables->block_vars; }
  1825. compstmt kEND
  1826. {
  1827. $$ = NEW_ITER($3, 0, extract_block_vars(vps, $5, $<vars>4));
  1828. nd_set_line($$, $<num>1);
  1829. }
  1830. ;
  1831. case_body : kWHEN when_args then
  1832. compstmt
  1833. cases
  1834. {
  1835. $$ = NEW_WHEN($2, $4, $5);
  1836. }
  1837. ;
  1838. when_args : args
  1839. | args ',' tSTAR arg_value
  1840. {
  1841. $$ = list_append(vps, $1, NEW_WHEN($4, 0, 0));
  1842. }
  1843. | tSTAR arg_value
  1844. {
  1845. $$ = NEW_LIST(NEW_WHEN($2, 0, 0));
  1846. }
  1847. ;
  1848. cases : opt_else
  1849. | case_body
  1850. ;
  1851. opt_rescue : kRESCUE exc_list exc_var then
  1852. compstmt
  1853. opt_rescue
  1854. {
  1855. if ($3) {
  1856. $3 = node_assign($3, NEW_GVAR(rb_intern("$!")), vps);
  1857. $5 = block_append(vps, $3, $5);
  1858. }
  1859. $$ = NEW_RESBODY($2, $5, $6);
  1860. fixpos($$, $2?$2:$5);
  1861. }
  1862. | none
  1863. ;
  1864. exc_list : arg_value
  1865. {
  1866. $$ = NEW_LIST($1);
  1867. }
  1868. | mrhs
  1869. | none
  1870. ;
  1871. exc_var : tASSOC lhs
  1872. {
  1873. $$ = $2;
  1874. }
  1875. | none
  1876. ;
  1877. opt_ensure : kENSURE compstmt
  1878. {
  1879. if ($2)
  1880. $$ = $2;
  1881. else
  1882. /* place holder */
  1883. $$ = NEW_NIL();
  1884. }
  1885. | none
  1886. ;
  1887. literal : numeric
  1888. | symbol
  1889. {
  1890. $$ = NEW_LIT(ID2SYM($1));
  1891. }
  1892. | dsym
  1893. ;
  1894. strings : string
  1895. {
  1896. NODE *node = $1;
  1897. if (!node) {
  1898. node = NEW_STR(string_new(0, 0));
  1899. }
  1900. else {
  1901. node = evstr2dstr(vps, node);
  1902. }
  1903. $$ = node;
  1904. }
  1905. ;
  1906. string : string1
  1907. | string string1
  1908. {
  1909. $$ = literal_concat(vps, $1, $2);
  1910. }
  1911. ;
  1912. string1 : tSTRING_BEG string_contents tSTRING_END
  1913. {
  1914. $$ = $2;
  1915. }
  1916. ;
  1917. xstring : tXSTRING_BEG xstring_contents tSTRING_END
  1918. {
  1919. NODE *node = $2;
  1920. if (!node) {
  1921. node = NEW_XSTR(string_new(0, 0));
  1922. }
  1923. else {
  1924. switch (nd_type(node)) {
  1925. case NODE_STR:
  1926. nd_set_type(node, NODE_XSTR);
  1927. break;
  1928. case NODE_DSTR:
  1929. nd_set_type(node, NODE_DXSTR);
  1930. break;
  1931. default:
  1932. node = NEW_NODE(NODE_DXSTR, string_new(0, 0), 1, NEW_LIST(node));
  1933. break;
  1934. }
  1935. }
  1936. $$ = node;
  1937. }
  1938. ;
  1939. regexp : tREGEXP_BEG xstring_contents tREGEXP_END
  1940. {
  1941. intptr_t options = $3;
  1942. NODE *node = $2;
  1943. if (!node) {
  1944. node = NEW_REGEX(string_new2(""), options & ~RE_OPTION_ONCE);
  1945. }
  1946. else switch (nd_type(node)) {
  1947. case NODE_STR:
  1948. {
  1949. nd_set_type(node, NODE_REGEX);
  1950. node->nd_cnt = options & ~RE_OPTION_ONCE;
  1951. /*
  1952. node->nd_lit = rb_reg_new(RSTRING(src)->ptr,
  1953. RSTRING(src)->len,
  1954. options & ~RE_OPTION_ONCE);
  1955. */
  1956. }
  1957. break;
  1958. default:
  1959. node = NEW_NODE(NODE_DSTR, string_new(0, 0), 1, NEW_LIST(node));
  1960. case NODE_DSTR:
  1961. if (options & RE_OPTION_ONCE) {
  1962. nd_set_type(node, NODE_DREGX_ONCE);
  1963. }
  1964. else {
  1965. nd_set_type(node, NODE_DREGX);
  1966. }
  1967. node->nd_cflag = options & ~RE_OPTION_ONCE;
  1968. break;
  1969. }
  1970. $$ = node;
  1971. }
  1972. ;
  1973. words : tWORDS_BEG ' ' tSTRING_END
  1974. {
  1975. $$ = NEW_ZARRAY();
  1976. }
  1977. | tWORDS_BEG word_list tSTRING_END
  1978. {
  1979. $$ = $2;
  1980. }
  1981. ;
  1982. word_list : /* none */
  1983. {
  1984. $$ = 0;
  1985. }
  1986. | word_list word ' '
  1987. {
  1988. $$ = list_append(vps, $1, evstr2dstr(vps, $2));
  1989. }
  1990. ;
  1991. word : string_content
  1992. | word string_content
  1993. {
  1994. $$ = literal_concat(vps, $1, $2);
  1995. }
  1996. ;
  1997. qwords : tQWORDS_BEG ' ' tSTRING_END
  1998. {
  1999. $$ = NEW_ZARRAY();
  2000. }
  2001. | tQWORDS_BEG qword_list tSTRING_END
  2002. {
  2003. $$ = $2;
  2004. }
  2005. ;
  2006. qword_list : /* none */
  2007. {
  2008. $$ = 0;
  2009. }
  2010. | qword_list tSTRING_CONTENT ' '
  2011. {
  2012. $$ = list_append(vps, $1, $2);
  2013. }
  2014. ;
  2015. string_contents : /* none */
  2016. {
  2017. $$ = 0;
  2018. }
  2019. | string_contents string_content
  2020. {
  2021. $$ = literal_concat(vps, $1, $2);
  2022. }
  2023. ;
  2024. xstring_contents: /* none */
  2025. {
  2026. $$ = 0;
  2027. }
  2028. | xstring_contents string_content
  2029. {
  2030. $$ = literal_concat(vps, $1, $2);
  2031. }
  2032. ;
  2033. string_content : tSTRING_CONTENT
  2034. | tSTRING_DVAR
  2035. {
  2036. $<node>$ = lex_strterm;
  2037. lex_strterm = 0;
  2038. vps->lex_state = EXPR_BEG;
  2039. }
  2040. string_dvar
  2041. {
  2042. lex_strterm = $<node>2;
  2043. $$ = NEW_EVSTR($3);
  2044. }
  2045. | tSTRING_DBEG
  2046. {
  2047. $<node>$ = lex_strterm;
  2048. lex_strterm = 0;
  2049. vps->lex_state = EXPR_BEG;
  2050. COND_PUSH(0);
  2051. CMDARG_PUSH(0);
  2052. }
  2053. compstmt '}'
  2054. {
  2055. lex_strterm = $<node>2;
  2056. COND_LEXPOP();
  2057. CMDARG_LEXPOP();
  2058. if (($$ = $3) && nd_type($$) == NODE_NEWLINE) {
  2059. $$ = $$->nd_next;
  2060. }
  2061. $$ = new_evstr(vps, $$);
  2062. }
  2063. ;
  2064. string_dvar : tGVAR {$$ = NEW_GVAR($1);}
  2065. | tIVAR {$$ = NEW_IVAR($1);}
  2066. | tCVAR {$$ = NEW_CVAR($1);}
  2067. | backref
  2068. ;
  2069. symbol : tSYMBEG sym
  2070. {
  2071. vps->lex_state = EXPR_END;
  2072. $$ = $2;
  2073. }
  2074. ;
  2075. sym : fname
  2076. | tIVAR
  2077. | tGVAR
  2078. | tCVAR
  2079. ;
  2080. dsym : tSYMBEG xstring_contents tSTRING_END
  2081. {
  2082. vps->lex_state = EXPR_END;
  2083. if (!($$ = $2)) {
  2084. yyerror("empty symbol literal");
  2085. }
  2086. else {
  2087. switch (nd_type($$)) {
  2088. case NODE_DSTR:
  2089. nd_set_type($$, NODE_DSYM);
  2090. break;
  2091. case NODE_STR:
  2092. /* TODO: this line should never fail unless nd_str is binary */
  2093. if (strlen(bdatae($$->nd_str,"")) == (size_t)blength($$->nd_str)) {
  2094. ID tmp = rb_intern(bdata($$->nd_str));
  2095. bdestroy($$->nd_str);
  2096. $$->nd_lit = ID2SYM(tmp);
  2097. nd_set_type($$, NODE_LIT);
  2098. break;
  2099. } else {
  2100. bdestroy($$->nd_str);
  2101. }
  2102. /* fall through */
  2103. default:
  2104. $$ = NEW_NODE(NODE_DSYM, string_new(0, 0), 1, NEW_LIST($$));
  2105. break;
  2106. }
  2107. }
  2108. }
  2109. ;
  2110. numeric : tINTEGER
  2111. | tFLOAT
  2112. | tUMINUS_NUM tINTEGER %prec tLOWEST
  2113. {
  2114. $$ = NEW_NEGATE($2);
  2115. }
  2116. | tUMINUS_NUM tFLOAT %prec tLOWEST
  2117. {
  2118. $$ = NEW_NEGATE($2);
  2119. }
  2120. ;
  2121. variable : tIDENTIFIER
  2122. | tIVAR
  2123. | tGVAR
  2124. | tCONSTANT
  2125. | tCVAR
  2126. | kNIL {$$ = kNIL;}
  2127. | kSELF {$$ = kSELF;}
  2128. | kTRUE {$$ = kTRUE;}
  2129. | kFALSE {$$ = kFALSE;}
  2130. | k__FILE__ {$$ = k__FILE__;}
  2131. | k__LINE__ {$$ = k__LINE__;}
  2132. ;
  2133. var_ref : variable
  2134. {
  2135. $$ = gettable($1);
  2136. }
  2137. ;
  2138. var_lhs : variable
  2139. {
  2140. $$ = assignable($1, 0, vps);
  2141. }
  2142. ;
  2143. backref : tNTH_REF
  2144. | tBACK_REF
  2145. ;
  2146. superclass : term
  2147. {
  2148. $$ = 0;
  2149. }
  2150. | '<'
  2151. {
  2152. vps->lex_state = EXPR_BEG;
  2153. }
  2154. expr_value term
  2155. {
  2156. $$ = $3;
  2157. }
  2158. | error term {yyerrok; $$ = 0;}
  2159. ;
  2160. f_arglist : '(' f_args opt_nl ')'
  2161. {
  2162. $$ = $2;
  2163. vps->lex_state = EXPR_BEG;
  2164. command_start = TRUE;
  2165. }
  2166. | f_args term
  2167. {
  2168. $$ = $1;
  2169. }
  2170. ;
  2171. f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
  2172. {
  2173. $$ = block_append(vps, NEW_ARGS((intptr_t)$1, $3, $5), $6);
  2174. }
  2175. | f_arg ',' f_optarg opt_f_block_arg
  2176. {
  2177. $$ = block_append(vps, NEW_ARGS((intptr_t)$1, $3, 0), $4);
  2178. }
  2179. | f_arg ',' f_rest_arg opt_f_block_arg
  2180. {
  2181. $$ = block_append(vps, NEW_ARGS((intptr_t)$1, 0, $3), $4);
  2182. }
  2183. | f_arg opt_f_block_arg
  2184. {
  2185. $$ = block_append(vps, NEW_ARGS((intptr_t)$1, 0, 0), $2);
  2186. }
  2187. | f_optarg ',' f_rest_arg opt_f_block_arg
  2188. {
  2189. $$ = block_append(vps, NEW_ARGS(0, $1, $3), $4);
  2190. }
  2191. | f_optarg opt_f_block_arg
  2192. {
  2193. $$ = block_append(vps, NEW_ARGS(0, $1, 0), $2);
  2194. }
  2195. | f_rest_arg opt_f_block_arg
  2196. {
  2197. $$ = block_append(vps, NEW_ARGS(0, 0, $1), $2);
  2198. }
  2199. | f_block_arg
  2200. {
  2201. $$ = block_append(vps, NEW_ARGS(0, 0, 0), $1);
  2202. }
  2203. | /* none */
  2204. {
  2205. $$ = NEW_ARGS(0, 0, 0);
  2206. }
  2207. ;
  2208. f_norm_arg : tCONSTANT
  2209. {
  2210. yyerror("formal argument cannot be a constant");
  2211. }
  2212. | tIVAR
  2213. {
  2214. yyerror("formal argument cannot be an instance variable");
  2215. }
  2216. | tGVAR
  2217. {
  2218. yyerror("formal argument cannot be a global variable");
  2219. }
  2220. | tCVAR
  2221. {
  2222. yyerror("formal argument cannot be a class variable");
  2223. }
  2224. | tIDENTIFIER
  2225. {
  2226. if (!is_local_id($1))
  2227. yyerror("formal argument must be local variable");
  2228. else if (local_id($1))
  2229. yyerror("duplicate argument name");
  2230. local_cnt($1);
  2231. $$ = 1;
  2232. }
  2233. ;
  2234. f_arg : f_norm_arg
  2235. | f_arg ',' f_norm_arg
  2236. {
  2237. $$ += 1;
  2238. }
  2239. ;
  2240. f_opt : tIDENTIFIER '=' arg_value
  2241. {
  2242. if (!is_local_id($1))
  2243. yyerror("formal argument must be local variable");
  2244. else if (local_id($1))
  2245. yyerror("duplicate optional argument name");
  2246. $$ = assignable($1, $3, vps);
  2247. }
  2248. ;
  2249. f_optarg : f_opt
  2250. {
  2251. $$ = NEW_BLOCK($1);
  2252. $$->nd_end = $$;
  2253. }
  2254. | f_optarg ',' f_opt
  2255. {
  2256. $$ = block_append(vps, $1, $3);
  2257. }
  2258. ;
  2259. restarg_mark : '*'
  2260. | tSTAR
  2261. ;
  2262. f_rest_arg : restarg_mark tIDENTIFIER
  2263. {
  2264. if (!is_local_id($2))
  2265. yyerror("rest argument must be local variable");
  2266. else if (local_id($2))
  2267. yyerror("duplicate rest argument name");
  2268. $$ = local_cnt($2) + 1;
  2269. }
  2270. | restarg_mark
  2271. {
  2272. $$ = -2;
  2273. }
  2274. ;
  2275. blkarg_mark : '&'
  2276. | tAMPER
  2277. ;
  2278. f_block_arg : blkarg_mark tIDENTIFIER
  2279. {
  2280. if (!is_local_id($2))
  2281. yyerror("block argument must be local variable");
  2282. else if (local_id($2))
  2283. yyerror("duplicate block argument name");
  2284. $$ = NEW_BLOCK_ARG($2);
  2285. }
  2286. ;
  2287. opt_f_block_arg : ',' f_block_arg
  2288. {
  2289. $$ = $2;
  2290. }
  2291. | none
  2292. ;
  2293. singleton : var_ref
  2294. {
  2295. $$ = $1;
  2296. value_expr($$);
  2297. }
  2298. | '(' {vps->lex_state = EXPR_BEG;} expr opt_nl ')'
  2299. {
  2300. if ($3 == 0) {
  2301. yyerror("can't define singleton method for ().");
  2302. }
  2303. else {
  2304. switch (nd_type($3)) {
  2305. case NODE_STR:
  2306. case NODE_DSTR:
  2307. case NODE_XSTR:
  2308. case NODE_DXSTR:
  2309. case NODE_DREGX:
  2310. case NODE_LIT:
  2311. case NODE_ARRAY:
  2312. case NODE_ZARRAY:
  2313. yyerror("can't define singleton method for literals");
  2314. default:
  2315. value_expr($3);
  2316. break;
  2317. }
  2318. }
  2319. $$ = $3;
  2320. }
  2321. ;
  2322. assoc_list : none
  2323. | assocs trailer
  2324. {
  2325. $$ = $1;
  2326. }
  2327. | args trailer
  2328. {
  2329. if ($1->nd_alen%2 != 0) {
  2330. yyerror("odd number list for Hash");
  2331. }
  2332. $$ = $1;
  2333. }
  2334. ;
  2335. assocs : assoc
  2336. | assocs ',' assoc
  2337. {
  2338. $$ = list_concat($1, $3);
  2339. }
  2340. ;
  2341. assoc : arg_value tASSOC arg_value
  2342. {
  2343. $$ = list_append(vps, NEW_LIST($1), $3);
  2344. }
  2345. ;
  2346. operation : tIDENTIFIER
  2347. | tCONSTANT
  2348. | tFID
  2349. ;
  2350. operation2 : tIDENTIFIER
  2351. | tCONSTANT
  2352. | tFID
  2353. | op
  2354. ;
  2355. operation3 : tIDENTIFIER
  2356. | tFID
  2357. | op
  2358. ;
  2359. dot_or_colon : '.'
  2360. | tCOLON2
  2361. ;
  2362. opt_terms : /* none */
  2363. | terms
  2364. ;
  2365. opt_nl : /* none */
  2366. | '\n'
  2367. ;
  2368. trailer : /* none */
  2369. | '\n'
  2370. | ','
  2371. ;
  2372. term : ';' {yyerrok;}
  2373. | '\n'
  2374. ;
  2375. terms : term
  2376. | terms ';' {yyerrok;}
  2377. ;
  2378. none : /* none */ {$$ = 0;}
  2379. ;
  2380. %%
  2381. /* We remove any previous definition of `SIGN_EXTEND_CHAR',
  2382. since ours (we hope) works properly with all combinations of
  2383. machines, compilers, `char' and `unsigned char' argument types.
  2384. (Per Bothner suggested the basic approach.) */
  2385. #undef SIGN_EXTEND_CHAR
  2386. #if __STDC__
  2387. # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
  2388. #else /* not __STDC__ */
  2389. /* As in Harbison and Steele. */
  2390. # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
  2391. #endif
  2392. #define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_' || ismbchar(c)))
  2393. #define LEAVE_BS 1
  2394. static int
  2395. syd_yyerror(const char *msg, rb_parse_state *parse_state)
  2396. {
  2397. create_error(parse_state, (char *)msg);
  2398. return 1;
  2399. }
  2400. static int
  2401. yycompile(rb_parse_state *parse_state, char *f, int line)
  2402. {
  2403. int n;
  2404. /* Setup an initial empty scope. */
  2405. heredoc_end = 0;
  2406. lex_strterm = 0;
  2407. parse_state->end_seen = 0;
  2408. ruby_sourcefile = f;
  2409. command_start = TRUE;
  2410. n = yyparse(parse_state);
  2411. ruby_debug_lines = 0;
  2412. compile_for_eval = 0;
  2413. parse_state->cond_stack = 0;
  2414. parse_state->cmdarg_stack = 0;
  2415. command_start = TRUE;
  2416. class_nest = 0;
  2417. in_single = 0;
  2418. in_def = 0;
  2419. cur_mid = 0;
  2420. lex_strterm = 0;
  2421. return n;
  2422. }
  2423. static bool
  2424. lex_get_str(rb_parse_state *parse_state)
  2425. {
  2426. const char *str;
  2427. const char *beg, *end, *pend;
  2428. int sz;
  2429. str = bdata(parse_state->lex_string);
  2430. beg = str;
  2431. if (parse_state->lex_str_used) {
  2432. if (blength(parse_state->lex_string) == parse_state->lex_str_used) {
  2433. return false;
  2434. }
  2435. beg += parse_state->lex_str_used;
  2436. }
  2437. pend = str + blength(parse_state->lex_string);
  2438. end = beg;
  2439. while(end < pend) {
  2440. if(*end++ == '\n') break;
  2441. }
  2442. sz = end - beg;
  2443. bcatblk(parse_state->line_buffer, beg, sz);
  2444. parse_state->lex_str_used += sz;
  2445. return TRUE;
  2446. }
  2447. void syd_add_to_parse_tree(STATE, rb_parse_state*, Object*, NODE*, ID*);
  2448. static Object* convert_to_sexp(STATE, rb_parse_state *parse_state, NODE *node) {
  2449. Array* ary;
  2450. ary = Array::create(state, 1);
  2451. syd_add_to_parse_tree(state, parse_state, ary, node, NULL);
  2452. return ary->get(state, 0);
  2453. }
  2454. static bool
  2455. lex_getline(rb_parse_state *parse_state)
  2456. {
  2457. if(!parse_state->line_buffer) {
  2458. parse_state->line_buffer = cstr2bstr("");
  2459. } else {
  2460. btrunc(parse_state->line_buffer, 0);
  2461. }
  2462. return parse_state->lex_gets(parse_state);
  2463. }
  2464. Object*
  2465. syd_compile_string(STATE, const char *f, bstring s, int line)
  2466. {
  2467. int n;
  2468. rb_parse_state *parse_state;
  2469. Object* ret;
  2470. parse_state = alloc_parse_state();
  2471. parse_state->state = state;
  2472. parse_state->lex_string = s;
  2473. parse_state->lex_gets = lex_get_str;
  2474. parse_state->lex_pbeg = 0;
  2475. parse_state->lex_p = 0;
  2476. parse_state->lex_pend = 0;
  2477. parse_state->error = Qfalse;
  2478. ruby_sourceline = line - 1;
  2479. compile_for_eval = 1;
  2480. n = yycompile(parse_state, (char*)f, line);
  2481. if(parse_state->error == Qfalse) {
  2482. ret = convert_to_sexp(state, parse_state, parse_state->top);
  2483. } else {
  2484. ret = parse_state->error;
  2485. }
  2486. pt_free(parse_state);
  2487. free(parse_state);
  2488. return ret;
  2489. }
  2490. static bool parse_io_gets(rb_parse_state *parse_state) {
  2491. if(feof(parse_state->lex_io)) {
  2492. return false;
  2493. }
  2494. while(TRUE) {
  2495. char *ptr, buf[1024];
  2496. int read;
  2497. ptr = fgets(buf, sizeof(buf), parse_state->lex_io);
  2498. if(!ptr) {
  2499. return false;
  2500. }
  2501. read = strlen(ptr);
  2502. bcatblk(parse_state->line_buffer, ptr, read);
  2503. /* check whether we read a full line */
  2504. if(!(read == (sizeof(buf) - 1) && ptr[read] != '\n')) {
  2505. break;
  2506. }
  2507. }
  2508. return TRUE;
  2509. }
  2510. Object*
  2511. syd_compile_file(STATE, const char *f, FILE *file, int start)
  2512. {
  2513. int n;
  2514. Object* ret;
  2515. rb_parse_state *parse_state;
  2516. parse_state = alloc_parse_state();
  2517. parse_state->state = state;
  2518. parse_state->lex_io = file;
  2519. parse_state->lex_gets = parse_io_gets;
  2520. parse_state->lex_pbeg = 0;
  2521. parse_state->lex_p = 0;
  2522. parse_state->lex_pend = 0;
  2523. parse_state->error = Qfalse;
  2524. ruby_sourceline = start - 1;
  2525. n = yycompile(parse_state, (char*)f, start);
  2526. if(parse_state->error == Qfalse) {
  2527. ret = convert_to_sexp(state, parse_state, parse_state->top);
  2528. } else {
  2529. ret = parse_state->error;
  2530. }
  2531. pt_free(parse_state);
  2532. free(parse_state);
  2533. return ret;
  2534. }
  2535. #define nextc() ps_nextc(parse_state)
  2536. static inline int
  2537. ps_nextc(rb_parse_state *parse_state)
  2538. {
  2539. int c;
  2540. if (parse_state->lex_p == parse_state->lex_pend) {
  2541. bstring v;
  2542. if (!lex_getline(parse_state)) return -1;
  2543. v = parse_state->line_buffer;
  2544. if (heredoc_end > 0) {
  2545. ruby_sourceline = heredoc_end;
  2546. heredoc_end = 0;
  2547. }
  2548. ruby_sourceline++;
  2549. /* This code is setup so that lex_pend can be compared to
  2550. the data in lex_lastline. Thats important, otherwise
  2551. the heredoc code breaks. */
  2552. if(parse_state->lex_lastline) {
  2553. bassign(parse_state->lex_lastline, v);
  2554. } else {
  2555. parse_state->lex_lastline = bstrcpy(v);
  2556. }
  2557. v = parse_state->lex_lastline;
  2558. parse_state->lex_pbeg = parse_state->lex_p = bdata(v);
  2559. parse_state->lex_pend = parse_state->lex_p + blength(v);
  2560. }
  2561. c = (unsigned char)*(parse_state->lex_p++);
  2562. if (c == '\r' && parse_state->lex_p < parse_state->lex_pend && *(parse_state->lex_p) == '\n') {
  2563. parse_state->lex_p++;
  2564. c = '\n';
  2565. parse_state->column = 0;
  2566. } else if(c == '\n') {
  2567. parse_state->column = 0;
  2568. } else {
  2569. parse_state->column++;
  2570. }
  2571. return c;
  2572. }
  2573. static void
  2574. pushback(int c, rb_parse_state *parse_state)
  2575. {
  2576. if (c == -1) return;
  2577. parse_state->lex_p--;
  2578. }
  2579. /* Indicates if we're currently at the beginning of a line. */
  2580. #define was_bol() (parse_state->lex_p == parse_state->lex_pbeg + 1)
  2581. #define peek(c) (parse_state->lex_p != parse_state->lex_pend && (c) == *(parse_state->lex_p))
  2582. /* The token buffer. It's just a global string that has
  2583. functions to build up the string easily. */
  2584. #define tokfix() (tokenbuf[tokidx]='\0')
  2585. #define tok() tokenbuf
  2586. #define toklen() tokidx
  2587. #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
  2588. static char*
  2589. newtok(rb_parse_state *parse_state)
  2590. {
  2591. tokidx = 0;
  2592. if (!tokenbuf) {
  2593. toksiz = 60;
  2594. tokenbuf = ALLOC_N(char, 60);
  2595. }
  2596. if (toksiz > 4096) {
  2597. toksiz = 60;
  2598. REALLOC_N(tokenbuf, char, 60);
  2599. }
  2600. return tokenbuf;
  2601. }
  2602. static void tokadd(char c, rb_parse_state *parse_state)
  2603. {
  2604. assert(tokidx < toksiz && tokidx >= 0);
  2605. tokenbuf[tokidx++] = c;
  2606. if (tokidx >= toksiz) {
  2607. toksiz *= 2;
  2608. REALLOC_N(tokenbuf, char, toksiz);
  2609. }
  2610. }
  2611. static int
  2612. read_escape(rb_parse_state *parse_state)
  2613. {
  2614. int c;
  2615. switch (c = nextc()) {
  2616. case '\\': /* Backslash */
  2617. return c;
  2618. case 'n': /* newline */
  2619. return '\n';
  2620. case 't': /* horizontal tab */
  2621. return '\t';
  2622. case 'r': /* carriage-return */
  2623. return '\r';
  2624. case 'f': /* form-feed */
  2625. return '\f';
  2626. case 'v': /* vertical tab */
  2627. return '\13';
  2628. case 'a': /* alarm(bell) */
  2629. return '\007';
  2630. case 'e': /* escape */
  2631. return 033;
  2632. case '0': case '1': case '2': case '3': /* octal constant */
  2633. case '4': case '5': case '6': case '7':
  2634. {
  2635. int numlen;
  2636. pushback(c, parse_state);
  2637. c = scan_oct(parse_state->lex_p, 3, &numlen);
  2638. parse_state->lex_p += numlen;
  2639. }
  2640. return c;
  2641. case 'x': /* hex constant */
  2642. {
  2643. int numlen;
  2644. c = scan_hex(parse_state->lex_p, 2, &numlen);
  2645. if (numlen == 0) {
  2646. yyerror("Invalid escape character syntax");
  2647. return 0;
  2648. }
  2649. parse_state->lex_p += numlen;
  2650. }
  2651. return c;
  2652. case 'b': /* backspace */
  2653. return '\010';
  2654. case 's': /* space */
  2655. return ' ';
  2656. case 'M':
  2657. if ((c = nextc()) != '-') {
  2658. yyerror("Invalid escape character syntax");
  2659. pushback(c, parse_state);
  2660. return '\0';
  2661. }
  2662. if ((c = nextc()) == '\\') {
  2663. return read_escape(parse_state) | 0x80;
  2664. }
  2665. else if (c == -1) goto eof;
  2666. else {
  2667. return ((c & 0xff) | 0x80);
  2668. }
  2669. case 'C':
  2670. if ((c = nextc()) != '-') {
  2671. yyerror("Invalid escape character syntax");
  2672. pushback(c, parse_state);
  2673. return '\0';
  2674. }
  2675. case 'c':
  2676. if ((c = nextc())== '\\') {
  2677. c = read_escape(parse_state);
  2678. }
  2679. else if (c == '?')
  2680. return 0177;
  2681. else if (c == -1) goto eof;
  2682. return c & 0x9f;
  2683. eof:
  2684. case -1:
  2685. yyerror("Invalid escape character syntax");
  2686. return '\0';
  2687. default:
  2688. return c;
  2689. }
  2690. }
  2691. static int
  2692. tokadd_escape(int term, rb_parse_state *parse_state)
  2693. {
  2694. int c;
  2695. switch (c = nextc()) {
  2696. case '\n':
  2697. return 0; /* just ignore */
  2698. case '0': case '1': case '2': case '3': /* octal constant */
  2699. case '4': case '5': case '6': case '7':
  2700. {
  2701. int i;
  2702. tokadd((char)'\\', parse_state);
  2703. tokadd((char)c, parse_state);
  2704. for (i=0; i<2; i++) {
  2705. c = nextc();
  2706. if (c == -1) goto eof;
  2707. if (c < '0' || '7' < c) {
  2708. pushback(c, parse_state);
  2709. break;
  2710. }
  2711. tokadd((char)c, parse_state);
  2712. }
  2713. }
  2714. return 0;
  2715. case 'x': /* hex constant */
  2716. {
  2717. int numlen;
  2718. tokadd('\\', parse_state);
  2719. tokadd((char)c, parse_state);
  2720. scan_hex(parse_state->lex_p, 2, &numlen);
  2721. if (numlen == 0) {
  2722. yyerror("Invalid escape character syntax");
  2723. return -1;
  2724. }
  2725. while (numlen--)
  2726. tokadd((char)nextc(), parse_state);
  2727. }
  2728. return 0;
  2729. case 'M':
  2730. if ((c = nextc()) != '-') {
  2731. yyerror("Invalid escape character syntax");
  2732. pushback(c, parse_state);
  2733. return 0;
  2734. }
  2735. tokadd('\\',parse_state);
  2736. tokadd('M', parse_state);
  2737. tokadd('-', parse_state);
  2738. goto escaped;
  2739. case 'C':
  2740. if ((c = nextc()) != '-') {
  2741. yyerror("Invalid escape character syntax");
  2742. pushback(c, parse_state);
  2743. return 0;
  2744. }
  2745. tokadd('\\', parse_state);
  2746. tokadd('C', parse_state);
  2747. tokadd('-', parse_state);
  2748. goto escaped;
  2749. case 'c':
  2750. tokadd('\\', parse_state);
  2751. tokadd('c', parse_state);
  2752. escaped:
  2753. if ((c = nextc()) == '\\') {
  2754. return tokadd_escape(term, parse_state);
  2755. }
  2756. else if (c == -1) goto eof;
  2757. tokadd((char)c, parse_state);
  2758. return 0;
  2759. eof:
  2760. case -1:
  2761. yyerror("Invalid escape character syntax");
  2762. return -1;
  2763. default:
  2764. if (c != '\\' || c != term)
  2765. tokadd('\\', parse_state);
  2766. tokadd((char)c, parse_state);
  2767. }
  2768. return 0;
  2769. }
  2770. static int
  2771. regx_options(rb_parse_state *parse_state)
  2772. {
  2773. char kcode = 0;
  2774. int options = 0;
  2775. int c;
  2776. newtok(parse_state);
  2777. while (c = nextc(), ISALPHA(c)) {
  2778. switch (c) {
  2779. case 'i':
  2780. options |= RE_OPTION_IGNORECASE;
  2781. break;
  2782. case 'x':
  2783. options |= RE_OPTION_EXTENDED;
  2784. break;
  2785. case 'm':
  2786. options |= RE_OPTION_MULTILINE;
  2787. break;
  2788. case 'o':
  2789. options |= RE_OPTION_ONCE;
  2790. break;
  2791. case 'n':
  2792. kcode = 16;
  2793. break;
  2794. case 'e':
  2795. kcode = 32;
  2796. break;
  2797. case 's':
  2798. kcode = 48;
  2799. break;
  2800. case 'u':
  2801. kcode = 64;
  2802. break;
  2803. default:
  2804. tokadd((char)c, parse_state);
  2805. break;
  2806. }
  2807. }
  2808. pushback(c, parse_state);
  2809. if (toklen()) {
  2810. tokfix();
  2811. rb_compile_error(parse_state, "unknown regexp option%s - %s",
  2812. toklen() > 1 ? "s" : "", tok());
  2813. }
  2814. return options | kcode;
  2815. }
  2816. #define STR_FUNC_ESCAPE 0x01
  2817. #define STR_FUNC_EXPAND 0x02
  2818. #define STR_FUNC_REGEXP 0x04
  2819. #define STR_FUNC_QWORDS 0x08
  2820. #define STR_FUNC_SYMBOL 0x10
  2821. #define STR_FUNC_INDENT 0x20
  2822. enum string_type {
  2823. str_squote = (0),
  2824. str_dquote = (STR_FUNC_EXPAND),
  2825. str_xquote = (STR_FUNC_EXPAND),
  2826. str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
  2827. str_sword = (STR_FUNC_QWORDS),
  2828. str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
  2829. str_ssym = (STR_FUNC_SYMBOL),
  2830. str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND),
  2831. };
  2832. static int tokadd_string(int func, int term, int paren, quark *nest, rb_parse_state *parse_state)
  2833. {
  2834. int c;
  2835. while ((c = nextc()) != -1) {
  2836. if (paren && c == paren) {
  2837. ++*nest;
  2838. }
  2839. else if (c == term) {
  2840. if (!nest || !*nest) {
  2841. pushback(c, parse_state);
  2842. break;
  2843. }
  2844. --*nest;
  2845. }
  2846. else if ((func & STR_FUNC_EXPAND) && c == '#' && parse_state->lex_p < parse_state->lex_pend) {
  2847. int c2 = *(parse_state->lex_p);
  2848. if (c2 == '$' || c2 == '@' || c2 == '{') {
  2849. pushback(c, parse_state);
  2850. break;
  2851. }
  2852. }
  2853. else if (c == '\\') {
  2854. c = nextc();
  2855. switch (c) {
  2856. case '\n':
  2857. if (func & STR_FUNC_QWORDS) break;
  2858. if (func & STR_FUNC_EXPAND) continue;
  2859. tokadd('\\', parse_state);
  2860. break;
  2861. case '\\':
  2862. if (func & STR_FUNC_ESCAPE) tokadd((char)c, parse_state);
  2863. break;
  2864. default:
  2865. if (func & STR_FUNC_REGEXP) {
  2866. pushback(c, parse_state);
  2867. if (tokadd_escape(term, parse_state) < 0)
  2868. return -1;
  2869. continue;
  2870. }
  2871. else if (func & STR_FUNC_EXPAND) {
  2872. pushback(c, parse_state);
  2873. if (func & STR_FUNC_ESCAPE) tokadd('\\', parse_state);
  2874. c = read_escape(parse_state);
  2875. }
  2876. else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
  2877. /* ignore backslashed spaces in %w */
  2878. }
  2879. else if (c != term && !(paren && c == paren)) {
  2880. tokadd('\\', parse_state);
  2881. }
  2882. }
  2883. }
  2884. else if (ismbchar(c)) {
  2885. int i, len = mbclen(c)-1;
  2886. for (i = 0; i < len; i++) {
  2887. tokadd((char)c, parse_state);
  2888. c = nextc();
  2889. }
  2890. }
  2891. else if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
  2892. pushback(c, parse_state);
  2893. break;
  2894. }
  2895. if (!c && (func & STR_FUNC_SYMBOL)) {
  2896. func &= ~STR_FUNC_SYMBOL;
  2897. rb_compile_error(parse_state, "symbol cannot contain '\\0'");
  2898. continue;
  2899. }
  2900. tokadd((char)c, parse_state);
  2901. }
  2902. return c;
  2903. }
  2904. #define NEW_STRTERM(func, term, paren) \
  2905. syd_node_newnode(parse_state, NODE_STRTERM, (Object*)(func), (Object*)((term) | ((paren) << (CHAR_BIT * 2))), NULL)
  2906. #define pslval ((YYSTYPE *)parse_state->lval)
  2907. static int
  2908. parse_string(NODE *quote, rb_parse_state *parse_state)
  2909. {
  2910. int func = quote->nd_func;
  2911. int term = nd_term(quote);
  2912. int paren = nd_paren(quote);
  2913. int c, space = 0;
  2914. if (func == -1) return tSTRING_END;
  2915. c = nextc();
  2916. if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {
  2917. do {c = nextc();} while (ISSPACE(c));
  2918. space = 1;
  2919. }
  2920. if (c == term && !quote->nd_nest) {
  2921. if (func & STR_FUNC_QWORDS) {
  2922. quote->nd_func = -1;
  2923. return ' ';
  2924. }
  2925. if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
  2926. pslval->num = regx_options(parse_state);
  2927. return tREGEXP_END;
  2928. }
  2929. if (space) {
  2930. pushback(c, parse_state);
  2931. return ' ';
  2932. }
  2933. newtok(parse_state);
  2934. if ((func & STR_FUNC_EXPAND) && c == '#') {
  2935. switch (c = nextc()) {
  2936. case '$':
  2937. case '@':
  2938. pushback(c, parse_state);
  2939. return tSTRING_DVAR;
  2940. case '{':
  2941. return tSTRING_DBEG;
  2942. }
  2943. tokadd('#', parse_state);
  2944. }
  2945. pushback(c, parse_state);
  2946. if (tokadd_string(func, term, paren, &quote->nd_nest, parse_state) == -1) {
  2947. ruby_sourceline = nd_line(quote);
  2948. rb_compile_error(parse_state, "unterminated string meets end of file");
  2949. return tSTRING_END;
  2950. }
  2951. tokfix();
  2952. pslval->node = NEW_STR(string_new(tok(), toklen()));
  2953. return tSTRING_CONTENT;
  2954. }
  2955. /* Called when the lexer detects a heredoc is beginning. This pulls
  2956. in more characters and detects what kind of heredoc it is. */
  2957. static int
  2958. heredoc_identifier(rb_parse_state *parse_state)
  2959. {
  2960. int c = nextc(), term, func = 0;
  2961. size_t len;
  2962. if (c == '-') {
  2963. c = nextc();
  2964. func = STR_FUNC_INDENT;
  2965. }
  2966. switch (c) {
  2967. case '\'':
  2968. func |= str_squote; goto quoted;
  2969. case '"':
  2970. func |= str_dquote; goto quoted;
  2971. case '`':
  2972. func |= str_xquote;
  2973. quoted:
  2974. /* The heredoc indent is quoted, so its easy to find, we just
  2975. continue to consume characters into the token buffer until
  2976. we hit the terminating character. */
  2977. newtok(parse_state);
  2978. tokadd((char)func, parse_state);
  2979. term = c;
  2980. /* Where of where has the term gone.. */
  2981. while ((c = nextc()) != -1 && c != term) {
  2982. len = mbclen(c);
  2983. do {
  2984. tokadd((char)c, parse_state);
  2985. } while (--len > 0 && (c = nextc()) != -1);
  2986. }
  2987. /* Ack! end of file or end of string. */
  2988. if (c == -1) {
  2989. rb_compile_error(parse_state, "unterminated here document identifier");
  2990. return 0;
  2991. }
  2992. break;
  2993. default:
  2994. /* Ok, this is an unquoted heredoc ident. We just consume
  2995. until we hit a non-ident character. */
  2996. /* Do a quick check that first character is actually valid.
  2997. if it's not, then this isn't actually a heredoc at all!
  2998. It sucks that it's way down here in this function that in
  2999. finally bails with this not being a heredoc.*/
  3000. if (!is_identchar(c)) {
  3001. pushback(c, parse_state);
  3002. if (func & STR_FUNC_INDENT) {
  3003. pushback('-', parse_state);
  3004. }
  3005. return 0;
  3006. }
  3007. /* Finally, setup the token buffer and begin to fill it. */
  3008. newtok(parse_state);
  3009. term = '"';
  3010. tokadd((char)(func |= str_dquote), parse_state);
  3011. do {
  3012. len = mbclen(c);
  3013. do { tokadd((char)c, parse_state); } while (--len > 0 && (c = nextc()) != -1);
  3014. } while ((c = nextc()) != -1 && is_identchar(c));
  3015. pushback(c, parse_state);
  3016. break;
  3017. }
  3018. /* Fixup the token buffer, ie set the last character to null. */
  3019. tokfix();
  3020. len = parse_state->lex_p - parse_state->lex_pbeg;
  3021. parse_state->lex_p = parse_state->lex_pend;
  3022. pslval->id = 0;
  3023. /* Tell the lexer that we're inside a string now. nd_lit is
  3024. the heredoc identifier that we watch the stream for to
  3025. detect the end of the heredoc. */
  3026. bstring str = bstrcpy(parse_state->lex_lastline);
  3027. lex_strterm = syd_node_newnode(parse_state, NODE_HEREDOC,
  3028. (Object*)string_new(tok(), toklen()), /* nd_lit */
  3029. (Object*)len, /* nd_nth */
  3030. (Object*)str); /* nd_orig */
  3031. return term == '`' ? tXSTRING_BEG : tSTRING_BEG;
  3032. }
  3033. static void
  3034. heredoc_restore(NODE *here, rb_parse_state *parse_state)
  3035. {
  3036. bstring line = here->nd_orig;
  3037. bdestroy(parse_state->lex_lastline);
  3038. parse_state->lex_lastline = line;
  3039. parse_state->lex_pbeg = bdata(line);
  3040. parse_state->lex_pend = parse_state->lex_pbeg + blength(line);
  3041. parse_state->lex_p = parse_state->lex_pbeg + here->nd_nth;
  3042. heredoc_end = ruby_sourceline;
  3043. ruby_sourceline = nd_line(here);
  3044. bdestroy((bstring)here->nd_lit);
  3045. }
  3046. static int
  3047. whole_match_p(const char *eos, int len, int indent, rb_parse_state *parse_state)
  3048. {
  3049. char *p = parse_state->lex_pbeg;
  3050. int n;
  3051. if (indent) {
  3052. while (*p && ISSPACE(*p)) p++;
  3053. }
  3054. n = parse_state->lex_pend - (p + len);
  3055. if (n < 0 || (n > 0 && p[len] != '\n' && p[len] != '\r')) return FALSE;
  3056. if (strncmp(eos, p, len) == 0) return TRUE;
  3057. return FALSE;
  3058. }
  3059. /* Called when the lexer knows it's inside a heredoc. This function
  3060. is responsible for detecting an expandions (ie #{}) in the heredoc
  3061. and emitting a lex token and also detecting the end of the heredoc. */
  3062. static int
  3063. here_document(NODE *here, rb_parse_state *parse_state)
  3064. {
  3065. int c, func, indent = 0;
  3066. char *eos, *p, *pend;
  3067. long len;
  3068. bstring str = NULL;
  3069. /* eos == the heredoc ident that we found when the heredoc started */
  3070. eos = bdata(here->nd_str);
  3071. len = blength(here->nd_str) - 1;
  3072. /* indicates if we should search for expansions. */
  3073. indent = (func = *eos++) & STR_FUNC_INDENT;
  3074. /* Ack! EOF or end of input string! */
  3075. if ((c = nextc()) == -1) {
  3076. error:
  3077. rb_compile_error(parse_state, "can't find string \"%s\" anywhere before EOF", eos);
  3078. heredoc_restore(lex_strterm, parse_state);
  3079. lex_strterm = 0;
  3080. return 0;
  3081. }
  3082. /* Gr. not yet sure what was_bol() means other than it seems like
  3083. it means only 1 character has been consumed. */
  3084. if (was_bol() && whole_match_p(eos, len, indent, parse_state)) {
  3085. heredoc_restore(lex_strterm, parse_state);
  3086. return tSTRING_END;
  3087. }
  3088. /* If aren't doing expansions, we can just scan until
  3089. we find the identifier. */
  3090. if ((func & STR_FUNC_EXPAND) == 0) {
  3091. do {
  3092. p = bdata(parse_state->lex_lastline);
  3093. pend = parse_state->lex_pend;
  3094. if (pend > p) {
  3095. switch (pend[-1]) {
  3096. case '\n':
  3097. if (--pend == p || pend[-1] != '\r') {
  3098. pend++;
  3099. break;
  3100. }
  3101. case '\r':
  3102. --pend;
  3103. }
  3104. }
  3105. if (str) {
  3106. bcatblk(str, p, pend - p);
  3107. } else {
  3108. str = blk2bstr(p, pend - p);
  3109. }
  3110. if (pend < parse_state->lex_pend) bcatblk(str, "\n", 1);
  3111. parse_state->lex_p = parse_state->lex_pend;
  3112. if (nextc() == -1) {
  3113. if (str) bdestroy(str);
  3114. goto error;
  3115. }
  3116. } while (!whole_match_p(eos, len, indent, parse_state));
  3117. }
  3118. else {
  3119. newtok(parse_state);
  3120. if (c == '#') {
  3121. switch (c = nextc()) {
  3122. case '$':
  3123. case '@':
  3124. pushback(c, parse_state);
  3125. return tSTRING_DVAR;
  3126. case '{':
  3127. return tSTRING_DBEG;
  3128. }
  3129. tokadd('#', parse_state);
  3130. }
  3131. /* Loop while we haven't found a the heredoc ident. */
  3132. do {
  3133. pushback(c, parse_state);
  3134. /* Scan up until a \n and fill in the token buffer. */
  3135. if ((c = tokadd_string(func, '\n', 0, NULL, parse_state)) == -1) goto error;
  3136. /* We finished scanning, but didn't find a \n, so we setup the node
  3137. and have the lexer file in more. */
  3138. if (c != '\n') {
  3139. pslval->node = NEW_STR(string_new(tok(), toklen()));
  3140. return tSTRING_CONTENT;
  3141. }
  3142. /* I think this consumes the \n */
  3143. tokadd((char)nextc(), parse_state);
  3144. if ((c = nextc()) == -1) goto error;
  3145. } while (!whole_match_p(eos, len, indent, parse_state));
  3146. str = string_new(tok(), toklen());
  3147. }
  3148. heredoc_restore(lex_strterm, parse_state);
  3149. lex_strterm = NEW_STRTERM(-1, 0, 0);
  3150. pslval->node = NEW_STR(str);
  3151. return tSTRING_CONTENT;
  3152. }
  3153. #include "parser/grammar_lex.c.tab"
  3154. static void
  3155. arg_ambiguous()
  3156. {
  3157. rb_warning("ambiguous first argument; put parentheses or even spaces");
  3158. }
  3159. #define IS_ARG() (parse_state->lex_state == EXPR_ARG || parse_state->lex_state == EXPR_CMDARG)
  3160. static int
  3161. yylex(void *yylval_v, void *vstate)
  3162. {
  3163. register int c;
  3164. int space_seen = 0;
  3165. int cmd_state, comment_column;
  3166. struct rb_parse_state *parse_state;
  3167. bstring cur_line;
  3168. enum lex_state last_state;
  3169. YYSTYPE *yylval = (YYSTYPE*)yylval_v;
  3170. parse_state = (struct rb_parse_state*)vstate;
  3171. parse_state->lval = (void *)yylval;
  3172. /*
  3173. c = nextc();
  3174. printf("lex char: %c\n", c);
  3175. pushback(c, parse_state);
  3176. */
  3177. if (lex_strterm) {
  3178. int token;
  3179. if (nd_type(lex_strterm) == NODE_HEREDOC) {
  3180. token = here_document(lex_strterm, parse_state);
  3181. if (token == tSTRING_END) {
  3182. lex_strterm = 0;
  3183. parse_state->lex_state = EXPR_END;
  3184. }
  3185. }
  3186. else {
  3187. token = parse_string(lex_strterm, parse_state);
  3188. if (token == tSTRING_END || token == tREGEXP_END) {
  3189. lex_strterm = 0;
  3190. parse_state->lex_state = EXPR_END;
  3191. }
  3192. }
  3193. return token;
  3194. }
  3195. if (parse_state->end_seen) { /* After __END__ */
  3196. newtok(parse_state);
  3197. while ((c = nextc()) != -1) {
  3198. tokadd(c, parse_state);
  3199. }
  3200. tokfix();
  3201. pslval->node = NEW_END_DATA(string_new(tok(), toklen()));
  3202. parse_state->end_seen = 0;
  3203. return tEND_DATA;
  3204. }
  3205. cmd_state = command_start;
  3206. command_start = FALSE;
  3207. retry:
  3208. switch (c = nextc()) {
  3209. case '\0': /* NUL */
  3210. case '\004': /* ^D */
  3211. case '\032': /* ^Z */
  3212. case -1: /* end of script. */
  3213. return 0;
  3214. /* white spaces */
  3215. case ' ': case '\t': case '\f': case '\r':
  3216. case '\13': /* '\v' */
  3217. space_seen++;
  3218. goto retry;
  3219. case '#': /* it's a comment */
  3220. if(parse_state->comments) {
  3221. comment_column = parse_state->column;
  3222. cur_line = bfromcstralloc(50, "");
  3223. while((c = nextc()) != '\n' && c != -1) {
  3224. bconchar(cur_line, c);
  3225. }
  3226. // FIXME: used to have the file and column too, but took it out.
  3227. ptr_array_append(parse_state->comments, cur_line);
  3228. if(c == -1) {
  3229. return 0;
  3230. }
  3231. } else {
  3232. while ((c = nextc()) != '\n') {
  3233. if (c == -1)
  3234. return 0;
  3235. }
  3236. }
  3237. /* fall through */
  3238. case '\n':
  3239. switch (parse_state->lex_state) {
  3240. case EXPR_BEG:
  3241. case EXPR_FNAME:
  3242. case EXPR_DOT:
  3243. case EXPR_CLASS:
  3244. goto retry;
  3245. default:
  3246. break;
  3247. }
  3248. command_start = TRUE;
  3249. parse_state->lex_state = EXPR_BEG;
  3250. return '\n';
  3251. case '*':
  3252. if ((c = nextc()) == '*') {
  3253. if ((c = nextc()) == '=') {
  3254. pslval->id = tPOW;
  3255. parse_state->lex_state = EXPR_BEG;
  3256. return tOP_ASGN;
  3257. }
  3258. pushback(c, parse_state);
  3259. c = tPOW;
  3260. }
  3261. else {
  3262. if (c == '=') {
  3263. pslval->id = '*';
  3264. parse_state->lex_state = EXPR_BEG;
  3265. return tOP_ASGN;
  3266. }
  3267. pushback(c, parse_state);
  3268. if (IS_ARG() && space_seen && !ISSPACE(c)){
  3269. rb_warning("`*' interpreted as argument prefix");
  3270. c = tSTAR;
  3271. }
  3272. else if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID) {
  3273. c = tSTAR;
  3274. }
  3275. else {
  3276. c = '*';
  3277. }
  3278. }
  3279. switch (parse_state->lex_state) {
  3280. case EXPR_FNAME: case EXPR_DOT:
  3281. parse_state->lex_state = EXPR_ARG; break;
  3282. default:
  3283. parse_state->lex_state = EXPR_BEG; break;
  3284. }
  3285. return c;
  3286. case '!':
  3287. parse_state->lex_state = EXPR_BEG;
  3288. if ((c = nextc()) == '=') {
  3289. return tNEQ;
  3290. }
  3291. if (c == '~') {
  3292. return tNMATCH;
  3293. }
  3294. pushback(c, parse_state);
  3295. return '!';
  3296. case '=':
  3297. if (was_bol()) {
  3298. /* skip embedded rd document */
  3299. if (strncmp(parse_state->lex_p, "begin", 5) == 0 && ISSPACE(parse_state->lex_p[5])) {
  3300. for (;;) {
  3301. parse_state->lex_p = parse_state->lex_pend;
  3302. c = nextc();
  3303. if (c == -1) {
  3304. rb_compile_error(parse_state, "embedded document meets end of file");
  3305. return 0;
  3306. }
  3307. if (c != '=') continue;
  3308. if (strncmp(parse_state->lex_p, "end", 3) == 0 &&
  3309. (parse_state->lex_p + 3 == parse_state->lex_pend || ISSPACE(parse_state->lex_p[3]))) {
  3310. break;
  3311. }
  3312. }
  3313. parse_state->lex_p = parse_state->lex_pend;
  3314. goto retry;
  3315. }
  3316. }
  3317. switch (parse_state->lex_state) {
  3318. case EXPR_FNAME: case EXPR_DOT:
  3319. parse_state->lex_state = EXPR_ARG; break;
  3320. default:
  3321. parse_state->lex_state = EXPR_BEG; break;
  3322. }
  3323. if ((c = nextc()) == '=') {
  3324. if ((c = nextc()) == '=') {
  3325. return tEQQ;
  3326. }
  3327. pushback(c, parse_state);
  3328. return tEQ;
  3329. }
  3330. if (c == '~') {
  3331. return tMATCH;
  3332. }
  3333. else if (c == '>') {
  3334. return tASSOC;
  3335. }
  3336. pushback(c, parse_state);
  3337. return '=';
  3338. case '<':
  3339. c = nextc();
  3340. if (c == '<' &&
  3341. parse_state->lex_state != EXPR_END &&
  3342. parse_state->lex_state != EXPR_DOT &&
  3343. parse_state->lex_state != EXPR_ENDARG &&
  3344. parse_state->lex_state != EXPR_CLASS &&
  3345. (!IS_ARG() || space_seen)) {
  3346. int token = heredoc_identifier(parse_state);
  3347. if (token) return token;
  3348. }
  3349. switch (parse_state->lex_state) {
  3350. case EXPR_FNAME: case EXPR_DOT:
  3351. parse_state->lex_state = EXPR_ARG; break;
  3352. default:
  3353. parse_state->lex_state = EXPR_BEG; break;
  3354. }
  3355. if (c == '=') {
  3356. if ((c = nextc()) == '>') {
  3357. return tCMP;
  3358. }
  3359. pushback(c, parse_state);
  3360. return tLEQ;
  3361. }
  3362. if (c == '<') {
  3363. if ((c = nextc()) == '=') {
  3364. pslval->id = tLSHFT;
  3365. parse_state->lex_state = EXPR_BEG;
  3366. return tOP_ASGN;
  3367. }
  3368. pushback(c, parse_state);
  3369. return tLSHFT;
  3370. }
  3371. pushback(c, parse_state);
  3372. return '<';
  3373. case '>':
  3374. switch (parse_state->lex_state) {
  3375. case EXPR_FNAME: case EXPR_DOT:
  3376. parse_state->lex_state = EXPR_ARG; break;
  3377. default:
  3378. parse_state->lex_state = EXPR_BEG; break;
  3379. }
  3380. if ((c = nextc()) == '=') {
  3381. return tGEQ;
  3382. }
  3383. if (c == '>') {
  3384. if ((c = nextc()) == '=') {
  3385. pslval->id = tRSHFT;
  3386. parse_state->lex_state = EXPR_BEG;
  3387. return tOP_ASGN;
  3388. }
  3389. pushback(c, parse_state);
  3390. return tRSHFT;
  3391. }
  3392. pushback(c, parse_state);
  3393. return '>';
  3394. case '"':
  3395. lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
  3396. return tSTRING_BEG;
  3397. case '`':
  3398. if (parse_state->lex_state == EXPR_FNAME) {
  3399. parse_state->lex_state = EXPR_END;
  3400. return c;
  3401. }
  3402. if (parse_state->lex_state == EXPR_DOT) {
  3403. if (cmd_state)
  3404. parse_state->lex_state = EXPR_CMDARG;
  3405. else
  3406. parse_state->lex_state = EXPR_ARG;
  3407. return c;
  3408. }
  3409. lex_strterm = NEW_STRTERM(str_xquote, '`', 0);
  3410. pslval->id = 0; /* so that xstring gets used normally */
  3411. return tXSTRING_BEG;
  3412. case '\'':
  3413. lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
  3414. pslval->id = 0; /* so that xstring gets used normally */
  3415. return tSTRING_BEG;
  3416. case '?':
  3417. if (parse_state->lex_state == EXPR_END || parse_state->lex_state == EXPR_ENDARG) {
  3418. parse_state->lex_state = EXPR_BEG;
  3419. return '?';
  3420. }
  3421. c = nextc();
  3422. if (c == -1) {
  3423. rb_compile_error(parse_state, "incomplete character syntax");
  3424. return 0;
  3425. }
  3426. if (ISSPACE(c)){
  3427. if (!IS_ARG()){
  3428. int c2 = 0;
  3429. switch (c) {
  3430. case ' ':
  3431. c2 = 's';
  3432. break;
  3433. case '\n':
  3434. c2 = 'n';
  3435. break;
  3436. case '\t':
  3437. c2 = 't';
  3438. break;
  3439. case '\v':
  3440. c2 = 'v';
  3441. break;
  3442. case '\r':
  3443. c2 = 'r';
  3444. break;
  3445. case '\f':
  3446. c2 = 'f';
  3447. break;
  3448. }
  3449. if (c2) {
  3450. rb_warn("invalid character syntax; use ?\\%c", c2);
  3451. }
  3452. }
  3453. ternary:
  3454. pushback(c, parse_state);
  3455. parse_state->lex_state = EXPR_BEG;
  3456. parse_state->ternary_colon = 1;
  3457. return '?';
  3458. }
  3459. else if (ismbchar(c)) {
  3460. rb_warn("multibyte character literal not supported yet; use ?\\%.3o", c);
  3461. goto ternary;
  3462. }
  3463. else if ((ISALNUM(c) || c == '_') && parse_state->lex_p < parse_state->lex_pend && is_identchar(*(parse_state->lex_p))) {
  3464. goto ternary;
  3465. }
  3466. else if (c == '\\') {
  3467. c = read_escape(parse_state);
  3468. }
  3469. c &= 0xff;
  3470. parse_state->lex_state = EXPR_END;
  3471. pslval->node = NEW_FIXNUM((intptr_t)c);
  3472. return tINTEGER;
  3473. case '&':
  3474. if ((c = nextc()) == '&') {
  3475. parse_state->lex_state = EXPR_BEG;
  3476. if ((c = nextc()) == '=') {
  3477. pslval->id = tANDOP;
  3478. parse_state->lex_state = EXPR_BEG;
  3479. return tOP_ASGN;
  3480. }
  3481. pushback(c, parse_state);
  3482. return tANDOP;
  3483. }
  3484. else if (c == '=') {
  3485. pslval->id = '&';
  3486. parse_state->lex_state = EXPR_BEG;
  3487. return tOP_ASGN;
  3488. }
  3489. pushback(c, parse_state);
  3490. if (IS_ARG() && space_seen && !ISSPACE(c)){
  3491. rb_warning("`&' interpreted as argument prefix");
  3492. c = tAMPER;
  3493. }
  3494. else if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID) {
  3495. c = tAMPER;
  3496. }
  3497. else {
  3498. c = '&';
  3499. }
  3500. switch (parse_state->lex_state) {
  3501. case EXPR_FNAME: case EXPR_DOT:
  3502. parse_state->lex_state = EXPR_ARG; break;
  3503. default:
  3504. parse_state->lex_state = EXPR_BEG;
  3505. }
  3506. return c;
  3507. case '|':
  3508. if ((c = nextc()) == '|') {
  3509. parse_state->lex_state = EXPR_BEG;
  3510. if ((c = nextc()) == '=') {
  3511. pslval->id = tOROP;
  3512. parse_state->lex_state = EXPR_BEG;
  3513. return tOP_ASGN;
  3514. }
  3515. pushback(c, parse_state);
  3516. return tOROP;
  3517. }
  3518. if (c == '=') {
  3519. pslval->id = '|';
  3520. parse_state->lex_state = EXPR_BEG;
  3521. return tOP_ASGN;
  3522. }
  3523. if (parse_state->lex_state == EXPR_FNAME || parse_state->lex_state == EXPR_DOT) {
  3524. parse_state->lex_state = EXPR_ARG;
  3525. }
  3526. else {
  3527. parse_state->lex_state = EXPR_BEG;
  3528. }
  3529. pushback(c, parse_state);
  3530. return '|';
  3531. case '+':
  3532. c = nextc();
  3533. if (parse_state->lex_state == EXPR_FNAME || parse_state->lex_state == EXPR_DOT) {
  3534. parse_state->lex_state = EXPR_ARG;
  3535. if (c == '@') {
  3536. return tUPLUS;
  3537. }
  3538. pushback(c, parse_state);
  3539. return '+';
  3540. }
  3541. if (c == '=') {
  3542. pslval->id = '+';
  3543. parse_state->lex_state = EXPR_BEG;
  3544. return tOP_ASGN;
  3545. }
  3546. if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID ||
  3547. (IS_ARG() && space_seen && !ISSPACE(c))) {
  3548. if (IS_ARG()) arg_ambiguous();
  3549. parse_state->lex_state = EXPR_BEG;
  3550. pushback(c, parse_state);
  3551. if (ISDIGIT(c)) {
  3552. c = '+';
  3553. goto start_num;
  3554. }
  3555. return tUPLUS;
  3556. }
  3557. parse_state->lex_state = EXPR_BEG;
  3558. pushback(c, parse_state);
  3559. return '+';
  3560. case '-':
  3561. c = nextc();
  3562. if (parse_state->lex_state == EXPR_FNAME || parse_state->lex_state == EXPR_DOT) {
  3563. parse_state->lex_state = EXPR_ARG;
  3564. if (c == '@') {
  3565. return tUMINUS;
  3566. }
  3567. pushback(c, parse_state);
  3568. return '-';
  3569. }
  3570. if (c == '=') {
  3571. pslval->id = '-';
  3572. parse_state->lex_state = EXPR_BEG;
  3573. return tOP_ASGN;
  3574. }
  3575. if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID ||
  3576. (IS_ARG() && space_seen && !ISSPACE(c))) {
  3577. if (IS_ARG()) arg_ambiguous();
  3578. parse_state->lex_state = EXPR_BEG;
  3579. pushback(c, parse_state);
  3580. if (ISDIGIT(c)) {
  3581. return tUMINUS_NUM;
  3582. }
  3583. return tUMINUS;
  3584. }
  3585. parse_state->lex_state = EXPR_BEG;
  3586. pushback(c, parse_state);
  3587. return '-';
  3588. case '.':
  3589. parse_state->lex_state = EXPR_BEG;
  3590. if ((c = nextc()) == '.') {
  3591. if ((c = nextc()) == '.') {
  3592. return tDOT3;
  3593. }
  3594. pushback(c, parse_state);
  3595. return tDOT2;
  3596. }
  3597. pushback(c, parse_state);
  3598. if (ISDIGIT(c)) {
  3599. yyerror("no .<digit> floating literal anymore; put 0 before dot");
  3600. }
  3601. parse_state->lex_state = EXPR_DOT;
  3602. return '.';
  3603. start_num:
  3604. case '0': case '1': case '2': case '3': case '4':
  3605. case '5': case '6': case '7': case '8': case '9':
  3606. {
  3607. int is_float, seen_point, seen_e, nondigit;
  3608. is_float = seen_point = seen_e = nondigit = 0;
  3609. parse_state->lex_state = EXPR_END;
  3610. newtok(parse_state);
  3611. if (c == '-' || c == '+') {
  3612. tokadd((char)c,parse_state);
  3613. c = nextc();
  3614. }
  3615. if (c == '0') {
  3616. int start = toklen();
  3617. c = nextc();
  3618. if (c == 'x' || c == 'X') {
  3619. /* hexadecimal */
  3620. c = nextc();
  3621. if (ISXDIGIT(c)) {
  3622. do {
  3623. if (c == '_') {
  3624. if (nondigit) break;
  3625. nondigit = c;
  3626. continue;
  3627. }
  3628. if (!ISXDIGIT(c)) break;
  3629. nondigit = 0;
  3630. tokadd((char)c,parse_state);
  3631. } while ((c = nextc()) != -1);
  3632. }
  3633. pushback(c, parse_state);
  3634. tokfix();
  3635. if (toklen() == start) {
  3636. yyerror("numeric literal without digits");
  3637. }
  3638. else if (nondigit) goto trailing_uc;
  3639. pslval->node = NEW_HEXNUM(string_new2(tok()));
  3640. return tINTEGER;
  3641. }
  3642. if (c == 'b' || c == 'B') {
  3643. /* binary */
  3644. c = nextc();
  3645. if (c == '0' || c == '1') {
  3646. do {
  3647. if (c == '_') {
  3648. if (nondigit) break;
  3649. nondigit = c;
  3650. continue;
  3651. }
  3652. if (c != '0' && c != '1') break;
  3653. nondigit = 0;
  3654. tokadd((char)c, parse_state);
  3655. } while ((c = nextc()) != -1);
  3656. }
  3657. pushback(c, parse_state);
  3658. tokfix();
  3659. if (toklen() == start) {
  3660. yyerror("numeric literal without digits");
  3661. }
  3662. else if (nondigit) goto trailing_uc;
  3663. pslval->node = NEW_BINNUM(string_new2(tok()));
  3664. return tINTEGER;
  3665. }
  3666. if (c == 'd' || c == 'D') {
  3667. /* decimal */
  3668. c = nextc();
  3669. if (ISDIGIT(c)) {
  3670. do {
  3671. if (c == '_') {
  3672. if (nondigit) break;
  3673. nondigit = c;
  3674. continue;
  3675. }
  3676. if (!ISDIGIT(c)) break;
  3677. nondigit = 0;
  3678. tokadd((char)c, parse_state);
  3679. } while ((c = nextc()) != -1);
  3680. }
  3681. pushback(c, parse_state);
  3682. tokfix();
  3683. if (toklen() == start) {
  3684. yyerror("numeric literal without digits");
  3685. }
  3686. else if (nondigit) goto trailing_uc;
  3687. pslval->node = NEW_NUMBER(string_new2(tok()));
  3688. return tINTEGER;
  3689. }
  3690. if (c == '_') {
  3691. /* 0_0 */
  3692. goto octal_number;
  3693. }
  3694. if (c == 'o' || c == 'O') {
  3695. /* prefixed octal */
  3696. c = nextc();
  3697. if (c == '_') {
  3698. yyerror("numeric literal without digits");
  3699. }
  3700. }
  3701. if (c >= '0' && c <= '7') {
  3702. /* octal */
  3703. octal_number:
  3704. do {
  3705. if (c == '_') {
  3706. if (nondigit) break;
  3707. nondigit = c;
  3708. continue;
  3709. }
  3710. if (c < '0' || c > '7') break;
  3711. nondigit = 0;
  3712. tokadd((char)c, parse_state);
  3713. } while ((c = nextc()) != -1);
  3714. if (toklen() > start) {
  3715. pushback(c, parse_state);
  3716. tokfix();
  3717. if (nondigit) goto trailing_uc;
  3718. pslval->node = NEW_OCTNUM(string_new2(tok()));
  3719. return tINTEGER;
  3720. }
  3721. if (nondigit) {
  3722. pushback(c, parse_state);
  3723. goto trailing_uc;
  3724. }
  3725. }
  3726. if (c > '7' && c <= '9') {
  3727. yyerror("Illegal octal digit");
  3728. }
  3729. else if (c == '.' || c == 'e' || c == 'E') {
  3730. tokadd('0', parse_state);
  3731. }
  3732. else {
  3733. pushback(c, parse_state);
  3734. pslval->node = NEW_FIXNUM(0);
  3735. return tINTEGER;
  3736. }
  3737. }
  3738. for (;;) {
  3739. switch (c) {
  3740. case '0': case '1': case '2': case '3': case '4':
  3741. case '5': case '6': case '7': case '8': case '9':
  3742. nondigit = 0;
  3743. tokadd((char)c, parse_state);
  3744. break;
  3745. case '.':
  3746. if (nondigit) goto trailing_uc;
  3747. if (seen_point || seen_e) {
  3748. goto decode_num;
  3749. }
  3750. else {
  3751. int c0 = nextc();
  3752. if (!ISDIGIT(c0)) {
  3753. pushback(c0, parse_state);
  3754. goto decode_num;
  3755. }
  3756. c = c0;
  3757. }
  3758. tokadd('.', parse_state);
  3759. tokadd((char)c, parse_state);
  3760. is_float++;
  3761. seen_point++;
  3762. nondigit = 0;
  3763. break;
  3764. case 'e':
  3765. case 'E':
  3766. if (nondigit) {
  3767. pushback(c, parse_state);
  3768. c = nondigit;
  3769. goto decode_num;
  3770. }
  3771. if (seen_e) {
  3772. goto decode_num;
  3773. }
  3774. tokadd((char)c, parse_state);
  3775. seen_e++;
  3776. is_float++;
  3777. nondigit = c;
  3778. c = nextc();
  3779. if (c != '-' && c != '+') continue;
  3780. tokadd((char)c, parse_state);
  3781. nondigit = c;
  3782. break;
  3783. case '_': /* `_' in number just ignored */
  3784. if (nondigit) goto decode_num;
  3785. nondigit = c;
  3786. break;
  3787. default:
  3788. goto decode_num;
  3789. }
  3790. c = nextc();
  3791. }
  3792. decode_num:
  3793. pushback(c, parse_state);
  3794. tokfix();
  3795. if (nondigit) {
  3796. char tmp[30];
  3797. trailing_uc:
  3798. snprintf(tmp, sizeof(tmp), "trailing `%c' in number", nondigit);
  3799. yyerror(tmp);
  3800. }
  3801. if (is_float) {
  3802. pslval->node = NEW_FLOAT(string_new2(tok()));
  3803. return tFLOAT;
  3804. }
  3805. pslval->node = NEW_NUMBER(string_new2(tok()));
  3806. return tINTEGER;
  3807. }
  3808. case ']':
  3809. case '}':
  3810. case ')':
  3811. COND_LEXPOP();
  3812. CMDARG_LEXPOP();
  3813. parse_state->lex_state = EXPR_END;
  3814. return c;
  3815. case ':':
  3816. c = nextc();
  3817. if (c == ':') {
  3818. if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID ||
  3819. parse_state->lex_state == EXPR_CLASS || (IS_ARG() && space_seen)) {
  3820. parse_state->lex_state = EXPR_BEG;
  3821. return tCOLON3;
  3822. }
  3823. parse_state->lex_state = EXPR_DOT;
  3824. return tCOLON2;
  3825. }
  3826. if (parse_state->lex_state == EXPR_END || parse_state->lex_state == EXPR_ENDARG || ISSPACE(c)) {
  3827. pushback(c, parse_state);
  3828. parse_state->lex_state = EXPR_BEG;
  3829. return ':';
  3830. }
  3831. switch (c) {
  3832. case '\'':
  3833. lex_strterm = NEW_STRTERM(str_ssym, (intptr_t)c, 0);
  3834. break;
  3835. case '"':
  3836. lex_strterm = NEW_STRTERM(str_dsym, (intptr_t)c, 0);
  3837. break;
  3838. default:
  3839. pushback(c, parse_state);
  3840. break;
  3841. }
  3842. parse_state->lex_state = EXPR_FNAME;
  3843. return tSYMBEG;
  3844. case '/':
  3845. if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID) {
  3846. lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
  3847. return tREGEXP_BEG;
  3848. }
  3849. if ((c = nextc()) == '=') {
  3850. pslval->id = '/';
  3851. parse_state->lex_state = EXPR_BEG;
  3852. return tOP_ASGN;
  3853. }
  3854. pushback(c, parse_state);
  3855. if (IS_ARG() && space_seen) {
  3856. if (!ISSPACE(c)) {
  3857. arg_ambiguous();
  3858. lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
  3859. return tREGEXP_BEG;
  3860. }
  3861. }
  3862. switch (parse_state->lex_state) {
  3863. case EXPR_FNAME: case EXPR_DOT:
  3864. parse_state->lex_state = EXPR_ARG; break;
  3865. default:
  3866. parse_state->lex_state = EXPR_BEG; break;
  3867. }
  3868. return '/';
  3869. case '^':
  3870. if ((c = nextc()) == '=') {
  3871. pslval->id = '^';
  3872. parse_state->lex_state = EXPR_BEG;
  3873. return tOP_ASGN;
  3874. }
  3875. switch (parse_state->lex_state) {
  3876. case EXPR_FNAME: case EXPR_DOT:
  3877. parse_state->lex_state = EXPR_ARG; break;
  3878. default:
  3879. parse_state->lex_state = EXPR_BEG; break;
  3880. }
  3881. pushback(c, parse_state);
  3882. return '^';
  3883. case ';':
  3884. command_start = TRUE;
  3885. case ',':
  3886. parse_state->lex_state = EXPR_BEG;
  3887. return c;
  3888. case '~':
  3889. if (parse_state->lex_state == EXPR_FNAME || parse_state->lex_state == EXPR_DOT) {
  3890. if ((c = nextc()) != '@') {
  3891. pushback(c, parse_state);
  3892. }
  3893. }
  3894. switch (parse_state->lex_state) {
  3895. case EXPR_FNAME: case EXPR_DOT:
  3896. parse_state->lex_state = EXPR_ARG; break;
  3897. default:
  3898. parse_state->lex_state = EXPR_BEG; break;
  3899. }
  3900. return '~';
  3901. case '(':
  3902. command_start = TRUE;
  3903. if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID) {
  3904. c = tLPAREN;
  3905. }
  3906. else if (space_seen) {
  3907. if (parse_state->lex_state == EXPR_CMDARG) {
  3908. c = tLPAREN_ARG;
  3909. }
  3910. else if (parse_state->lex_state == EXPR_ARG) {
  3911. rb_warn("don't put space before argument parentheses");
  3912. c = '(';
  3913. }
  3914. }
  3915. COND_PUSH(0);
  3916. CMDARG_PUSH(0);
  3917. parse_state->lex_state = EXPR_BEG;
  3918. return c;
  3919. case '[':
  3920. if (parse_state->lex_state == EXPR_FNAME || parse_state->lex_state == EXPR_DOT) {
  3921. parse_state->lex_state = EXPR_ARG;
  3922. if ((c = nextc()) == ']') {
  3923. if ((c = nextc()) == '=') {
  3924. return tASET;
  3925. }
  3926. pushback(c, parse_state);
  3927. return tAREF;
  3928. }
  3929. pushback(c, parse_state);
  3930. return '[';
  3931. }
  3932. else if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID) {
  3933. c = tLBRACK;
  3934. }
  3935. else if (IS_ARG() && space_seen) {
  3936. c = tLBRACK;
  3937. }
  3938. parse_state->lex_state = EXPR_BEG;
  3939. COND_PUSH(0);
  3940. CMDARG_PUSH(0);
  3941. return c;
  3942. case '{':
  3943. if (IS_ARG() || parse_state->lex_state == EXPR_END)
  3944. c = '{'; /* block (primary) */
  3945. else if (parse_state->lex_state == EXPR_ENDARG)
  3946. c = tLBRACE_ARG; /* block (expr) */
  3947. else
  3948. c = tLBRACE; /* hash */
  3949. COND_PUSH(0);
  3950. CMDARG_PUSH(0);
  3951. parse_state->lex_state = EXPR_BEG;
  3952. if (c != tLBRACE) command_start = TRUE;
  3953. return c;
  3954. case '\\':
  3955. c = nextc();
  3956. if (c == '\n') {
  3957. space_seen = 1;
  3958. goto retry; /* skip \\n */
  3959. }
  3960. pushback(c, parse_state);
  3961. if(parse_state->lex_state == EXPR_BEG
  3962. || parse_state->lex_state == EXPR_MID || space_seen) {
  3963. parse_state->lex_state = EXPR_DOT;
  3964. return tUBS;
  3965. }
  3966. parse_state->lex_state = EXPR_DOT;
  3967. return '\\';
  3968. case '%':
  3969. if (parse_state->lex_state == EXPR_BEG || parse_state->lex_state == EXPR_MID) {
  3970. intptr_t term;
  3971. intptr_t paren;
  3972. char tmpstr[256];
  3973. char *cur;
  3974. c = nextc();
  3975. quotation:
  3976. if (!ISALNUM(c)) {
  3977. term = c;
  3978. c = 'Q';
  3979. }
  3980. else {
  3981. term = nextc();
  3982. if (ISALNUM(term) || ismbchar(term)) {
  3983. cur = tmpstr;
  3984. *cur++ = c;
  3985. while(ISALNUM(term) || ismbchar(term)) {
  3986. *cur++ = term;
  3987. term = nextc();
  3988. }
  3989. *cur = 0;
  3990. c = 1;
  3991. }
  3992. }
  3993. if (c == -1 || term == -1) {
  3994. rb_compile_error(parse_state, "unterminated quoted string meets end of file");
  3995. return 0;
  3996. }
  3997. paren = term;
  3998. if (term == '(') term = ')';
  3999. else if (term == '[') term = ']';
  4000. else if (term == '{') term = '}';
  4001. else if (term == '<') term = '>';
  4002. else paren = 0;
  4003. switch (c) {
  4004. case 'Q':
  4005. lex_strterm = NEW_STRTERM(str_dquote, term, paren);
  4006. return tSTRING_BEG;
  4007. case 'q':
  4008. lex_strterm = NEW_STRTERM(str_squote, term, paren);
  4009. return tSTRING_BEG;
  4010. case 'W':
  4011. lex_strterm = NEW_STRTERM(str_dquote | STR_FUNC_QWORDS, term, paren);
  4012. do {c = nextc();} while (ISSPACE(c));
  4013. pushback(c, parse_state);
  4014. return tWORDS_BEG;
  4015. case 'w':
  4016. lex_strterm = NEW_STRTERM(str_squote | STR_FUNC_QWORDS, term, paren);
  4017. do {c = nextc();} while (ISSPACE(c));
  4018. pushback(c, parse_state);
  4019. return tQWORDS_BEG;
  4020. case 'x':
  4021. lex_strterm = NEW_STRTERM(str_xquote, term, paren);
  4022. pslval->id = 0;
  4023. return tXSTRING_BEG;
  4024. case 'r':
  4025. lex_strterm = NEW_STRTERM(str_regexp, term, paren);
  4026. return tREGEXP_BEG;
  4027. case 's':
  4028. lex_strterm = NEW_STRTERM(str_ssym, term, paren);
  4029. parse_state->lex_state = EXPR_FNAME;
  4030. return tSYMBEG;
  4031. case 1:
  4032. lex_strterm = NEW_STRTERM(str_xquote, term, paren);
  4033. pslval->id = rb_intern(tmpstr);
  4034. return tXSTRING_BEG;
  4035. default:
  4036. lex_strterm = NEW_STRTERM(str_xquote, term, paren);
  4037. tmpstr[0] = c;
  4038. tmpstr[1] = 0;
  4039. pslval->id = rb_intern(tmpstr);
  4040. return tXSTRING_BEG;
  4041. }
  4042. }
  4043. if ((c = nextc()) == '=') {
  4044. pslval->id = '%';
  4045. parse_state->lex_state = EXPR_BEG;
  4046. return tOP_ASGN;
  4047. }
  4048. if (IS_ARG() && space_seen && !ISSPACE(c)) {
  4049. goto quotation;
  4050. }
  4051. switch (parse_state->lex_state) {
  4052. case EXPR_FNAME: case EXPR_DOT:
  4053. parse_state->lex_state = EXPR_ARG; break;
  4054. default:
  4055. parse_state->lex_state = EXPR_BEG; break;
  4056. }
  4057. pushback(c, parse_state);
  4058. return '%';
  4059. case '$':
  4060. last_state = parse_state->lex_state;
  4061. parse_state->lex_state = EXPR_END;
  4062. newtok(parse_state);
  4063. c = nextc();
  4064. switch (c) {
  4065. case '_': /* $_: last read line string */
  4066. c = nextc();
  4067. if (is_identchar(c)) {
  4068. tokadd('$', parse_state);
  4069. tokadd('_', parse_state);
  4070. break;
  4071. }
  4072. pushback(c, parse_state);
  4073. c = '_';
  4074. /* fall through */
  4075. case '~': /* $~: match-data */
  4076. local_cnt(c);
  4077. /* fall through */
  4078. case '*': /* $*: argv */
  4079. case '$': /* $$: pid */
  4080. case '?': /* $?: last status */
  4081. case '!': /* $!: error string */
  4082. case '@': /* $@: error position */
  4083. case '/': /* $/: input record separator */
  4084. case '\\': /* $\: output record separator */
  4085. case ';': /* $;: field separator */
  4086. case ',': /* $,: output field separator */
  4087. case '.': /* $.: last read line number */
  4088. case '=': /* $=: ignorecase */
  4089. case ':': /* $:: load path */
  4090. case '<': /* $<: reading filename */
  4091. case '>': /* $>: default output handle */
  4092. case '\"': /* $": already loaded files */
  4093. tokadd('$', parse_state);
  4094. tokadd((char)c, parse_state);
  4095. tokfix();
  4096. pslval->id = rb_intern(tok());
  4097. return tGVAR;
  4098. case '-':
  4099. tokadd('$', parse_state);
  4100. tokadd((char)c, parse_state);
  4101. c = nextc();
  4102. tokadd((char)c, parse_state);
  4103. gvar:
  4104. tokfix();
  4105. pslval->id = rb_intern(tok());
  4106. /* xxx shouldn't check if valid option variable */
  4107. return tGVAR;
  4108. case '&': /* $&: last match */
  4109. case '`': /* $`: string before last match */
  4110. case '\'': /* $': string after last match */
  4111. case '+': /* $+: string matches last paren. */
  4112. if (last_state == EXPR_FNAME) {
  4113. tokadd((char)'$', parse_state);
  4114. tokadd(c, parse_state);
  4115. goto gvar;
  4116. }
  4117. pslval->node = NEW_BACK_REF((intptr_t)c);
  4118. return tBACK_REF;
  4119. case '1': case '2': case '3':
  4120. case '4': case '5': case '6':
  4121. case '7': case '8': case '9':
  4122. tokadd('$', parse_state);
  4123. do {
  4124. tokadd((char)c, parse_state);
  4125. c = nextc();
  4126. } while (ISDIGIT(c));
  4127. pushback(c, parse_state);
  4128. if (last_state == EXPR_FNAME) goto gvar;
  4129. tokfix();
  4130. pslval->node = NEW_NTH_REF((intptr_t)atoi(tok()+1));
  4131. return tNTH_REF;
  4132. default:
  4133. if (!is_identchar(c)) {
  4134. pushback(c, parse_state);
  4135. return '$';
  4136. }
  4137. case '0':
  4138. tokadd('$', parse_state);
  4139. }
  4140. break;
  4141. case '@':
  4142. c = nextc();
  4143. newtok(parse_state);
  4144. tokadd('@', parse_state);
  4145. if (c == '@') {
  4146. tokadd('@', parse_state);
  4147. c = nextc();
  4148. }
  4149. if (ISDIGIT(c)) {
  4150. if (tokidx == 1) {
  4151. rb_compile_error(parse_state,
  4152. "`@%c' is not allowed as an instance variable name", c);
  4153. }
  4154. else {
  4155. rb_compile_error(parse_state,
  4156. "`@@%c' is not allowed as a class variable name", c);
  4157. }
  4158. }
  4159. if (!is_identchar(c)) {
  4160. pushback(c, parse_state);
  4161. return '@';
  4162. }
  4163. break;
  4164. case '_':
  4165. if (was_bol() && whole_match_p("__END__", 7, 0, parse_state)) {
  4166. parse_state->lex_lastline = 0;
  4167. parse_state->end_seen = 1;
  4168. parse_state->lex_p = parse_state->lex_pend;
  4169. return k__END__;
  4170. }
  4171. newtok(parse_state);
  4172. break;
  4173. default:
  4174. if (!is_identchar(c)) {
  4175. rb_compile_error(parse_state, "Invalid char `\\%03o' in expression", c);
  4176. goto retry;
  4177. }
  4178. newtok(parse_state);
  4179. break;
  4180. }
  4181. do {
  4182. tokadd((char)c, parse_state);
  4183. if (ismbchar(c)) {
  4184. int i, len = mbclen(c)-1;
  4185. for (i = 0; i < len; i++) {
  4186. c = nextc();
  4187. tokadd((char)c, parse_state);
  4188. }
  4189. }
  4190. c = nextc();
  4191. } while (is_identchar(c));
  4192. if ((c == '!' || c == '?') && is_identchar(tok()[0]) && !peek('=')) {
  4193. tokadd((char)c, parse_state);
  4194. }
  4195. else {
  4196. pushback(c, parse_state);
  4197. }
  4198. tokfix();
  4199. {
  4200. int result = 0;
  4201. last_state = parse_state->lex_state;
  4202. switch (tok()[0]) {
  4203. case '$':
  4204. parse_state->lex_state = EXPR_END;
  4205. result = tGVAR;
  4206. break;
  4207. case '@':
  4208. parse_state->lex_state = EXPR_END;
  4209. if (tok()[1] == '@')
  4210. result = tCVAR;
  4211. else
  4212. result = tIVAR;
  4213. break;
  4214. default:
  4215. if (toklast() == '!' || toklast() == '?') {
  4216. result = tFID;
  4217. }
  4218. else {
  4219. if (parse_state->lex_state == EXPR_FNAME) {
  4220. if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
  4221. (!peek('=') || (parse_state->lex_p + 1 < parse_state->lex_pend && (parse_state->lex_p)[1] == '>'))) {
  4222. result = tIDENTIFIER;
  4223. tokadd((char)c, parse_state);
  4224. tokfix();
  4225. }
  4226. else {
  4227. pushback(c, parse_state);
  4228. }
  4229. }
  4230. if (result == 0 && ISUPPER(tok()[0])) {
  4231. result = tCONSTANT;
  4232. }
  4233. else {
  4234. result = tIDENTIFIER;
  4235. }
  4236. }
  4237. if (parse_state->lex_state != EXPR_DOT) {
  4238. const struct kwtable *kw;
  4239. /* See if it is a reserved word. */
  4240. kw = syd_reserved_word(tok(), toklen());
  4241. if (kw) {
  4242. enum lex_state state = parse_state->lex_state;
  4243. parse_state->lex_state = kw->state;
  4244. if (state == EXPR_FNAME) {
  4245. pslval->id = rb_intern(kw->name);
  4246. }
  4247. if (kw->id[0] == kDO) {
  4248. command_start = TRUE;
  4249. if (COND_P()) return kDO_COND;
  4250. if (CMDARG_P() && state != EXPR_CMDARG)
  4251. return kDO_BLOCK;
  4252. if (state == EXPR_ENDARG)
  4253. return kDO_BLOCK;
  4254. return kDO;
  4255. }
  4256. if (state == EXPR_BEG)
  4257. return kw->id[0];
  4258. else {
  4259. if (kw->id[0] != kw->id[1])
  4260. parse_state->lex_state = EXPR_BEG;
  4261. return kw->id[1];
  4262. }
  4263. }
  4264. }
  4265. if (parse_state->lex_state == EXPR_BEG ||
  4266. parse_state->lex_state == EXPR_MID ||
  4267. parse_state->lex_state == EXPR_DOT ||
  4268. parse_state->lex_state == EXPR_ARG ||
  4269. parse_state->lex_state == EXPR_CMDARG) {
  4270. if (cmd_state) {
  4271. parse_state->lex_state = EXPR_CMDARG;
  4272. }
  4273. else {
  4274. parse_state->lex_state = EXPR_ARG;
  4275. }
  4276. }
  4277. else {
  4278. parse_state->lex_state = EXPR_END;
  4279. }
  4280. }
  4281. pslval->id = rb_intern(tok());
  4282. if(is_local_id(pslval->id) &&
  4283. last_state != EXPR_DOT &&
  4284. local_id(pslval->id)) {
  4285. parse_state->lex_state = EXPR_END;
  4286. }
  4287. /* if (is_local_id(pslval->id) && local_id(pslval->id)) { */
  4288. /* parse_state->lex_state = EXPR_END; */
  4289. /* } */
  4290. return result;
  4291. }
  4292. }
  4293. NODE*
  4294. syd_node_newnode(rb_parse_state *st, enum node_type type,
  4295. Object* a0, Object* a1, Object* a2)
  4296. {
  4297. NODE *n = (NODE*)pt_allocate(st, sizeof(NODE));
  4298. n->flags = 0;
  4299. nd_set_type(n, type);
  4300. nd_set_line(n, ruby_sourceline);
  4301. n->nd_file = ruby_sourcefile;
  4302. n->u1.value = a0;
  4303. n->u2.value = a1;
  4304. n->u3.value = a2;
  4305. return n;
  4306. }
  4307. static NODE*
  4308. newline_node(rb_parse_state *parse_state, NODE *node)
  4309. {
  4310. NODE *nl = 0;
  4311. if (node) {
  4312. if (nd_type(node) == NODE_NEWLINE) return node;
  4313. nl = NEW_NEWLINE(node);
  4314. fixpos(nl, node);
  4315. nl->nd_nth = nd_line(node);
  4316. }
  4317. return nl;
  4318. }
  4319. static void
  4320. fixpos(NODE *node, NODE *orig)
  4321. {
  4322. if (!node) return;
  4323. if (!orig) return;
  4324. if (orig == (NODE*)1) return;
  4325. node->nd_file = orig->nd_file;
  4326. nd_set_line(node, nd_line(orig));
  4327. }
  4328. static void
  4329. parser_warning(rb_parse_state *parse_state, NODE *node, const char *mesg)
  4330. {
  4331. int line = ruby_sourceline;
  4332. if(parse_state->emit_warnings) {
  4333. ruby_sourceline = nd_line(node);
  4334. printf("%s:%zi: warning: %s\n", ruby_sourcefile, ruby_sourceline, mesg);
  4335. ruby_sourceline = line;
  4336. }
  4337. }
  4338. static NODE*
  4339. block_append(rb_parse_state *parse_state, NODE *head, NODE *tail)
  4340. {
  4341. NODE *end, *h = head;
  4342. if (tail == 0) return head;
  4343. again:
  4344. if (h == 0) return tail;
  4345. switch (nd_type(h)) {
  4346. case NODE_NEWLINE:
  4347. h = h->nd_next;
  4348. goto again;
  4349. case NODE_STR:
  4350. case NODE_LIT:
  4351. parser_warning(parse_state, h, "unused literal ignored");
  4352. return tail;
  4353. default:
  4354. h = end = NEW_BLOCK(head);
  4355. end->nd_end = end;
  4356. fixpos(end, head);
  4357. head = end;
  4358. break;
  4359. case NODE_BLOCK:
  4360. end = h->nd_end;
  4361. break;
  4362. }
  4363. if (RTEST(ruby_verbose)) {
  4364. NODE *nd = end->nd_head;
  4365. newline:
  4366. switch (nd_type(nd)) {
  4367. case NODE_RETURN:
  4368. case NODE_BREAK:
  4369. case NODE_NEXT:
  4370. case NODE_REDO:
  4371. case NODE_RETRY:
  4372. parser_warning(parse_state, nd, "statement not reached");
  4373. break;
  4374. case NODE_NEWLINE:
  4375. nd = nd->nd_next;
  4376. goto newline;
  4377. default:
  4378. break;
  4379. }
  4380. }
  4381. if (nd_type(tail) != NODE_BLOCK) {
  4382. tail = NEW_BLOCK(tail);
  4383. tail->nd_end = tail;
  4384. }
  4385. end->nd_next = tail;
  4386. h->nd_end = tail->nd_end;
  4387. return head;
  4388. }
  4389. /* append item to the list */
  4390. static NODE*
  4391. list_append(rb_parse_state *parse_state, NODE *list, NODE *item)
  4392. {
  4393. NODE *last;
  4394. if (list == 0) return NEW_LIST(item);
  4395. if (list->nd_next) {
  4396. last = list->nd_next->nd_end;
  4397. }
  4398. else {
  4399. last = list;
  4400. }
  4401. list->nd_alen += 1;
  4402. last->nd_next = NEW_LIST(item);
  4403. list->nd_next->nd_end = last->nd_next;
  4404. return list;
  4405. }
  4406. /* concat two lists */
  4407. static NODE*
  4408. list_concat(NODE *head, NODE *tail)
  4409. {
  4410. NODE *last;
  4411. if (head->nd_next) {
  4412. last = head->nd_next->nd_end;
  4413. }
  4414. else {
  4415. last = head;
  4416. }
  4417. head->nd_alen += tail->nd_alen;
  4418. last->nd_next = tail;
  4419. if (tail->nd_next) {
  4420. head->nd_next->nd_end = tail->nd_next->nd_end;
  4421. }
  4422. else {
  4423. head->nd_next->nd_end = tail;
  4424. }
  4425. return head;
  4426. }
  4427. /* concat two string literals */
  4428. static NODE *
  4429. literal_concat(rb_parse_state *parse_state, NODE *head, NODE *tail)
  4430. {
  4431. enum node_type htype;
  4432. if (!head) return tail;
  4433. if (!tail) return head;
  4434. htype = (enum node_type)nd_type(head);
  4435. if (htype == NODE_EVSTR) {
  4436. NODE *node = NEW_DSTR(string_new(0, 0));
  4437. head = list_append(parse_state, node, head);
  4438. }
  4439. switch (nd_type(tail)) {
  4440. case NODE_STR:
  4441. if (htype == NODE_STR) {
  4442. if(head->nd_str) {
  4443. bconcat(head->nd_str, tail->nd_str);
  4444. bdestroy(tail->nd_str);
  4445. } else {
  4446. head = tail;
  4447. }
  4448. }
  4449. else {
  4450. list_append(parse_state, head, tail);
  4451. }
  4452. break;
  4453. case NODE_DSTR:
  4454. if (htype == NODE_STR) {
  4455. bconcat(head->nd_str, tail->nd_str);
  4456. bdestroy(tail->nd_str);
  4457. tail->nd_lit = head->nd_lit;
  4458. head = tail;
  4459. }
  4460. else {
  4461. nd_set_type(tail, NODE_ARRAY);
  4462. tail->nd_head = NEW_STR(tail->nd_lit);
  4463. list_concat(head, tail);
  4464. }
  4465. break;
  4466. case NODE_EVSTR:
  4467. if (htype == NODE_STR) {
  4468. nd_set_type(head, NODE_DSTR);
  4469. head->nd_alen = 1;
  4470. }
  4471. list_append(parse_state, head, tail);
  4472. break;
  4473. }
  4474. return head;
  4475. }
  4476. static NODE *
  4477. evstr2dstr(rb_parse_state *parse_state, NODE *node)
  4478. {
  4479. if (nd_type(node) == NODE_EVSTR) {
  4480. node = list_append(parse_state, NEW_DSTR(string_new(0, 0)), node);
  4481. }
  4482. return node;
  4483. }
  4484. static NODE *
  4485. new_evstr(rb_parse_state *parse_state, NODE *node)
  4486. {
  4487. NODE *head = node;
  4488. again:
  4489. if (node) {
  4490. switch (nd_type(node)) {
  4491. case NODE_STR: case NODE_DSTR: case NODE_EVSTR:
  4492. return node;
  4493. case NODE_NEWLINE:
  4494. node = node->nd_next;
  4495. goto again;
  4496. }
  4497. }
  4498. return NEW_EVSTR(head);
  4499. }
  4500. static const struct {
  4501. ID token;
  4502. const char name[12];
  4503. } op_tbl[] = {
  4504. {tDOT2, ".."},
  4505. {tDOT3, "..."},
  4506. {'+', "+"},
  4507. {'-', "-"},
  4508. {'+', "+(binary)"},
  4509. {'-', "-(binary)"},
  4510. {'*', "*"},
  4511. {'/', "/"},
  4512. {'%', "%"},
  4513. {tPOW, "**"},
  4514. {tUPLUS, "+@"},
  4515. {tUMINUS, "-@"},
  4516. {tUPLUS, "+(unary)"},
  4517. {tUMINUS, "-(unary)"},
  4518. {'|', "|"},
  4519. {'^', "^"},
  4520. {'&', "&"},
  4521. {tCMP, "<=>"},
  4522. {'>', ">"},
  4523. {tGEQ, ">="},
  4524. {'<', "<"},
  4525. {tLEQ, "<="},
  4526. {tEQ, "=="},
  4527. {tEQQ, "==="},
  4528. {tNEQ, "!="},
  4529. {tMATCH, "=~"},
  4530. {tNMATCH, "!~"},
  4531. {'!', "!"},
  4532. {'~', "~"},
  4533. {'!', "!(unary)"},
  4534. {'~', "~(unary)"},
  4535. {'!', "!@"},
  4536. {'~', "~@"},
  4537. {tAREF, "[]"},
  4538. {tASET, "[]="},
  4539. {tLSHFT, "<<"},
  4540. {tRSHFT, ">>"},
  4541. {tCOLON2, "::"},
  4542. {'`', "`"},
  4543. {0, ""}
  4544. };
  4545. static ID convert_op(ID id) {
  4546. int i;
  4547. for(i = 0; op_tbl[i].token; i++) {
  4548. if(op_tbl[i].token == id) {
  4549. return rb_intern(op_tbl[i].name);
  4550. }
  4551. }
  4552. return id;
  4553. }
  4554. static NODE *
  4555. call_op(NODE *recv, ID id, int narg, NODE *arg1, rb_parse_state *parse_state)
  4556. {
  4557. value_expr(recv);
  4558. if (narg == 1) {
  4559. value_expr(arg1);
  4560. arg1 = NEW_LIST(arg1);
  4561. }
  4562. else {
  4563. arg1 = 0;
  4564. }
  4565. id = convert_op(id);
  4566. return NEW_CALL(recv, id, arg1);
  4567. }
  4568. static NODE*
  4569. match_gen(NODE *node1, NODE *node2, rb_parse_state *parse_state)
  4570. {
  4571. local_cnt('~');
  4572. value_expr(node1);
  4573. value_expr(node2);
  4574. if (node1) {
  4575. switch (nd_type(node1)) {
  4576. case NODE_DREGX:
  4577. case NODE_DREGX_ONCE:
  4578. return NEW_MATCH2(node1, node2);
  4579. case NODE_REGEX:
  4580. return NEW_MATCH2(node1, node2);
  4581. }
  4582. }
  4583. if (node2) {
  4584. switch (nd_type(node2)) {
  4585. case NODE_DREGX:
  4586. case NODE_DREGX_ONCE:
  4587. return NEW_MATCH3(node2, node1);
  4588. case NODE_REGEX:
  4589. return NEW_MATCH3(node2, node1);
  4590. }
  4591. }
  4592. return NEW_CALL(node1, convert_op(tMATCH), NEW_LIST(node2));
  4593. }
  4594. static NODE*
  4595. syd_gettable(rb_parse_state *parse_state, ID id)
  4596. {
  4597. if (id == kSELF) {
  4598. return NEW_SELF();
  4599. }
  4600. else if (id == kNIL) {
  4601. return NEW_NIL();
  4602. }
  4603. else if (id == kTRUE) {
  4604. return NEW_TRUE();
  4605. }
  4606. else if (id == kFALSE) {
  4607. return NEW_FALSE();
  4608. }
  4609. else if (id == k__FILE__) {
  4610. return NEW_FILE();
  4611. }
  4612. else if (id == k__LINE__) {
  4613. return NEW_FIXNUM(ruby_sourceline);
  4614. }
  4615. else if (is_local_id(id)) {
  4616. if (local_id(id)) return NEW_LVAR(id);
  4617. /* method call without arguments */
  4618. return NEW_VCALL(id);
  4619. }
  4620. else if (is_global_id(id)) {
  4621. return NEW_GVAR(id);
  4622. }
  4623. else if (is_instance_id(id)) {
  4624. return NEW_IVAR(id);
  4625. }
  4626. else if (is_const_id(id)) {
  4627. return NEW_CONST(id);
  4628. }
  4629. else if (is_class_id(id)) {
  4630. return NEW_CVAR(id);
  4631. }
  4632. /* FIXME: indicate which identifier. */
  4633. rb_compile_error(parse_state, "identifier is not valid 1\n");
  4634. return 0;
  4635. }
  4636. static void
  4637. reset_block(rb_parse_state *parse_state) {
  4638. if(!parse_state->variables->block_vars) {
  4639. parse_state->variables->block_vars = var_table_create();
  4640. } else {
  4641. parse_state->variables->block_vars = var_table_push(parse_state->variables->block_vars);
  4642. }
  4643. }
  4644. static NODE *
  4645. extract_block_vars(rb_parse_state *parse_state, NODE* node, var_table vars)
  4646. {
  4647. int i;
  4648. NODE *var, *out = node;
  4649. // we don't create any DASGN_CURR nodes
  4650. goto out;
  4651. if (!node) goto out;
  4652. if(var_table_size(vars) == 0) goto out;
  4653. var = NULL;
  4654. for(i = 0; i < var_table_size(vars); i++) {
  4655. var = NEW_DASGN_CURR(var_table_get(vars, i), var);
  4656. }
  4657. out = block_append(parse_state, var, node);
  4658. out:
  4659. assert(vars == parse_state->variables->block_vars);
  4660. parse_state->variables->block_vars = var_table_pop(parse_state->variables->block_vars);
  4661. return out;
  4662. }
  4663. static NODE*
  4664. assignable(ID id, NODE *val, rb_parse_state *parse_state)
  4665. {
  4666. value_expr(val);
  4667. if (id == kSELF) {
  4668. yyerror("Can't change the value of self");
  4669. }
  4670. else if (id == kNIL) {
  4671. yyerror("Can't assign to nil");
  4672. }
  4673. else if (id == kTRUE) {
  4674. yyerror("Can't assign to true");
  4675. }
  4676. else if (id == kFALSE) {
  4677. yyerror("Can't assign to false");
  4678. }
  4679. else if (id == k__FILE__) {
  4680. yyerror("Can't assign to __FILE__");
  4681. }
  4682. else if (id == k__LINE__) {
  4683. yyerror("Can't assign to __LINE__");
  4684. }
  4685. else if (is_local_id(id)) {
  4686. if(parse_state->variables->block_vars) {
  4687. var_table_add(parse_state->variables->block_vars, id);
  4688. }
  4689. return NEW_LASGN(id, val);
  4690. }
  4691. else if (is_global_id(id)) {
  4692. return NEW_GASGN(id, val);
  4693. }
  4694. else if (is_instance_id(id)) {
  4695. return NEW_IASGN(id, val);
  4696. }
  4697. else if (is_const_id(id)) {
  4698. if (in_def || in_single)
  4699. yyerror("dynamic constant assignment");
  4700. return NEW_CDECL(id, val, 0);
  4701. }
  4702. else if (is_class_id(id)) {
  4703. if (in_def || in_single) return NEW_CVASGN(id, val);
  4704. return NEW_CVDECL(id, val);
  4705. }
  4706. else {
  4707. /* FIXME: indicate which identifier. */
  4708. rb_compile_error(parse_state, "identifier is not valid 2 (%d)\n", id);
  4709. }
  4710. return 0;
  4711. }
  4712. static NODE *
  4713. aryset(NODE *recv, NODE *idx, rb_parse_state *parse_state)
  4714. {
  4715. if (recv && nd_type(recv) == NODE_SELF)
  4716. recv = (NODE *)1;
  4717. else
  4718. value_expr(recv);
  4719. return NEW_ATTRASGN(recv, convert_op(tASET), idx);
  4720. }
  4721. static ID
  4722. rb_id_attrset(ID id)
  4723. {
  4724. id &= ~ID_SCOPE_MASK;
  4725. id |= ID_ATTRSET;
  4726. return id;
  4727. }
  4728. static NODE *
  4729. attrset(NODE *recv, ID id, rb_parse_state *parse_state)
  4730. {
  4731. if (recv && nd_type(recv) == NODE_SELF)
  4732. recv = (NODE *)1;
  4733. else
  4734. value_expr(recv);
  4735. return NEW_ATTRASGN(recv, rb_id_attrset(id), 0);
  4736. }
  4737. static void
  4738. rb_backref_error(NODE *node, rb_parse_state *parse_state)
  4739. {
  4740. switch (nd_type(node)) {
  4741. case NODE_NTH_REF:
  4742. rb_compile_error(parse_state, "Can't set variable $%u", node->nd_nth);
  4743. break;
  4744. case NODE_BACK_REF:
  4745. rb_compile_error(parse_state, "Can't set variable $%c", (int)node->nd_nth);
  4746. break;
  4747. }
  4748. }
  4749. static NODE *
  4750. arg_concat(rb_parse_state *parse_state, NODE *node1, NODE *node2)
  4751. {
  4752. if (!node2) return node1;
  4753. return NEW_ARGSCAT(node1, node2);
  4754. }
  4755. static NODE *
  4756. arg_add(rb_parse_state *parse_state, NODE *node1, NODE *node2)
  4757. {
  4758. if (!node1) return NEW_LIST(node2);
  4759. if (nd_type(node1) == NODE_ARRAY) {
  4760. return list_append(parse_state, node1, node2);
  4761. }
  4762. else {
  4763. return NEW_ARGSPUSH(node1, node2);
  4764. }
  4765. }
  4766. static NODE*
  4767. node_assign(NODE *lhs, NODE *rhs, rb_parse_state *parse_state)
  4768. {
  4769. if (!lhs) return 0;
  4770. value_expr(rhs);
  4771. switch (nd_type(lhs)) {
  4772. case NODE_GASGN:
  4773. case NODE_IASGN:
  4774. case NODE_LASGN:
  4775. case NODE_DASGN:
  4776. case NODE_DASGN_CURR:
  4777. case NODE_MASGN:
  4778. case NODE_CDECL:
  4779. case NODE_CVDECL:
  4780. case NODE_CVASGN:
  4781. lhs->nd_value = rhs;
  4782. break;
  4783. case NODE_ATTRASGN:
  4784. case NODE_CALL:
  4785. lhs->nd_args = arg_add(parse_state, lhs->nd_args, rhs);
  4786. break;
  4787. default:
  4788. /* should not happen */
  4789. break;
  4790. }
  4791. return lhs;
  4792. }
  4793. static int
  4794. value_expr0(NODE *node, rb_parse_state *parse_state)
  4795. {
  4796. int cond = 0;
  4797. while (node) {
  4798. switch (nd_type(node)) {
  4799. case NODE_DEFN:
  4800. case NODE_DEFS:
  4801. parser_warning(parse_state, node, "void value expression");
  4802. return FALSE;
  4803. case NODE_RETURN:
  4804. case NODE_BREAK:
  4805. case NODE_NEXT:
  4806. case NODE_REDO:
  4807. case NODE_RETRY:
  4808. if (!cond) yyerror("void value expression");
  4809. /* or "control never reach"? */
  4810. return FALSE;
  4811. case NODE_BLOCK:
  4812. while (node->nd_next) {
  4813. node = node->nd_next;
  4814. }
  4815. node = node->nd_head;
  4816. break;
  4817. case NODE_BEGIN:
  4818. node = node->nd_body;
  4819. break;
  4820. case NODE_IF:
  4821. if (!value_expr(node->nd_body)) return FALSE;
  4822. node = node->nd_else;
  4823. break;
  4824. case NODE_AND:
  4825. case NODE_OR:
  4826. cond = 1;
  4827. node = node->nd_2nd;
  4828. break;
  4829. case NODE_NEWLINE:
  4830. node = node->nd_next;
  4831. break;
  4832. default:
  4833. return TRUE;
  4834. }
  4835. }
  4836. return TRUE;
  4837. }
  4838. static void
  4839. void_expr0(NODE *node)
  4840. {
  4841. const char *useless = NULL;
  4842. if (!RTEST(ruby_verbose)) return;
  4843. again:
  4844. if (!node) return;
  4845. switch (nd_type(node)) {
  4846. case NODE_NEWLINE:
  4847. node = node->nd_next;
  4848. goto again;
  4849. case NODE_CALL:
  4850. switch (node->nd_mid) {
  4851. case '+':
  4852. case '-':
  4853. case '*':
  4854. case '/':
  4855. case '%':
  4856. case tPOW:
  4857. case tUPLUS:
  4858. case tUMINUS:
  4859. case '|':
  4860. case '^':
  4861. case '&':
  4862. case tCMP:
  4863. case '>':
  4864. case tGEQ:
  4865. case '<':
  4866. case tLEQ:
  4867. case tEQ:
  4868. case tNEQ:
  4869. useless = "";
  4870. break;
  4871. }
  4872. break;
  4873. case NODE_LVAR:
  4874. case NODE_DVAR:
  4875. case NODE_GVAR:
  4876. case NODE_IVAR:
  4877. case NODE_CVAR:
  4878. case NODE_NTH_REF:
  4879. case NODE_BACK_REF:
  4880. useless = "a variable";
  4881. break;
  4882. case NODE_CONST:
  4883. case NODE_CREF:
  4884. useless = "a constant";
  4885. break;
  4886. case NODE_LIT:
  4887. case NODE_STR:
  4888. case NODE_DSTR:
  4889. case NODE_DREGX:
  4890. case NODE_DREGX_ONCE:
  4891. useless = "a literal";
  4892. break;
  4893. case NODE_COLON2:
  4894. case NODE_COLON3:
  4895. useless = "::";
  4896. break;
  4897. case NODE_DOT2:
  4898. useless = "..";
  4899. break;
  4900. case NODE_DOT3:
  4901. useless = "...";
  4902. break;
  4903. case NODE_SELF:
  4904. useless = "self";
  4905. break;
  4906. case NODE_NIL:
  4907. useless = "nil";
  4908. break;
  4909. case NODE_TRUE:
  4910. useless = "true";
  4911. break;
  4912. case NODE_FALSE:
  4913. useless = "false";
  4914. break;
  4915. case NODE_DEFINED:
  4916. useless = "defined?";
  4917. break;
  4918. }
  4919. if (useless) {
  4920. int line = ruby_sourceline;
  4921. ruby_sourceline = nd_line(node);
  4922. rb_warn("useless use of %s in void context", useless);
  4923. ruby_sourceline = line;
  4924. }
  4925. }
  4926. static void
  4927. void_stmts(NODE *node, rb_parse_state *parse_state)
  4928. {
  4929. if (!RTEST(ruby_verbose)) return;
  4930. if (!node) return;
  4931. if (nd_type(node) != NODE_BLOCK) return;
  4932. for (;;) {
  4933. if (!node->nd_next) return;
  4934. void_expr(node->nd_head);
  4935. node = node->nd_next;
  4936. }
  4937. }
  4938. static NODE *
  4939. remove_begin(NODE *node, rb_parse_state *parse_state)
  4940. {
  4941. NODE **n = &node;
  4942. while (*n) {
  4943. switch (nd_type(*n)) {
  4944. case NODE_NEWLINE:
  4945. n = &(*n)->nd_next;
  4946. continue;
  4947. case NODE_BEGIN:
  4948. *n = (*n)->nd_body;
  4949. default:
  4950. return node;
  4951. }
  4952. }
  4953. return node;
  4954. }
  4955. static int
  4956. assign_in_cond(NODE *node, rb_parse_state *parse_state)
  4957. {
  4958. switch (nd_type(node)) {
  4959. case NODE_MASGN:
  4960. yyerror("multiple assignment in conditional");
  4961. return 1;
  4962. case NODE_LASGN:
  4963. case NODE_DASGN:
  4964. case NODE_GASGN:
  4965. case NODE_IASGN:
  4966. break;
  4967. case NODE_NEWLINE:
  4968. default:
  4969. return 0;
  4970. }
  4971. switch (nd_type(node->nd_value)) {
  4972. case NODE_LIT:
  4973. case NODE_STR:
  4974. case NODE_NIL:
  4975. case NODE_TRUE:
  4976. case NODE_FALSE:
  4977. return 1;
  4978. case NODE_DSTR:
  4979. case NODE_XSTR:
  4980. case NODE_DXSTR:
  4981. case NODE_EVSTR:
  4982. case NODE_DREGX:
  4983. default:
  4984. break;
  4985. }
  4986. return 1;
  4987. }
  4988. static int
  4989. e_option_supplied()
  4990. {
  4991. if (strcmp(ruby_sourcefile, "-e") == 0)
  4992. return TRUE;
  4993. return FALSE;
  4994. }
  4995. static void
  4996. warn_unless_e_option(rb_parse_state *ps, NODE *node, const char *str)
  4997. {
  4998. if (!e_option_supplied()) parser_warning(ps, node, str);
  4999. }
  5000. static NODE *cond0(NODE *node, rb_parse_state *parse_state);
  5001. static NODE*
  5002. range_op(NODE *node, rb_parse_state *parse_state)
  5003. {
  5004. enum node_type type;
  5005. if (!e_option_supplied()) return node;
  5006. if (node == 0) return 0;
  5007. value_expr(node);
  5008. node = cond0(node, parse_state);
  5009. type = (enum node_type)nd_type(node);
  5010. if (type == NODE_NEWLINE) {
  5011. node = node->nd_next;
  5012. type = (enum node_type)nd_type(node);
  5013. }
  5014. if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
  5015. warn_unless_e_option(parse_state, node, "integer literal in conditional range");
  5016. return call_op(node,tEQ,1,NEW_GVAR(rb_intern("$.")), parse_state);
  5017. }
  5018. return node;
  5019. }
  5020. static int
  5021. literal_node(NODE *node)
  5022. {
  5023. if (!node) return 1; /* same as NODE_NIL */
  5024. switch (nd_type(node)) {
  5025. case NODE_LIT:
  5026. case NODE_STR:
  5027. case NODE_DSTR:
  5028. case NODE_EVSTR:
  5029. case NODE_DREGX:
  5030. case NODE_DREGX_ONCE:
  5031. case NODE_DSYM:
  5032. return 2;
  5033. case NODE_TRUE:
  5034. case NODE_FALSE:
  5035. case NODE_NIL:
  5036. return 1;
  5037. }
  5038. return 0;
  5039. }
  5040. static NODE*
  5041. cond0(NODE *node, rb_parse_state *parse_state)
  5042. {
  5043. if (node == 0) return 0;
  5044. assign_in_cond(node, parse_state);
  5045. switch (nd_type(node)) {
  5046. case NODE_DSTR:
  5047. case NODE_EVSTR:
  5048. case NODE_STR:
  5049. break;
  5050. case NODE_DREGX:
  5051. case NODE_DREGX_ONCE:
  5052. local_cnt('_');
  5053. local_cnt('~');
  5054. return NEW_MATCH2(node, NEW_GVAR(rb_intern("$_")));
  5055. case NODE_AND:
  5056. case NODE_OR:
  5057. node->nd_1st = cond0(node->nd_1st, parse_state);
  5058. node->nd_2nd = cond0(node->nd_2nd, parse_state);
  5059. break;
  5060. case NODE_DOT2:
  5061. case NODE_DOT3:
  5062. node->nd_beg = range_op(node->nd_beg, parse_state);
  5063. node->nd_end = range_op(node->nd_end, parse_state);
  5064. if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
  5065. else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
  5066. if (!e_option_supplied()) {
  5067. int b = literal_node(node->nd_beg);
  5068. int e = literal_node(node->nd_end);
  5069. if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {
  5070. }
  5071. }
  5072. break;
  5073. case NODE_DSYM:
  5074. break;
  5075. case NODE_REGEX:
  5076. nd_set_type(node, NODE_MATCH);
  5077. local_cnt('_');
  5078. local_cnt('~');
  5079. default:
  5080. break;
  5081. }
  5082. return node;
  5083. }
  5084. static NODE*
  5085. cond(NODE *node, rb_parse_state *parse_state)
  5086. {
  5087. if (node == 0) return 0;
  5088. value_expr(node);
  5089. if (nd_type(node) == NODE_NEWLINE){
  5090. node->nd_next = cond0(node->nd_next, parse_state);
  5091. return node;
  5092. }
  5093. return cond0(node, parse_state);
  5094. }
  5095. static NODE*
  5096. logop(enum node_type type, NODE *left, NODE *right, rb_parse_state *parse_state)
  5097. {
  5098. value_expr(left);
  5099. if (left && nd_type(left) == type) {
  5100. NODE *node = left, *second;
  5101. while ((second = node->nd_2nd) != 0 && nd_type(second) == type) {
  5102. node = second;
  5103. }
  5104. node->nd_2nd = NEW_NODE(type, second, right, 0);
  5105. return left;
  5106. }
  5107. return NEW_NODE(type, left, right, 0);
  5108. }
  5109. static int
  5110. cond_negative(NODE **nodep)
  5111. {
  5112. NODE *c = *nodep;
  5113. if (!c) return 0;
  5114. switch (nd_type(c)) {
  5115. case NODE_NOT:
  5116. *nodep = c->nd_body;
  5117. return 1;
  5118. case NODE_NEWLINE:
  5119. if (c->nd_next && nd_type(c->nd_next) == NODE_NOT) {
  5120. c->nd_next = c->nd_next->nd_body;
  5121. return 1;
  5122. }
  5123. }
  5124. return 0;
  5125. }
  5126. static void
  5127. no_blockarg(rb_parse_state *parse_state, NODE *node)
  5128. {
  5129. if (node && nd_type(node) == NODE_BLOCK_PASS) {
  5130. rb_compile_error(parse_state, "block argument should not be given");
  5131. }
  5132. }
  5133. static NODE *
  5134. ret_args(rb_parse_state *parse_state, NODE *node)
  5135. {
  5136. if (node) {
  5137. no_blockarg(parse_state, node);
  5138. if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {
  5139. node = node->nd_head;
  5140. }
  5141. if (node && nd_type(node) == NODE_SPLAT) {
  5142. node = NEW_SVALUE(node);
  5143. }
  5144. }
  5145. return node;
  5146. }
  5147. static NODE *
  5148. new_yield(rb_parse_state *parse_state, NODE *node)
  5149. {
  5150. Object* state = Qtrue;
  5151. if (node) {
  5152. no_blockarg(parse_state, node);
  5153. if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {
  5154. node = node->nd_head;
  5155. state = Qfalse;
  5156. }
  5157. if (node && nd_type(node) == NODE_SPLAT) {
  5158. state = Qtrue;
  5159. }
  5160. }
  5161. else {
  5162. state = Qfalse;
  5163. }
  5164. return NEW_YIELD(node, state);
  5165. }
  5166. static NODE *
  5167. arg_blk_pass(NODE *node1, NODE *node2)
  5168. {
  5169. if (node2) {
  5170. node2->nd_head = node1;
  5171. return node2;
  5172. }
  5173. return node1;
  5174. }
  5175. static NODE*
  5176. arg_prepend(rb_parse_state *parse_state, NODE *node1, NODE *node2)
  5177. {
  5178. switch (nd_type(node2)) {
  5179. case NODE_ARRAY:
  5180. return list_concat(NEW_LIST(node1), node2);
  5181. case NODE_SPLAT:
  5182. return arg_concat(parse_state, node1, node2->nd_head);
  5183. case NODE_BLOCK_PASS:
  5184. node2->nd_body = arg_prepend(parse_state, node1, node2->nd_body);
  5185. return node2;
  5186. default:
  5187. printf("unknown nodetype(%d) for arg_prepend", nd_type(node2));
  5188. abort();
  5189. }
  5190. return 0; /* not reached */
  5191. }
  5192. static NODE*
  5193. new_call(rb_parse_state *parse_state,NODE *r,ID m,NODE *a)
  5194. {
  5195. if (a && nd_type(a) == NODE_BLOCK_PASS) {
  5196. a->nd_iter = NEW_CALL(r,convert_op(m),a->nd_head);
  5197. return a;
  5198. }
  5199. return NEW_CALL(r,convert_op(m),a);
  5200. }
  5201. static NODE*
  5202. new_fcall(rb_parse_state *parse_state,ID m,NODE *a)
  5203. {
  5204. if (a && nd_type(a) == NODE_BLOCK_PASS) {
  5205. a->nd_iter = NEW_FCALL(m,a->nd_head);
  5206. return a;
  5207. }
  5208. return NEW_FCALL(m,a);
  5209. }
  5210. static NODE*
  5211. new_super(rb_parse_state *parse_state,NODE *a)
  5212. {
  5213. if (a && nd_type(a) == NODE_BLOCK_PASS) {
  5214. a->nd_iter = NEW_SUPER(a->nd_head);
  5215. return a;
  5216. }
  5217. return NEW_SUPER(a);
  5218. }
  5219. static void
  5220. syd_local_push(rb_parse_state *st, int top)
  5221. {
  5222. st->variables = LocalState::push(st->variables);
  5223. }
  5224. static void
  5225. syd_local_pop(rb_parse_state *st)
  5226. {
  5227. st->variables = LocalState::pop(st->variables);
  5228. }
  5229. static ID*
  5230. syd_local_tbl(rb_parse_state *st)
  5231. {
  5232. ID *lcl_tbl;
  5233. var_table tbl;
  5234. int i, len;
  5235. tbl = st->variables->variables;
  5236. len = var_table_size(tbl);
  5237. lcl_tbl = (ID*)pt_allocate(st, sizeof(ID) * (len + 3));
  5238. lcl_tbl[0] = (ID)len;
  5239. lcl_tbl[1] = '_';
  5240. lcl_tbl[2] = '~';
  5241. for(i = 0; i < len; i++) {
  5242. lcl_tbl[i + 3] = var_table_get(tbl, i);
  5243. }
  5244. return lcl_tbl;
  5245. }
  5246. static intptr_t
  5247. syd_local_cnt(rb_parse_state *st, ID id)
  5248. {
  5249. int idx;
  5250. /* Leave these hardcoded here because they arne't REALLY ids at all. */
  5251. if(id == '_') {
  5252. return 0;
  5253. } else if(id == '~') {
  5254. return 1;
  5255. }
  5256. // if there are block variables, check to see if there is already
  5257. // a local by this name. If not, create one in the top block_vars
  5258. // table.
  5259. if(st->variables->block_vars) {
  5260. idx = var_table_find_chained(st->variables->block_vars, id);
  5261. if(idx >= 0) {
  5262. return idx;
  5263. } else {
  5264. return var_table_add(st->variables->block_vars, id);
  5265. }
  5266. }
  5267. idx = var_table_find(st->variables->variables, id);
  5268. if(idx >= 0) {
  5269. return idx + 2;
  5270. }
  5271. return var_table_add(st->variables->variables, id);
  5272. }
  5273. static int
  5274. syd_local_id(rb_parse_state *st, ID id)
  5275. {
  5276. if(st->variables->block_vars) {
  5277. if(var_table_find_chained(st->variables->block_vars, id) >= 0) return 1;
  5278. }
  5279. if(var_table_find(st->variables->variables, id) >= 0) return 1;
  5280. return 0;
  5281. }
  5282. static ID
  5283. rb_intern(const char *name)
  5284. {
  5285. const char *m = name;
  5286. ID id, pre, qrk, bef;
  5287. int last;
  5288. id = 0;
  5289. last = strlen(name)-1;
  5290. switch (*name) {
  5291. case '$':
  5292. id |= ID_GLOBAL;
  5293. m++;
  5294. if (!is_identchar(*m)) m++;
  5295. break;
  5296. case '@':
  5297. if (name[1] == '@') {
  5298. m++;
  5299. id |= ID_CLASS;
  5300. }
  5301. else {
  5302. id |= ID_INSTANCE;
  5303. }
  5304. m++;
  5305. break;
  5306. default:
  5307. if (name[0] != '_' && !ISALPHA(name[0]) && !ismbchar(name[0])) {
  5308. int i;
  5309. for (i=0; op_tbl[i].token; i++) {
  5310. if (*op_tbl[i].name == *name &&
  5311. strcmp(op_tbl[i].name, name) == 0) {
  5312. id = op_tbl[i].token;
  5313. return id;
  5314. }
  5315. }
  5316. }
  5317. if (name[last] == '=') {
  5318. id = ID_ATTRSET;
  5319. }
  5320. else if (ISUPPER(name[0])) {
  5321. id = ID_CONST;
  5322. }
  5323. else {
  5324. id = ID_LOCAL;
  5325. }
  5326. break;
  5327. }
  5328. while (m <= name + last && is_identchar(*m)) {
  5329. m += mbclen(*m);
  5330. }
  5331. if (*m) id = ID_JUNK;
  5332. qrk = (ID)quark_from_string(name);
  5333. pre = qrk + tLAST_TOKEN;
  5334. bef = id;
  5335. id |= ( pre << ID_SCOPE_SHIFT );
  5336. return id;
  5337. }
  5338. static unsigned long
  5339. scan_oct(const char *start, int len, int *retlen)
  5340. {
  5341. register const char *s = start;
  5342. register unsigned long retval = 0;
  5343. while (len-- && *s >= '0' && *s <= '7') {
  5344. retval <<= 3;
  5345. retval |= *s++ - '0';
  5346. }
  5347. *retlen = s - start;
  5348. return retval;
  5349. }
  5350. static unsigned long
  5351. scan_hex(const char *start, int len, int *retlen)
  5352. {
  5353. static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
  5354. register const char *s = start;
  5355. register unsigned long retval = 0;
  5356. const char *tmp;
  5357. while (len-- && *s && (tmp = strchr(hexdigit, *s))) {
  5358. retval <<= 4;
  5359. retval |= (tmp - hexdigit) & 15;
  5360. s++;
  5361. }
  5362. *retlen = s - start;
  5363. return retval;
  5364. }
  5365. const char *op_to_name(ID id) {
  5366. if(id < tLAST_TOKEN) {
  5367. int i = 0;
  5368. for (i=0; op_tbl[i].token; i++) {
  5369. if (op_tbl[i].token == id)
  5370. return op_tbl[i].name;
  5371. }
  5372. }
  5373. return NULL;
  5374. }
  5375. quark id_to_quark(ID id) {
  5376. quark qrk;
  5377. qrk = (quark)((id >> ID_SCOPE_SHIFT) - tLAST_TOKEN);
  5378. return qrk;
  5379. }
  5380. }; // namespace parser
  5381. }; // namespace rubinius