3.3. Interpreter¶
3.3.1. Purpose¶
For a given language, it defines the representation of its grammar as „No Terminal Expression” and „Terminal Expression”, as well as an interpreter for the sentences of that language.
3.3.2. Examples¶
- An example of a binary logic interpreter, each definition is defined by its own class
3.3.3. UML Diagram¶

3.3.4. Code¶
You can also find this code on GitHub
AbstractExp.php
1 2 3 4 5 6 7 8 9 10 | <?php
declare(strict_types=1);
namespace DesignPatterns\Behavioral\Interpreter;
abstract class AbstractExp
{
abstract public function interpret(Context $context): bool;
}
|
Context.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <?php
declare(strict_types=1);
namespace DesignPatterns\Behavioral\Interpreter;
use Exception;
class Context
{
private array $poolVariable;
public function lookUp(string $name): bool
{
if (!key_exists($name, $this->poolVariable)) {
throw new Exception("no exist variable: $name");
}
return $this->poolVariable[$name];
}
public function assign(VariableExp $variable, bool $val)
{
$this->poolVariable[$variable->getName()] = $val;
}
}
|
VariableExp.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <?php
declare(strict_types=1);
namespace DesignPatterns\Behavioral\Interpreter;
/**
* This TerminalExpression
*/
class VariableExp extends AbstractExp
{
public function __construct(private string $name)
{
}
public function interpret(Context $context): bool
{
return $context->lookUp($this->name);
}
public function getName(): string
{
return $this->name;
}
}
|
AndExp.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php
declare(strict_types=1);
namespace DesignPatterns\Behavioral\Interpreter;
/**
* This NoTerminalExpression
*/
class AndExp extends AbstractExp
{
public function __construct(private AbstractExp $first, private AbstractExp $second)
{
}
public function interpret(Context $context): bool
{
return $this->first->interpret($context) && $this->second->interpret($context);
}
}
|
OrExp.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php
declare(strict_types=1);
namespace DesignPatterns\Behavioral\Interpreter;
/**
* This NoTerminalExpression
*/
class OrExp extends AbstractExp
{
public function __construct(private AbstractExp $first, private AbstractExp $second)
{
}
public function interpret(Context $context): bool
{
return $this->first->interpret($context) || $this->second->interpret($context);
}
}
|
3.3.5. Test¶
Tests/InterpreterTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | <?php
declare(strict_types=1);
namespace DesignPatterns\Behavioral\Interpreter\Tests;
use DesignPatterns\Behavioral\Interpreter\AndExp;
use DesignPatterns\Behavioral\Interpreter\Context;
use DesignPatterns\Behavioral\Interpreter\OrExp;
use DesignPatterns\Behavioral\Interpreter\VariableExp;
use PHPUnit\Framework\TestCase;
class InterpreterTest extends TestCase
{
private Context $context;
private VariableExp $a;
private VariableExp $b;
private VariableExp $c;
public function setUp(): void
{
$this->context = new Context();
$this->a = new VariableExp('A');
$this->b = new VariableExp('B');
$this->c = new VariableExp('C');
}
public function testOr()
{
$this->context->assign($this->a, false);
$this->context->assign($this->b, false);
$this->context->assign($this->c, true);
// A ∨ B
$exp1 = new OrExp($this->a, $this->b);
$result1 = $exp1->interpret($this->context);
$this->assertFalse($result1, 'A ∨ B must false');
// $exp1 ∨ C
$exp2 = new OrExp($exp1, $this->c);
$result2 = $exp2->interpret($this->context);
$this->assertTrue($result2, '(A ∨ B) ∨ C must true');
}
public function testAnd()
{
$this->context->assign($this->a, true);
$this->context->assign($this->b, true);
$this->context->assign($this->c, false);
// A ∧ B
$exp1 = new AndExp($this->a, $this->b);
$result1 = $exp1->interpret($this->context);
$this->assertTrue($result1, 'A ∧ B must true');
// $exp1 ∧ C
$exp2 = new AndExp($exp1, $this->c);
$result2 = $exp2->interpret($this->context);
$this->assertFalse($result2, '(A ∧ B) ∧ C must false');
}
}
|