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