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,它允许我们的客户在设置定价时具有很大的灵活性,而无需让我们为每个案例编写代码.
这是基本的想法:
>我会提供一系列变量和客户编写的代码.
>解析器将使用提供的变量评估用户编写的代码,并将客户返回的值返回给我.它会抛出任何语法错误等异常.
>然后我将在应用程序的正常逻辑中使用返回的值.
那么你知道在PHP中构建一个简单的DSL的任何资源或框架吗?任何想法从哪里开始?
谢谢!
但你问了一个问题,所以我会试着回答这个问题.内部风格的DSL(大多数人使用单词DSL时的含义)和外部风格的DSL(更像是迷你语言)之间存在着区别. Ruby以其语法为内部风格的DSL而自然而闻名.另一方面,PHP在这方面相当糟糕.
也就是说,你仍然可以在PHP中做一些事情 – 最简单的可能只是编写一个函数库,然后让你的客户使用该库在纯PHP中编写代码.您当然必须审核代码,但它会提供使用现有运行时的所有好处.
如果这不够花哨,你将不得不深入挖掘重物.首先,您需要一个解析器.如果你知道如何,他们可以很容易手写,但除非你被迫在学校写一个或你有一个奇怪的爱好写这种东西只是为了好玩(我这样做),它可能会带你一个一点工作.解析器的基本组件是标记器和某种自动机(状态机),它将标记排列成树结构(AST).
获得解析后的结构后,需要对其进行评估.由于这是一个DSL,功能的数量是有限的,性能可能不是你最关心的问题,你可以在AST周围编写一些面向对象的代码并保留它.否则,您可以选择编写某种解释器或将其交叉编译为另一种格式(PHP将是一个明显的选择).
在这方面,棘手的部分主要是处理边缘情况,例如语法错误,并向用户报告有意义的内容.再次,只是给予访问PHP的子集,将免费提供给您,所以首先考虑.