Token の種類を判定する (コメント)

前回は仮に、英数字を「予約語」としてあつかったが、
今回は実際に、「/*」 から 「*/」 までと、「//」から「\n」までを「コメント」として扱う。
それ以外は、「その他」として扱う。

SourceToHtml6.plx


use strict;
#******************************************************************************
# C# → HTML 変換処理
#******************************************************************************
# ヘッダ部
fileCopy(".\\Template\\header.txt");

# ソース部の変換
my $state = "その他";
my $kind = "";

my $line;
putLine() while ($line = getLine());

# フッタ部
fileCopy(".\\Template\\footer.txt");

#==============================================================================
# テンプレートファイルのコピー
#==============================================================================
sub fileCopy
{
my ($fileName) = @_;

open(F, $fileName) || die "open: $!";
print while (<F>);
close(F);
}
#==============================================================================
# 1行ずつ読み込む
#==============================================================================
sub getLine
{
# 1行読み込む
$_ = <>;

# TABを空白に変換
my $pos;
my $num;
while(($pos = index($_, "\t")) >= 0) #TABがあるか
{
$num = 4 - ($pos % 4); #空白何文字分に置き換えればよいか
$_ = substr($_,0,$pos).(' ' x $num).substr($_,$pos+1); #空白に置き換え
}

# 行末の空白を削除
s/ +$//;

# 変換結果を返す
return $_;
}
#==============================================================================
# 1行ずつ書き込む
#==============================================================================
sub putLine
{
# 改行コードを取り除く
chomp($line);

while(length($line))
{
if ($state eq "その他")
{
if ($line =~ /^\/\//) # 単一行コメントか?
{
putToken($line, "単一行コメント");
$line = "";
}
elsif ($line =~ /^\/\*/) # 複数行コメントか?
{
putToken("/*", "複数行コメント");

$line = substr($line, 2);
if ($line =~ /\*\//) # 終了があるか?
{
putToken($`."*/", "複数行コメント");
$line = substr($line, length($`) + 2);
}
else
{
putToken($line, "複数行コメント");
$line = "";
$state = "複数行コメント";
}
}
else
{
# 1文字取得
$line =~ /./;
putToken($&, "その他");

# 1文字切り詰める
$line = substr($line, length($&));
}
}
elsif ($state eq "複数行コメント")
{
if ($line =~ /\*\//) # 終了があるか?
{
putToken($`."*/", "複数行コメント");
$line = substr($line, length($`) + 2);
$state = "その他";
}
else
{
putToken($line, "複数行コメント");
$line = "";
}
}
}

# 改行
putToken("\n", $state);
}
#==============================================================================
# トークンを書き込む
#==============================================================================
sub putToken
{
$_ = shift; #追加する文字列
my $kind_next = shift; #追加するトークンの種類

# トークンの種類が変わったら、書き込む
if ($kind ne $kind_next)
{
print "</SPAN>" unless (($kind eq "その他") || ($kind eq ""));

if ($kind_next eq "複数行コメント") { print "<SPAN CLASS=\"COM\">"; }
elsif ($kind_next eq "単一行コメント") { print "<SPAN CLASS=\"COM\">"; }
}
$kind = $kind_next;

# <, >, &, |, (, ) を置換
s/&/&#x26;/g; # &
s/</&#x3C;/g; # <
s/>/&#x3E;/g; # >
s/\(/&#x28;/g; # ( はてな
s/\)/&#x29;/g; # ) はてな
s/\|/&#x7C;/g; # | はてな

print $_;
}

実行形式


C:\Perl5>jperl SourceToHtml6.plx input.txt > output.txt