実用化

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

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



構造



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 ;

whilefalse !==( $ obj = readdir( $ dh ))){

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

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

}

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( $ expr0$ 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