9

考えがある。次のような単純なコードを記述して、多くの変数に基づいて価格を指定する機能をクライアントに提供したいと考えています。

if customer.zip is "37208"
   return 39.99
else
   return 59.99

私のコードでは、次のようにします。

try {
   $variables = array('customer' => array('zip' => '63901'));
   $code = DSL::parse(DSL::tokenize($userCode))
   $returnValue = DSL::run($code, $variables);
} catch (SyntaxErrorException $e) {
   ...
}

私が望んでいるのは、PHP で単純な DSL を作成することだと思います。これにより、顧客は価格を非常に柔軟に設定できるようになり、すべてのケースでコードを作成する必要がなくなります。

基本的な考え方は次のとおりです。

  1. 変数の配列と顧客が作成したコードを提供します。
  2. パーサーは、提供された変数を使用してユーザーが記述したコードを評価し、顧客が返した値を返します。構文エラーなどの例外がスローされます。
  3. 次に、返された値をアプリケーションの通常のロジックで使用します。

PHP で単純な DSL を構築するためのリソースやフレームワークを知っていますか? どこから始めればよいですか?

ありがとう!

4

3 に答える 3

10

技術的な制限はさておき、この種のプログラミング機能を (私が推測するに) 非プログラマーに提供することについては、よく考えたほうがよいかもしれません。彼らはおそらく完全に予測不可能な方法で混乱し、あなたは混乱を片付けなければならない人になるでしょう. 少なくとも多くのテストでそれを守ってください。そしておそらく法律用語も。

しかし、あなたは質問をしたので、私はそれに答えようとします。内部スタイルの DSL (ほとんどの人が DSL という言葉を使用するときの意味) と外部スタイルの DSL (ミニ言語のようなもの) の間には区別が必要です。Ruby は、内部スタイルの DSL に適した構文を持つことで有名です。一方、PHPはその点でかなり悪いです。

とはいえ、PHP でいくつかのことを行うこともできます。最も簡単なのは、おそらく関数のライブラリを作成し、そのライブラリを使用してプレーンな PHP でコードを記述してもらうことです。もちろん、コードを監査する必要がありますが、既存のランタイムを使用するすべての利点が得られます。

それが十分に派手でない場合は、重いものを掘り下げる必要があります. まず、パーサーが必要です。方法を知っていれば、かなり簡単に手書きで書くことができますが、学校で書くことを強制されたり、楽しみのためにそのようなものを書くという奇妙な趣味を持っていない限り (私はそうしています)、おそらく時間がかかるでしょう。ちょっとした仕事。パーサーの基本コンポーネントは、トークナイザーと、トークンをツリー構造 (AST) に配置するある種のオートマトン (ステート マシン) です。

構造を解析したら、それを評価する必要があります。これは DSL であるため、機能の数は限られており、パフォーマンスはおそらく最大の関心事ではありません。AST の周りにオブジェクト指向のコードを書き、そのままにしておくことができます。それ以外の場合は、ある種のインタープリターを作成するか、それを別の形式にクロスコンパイルするなどのオプションがあります (PHP は当然の選択です)。

これを通じて難しい部分は、ほとんどの場合、構文エラーなどの特殊なケースを処理し、意味のあるものをユーザーに報告することです。繰り返しになりますが、PHP のサブセットへのアクセスを許可するだけで無料でアクセスできるようになるため、最初にそれを検討してください。

于 2012-12-18T20:30:45.297 に答える
3

他の誰かが別のオプションを探している場合は、Pico CMS ( http://pico.dev7studios.com/# )に統合された DSL/解析 ( http://twig.sensiolabs.org/ ) を作成するために Twig を使用することを検討してください。 .

于 2014-02-19T21:43:18.597 に答える
2

DSL パーサーを構築するための標準的なアプローチは、パーサー ジェネレーター (コンパイラー コンパイラーとも呼ばれます) を使用して面倒な作業を行うことです。これにより、開発者は DSL を抽象的なBNF風の構文で表現でき、解析や字句解析の核心に入る必要がなくなります。

例には、C のYacc、Perl のRegexp::Grammars 、およびJava と他のいくつかの言語をターゲットとするANTLRなどがあります。PHP オプションはPHP-PEG のようです。

于 2015-01-08T22:01:53.157 に答える