以下是一个使用PHP实现简单领域特定语言(DSL)的实例。在这个例子中,我们将创建一个用于解析和执行简单的数学表达式的DSL。
DSL设计
我们的数学表达式DSL将支持以下功能:
- 加法(+)
- 减法(-)
- 乘法(*)
- 除法(/)
代码实现
```php
class MathExpressionDSL
{
public function parse($expression)
{
$tokens = $this->tokenize($expression);
$ast = $this->parseTokens($tokens);
return $this->evaluate($ast);
}
private function tokenize($expression)
{
$tokens = [];
$length = strlen($expression);
for ($i = 0; $i < $length; $i++) {
$char = $expression[$i];
if (ctype_digit($char) || $char == '.') {
$tokens[] = $char;
} elseif (in_array($char, ['+', '-', '*', '/'])) {
$tokens[] = 'operator';
$tokens[] = $char;
}
}
return $tokens;
}
private function parseTokens($tokens)
{
$ast = [];
$stack = [];
$i = 0;
$length = count($tokens);
while ($i < $length) {
$token = $tokens[$i];
if (is_numeric($token)) {
$ast[] = $token;
} elseif ($token == 'operator') {
$operator = $tokens[$i + 1];
while (count($stack) > 0 && $this->hasPrecedence($operator, $stack[count($stack) - 1])) {
$ast[] = $stack[count($stack) - 1];
$stack[] = $operator;
$i++;
}
$stack[] = $operator;
}
$i++;
}
while (count($stack) > 0) {
$ast[] = $stack[count($stack) - 1];
$stack[] = $stack[count($stack) - 1];
}
return $ast;
}
private function evaluate($ast)
{
$result = $ast[0];
$i = 1;
while ($i < count($ast)) {
$operator = $ast[$i];
$value = $ast[$i + 1];
switch ($operator) {
case '+':
$result += $value;
break;
case '-':
$result -= $value;
break;
case '*':
$result *= $value;
break;
case '/':
$result /= $value;
break;
}
$i += 2;
}
return $result;
}
private function hasPrecedence($op1, $op2)
{
$precedence = [
'+' => 1,
'-' => 1,
'*' => 2,
'/' => 2,
];
return $precedence[$op1] <= $precedence[$op2];
}
}
// 使用示例
$expression = "