【问题标题】:cannot parse using Parse::Lex无法使用 Parse::Lex 解析
【发布时间】:2011-09-12 15:12:43
【问题描述】:

我在 Windows XP(版本 5.1.2600)上使用处于活动状态的 Perl 版本 5.12.4。安装了 ParseLex 2.20。 尝试从 Apress 的 Pro Perl Parsing 书中运行此代码。

#!/usr/bin/perl

use Parse::Lex;

#defines the tokens
@token=qw(  
BegParen [\(]
EndParen [\)]
Operator [-+*/^]
Number   [-?\d+|-?\d+\.\d*]
);
$lexer=Parse::Lex->new(@token); #Specifies the lexer
$lexer->from(STDIN); #Specifies the input source

TOKEN:
while(1){ #1 will be returned unless EOI
$token=$lexer->next;
if(not $lexer->eoi){
    print $token->name . " " . $token->text . " " . "\n";
}
else {last TOKEN;}
}

由于这不起作用,我用数字 [-?\d+] 进行了简化。 它告诉我“无法在未定义的值上调用方法“名称”。它无法识别 $token->name & $token->text。 我在这里缺少什么?请帮忙。

根据 Alexandar 的建议,我已将代码更改为 $lexer->from(*STDIN);并且能够成功地从标准输入读取。还更改了数字 [(-?\d+)|(-?\d+.\d*)]。现在当我将 43.4*15^2 输入到标准输入时,我得到的输出是:

Number 4
Number 3
Number .
Number 4
Operator *
Number 1
Number 5
Operator ^
Number 2
Can't call method "name" on an undefined value at listing1-1.pl line 20, <STDIN>.

这里第 20 行是 print $token->name, " ", $token->text,"\n"。

【问题讨论】:

  • 你要解析什么输入?
  • 错误是由输入字符串中的换行引起的。我建议添加 WS \s+ 令牌来解析这些。

标签: perl


【解决方案1】:

应该是 "Number -?\d+|-?\d+.\d*" 并且从 STDIN 读取 "from" 方法应该这样调用:

$lexer->from(\*STDIN);

更新完整代码,提供更好的错误处理和修复:

#!/usr/bin/perl

use Parse::Lex;

#defines the tokens
my @token=(qw(  
BegParen [\(]
EndParen [\)]
Operator [-+*/^]
Number   -?\d+(?:\.\d*)?
NEWLINE  \n
     ),
     qw(ERROR  (?s:.*)), sub {
       print STDERR "ERROR: buffer content->", $_[0]->lexer->buffer, "<-\n";
       die qq!can\'t analyze: "$_[1]"!;
     }
);
my $lexer=Parse::Lex->new(@token); #Specifies the lexer
$lexer->from(\*STDIN); #Specifies the input source

TOKEN:
while(1){ #1 will be returned unless EOI
  my $token=$lexer->next;
  if (not $lexer->eoi){
    print $token->name . " " . $token->text . " " . "\n";
  }
  else {last TOKEN;}
}

另见Parse::Lex documentation

【讨论】:

  • 您关于从 STDIN 读取的建议非常完美。现在我在 STDIN 输入 43.4*15^2 并获得输出---------------- ------4号3号。编号 4 运算符 * 编号 1 编号 5 运算符 ^ 编号 2 无法在 E:/indigoworkspace/properlparsing/listing1-1.pl 第 20 行, 第 1 行的未定义值上调用方法“名称”。打印第 20 行$token->name, " ", $token->text,"\n".
  • 感谢 Alexandr,它的工作就像轻而易举。现在我有了更好的理解。
猜你喜欢
  • 2016-04-22
  • 2017-09-07
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
  • 2017-08-22
相关资源
最近更新 更多