doy / parse-keyword

DEPRECATED: write syntax extensions in perl
http://metacpan.org/release/Parse-Keyword
5 stars 4 forks source link

Failure when used on expression level #4

Closed latk closed 11 years ago

latk commented 11 years ago

When using Parse::Keyword on the expression level, the custom parser runs as expected. However, a nondescriptive syntax error is thrown afterwards. Code to reproduce:

# tested under perl 5.18.1
BEGIN {
  use Parse::Keyword {
    foo => sub {
      warn "parser runs all right";
      return sub { 42 }, 1;
    },
  };
  sub foo { print @_, "\n" }
}

#1. this works fine:
foo;

#2. this fails:
my $x = foo;

#3. but this works, of course:
my $y = do { foo };

The error message in the 2nd case is:

syntax error at - line 16, near "= foo"
Execution of - aborted due to compilation errors.

Can this error be avoided?

If not, can a better error message be displayed when Parse::Keyword is used on the expression level? Adding this to the “Limitations” section of the documentation might be helpful as well.

doy commented 11 years ago

By using return sub { 42 }, 1; instead of return sub { 42 };, you are telling Parse::Keyword to parse the keyword as a statement instead of an expression. The parse error you get in this case is the same as the parse error you get for any other use of a statement where the parser expects an expression:

$ perl -e'my $x = if (1) { };'
syntax error at -e line 1, near "= if"
Execution of -e aborted due to compilation errors.

If you want your keyword to parse as an expression, you shouldn't return the second true value from your parser function.

latk commented 11 years ago

Thank you for this information. Where is this documented?

doy commented 11 years ago

In the DESCRIPTION section:

The parsing coderefs will be called when perl encounters a call to the keyword
that you attached custom parsing to. The current parser state will be directly
after parsing the keyword. The parser function will receive the name of the
keyword as a parameter, and should return a coderef which, when called at
runtime, will produce the arguments to the function. In addition, if your
keyword should be parsed as a statement (for instance, if you don't want to
require a trailing semicolon), you can return a second, true value.
latk commented 11 years ago

I'm terribly sorry for not having seen that. Thanks for your help.