Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: why does 'print ("hey)")' give a warning?

by chipmunk (Parson)
on Jul 09, 2001 at 18:58 UTC ( [id://94993]=note: print w/replies, xml ) Need Help??


in reply to why does 'print ("hey)")' give a warning?

This a bug in toke.c, in the following code:
STATIC void S_checkcomma(pTHX_ register char *s, char *name, char *what) { char *w; if (*s == ' ' && s[1] == '(') { /* XXX gotta be a better way * +/ if (ckWARN(WARN_SYNTAX)) { int level = 1; for (w = s+2; *w && level; w++) { if (*w == '(') ++level; else if (*w == ')') --level; } if (*w) for (; *w && isSPACE(*w); w++) ; if (!*w || !strchr(";|})]oaiuw!=", *w)) /* an advisory + hack only... */ Perl_warner(aTHX_ WARN_SYNTAX, "%s (...) interpreted as function",name); } } # [the S_checkcomma function continues from here with an unrelated + syntax check]

 

Here's the code again, this time with comments interspersed:
STATIC void S_checkcomma(pTHX_ register char *s, char *name, char *what) { char *w; if (*s == ' ' && s[1] == '(') { /* XXX gotta be a better way * +/
When this function is called, the tokenizer has just grabbed the name of a function. If the current character is a space, and the next character is an open paren, then we'll do the following...         if (ckWARN(WARN_SYNTAX)) { (...but only if syntax warnings are turned on...)
int level = 1; for (w = s+2; *w && level; w++) { if (*w == '(') ++level; else if (*w == ')') --level; }
That for loop should be familiar to many programmers. It's simply counting open and close parens. The conditional, *w && level, will cause the loop to exit either at the end of the line (when *w is null) or when the matching close paren for the first open paren is found (level is 0). However, note that the loop ignores anything that isn't a paren.
if (*w) for (; *w && isSPACE(*w); w++) ;
This extra loop just skips any whitespace after that last closing paren.             if (!*w || !strchr(";|})]oaiuw!=", *w))     /* an advisory hack only... */ Now, if we're at the end of the line (*w is null) or the current character is not one of ;|})]oaiuw!=, then the warning in question is produced:
Perl_warner(aTHX_ WARN_SYNTAX, "%s (...) interpreted as function",name); } }
Remember the part about the counting of parens ignoring anything that isn't a paren? So, in print ("hey)");, this bit of toke.c thinks that the first close paren is the matching paren, even though that paren is inside a string. The character after that paren is a double quote, which is not in that set of acceptable characters, and so the warning is produced.

This suggests some other interesting snippets:

print (/\)/); # warning print (/./); # no warning print ("hey))"); # no warning print ("hey")&&1; # warning print ("hey")||1; # no warning

As the comment says, there's "gotta be a better way". :)

To avoid this warning, you could remove the space before the open paren, add a plus before the open paren, or remove the parens entirely if they're unneeded.

By the way, you're probably wondering why the set of characters ;|})]oaiuw!= is special. Frankly, I just don't know!

Replies are listed 'Best First'.
Re: Re: why does 'print ("hey)")' give a warning?
by iakobski (Pilgrim) on Jul 09, 2001 at 19:13 UTC
    By the way, you're probably wondering why the set of characters ;|})]oaiuw!= is special. Frankly, I just don't know!

    They are most of the characters that can end an expression:

    or and if unless while
    And, as you spotted, & is valid but missing.

    -- iakobski

      And so is f for for.

      -- Abigail

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://94993]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-24 23:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found