実用化

次に、コード生成と創造性を結び付ける方法について説明します。

コード生成を理解するために、それを試してみましょう。



構造



PHPプロジェクトを作成し、そこに3つのディレクトリを追加しましょう。



1. source-ソースコードを追加するディレクトリ。

2. gen-コード生成スクリプトを含むディレクトリ。

3. result- 結果のあるディレクトリ。



ルートへの1つのファイル: make.php-コード生成ルールを決定し、コード生成プロセスを開始します。



プロセス



コード生成によりmake.phpファイルが実行され、このプロセスの実行方法に関する指示が含まれます。



一般的には、次のようになります。



手順make.php + ソースディレクトリのソースコード-> genディレクトリのスクリプトによる処理->結果を結果ディレクトリに生成します。



始めましょう



開始するには、処理せずにソースから結果にデータをコピーしてみましょう。 将来、このデータの処理を実装できるように、各ファイルの内容を読み取り、書き込みます。



ソースから結果を生成する前に、 結果をクリアする必要があります。そのために、 genディレクトリに次の内容のclear.phpを作成します。



機能クリア()

{

full_delete(dirname(__ FILE__)。 '/../result'、false );

}



関数 full_delete( $ dir 、 $ delete_me )

{

if (! $ dh = @opendir( $ dir )) return ;

while ( false !==( $ obj = readdir( $ dh ))){

if ( $ obj == '。' || $ obj == '..' ) continue ;

もし
(!@unlink( $ dir 。 ' /'。$ obj ))full_delete( $ dir 。 ' /'。$ obj 、 true );

}

closedir( $ dh );

if ( $ delete_me )@rmdir( $ dir );

}

ここでは、php.netで見つけたfull_delete関数を使用し、ほとんど変更しませんでした。



ここで処理を考えてみましょう。 ソースディレクトリにindex.phpファイルを作成し、次のように記述します。

echo 'Hello world!' ;
次の2つの理由でPHPタグを提供していません。

1.あなたはそれらをどこに置くかを自分で理解しています。

2. Habrはそれらを食べます。



gen / filter.phpファイルにフィルターを作成しましょう:

関数フィルター( $ input )

{

$出力 = $入力 ;

return $ output ;

}




そして、 make.phpに指示を書くことができます:

'gen / clear.php' が必要です 。

'gen / filter.php' が必要です 。



クリア();



$ index = file_get_contents( 'source / index.php' );

file_put_contents( 'result / index.php' 、フィルター( $ index ));



どうした



私たちは特定の概念を実装しましたが、これはまだ役に立たないものの、特定の可能性を秘めています。

フィルターを改良しましょう!



プリプロセッサ



私たちのシステムを試してみましょう。 PHPのラムダ式が本当に恋しいです。 それらの類似性の一部を実験として実装できます。



私はいつもusort関数を使用することを好まなかったので、別の関数を作成する必要があり、create_functionを使用することはまったく楽しいものではありませんでした。 いくつかの制限されたラムダ構文を実装しましょう。



私は `文字を使用しないので(shell_exec関数への単純化されたアクセスを実装しています)、ラムダ式に簡単に寄付できます。 ラムダ式の実験的な構文:

`引数リスト->アクション`


例:

` $ var1 、 $ var2- > $ var1 + $ var2`




このような構成を処理するには、ファイルgen / filter.phpに filter_lambda関数を記述します。

$ uid = 0 ;



関数 filter_lambda( $ input )

{

グローバル $ uid ;

$ additional_code = '' ;

while (( $ spos = strpos( $ input 、 '' ' ))!== false )

{

$ epos = strpos( $ input 、 '' ' 、 $ spos + 1 );

$ expr = substr( $ input 、 $ spos + 1 、 $ epos-$ spos - 1 );

$ divider_pos = strpos( $ expr 、 '->' );

$ vars = trim(substr( $ expr 、 0 、 $ divider_pos ));

$ body = trim(substr( $ expr 、 $ divider_pos + 2 ));

$ additional_code 。= "function lambda_ $ uid ( $ vars ){return( $ body );} \ n" ;

$ input = substr( $ input 、0、 $ spos )。 "'lambda_ $ uid '" .substr( $ input 、 $ epos +1);

$ uid ++;

}

return ( $ additional_code != '' ? "<?php \ n $ additional_code ?>" : '' )。 $入力 ;

}


次に、フィルター関数を改良します。

関数フィルター( $ input )

{

$出力 = $入力 ;

$ output = filter_lambda( $ output );

return $ output ;

}


結果



これで、 source / index.phpファイルに書き込むことができます。

$数 =配列( 'much long' 、 'short' 、 'longer' );

usort( $ numbers 、 `$ value1、$ value2- > strlen($ value1)> strlen($ value2)` );



foreach ( $ キー としての 数字 == 値 )

{

echo " $ key : $ value <br/>" ;

}


make.phpを実行し、 result / index.phpを取得します。

<?php

function lambda_0( $ value1 、 $ value2 ){ return (strlen( $ value1 )> strlen( $ value2 ));}

?> <?php



$数 = 配列 ( 'much long' 、 'short' 、 'longer' );

usort( $ numbers 、 'lambda_0' );



foreach ( $ キー としての 数字 == 値 )

{

echo " $ key : $ value <br/>" ;

}

?>


残念ながら、PHPにはラムダ式はなく、この方法でさえ完全ではありません-ラムダ式で(環境から)変数を使用することはできません。

おわりに



このかなり単純な実験は、ソースコードに規則を追加し、単純な規則から複雑な規則を作成する方法を示しています。 この実験は完璧とはほど遠いです。理想的には、解析などを使用する必要がありますが、経験によりコードの前処理とコード生成の力を感じることができます。



さらに一歩



素材を統合して、次のような興味深いタスクを実現することを提案します。

1. make.phpに各ファイルを書き込まないように、 ソースディレクトリからphpファイルを再帰的に処理します。

2.条件付き生成(Cなど)の実装を試みます-#define、#ifdef、#elif、#endifの類似物。



All Articles