在运行一个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);
这种赋值方法完全没见过,不知道问题到底出现在哪。。
跪谢耐心地看到这里的各位大大。