コード生成を理解するために、それを試してみましょう。
構造
PHPプロジェクトを作成し、そこに3つのディレクトリを追加しましょう。
1. source-ソースコードを追加するディレクトリ。
2. gen-コード生成スクリプトを含むディレクトリ。
3. result- 結果のあるディレクトリ。
ルートへの1つのファイル: make.php-コード生成ルールを決定し、コード生成プロセスを開始します。
プロセス
コード生成によりmake.phpファイルが実行され、このプロセスの実行方法に関する指示が含まれます。
一般的には、次のようになります。
手順make.php + ソースディレクトリのソースコード-> genディレクトリのスクリプトによる処理->結果を結果ディレクトリに生成します。
始めましょう
開始するには、処理せずにソースから結果にデータをコピーしてみましょう。 将来、このデータの処理を実装できるように、各ファイルの内容を読み取り、書き込みます。
ソースから結果を生成する前に、 結果をクリアする必要があります。そのために、 genディレクトリに次の内容のclear.phpを作成します。
機能クリア()(!@unlink( $ dir 。 ' /'。$ obj ))full_delete( $ dir 。 ' /'。$ obj 、 true );
{
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 ;
もし
}
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の類似物。