Implementing DSL in PHP

I have an idea. I want to give our client the opportunity to specify prices based on a number of variables by writing simple code, for example:

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

And in my code, I would do something like this:

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

I assume that I want to create a simple DSL in PHP, which allows our client to have great flexibility in setting prices without having code for each case.

Here is the basic idea:

  • I would provide an array of variables and the code that the client wrote.
  • The parser will evaluate the code that the user wrote using the provided variables and return the value returned by our client to me. It will throw exceptions for any syntax errors, etc.
  • Then I used the return value in the normal application logic.

Do you know of any resources or frameworks for creating simple DSL in PHP? Any ideas where to start?

Thanks!

+7
source share
3 answers

Technical limitations aside, you may think twice about enabling such programming (I suppose) to non-programmers. They will probably be randomly messed up and you will need to clean up the mess. At the very least, protect it with lots of tests. And, possibly, legal.

But you asked a question, so I will try to answer this question. There is a distinction between internal style DSL (which most people mean when they use the word DSL) and then external style DSL (which is more like a mini-language). Ruby is famous for having syntax that lends itself well to internal DSL. PHP, on the other hand, is pretty bad in this regard.

However, you can still do some things in PHP. The simplest thing is probably just to write a library of functions, and then your clients write code in simple PHP using this library. Of course, you will have to check the code, but this will give all the advantages of using the existing runtime.

If this is not enough, you will have to dig in to heavy things. First you need a parser. If you know how to do this, they can be written quite easily, but if you were not forced to write a book at school or you had a strange hobby for writing such material just for fun (I know), this will probably lead you to a bit work. The main components of the analyzer are a tokenizer and some automata (state machine) that place tokens in a tree structure (AST).

Once you have your own structure, you should evaluate it. Since this is DSL, the number of functions is limited, and performance is probably not the biggest problem, you can write some object-oriented code around the AST and leave it to that. Otherwise, you have options such as writing some kind of interpreter or cross-compiling it into another format (PHP will be the obvious choice).

All this complex part is mainly related to handling extreme cases, such as syntax errors and reporting something meaningful to the user. Again, simply by providing access to a subset of PHP, you will get it for free, so keep that in mind first.

+7
source

If someone else is looking for another option, consider using Twig to create DSL / parsing ( http://twig.sensiolabs.org/ ), which is integrated into Pico CMS ( http://pico.dev7studios.com/ # ).

+3
source

The standard approach to creating a DSL parser is to use the aka compiler-compiler parser generator to do the hard work. This allows the developer to express DSL in the abstract syntax of BNF , and he does not need to go into the parsing of parsing and lexing.

Examples include Yacc in C, Regexp :: Grammars in Perl, and ANTLR , which targets Java and several other languages, etc. The PHP parameter looks like PHP-PEG .

+1
source

All Articles