From 75230cc19006735d29105daf0c6dcaf41880f961 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Thu, 22 Feb 2018 14:44:51 +0000 Subject: rationalise subroutine parsing rules Now that the parser rules have been split into separate rules for subs under 'use feature "signatures"' and not, refine the rules to reflect the different regimes. In particular: 1) no longer include 'proto' in the signature variants: as it happens the toker would never return a proto THING under signatures anyway, but removing it from the grammar makes it clearer what's expected and not expected. 2) Remove 'subsignature' from non-sig rules: what used to happen before was that outside of 'use feature "signatures"', it might still try to parse a signature, e.g. $ perl5279 -we 'sub f :lvalue ($$@) { $x = 1 }' Illegal character following sigil in a subroutine signature at -e line 1, near "($" syntax error at -e line 1, near "$$@" Now it's just a plain syntax error. --- perly.y | 65 ++++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 19 deletions(-) (limited to 'perly.y') diff --git a/perly.y b/perly.y index dd00deb264..2af1b5bf62 100644 --- a/perly.y +++ b/perly.y @@ -71,13 +71,14 @@ %type sliceme kvslice gelem %type listexpr nexpr texpr iexpr mexpr mnexpr %type optlistexpr optexpr optrepl indirob listop method -%type formname subname proto optsubbody cont my_scalar my_var +%type formname subname proto cont my_scalar my_var %type refgen_topic formblock %type subattrlist myattrlist myattrterm myterm -%type realsubbody termbinop termunop anonymous termdo +%type termbinop termunop anonymous termdo %type sigslurpsigil %type sigvarname sigdefault sigscalarelem sigslurpelem -%type sigelem siglist siglistornull subsignature +%type sigelem siglist siglistornull subsignature optsubsignature +%type subbody optsubbody sigsubbody optsigsubbody %type formstmtseq formline formarg %nonassoc PREC_LOW @@ -274,12 +275,14 @@ barestmt: PLUGSTMT parser->parsed_sub = 1; } | SUB subname startsub + /* sub declaration or definition not within scope + of 'use feature "signatures"'*/ { init_named_cv(PL_compcv, $2); parser->in_my = 0; parser->in_my_stash = NULL; } - proto subattrlist optsubbody + proto subattrlist optsubbody { SvREFCNT_inc_simple_void(PL_compcv); $2->op_type == OP_CONST @@ -291,17 +294,21 @@ barestmt: PLUGSTMT parser->parsed_sub = 1; } | SIGSUB subname startsub + /* sub declaration or definition under 'use feature + * "signatures"'. (Note that a signature isn't + * allowed in a declaration) + */ { init_named_cv(PL_compcv, $2); parser->in_my = 0; parser->in_my_stash = NULL; } - proto subattrlist optsubbody + subattrlist optsigsubbody { SvREFCNT_inc_simple_void(PL_compcv); $2->op_type == OP_CONST - ? newATTRSUB($3, $2, $5, $6, $7) - : newMYSUB($3, $2, $5, $6, $7) + ? newATTRSUB($3, $2, NULL, $5, $6) + : newMYSUB( $3, $2, NULL, $5, $6) ; $$ = NULL; intro_my(); @@ -742,9 +749,14 @@ siglistornull: /* NULL */ | siglist { $$ = $1; } +/* optional subroutine signature */ +optsubsignature: /* NULL */ + { $$ = NULL; } + | subsignature + { $$ = $1; } + /* Subroutine signature */ -subsignature: /* NULL */ { $$ = (OP*)NULL; } - | '(' +subsignature: '(' { ENTER; SAVEIV(parser->sig_elems); @@ -793,9 +805,29 @@ subsignature: /* NULL */ { $$ = (OP*)NULL; } } ; +/* Optional subroutine body (for named subroutine declaration) */ +optsubbody: subbody { $$ = $1; } + | ';' { $$ = NULL; } + ; + + +/* Subroutine body (without signature) */ +subbody: remember '{' stmtseq '}' + { + if (parser->copline > (line_t)$2) + parser->copline = (line_t)$2; + $$ = block_end($1, $3); + } + ; + + +/* optional [ Subroutine body with optional signature ] (for named + * subroutine declaration) */ +optsigsubbody: sigsubbody { $$ = $1; } + | ';' { $$ = NULL; } -/* Subroutine body - block with optional signature */ -realsubbody: remember subsignature '{' stmtseq '}' +/* Subroutine body with optional signature */ +sigsubbody: remember optsubsignature '{' stmtseq '}' { if (parser->copline > (line_t)$3) parser->copline = (line_t)$3; @@ -805,11 +837,6 @@ realsubbody: remember subsignature '{' stmtseq '}' ; -/* Optional subroutine body, for named subroutine declaration */ -optsubbody: realsubbody { $$ = $1; } - | ';' { $$ = NULL; } - ; - /* Ordinary expressions; logical combinations */ expr : expr ANDOP expr { $$ = newLOGOP(OP_AND, 0, $1, $3); } @@ -1025,12 +1052,12 @@ anonymous: '[' expr ']' { $$ = newANONHASH($2); } | HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */ { $$ = newANONHASH(NULL); } - | ANONSUB startanonsub proto subattrlist realsubbody %prec '(' + | ANONSUB startanonsub proto subattrlist subbody %prec '(' { SvREFCNT_inc_simple_void(PL_compcv); $$ = newANONATTRSUB($2, $3, $4, $5); } - | ANON_SIGSUB startanonsub proto subattrlist realsubbody %prec '(' + | ANON_SIGSUB startanonsub subattrlist sigsubbody %prec '(' { SvREFCNT_inc_simple_void(PL_compcv); - $$ = newANONATTRSUB($2, $3, $4, $5); } + $$ = newANONATTRSUB($2, NULL, $3, $4); } ; /* Things called with "do" */ -- cgit v1.2.1