File: ruleEvaluator.C

package info (click to toggle)
ball 1.5.0%2Bgit20180813.37fc53c-6
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 239,888 kB
  • sloc: cpp: 326,149; ansic: 4,208; python: 2,303; yacc: 1,778; lex: 1,099; xml: 958; sh: 322; makefile: 95
file content (240 lines) | stat: -rw-r--r-- 4,941 bytes parent folder | download | duplicates (9)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

// $Id: ruleEvaluator.C,v 1.12 2002/02/27 12:21:35 sturm Exp $

#include <BALL/MOLMEC/COMMON/ruleEvaluator.h>
#include <BALL/FORMAT/INIFile.h>
#include <BALL/KERNEL/PTE.h>

//#define DEBUG_RULEEVALUATOR

using namespace std;

namespace BALL 
{

	RuleEvaluator::RuleEvaluator() 
		:	prefix_(),
			rule_map_(),
			valid_(false)
	{
	}


	RuleEvaluator::RuleEvaluator(INIFile& file, const String& prefix) 
		:	prefix_(),
			rule_map_(),
			valid_(false)
	{
		valid_ = initialize(file, prefix);
	}


	RuleEvaluator::RuleEvaluator(const RuleEvaluator& evaluator) 
		:	prefix_(evaluator.prefix_),
			rule_map_(evaluator.rule_map_),
			valid_(evaluator.valid_)
	{
	}


	RuleEvaluator::~RuleEvaluator() 
	{
		clear();
	}

	
	void RuleEvaluator::clear() 
		
	{
		prefix_ = "";
		rule_map_.clear();

		valid_ = false;
	}
	

	const String& RuleEvaluator::getPrefix() const 
	{
		return prefix_;
	}


	void RuleEvaluator::setPrefix(const String& prefix) 
	{
		prefix_ = prefix;
	}


	bool RuleEvaluator::initialize
		(INIFile& file, const String& prefix) 
	{
		// destroy the old rules
		rule_map_.clear();
		valid_ = false;

		// store the new prefix
		prefix_ = prefix;

		// check whether the INI file is valid
		if (!file.isValid())
		{
			// we didn't get a valid prefix file: abort
			return false;
		}

		// check for the sections and create the corresponding
		// Expressions
		for (Position i = 0; i < Element::NUMBER_OF_ELEMENTS; i++)
		{
			extractSection_(file, PTE[i].getSymbol());
		}

		// the last rule is a general rule
		extractSection_(file, "*");
	
		if (rule_map_.size() == 0)
		{
			Log.error() << "RuleEvaluator::initialize: no matching sections found for prefix " << prefix_ << endl;
		}
		
		// we create a map - done.
		valid_ = true;
		return true;
	}


	void RuleEvaluator::extractSection_(INIFile& file, const String& symbol)
		
	{
		// assemble the section name
		String section_name(prefix_ + ":" + symbol);

		// abort if the INI file does not contain the requested section
		if (!file.hasSection(section_name))
		{
			return;
		}

		// create a new entry for symbol
		if (!rule_map_.has(symbol))
		{
			rule_map_.insert(symbol, list<pair<Expression, String> >());
		}

		// iterate over all lines of the respective section
		INIFile::LineIterator it = file.getSectionFirstLine(section_name);
		++it;//skip section line
		for (; +it ; it.getSectionNextLine())
		{
			String line(*it);
			// empty lines or comment lines (starting with ';' or '#') are ignored
			if (line.has('=') && (line[0] != ';') && (line[0] != '#'))
			{
				if (line[0] == '=')
				{
					Log.error() << "RuleEvaluator:: invalid rule in line: " << line << endl;
					continue;
				}

				String value = line.before("=");	
				String expression_string;
				if (line.after("=").isValid())
				{
					expression_string = line.after("=");
				}
				expression_string.trim();
				value.trim();

				// push the expression into the list
				rule_map_[symbol].push_back(pair<Expression, String>(Expression(expression_string), value));
			}
		}
	}


	String RuleEvaluator::operator () (const Atom& atom) const 
	{
		// check whether we got a rule for this element
		String symbol = atom.getElement().getSymbol();
		RuleList::const_iterator it;

		// the return value
		String result = "";
		if (rule_map_.has(symbol))
		{
			// iterate over all rules in the list until the first rule
			// matches
			for (it = rule_map_[symbol].begin(); it != rule_map_[symbol].end(); ++it)
			{
				// check whether the expression matches for this atom
				if (it->first(atom))
				{
					#ifdef DEBUG_RULEEVALUATOR
						Log.info() << "atom "<< atom.getFullName() << " matches rule " << it->first.getExpression() << endl;
					#endif
					// retrieve the return value
					result = it->second;
					break;
				}
			}
		} 
		
		// if no rule was applicable, check the default rule "*"
		if ((result == "") && (rule_map_.has("*")))
		{
			// iterate over all rules in the list until the first rule
			// matches
			for (it = rule_map_["*"].begin(); it != rule_map_["*"].end(); ++it)
			{
				// check whether the expression matches for this atom
				if (it->first(atom))
				{
					// retrieve the return value
					result = it->second;
					
					// and exit the loop
					break;
				}
			}
		}
				
		// return the value
		return result;
	}


	bool RuleEvaluator::operator == (const RuleEvaluator& evaluator) const
		
	{
		return ((prefix_ == evaluator.prefix_)
			&& (rule_map_ == evaluator.rule_map_)
			&& (valid_ == evaluator.valid_));
	}


	const RuleEvaluator& RuleEvaluator::operator = 
		(const RuleEvaluator& evaluator) 
	{
		valid_ = evaluator.valid_;
		prefix_ = evaluator.prefix_;
		rule_map_ = evaluator.rule_map_;

		return *this;
	}


	bool RuleEvaluator::isValid() const 
	{
		return valid_;
	}


	void RuleEvaluator::dump(std::ostream& /* s */, Size /* indent_depth */)
		const 
	{
		// ?????
	}
}