PageRenderTime 64ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/perl/perly.y

https://review.tizen.org/git/
Happy | 1376 lines | 1300 code | 76 blank | 0 comment | 0 complexity | 6b98f507bc79b1b0a487011281754f41 MD5 | raw file
Possible License(s): GPL-3.0, AGPL-3.0, GPL-2.0, MPL-2.0, JSON, WTFPL, CC-BY-SA-4.0, CC-BY-3.0, BSD-3-Clause, LGPL-2.0, MPL-2.0-no-copyleft-exception, AGPL-1.0, 0BSD, Zlib, Unlicense, BSD-2-Clause, Apache-2.0, LGPL-3.0, ISC, MIT, CC-BY-SA-3.0, CC0-1.0, LGPL-2.1
  1. /* perly.y
  2. *
  3. * Copyright (c) 1991-2002, 2003, 2004, 2005, 2006 Larry Wall
  4. * Copyright (c) 2007, 2008 by Larry Wall and others
  5. *
  6. * You may distribute under the terms of either the GNU General Public
  7. * License or the Artistic License, as specified in the README file.
  8. *
  9. */
  10. /*
  11. * 'I see,' laughed Strider. 'I look foul and feel fair. Is that it?
  12. * All that is gold does not glitter, not all those who wander are lost.'
  13. *
  14. * [p.171 of _The Lord of the Rings_, I/x: "Strider"]
  15. */
  16. /*
  17. * This file holds the grammar for the Perl language. If edited, you need
  18. * to run regen_perly.pl, which re-creates the files perly.h, perly.tab
  19. * and perly.act which are derived from this.
  20. *
  21. * Note that these derived files are included and compiled twice; once
  22. * from perly.c, and once from madly.c. The second time, a number of MAD
  23. * macros are defined, which compile in extra code that allows the parse
  24. * tree to be accurately dumped. In particular:
  25. *
  26. * MAD defined if compiling madly.c
  27. * DO_MAD(A) expands to A under madly.c, to null otherwise
  28. * IF_MAD(a,b) expands to A under madly.c, to B otherwise
  29. * TOKEN_GETMAD() expands to token_getmad() under madly.c, to null otherwise
  30. * TOKEN_FREE() similarly
  31. * OP_GETMAD() similarly
  32. * IVAL(i) expands to (i)->tk_lval.ival or (i)
  33. * PVAL(p) expands to (p)->tk_lval.pval or (p)
  34. *
  35. * The main job of of this grammar is to call the various newFOO()
  36. * functions in op.c to build a syntax tree of OP structs.
  37. * It relies on the lexer in toke.c to do the tokenizing.
  38. *
  39. * Note: due to the way that the cleanup code works WRT to freeing ops on
  40. * the parse stack, it is dangerous to assign to the $n variables within
  41. * an action.
  42. */
  43. /* Make the parser re-entrant. */
  44. %pure_parser
  45. /* FIXME for MAD - is the new mintro on while and until important? */
  46. %start grammar
  47. %union {
  48. I32 ival; /* __DEFAULT__ (marker for regen_perly.pl;
  49. must always be 1st union member) */
  50. char *pval;
  51. OP *opval;
  52. GV *gvval;
  53. #ifdef PERL_IN_MADLY_C
  54. TOKEN* p_tkval;
  55. TOKEN* i_tkval;
  56. #else
  57. char *p_tkval;
  58. I32 i_tkval;
  59. #endif
  60. #ifdef PERL_MAD
  61. TOKEN* tkval;
  62. #endif
  63. }
  64. %token <ival> GRAMPROG GRAMEXPR GRAMBLOCK GRAMBARESTMT GRAMFULLSTMT GRAMSTMTSEQ
  65. %token <i_tkval> '{' '}' '[' ']' '-' '+' '$' '@' '%' '*' '&' ';'
  66. %token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF QWLIST
  67. %token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
  68. %token <opval> PLUGEXPR PLUGSTMT
  69. %token <p_tkval> LABEL
  70. %token <i_tkval> FORMAT SUB ANONSUB PACKAGE USE
  71. %token <i_tkval> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
  72. %token <i_tkval> GIVEN WHEN DEFAULT
  73. %token <i_tkval> LOOPEX DOTDOT YADAYADA
  74. %token <i_tkval> FUNC0 FUNC1 FUNC UNIOP LSTOP
  75. %token <i_tkval> RELOP EQOP MULOP ADDOP
  76. %token <i_tkval> DOLSHARP DO HASHBRACK NOAMP
  77. %token <i_tkval> LOCAL MY MYSUB REQUIRE
  78. %token <i_tkval> COLONATTR
  79. %type <i_tkval> lpar_or_qw
  80. %type <ival> grammar remember mremember
  81. %type <ival> startsub startanonsub startformsub
  82. /* FIXME for MAD - are these two ival? */
  83. %type <ival> mydefsv mintro
  84. %type <opval> stmtseq fullstmt labfullstmt barestmt block mblock else
  85. %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
  86. %type <opval> listexpr nexpr texpr iexpr mexpr mnexpr miexpr
  87. %type <opval> optlistexpr optexpr indirob listop method
  88. %type <opval> formname subname proto subbody cont my_scalar
  89. %type <opval> subattrlist myattrlist myattrterm myterm
  90. %type <opval> termbinop termunop anonymous termdo
  91. %nonassoc <i_tkval> PREC_LOW
  92. %nonassoc LOOPEX
  93. %left <i_tkval> OROP DOROP
  94. %left <i_tkval> ANDOP
  95. %right <i_tkval> NOTOP
  96. %nonassoc LSTOP LSTOPSUB
  97. %left <i_tkval> ','
  98. %right <i_tkval> ASSIGNOP
  99. %right <i_tkval> '?' ':'
  100. %nonassoc DOTDOT YADAYADA
  101. %left <i_tkval> OROR DORDOR
  102. %left <i_tkval> ANDAND
  103. %left <i_tkval> BITOROP
  104. %left <i_tkval> BITANDOP
  105. %nonassoc EQOP
  106. %nonassoc RELOP
  107. %nonassoc UNIOP UNIOPSUB
  108. %nonassoc REQUIRE
  109. %left <i_tkval> SHIFTOP
  110. %left ADDOP
  111. %left MULOP
  112. %left <i_tkval> MATCHOP
  113. %right <i_tkval> '!' '~' UMINUS REFGEN
  114. %right <i_tkval> POWOP
  115. %nonassoc <i_tkval> PREINC PREDEC POSTINC POSTDEC
  116. %left <i_tkval> ARROW
  117. %nonassoc <i_tkval> ')'
  118. %left <i_tkval> '('
  119. %left '[' '{'
  120. %token <i_tkval> PEG
  121. %% /* RULES */
  122. /* Top-level choice of what kind of thing yyparse was called to parse */
  123. grammar : GRAMPROG
  124. {
  125. PL_parser->expect = XSTATE;
  126. }
  127. remember stmtseq
  128. {
  129. newPROG(block_end($3,$4));
  130. $$ = 0;
  131. }
  132. | GRAMEXPR
  133. {
  134. parser->expect = XTERM;
  135. }
  136. optexpr
  137. {
  138. PL_eval_root = $3;
  139. $$ = 0;
  140. }
  141. | GRAMBLOCK
  142. {
  143. parser->expect = XBLOCK;
  144. }
  145. block
  146. {
  147. PL_pad_reset_pending = TRUE;
  148. PL_eval_root = $3;
  149. $$ = 0;
  150. yyunlex();
  151. parser->yychar = YYEOF;
  152. }
  153. | GRAMBARESTMT
  154. {
  155. parser->expect = XSTATE;
  156. }
  157. barestmt
  158. {
  159. PL_pad_reset_pending = TRUE;
  160. PL_eval_root = $3;
  161. $$ = 0;
  162. yyunlex();
  163. parser->yychar = YYEOF;
  164. }
  165. | GRAMFULLSTMT
  166. {
  167. parser->expect = XSTATE;
  168. }
  169. fullstmt
  170. {
  171. PL_pad_reset_pending = TRUE;
  172. PL_eval_root = $3;
  173. $$ = 0;
  174. yyunlex();
  175. parser->yychar = YYEOF;
  176. }
  177. | GRAMSTMTSEQ
  178. {
  179. parser->expect = XSTATE;
  180. }
  181. stmtseq
  182. {
  183. PL_eval_root = $3;
  184. $$ = 0;
  185. }
  186. ;
  187. /* An ordinary block */
  188. block : '{' remember stmtseq '}'
  189. { if (PL_parser->copline > (line_t)IVAL($1))
  190. PL_parser->copline = (line_t)IVAL($1);
  191. $$ = block_end($2, $3);
  192. TOKEN_GETMAD($1,$$,'{');
  193. TOKEN_GETMAD($4,$$,'}');
  194. }
  195. ;
  196. remember: /* NULL */ /* start a full lexical scope */
  197. { $$ = block_start(TRUE); }
  198. ;
  199. mydefsv: /* NULL */ /* lexicalize $_ */
  200. { $$ = (I32) Perl_allocmy(aTHX_ STR_WITH_LEN("$_"), 0); }
  201. ;
  202. mblock : '{' mremember stmtseq '}'
  203. { if (PL_parser->copline > (line_t)IVAL($1))
  204. PL_parser->copline = (line_t)IVAL($1);
  205. $$ = block_end($2, $3);
  206. TOKEN_GETMAD($1,$$,'{');
  207. TOKEN_GETMAD($4,$$,'}');
  208. }
  209. ;
  210. mremember: /* NULL */ /* start a partial lexical scope */
  211. { $$ = block_start(FALSE); }
  212. ;
  213. /* A sequence of statements in the program */
  214. stmtseq : /* NULL */
  215. { $$ = (OP*)NULL; }
  216. | stmtseq fullstmt
  217. { $$ = op_append_list(OP_LINESEQ, $1, $2);
  218. PL_pad_reset_pending = TRUE;
  219. if ($1 && $2)
  220. PL_hints |= HINT_BLOCK_SCOPE;
  221. }
  222. ;
  223. /* A statement in the program, including optional labels */
  224. fullstmt: barestmt
  225. {
  226. if($1) {
  227. $$ = newSTATEOP(0, NULL, $1);
  228. } else {
  229. $$ = IF_MAD(newOP(OP_NULL, 0), NULL);
  230. }
  231. }
  232. | labfullstmt
  233. { $$ = $1; }
  234. ;
  235. labfullstmt: LABEL barestmt
  236. {
  237. $$ = newSTATEOP(0, PVAL($1), $2);
  238. TOKEN_GETMAD($1,
  239. $2 ? cLISTOPx($$)->op_first : $$, 'L');
  240. }
  241. | LABEL labfullstmt
  242. {
  243. $$ = newSTATEOP(0, PVAL($1), $2);
  244. TOKEN_GETMAD($1, cLISTOPx($$)->op_first, 'L');
  245. }
  246. ;
  247. /* A bare statement, lacking label and other aspects of state op */
  248. barestmt: PLUGSTMT
  249. { $$ = $1; }
  250. | PEG
  251. {
  252. $$ = newOP(OP_NULL,0);
  253. TOKEN_GETMAD($1,$$,'p');
  254. }
  255. | FORMAT startformsub formname block
  256. {
  257. CV *fmtcv = PL_compcv;
  258. SvREFCNT_inc_simple_void(PL_compcv);
  259. #ifdef MAD
  260. $$ = newFORM($2, $3, $4);
  261. prepend_madprops($1->tk_mad, $$, 'F');
  262. $1->tk_mad = 0;
  263. token_free($1);
  264. #else
  265. newFORM($2, $3, $4);
  266. $$ = (OP*)NULL;
  267. #endif
  268. if (CvOUTSIDE(fmtcv) && !CvUNIQUE(CvOUTSIDE(fmtcv))) {
  269. SvREFCNT_inc_simple_void(fmtcv);
  270. pad_add_anon((SV*)fmtcv, OP_NULL);
  271. }
  272. }
  273. | SUB startsub subname proto subattrlist subbody
  274. {
  275. SvREFCNT_inc_simple_void(PL_compcv);
  276. #ifdef MAD
  277. {
  278. OP* o = newSVOP(OP_ANONCODE, 0,
  279. (SV*)newATTRSUB($2, $3, $4, $5, $6));
  280. $$ = newOP(OP_NULL,0);
  281. op_getmad(o,$$,'&');
  282. op_getmad($3,$$,'n');
  283. op_getmad($4,$$,'s');
  284. op_getmad($5,$$,'a');
  285. token_getmad($1,$$,'d');
  286. append_madprops($6->op_madprop, $$, 0);
  287. $6->op_madprop = 0;
  288. }
  289. #else
  290. newATTRSUB($2, $3, $4, $5, $6);
  291. $$ = (OP*)NULL;
  292. #endif
  293. }
  294. | MYSUB startsub subname proto subattrlist subbody
  295. {
  296. /* Unimplemented "my sub foo { }" */
  297. SvREFCNT_inc_simple_void(PL_compcv);
  298. #ifdef MAD
  299. $$ = newMYSUB($2, $3, $4, $5, $6);
  300. token_getmad($1,$$,'d');
  301. #else
  302. newMYSUB($2, $3, $4, $5, $6);
  303. $$ = (OP*)NULL;
  304. #endif
  305. }
  306. | PACKAGE WORD WORD ';'
  307. {
  308. #ifdef MAD
  309. $$ = package($3);
  310. token_getmad($1,$$,'o');
  311. if ($2)
  312. package_version($2);
  313. token_getmad($4,$$,';');
  314. #else
  315. package($3);
  316. if ($2)
  317. package_version($2);
  318. $$ = (OP*)NULL;
  319. #endif
  320. }
  321. | USE startsub
  322. { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
  323. WORD WORD optlistexpr ';'
  324. {
  325. SvREFCNT_inc_simple_void(PL_compcv);
  326. #ifdef MAD
  327. $$ = utilize(IVAL($1), $2, $4, $5, $6);
  328. token_getmad($1,$$,'o');
  329. token_getmad($7,$$,';');
  330. if (PL_parser->rsfp_filters &&
  331. AvFILLp(PL_parser->rsfp_filters) >= 0)
  332. append_madprops(newMADPROP('!', MAD_NULL, NULL, 0), $$, 0);
  333. #else
  334. utilize(IVAL($1), $2, $4, $5, $6);
  335. $$ = (OP*)NULL;
  336. #endif
  337. }
  338. | IF lpar_or_qw remember mexpr ')' mblock else
  339. {
  340. $$ = block_end($3,
  341. newCONDOP(0, $4, op_scope($6), $7));
  342. TOKEN_GETMAD($1,$$,'I');
  343. TOKEN_GETMAD($2,$$,'(');
  344. TOKEN_GETMAD($5,$$,')');
  345. PL_parser->copline = (line_t)IVAL($1);
  346. }
  347. | UNLESS lpar_or_qw remember miexpr ')' mblock else
  348. {
  349. $$ = block_end($3,
  350. newCONDOP(0, $4, op_scope($6), $7));
  351. TOKEN_GETMAD($1,$$,'I');
  352. TOKEN_GETMAD($2,$$,'(');
  353. TOKEN_GETMAD($5,$$,')');
  354. PL_parser->copline = (line_t)IVAL($1);
  355. }
  356. | GIVEN lpar_or_qw remember mydefsv mexpr ')' mblock
  357. {
  358. $$ = block_end($3,
  359. newGIVENOP($5, op_scope($7), (PADOFFSET)$4));
  360. PL_parser->copline = (line_t)IVAL($1);
  361. }
  362. | WHEN lpar_or_qw remember mexpr ')' mblock
  363. { $$ = block_end($3, newWHENOP($4, op_scope($6))); }
  364. | DEFAULT block
  365. { $$ = newWHENOP(0, op_scope($2)); }
  366. | WHILE lpar_or_qw remember texpr ')' mintro mblock cont
  367. {
  368. $$ = block_end($3,
  369. newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
  370. $4, $7, $8, $6));
  371. TOKEN_GETMAD($1,$$,'W');
  372. TOKEN_GETMAD($2,$$,'(');
  373. TOKEN_GETMAD($5,$$,')');
  374. PL_parser->copline = (line_t)IVAL($1);
  375. }
  376. | UNTIL lpar_or_qw remember iexpr ')' mintro mblock cont
  377. {
  378. $$ = block_end($3,
  379. newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
  380. $4, $7, $8, $6));
  381. TOKEN_GETMAD($1,$$,'W');
  382. TOKEN_GETMAD($2,$$,'(');
  383. TOKEN_GETMAD($5,$$,')');
  384. PL_parser->copline = (line_t)IVAL($1);
  385. }
  386. | FOR lpar_or_qw remember mnexpr ';' texpr ';' mintro mnexpr ')'
  387. mblock
  388. {
  389. OP *initop = IF_MAD($4 ? $4 : newOP(OP_NULL, 0), $4);
  390. OP *forop = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
  391. scalar($6), $11, $9, $8);
  392. if (initop) {
  393. forop = op_prepend_elem(OP_LINESEQ, initop,
  394. op_append_elem(OP_LINESEQ,
  395. newOP(OP_UNSTACK, OPf_SPECIAL),
  396. forop));
  397. }
  398. DO_MAD({ forop = newUNOP(OP_NULL, 0, forop); })
  399. $$ = block_end($3, forop);
  400. TOKEN_GETMAD($1,$$,'3');
  401. TOKEN_GETMAD($2,$$,'(');
  402. TOKEN_GETMAD($5,$$,'1');
  403. TOKEN_GETMAD($7,$$,'2');
  404. TOKEN_GETMAD($10,$$,')');
  405. PL_parser->copline = (line_t)IVAL($1);
  406. }
  407. | FOR MY remember my_scalar lpar_or_qw mexpr ')' mblock cont
  408. {
  409. $$ = block_end($3, newFOROP(0, $4, $6, $8, $9));
  410. TOKEN_GETMAD($1,$$,'W');
  411. TOKEN_GETMAD($2,$$,'d');
  412. TOKEN_GETMAD($5,$$,'(');
  413. TOKEN_GETMAD($7,$$,')');
  414. PL_parser->copline = (line_t)IVAL($1);
  415. }
  416. | FOR scalar lpar_or_qw remember mexpr ')' mblock cont
  417. {
  418. $$ = block_end($4, newFOROP(0,
  419. op_lvalue($2, OP_ENTERLOOP), $5, $7, $8));
  420. TOKEN_GETMAD($1,$$,'W');
  421. TOKEN_GETMAD($3,$$,'(');
  422. TOKEN_GETMAD($6,$$,')');
  423. PL_parser->copline = (line_t)IVAL($1);
  424. }
  425. | FOR lpar_or_qw remember mexpr ')' mblock cont
  426. {
  427. $$ = block_end($3,
  428. newFOROP(0, (OP*)NULL, $4, $6, $7));
  429. TOKEN_GETMAD($1,$$,'W');
  430. TOKEN_GETMAD($2,$$,'(');
  431. TOKEN_GETMAD($5,$$,')');
  432. PL_parser->copline = (line_t)IVAL($1);
  433. }
  434. | block cont
  435. {
  436. /* a block is a loop that happens once */
  437. $$ = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
  438. (OP*)NULL, $1, $2, 0);
  439. }
  440. | PACKAGE WORD WORD '{' remember
  441. {
  442. int save_3_latefree = $3->op_latefree;
  443. $3->op_latefree = 1;
  444. package($3);
  445. $3->op_latefree = save_3_latefree;
  446. if ($2) {
  447. int save_2_latefree = $2->op_latefree;
  448. $2->op_latefree = 1;
  449. package_version($2);
  450. $2->op_latefree = save_2_latefree;
  451. }
  452. }
  453. stmtseq '}'
  454. {
  455. /* a block is a loop that happens once */
  456. $$ = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
  457. (OP*)NULL, block_end($5, $7), (OP*)NULL, 0);
  458. op_free($3);
  459. if ($2)
  460. op_free($2);
  461. TOKEN_GETMAD($4,$$,'{');
  462. TOKEN_GETMAD($8,$$,'}');
  463. if (PL_parser->copline > (line_t)IVAL($4))
  464. PL_parser->copline = (line_t)IVAL($4);
  465. }
  466. | sideff ';'
  467. {
  468. PL_parser->expect = XSTATE;
  469. $$ = $1;
  470. TOKEN_GETMAD($2,$$,';');
  471. }
  472. | ';'
  473. {
  474. PL_parser->expect = XSTATE;
  475. $$ = IF_MAD(newOP(OP_NULL, 0), (OP*)NULL);
  476. TOKEN_GETMAD($1,$$,';');
  477. PL_parser->copline = NOLINE;
  478. }
  479. ;
  480. /* An expression which may have a side-effect */
  481. sideff : error
  482. { $$ = (OP*)NULL; }
  483. | expr
  484. { $$ = $1; }
  485. | expr IF expr
  486. { $$ = newLOGOP(OP_AND, 0, $3, $1);
  487. TOKEN_GETMAD($2,$$,'i');
  488. }
  489. | expr UNLESS expr
  490. { $$ = newLOGOP(OP_OR, 0, $3, $1);
  491. TOKEN_GETMAD($2,$$,'i');
  492. }
  493. | expr WHILE expr
  494. { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1);
  495. TOKEN_GETMAD($2,$$,'w');
  496. }
  497. | expr UNTIL iexpr
  498. { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);
  499. TOKEN_GETMAD($2,$$,'w');
  500. }
  501. | expr FOR expr
  502. { $$ = newFOROP(0, (OP*)NULL, $3, $1, (OP*)NULL);
  503. TOKEN_GETMAD($2,$$,'w');
  504. PL_parser->copline = (line_t)IVAL($2);
  505. }
  506. | expr WHEN expr
  507. { $$ = newWHENOP($3, op_scope($1)); }
  508. ;
  509. /* else and elsif blocks */
  510. else : /* NULL */
  511. { $$ = (OP*)NULL; }
  512. | ELSE mblock
  513. {
  514. ($2)->op_flags |= OPf_PARENS;
  515. $$ = op_scope($2);
  516. TOKEN_GETMAD($1,$$,'o');
  517. }
  518. | ELSIF lpar_or_qw mexpr ')' mblock else
  519. { PL_parser->copline = (line_t)IVAL($1);
  520. $$ = newCONDOP(0,
  521. newSTATEOP(OPf_SPECIAL,NULL,$3),
  522. op_scope($5), $6);
  523. PL_hints |= HINT_BLOCK_SCOPE;
  524. TOKEN_GETMAD($1,$$,'I');
  525. TOKEN_GETMAD($2,$$,'(');
  526. TOKEN_GETMAD($4,$$,')');
  527. }
  528. ;
  529. /* Continue blocks */
  530. cont : /* NULL */
  531. { $$ = (OP*)NULL; }
  532. | CONTINUE block
  533. {
  534. $$ = op_scope($2);
  535. TOKEN_GETMAD($1,$$,'o');
  536. }
  537. ;
  538. /* determine whether there are any new my declarations */
  539. mintro : /* NULL */
  540. { $$ = (PL_min_intro_pending &&
  541. PL_max_intro_pending >= PL_min_intro_pending);
  542. intro_my(); }
  543. /* Normal expression */
  544. nexpr : /* NULL */
  545. { $$ = (OP*)NULL; }
  546. | sideff
  547. ;
  548. /* Boolean expression */
  549. texpr : /* NULL means true */
  550. { YYSTYPE tmplval;
  551. (void)scan_num("1", &tmplval);
  552. $$ = tmplval.opval; }
  553. | expr
  554. ;
  555. /* Inverted boolean expression */
  556. iexpr : expr
  557. { $$ = invert(scalar($1)); }
  558. ;
  559. /* Expression with its own lexical scope */
  560. mexpr : expr
  561. { $$ = $1; intro_my(); }
  562. ;
  563. mnexpr : nexpr
  564. { $$ = $1; intro_my(); }
  565. ;
  566. miexpr : iexpr
  567. { $$ = $1; intro_my(); }
  568. ;
  569. formname: WORD { $$ = $1; }
  570. | /* NULL */ { $$ = (OP*)NULL; }
  571. ;
  572. startsub: /* NULL */ /* start a regular subroutine scope */
  573. { $$ = start_subparse(FALSE, 0);
  574. SAVEFREESV(PL_compcv); }
  575. ;
  576. startanonsub: /* NULL */ /* start an anonymous subroutine scope */
  577. { $$ = start_subparse(FALSE, CVf_ANON);
  578. SAVEFREESV(PL_compcv); }
  579. ;
  580. startformsub: /* NULL */ /* start a format subroutine scope */
  581. { $$ = start_subparse(TRUE, 0);
  582. SAVEFREESV(PL_compcv); }
  583. ;
  584. /* Name of a subroutine - must be a bareword, could be special */
  585. subname : WORD { const char *const name = SvPV_nolen_const(((SVOP*)$1)->op_sv);
  586. if (strEQ(name, "BEGIN") || strEQ(name, "END")
  587. || strEQ(name, "INIT") || strEQ(name, "CHECK")
  588. || strEQ(name, "UNITCHECK"))
  589. CvSPECIAL_on(PL_compcv);
  590. $$ = $1; }
  591. ;
  592. /* Subroutine prototype */
  593. proto : /* NULL */
  594. { $$ = (OP*)NULL; }
  595. | THING
  596. ;
  597. /* Optional list of subroutine attributes */
  598. subattrlist: /* NULL */
  599. { $$ = (OP*)NULL; }
  600. | COLONATTR THING
  601. { $$ = $2;
  602. TOKEN_GETMAD($1,$$,':');
  603. }
  604. | COLONATTR
  605. { $$ = IF_MAD(
  606. newOP(OP_NULL, 0),
  607. (OP*)NULL
  608. );
  609. TOKEN_GETMAD($1,$$,':');
  610. }
  611. ;
  612. /* List of attributes for a "my" variable declaration */
  613. myattrlist: COLONATTR THING
  614. { $$ = $2;
  615. TOKEN_GETMAD($1,$$,':');
  616. }
  617. | COLONATTR
  618. { $$ = IF_MAD(
  619. newOP(OP_NULL, 0),
  620. (OP*)NULL
  621. );
  622. TOKEN_GETMAD($1,$$,':');
  623. }
  624. ;
  625. /* Subroutine body - either null or a block */
  626. subbody : block { $$ = $1; }
  627. | ';' { $$ = IF_MAD(
  628. newOP(OP_NULL,0),
  629. (OP*)NULL
  630. );
  631. PL_parser->expect = XSTATE;
  632. TOKEN_GETMAD($1,$$,';');
  633. }
  634. ;
  635. /* Ordinary expressions; logical combinations */
  636. expr : expr ANDOP expr
  637. { $$ = newLOGOP(OP_AND, 0, $1, $3);
  638. TOKEN_GETMAD($2,$$,'o');
  639. }
  640. | expr OROP expr
  641. { $$ = newLOGOP(IVAL($2), 0, $1, $3);
  642. TOKEN_GETMAD($2,$$,'o');
  643. }
  644. | expr DOROP expr
  645. { $$ = newLOGOP(OP_DOR, 0, $1, $3);
  646. TOKEN_GETMAD($2,$$,'o');
  647. }
  648. | listexpr %prec PREC_LOW
  649. ;
  650. /* Expressions are a list of terms joined by commas */
  651. listexpr: listexpr ','
  652. {
  653. #ifdef MAD
  654. OP* op = newNULLLIST();
  655. token_getmad($2,op,',');
  656. $$ = op_append_elem(OP_LIST, $1, op);
  657. #else
  658. $$ = $1;
  659. #endif
  660. }
  661. | listexpr ',' term
  662. {
  663. OP* term = $3;
  664. DO_MAD(
  665. term = newUNOP(OP_NULL, 0, term);
  666. token_getmad($2,term,',');
  667. )
  668. $$ = op_append_elem(OP_LIST, $1, term);
  669. }
  670. | term %prec PREC_LOW
  671. ;
  672. /* List operators */
  673. listop : LSTOP indirob listexpr /* map {...} @args or print $fh @args */
  674. { $$ = convert(IVAL($1), OPf_STACKED,
  675. op_prepend_elem(OP_LIST, newGVREF(IVAL($1),$2), $3) );
  676. TOKEN_GETMAD($1,$$,'o');
  677. }
  678. | FUNC '(' indirob expr ')' /* print ($fh @args */
  679. { $$ = convert(IVAL($1), OPf_STACKED,
  680. op_prepend_elem(OP_LIST, newGVREF(IVAL($1),$3), $4) );
  681. TOKEN_GETMAD($1,$$,'o');
  682. TOKEN_GETMAD($2,$$,'(');
  683. TOKEN_GETMAD($5,$$,')');
  684. }
  685. | term ARROW method lpar_or_qw optexpr ')' /* $foo->bar(list) */
  686. { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  687. op_append_elem(OP_LIST,
  688. op_prepend_elem(OP_LIST, scalar($1), $5),
  689. newUNOP(OP_METHOD, 0, $3)));
  690. TOKEN_GETMAD($2,$$,'A');
  691. TOKEN_GETMAD($4,$$,'(');
  692. TOKEN_GETMAD($6,$$,')');
  693. }
  694. | term ARROW method /* $foo->bar */
  695. { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  696. op_append_elem(OP_LIST, scalar($1),
  697. newUNOP(OP_METHOD, 0, $3)));
  698. TOKEN_GETMAD($2,$$,'A');
  699. }
  700. | METHOD indirob optlistexpr /* new Class @args */
  701. { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  702. op_append_elem(OP_LIST,
  703. op_prepend_elem(OP_LIST, $2, $3),
  704. newUNOP(OP_METHOD, 0, $1)));
  705. }
  706. | FUNCMETH indirob '(' optexpr ')' /* method $object (@args) */
  707. { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  708. op_append_elem(OP_LIST,
  709. op_prepend_elem(OP_LIST, $2, $4),
  710. newUNOP(OP_METHOD, 0, $1)));
  711. TOKEN_GETMAD($3,$$,'(');
  712. TOKEN_GETMAD($5,$$,')');
  713. }
  714. | LSTOP optlistexpr /* print @args */
  715. { $$ = convert(IVAL($1), 0, $2);
  716. TOKEN_GETMAD($1,$$,'o');
  717. }
  718. | FUNC '(' optexpr ')' /* print (@args) */
  719. { $$ = convert(IVAL($1), 0, $3);
  720. TOKEN_GETMAD($1,$$,'o');
  721. TOKEN_GETMAD($2,$$,'(');
  722. TOKEN_GETMAD($4,$$,')');
  723. }
  724. | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */
  725. { SvREFCNT_inc_simple_void(PL_compcv);
  726. $<opval>$ = newANONATTRSUB($2, 0, (OP*)NULL, $3); }
  727. optlistexpr %prec LSTOP /* ... @bar */
  728. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  729. op_append_elem(OP_LIST,
  730. op_prepend_elem(OP_LIST, $<opval>4, $5), $1));
  731. }
  732. ;
  733. /* Names of methods. May use $object->$methodname */
  734. method : METHOD
  735. | scalar
  736. ;
  737. /* Some kind of subscripted expression */
  738. subscripted: star '{' expr ';' '}' /* *main::{something} */
  739. /* In this and all the hash accessors, ';' is
  740. * provided by the tokeniser */
  741. { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3));
  742. PL_parser->expect = XOPERATOR;
  743. TOKEN_GETMAD($2,$$,'{');
  744. TOKEN_GETMAD($4,$$,';');
  745. TOKEN_GETMAD($5,$$,'}');
  746. }
  747. | scalar '[' expr ']' /* $array[$element] */
  748. { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3));
  749. TOKEN_GETMAD($2,$$,'[');
  750. TOKEN_GETMAD($4,$$,']');
  751. }
  752. | term ARROW '[' expr ']' /* somearef->[$element] */
  753. { $$ = newBINOP(OP_AELEM, 0,
  754. ref(newAVREF($1),OP_RV2AV),
  755. scalar($4));
  756. TOKEN_GETMAD($2,$$,'a');
  757. TOKEN_GETMAD($3,$$,'[');
  758. TOKEN_GETMAD($5,$$,']');
  759. }
  760. | subscripted '[' expr ']' /* $foo->[$bar]->[$baz] */
  761. { $$ = newBINOP(OP_AELEM, 0,
  762. ref(newAVREF($1),OP_RV2AV),
  763. scalar($3));
  764. TOKEN_GETMAD($2,$$,'[');
  765. TOKEN_GETMAD($4,$$,']');
  766. }
  767. | scalar '{' expr ';' '}' /* $foo->{bar();} */
  768. { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
  769. PL_parser->expect = XOPERATOR;
  770. TOKEN_GETMAD($2,$$,'{');
  771. TOKEN_GETMAD($4,$$,';');
  772. TOKEN_GETMAD($5,$$,'}');
  773. }
  774. | term ARROW '{' expr ';' '}' /* somehref->{bar();} */
  775. { $$ = newBINOP(OP_HELEM, 0,
  776. ref(newHVREF($1),OP_RV2HV),
  777. jmaybe($4));
  778. PL_parser->expect = XOPERATOR;
  779. TOKEN_GETMAD($2,$$,'a');
  780. TOKEN_GETMAD($3,$$,'{');
  781. TOKEN_GETMAD($5,$$,';');
  782. TOKEN_GETMAD($6,$$,'}');
  783. }
  784. | subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */
  785. { $$ = newBINOP(OP_HELEM, 0,
  786. ref(newHVREF($1),OP_RV2HV),
  787. jmaybe($3));
  788. PL_parser->expect = XOPERATOR;
  789. TOKEN_GETMAD($2,$$,'{');
  790. TOKEN_GETMAD($4,$$,';');
  791. TOKEN_GETMAD($5,$$,'}');
  792. }
  793. | term ARROW '(' ')' /* $subref->() */
  794. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  795. newCVREF(0, scalar($1)));
  796. TOKEN_GETMAD($2,$$,'a');
  797. TOKEN_GETMAD($3,$$,'(');
  798. TOKEN_GETMAD($4,$$,')');
  799. }
  800. | term ARROW '(' expr ')' /* $subref->(@args) */
  801. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  802. op_append_elem(OP_LIST, $4,
  803. newCVREF(0, scalar($1))));
  804. TOKEN_GETMAD($2,$$,'a');
  805. TOKEN_GETMAD($3,$$,'(');
  806. TOKEN_GETMAD($5,$$,')');
  807. }
  808. | subscripted lpar_or_qw expr ')' /* $foo->{bar}->(@args) */
  809. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  810. op_append_elem(OP_LIST, $3,
  811. newCVREF(0, scalar($1))));
  812. TOKEN_GETMAD($2,$$,'(');
  813. TOKEN_GETMAD($4,$$,')');
  814. }
  815. | subscripted lpar_or_qw ')' /* $foo->{bar}->() */
  816. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  817. newCVREF(0, scalar($1)));
  818. TOKEN_GETMAD($2,$$,'(');
  819. TOKEN_GETMAD($3,$$,')');
  820. }
  821. | '(' expr ')' '[' expr ']' /* list slice */
  822. { $$ = newSLICEOP(0, $5, $2);
  823. TOKEN_GETMAD($1,$$,'(');
  824. TOKEN_GETMAD($3,$$,')');
  825. TOKEN_GETMAD($4,$$,'[');
  826. TOKEN_GETMAD($6,$$,']');
  827. }
  828. | QWLIST '[' expr ']' /* list literal slice */
  829. { $$ = newSLICEOP(0, $3, $1);
  830. TOKEN_GETMAD($2,$$,'[');
  831. TOKEN_GETMAD($4,$$,']');
  832. }
  833. | '(' ')' '[' expr ']' /* empty list slice! */
  834. { $$ = newSLICEOP(0, $4, (OP*)NULL);
  835. TOKEN_GETMAD($1,$$,'(');
  836. TOKEN_GETMAD($2,$$,')');
  837. TOKEN_GETMAD($3,$$,'[');
  838. TOKEN_GETMAD($5,$$,']');
  839. }
  840. ;
  841. /* Binary operators between terms */
  842. termbinop: term ASSIGNOP term /* $x = $y */
  843. { $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3);
  844. TOKEN_GETMAD($2,$$,'o');
  845. }
  846. | term POWOP term /* $x ** $y */
  847. { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
  848. TOKEN_GETMAD($2,$$,'o');
  849. }
  850. | term MULOP term /* $x * $y, $x x $y */
  851. { if (IVAL($2) != OP_REPEAT)
  852. scalar($1);
  853. $$ = newBINOP(IVAL($2), 0, $1, scalar($3));
  854. TOKEN_GETMAD($2,$$,'o');
  855. }
  856. | term ADDOP term /* $x + $y */
  857. { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
  858. TOKEN_GETMAD($2,$$,'o');
  859. }
  860. | term SHIFTOP term /* $x >> $y, $x << $y */
  861. { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
  862. TOKEN_GETMAD($2,$$,'o');
  863. }
  864. | term RELOP term /* $x > $y, etc. */
  865. { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
  866. TOKEN_GETMAD($2,$$,'o');
  867. }
  868. | term EQOP term /* $x == $y, $x eq $y */
  869. { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
  870. TOKEN_GETMAD($2,$$,'o');
  871. }
  872. | term BITANDOP term /* $x & $y */
  873. { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
  874. TOKEN_GETMAD($2,$$,'o');
  875. }
  876. | term BITOROP term /* $x | $y */
  877. { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
  878. TOKEN_GETMAD($2,$$,'o');
  879. }
  880. | term DOTDOT term /* $x..$y, $x...$y */
  881. {
  882. $$ = newRANGE(IVAL($2), scalar($1), scalar($3));
  883. DO_MAD({
  884. UNOP *op;
  885. op = (UNOP*)$$;
  886. op = (UNOP*)op->op_first; /* get to flop */
  887. op = (UNOP*)op->op_first; /* get to flip */
  888. op = (UNOP*)op->op_first; /* get to range */
  889. token_getmad($2,(OP*)op,'o');
  890. })
  891. }
  892. | term ANDAND term /* $x && $y */
  893. { $$ = newLOGOP(OP_AND, 0, $1, $3);
  894. TOKEN_GETMAD($2,$$,'o');
  895. }
  896. | term OROR term /* $x || $y */
  897. { $$ = newLOGOP(OP_OR, 0, $1, $3);
  898. TOKEN_GETMAD($2,$$,'o');
  899. }
  900. | term DORDOR term /* $x // $y */
  901. { $$ = newLOGOP(OP_DOR, 0, $1, $3);
  902. TOKEN_GETMAD($2,$$,'o');
  903. }
  904. | term MATCHOP term /* $x =~ /$y/ */
  905. { $$ = bind_match(IVAL($2), $1, $3);
  906. TOKEN_GETMAD($2,
  907. ($$->op_type == OP_NOT
  908. ? ((UNOP*)$$)->op_first : $$),
  909. '~');
  910. }
  911. ;
  912. /* Unary operators and terms */
  913. termunop : '-' term %prec UMINUS /* -$x */
  914. { $$ = newUNOP(OP_NEGATE, 0, scalar($2));
  915. TOKEN_GETMAD($1,$$,'o');
  916. }
  917. | '+' term %prec UMINUS /* +$x */
  918. { $$ = IF_MAD(
  919. newUNOP(OP_NULL, 0, $2),
  920. $2
  921. );
  922. TOKEN_GETMAD($1,$$,'+');
  923. }
  924. | '!' term /* !$x */
  925. { $$ = newUNOP(OP_NOT, 0, scalar($2));
  926. TOKEN_GETMAD($1,$$,'o');
  927. }
  928. | '~' term /* ~$x */
  929. { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));
  930. TOKEN_GETMAD($1,$$,'o');
  931. }
  932. | term POSTINC /* $x++ */
  933. { $$ = newUNOP(OP_POSTINC, 0,
  934. op_lvalue(scalar($1), OP_POSTINC));
  935. TOKEN_GETMAD($2,$$,'o');
  936. }
  937. | term POSTDEC /* $x-- */
  938. { $$ = newUNOP(OP_POSTDEC, 0,
  939. op_lvalue(scalar($1), OP_POSTDEC));
  940. TOKEN_GETMAD($2,$$,'o');
  941. }
  942. | PREINC term /* ++$x */
  943. { $$ = newUNOP(OP_PREINC, 0,
  944. op_lvalue(scalar($2), OP_PREINC));
  945. TOKEN_GETMAD($1,$$,'o');
  946. }
  947. | PREDEC term /* --$x */
  948. { $$ = newUNOP(OP_PREDEC, 0,
  949. op_lvalue(scalar($2), OP_PREDEC));
  950. TOKEN_GETMAD($1,$$,'o');
  951. }
  952. ;
  953. /* Constructors for anonymous data */
  954. anonymous: '[' expr ']'
  955. { $$ = newANONLIST($2);
  956. TOKEN_GETMAD($1,$$,'[');
  957. TOKEN_GETMAD($3,$$,']');
  958. }
  959. | '[' ']'
  960. { $$ = newANONLIST((OP*)NULL);
  961. TOKEN_GETMAD($1,$$,'[');
  962. TOKEN_GETMAD($2,$$,']');
  963. }
  964. | HASHBRACK expr ';' '}' %prec '(' /* { foo => "Bar" } */
  965. { $$ = newANONHASH($2);
  966. TOKEN_GETMAD($1,$$,'{');
  967. TOKEN_GETMAD($3,$$,';');
  968. TOKEN_GETMAD($4,$$,'}');
  969. }
  970. | HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */
  971. { $$ = newANONHASH((OP*)NULL);
  972. TOKEN_GETMAD($1,$$,'{');
  973. TOKEN_GETMAD($2,$$,';');
  974. TOKEN_GETMAD($3,$$,'}');
  975. }
  976. | ANONSUB startanonsub proto subattrlist block %prec '('
  977. { SvREFCNT_inc_simple_void(PL_compcv);
  978. $$ = newANONATTRSUB($2, $3, $4, $5);
  979. TOKEN_GETMAD($1,$$,'o');
  980. OP_GETMAD($3,$$,'s');
  981. OP_GETMAD($4,$$,'a');
  982. }
  983. ;
  984. /* Things called with "do" */
  985. termdo : DO term %prec UNIOP /* do $filename */
  986. { $$ = dofile($2, IVAL($1));
  987. TOKEN_GETMAD($1,$$,'o');
  988. }
  989. | DO block %prec '(' /* do { code */
  990. { $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($2));
  991. TOKEN_GETMAD($1,$$,'D');
  992. }
  993. | DO WORD lpar_or_qw ')' /* do somesub() */
  994. { $$ = newUNOP(OP_ENTERSUB,
  995. OPf_SPECIAL|OPf_STACKED,
  996. op_prepend_elem(OP_LIST,
  997. scalar(newCVREF(
  998. (OPpENTERSUB_AMPER<<8),
  999. scalar($2)
  1000. )),(OP*)NULL)); dep();
  1001. TOKEN_GETMAD($1,$$,'o');
  1002. TOKEN_GETMAD($3,$$,'(');
  1003. TOKEN_GETMAD($4,$$,')');
  1004. }
  1005. | DO WORD lpar_or_qw expr ')' /* do somesub(@args) */
  1006. { $$ = newUNOP(OP_ENTERSUB,
  1007. OPf_SPECIAL|OPf_STACKED,
  1008. op_append_elem(OP_LIST,
  1009. $4,
  1010. scalar(newCVREF(
  1011. (OPpENTERSUB_AMPER<<8),
  1012. scalar($2)
  1013. )))); dep();
  1014. TOKEN_GETMAD($1,$$,'o');
  1015. TOKEN_GETMAD($3,$$,'(');
  1016. TOKEN_GETMAD($5,$$,')');
  1017. }
  1018. | DO scalar lpar_or_qw ')' /* do $subref () */
  1019. { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
  1020. op_prepend_elem(OP_LIST,
  1021. scalar(newCVREF(0,scalar($2))), (OP*)NULL)); dep();
  1022. TOKEN_GETMAD($1,$$,'o');
  1023. TOKEN_GETMAD($3,$$,'(');
  1024. TOKEN_GETMAD($4,$$,')');
  1025. }
  1026. | DO scalar lpar_or_qw expr ')' /* do $subref (@args) */
  1027. { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
  1028. op_prepend_elem(OP_LIST,
  1029. $4,
  1030. scalar(newCVREF(0,scalar($2))))); dep();
  1031. TOKEN_GETMAD($1,$$,'o');
  1032. TOKEN_GETMAD($3,$$,'(');
  1033. TOKEN_GETMAD($5,$$,')');
  1034. }
  1035. ;
  1036. term : termbinop
  1037. | termunop
  1038. | anonymous
  1039. | termdo
  1040. | term '?' term ':' term
  1041. { $$ = newCONDOP(0, $1, $3, $5);
  1042. TOKEN_GETMAD($2,$$,'?');
  1043. TOKEN_GETMAD($4,$$,':');
  1044. }
  1045. | REFGEN term /* \$x, \@y, \%z */
  1046. { $$ = newUNOP(OP_REFGEN, 0, op_lvalue($2,OP_REFGEN));
  1047. TOKEN_GETMAD($1,$$,'o');
  1048. }
  1049. | myattrterm %prec UNIOP
  1050. { $$ = $1; }
  1051. | LOCAL term %prec UNIOP
  1052. { $$ = localize($2,IVAL($1));
  1053. TOKEN_GETMAD($1,$$,'k');
  1054. }
  1055. | '(' expr ')'
  1056. { $$ = sawparens(IF_MAD(newUNOP(OP_NULL,0,$2), $2));
  1057. TOKEN_GETMAD($1,$$,'(');
  1058. TOKEN_GETMAD($3,$$,')');
  1059. }
  1060. | QWLIST
  1061. { $$ = IF_MAD(newUNOP(OP_NULL,0,$1), $1); }
  1062. | '(' ')'
  1063. { $$ = sawparens(newNULLLIST());
  1064. TOKEN_GETMAD($1,$$,'(');
  1065. TOKEN_GETMAD($2,$$,')');
  1066. }
  1067. | scalar %prec '('
  1068. { $$ = $1; }
  1069. | star %prec '('
  1070. { $$ = $1; }
  1071. | hsh %prec '('
  1072. { $$ = $1; }
  1073. | ary %prec '('
  1074. { $$ = $1; }
  1075. | arylen %prec '(' /* $#x, $#{ something } */
  1076. { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
  1077. | subscripted
  1078. { $$ = $1; }
  1079. | ary '[' expr ']' /* array slice */
  1080. { $$ = op_prepend_elem(OP_ASLICE,
  1081. newOP(OP_PUSHMARK, 0),
  1082. newLISTOP(OP_ASLICE, 0,
  1083. list($3),
  1084. ref($1, OP_ASLICE)));
  1085. TOKEN_GETMAD($2,$$,'[');
  1086. TOKEN_GETMAD($4,$$,']');
  1087. }
  1088. | ary '{' expr ';' '}' /* @hash{@keys} */
  1089. { $$ = op_prepend_elem(OP_HSLICE,
  1090. newOP(OP_PUSHMARK, 0),
  1091. newLISTOP(OP_HSLICE, 0,
  1092. list($3),
  1093. ref(oopsHV($1), OP_HSLICE)));
  1094. PL_parser->expect = XOPERATOR;
  1095. TOKEN_GETMAD($2,$$,'{');
  1096. TOKEN_GETMAD($4,$$,';');
  1097. TOKEN_GETMAD($5,$$,'}');
  1098. }
  1099. | THING %prec '('
  1100. { $$ = $1; }
  1101. | amper /* &foo; */
  1102. { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
  1103. | amper lpar_or_qw ')' /* &foo() */
  1104. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1));
  1105. TOKEN_GETMAD($2,$$,'(');
  1106. TOKEN_GETMAD($3,$$,')');
  1107. }
  1108. | amper lpar_or_qw expr ')' /* &foo(@args) */
  1109. {
  1110. $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  1111. op_append_elem(OP_LIST, $3, scalar($1)));
  1112. DO_MAD({
  1113. OP* op = $$;
  1114. if (op->op_type == OP_CONST) { /* defeat const fold */
  1115. op = (OP*)op->op_madprop->mad_val;
  1116. }
  1117. token_getmad($2,op,'(');
  1118. token_getmad($4,op,')');
  1119. })
  1120. }
  1121. | NOAMP WORD optlistexpr /* foo(@args) */
  1122. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  1123. op_append_elem(OP_LIST, $3, scalar($2)));
  1124. TOKEN_GETMAD($1,$$,'o');
  1125. }
  1126. | LOOPEX /* loop exiting command (goto, last, dump, etc) */
  1127. { $$ = newOP(IVAL($1), OPf_SPECIAL);
  1128. PL_hints |= HINT_BLOCK_SCOPE;
  1129. TOKEN_GETMAD($1,$$,'o');
  1130. }
  1131. | LOOPEX term
  1132. { $$ = newLOOPEX(IVAL($1),$2);
  1133. TOKEN_GETMAD($1,$$,'o');
  1134. }
  1135. | NOTOP listexpr /* not $foo */
  1136. { $$ = newUNOP(OP_NOT, 0, scalar($2));
  1137. TOKEN_GETMAD($1,$$,'o');
  1138. }
  1139. | UNIOP /* Unary op, $_ implied */
  1140. { $$ = newOP(IVAL($1), 0);
  1141. TOKEN_GETMAD($1,$$,'o');
  1142. }
  1143. | UNIOP block /* eval { foo }* */
  1144. { $$ = newUNOP(IVAL($1), 0, $2);
  1145. TOKEN_GETMAD($1,$$,'o');
  1146. }
  1147. | UNIOP term /* Unary op */
  1148. { $$ = newUNOP(IVAL($1), 0, $2);
  1149. TOKEN_GETMAD($1,$$,'o');
  1150. }
  1151. | REQUIRE /* require, $_ implied */
  1152. { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0);
  1153. TOKEN_GETMAD($1,$$,'o');
  1154. }
  1155. | REQUIRE term /* require Foo */
  1156. { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2);
  1157. TOKEN_GETMAD($1,$$,'o');
  1158. }
  1159. | UNIOPSUB
  1160. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
  1161. | UNIOPSUB term /* Sub treated as unop */
  1162. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  1163. op_append_elem(OP_LIST, $2, scalar($1))); }
  1164. | FUNC0 /* Nullary operator */
  1165. { $$ = newOP(IVAL($1), 0);
  1166. TOKEN_GETMAD($1,$$,'o');
  1167. }
  1168. | FUNC0 '(' ')'
  1169. { $$ = newOP(IVAL($1), 0);
  1170. TOKEN_GETMAD($1,$$,'o');
  1171. TOKEN_GETMAD($2,$$,'(');
  1172. TOKEN_GETMAD($3,$$,')');
  1173. }
  1174. | FUNC0SUB /* Sub treated as nullop */
  1175. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  1176. scalar($1)); }
  1177. | FUNC1 '(' ')' /* not () */
  1178. { $$ = (IVAL($1) == OP_NOT)
  1179. ? newUNOP(IVAL($1), 0, newSVOP(OP_CONST, 0, newSViv(0)))
  1180. : newOP(IVAL($1), OPf_SPECIAL);
  1181. TOKEN_GETMAD($1,$$,'o');
  1182. TOKEN_GETMAD($2,$$,'(');
  1183. TOKEN_GETMAD($3,$$,')');
  1184. }
  1185. | FUNC1 '(' expr ')' /* not($foo) */
  1186. { $$ = newUNOP(IVAL($1), 0, $3);
  1187. TOKEN_GETMAD($1,$$,'o');
  1188. TOKEN_GETMAD($2,$$,'(');
  1189. TOKEN_GETMAD($4,$$,')');
  1190. }
  1191. | PMFUNC '(' listexpr ')' /* m//, s///, tr/// */
  1192. { $$ = pmruntime($1, $3, 1);
  1193. TOKEN_GETMAD($2,$$,'(');
  1194. TOKEN_GETMAD($4,$$,')');
  1195. }
  1196. | WORD
  1197. | listop
  1198. | YADAYADA
  1199. {
  1200. $$ = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0),
  1201. newSVOP(OP_CONST, 0, newSVpvs("Unimplemented")));
  1202. TOKEN_GETMAD($1,$$,'X');
  1203. }
  1204. | PLUGEXPR
  1205. ;
  1206. /* "my" declarations, with optional attributes */
  1207. myattrterm: MY myterm myattrlist
  1208. { $$ = my_attrs($2,$3);
  1209. DO_MAD(
  1210. token_getmad($1,$$,'d');
  1211. append_madprops($3->op_madprop, $$, 'a');
  1212. $3->op_madprop = 0;
  1213. )
  1214. }
  1215. | MY myterm
  1216. { $$ = localize($2,IVAL($1));
  1217. TOKEN_GETMAD($1,$$,'d');
  1218. }
  1219. ;
  1220. /* Things that can be "my"'d */
  1221. myterm : '(' expr ')'
  1222. { $$ = sawparens($2);
  1223. TOKEN_GETMAD($1,$$,'(');
  1224. TOKEN_GETMAD($3,$$,')');
  1225. }
  1226. | '(' ')'
  1227. { $$ = sawparens(newNULLLIST());
  1228. TOKEN_GETMAD($1,$$,'(');
  1229. TOKEN_GETMAD($2,$$,')');
  1230. }
  1231. | scalar %prec '('
  1232. { $$ = $1; }
  1233. | hsh %prec '('
  1234. { $$ = $1; }
  1235. | ary %prec '('
  1236. { $$ = $1; }
  1237. ;
  1238. /* Basic list expressions */
  1239. optlistexpr: /* NULL */ %prec PREC_LOW
  1240. { $$ = (OP*)NULL; }
  1241. | listexpr %prec PREC_LOW
  1242. { $$ = $1; }
  1243. ;
  1244. optexpr: /* NULL */
  1245. { $$ = (OP*)NULL; }
  1246. | expr
  1247. { $$ = $1; }
  1248. ;
  1249. lpar_or_qw: '('
  1250. { $$ = $1; }
  1251. | QWLIST
  1252. { munge_qwlist_to_paren_list($1); }
  1253. '('
  1254. { $$ = $3; }
  1255. ;
  1256. /* A little bit of trickery to make "for my $foo (@bar)" actually be
  1257. lexical */
  1258. my_scalar: scalar
  1259. { PL_parser->in_my = 0; $$ = my($1); }
  1260. ;
  1261. amper : '&' indirob
  1262. { $$ = newCVREF(IVAL($1),$2);
  1263. TOKEN_GETMAD($1,$$,'&');
  1264. }
  1265. ;
  1266. scalar : '$' indirob
  1267. { $$ = newSVREF($2);
  1268. TOKEN_GETMAD($1,$$,'$');
  1269. }
  1270. ;
  1271. ary : '@' indirob
  1272. { $$ = newAVREF($2);
  1273. TOKEN_GETMAD($1,$$,'@');
  1274. }
  1275. ;
  1276. hsh : '%' indirob
  1277. { $$ = newHVREF($2);
  1278. TOKEN_GETMAD($1,$$,'%');
  1279. }
  1280. ;
  1281. arylen : DOLSHARP indirob
  1282. { $$ = newAVREF($2);
  1283. TOKEN_GETMAD($1,$$,'l');
  1284. }
  1285. ;
  1286. star : '*' indirob
  1287. { $$ = newGVREF(0,$2);
  1288. TOKEN_GETMAD($1,$$,'*');
  1289. }
  1290. ;
  1291. /* Indirect objects */
  1292. indirob : WORD
  1293. { $$ = scalar($1); }
  1294. | scalar %prec PREC_LOW
  1295. { $$ = scalar($1); }
  1296. | block
  1297. { $$ = op_scope($1); }
  1298. | PRIVATEREF
  1299. { $$ = $1; }
  1300. ;