Jul 26, 2011

IRCダイスボットへの道 - ダイスコマンドをパースする

Perl をはじめたての頃に IRCダイスボットを書いていたのですけども、その後の HDDクラッシュで影も形も無くなってしまいました。既にボーンズ&カーズという高機能な IRCダイスボットが公開されている事だし、一から作り直すのも面倒でそのまま放置していたのですけども、最近なんとなく自分専用にシンプルな IRCダイスボットを作ってみたくなりました。

  • ダイスコマンド文字列のパーサを書く
  • パーサ組み込んだローカルダイスツールを作る
  • ローカルダイスツールを IRCボットに組み込む

という手順で作ってみる予定です。

Perlモジュールの Parse::RecDescent を使ってダイスコマンド文字列のパーサを書くとこんな感じになります。

diceparser.pl

#!/usr/bin/env perl

use strict;
use warnings;
use Parse::RecDescent;
use Data::Dumper;

my $grammar = <<'GRAMMER';
expression: add end { $item[1] }
add: val '+' add { { left => $item[1], op => '+', right => $item[3] } }
add: val '-' add { { left => $item[1], op => '-', right => $item[3] } }
add: val
val: /[1-9]\d?d(?:100|20|12|10|8|6|4|2)/i
val: /\d{1,2}/
end: /\s*$/
GRAMMER

my $parser = Parse::RecDescent->new( $grammar ) or die 'Bad grammar';

my $text = $ARGV[0];
my $result = $parser->expression( $text ) or die 'Bad text';

local $Data::Dumper::Sortkeys = 1;
my $d = Data::Dumper->new( [ $result ] );
print $d->Dump;
$ ./diceparser.pl 1d8+1d6+1d100-2
$VAR1 = {
          'left' => '1d8',
          'op' => '+',
          'right' => {
                       'left' => '1d6',
                       'op' => '+',
                       'right' => {
                                    'left' => '1d100',
                                    'op' => '-',
                                    'right' => '2'
                                  }
                     }
        };

と、それぞれのダイスと修正値、演算子が無名ハッシュへのリファレンスに収まります。便利べんり!次回はこれを取り出してダイスをロールし結果を表示するローカルダイスツールを作ってみようと思います。

Posted at 22:02 in perl | Comments/Trackbacks ()
Comments/Trackbacks
TrackBack ping me at
http://pochi.usamimi.info/blog/perl/dice_parser.
Post a comment

writeback message: