PageRenderTime 65ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/opensource.apple.com/source/perl/perl-24.1/perl/perly.y

#
Happy | 826 lines | 738 code | 88 blank | 0 comment | 0 complexity | 3431f398193b00c0ae28185c1fe59aae MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0, GPL-2.0, ISC, LGPL-2.1, Apache-2.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause, WTFPL, MIT, AGPL-1.0, AGPL-3.0
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <title>perly.y</title>
  6. <style type="text/css">
  7. .enscript-comment { font-style: italic; color: rgb(178,34,34); }
  8. .enscript-function-name { font-weight: bold; color: rgb(0,0,255); }
  9. .enscript-variable-name { font-weight: bold; color: rgb(184,134,11); }
  10. .enscript-keyword { font-weight: bold; color: rgb(160,32,240); }
  11. .enscript-reference { font-weight: bold; color: rgb(95,158,160); }
  12. .enscript-string { font-weight: bold; color: rgb(188,143,143); }
  13. .enscript-builtin { font-weight: bold; color: rgb(218,112,214); }
  14. .enscript-type { font-weight: bold; color: rgb(34,139,34); }
  15. .enscript-highlight { text-decoration: underline; color: 0; }
  16. </style>
  17. </head>
  18. <body id="top">
  19. <h1 style="margin:8px;" id="f1">perly.y&nbsp;&nbsp;&nbsp;<span style="font-weight: normal; font-size: 0.5em;">[<a href="?txt">plain text</a>]</span></h1>
  20. <hr/>
  21. <div></div>
  22. <pre>
  23. /* perly.y
  24. *
  25. * Copyright (c) 1991-2002, Larry Wall
  26. *
  27. * You may distribute under the terms of either the GNU General Public
  28. * License or the Artistic License, as specified in the README file.
  29. *
  30. */
  31. /*
  32. * 'I see,' laughed Strider. 'I look foul and feel fair. Is that it?
  33. * All that is gold does not glitter, not all those who wander are lost.'
  34. */
  35. %{
  36. #include &quot;EXTERN.h&quot;
  37. #define PERL_IN_PERLY_C
  38. #include &quot;perl.h&quot;
  39. #ifdef EBCDIC
  40. #undef YYDEBUG
  41. #endif
  42. #define dep() deprecate(&quot;\&quot;do\&quot; to call subroutines&quot;)
  43. /* stuff included here to make perly_c.diff apply better */
  44. #define yydebug PL_yydebug
  45. #define yynerrs PL_yynerrs
  46. #define yyerrflag PL_yyerrflag
  47. #define yychar PL_yychar
  48. #define yyval PL_yyval
  49. #define yylval PL_yylval
  50. struct ysv {
  51. short* yyss;
  52. YYSTYPE* yyvs;
  53. int oldyydebug;
  54. int oldyynerrs;
  55. int oldyyerrflag;
  56. int oldyychar;
  57. YYSTYPE oldyyval;
  58. YYSTYPE oldyylval;
  59. };
  60. static void yydestruct(pTHX_ void *ptr);
  61. %}
  62. %start prog
  63. %{
  64. #if 0 /* get this from perly.h instead */
  65. %}
  66. %union {
  67. I32 ival;
  68. char *pval;
  69. OP *opval;
  70. GV *gvval;
  71. }
  72. %{
  73. #endif /* 0 */
  74. #ifdef USE_PURE_BISON
  75. #define YYLEX_PARAM (&amp;yychar)
  76. #define yylex yylex_r
  77. #endif
  78. %}
  79. %token &lt;ival&gt; '{'
  80. %token &lt;opval&gt; WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
  81. %token &lt;opval&gt; FUNC0SUB UNIOPSUB LSTOPSUB
  82. %token &lt;pval&gt; LABEL
  83. %token &lt;ival&gt; FORMAT SUB ANONSUB PACKAGE USE
  84. %token &lt;ival&gt; WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
  85. %token &lt;ival&gt; LOOPEX DOTDOT
  86. %token &lt;ival&gt; FUNC0 FUNC1 FUNC UNIOP LSTOP
  87. %token &lt;ival&gt; RELOP EQOP MULOP ADDOP
  88. %token &lt;ival&gt; DOLSHARP DO HASHBRACK NOAMP
  89. %token &lt;ival&gt; LOCAL MY MYSUB
  90. %token COLONATTR
  91. %type &lt;ival&gt; prog decl format startsub startanonsub startformsub
  92. %type &lt;ival&gt; progstart remember mremember '&amp;'
  93. %type &lt;opval&gt; block mblock lineseq line loop cond else
  94. %type &lt;opval&gt; expr term subscripted scalar ary hsh arylen star amper sideff
  95. %type &lt;opval&gt; argexpr nexpr texpr iexpr mexpr mnexpr mtexpr miexpr
  96. %type &lt;opval&gt; listexpr listexprcom indirob listop method
  97. %type &lt;opval&gt; formname subname proto subbody cont my_scalar
  98. %type &lt;opval&gt; subattrlist myattrlist mysubrout myattrterm myterm
  99. %type &lt;opval&gt; termbinop termunop anonymous termdo
  100. %type &lt;pval&gt; label
  101. %nonassoc PREC_LOW
  102. %nonassoc LOOPEX
  103. %left &lt;ival&gt; OROP
  104. %left ANDOP
  105. %right NOTOP
  106. %nonassoc LSTOP LSTOPSUB
  107. %left ','
  108. %right &lt;ival&gt; ASSIGNOP
  109. %right '?' ':'
  110. %nonassoc DOTDOT
  111. %left OROR
  112. %left ANDAND
  113. %left &lt;ival&gt; BITOROP
  114. %left &lt;ival&gt; BITANDOP
  115. %nonassoc EQOP
  116. %nonassoc RELOP
  117. %nonassoc UNIOP UNIOPSUB
  118. %left &lt;ival&gt; SHIFTOP
  119. %left ADDOP
  120. %left MULOP
  121. %left &lt;ival&gt; MATCHOP
  122. %right '!' '~' UMINUS REFGEN
  123. %right &lt;ival&gt; POWOP
  124. %nonassoc PREINC PREDEC POSTINC POSTDEC
  125. %left ARROW
  126. %nonassoc &lt;ival&gt; ')'
  127. %left '('
  128. %left '[' '{'
  129. %% /* RULES */
  130. /* The whole program */
  131. prog : progstart
  132. /*CONTINUED*/ lineseq
  133. { $$ = $1; newPROG(block_end($1,$2)); }
  134. ;
  135. /* An ordinary block */
  136. block : '{' remember lineseq '}'
  137. { if (PL_copline &gt; (line_t)$1)
  138. PL_copline = (line_t)$1;
  139. $$ = block_end($2, $3); }
  140. ;
  141. remember: /* NULL */ /* start a full lexical scope */
  142. { $$ = block_start(TRUE); }
  143. ;
  144. progstart:
  145. {
  146. #if defined(YYDEBUG) &amp;&amp; defined(DEBUGGING)
  147. yydebug = (DEBUG_p_TEST);
  148. #endif
  149. PL_expect = XSTATE; $$ = block_start(TRUE);
  150. }
  151. ;
  152. mblock : '{' mremember lineseq '}'
  153. { if (PL_copline &gt; (line_t)$1)
  154. PL_copline = (line_t)$1;
  155. $$ = block_end($2, $3); }
  156. ;
  157. mremember: /* NULL */ /* start a partial lexical scope */
  158. { $$ = block_start(FALSE); }
  159. ;
  160. /* A collection of &quot;lines&quot; in the program */
  161. lineseq : /* NULL */
  162. { $$ = Nullop; }
  163. | lineseq decl
  164. { $$ = $1; }
  165. | lineseq line
  166. { $$ = append_list(OP_LINESEQ,
  167. (LISTOP*)$1, (LISTOP*)$2);
  168. PL_pad_reset_pending = TRUE;
  169. if ($1 &amp;&amp; $2) PL_hints |= HINT_BLOCK_SCOPE; }
  170. ;
  171. /* A &quot;line&quot; in the program */
  172. line : label cond
  173. { $$ = newSTATEOP(0, $1, $2); }
  174. | loop /* loops add their own labels */
  175. | label ';'
  176. { if ($1 != Nullch) {
  177. $$ = newSTATEOP(0, $1, newOP(OP_NULL, 0));
  178. }
  179. else {
  180. $$ = Nullop;
  181. PL_copline = NOLINE;
  182. }
  183. PL_expect = XSTATE; }
  184. | label sideff ';'
  185. { $$ = newSTATEOP(0, $1, $2);
  186. PL_expect = XSTATE; }
  187. ;
  188. /* An expression which may have a side-effect */
  189. sideff : error
  190. { $$ = Nullop; }
  191. | expr
  192. { $$ = $1; }
  193. | expr IF expr
  194. { $$ = newLOGOP(OP_AND, 0, $3, $1); }
  195. | expr UNLESS expr
  196. { $$ = newLOGOP(OP_OR, 0, $3, $1); }
  197. | expr WHILE expr
  198. { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); }
  199. | expr UNTIL iexpr
  200. { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);}
  201. | expr FOR expr
  202. { $$ = newFOROP(0, Nullch, (line_t)$2,
  203. Nullop, $3, $1, Nullop); }
  204. ;
  205. /* else and elsif blocks */
  206. else : /* NULL */
  207. { $$ = Nullop; }
  208. | ELSE mblock
  209. { ($2)-&gt;op_flags |= OPf_PARENS; $$ = scope($2); }
  210. | ELSIF '(' mexpr ')' mblock else
  211. { PL_copline = (line_t)$1;
  212. $$ = newCONDOP(0, $3, scope($5), $6);
  213. PL_hints |= HINT_BLOCK_SCOPE; }
  214. ;
  215. /* Real conditional expressions */
  216. cond : IF '(' remember mexpr ')' mblock else
  217. { PL_copline = (line_t)$1;
  218. $$ = block_end($3,
  219. newCONDOP(0, $4, scope($6), $7)); }
  220. | UNLESS '(' remember miexpr ')' mblock else
  221. { PL_copline = (line_t)$1;
  222. $$ = block_end($3,
  223. newCONDOP(0, $4, scope($6), $7)); }
  224. ;
  225. /* Continue blocks */
  226. cont : /* NULL */
  227. { $$ = Nullop; }
  228. | CONTINUE block
  229. { $$ = scope($2); }
  230. ;
  231. /* Loops: while, until, for, and a bare block */
  232. loop : label WHILE '(' remember mtexpr ')' mblock cont
  233. { PL_copline = (line_t)$2;
  234. $$ = block_end($4,
  235. newSTATEOP(0, $1,
  236. newWHILEOP(0, 1, (LOOP*)Nullop,
  237. $2, $5, $7, $8))); }
  238. | label UNTIL '(' remember miexpr ')' mblock cont
  239. { PL_copline = (line_t)$2;
  240. $$ = block_end($4,
  241. newSTATEOP(0, $1,
  242. newWHILEOP(0, 1, (LOOP*)Nullop,
  243. $2, $5, $7, $8))); }
  244. | label FOR MY remember my_scalar '(' mexpr ')' mblock cont
  245. { $$ = block_end($4,
  246. newFOROP(0, $1, (line_t)$2, $5, $7, $9, $10)); }
  247. | label FOR scalar '(' remember mexpr ')' mblock cont
  248. { $$ = block_end($5,
  249. newFOROP(0, $1, (line_t)$2, mod($3, OP_ENTERLOOP),
  250. $6, $8, $9)); }
  251. | label FOR '(' remember mexpr ')' mblock cont
  252. { $$ = block_end($4,
  253. newFOROP(0, $1, (line_t)$2, Nullop, $5, $7, $8)); }
  254. | label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock
  255. /* basically fake up an initialize-while lineseq */
  256. { OP *forop;
  257. PL_copline = (line_t)$2;
  258. forop = newSTATEOP(0, $1,
  259. newWHILEOP(0, 1, (LOOP*)Nullop,
  260. $2, scalar($7),
  261. $11, $9));
  262. if ($5) {
  263. forop = append_elem(OP_LINESEQ,
  264. newSTATEOP(0, ($1?savepv($1):Nullch),
  265. $5),
  266. forop);
  267. }
  268. $$ = block_end($4, forop); }
  269. | label block cont /* a block is a loop that happens once */
  270. { $$ = newSTATEOP(0, $1,
  271. newWHILEOP(0, 1, (LOOP*)Nullop,
  272. NOLINE, Nullop, $2, $3)); }
  273. ;
  274. /* Normal expression */
  275. nexpr : /* NULL */
  276. { $$ = Nullop; }
  277. | sideff
  278. ;
  279. /* Boolean expression */
  280. texpr : /* NULL means true */
  281. { (void)scan_num(&quot;1&quot;, &amp;yylval); $$ = yylval.opval; }
  282. | expr
  283. ;
  284. /* Inverted boolean expression */
  285. iexpr : expr
  286. { $$ = invert(scalar($1)); }
  287. ;
  288. /* Expression with its own lexical scope */
  289. mexpr : expr
  290. { $$ = $1; intro_my(); }
  291. ;
  292. mnexpr : nexpr
  293. { $$ = $1; intro_my(); }
  294. ;
  295. mtexpr : texpr
  296. { $$ = $1; intro_my(); }
  297. ;
  298. miexpr : iexpr
  299. { $$ = $1; intro_my(); }
  300. ;
  301. /* Optional &quot;MAIN:&quot;-style loop labels */
  302. label : /* empty */
  303. { $$ = Nullch; }
  304. | LABEL
  305. ;
  306. /* Some kind of declaration - does not take part in the parse tree */
  307. decl : format
  308. { $$ = 0; }
  309. | subrout
  310. { $$ = 0; }
  311. | mysubrout
  312. { $$ = 0; }
  313. | package
  314. { $$ = 0; }
  315. | use
  316. { $$ = 0; }
  317. ;
  318. format : FORMAT startformsub formname block
  319. { newFORM($2, $3, $4); }
  320. ;
  321. formname: WORD { $$ = $1; }
  322. | /* NULL */ { $$ = Nullop; }
  323. ;
  324. /* Unimplemented &quot;my sub foo { }&quot; */
  325. mysubrout: MYSUB startsub subname proto subattrlist subbody
  326. { newMYSUB($2, $3, $4, $5, $6); }
  327. ;
  328. /* Subroutine definition */
  329. subrout : SUB startsub subname proto subattrlist subbody
  330. { newATTRSUB($2, $3, $4, $5, $6); }
  331. ;
  332. startsub: /* NULL */ /* start a regular subroutine scope */
  333. { $$ = start_subparse(FALSE, 0); }
  334. ;
  335. startanonsub: /* NULL */ /* start an anonymous subroutine scope */
  336. { $$ = start_subparse(FALSE, CVf_ANON); }
  337. ;
  338. startformsub: /* NULL */ /* start a format subroutine scope */
  339. { $$ = start_subparse(TRUE, 0); }
  340. ;
  341. /* Name of a subroutine - must be a bareword, could be special */
  342. subname : WORD { STRLEN n_a; char *name = SvPV(((SVOP*)$1)-&gt;op_sv,n_a);
  343. if (strEQ(name, &quot;BEGIN&quot;) || strEQ(name, &quot;END&quot;)
  344. || strEQ(name, &quot;INIT&quot;) || strEQ(name, &quot;CHECK&quot;))
  345. CvSPECIAL_on(PL_compcv);
  346. $$ = $1; }
  347. ;
  348. /* Subroutine prototype */
  349. proto : /* NULL */
  350. { $$ = Nullop; }
  351. | THING
  352. ;
  353. /* Optional list of subroutine attributes */
  354. subattrlist: /* NULL */
  355. { $$ = Nullop; }
  356. | COLONATTR THING
  357. { $$ = $2; }
  358. | COLONATTR
  359. { $$ = Nullop; }
  360. ;
  361. /* List of attributes for a &quot;my&quot; variable declaration */
  362. myattrlist: COLONATTR THING
  363. { $$ = $2; }
  364. | COLONATTR
  365. { $$ = Nullop; }
  366. ;
  367. /* Subroutine body - either null or a block */
  368. subbody : block { $$ = $1; }
  369. | ';' { $$ = Nullop; PL_expect = XSTATE; }
  370. ;
  371. package : PACKAGE WORD ';'
  372. { package($2); }
  373. | PACKAGE ';'
  374. { package(Nullop); }
  375. ;
  376. use : USE startsub
  377. { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
  378. WORD WORD listexpr ';'
  379. { utilize($1, $2, $4, $5, $6); }
  380. ;
  381. /* Ordinary expressions; logical combinations */
  382. expr : expr ANDOP expr
  383. { $$ = newLOGOP(OP_AND, 0, $1, $3); }
  384. | expr OROP expr
  385. { $$ = newLOGOP($2, 0, $1, $3); }
  386. | argexpr %prec PREC_LOW
  387. ;
  388. /* Expressions are a list of terms joined by commas */
  389. argexpr : argexpr ','
  390. { $$ = $1; }
  391. | argexpr ',' term
  392. { $$ = append_elem(OP_LIST, $1, $3); }
  393. | term %prec PREC_LOW
  394. ;
  395. /* List operators */
  396. listop : LSTOP indirob argexpr /* print $fh @args */
  397. { $$ = convert($1, OPf_STACKED,
  398. prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); }
  399. | FUNC '(' indirob expr ')' /* print ($fh @args */
  400. { $$ = convert($1, OPf_STACKED,
  401. prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); }
  402. | term ARROW method '(' listexprcom ')' /* $foo-&gt;bar(list) */
  403. { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  404. append_elem(OP_LIST,
  405. prepend_elem(OP_LIST, scalar($1), $5),
  406. newUNOP(OP_METHOD, 0, $3))); }
  407. | term ARROW method /* $foo-&gt;bar */
  408. { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  409. append_elem(OP_LIST, scalar($1),
  410. newUNOP(OP_METHOD, 0, $3))); }
  411. | METHOD indirob listexpr /* new Class @args */
  412. { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  413. append_elem(OP_LIST,
  414. prepend_elem(OP_LIST, $2, $3),
  415. newUNOP(OP_METHOD, 0, $1))); }
  416. | FUNCMETH indirob '(' listexprcom ')' /* method $object (@args) */
  417. { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  418. append_elem(OP_LIST,
  419. prepend_elem(OP_LIST, $2, $4),
  420. newUNOP(OP_METHOD, 0, $1))); }
  421. | LSTOP listexpr /* print @args */
  422. { $$ = convert($1, 0, $2); }
  423. | FUNC '(' listexprcom ')' /* print (@args) */
  424. { $$ = convert($1, 0, $3); }
  425. | LSTOPSUB startanonsub block /* map { foo } ... */
  426. { $3 = newANONATTRSUB($2, 0, Nullop, $3); }
  427. listexpr %prec LSTOP /* ... @bar */
  428. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  429. append_elem(OP_LIST,
  430. prepend_elem(OP_LIST, $3, $5), $1)); }
  431. ;
  432. /* Names of methods. May use $object-&gt;$methodname */
  433. method : METHOD
  434. | scalar
  435. ;
  436. /* Some kind of subscripted expression */
  437. subscripted: star '{' expr ';' '}' /* *main::{something} */
  438. /* In this and all the hash accessors, ';' is
  439. * provided by the tokeniser */
  440. { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3)); }
  441. | scalar '[' expr ']' /* $array[$element] */
  442. { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); }
  443. | term ARROW '[' expr ']' /* somearef-&gt;[$element] */
  444. { $$ = newBINOP(OP_AELEM, 0,
  445. ref(newAVREF($1),OP_RV2AV),
  446. scalar($4));}
  447. | subscripted '[' expr ']' /* $foo-&gt;[$bar]-&gt;[$baz] */
  448. { $$ = newBINOP(OP_AELEM, 0,
  449. ref(newAVREF($1),OP_RV2AV),
  450. scalar($3));}
  451. | scalar '{' expr ';' '}' /* $foo-&gt;{bar();} */
  452. { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
  453. PL_expect = XOPERATOR; }
  454. | term ARROW '{' expr ';' '}' /* somehref-&gt;{bar();} */
  455. { $$ = newBINOP(OP_HELEM, 0,
  456. ref(newHVREF($1),OP_RV2HV),
  457. jmaybe($4));
  458. PL_expect = XOPERATOR; }
  459. | subscripted '{' expr ';' '}' /* $foo-&gt;[bar]-&gt;{baz;} */
  460. { $$ = newBINOP(OP_HELEM, 0,
  461. ref(newHVREF($1),OP_RV2HV),
  462. jmaybe($3));
  463. PL_expect = XOPERATOR; }
  464. | term ARROW '(' ')' /* $subref-&gt;() */
  465. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  466. newCVREF(0, scalar($1))); }
  467. | term ARROW '(' expr ')' /* $subref-&gt;(@args) */
  468. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  469. append_elem(OP_LIST, $4,
  470. newCVREF(0, scalar($1)))); }
  471. | subscripted '(' expr ')' /* $foo-&gt;{bar}-&gt;(@args) */
  472. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  473. append_elem(OP_LIST, $3,
  474. newCVREF(0, scalar($1)))); }
  475. | subscripted '(' ')' /* $foo-&gt;{bar}-&gt;() */
  476. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  477. newCVREF(0, scalar($1))); }
  478. ;
  479. /* Binary operators between terms */
  480. termbinop : term ASSIGNOP term /* $x = $y */
  481. { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); }
  482. | term POWOP term /* $x ** $y */
  483. { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  484. | term MULOP term /* $x * $y, $x x $y */
  485. { if ($2 != OP_REPEAT)
  486. scalar($1);
  487. $$ = newBINOP($2, 0, $1, scalar($3)); }
  488. | term ADDOP term /* $x + $y */
  489. { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  490. | term SHIFTOP term /* $x &gt;&gt; $y, $x &lt;&lt; $y */
  491. { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  492. | term RELOP term /* $x &gt; $y, etc. */
  493. { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  494. | term EQOP term /* $x == $y, $x eq $y */
  495. { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  496. | term BITANDOP term /* $x &amp; $y */
  497. { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  498. | term BITOROP term /* $x | $y */
  499. { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  500. | term DOTDOT term /* $x..$y, $x...$y */
  501. { $$ = newRANGE($2, scalar($1), scalar($3));}
  502. | term ANDAND term /* $x &amp;&amp; $y */
  503. { $$ = newLOGOP(OP_AND, 0, $1, $3); }
  504. | term OROR term /* $x || $y */
  505. { $$ = newLOGOP(OP_OR, 0, $1, $3); }
  506. | term MATCHOP term /* $x =~ /$y/ */
  507. { $$ = bind_match($2, $1, $3); }
  508. ;
  509. /* Unary operators and terms */
  510. termunop : '-' term %prec UMINUS /* -$x */
  511. { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
  512. | '+' term %prec UMINUS /* +$x */
  513. { $$ = $2; }
  514. | '!' term /* !$x */
  515. { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
  516. | '~' term /* ~$x */
  517. { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));}
  518. | term POSTINC /* $x++ */
  519. { $$ = newUNOP(OP_POSTINC, 0,
  520. mod(scalar($1), OP_POSTINC)); }
  521. | term POSTDEC /* $x-- */
  522. { $$ = newUNOP(OP_POSTDEC, 0,
  523. mod(scalar($1), OP_POSTDEC)); }
  524. | PREINC term /* ++$x */
  525. { $$ = newUNOP(OP_PREINC, 0,
  526. mod(scalar($2), OP_PREINC)); }
  527. | PREDEC term /* --$x */
  528. { $$ = newUNOP(OP_PREDEC, 0,
  529. mod(scalar($2), OP_PREDEC)); }
  530. ;
  531. /* Constructors for anonymous data */
  532. anonymous: '[' expr ']'
  533. { $$ = newANONLIST($2); }
  534. | '[' ']'
  535. { $$ = newANONLIST(Nullop); }
  536. | HASHBRACK expr ';' '}' %prec '(' /* { foo =&gt; &quot;Bar&quot; } */
  537. { $$ = newANONHASH($2); }
  538. | HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */
  539. { $$ = newANONHASH(Nullop); }
  540. | ANONSUB startanonsub proto subattrlist block %prec '('
  541. { $$ = newANONATTRSUB($2, $3, $4, $5); }
  542. ;
  543. /* Things called with &quot;do&quot; */
  544. termdo : DO term %prec UNIOP /* do $filename */
  545. { $$ = dofile($2); }
  546. | DO block %prec '(' /* do { code */
  547. { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
  548. | DO WORD '(' ')' /* do somesub() */
  549. { $$ = newUNOP(OP_ENTERSUB,
  550. OPf_SPECIAL|OPf_STACKED,
  551. prepend_elem(OP_LIST,
  552. scalar(newCVREF(
  553. (OPpENTERSUB_AMPER&lt;&lt;8),
  554. scalar($2)
  555. )),Nullop)); dep();}
  556. | DO WORD '(' expr ')' /* do somesub(@args) */
  557. { $$ = newUNOP(OP_ENTERSUB,
  558. OPf_SPECIAL|OPf_STACKED,
  559. append_elem(OP_LIST,
  560. $4,
  561. scalar(newCVREF(
  562. (OPpENTERSUB_AMPER&lt;&lt;8),
  563. scalar($2)
  564. )))); dep();}
  565. | DO scalar '(' ')' /* do $subref () */
  566. { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
  567. prepend_elem(OP_LIST,
  568. scalar(newCVREF(0,scalar($2))), Nullop)); dep();}
  569. | DO scalar '(' expr ')' /* do $subref (@args) */
  570. { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
  571. prepend_elem(OP_LIST,
  572. $4,
  573. scalar(newCVREF(0,scalar($2))))); dep();}
  574. ;
  575. term : termbinop
  576. | termunop
  577. | anonymous
  578. | termdo
  579. | term '?' term ':' term
  580. { $$ = newCONDOP(0, $1, $3, $5); }
  581. | REFGEN term /* \$x, \@y, \%z */
  582. { $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN)); }
  583. | myattrterm %prec UNIOP
  584. { $$ = $1; }
  585. | LOCAL term %prec UNIOP
  586. { $$ = localize($2,$1); }
  587. | '(' expr ')'
  588. { $$ = sawparens($2); }
  589. | '(' ')'
  590. { $$ = sawparens(newNULLLIST()); }
  591. | scalar %prec '('
  592. { $$ = $1; }
  593. | star %prec '('
  594. { $$ = $1; }
  595. | hsh %prec '('
  596. { $$ = $1; }
  597. | ary %prec '('
  598. { $$ = $1; }
  599. | arylen %prec '(' /* $#x, $#{ something } */
  600. { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
  601. | subscripted
  602. { $$ = $1; }
  603. | '(' expr ')' '[' expr ']' /* list slice */
  604. { $$ = newSLICEOP(0, $5, $2); }
  605. | '(' ')' '[' expr ']' /* empty list slice! */
  606. { $$ = newSLICEOP(0, $4, Nullop); }
  607. | ary '[' expr ']' /* array slice */
  608. { $$ = prepend_elem(OP_ASLICE,
  609. newOP(OP_PUSHMARK, 0),
  610. newLISTOP(OP_ASLICE, 0,
  611. list($3),
  612. ref($1, OP_ASLICE))); }
  613. | ary '{' expr ';' '}' /* @hash{@keys} */
  614. { $$ = prepend_elem(OP_HSLICE,
  615. newOP(OP_PUSHMARK, 0),
  616. newLISTOP(OP_HSLICE, 0,
  617. list($3),
  618. ref(oopsHV($1), OP_HSLICE)));
  619. PL_expect = XOPERATOR; }
  620. | THING %prec '('
  621. { $$ = $1; }
  622. | amper /* &amp;foo; */
  623. { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
  624. | amper '(' ')' /* &amp;foo() */
  625. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
  626. | amper '(' expr ')' /* &amp;foo(@args) */
  627. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  628. append_elem(OP_LIST, $3, scalar($1))); }
  629. | NOAMP WORD listexpr /* foo(@args) */
  630. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  631. append_elem(OP_LIST, $3, scalar($2))); }
  632. | LOOPEX /* loop exiting command (goto, last, dump, etc) */
  633. { $$ = newOP($1, OPf_SPECIAL);
  634. PL_hints |= HINT_BLOCK_SCOPE; }
  635. | LOOPEX term
  636. { $$ = newLOOPEX($1,$2); }
  637. | NOTOP argexpr /* not $foo */
  638. { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
  639. | UNIOP /* Unary op, $_ implied */
  640. { $$ = newOP($1, 0); }
  641. | UNIOP block /* eval { foo }, I *think* */
  642. { $$ = newUNOP($1, 0, $2); }
  643. | UNIOP term /* Unary op */
  644. { $$ = newUNOP($1, 0, $2); }
  645. | UNIOPSUB term /* Sub treated as unop */
  646. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  647. append_elem(OP_LIST, $2, scalar($1))); }
  648. | FUNC0 /* Nullary operator */
  649. { $$ = newOP($1, 0); }
  650. | FUNC0 '(' ')'
  651. { $$ = newOP($1, 0); }
  652. | FUNC0SUB /* Sub treated as nullop */
  653. { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  654. scalar($1)); }
  655. | FUNC1 '(' ')' /* not () */
  656. { $$ = newOP($1, OPf_SPECIAL); }
  657. | FUNC1 '(' expr ')' /* not($foo) */
  658. { $$ = newUNOP($1, 0, $3); }
  659. | PMFUNC '(' term ')' /* split (/foo/) */
  660. { $$ = pmruntime($1, $3, Nullop); }
  661. | PMFUNC '(' term ',' term ')' /* split (/foo/,$bar) */
  662. { $$ = pmruntime($1, $3, $5); }
  663. | WORD
  664. | listop
  665. ;
  666. /* &quot;my&quot; declarations, with optional attributes */
  667. myattrterm: MY myterm myattrlist
  668. { $$ = my_attrs($2,$3); }
  669. | MY myterm
  670. { $$ = localize($2,$1); }
  671. ;
  672. /* Things that can be &quot;my&quot;'d */
  673. myterm : '(' expr ')'
  674. { $$ = sawparens($2); }
  675. | '(' ')'
  676. { $$ = sawparens(newNULLLIST()); }
  677. | scalar %prec '('
  678. { $$ = $1; }
  679. | hsh %prec '('
  680. { $$ = $1; }
  681. | ary %prec '('
  682. { $$ = $1; }
  683. ;
  684. /* Basic list expressions */
  685. listexpr: /* NULL */ %prec PREC_LOW
  686. { $$ = Nullop; }
  687. | argexpr %prec PREC_LOW
  688. { $$ = $1; }
  689. ;
  690. listexprcom: /* NULL */
  691. { $$ = Nullop; }
  692. | expr
  693. { $$ = $1; }
  694. | expr ','
  695. { $$ = $1; }
  696. ;
  697. /* A little bit of trickery to make &quot;for my $foo (@bar)&quot; actually be
  698. lexical */
  699. my_scalar: scalar
  700. { PL_in_my = 0; $$ = my($1); }
  701. ;
  702. amper : '&amp;' indirob
  703. { $$ = newCVREF($1,$2); }
  704. ;
  705. scalar : '$' indirob
  706. { $$ = newSVREF($2); }
  707. ;
  708. ary : '@' indirob
  709. { $$ = newAVREF($2); }
  710. ;
  711. hsh : '%' indirob
  712. { $$ = newHVREF($2); }
  713. ;
  714. arylen : DOLSHARP indirob
  715. { $$ = newAVREF($2); }
  716. ;
  717. star : '*' indirob
  718. { $$ = newGVREF(0,$2); }
  719. ;
  720. /* Indirect objects */
  721. indirob : WORD
  722. { $$ = scalar($1); }
  723. | scalar %prec PREC_LOW
  724. { $$ = scalar($1); }
  725. | block
  726. { $$ = scope($1); }
  727. | PRIVATEREF
  728. { $$ = $1; }
  729. ;
  730. %% /* PROGRAM */
  731. /* more stuff added to make perly_c.diff easier to apply */
  732. #ifdef yyparse
  733. #undef yyparse
  734. #endif
  735. #define yyparse() Perl_yyparse(pTHX)
  736. </pre>
  737. <hr />
  738. </body></html>