実用化

次に、コード生成と創造性を結び付ける方法について説明します。
コード生成を理解するために、それを試してみましょう。

構造


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の類似物。

Source: https://habr.com/ru/post/J24266/


All Articles