summaryrefslogtreecommitdiff
path: root/perly.y
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2018-02-22 14:44:51 +0000
committerDavid Mitchell <davem@iabyn.com>2018-03-02 13:36:43 +0000
commit75230cc19006735d29105daf0c6dcaf41880f961 (patch)
tree13ebdac2b64e5118f016e682adbf12e4c4ec7d4d /perly.y
parent436ddf68a973edeede30e3cdf27a8063d7686eec (diff)
downloadperl-75230cc19006735d29105daf0c6dcaf41880f961.tar.gz
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.
Diffstat (limited to 'perly.y')
-rw-r--r--perly.y65
1 files changed, 46 insertions, 19 deletions
diff --git a/perly.y b/perly.y
index dd00deb264..2af1b5bf62 100644
--- a/perly.y
+++ b/perly.y
@@ -71,13 +71,14 @@
%type <opval> sliceme kvslice gelem
%type <opval> listexpr nexpr texpr iexpr mexpr mnexpr
%type <opval> optlistexpr optexpr optrepl indirob listop method
-%type <opval> formname subname proto optsubbody cont my_scalar my_var
+%type <opval> formname subname proto cont my_scalar my_var
%type <opval> refgen_topic formblock
%type <opval> subattrlist myattrlist myattrterm myterm
-%type <opval> realsubbody termbinop termunop anonymous termdo
+%type <opval> termbinop termunop anonymous termdo
%type <ival> sigslurpsigil
%type <opval> sigvarname sigdefault sigscalarelem sigslurpelem
-%type <opval> sigelem siglist siglistornull subsignature
+%type <opval> sigelem siglist siglistornull subsignature optsubsignature
+%type <opval> subbody optsubbody sigsubbody optsigsubbody
%type <opval> formstmtseq formline formarg
%nonassoc <ival> 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" */