* The main job of of this grammar is to call the various newFOO()
* functions in op.c to build a syntax tree of OP structs.
* It relies on the lexer in toke.c to do the tokenizing.
+ *
+ * Note: due to the way that the cleanup code works WRT to freeing ops on
+ * the parse stack, it is dangerous to assign to the $n variables within
+ * an action.
*/
/* Make the parser re-entrant. */
%start prog
%union {
- I32 ival;
+ I32 ival; /* __DEFAULT__ (marker for regen_perly.pl;
+ must always be 1st union member) */
char *pval;
OP *opval;
GV *gvval;
#ifdef PERL_IN_MADLY_C
TOKEN* p_tkval;
- TOKEN* tkval;
+ TOKEN* i_tkval;
#else
char *p_tkval;
- I32 tkval;
+ I32 i_tkval;
+#endif
+#ifdef PERL_MAD
+ TOKEN* tkval;
#endif
}
-%token <tkval> '{' '}' '[' ']' '-' '+' '$' '@' '%' '*' '&' ';'
+%token <i_tkval> '{' '}' '[' ']' '-' '+' '$' '@' '%' '*' '&' ';'
%token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
%token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
%token <p_tkval> LABEL
-%token <tkval> FORMAT SUB ANONSUB PACKAGE USE
-%token <tkval> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
-%token <tkval> GIVEN WHEN DEFAULT
-%token <tkval> LOOPEX DOTDOT
-%token <tkval> FUNC0 FUNC1 FUNC UNIOP LSTOP
-%token <tkval> RELOP EQOP MULOP ADDOP
-%token <tkval> DOLSHARP DO HASHBRACK NOAMP
-%token <tkval> LOCAL MY MYSUB REQUIRE
-%token <tkval> COLONATTR
+%token <i_tkval> FORMAT SUB ANONSUB PACKAGE USE
+%token <i_tkval> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
+%token <i_tkval> GIVEN WHEN DEFAULT
+%token <i_tkval> LOOPEX DOTDOT
+%token <i_tkval> FUNC0 FUNC1 FUNC UNIOP LSTOP
+%token <i_tkval> RELOP EQOP MULOP ADDOP
+%token <i_tkval> DOLSHARP DO HASHBRACK NOAMP
+%token <i_tkval> LOCAL MY MYSUB REQUIRE
+%token <i_tkval> COLONATTR
%type <ival> prog progstart remember mremember savescope
%type <ival> startsub startanonsub startformsub
%type <opval> switch case
%type <p_tkval> label
-%nonassoc <tkval> PREC_LOW
+%nonassoc <i_tkval> PREC_LOW
%nonassoc LOOPEX
-%left <tkval> OROP DOROP
-%left <tkval> ANDOP
-%right <tkval> NOTOP
+%left <i_tkval> OROP DOROP
+%left <i_tkval> ANDOP
+%right <i_tkval> NOTOP
%nonassoc LSTOP LSTOPSUB
-%left <tkval> ','
-%right <tkval> ASSIGNOP
-%right <tkval> '?' ':'
+%left <i_tkval> ','
+%right <i_tkval> ASSIGNOP
+%right <i_tkval> '?' ':'
%nonassoc DOTDOT
-%left <tkval> OROR DORDOR
-%left <tkval> ANDAND
-%left <tkval> BITOROP
-%left <tkval> BITANDOP
+%left <i_tkval> OROR DORDOR
+%left <i_tkval> ANDAND
+%left <i_tkval> BITOROP
+%left <i_tkval> BITANDOP
%nonassoc EQOP
%nonassoc RELOP
%nonassoc UNIOP UNIOPSUB
%nonassoc REQUIRE
-%left <tkval> SHIFTOP
+%left <i_tkval> SHIFTOP
%left ADDOP
%left MULOP
-%left <tkval> MATCHOP
-%right <tkval> '!' '~' UMINUS REFGEN
-%right <tkval> POWOP
-%nonassoc <tkval> PREINC PREDEC POSTINC POSTDEC
-%left <tkval> ARROW
-%nonassoc <tkval> ')'
-%left <tkval> '('
+%left <i_tkval> MATCHOP
+%right <i_tkval> '!' '~' UMINUS REFGEN
+%right <i_tkval> POWOP
+%nonassoc <i_tkval> PREINC PREDEC POSTINC POSTDEC
+%left <i_tkval> ARROW
+%nonassoc <i_tkval> ')'
+%left <i_tkval> '('
%left '[' '{'
-%token <tkval> PEG
+%token <i_tkval> PEG
%% /* RULES */
IVAL($2), scalar($7),
$12, $10, $9));
#ifdef MAD
- if (!$5)
- $5 = newOP(OP_NULL, 0);
forop = newUNOP(OP_NULL, 0, append_elem(OP_LINESEQ,
newSTATEOP(0,
- (($1)->tk_lval.pval
- ?savepv(($1)->tk_lval.pval):Nullch),
- $5),
+ CopLABEL_alloc(($1)->tk_lval.pval),
+ ($5 ? newOP(OP_NULL, 0) : $5) ),
forop));
token_getmad($2,forop,'3');
#else
if ($5) {
forop = append_elem(OP_LINESEQ,
- newSTATEOP(0, ($1?savepv($1):Nullch),
- $5),
+ newSTATEOP(0, CopLABEL_alloc($1), $5),
forop);
}
token_free($1);
#else
newFORM($2, $3, $4);
+ $$ = Nullop;
#endif
}
;
token_getmad($1,$$,'d');
#else
newMYSUB($2, $3, $4, $5, $6);
+ $$ = Nullop;
#endif
}
;
token_getmad($3,$$,';');
#else
package($2);
+ $$ = Nullop;
#endif
}
;
append_madprops(newMADPROP('!', MAD_PV, "", 0), $$, 0);
#else
utilize(IVAL($1), $2, $4, $5, $6);
+ $$ = Nullop;
#endif
}
;
}
| argexpr ',' term
{
+ OP* term = $3;
DO_MAD(
- $3 = newUNOP(OP_NULL, 0, $3);
- token_getmad($2,$3,',');
+ term = newUNOP(OP_NULL, 0, term);
+ token_getmad($2,term,',');
)
- $$ = append_elem(OP_LIST, $1, $3);
+ $$ = append_elem(OP_LIST, $1, term);
}
| term %prec PREC_LOW
;
}
| LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */
{ SvREFCNT_inc(PL_compcv);
- $3 = newANONATTRSUB($2, 0, Nullop, $3); }
+ $<opval>$ = newANONATTRSUB($2, 0, Nullop, $3); }
listexpr %prec LSTOP /* ... @bar */
{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST,
- prepend_elem(OP_LIST, $3, $5), $1));
+ prepend_elem(OP_LIST, $<opval>4, $5), $1));
}
;
/* Things called with "do" */
termdo : DO term %prec UNIOP /* do $filename */
- { $$ = dofile($2, $1);
+ { $$ = dofile($2, IVAL($1));
TOKEN_GETMAD($1,$$,'o');
}
| DO block %prec '(' /* do { code */