首页 > 运行perl文件时出现“Scalar found where operator expected at line XXX”问题

运行perl文件时出现“Scalar found where operator expected at line XXX”问题

在运行一个perl2java的源码时,遇到了一些问题。小白向各位请教下。
以下是相关的源码:
test.pl:

#GRAMPROG

use strict;
use Data::Dumper;
use Digest::MD5;

sub test
{

    my $value = shift;
    print($value);
}

sub main
{

    my $string  = "Hello world\n";
    my $integer = "1";

    print($string);
    print(Dumper($integer));

    $string = md5_hex("test");

    print(STDERR "stderr $integer");
    print(STDOUT "stdout\n");

    print("a string");

    open(FILE,">out");
    print(FILE "data");
    close(FILE);

    test("100");
}

main();

yappie.pl

use strict;

use Parse::Lex;
use Parse::Yapp;
use PerlParser;
use JavaGenerator;
use Data::Dumper;
use Log;

# Bit Value    Outputs
#    0x01         Token reading (useful for Lexer debugging)
#    0x02         States information
#    0x04         Driver actions (shifts, reduces, accept...)
#    0x08         Parse Stack dump
#    0x10         Error Recovery tracing

#use constant DEBUG => 0xFF;
use constant DEBUG => 0x0;

# Lexicon

our $lexer = undef;

our @token_injects = ();
our @value_injects = ();

our @token = (
          qw(
         GRAMPROG #GRAMPROG
         GRAMSTMTSEQ #STMTSEQ

         USE      use
         SUB      sub
         MY          my

         ASSIGNOP    =
             ADDOP    [-+]
             LEFTP    [\(]
             RIGHTP   [\)]
         SPACE    [\s]
         WORD     [A-z0-9_\>\<\"][A-z0-9_\>\<\"\$\s]*
         SEMICOL  [\;]
         PACKSEP  [\:\:]
         CURLYBRACKOPEN  [\{]
         CURLYBRACKCLOSE [\}]
         COMMA    ,
         DOLLAR    \$
         AMP    \&
         AT        \@
         PCT    \%
             
            ),
          qw(WORD),   [qw(" (?:[^"]+|"")* ")],
          qw(ERROR  .*), sub {
            die qq!can\'t analyze: "$_[1]"!;
          }
         );



sub initialize_lexer {

    my $file = shift;
    #Parse::Lex->trace;  # Class method
        $lexer = Parse::Lex->new(@token);
    $lexer->skip("\n");
    open(FILE,"<$file");
        $lexer->from(\*FILE);
    return $lexer;
}

sub lexer_sub {

    my $parser = shift; # yapp parser

    my $lexer_token = undef;

    my $token  = undef;
    my $value  = undef;

    # allow injects
     if (@token_injects) {
       $token=shift @token_injects;
       $value=shift @value_injects;
    } else {
       $lexer_token = $lexer->next();
       $token = $lexer_token->name();
       $value = $lexer_token->text();
       while ($token eq 'SPACE' || $token eq 'PACKSEP' || $token eq 'EQ') {
          $lexer_token = $lexer->next();
          $token = $lexer_token->name();
          $value = $lexer_token->text();
       }
    }

    my $buffer=$lexer->buffer();
        

    # literal stuff
    return '{' if $token eq 'CURLYBRACKOPEN';
    return '}' if $token eq 'CURLYBRACKCLOSE';
    return '(' if $token eq 'LEFTP';
    return ')' if $token eq 'RIGHTP';
    return ';' if $token eq 'SEMICOL';
    return ',' if $token eq 'COMMA';
    return '$' if $token eq 'DOLLAR';
    return '&' if $token eq 'AMP';
    return '@' if $token eq 'AT';
    return '%' if $token eq 'PCT';

    # WORD upgrade to FUNC or UNIOP
    my $is_sub=$parser->{_generator}->is_sub($value);
    $token = 'FUNC'  if ($is_sub && $buffer =~ /\(/);
    $token = 'UNIOP' if ($is_sub && $buffer !~ /\(/);

    #print "lexer_sub token=$token value='$value' is_sub=$is_sub buffer='$buffer'\n";
    print "lexer_sub token=$token value='$value' is_sub=$is_sub\n";

    if ($token eq 'EOI') {
        return undef;
    }

    if ($token eq 'USE' && $buffer =~/strict/) { # use strict
        print "** Inject WORD\n";
        push @token_injects,'WORD'; # its a strange perl grammar with use WORD WORD
        push @value_injects, 'inject';
    }

    return ($token,$value);

}

sub error_sub {

    my $parser = shift;
    if ($parser->YYCurtok ne 'EOI') {
       warn "YAPP PARSE Error: found ", $parser->YYCurtok, " and expecting one of ", join(" or ",$parser->YYExpect);
       exit;
    }
}

#
# fieldname -> Fieldname
#
sub uc1
{
   my $name = shift;
   my @chars = split('',$name);
   $chars[0] = uc($chars[0]);
   return join('',@chars);
}


sub get_classname
{
    my $name = shift;
    
    $name =~ s/\.pl$//g;
    $name =~ s/\.pm$//g;

    return uc1($name);
}

sub main 
{

   my $perl_filename  = $ARGV[0];
   my $java_classname = get_classname($perl_filename);
   my $java_filename  = $java_classname . '.java';

   my $lexer     = initialize_lexer($perl_filename);
   my $parser    = new PerlParser();
   my $generator = new JavaGenerator(lexer           => $lexer, 
                                 parser          => $parser, 
                                     perl_filename   => $perl_filename,
                                     java_filename   => $java_filename, 
                                     java_classname  => $java_classname);

   $parser->{_generator}=$generator;

   my $value=$parser->YYParse(yydebug => DEBUG, yylex => \&lexer_sub, yyerror => \&error_sub);

   print "value=$value\n";

   my $javacode = $generator->generateJavaClass();

   open(JAVA,">$java_filename");
   print JAVA $javacode;
   close(JAVA);

   Log::info("generated JAVA file $java_filename");

}

main();

根据源码包里面的使用方法,我运行了perl yappie.pl test.pl这行命令,但是却报错了

macmatoMacBook-Air-2:perl2java-master mac$ perl yappie.pl test.pl
lexer_sub token=GRAMPROG value='#GRAMPROG' is_sub=0
YP: GRAMPROG
lexer_sub token=USE value='use' is_sub=0
** Inject WORD
lexer_sub token=WORD value='inject' is_sub=0
lexer_sub token=WORD value='strict' is_sub=0
YP: barestmt
YP: stmtseq fullstmt
lexer_sub token=USE value='use' is_sub=0
lexer_sub token=WORD value='Data' is_sub=0
lexer_sub token=WORD value='Dumper' is_sub=0
YP: barestmt
YP: stmtseq fullstmt
lexer_sub token=USE value='use' is_sub=0
lexer_sub token=WORD value='Digest' is_sub=0
lexer_sub token=WORD value='MD5' is_sub=0
YP: barestmt
YP: stmtseq fullstmt
lexer_sub token=SUB value='sub' is_sub=0
lexer_sub token=WORD value='test
' is_sub=0
lexer_sub token=MY value='my' is_sub=0
lexer_sub token=WORD value='value ' is_sub=0
Undefined subroutine &Log::info called at perly.yp line 840, <FILE> line 10.

之后我便运行了perl yappie.pl这行命令,又出现了错误。

macmatoMacBook-Air-2:perl2java-master mac$ perl yappie.pl
lexer_sub token=EOI value='' is_sub=0
YAPP PARSE Error: found  and expecting one of GRAMSTMTSEQ or GRAMFULLSTMT or GRAMBARESTMT or GRAMBLOCK or GRAMEXPR or GRAMPROG at yappie.pl line 137.

之后,我发现yappie.pl中[qw(" (?:[^"]+|"")* ")],这个赋值方法有点与众不同:

our @token = (
          qw(
         GRAMPROG #GRAMPROG
         GRAMSTMTSEQ #STMTSEQ

         USE      use
         SUB      sub
         MY          my

         ASSIGNOP    =
             ADDOP    [-+]
             LEFTP    [\(]
             RIGHTP   [\)]
         SPACE    [\s]
         WORD     [A-z0-9_\>\<\"][A-z0-9_\>\<\"\$\s]*
         SEMICOL  [\;]
         PACKSEP  [\:\:]
         CURLYBRACKOPEN  [\{]
         CURLYBRACKCLOSE [\}]
         COMMA    ,
         DOLLAR    \$
         AMP    \&
         AT        \@
         PCT    \%
             
            ),
          qw(WORD),   
          [qw(" (?:[^"]+|"")* ")],#<==这里
          qw(ERROR  .*), sub {
            die qq!can\'t analyze: "$_[1]"!;
          }
         );

我就把它去掉了,之后运行出来了,但是仍然报错了。(省略部分输出)

394    $LEX_BUFFER =~ /\G(?:ERROR)/cg and do {
395      
396      $textLength = pos($LEX_BUFFER) - $LEX_POS;
397      $content = substr($LEX_BUFFER, $LEX_POS, $textLength); # $&
398      $LEX_OFFSET += $textLength;
399      $LEX_POS += $textLength;
400 
401      
402      
403     $main::.*->setText($content);
404     $LEX_TOKEN = $main::.*;
405     last CASE;
406    };
407 
408 
409   }#CASE
410   
411   $self->[4] = $LEX_TOKEN;
412   $LEX_TOKEN;
413 }

syntax error at (eval 168) line 406, near "*;
    last CASE"

之后,把[qw(" (?:[^"]+|"")* ")],放到qw(ERROR .*),后面,这次输出的行数更多了,但是报错也更多了。(只展出错误出现的地方)

Scalar found where operator expected at (eval 176) line 435, near "*;
    $content"
    (Missing operator before 
    $content?)
  0 my $INITIAL = 1;
  1 $LEX_STATE{'INITIAL'} = \$INITIAL;
  2 
  3   {
  4    pos($LEX_BUFFER) = $LEX_POS;
  5    my $textLength = 0;
  6    my $LEX_FH = $$LEX_FHR;
  7    #
    ...(省略)
    ...(省略)
432     $main::.*->setText($content);
433     $self->[4] = $LEX_TOKEN = $main::.*;
434     $content = &{$main::.*->action}($LEX_TOKEN, $content);
435     ($LEX_TOKEN = $self->getToken)->setText($content);
436      
437     last CASE;
438   };
439 
440 
441 
442   }#CASE
443   
444   $self->[4] = $LEX_TOKEN;
445   $LEX_TOKEN;
446 }

syntax error at (eval 176) line 435, near "*;
    $content "
syntax error at (eval 176) line 445, near "}#CASE
  
  $self"
syntax error at (eval 176) line 447, near ";
}"

$content = &{$main::.*->action}($LEX_TOKEN, $content);这种赋值方法完全没见过,不知道问题到底出现在哪。。

跪谢耐心地看到这里的各位大大。

【热门文章】
【热门文章】