Merge pull request #429 from a1812/interpreter

Add pattern Interpreter
This commit is contained in:
Dominik Liebler 2021-04-30 08:32:57 +02:00 committed by GitHub
commit 3f84442528
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 230 additions and 2 deletions

View File

@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace DesignPatterns\Behavioral\Interpreter;
abstract class AbstractExp
{
abstract public function interpret(Context $context): bool;
}

View File

@ -0,0 +1,18 @@
<?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);
}
}

View File

@ -0,0 +1,24 @@
<?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;
}
}

View File

@ -0,0 +1,18 @@
<?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);
}
}

View File

@ -0,0 +1,71 @@
`Interpreter`__
============
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.
Examples
--------
- An example of a binary logic interpreter, each definition is defined by its own class
UML Diagram
-----------
.. image:: uml/uml.png
:alt: Alt Interpreter UML Diagram
:align: center
Code
----
You can also find this code on `GitHub`_
AbstractExp.php
.. literalinclude:: AbstractExp.php
:language: php
:linenos:
Context.php
.. literalinclude:: Context.php
:language: php
:linenos:
VariableExp.php
.. literalinclude:: VariableExp.php
:language: php
:linenos:
AndExp.php
.. literalinclude:: AndExp.php
:language: php
:linenos:
OrExp.php
.. literalinclude:: OrExp.php
:language: php
:linenos:
Test
----
Tests/InterpreterTest.php
.. literalinclude:: Tests/InterpreterTest.php
:language: php
:linenos:
.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/main/Behavioral/Interpreter
.. __: https://en.wikipedia.org/wiki/Interpreter_pattern

View File

@ -0,0 +1,63 @@
<?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');
}
}

View File

@ -0,0 +1,23 @@
<?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;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -7,6 +7,7 @@ communication.
* [ChainOfResponsibilities](ChainOfResponsibilities) [:notebook:](http://en.wikipedia.org/wiki/Chain_of_responsibility_pattern)
* [Command](Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern)
* [Interpreter](Interpreter) [:notebook:](https://en.wikipedia.org/wiki/Interpreter_pattern)
* [Iterator](Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern)
* [Mediator](Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern)
* [Memento](Memento) [:notebook:](http://en.wikipedia.org/wiki/Memento_pattern)

View File

@ -11,6 +11,7 @@ carrying out this communication.
ChainOfResponsibilities/README
Command/README
Interpreter/README
Iterator/README
Mediator/README
Memento/README
@ -22,4 +23,4 @@ carrying out this communication.
TemplateMethod/README
Visitor/README
.. __: http://en.wikipedia.org/wiki/Behavioral_pattern
.. __: http://en.wikipedia.org/wiki/Behavioral_pattern

View File

@ -79,6 +79,7 @@ The patterns can be structured in roughly three different categories. Please cli
* [ChainOfResponsibilities](Behavioral/ChainOfResponsibilities) [:notebook:](http://en.wikipedia.org/wiki/Chain_of_responsibility_pattern)
* [Command](Behavioral/Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern)
* [Interpreter](Behavioral/Interpreter) [:notebook:](https://en.wikipedia.org/wiki/Interpreter_pattern)
* [Iterator](Behavioral/Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern)
* [Mediator](Behavioral/Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern)
* [Memento](Behavioral/Memento) [:notebook:](http://en.wikipedia.org/wiki/Memento_pattern)
@ -113,4 +114,4 @@ The patterns can be structured in roughly three different categories. Please cli
| es_MX | Spanish-Mexican | [Docs :notebook:](https://designpatternsphp.readthedocs.io/es_MX/latest/README.html) |
| tr | Turkish | [Docs :notebook:](https://designpatternsphp.readthedocs.io/tr/latest/README.html) |
| bg | Bulgarian | [Docs :notebook:](https://designpatternsphp.readthedocs.io/bg/latest/README.html) |
| fr | French | [Docs :notebook:](https://designpatternsphp.readthedocs.io/fr/latest/README.html) |
| fr | French | [Docs :notebook:](https://designpatternsphp.readthedocs.io/fr/latest/README.html) |