-
Notifications
You must be signed in to change notification settings - Fork 961
/
Copy pathInterpreter.cpp
125 lines (106 loc) · 2.46 KB
/
Interpreter.cpp
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* C++ Design Patterns: Interpreter
* Author: Jakub Vojvoda [github.com/JakubVojvoda]
* 2016
*
* Source code is licensed under MIT License
* (for more details see LICENSE)
*
*/
#include <iostream>
#include <map>
/*
* Context
* contains information that's global to the interpreter
*/
class Context
{
public:
void set( const std::string& var, const bool value)
{
vars.insert( std::pair<std::string, bool>( var, value ) );
}
bool get( const std::string& exp )
{
return vars[ exp ];
}
// ...
private:
std::map<std::string, bool> vars;
// ...
};
/*
* Abstract Expression
* declares an abstract Interpret operation that is common to all nodes
* in the abstract syntax tree
*/
class AbstractExpression
{
public:
virtual ~AbstractExpression() {}
virtual bool interpret( Context* const )
{
return false;
}
// ...
};
/*
* Terminal Expression
* implements an Interpret operation associated with terminal symbols
* in the grammar (an instance is required for every terminal symbol
* in a sentence)
*/
class TerminalExpression : public AbstractExpression
{
public:
TerminalExpression( const std::string& val ) : value( val ) {}
~TerminalExpression() {}
bool interpret( Context* const context )
{
return context->get( value );
}
// ...
private:
std::string value;
// ...
};
/*
* Nonterminal Expression
* implements an Interpret operation for nonterminal symbols
* in the grammar (one such class is required for every rule in the grammar)
*/
class NonterminalExpression : public AbstractExpression
{
public:
NonterminalExpression( AbstractExpression *left, AbstractExpression *right ) :
lop( left ), rop( right ) {}
~NonterminalExpression()
{
delete lop;
delete rop;
}
bool interpret( Context *const context )
{
return lop->interpret( context ) && rop->interpret( context );
}
// ...
private:
AbstractExpression *lop;
AbstractExpression *rop;
// ...
};
int main()
{
// An example of very simple expression tree
// that corresponds to expression (A AND B)
AbstractExpression *A = new TerminalExpression("A");
AbstractExpression *B = new TerminalExpression("B");
AbstractExpression *exp = new NonterminalExpression( A, B );
Context context;
context.set( "A", true );
context.set( "B", false );
std::cout << context.get( "A" ) << " AND " << context.get( "B" );
std::cout << " = " << exp->interpret( &context ) << std::endl;
delete exp;
return 0;
}