Разобрать сериализованный объект Python в Perl - PullRequest
2 голосов
/ 28 мая 2011

Мне нужно, чтобы мой код Perl читал сериализованный объект Python для последующей обработки. Я пришел с парсером на основе Parse :: MGC, но он медленный. Может быть, я сделал это неправильно или кто-то знает лучший способ преобразовать сериализованный объект Python в какую-то структуру Perl?

Вот мой код разбора:

package Room::HandParser;
use base qw( Parser::MGC );

my @poker_cards_string = ( '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', 'Th', 'Jh', 'Qh', 'Kh', 'Ah', '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', 'Td', 'Jd', 'Qd', 'Kd', 'Ax', '2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', 'Tc', 'Jc', 'Qc', 'Kc', 'Ac', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', 'Ts', 'Js', 'Qs', 'Ks', 'As' );

sub parse_declaration {
  my $self = shift;

  [  
    $self->any_of(
      sub { $self->token_int },
      sub { $self->token_string },
    ),
    $self->expect(":"),
    $self->parse,
  ]
}

sub parse_hash {
  my $self = shift;

  my %ret;
  $self->list_of(",", sub {
      my $res = $self->parse_declaration;
      $ret{$res->[0]} = $res->[2];
  });

  return \%ret;
}


sub parse_cards {
  my $self = shift;
  my $card = $self->token_int;
  return $poker_cards_string[$card & 0x3F];
}

sub parse {
  my $self = shift;

  $self->any_of(
    sub { $self->scope_of( "[", sub { $self->list_of(",", \&parse) }, "]" ) },
    sub { $self->scope_of( "(", sub { $self->list_of(",", \&parse) }, ")" ) },
    sub { $self->scope_of( "{", sub { $self->parse_hash }, "}" ) },
    sub { $self->scope_of( "PokerCards([", sub { $self->list_of(",", \&parse_cards) }, "])" ) },
    sub { $self->token_float },
    sub { $self->token_int },
    sub { $self->token_string },
    sub { $self->token_kw( qw(None True False) ) },
  );
}

1;

Вот пример сериализованного объекта Python, который мне нужно проанализировать:

[('game', 0, 195, 0, 0.0, 'holdem', '100-200-no-limit', [50312, 50313, 50314, 50315, 50316, 50317, 2], 0, {2: 1000000, 50312: 200000, 50313: 200000, 50314: 200000, 50315: 200000, 50316: 200000, 50317: 200000}), ('position', 1), ('blind', 50313, 10000, 0), ('position', 2), ('blind', 50314, 20000, 0), ('position', -1), ('round', 'pre-flop', PokerCards([]), {2: PokerCards([226, 208]), 50312: PokerCards([223, 206]), 50313: PokerCards([221, 233]), 50314: PokerCards([222, 211]), 50315: PokerCards([235, 216]), 50316: PokerCards([209, 236]), 50317: PokerCards([237, 243])}), ('position', 3), ('call', 50315, 20000), ('position', 4), ('call', 50316, 20000), ('position', 5), ('call', 50317, 20000), ('position', 6), ('call', 2, 20000), ('position', 0), ('fold', 50312), ('position', 1), ('call', 50313, 10000), ('position', 2), ('check', 50314), ('position', -1), ('round', 'flop', PokerCards([7, 21, 46]), {2: PokerCards([226, 208]), 50313: PokerCards([221, 233]), 50314: PokerCards([222, 211]), 50315: PokerCards([235, 216]), 50316: PokerCards([209, 236]), 50317: PokerCards([237, 243])}), ('position', 1), ('check', 50313), ('position', 2), ('check', 50314), ('position', 3), ('check', 50315), ('position', 4), ('check', 50316), ('position', 5), ('check', 50317), ('position', 6), ('check', 2), ('position', -1), ('round', 'turn', PokerCards([7, 21, 46, 38]), None), ('position', 1), ('check', 50313), ('position', 2), ('check', 50314), ('position', 3), ('check', 50315), ('position', 4), ('check', 50316), ('position', 5), ('check', 50317), ('position', 6), ('check', 2), ('position', -1), ('round', 'river', PokerCards([7, 21, 46, 38, 20]), None), ('position', 1), ('check', 50313), ('position', 2), ('check', 50314), ('position', 3), ('check', 50315), ('position', 4), ('check', 50316), ('position', 5), ('check', 50317), ('position', 6), ('check', 2), ('position', -1), ('showdown', None, {2: PokerCards([226, 208]), 50313: PokerCards([29, 41]), 50314: PokerCards([222, 211]), 50315: PokerCards([43, 24]), 50316: PokerCards([209, 236]), 50317: PokerCards([45, 51])}), ('end', [50317], [{'serial2delta': {2: -20000, 50313: -20000, 50314: -20000, 50315: -20000, 50316: -20000, 50317: 100000}, 'player_list': [50312, 50313, 50314, 50315, 50316, 50317, 2], 'serial2rake': {50317: 0}, 'serial2share': {50317: 120000}, 'pot': 120000, 'serial2best': {2: {'hi': [101154816, ['FlHouse', 46, 20, 7, 34, 21]]}, 50313: {'hi': [50841600, ['Trips', 46, 20, 7, 38, 21]]}, 50314: {'hi': [50841600, ['Trips', 46, 20, 7, 38, 21]]}, 50315: {'hi': [50842368, ['Trips', 46, 20, 7, 38, 24]]}, 50316: {'hi': [50841600, ['Trips', 46, 20, 7, 38, 21]]}, 50317: {'hi': [101171200, ['FlHouse', 46, 20, 7, 51, 38]]}}, 'type': 'game_state', 'side_pots': {'building': 0, 'pots': [[120000, 120000]], 'last_round': 3, 'contributions': {0: {0: {2: 20000, 50313: 20000, 50314: 20000, 50315: 20000, 50316: 20000, 50317: 20000}}, 1: {}, 2: {}, 'total': {2: 20000, 50313: 20000, 50314: 20000, 50315: 20000, 50316: 20000, 50317: 20000}, 3: {}}}}, {'serials': [50313, 50314, 50315, 50316, 50317, 2], 'pot': 120000, 'hi': [50317], 'chips_left': 0, 'type': 'resolve', 'serial2share': {50317: 120000}}])]

Для такой структуры требуется несколько секунд и 100% CPU для анализа этого объекта, что в моем случае неприемлемо.

РЕДАКТИРОВАТЬ: здесь я НЕ ищу обходной путь, как написание скрипта Python для оценки этого Strucutre и вывода его JSON, или переписать оригинальное приложение Python с добавленными функциями для хранения данных в виде JSON. Я пытаюсь проанализировать эти данные с помощью Perl с разумной производительностью, поскольку этот формат довольно близок к JSON, и его можно будет проанализировать за то же время.

Ответы [ 2 ]

6 голосов
/ 28 мая 2011

Как насчет использования другого формата?Например, JSON довольно легко анализировать, и в Perl есть реализации, которые должны работать «из коробки».В Python встроены JSON-сериализация и десериализация, так что вам не придется изобретать там и другие колеса.

0 голосов
/ 27 июня 2011

Если кому-то интересно: я получаю несколько регулярных выражений, которые преобразуют эту строку в JSON (поскольку они очень близки), а затем анализируют ее с помощью JSON :: XS https://github.com/hippich/Bitcoin-Poker-Room/commit/2f0e089908d3fa71dc16021ac6a24807c46529ad#diff-1 __parse_hands () подпрограмма.

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