CondParse, a condition string parser in PHP.- 2 mins
CondParse is a “condition string” parser, written in PHP.
A piece of legacy software our team was using, contained a rather botched attempt at a business rules engine. This engine has been permeated so deeply into the whole system, it’s become barely possible to refactor it, let alone replace it entirely. So, accepting that technical debt, the least we could do was attempt to clean it up.
A “condition string”, as the engine refers to its business rule descriptors, would look something like this:
#1# && #2#. This condition would evaluate to
true if and only if both the object referred to by
id:2 would also evaluate to
true when called. This makes a fair amount of sense.
However, the approach it took to evaluating a condition string was to quite simply transform the string into something akin to
return Condition::evaluate("1") && Condition::evaluate("2"); and throwing that string into
eval. While that did work fine, it made debugging, optimization, opcode-caching and so on a bit of a nightmare. In other words, the usual problems that tend to arise when using
eval in production code.
So, I attempted to create a replacement system. The result of which has become a rather performant, rather extensible, and fairly comprehensible condition-string parser.
First, it takes your input string - for example
#1# && #2# - and runs it through the lexer which just turns it into a stream of tokens. This tokenstream is provided to the parser, together with a “TokenMap” (which basically tells the parser which token should be turned into which Operand), who ends up returning a single, executable Operand.
This operand is, in so many words, just an infix representation of the input. In fact, the builtin operands have a toString method which would just return an infix representation. The example input would, hence, be rendered into something representing
Find the code on GitHub. Not actively maintained, but a fun experiment nevertheless.