ルールエンジン DSL の再作成

Susan Sarandon
Susan Sarandonオリジナル
2024-12-01 09:36:10118ブラウズ

数年前、私はもともと仕事のルールエンジン用に設計されたドメイン固有言語 (DSL) を再実装しました。おもちゃの再実装は Javascript (元々は Python) で書かれ、GitHub にリリースされました。これは公開すべきではない非常に特殊な使用例向けに特別に設計されていたため、あまり効果があるとは期待していませんでした。

Remaking a rule-engine DSL
bing副操縦士が吐いたちょっと可愛い写真

設計の主な目標は、簡単にシリアル化できるものにすることでした。チューリング完全性は次の 2 つのことだけを実行するだけで必要だったので、気にする必要はありませんでした。

  1. 簡単なブール比較 (x が y に対して == の場合)
  2. 辞書/ハッシュのフィールドから値を取得します

私はまず Python で匿名関数を書くことから始めました。ただし、作業を一連のスレッド/プロセスに分散しようとすると、インタープリターはラムダがシリアル化できないと不平を言いました。当時、メイン コードの外側にロジックを配置する必要があったため、最終的にはその目的のために DSL を作成しました。

最初に思い浮かんだのは Lisp でした。コードが配列/リストに似ているところが気に入っているからです。構成は既に YAML に保存されているため、類似性は良いことです。したがって、ロジックを表現するための新しい方法を作成することを心配する必要はありません。

言語をリストとして保存すると、別の利点がもたらされます。パーサーを最初から作成する必要がありません。つまり、トークン化/字句解析 (レクサー) を実行する必要がありません。言い換えれば、著者はレクサーです。実装する必要があるのは、入力リストを取得し、それがプログラムであるかどうかを確認し (これをルールと呼びます)、コンテキストに基づいて実行することだけです。

const schema = ["condition.Equal", ["basic.Field", "foo"], ["basic.Field", "bar"]];

// returns a function that checks if context.foo === context.bar
const rule = ruler.parse(rule)

const context = {foo: "meow", bar: "woof"};
rule(context) // returns false

すべてが期待どおりにうまくいきました。そして数日前、Python でスキームを実装するための記事を偶然見つけました。おそらく以前、Clojure の学習に多くの時間を費やしていたときにこの記事を読みました。ただし、今回は、Python を使用してライブラリを最初から再実装することにしました。

そこで、今回はトークン化してレクサーを自分で実行する必要がありました。数値だけを扱う場合はすべて簡単ですが、文字列となると話はさらに複雑になります。別のチュートリアルに従って、make-a-lisp プロジェクトを再発見しました。結局諦めて、hy-lang が提供するレクサーを使用しました。

レクサーは s 式を受け取り、抽象構文ツリーに似た構造を返します。そこから、ツリーをトラバースしてパーサーを構築し、コンテキストとして辞書を受け取るクロージャーとしてルールを返します。

const schema = ["condition.Equal", ["basic.Field", "foo"], ["basic.Field", "bar"]];

// returns a function that checks if context.foo === context.bar
const rule = ruler.parse(rule)

const context = {foo: "meow", bar: "woof"};
rule(context) // returns false

私は数年間仕事を辞めていたので、新しい実装には実際的な利点はありません。私が残した実装はおそらく今日まで問題なく動作します (これに至るまでに非常に多くの反復を行った後であった方が良いでしょう)。しかし、この旅を通して私はまだ一つか二つのことを学びます。これが興味深いと思われた場合は、JavaScript (配列内のルール スキーマが必要な場合) または新しい Python バージョン (s 式) を自由にチェックしてください。

以上がルールエンジン DSL の再作成の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。