blob: 695c28c39b24b0c4d707bb1943607bc13f6b5107 (
plain)
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
|
struct EvalString {
struct Env {
virtual string Evaluate(const string& var) = 0;
};
bool Parse(const string& input);
string Evaluate(Env* env);
const string& unparsed() const { return unparsed_; }
string unparsed_;
enum TokenType { RAW, SPECIAL };
typedef vector<pair<string, TokenType> > TokenList;
TokenList parsed_;
};
bool EvalString::Parse(const string& input) {
unparsed_ = input;
string::size_type start, end;
start = 0;
do {
end = input.find_first_of("@$", start);
if (end == string::npos) {
end = input.size();
break;
}
if (end > start)
parsed_.push_back(make_pair(input.substr(start, end - start), RAW));
start = end;
for (end = start + 1; end < input.size(); ++end) {
if (!('a' <= input[end] && input[end] <= 'z'))
break;
}
if (end == start + 1) {
// XXX report bad parse here
return false;
}
parsed_.push_back(make_pair(input.substr(start, end - start), SPECIAL));
start = end;
} while (end < input.size());
if (end > start)
parsed_.push_back(make_pair(input.substr(start, end - start), RAW));
return true;
}
string EvalString::Evaluate(Env* env) {
string result;
for (TokenList::iterator i = parsed_.begin(); i != parsed_.end(); ++i) {
if (i->second == RAW)
result.append(i->first);
else
result.append(env->Evaluate(i->first));
}
return result;
}
|