<commit_before>#!/usr/local/bin/perl-5.22.0

=pod
- 1行1処理のまとまりとして処理する。

行の属性は段階的に付与していくか？
何が属性として必要か？
まずは関数単位に分割したい最初に見つけたが閉じられるまで


擬似コードを表示できるようにする必要があるか？
> 擬似コードを表示する(保持する)場合
  どこで表示する？表示する場所があるなら。
　SIML機能入れないなら擬似コードを元の構造で保つ必要はないだろう。
> 表示しない場合
　パースする時に元の構造を保持する必要が無いので楽。

異常を見つけた時にコードのおかしいところが必要か。
元の構造は維持しないと厳しいかなあ。

論理確認のSIMLは無くても困らないかな。
多分そこまで間に合わない。


サポートする制御構文
改行位置に関わらず解析できる必要がある。

セミコロンを不要にする代わりに、制御構文は行頭に無ければならない。
ただし、空白とコメントはあっても良い。

if (hoge) {
} else if (fuga) {
} else {
}

switch (hoge) {
case fuga:
    break;
default:
}

while (hoge) {
}

until (hoge) {
}

do {
} while (hoge);

for (i=0; i < hoge; i++) {
}

読み込む時に行番号と対応付けたハッシュデータで保持する？

前提として、ifとかwhileの前に処理を書くとか無いと信じる。
そういう書き方はコーディングの時にでもどうぞ。

というわけなので、制御文は行単位に解析で良い。
行番号に紐付けた構造で管理して、頭から順番に解析していく。

中括弧で囲まれた部分が処理単位なので、一番内側の中括弧を外しながら処理をしていく？
面倒くさそう？
サポートする制御は以下。
それぞれ形式が異なるので解析が面倒くさい。
人によって書き方違うかもしれないし。
絶対守ってほしいこと制御文は文の行頭(スペースを除く)から始めるという事。

解析は行単位に見ていき、制御文字を探す。
見つかった場合はその制御の最後(ifなら閉じ括弧と次の行にelseが続いていないか)を確認する。

if (hoge) { hogehoge; } else if (piyo) { piyopiyo; } else { fugafuga; }
switch (hoge) { case FOO: hogehoge; break; case BAR: piyopiyo; break; default: fugafuga; }
while (hoge) { hogehoge; }
for (i=0;i<=n;i++) { hogehoge; }

@src : ファイルを1行ごとに読み込んで格納
 |
 +-> % 

制御文のデータ構造
%{ ctrl => "define" : 関数定義
           "call"   : 関数コール
           "proc"   : 表示のみの処理
           "if"
           "switch"
           "while"
           "for"
   name => 関数名
   condition => true, false, null, or value
   proc => @処理、次の階層を繋げる場合もある
   prev => 一つ上の階層のハッシュ
   judgment => @条件
}

=cut

package C2Flow;

use utf8;
use strict;
use warnings;

sub new
{
    my $class = shift;

    my $read_src;
    my @funclist;

    my $self = {
        'read_src' => \$read_src,
        'funclist' => \@funclist
    };

    bless $self, $class;

    return $self;
}

sub read {
    my $self = shift;
    my $file = shift;

    open (my $fh, '<', $file) or die 'cannot open file';
    while (<$fh>) {
        s/[\r\n]+$/\n/; # 改行コードを\nに統一
        s/\t/ /g;       # タブを空白に置換
        s/\/\/.*$//; # 一行コメントを削除
        ${$self->{'read_src'}} .= $_;
    }
    ${$self->{'read_src'}} =~ s/\/\*.*?\*\///gs; # コメント行を削除
}

# $self->'read_src'を関数に分割する
# 分割した関数は$self->'functions'(@array)に以下のhashをpushする
#   % {
#     'name'
#     'src'
#   }
sub div_function {
    my $self = shift;
    my @functions;<commit_msg>[bugfix] 全角空白が一つの処理として表示されてしまう不具合を修正。<commit_after>#!/usr/local/bin/perl-5.22.0

=pod
- 1行1処理のまとまりとして処理する。

行の属性は段階的に付与していくか？
何が属性として必要か？
まずは関数単位に分割したい最初に見つけたが閉じられるまで


擬似コードを表示できるようにする必要があるか？
> 擬似コードを表示する(保持する)場合
  どこで表示する？表示する場所があるなら。
　SIML機能入れないなら擬似コードを元の構造で保つ必要はないだろう。
> 表示しない場合
　パースする時に元の構造を保持する必要が無いので楽。

異常を見つけた時にコードのおかしいところが必要か。
元の構造は維持しないと厳しいかなあ。

論理確認のSIMLは無くても困らないかな。
多分そこまで間に合わない。


サポートする制御構文
改行位置に関わらず解析できる必要がある。

セミコロンを不要にする代わりに、制御構文は行頭に無ければならない。
ただし、空白とコメントはあっても良い。

if (hoge) {
} else if (fuga) {
} else {
}

switch (hoge) {
case fuga:
    break;
default:
}

while (hoge) {
}

until (hoge) {
}

do {
} while (hoge);

for (i=0; i < hoge; i++) {
}

読み込む時に行番号と対応付けたハッシュデータで保持する？

前提として、ifとかwhileの前に処理を書くとか無いと信じる。
そういう書き方はコーディングの時にでもどうぞ。

というわけなので、制御文は行単位に解析で良い。
行番号に紐付けた構造で管理して、頭から順番に解析していく。

中括弧で囲まれた部分が処理単位なので、一番内側の中括弧を外しながら処理をしていく？
面倒くさそう？
サポートする制御は以下。
それぞれ形式が異なるので解析が面倒くさい。
人によって書き方違うかもしれないし。
絶対守ってほしいこと制御文は文の行頭(スペースを除く)から始めるという事。

解析は行単位に見ていき、制御文字を探す。
見つかった場合はその制御の最後(ifなら閉じ括弧と次の行にelseが続いていないか)を確認する。

if (hoge) { hogehoge; } else if (piyo) { piyopiyo; } else { fugafuga; }
switch (hoge) { case FOO: hogehoge; break; case BAR: piyopiyo; break; default: fugafuga; }
while (hoge) { hogehoge; }
for (i=0;i<=n;i++) { hogehoge; }

@src : ファイルを1行ごとに読み込んで格納
 |
 +-> % 

制御文のデータ構造
%{ ctrl => "define" : 関数定義
           "call"   : 関数コール
           "proc"   : 表示のみの処理
           "if"
           "switch"
           "while"
           "for"
   name => 関数名
   condition => true, false, null, or value
   proc => @処理、次の階層を繋げる場合もある
   prev => 一つ上の階層のハッシュ
   judgment => @条件
}

=cut

package C2Flow;

use utf8;
use strict;
use warnings;

sub new
{
    my $class = shift;

    my $read_src;
    my @funclist;

    my $self = {
        'read_src' => \$read_src,
        'funclist' => \@funclist
    };

    bless $self, $class;

    return $self;
}

sub read {
    my $self = shift;
    my $file = shift;

    open (my $fh, '<', $file) or die 'cannot open file';
    while (<$fh>) {
        s/[\r\n]+$/\n/; # 改行コードを\nに統一
        s/\t/ /g;       # タブを空白に置換
        s/　/  /g;      # 全角空白を半角空白x2に置換
        s/\/\/.*$//; # 一行コメントを削除
        ${$self->{'read_src'}} .= $_;
    }
    ${$self->{'read_src'}} =~ s/\/\*.*?\*\///gs; # コメント行を削除
}

# $self->'read_src'を関数に分割する
# 分割した関数は$self->'functions'(@array)に以下のhashをpushする
#   % {
#     'name'
#     'src'
#   }
sub div_function {
    my $self = shift;
    my @functions;
{'fraction_non_alphanumeric': 0.15023080151070078, 'fraction_numerical': 0.004825849769198489, 'mean_word_length': 3.152439024390244, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1474455', 'n_tokens_mistral': 3206, 'n_tokens_neox': 3129, 'n_words': 369}