注:コンテンツは必ずしも有効なPHPスクリプトである必要はありません
私の提案は次のようになります:
5e3n:3;geo(386299n283752w):4;delta(16e3n:5;line(20e0n;20e10n;0e10n;color:d);19w55n;rectangle(50w50n;height:100;width:50));88e2n:randomColor()
まず、パーサーを実装して、ステートメントを配列に分割します。すべての文字をループし、角かっこのカウンターを保持し、角かっこの;
外側で分割すると、次の配列になります。
array(
0 => object(prefix => "5e3n", suffix => "3"),
1 => object(prefix => "geo(386299n283752w)", suffix => "4"),
2 => object(prefix => "delta(16e3n:5;line(20e0n;20e10n;0e10n;color:d);19w55n;rectangle(50w50n;height:100;width:50))", suffix => ""),
3 => object(prefix => "88e2n", suffix => "randomColor()")
)
次に、関数パラメータを抽出します。オブジェクトを使用することもできます。
array(
0 => object(prefix => "5e3n", suffix => "3"),
1 => object(
prefix => (object)func(
name => "geo",
params => array(
0 => "386299n283752w"
)
),
suffix => "4"),
),
2 => object(
prefix => (object)func(
name => "delta",
params => array(
0 => "16e3n:5",
1 => "line(20e0n;20e10n;0e10n;color:d)",
2 => "19w55n",
3 => "rectangle(50w50n;height:100;width:50)"
)
),
suffix => ""
),
3 => object(
prefix => "88e2n",
suffix => (object)func(
name => "randomColor",
params => array()
)
)
)
内部のすべての関数が抽出されるまで、これを再帰的に実行します。
(object)func
次に、深さから、ブロックを結果の文字列に置き換えswitch
、名前に応じて適切なアクションを実行するブロックで関数を処理します。次に例を示します。
function processFunc($func){
switch($func->name){
case "randomColor":
return selectRandomColor();
/* ... */
}
}
これを処理します:
(object)func(
name => "randomColor",
params => array()
)
これに:
"blueColor"
次に、最後に、たとえば(上記で直接一致しない)内容の単一の配列になります。
array(
0 => object(prefix => "5e3n", suffix => "3"),
1 => object(prefix => "6e2n", suffix => "4"),
2 => object(prefix => "88e2n", suffix => "")
)
次に、それらを再結合して結果の文字列にします。
私はあなたのために完全なスクリプトを書くつもりはありませんが、それをどのように扱うかについての考えがここにあります。これは完全ではないかもしれませんが、少し考えれば、完了することができるはずです。