/ / WinChalow

ChangeLog パーザ[chalow]

2004-07-28

パーザのみを独立したモジュールにすると、なにかと便利ですね。
Parse::RecDescent を使った簡単なパーザを試作してみました。はあと

EUCコードで入出力することを前提していますので、nkf からパイプしてください。今回は動作確認だけなので、chalow とはデータ構造が異なります。いずれは chalow 互換になる予定です。

RecDescentを使うと、ChangeLog の論理構造を記述するだけですむので(作るのはたいへんだったけど結果的には)非常にシンプルになります。

#! perl -w
# Parse ChangeLog
# Copyright: (C) Project PaoPei with zuihu 2004 JAPAN
# $Id: remoteclog.txt,v 1.2 2004/12/06 08:58:45 zuihu Exp $

package ParseChangeLog;
use strict;
use Parse::RecDescent;
use Data::Dumper;

our $VERSION = '0.1';

my $grammar = q(

file: entry(s)
{
my %file;
for (@{$item[1]})
{
(my $date = $_->[1]->[0]->[0]) =~ s/\-//og;
$file{$date} = $_->[1];
}
\%file;
}

entry: entryheader item(s)
{
my @entry;
push @entry, $item[1], $item[2];
[ $item[1], \@entry ];
}

entryheader: date user
{[$item[1], $item[2]]}
 | date
{[$item[1]]}

date: /\d{4}-\d\d-\d\d/ /(\s\(.+?\))?/
{$item[1]}

user: /.+/
{$item[1]}

item: itemheader itembody(s)
{ [$item[1], $item[2]] }
 | itemheader
{ [$item[1]] }

itemheader: /^\* / /([^\:]+)/ /:\s*/
{$item[2]}

itembody: /^(?!(\* .+?:|\d{4}-\d\d\-\d\d))(.*)/
{$item[1]}

);

my $text;
{
  local $/ = undef;
  $text = <STDIN>;
}
my $log = Parse::RecDescent->new($grammar)->file($text);
print Dumper($log);

permlink