Skip to content

Commit 9ea20d2

Browse files
authored
Merge pull request #32 from a1812/interpreter
Add pattern Interpreter/RealWorld
2 parents e934d99 + c36d0ac commit 9ea20d2

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
boolean expression A ∧ (B ∨ C) = true, with variables A=true, B=true, C=false
2+
boolean expression B ∨ (A ∧ (B ∨ C)) = false, with variables A=false, B=false, C=true
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
namespace RefactoringGuru\Interpreter\RealWorld;
4+
5+
/**
6+
* EN: Interpreter Design Pattern
7+
*
8+
* Defines a representation for a grammar as well as a mechanism to understand and act upon the grammar.
9+
*
10+
* RU: Паттерн Интерпретатор
11+
*
12+
* Определяет грамматику простого языка, представляет предложения на этом языке и интерпретирует их.
13+
*/
14+
class Context
15+
{
16+
private $poolVariable;
17+
18+
public function lookUp(string $name): bool
19+
{
20+
if (!key_exists($name, $this->poolVariable)) {
21+
die("No exist variable: $name");
22+
}
23+
24+
return $this->poolVariable[$name];
25+
}
26+
27+
public function assign(VariableExp $variable, $val)
28+
{
29+
$this->poolVariable[$variable->getName()] = $val;
30+
}
31+
}
32+
33+
abstract class AbstractExp
34+
{
35+
abstract public function interpret(Context $context): bool;
36+
}
37+
38+
class VariableExp extends AbstractExp
39+
{
40+
private $name;
41+
42+
public function __construct(string $name)
43+
{
44+
$this->name = $name;
45+
}
46+
47+
public function interpret(Context $context): bool
48+
{
49+
return $context->lookUp($this->name);
50+
}
51+
52+
public function getName(): string
53+
{
54+
return $this->name;
55+
}
56+
}
57+
58+
class AndExp extends AbstractExp
59+
{
60+
private $first;
61+
private $second;
62+
63+
public function __construct(AbstractExp $first, AbstractExp $second)
64+
{
65+
$this->first = $first;
66+
$this->second = $second;
67+
}
68+
69+
public function interpret(Context $context): bool
70+
{
71+
return (bool)$this->first->interpret($context) && $this->second->interpret($context);
72+
}
73+
}
74+
75+
class OrExp extends AbstractExp
76+
{
77+
private $first;
78+
private $second;
79+
80+
public function __construct(AbstractExp $first, AbstractExp $second)
81+
{
82+
$this->first = $first;
83+
$this->second = $second;
84+
}
85+
86+
public function interpret(Context $context): bool
87+
{
88+
return $this->first->interpret($context) || $this->second->interpret($context);
89+
}
90+
}
91+
92+
/**
93+
* EN: The client code.
94+
*
95+
* RU: Клиентский код.
96+
*/
97+
98+
$context = new Context();
99+
100+
$a = new VariableExp('A');
101+
$b = new VariableExp('B');
102+
$c = new VariableExp('C');
103+
104+
// example 1:
105+
// A ∧ (B ∨ C)
106+
$exp = new AndExp(
107+
$a,
108+
new OrExp($b, $c)
109+
);
110+
111+
$context->assign($a, true);
112+
$context->assign($b, true);
113+
$context->assign($c, false);
114+
115+
$result = $exp->interpret($context) ? 'true' : 'false';
116+
117+
echo 'boolean expression A ∧ (B ∨ C) = ' . $result . ', with variables A=true, B=true, C=false' . PHP_EOL;
118+
119+
120+
// example 2:
121+
// B ∨ (A ∧ (B ∨ C))
122+
$exp = new OrExp(
123+
$b,
124+
new AndExp(
125+
$a,
126+
new OrExp($b, $c)
127+
)
128+
);
129+
130+
$context->assign($a, false);
131+
$context->assign($b, false);
132+
$context->assign($c, true);
133+
134+
$result2 = $exp->interpret($context) ? 'true' : 'false';
135+
136+
echo 'boolean expression B ∨ (A ∧ (B ∨ C)) = ' . $result2 . ', with variables A=false, B=false, C=true';

0 commit comments

Comments
 (0)