home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / perl-5.003-base.tgz / perl-5.003-base.tar / fsf / perl / perly.y < prev    next >
Text File  |  1996-02-14  |  14KB  |  572 lines

  1. /*    perly.y
  2.  *
  3.  *    Copyright (c) 1991-1994, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  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 that wander are lost.'
  13.  */
  14.  
  15. %{
  16. #include "EXTERN.h"
  17. #include "perl.h"
  18.  
  19. static void
  20. dep()
  21. {
  22.     deprecate("\"do\" to call subroutines");
  23. }
  24.  
  25. %}
  26.  
  27. %start prog
  28.  
  29. %union {
  30.     I32    ival;
  31.     char *pval;
  32.     OP *opval;
  33.     GV *gvval;
  34. }
  35.  
  36. %token <ival> '{' ')'
  37.  
  38. %token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
  39. %token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
  40. %token <pval> LABEL
  41. %token <ival> FORMAT SUB ANONSUB PACKAGE USE
  42. %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
  43. %token <ival> LOOPEX DOTDOT
  44. %token <ival> FUNC0 FUNC1 FUNC
  45. %token <ival> RELOP EQOP MULOP ADDOP
  46. %token <ival> DOLSHARP DO LOCAL HASHBRACK NOAMP
  47.  
  48. %type <ival> prog decl format remember startsub '&'
  49. %type <opval> block lineseq line loop cond nexpr else argexpr
  50. %type <opval> expr term scalar ary hsh arylen star amper sideff
  51. %type <opval> listexpr listexprcom indirob
  52. %type <opval> texpr listop method proto
  53. %type <pval> label
  54. %type <opval> cont
  55.  
  56. %left <ival> OROP
  57. %left ANDOP
  58. %right NOTOP
  59. %nonassoc <ival> LSTOP
  60. %left ','
  61. %right <ival> ASSIGNOP
  62. %right '?' ':'
  63. %nonassoc DOTDOT
  64. %left OROR
  65. %left ANDAND
  66. %left <ival> BITOROP
  67. %left <ival> BITANDOP
  68. %nonassoc EQOP
  69. %nonassoc RELOP
  70. %nonassoc <ival> UNIOP
  71. %left <ival> SHIFTOP
  72. %left ADDOP
  73. %left MULOP
  74. %left <ival> MATCHOP
  75. %right '!' '~' UMINUS REFGEN
  76. %right <ival> POWOP
  77. %nonassoc PREINC PREDEC POSTINC POSTDEC
  78. %left ARROW
  79. %left '('
  80.  
  81. %% /* RULES */
  82.  
  83. prog    :    /* NULL */
  84.         {
  85. #if defined(YYDEBUG) && defined(DEBUGGING)
  86.             yydebug = (debug & 1);
  87. #endif
  88.             expect = XSTATE;
  89.         }
  90.     /*CONTINUED*/    lineseq
  91.             { newPROG($2); }
  92.     ;
  93.  
  94. block    :    '{' remember lineseq '}'
  95.             { $$ = block_end($1,$2,$3); }
  96.     ;
  97.  
  98. remember:    /* NULL */    /* start a lexical scope */
  99.             { $$ = block_start(); }
  100.     ;
  101.  
  102. lineseq    :    /* NULL */
  103.             { $$ = Nullop; }
  104.     |    lineseq decl
  105.             { $$ = $1; }
  106.     |    lineseq line
  107.             {   $$ = append_list(OP_LINESEQ,
  108.                 (LISTOP*)$1, (LISTOP*)$2);
  109.                 pad_reset_pending = TRUE;
  110.                 if ($1 && $2) hints |= HINT_BLOCK_SCOPE; }
  111.     ;
  112.  
  113. line    :    label cond
  114.             { $$ = newSTATEOP(0, $1, $2); }
  115.     |    loop    /* loops add their own labels */
  116.     |    label ';'
  117.             { if ($1 != Nullch) {
  118.                   $$ = newSTATEOP(0, $1, newOP(OP_NULL, 0));
  119.                 }
  120.                 else {
  121.                   $$ = Nullop;
  122.                   copline = NOLINE;
  123.                 }
  124.                 expect = XSTATE; }
  125.     |    label sideff ';'
  126.             { $$ = newSTATEOP(0, $1, $2);
  127.               expect = XSTATE; }
  128.     ;
  129.  
  130. sideff    :    error
  131.             { $$ = Nullop; }
  132.     |    expr
  133.             { $$ = $1; }
  134.     |    expr IF expr
  135.             { $$ = newLOGOP(OP_AND, 0, $3, $1); }
  136.     |    expr UNLESS expr
  137.             { $$ = newLOGOP(OP_OR, 0, $3, $1); }
  138.     |    expr WHILE expr
  139.             { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); }
  140.     |    expr UNTIL expr
  141.             { $$ = newLOOPOP(OPf_PARENS, 1, invert(scalar($3)), $1);}
  142.     ;
  143.  
  144. else    :    /* NULL */
  145.             { $$ = Nullop; }
  146.     |    ELSE block
  147.             { $$ = scope($2); }
  148.     |    ELSIF '(' expr ')' block else
  149.             { copline = $1;
  150.                 $$ = newSTATEOP(0, 0,
  151.                 newCONDOP(0, $3, scope($5), $6));
  152.                 hints |= HINT_BLOCK_SCOPE; }
  153.     ;
  154.  
  155. cond    :    IF '(' expr ')' block else
  156.             { copline = $1;
  157.                 $$ = newCONDOP(0, $3, scope($5), $6); }
  158.     |    UNLESS '(' expr ')' block else
  159.             { copline = $1;
  160.                 $$ = newCONDOP(0,
  161.                 invert(scalar($3)), scope($5), $6); }
  162.     |    IF block block else
  163.             { copline = $1;
  164.                 deprecate("if BLOCK BLOCK");
  165.                 $$ = newCONDOP(0, scope($2), scope($3), $4); }
  166.     |    UNLESS block block else
  167.             { copline = $1;
  168.                 deprecate("unless BLOCK BLOCK");
  169.                 $$ = newCONDOP(0, invert(scalar(scope($2))),
  170.                         scope($3), $4); }
  171.     ;
  172.  
  173. cont    :    /* NULL */
  174.             { $$ = Nullop; }
  175.     |    CONTINUE block
  176.             { $$ = scope($2); }
  177.     ;
  178.  
  179. loop    :    label WHILE '(' texpr ')' block cont
  180.             { copline = $2;
  181.                 $$ = newSTATEOP(0, $1,
  182.                     newWHILEOP(0, 1, (LOOP*)Nullop,
  183.                     $4, $6, $7) ); }
  184.     |    label UNTIL '(' expr ')' block cont
  185.             { copline = $2;
  186.                 $$ = newSTATEOP(0, $1,
  187.                     newWHILEOP(0, 1, (LOOP*)Nullop,
  188.                     invert(scalar($4)), $6, $7) ); }
  189.     |    label WHILE block block cont
  190.             { copline = $2;
  191.                 $$ = newSTATEOP(0, $1,
  192.                     newWHILEOP(0, 1, (LOOP*)Nullop,
  193.                     scope($3), $4, $5) ); }
  194.     |    label UNTIL block block cont
  195.             { copline = $2;
  196.                 $$ = newSTATEOP(0, $1,
  197.                     newWHILEOP(0, 1, (LOOP*)Nullop,
  198.                     invert(scalar(scope($3))), $4, $5)); }
  199.     |    label FOR scalar '(' expr ')' block cont
  200.             { $$ = newFOROP(0, $1, $2, mod($3, OP_ENTERLOOP),
  201.                 $5, $7, $8); }
  202.     |    label FOR '(' expr ')' block cont
  203.             { $$ = newFOROP(0, $1, $2, Nullop, $4, $6, $7); }
  204.     |    label FOR '(' nexpr ';' texpr ';' nexpr ')' block
  205.             /* basically fake up an initialize-while lineseq */
  206.             {  copline = $2;
  207.                 $$ = append_elem(OP_LINESEQ,
  208.                     newSTATEOP(0, $1, scalar($4)),
  209.                     newSTATEOP(0, $1,
  210.                     newWHILEOP(0, 1, (LOOP*)Nullop,
  211.                         scalar($6), $10, scalar($8)) )); }
  212.     |    label block cont  /* a block is a loop that happens once */
  213.             { $$ = newSTATEOP(0,
  214.                 $1, newWHILEOP(0, 1, (LOOP*)Nullop,
  215.                     Nullop, $2, $3)); }
  216.     ;
  217.  
  218. nexpr    :    /* NULL */
  219.             { $$ = Nullop; }
  220.     |    sideff
  221.     ;
  222.  
  223. texpr    :    /* NULL means true */
  224.             { (void)scan_num("1"); $$ = yylval.opval; }
  225.     |    expr
  226.     ;
  227.  
  228. label    :    /* empty */
  229.             { $$ = Nullch; }
  230.     |    LABEL
  231.     ;
  232.  
  233. decl    :    format
  234.             { $$ = 0; }
  235.     |    subrout
  236.             { $$ = 0; }
  237.     |    package
  238.             { $$ = 0; }
  239.     |    use
  240.             { $$ = 0; }
  241.     ;
  242.  
  243. format    :    FORMAT startsub WORD block
  244.             { newFORM($2, $3, $4); }
  245.     |    FORMAT startsub block
  246.             { newFORM($2, Nullop, $3); }
  247.     ;
  248.  
  249. subrout    :    SUB startsub WORD proto block
  250.             { newSUB($2, $3, $4, $5); }
  251.     |    SUB startsub WORD proto ';'
  252.             { newSUB($2, $3, $4, Nullop); expect = XSTATE; }
  253.     ;
  254.  
  255. proto    :    /* NULL */
  256.             { $$ = Nullop; }
  257.     |    THING
  258.     ;
  259.         
  260. startsub:    /* NULL */    /* start a subroutine scope */
  261.             { $$ = start_subparse(); }
  262.     ;
  263.  
  264. package :    PACKAGE WORD ';'
  265.             { package($2); }
  266.     |    PACKAGE ';'
  267.             { package(Nullop); }
  268.     ;
  269.  
  270. use    :    USE startsub WORD listexpr ';'
  271.             { utilize($1, $2, $3, $4); }
  272.     ;
  273.  
  274. expr    :    expr ANDOP expr
  275.             { $$ = newLOGOP(OP_AND, 0, $1, $3); }
  276.     |    expr OROP expr
  277.             { $$ = newLOGOP($2, 0, $1, $3); }
  278.     |    argexpr
  279.     ;
  280.  
  281. argexpr    :    argexpr ','
  282.             { $$ = $1; }
  283.     |    argexpr ',' term
  284.             { $$ = append_elem(OP_LIST, $1, $3); }
  285.     |    term
  286.     ;
  287.  
  288. listop    :    LSTOP indirob argexpr
  289.             { $$ = convert($1, OPf_STACKED,
  290.                 prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); }
  291.     |    FUNC '(' indirob expr ')'
  292.             { $$ = convert($1, OPf_STACKED,
  293.                 prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); }
  294.     |    term ARROW method '(' listexprcom ')'
  295.             { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  296.                 append_elem(OP_LIST,
  297.                     prepend_elem(OP_LIST, $1, $5),
  298.                     newUNOP(OP_METHOD, 0, $3))); }
  299.     |    METHOD indirob listexpr
  300.             { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  301.                 append_elem(OP_LIST,
  302.                     prepend_elem(OP_LIST, $2, $3),
  303.                     newUNOP(OP_METHOD, 0, $1))); }
  304.     |    FUNCMETH indirob '(' listexprcom ')'
  305.             { $$ = convert(OP_ENTERSUB, OPf_STACKED,
  306.                 append_elem(OP_LIST,
  307.                     prepend_elem(OP_LIST, $2, $4),
  308.                     newUNOP(OP_METHOD, 0, $1))); }
  309.     |    LSTOP listexpr
  310.             { $$ = convert($1, 0, $2); }
  311.     |    FUNC '(' listexprcom ')'
  312.             { $$ = convert($1, 0, $3); }
  313.     |    LSTOPSUB startsub block listexpr    %prec LSTOP
  314.             { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  315.                 append_elem(OP_LIST,
  316.                   prepend_elem(OP_LIST, newANONSUB($2, 0, $3), $4),
  317.                   $1)); }
  318.     ;
  319.  
  320. method    :    METHOD
  321.     |    scalar
  322.     ;
  323.  
  324. term    :    term ASSIGNOP term
  325.             { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); }
  326.     |    term POWOP term
  327.             { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  328.     |    term MULOP term
  329.             {   if ($2 != OP_REPEAT)
  330.                 scalar($1);
  331.                 $$ = newBINOP($2, 0, $1, scalar($3)); }
  332.     |    term ADDOP term
  333.             { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  334.     |    term SHIFTOP term
  335.             { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  336.     |    term RELOP term
  337.             { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  338.     |    term EQOP term
  339.             { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  340.     |    term BITANDOP term
  341.             { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  342.     |    term BITOROP term
  343.             { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
  344.     |    term DOTDOT term
  345.             { $$ = newRANGE($2, scalar($1), scalar($3));}
  346.     |    term ANDAND term
  347.             { $$ = newLOGOP(OP_AND, 0, $1, $3); }
  348.     |    term OROR term
  349.             { $$ = newLOGOP(OP_OR, 0, $1, $3); }
  350.     |    term '?' term ':' term
  351.             { $$ = newCONDOP(0, $1, $3, $5); }
  352.     |    term MATCHOP term
  353.             { $$ = bind_match($2, $1, $3); }
  354.  
  355.     |    '-' term %prec UMINUS
  356.             { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
  357.     |    '+' term %prec UMINUS
  358.             { $$ = $2; }
  359.     |    '!' term
  360.             { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
  361.     |    '~' term
  362.             { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));}
  363.     |    REFGEN term
  364.             { $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN)); }
  365.     |    term POSTINC
  366.             { $$ = newUNOP(OP_POSTINC, 0,
  367.                     mod(scalar($1), OP_POSTINC)); }
  368.     |    term POSTDEC
  369.             { $$ = newUNOP(OP_POSTDEC, 0,
  370.                     mod(scalar($1), OP_POSTDEC)); }
  371.     |    PREINC term
  372.             { $$ = newUNOP(OP_PREINC, 0,
  373.                     mod(scalar($2), OP_PREINC)); }
  374.     |    PREDEC term
  375.             { $$ = newUNOP(OP_PREDEC, 0,
  376.                     mod(scalar($2), OP_PREDEC)); }
  377.     |    LOCAL term    %prec UNIOP
  378.             { $$ = localize($2,$1); }
  379.     |    '(' expr ')'
  380.             { $$ = sawparens($2); }
  381.     |    '(' ')'
  382.             { $$ = sawparens(newNULLLIST()); }
  383.     |    '[' expr ']'                %prec '('
  384.             { $$ = newANONLIST($2); }
  385.     |    '[' ']'                    %prec '('
  386.             { $$ = newANONLIST(Nullop); }
  387.     |    HASHBRACK expr ';' '}'            %prec '('
  388.             { $$ = newANONHASH($2); }
  389.     |    HASHBRACK ';' '}'                %prec '('
  390.             { $$ = newANONHASH(Nullop); }
  391.     |    ANONSUB startsub proto block            %prec '('
  392.             { $$ = newANONSUB($2, $3, $4); }
  393.     |    scalar    %prec '('
  394.             { $$ = $1; }
  395.     |    star '{' expr ';' '}'
  396.             { $$ = newBINOP(OP_GELEM, 0, newGVREF(0,$1), $3); }
  397.     |    star    %prec '('
  398.             { $$ = $1; }
  399.     |    scalar '[' expr ']'    %prec '('
  400.             { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); }
  401.     |    term ARROW '[' expr ']'    %prec '('
  402.             { $$ = newBINOP(OP_AELEM, 0,
  403.                     ref(newAVREF($1),OP_RV2AV),
  404.                     scalar($4));}
  405.     |    term '[' expr ']'    %prec '('
  406.             { assertref($1); $$ = newBINOP(OP_AELEM, 0,
  407.                     ref(newAVREF($1),OP_RV2AV),
  408.                     scalar($3));}
  409.     |    hsh     %prec '('
  410.             { $$ = $1; }
  411.     |    ary     %prec '('
  412.             { $$ = $1; }
  413.     |    arylen     %prec '('
  414.             { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
  415.     |    scalar '{' expr ';' '}'    %prec '('
  416.             { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
  417.                 expect = XOPERATOR; }
  418.     |    term ARROW '{' expr ';' '}'    %prec '('
  419.             { $$ = newBINOP(OP_HELEM, 0,
  420.                     ref(newHVREF($1),OP_RV2HV),
  421.                     jmaybe($4));
  422.                 expect = XOPERATOR; }
  423.     |    term '{' expr ';' '}'    %prec '('
  424.             { assertref($1); $$ = newBINOP(OP_HELEM, 0,
  425.                     ref(newHVREF($1),OP_RV2HV),
  426.                     jmaybe($3));
  427.                 expect = XOPERATOR; }
  428.     |    '(' expr ')' '[' expr ']'    %prec '('
  429.             { $$ = newSLICEOP(0, $5, $2); }
  430.     |    '(' ')' '[' expr ']'    %prec '('
  431.             { $$ = newSLICEOP(0, $4, Nullop); }
  432.     |    ary '[' expr ']'    %prec '('
  433.             { $$ = prepend_elem(OP_ASLICE,
  434.                 newOP(OP_PUSHMARK, 0),
  435.                     newLISTOP(OP_ASLICE, 0,
  436.                     list($3),
  437.                     ref($1, OP_ASLICE))); }
  438.     |    ary '{' expr ';' '}'    %prec '('
  439.             { $$ = prepend_elem(OP_HSLICE,
  440.                 newOP(OP_PUSHMARK, 0),
  441.                     newLISTOP(OP_HSLICE, 0,
  442.                     list($3),
  443.                     ref(oopsHV($1), OP_HSLICE)));
  444.                 expect = XOPERATOR; }
  445.     |    THING    %prec '('
  446.             { $$ = $1; }
  447.     |    amper
  448.             { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
  449.     |    amper '(' ')'
  450.             { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
  451.     |    amper '(' expr ')'
  452.             { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  453.                 append_elem(OP_LIST, $3, scalar($1))); }
  454.     |    NOAMP WORD listexpr
  455.             { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  456.                 append_elem(OP_LIST, $3, scalar($2))); }
  457.     |    DO term    %prec UNIOP
  458.             { $$ = newUNOP(OP_DOFILE, 0, scalar($2)); }
  459.     |    DO block    %prec '('
  460.             { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
  461.     |    DO WORD '(' ')'
  462.             { $$ = newUNOP(OP_ENTERSUB,
  463.                 OPf_SPECIAL|OPf_STACKED,
  464.                 prepend_elem(OP_LIST,
  465.                 scalar(newCVREF(
  466.                     (OPpENTERSUB_AMPER<<8),
  467.                     scalar($2)
  468.                 )),Nullop)); dep();}
  469.     |    DO WORD '(' expr ')'
  470.             { $$ = newUNOP(OP_ENTERSUB,
  471.                 OPf_SPECIAL|OPf_STACKED,
  472.                 append_elem(OP_LIST,
  473.                 $4,
  474.                 scalar(newCVREF(
  475.                     (OPpENTERSUB_AMPER<<8),
  476.                     scalar($2)
  477.                 )))); dep();}
  478.     |    DO scalar '(' ')'
  479.             { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
  480.                 prepend_elem(OP_LIST,
  481.                 scalar(newCVREF(0,scalar($2))), Nullop)); dep();}
  482.     |    DO scalar '(' expr ')'
  483.             { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
  484.                 prepend_elem(OP_LIST,
  485.                 $4,
  486.                 scalar(newCVREF(0,scalar($2))))); dep();}
  487.     |    LOOPEX
  488.             { $$ = newOP($1, OPf_SPECIAL);
  489.                 hints |= HINT_BLOCK_SCOPE; }
  490.     |    LOOPEX term
  491.             { $$ = newLOOPEX($1,$2); }
  492.     |    NOTOP argexpr
  493.             { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
  494.     |    UNIOP
  495.             { $$ = newOP($1, 0); }
  496.     |    UNIOP block
  497.             { $$ = newUNOP($1, 0, $2); }
  498.     |    UNIOP term
  499.             { $$ = newUNOP($1, 0, $2); }
  500.     |    UNIOPSUB term
  501.             { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
  502.                 append_elem(OP_LIST, $2, scalar($1))); }
  503.     |    FUNC0
  504.             { $$ = newOP($1, 0); }
  505.     |    FUNC0 '(' ')'
  506.             { $$ = newOP($1, 0); }
  507.     |    FUNC0SUB
  508.             { $$ = newUNOP(OP_ENTERSUB, 0,
  509.                 scalar($1)); }
  510.     |    FUNC1 '(' ')'
  511.             { $$ = newOP($1, OPf_SPECIAL); }
  512.     |    FUNC1 '(' expr ')'
  513.             { $$ = newUNOP($1, 0, $3); }
  514.     |    PMFUNC '(' term ')'
  515.             { $$ = pmruntime($1, $3, Nullop); }
  516.     |    PMFUNC '(' term ',' term ')'
  517.             { $$ = pmruntime($1, $3, $5); }
  518.     |    WORD
  519.     |    listop
  520.     ;
  521.  
  522. listexpr:    /* NULL */
  523.             { $$ = Nullop; }
  524.     |    argexpr
  525.             { $$ = $1; }
  526.     ;
  527.  
  528. listexprcom:    /* NULL */
  529.             { $$ = Nullop; }
  530.     |    expr
  531.             { $$ = $1; }
  532.     |    expr ','
  533.             { $$ = $1; }
  534.     ;
  535.  
  536. amper    :    '&' indirob
  537.             { $$ = newCVREF($1,$2); }
  538.     ;
  539.  
  540. scalar    :    '$' indirob
  541.             { $$ = newSVREF($2); }
  542.     ;
  543.  
  544. ary    :    '@' indirob
  545.             { $$ = newAVREF($2); }
  546.     ;
  547.  
  548. hsh    :    '%' indirob
  549.             { $$ = newHVREF($2); }
  550.     ;
  551.  
  552. arylen    :    DOLSHARP indirob
  553.             { $$ = newAVREF($2); }
  554.     ;
  555.  
  556. star    :    '*' indirob
  557.             { $$ = newGVREF(0,$2); }
  558.     ;
  559.  
  560. indirob    :    WORD
  561.             { $$ = scalar($1); }
  562.     |    scalar
  563.             { $$ = scalar($1);  }
  564.     |    block
  565.             { $$ = scope($1); }
  566.  
  567.     |    PRIVATEREF
  568.             { $$ = $1; }
  569.     ;
  570.  
  571. %% /* PROGRAM */
  572.