не могу разобрать используя Parse :: Lex - PullRequest
2 голосов
/ 11 сентября 2011

Я использую Perl версии 5.12.4 из активного состояния в Windows XP (версия 5.1.2600). Установлен ParseLex 2.20.Попытка запустить этот код из книги парсинга Pro Perl от Apress.

#!/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 +].Он говорит мне "Не могу вызвать метод" name "для неопределенного значения". Он не распознает $ token-> name & $ token-> text.Что мне здесь не хватает?Пожалуйста помоги.

Согласно предложению Александра, я изменил код на $ lexer-> from (* STDIN);и в состоянии успешно читать со стандартного ввода. Также изменилось число [(-? \ d +) | (-? \ d +. \ d *)]. Теперь, когда я передаю 43.4 * 15 ^ 2 в STDIN, я получаю вывод:

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 - это печать $ token-> name, "", $ token-> text, "\ n".

1 Ответ

2 голосов
/ 11 сентября 2011

Это должно быть "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 документация .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...